package Ġcom . t ice app . android doub ler at chet Ċ Ċ import Ġcom . got erl . l az ys odium . Lazy S odium Android Ċ import Ġcom . got erl . l az ys odium . S odium Android Ċ import Ġcom . got erl . l az ys odium . interfaces . AE AD Ċ import Ġcom . got erl . l az ys odium . utils . Key Ċ import Ġcom . got erl . l az ys odium . utils . KeyPair Ċ Ċ class ĠDouble Rat chet Ġ{ ĊĠĠĠ Ġprivate Ġval Ġs odium : ĠLazy S odium Android ĊĊĠĠĠ Ġval Ġmax Skip : ĠInt ĊĊĠĠĠ Ġprivate Ġval Ġroot Chain : ĠRoot Chain ĊĠĠĠ Ġprivate Ġval Ġsending Chain : ĠMessage Chain ĊĠĠĠ Ġprivate Ġval Ġreceiving Chain : ĠMessage Chain ĊĊĠĠĠ Ġprivate Ġvar ĠsendMessage Number : ĠInt ĊĠĠĠ Ġprivate Ġvar Ġreceived Message Number : ĠInt ĊĠĠĠ Ġprivate Ġvar Ġprevious Sending Chain Length : ĠInt ĊĠĠĠ Ġprivate Ġval Ġmessage Key Cache : ĠMessage Key Cache ? ĊĊĠĠĠ Ġval ĠpublicKey : ĠKey ĊĠĠĠĠĠĠĠ Ġget Ġ() Ġ= Ġroot Chain . key Pair . publicKey ĊĊĠĠĠ Ġval Ġsession State : ĠSession State ĊĠĠĠĠĠĠĠ Ġget () Ġ= ĠSession State ( ĊĠĠĠĠĠĠĠĠĠĠĠ Ġroot Chain . root Key , ĊĠĠĠĠĠĠĠĠĠĠĠ Ġroot Chain . key Pair , ĊĠĠĠĠĠĠĠĠĠĠĠ Ġroot Chain . remote PublicKey , ĊĠĠĠĠĠĠĠĠĠĠĠ Ġsending Chain . chain Key , ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreceiving Chain . chain Key , ĊĠĠĠĠĠĠĠĠĠĠĠ ĠsendMessage Number , ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreceived Message Number , ĊĠĠĠĠĠĠĠĠĠĠĠ Ġprevious Sending Chain Length , ĊĠĠĠĠĠĠĠĠĠĠĠ Ġroot Chain . info , ĊĠĠĠĠĠĠĠĠĠĠĠ Ġmax Skip , ĊĠĠĠĠĠĠĠ Ġ) ĊĊĠĠĠ Ġ@ Experimental Std lib Api ĊĠĠĠ Ġconstructor ( key Pair : ĠKey Pair ?, Ġremote PublicKey : ĠKey ?, Ġshared Secret : ĠByteArray , Ġmax Skip : ĠInt , Ġinfo : ĠString , Ġmessage Key Cache : ĠMessage Key Cache ?, Ġs odium : ĠLazy S odium Android ?) Ġ{ ĊĠĠĠĠĠĠĠ Ġrequire ( shared Secret . size Ġ== Ġ 3 2 ) ĊĊĠĠĠĠĠĠĠ Ġthis . s odium Ġ= Ġs odium Ġ?: ĠLazy S odium Android ( S odium Android (), ĠBase 6 4 Coder ) ĊĊĠĠĠĠĠĠĠ Ġval Ġkey Pair Ġ= Ġkey Pair Ġ?: Ġthis . s odium . crypto Kx Key pair () ĊĊĠĠĠĠĠĠĠ Ġthis . max Skip Ġ= Ġmax Skip ĊĠĠĠĠĠĠĠ Ġthis . root Chain Ġ= ĠRoot Chain ( key Pair , Ġremote PublicKey , Ġroot Key Ġ= ĠKey . from Bytes ( shared Secret ), Ġinfo Ġ= Ġinfo , Ġs odium Ġ= Ġthis . s odium ) ĊĠĠĠĠĠĠĠ Ġthis . sending Chain Ġ= ĠMessage Chain ( s odium Ġ= Ġthis . s odium ) ĊĠĠĠĠĠĠĠ Ġthis . re ceiving Chain Ġ= ĠMessage Chain ( s odium Ġ= Ġthis . s odium ) ĊĊĠĠĠĠĠĠĠ Ġthis . sendMessage Number Ġ= Ġ 0 ĊĠĠĠĠĠĠĠ Ġthis . received Message Number Ġ= Ġ 0 ĊĠĠĠĠĠĠĠ Ġthis . previous Sending Chain Length Ġ= Ġ 0 ĊĠĠĠĠĠĠĠ Ġthis . message Key Cache Ġ= Ġmessage Key Cache ĊĊĠĠĠĠĠĠĠ Ġif Ġ( remote PublicKey Ġ!= Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġsending Chain . chain Key Ġ= Ġroot Chain . rat chet Step ( Side . SEND ING ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ Experimental Std lib Api ĊĠĠĠ Ġconstructor ( session State : ĠSession State , Ġmessage Key Cache : ĠMessage Key Cache ?, Ġs odium : ĠLazy S odium Android ?) Ġ{ ĊĠĠĠĠĠĠĠ Ġthis . s odium Ġ= Ġs odium Ġ?: ĠLazy S odium Android ( S odium Android (), ĠBase 6 4 Coder ) ĊĊĠĠĠĠĠĠĠ Ġthis . max Skip Ġ= Ġsession State . max Skip ĊĊĠĠĠĠĠĠĠ Ġthis . root Chain Ġ= ĠRoot Chain ( session State . root Chain KeyPair , Ġsession State . root Chain Remote PublicKey , Ġsession State . root Key , Ġsession State . info , Ġs odium Ġ= Ġthis . s odium ) ĊĠĠĠĠĠĠĠ Ġthis . sending Chain Ġ= ĠMessage Chain ( session State . sending Chain Key , Ġs odium Ġ= Ġthis . s odium ) ĊĠĠĠĠĠĠĠ Ġthis . re ceiving Chain Ġ= ĠMessage Chain ( session State . re ceiving Chain Key , Ġs odium Ġ= Ġthis . s odium ) ĊĠĠĠĠĠĠĠ Ġthis . sendMessage Number Ġ= Ġsession State . sendMessage Number ĊĠĠĠĠĠĠĠ Ġthis . received Message Number Ġ= Ġsession State . received Message Number ĊĠĠĠĠĠĠĠ Ġthis . previous Sending Chain Length Ġ= Ġsession State . previous Sending Chain Length ĊĠĠĠĠĠĠĠ Ġthis . message Key Cache Ġ= Ġmessage Key Cache ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ Experimental Unsigned Types ĊĠĠĠ Ġfun Ġencrypt ( plaintext : ĠByteArray , Ġassociated Data : ĠByteArray ? Ġ= Ġnull ): ĠMessage Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġmessage Key Ġ= Ġsending Chain . next Message Key () ĊĠĠĠĠĠĠĠ Ġval Ġheader Ġ= ĠHeader ( root Chain . key Pair . publicKey , Ġprevious Sending Chain Length , ĠsendMessage Number ) ĊĊĠĠĠĠĠĠĠ ĠsendMessage Number ++ ĊĊĠĠĠĠĠĠĠ Ġvar Ġheader Data Ġ= Ġheader . bytes (). as ByteArray () ĊĠĠĠĠĠĠĠ Ġassociated Data ?. let Ġ{ Ġheader Data Ġ+= Ġit Ġ} ĊĊĠĠĠĠĠĠĠ Ġval Ġnonce Ġ= Ġs odium . nonce ( AE AD . X CH ACH A 2 0 POLY 1 3 0 5 _ I ET F _ NP UB BYTES ) ĊĠĠĠĠĠĠĠ Ġval Ġcipher Ġ= ĠByteArray ( plaintext . size Ġ+ ĠAE AD . X CH ACH A 2 0 POLY 1 3 0 5 _ I ET F _ AB Y TES ) ĊĠĠĠĠĠĠĠ Ġs odium . crypto A ead X Ch a Ch a 2 0 Poly 1 3 0 5 I et f Encrypt ( cipher , Ġnull , Ġplaintext , Ġplaintext . size . to Long (), Ġheader Data , Ġheader Data . size . to Long (), Ġnull , Ġnonce , Ġmessage Key . as Bytes ) ĊĊĠĠĠĠĠĠĠ Ġval Ġnonce And Cipher Ġ= Ġnonce Ġ+ Ġcipher ĊĠĠĠĠĠĠĠ Ġreturn ĠMessage ( header , Ġnonce And Cipher ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ Experimental Unsigned Types ĊĠĠĠ Ġ@ Experimental Std lib Api ĊĠĠĠ Ġsuspend Ġfun Ġdecrypt ( message : ĠMessage , Ġassociated Data : ĠByteArray ? Ġ= Ġnull ): ĠByteArray Ġ{ ĊĠĠĠĠĠĠĠ Ġmessage Key Cache ?. getMessage Key ( message . header . message Number , Ġmessage . header . publicKey . as Bytes )?. let Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġdecrypt ( message , ĠKey . from Bytes ( it ), Ġassociated Data ) ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġif Ġ( message . header . publicKey Ġ== Ġroot Chain . remote PublicKey Ġ&& ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġmessage . header . message Number Ġ< Ġreceived Message Number ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġthrow ĠD RE rror . Discard Old Message Exception () ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġval Ġremote PublicKey Ġ= Ġroot Chain . remote PublicKey Ġ?: Ġmessage . header . publicKey ĊĠĠĠĠĠĠĠ Ġif Ġ( message . header . publicKey Ġ!= Ġroot Chain . remote PublicKey ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġskip Received Messages ( message . header . numberOf Messages In Previous Sending Chain , Ġremote PublicKey ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġdouble Rat chet Step ( message . header . publicKey ) ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġskip Received Messages ( message . header . message Number , Ġmessage . header . publicKey ) ĊĊĠĠĠĠĠĠĠ Ġval Ġmessage Key Ġ= Ġreceiving Chain . next Message Key () ĊĠĠĠĠĠĠĠ Ġval Ġplaintext Ġ= Ġdecrypt ( message , Ġmessage Key , Ġassociated Data ) ĊĠĠĠĠĠĠĠ Ġreceived Message Number ++ ĊĠĠĠĠĠĠĠ Ġreturn Ġplaintext ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ Experimental Unsigned Types ĊĠĠĠ Ġprivate Ġfun Ġdecrypt ( message : ĠMessage , Ġkey : ĠKey , Ġassociated Data : ĠByteArray ?): ĠByteArray Ġ{ ĊĠĠĠĠĠĠĠ Ġvar Ġheader Data Ġ= Ġmessage . header . bytes (). toByteArray () ĊĠĠĠĠĠĠĠ Ġassociated Data ?. let Ġ{ Ġheader Data Ġ+= Ġit Ġ} ĊĊĠĠĠĠĠĠĠ Ġval Ġnonce Ġ= Ġmessage . cipher . slice Array ( 0 Ġuntil ĠAE AD . X CH ACH A 2 0 POLY 1 3 0 5 _ I ET F _ NP UB BYTES ) ĊĠĠĠĠĠĠĠ Ġval Ġcipher Ġ= Ġmessage . cipher . slice Array ( AE AD . X CH ACH A 2 0 POLY 1 3 0 5 _ I ET F _ NP UB BYTES Ġuntil Ġmessage . cipher . size ) ĊĊĠĠĠĠĠĠĠ Ġval Ġplaintext Length Ġ= Ġcipher . size Ġ- ĠAE AD . X CH ACH A 2 0 POLY 1 3 0 5 _ I ET F _ AB Y TES ĊĠĠĠĠĠĠĠ Ġval Ġplaintext Ġ= ĠByteArray ( plaintext Length ) ĊĠĠĠĠĠĠĠ Ġs odium . crypto A ead X Ch a Ch a 2 0 Poly 1 3 0 5 I et f Decrypt ( plaintext , Ġnull , Ġnull , Ġcipher , Ġcipher . size . to Long (), Ġheader Data , Ġheader Data . size . to Long (), Ġnonce , Ġkey . as Bytes ) ĊĠĠĠĠĠĠĠ Ġreturn Ġplaintext ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ Experimental Std lib Api ĊĠĠĠ Ġprivate Ġsuspend Ġfun Ġskip Received Messages ( next Message Number : ĠInt , Ġremote PublicKey : ĠKey ) Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ( next Message Number Ġ- Ġreceived Message Number Ġ> Ġmax Skip ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġthrow ĠD RE rror . Exceeded Max Skip Exception () ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġwhile Ġ( received Message Number Ġ< Ġnext Message Number ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġskipped Message Key Ġ= Ġreceiving Chain . next Message Key () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġmessage Key Cache ?. add ( skipped Message Key . as Bytes , Ġreceived Message Number , Ġremote PublicKey . as Bytes ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreceived Message Number ++ ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġdouble Rat chet Step ( publicKey : ĠKey ) Ġ{ ĊĠĠĠĠĠĠĠ Ġprevious Sending Chain Length Ġ= ĠsendMessage Number ĊĠĠĠĠĠĠĠ ĠsendMessage Number Ġ= Ġ 0 ĊĠĠĠĠĠĠĠ Ġreceived Message Number Ġ= Ġ 0 ĊĊĠĠĠĠĠĠĠ Ġroot Chain . remote PublicKey Ġ= ĠpublicKey ĊĊĠĠĠĠĠĠĠ Ġreceiving Chain . chain Key Ġ= Ġroot Chain . rat chet Step ( Side . RECE IV ING ) ĊĊĠĠĠĠĠĠĠ Ġroot Chain . key Pair Ġ= Ġs odium . crypto Kx Key pair () ĊĊĠĠĠĠĠĠĠ Ġsending Chain . chain Key Ġ= Ġroot Chain . rat chet Step ( Side . SEND ING ) ĊĠĠĠ Ġ} Ċ }