import Ġjava . lang . IllegalStateException Ċ import Ġkotlin . Throws Ċ import Ġjava . io . IOException Ċ import Ġjava . io . File Ċ import Ġjava . io . FileInputStream Ċ import Ġjava . nio . ByteBuffer Ċ import Ġjava . nio . Byte Order Ċ import Ġjava . nio . charset . StandardCharsets Ċ import Ġkotlin . jvm . Jvm Over loads Ċ Ċ /** Ċ Ġ* Ċ Ġ* ĠM ah di S ml . ir Ċ Ġ* ĠM ah di ĠS af ar mo ham mad lo o Ċ Ġ* Ċ Ġ* ĠSpecial ĠThanks Ġto Ġr ct c wy vr n Ġ! Ċ Ġ* ĠHe ĠTrans lated ĠBl ake 3 Ġreference Ġimplementation Ġfrom ĠRust Ġto ĠJava Ċ Ġ* ĠAND Ċ Ġ* Ġi Ġoptimized Ġand Ġtranslated Ġit Ġto ĠKotlin Ċ Ġ* Ċ Ġ*/ Ċ class ĠS ML BL A KE 3 Ġ{ ĊĠĠĠ Ġ// ĠNode Ġof Ġthe ĠBl ake 3 Ġhash Ġtree ĊĠĠĠ Ġ// ĠIs Ġeither Ġchained Ġinto Ġthe Ġnext Ġnode Ġusing Ġchaining Value () ĊĠĠĠ Ġ// ĠOr Ġused Ġto Ġcalculate Ġthe Ġhash Ġdigest Ġusing Ġroot Output Bytes () ĊĠĠĠ Ġprivate Ġclass ĠNode ( ĊĠĠĠĠĠĠĠ Ġvar Ġinput Ch aining Value : ĠInt Array , ĊĠĠĠĠĠĠĠ Ġvar Ġblock Words : ĠInt Array , ĊĠĠĠĠĠĠĠ Ġvar Ġcounter : ĠLong , ĊĠĠĠĠĠĠĠ Ġvar Ġblock Len : ĠInt , ĊĠĠĠĠĠĠĠ Ġvar Ġflags : ĠInt ĊĠĠĠ Ġ) Ġ{ ĊĠĠĠĠĠĠĠ Ġ// ĠReturn Ġthe Ġ 8 Ġint ĠCV ĊĠĠĠĠĠĠĠ Ġfun Ġchaining Value (): ĠInt Array Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġcompress ( input Ch aining Value , Ġblock Words , Ġcounter , Ġblock Len , Ġflags ). copyOf Range ( 0 , Ġ 8 ) ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġfun Ġroot Output Bytes ( out Len : ĠInt ): ĠByteArray Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġvar Ġoutput Counter Ġ= Ġ 0 ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġoutputs Needed Ġ= ĠMath . floor Div ( out Len , Ġ 2 Ġ* ĠOUT _ LEN ) Ġ+ Ġ 1 ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġhash Ġ= ĠByteArray ( out Len ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġvar Ġi Ġ= Ġ 0 ĊĠĠĠĠĠĠĠĠĠĠĠ Ġwhile Ġ( output Counter Ġ< Ġoutputs Needed ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġwords Ġ= Ġcompress ( input Ch aining Value , Ġblock Words , Ġoutput Counter . to Long (), Ġblock Len , Ġflags Ġor ĠROOT ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġfor Ġ( word Ġin Ġwords ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġfor Ġ( b Ġin ĠByteBuffer . allocate ( 4 ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. order ( Byte Order . LIT TLE _ ENDIAN ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. put Int ( word ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. array ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġhash [ i ] Ġ= Ġb ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġi Ġ+= Ġ 1 ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( i Ġ== Ġout Len ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġhash ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġoutput Counter Ġ+= Ġ 1 ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġthrow ĠIllegalStateException (" Uh Ġoh Ġsomething Ġhas Ġgone Ġhor rib ly Ġwrong .") ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ// ĠHelper Ġobject Ġfor Ġcreating Ġnew ĠNodes Ġand Ġchaining Ġthem ĊĠĠĠ Ġprivate Ġclass ĠChunk State ( var Ġchaining Value : ĠInt Array , Ġvar Ġchunk Counter : ĠLong , Ġvar Ġflags : ĠInt ) Ġ{ ĊĠĠĠĠĠĠĠ Ġvar Ġblock Ġ= ĠByteArray ( BLOCK _ LEN ) ĊĠĠĠĠĠĠĠ Ġvar Ġblock Len : ĠInt Ġ= Ġ 0 ĊĠĠĠĠĠĠĠ Ġvar Ġblocks Compressed : ĠInt Ġ= Ġ 0 ĊĠĠĠĠĠĠĠ Ġfun Ġlen (): ĠInt Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĠBLOCK _ LEN Ġ* Ġblocks Compressed Ġ+ Ġblock Len ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġprivate Ġfun Ġstart Flag (): ĠInt Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġif Ġ( blocks Compressed Ġ== Ġ 0 ) ĠCH UNK _ START Ġelse Ġ 0 ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġfun Ġupdate ( input : ĠByteArray ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġvar Ġcurr Pos Ġ= Ġ 0 ĊĠĠĠĠĠĠĠĠĠĠĠ Ġwhile Ġ( currPos Ġ< Ġinput . size ) Ġ{ ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠChain Ġthe Ġnext Ġ 6 4 Ġbyte Ġblock Ġinto Ġthis Ġchunk / node ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( block Len Ġ== ĠBLOCK _ LEN ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġblock Words Ġ= Ġwords From LE Bytes ( block ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġchaining Value Ġ= Ġcompress ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġchaining Value , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġblock Words , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġchunk Counter , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠBLOCK _ LEN , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġflags Ġor Ġstart Flag () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ). copyOf Range ( 0 , Ġ 8 ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġblocks Compressed Ġ+= Ġ 1 ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġblock Ġ= ĠByteArray ( BLOCK _ LEN ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġblock Len Ġ= Ġ 0 ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠTake Ġbytes Ġout Ġof Ġthe Ġinput Ġand Ġupdate ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġwant Ġ= ĠBLOCK _ LEN Ġ- Ġblock Len Ġ// ĠHow Ġmany Ġbytes Ġwe Ġneed Ġto Ġfill Ġup Ġthe Ġcurrent Ġblock ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġcan Take Ġ= Ġwant . coerce At Most ( input . size Ġ- Ġcurr Pos ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠSystem . arraycopy ( input , Ġcurr Pos , Ġblock , Ġblock Len , Ġcan Take ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġblock Len Ġ+= Ġcan Take ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcurr Pos Ġ+= Ġcan Take ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġfun Ġcreate Node (): ĠNode Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĠNode ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġchaining Value , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġwords From LE Bytes ( block ), ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġchunk Counter , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġblock Len . toInt (), ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġflags Ġor Ġstart Flag () Ġor ĠCH UNK _ END ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ// ĠHash er ĊĠĠĠ Ġprivate Ġvar Ġchunk State : ĠChunk State ? Ġ= Ġnull ĊĠĠĠ Ġprivate Ġlateinit Ġvar Ġkey : ĠInt Array ĊĠĠĠ Ġprivate Ġval Ġcv Stack Ġ= ĠarrayOf Null s < IntArray >( 5 4 ) ĊĠĠĠ Ġprivate Ġvar Ġcv Stack Len : ĠInt Ġ= Ġ 0 ĊĠĠĠ Ġprivate Ġvar Ġflags Ġ= Ġ 0 ĊĊĠĠĠ Ġprivate Ġconstructor () Ġ{ ĊĠĠĠĠĠĠĠ Ġinitialize ( IV , Ġ 0 ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġconstructor ( key : ĠByteArray ) Ġ{ ĊĠĠĠĠĠĠĠ Ġinitialize ( words From LE Bytes ( key ), ĠKEY ED _ HASH ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġconstructor ( context : ĠString ) Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġcontext Hash er Ġ= ĠS ML BL A KE 3 () ĊĠĠĠĠĠĠĠ Ġcontext Hash er . initialize ( IV , ĠD ER IVE _ KEY _ CONTEXT ) ĊĠĠĠĠĠĠĠ Ġcontext Hash er . update ( context . toByteArray ( StandardCharsets . UTF _ 8 )) ĊĠĠĠĠĠĠĠ Ġval Ġcontext Key Ġ= Ġwords From LE Bytes ( context Hash er . digest ()) ĊĠĠĠĠĠĠĠ Ġinitialize ( context Key , ĠD ER IVE _ KEY _ MAT ERIAL ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġinitialize ( key : ĠInt Array , Ġflags : ĠInt ) Ġ{ ĊĠĠĠĠĠĠĠ Ġchunk State Ġ= ĠChunk State ( key , Ġ 0 , Ġflags ) ĊĠĠĠĠĠĠĠ Ġthis . key Ġ= Ġkey ĊĠĠĠĠĠĠĠ Ġthis . flags Ġ= Ġflags ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠAppend Ġthe Ġbyte Ġcontents Ġof Ġthe Ġfile Ġto Ġthe Ġhash Ġtree ĊĠĠĠĠ Ġ* Ġ@ param Ġfile ĠFile Ġto Ġbe Ġadded ĊĠĠĠĠ Ġ* Ġ@ throws ĠIOException ĠIf Ġthe Ġfile Ġdoes Ġnot Ġexist ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġ@ Throws ( IOException :: class ) ĊĠĠĠ Ġfun Ġupdate ( file : ĠFile ) Ġ{ ĊĠĠĠĠĠĠĠ Ġ// ĠUpdate Ġthe Ġhash er Ġ 4 kb Ġat Ġa Ġtime Ġto Ġavoid Ġmemory Ġissues Ġwhen Ġhashing Ġlarge Ġfiles ĊĠĠĠĠĠĠĠ ĠFileInputStream ( file ). use Ġ{ Ġios Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġbuffer Ġ= ĠByteArray ( 4 0 9 6 ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġvar Ġread Ġ= Ġ 0 ĊĠĠĠĠĠĠĠĠĠĠĠ Ġwhile Ġ( ios . read ( buffer ). also Ġ{ Ġread Ġ= Ġit Ġ} Ġ!= Ġ- 1 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( read Ġ== Ġbuffer . size ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġupdate ( buffer ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġupdate ( buffer . copyOf Range ( 0 , Ġread )) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠApp ends Ġnew Ġdata Ġto Ġthe Ġhash Ġtree ĊĠĠĠĠ Ġ* Ġ@ param Ġinput ĠData Ġto Ġbe Ġadded ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġfun Ġupdate ( input : ĠByteArray ) Ġ{ ĊĠĠĠĠĠĠĠ Ġvar Ġcurr Pos Ġ= Ġ 0 ĊĠĠĠĠĠĠĠ Ġwhile Ġ( currPos Ġ< Ġinput . size ) Ġ{ ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠIf Ġthis Ġchunk Ġhas Ġchained Ġin Ġ 1 6 Ġ 6 4 Ġbytes Ġof Ġinput , Ġadd Ġits ĠCV Ġto Ġthe Ġstack ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( chunk State !!. len () Ġ== ĠCH UNK _ LEN ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġchunk CV Ġ= Ġchunk State !!. createNode (). chaining Value () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġtotal Chunks Ġ= Ġchunk State !!. chunk Counter Ġ+ Ġ 1 ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġadd Chunk Ch aining Value ( chunk CV , Ġtotal Chunks ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġchunk State Ġ= ĠChunk State ( key , Ġtotal Chunks , Ġflags ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġwant Ġ= ĠCH UNK _ LEN Ġ- Ġchunk State !!. len () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġtake Ġ= Ġwant . coerce At Most ( input . size Ġ- Ġcurr Pos ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġchunk State !!. update ( input . copyOf Range ( currPos , Ġcurr Pos Ġ+ Ġtake )) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġcurr Pos Ġ+= Ġtake ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠGenerate Ġthe Ġbl ake 3 Ġhash Ġfor Ġthe Ġcurrent Ġtree Ġwith Ġthe Ġgiven Ġbyte Ġlength ĊĠĠĠĠ Ġ* Ġ@ param Ġhash Len ĠThe Ġnumber Ġof Ġbytes Ġof Ġhash Ġto Ġreturn ĊĠĠĠĠ Ġ* Ġ@ return ĠThe Ġbyte Ġarray Ġrepresenting Ġthe Ġhash ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠGenerate Ġthe Ġbl ake 3 Ġhash Ġfor Ġthe Ġcurrent Ġtree Ġwith Ġthe Ġdefault Ġbyte Ġlength Ġof Ġ 3 2 ĊĠĠĠĠ Ġ* Ġ@ return ĠThe Ġbyte Ġarray Ġrepresenting Ġthe Ġhash ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġ@ Jvm Over loads ĊĠĠĠ Ġfun Ġdigest ( hash Len : ĠInt Ġ= ĠDEFAULT _ HASH _ LEN ): ĠByteArray Ġ{ ĊĠĠĠĠĠĠĠ Ġvar Ġnode Ġ= Ġchunk State !!. createNode () ĊĠĠĠĠĠĠĠ Ġvar Ġparent Nodes Remaining Ġ= Ġcv Stack Len . toInt () ĊĠĠĠĠĠĠĠ Ġwhile Ġ( parent Nodes Remaining Ġ> Ġ 0 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġparent Nodes Remaining Ġ-= Ġ 1 ĊĠĠĠĠĠĠĠĠĠĠĠ Ġnode Ġ= Ġparent Node ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcv Stack [ parent Nodes Remaining ], ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġnode . chaining Value (), ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġkey , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġflags ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġreturn Ġnode . root Output Bytes ( hash Len ) ĊĠĠĠ Ġ} ĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠGenerate Ġthe Ġbl ake 3 Ġhash Ġfor Ġthe Ġcurrent Ġtree Ġwith Ġthe Ġgiven Ġbyte Ġlength ĊĠĠĠĠ Ġ* Ġ@ param Ġhash Len ĠThe Ġnumber Ġof Ġbytes Ġof Ġhash Ġto Ġreturn ĊĠĠĠĠ Ġ* Ġ@ return ĠThe Ġhex Ġstring Ġrepresenting Ġthe Ġhash ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠGenerate Ġthe Ġbl ake 3 Ġhash Ġfor Ġthe Ġcurrent Ġtree Ġwith Ġthe Ġdefault Ġbyte Ġlength Ġof Ġ 3 2 ĊĠĠĠĠ Ġ* Ġ@ return ĠThe Ġhex Ġstring Ġrepresenting Ġthe Ġhash ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġ@ Jvm Over loads ĊĠĠĠ Ġfun Ġhex digest ( hash Len : ĠInt Ġ= ĠDEFAULT _ HASH _ LEN ): ĠString Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn Ġbytes To Hex ( digest ( hash Len )) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġpush Stack ( cv : ĠInt Array ) Ġ{ ĊĠĠĠĠĠĠĠ Ġcv Stack [ cv Stack Len ] Ġ= Ġcv ĊĠĠĠĠĠĠĠ Ġcv Stack Len Ġ+= Ġ 1 ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġpop Stack (): ĠInt Array ? Ġ{ ĊĠĠĠĠĠĠĠ Ġcv Stack Len Ġ-= Ġ 1 ĊĠĠĠĠĠĠĠ Ġreturn Ġcv Stack [ cv Stack Len ] ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġadd Chunk Ch aining Value ( new CV : ĠInt Array , Ġtotal Chunks : ĠLong ) Ġ{ ĊĠĠĠĠĠĠĠ Ġvar Ġnew CV Ġ= Ġnew CV ĊĠĠĠĠĠĠĠ Ġvar Ġtotal Chunks Ġ= Ġtotal Chunks ĊĠĠĠĠĠĠĠ Ġwhile Ġ( total Chunks Ġand Ġ 1 Ġ== Ġ 0 L ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġnew CV Ġ= Ġparent CV ( pop Stack (), Ġnew CV , Ġkey , Ġflags ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġtotal Chunks Ġ= Ġtotal Chunks Ġshr Ġ 1 ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġpush Stack ( new CV ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġcompanion Ġobject Ġ{ ĊĠĠĠĠĠĠĠ Ġprivate Ġval ĠHEX _ ARRAY Ġ= Ġ" 0 1 2 3 4 5 6 7 8 9 abcdef ". toCharArray () ĊĠĠĠĠĠĠĠ Ġprivate Ġconst Ġval ĠDEFAULT _ HASH _ LEN Ġ= Ġ 3 2 ĊĠĠĠĠĠĠĠ Ġprivate Ġconst Ġval ĠOUT _ LEN Ġ= Ġ 3 2 ĊĠĠĠĠĠĠĠ Ġprivate Ġconst Ġval ĠKEY _ LEN Ġ= Ġ 3 2 ĊĠĠĠĠĠĠĠ Ġprivate Ġconst Ġval ĠBLOCK _ LEN Ġ= Ġ 6 4 ĊĠĠĠĠĠĠĠ Ġprivate Ġconst Ġval ĠCH UNK _ LEN Ġ= Ġ 1 0 2 4 ĊĠĠĠĠĠĠĠ Ġprivate Ġconst Ġval ĠCH UNK _ START Ġ= Ġ 1 ĊĠĠĠĠĠĠĠ Ġprivate Ġconst Ġval ĠCH UNK _ END Ġ= Ġ 2 ĊĠĠĠĠĠĠĠ Ġprivate Ġconst Ġval ĠP ARENT Ġ= Ġ 4 ĊĠĠĠĠĠĠĠ Ġprivate Ġconst Ġval ĠROOT Ġ= Ġ 8 ĊĠĠĠĠĠĠĠ Ġprivate Ġconst Ġval ĠKEY ED _ HASH Ġ= Ġ 1 6 ĊĠĠĠĠĠĠĠ Ġprivate Ġconst Ġval ĠD ER IVE _ KEY _ CONTEXT Ġ= Ġ 3 2 ĊĠĠĠĠĠĠĠ Ġprivate Ġconst Ġval ĠD ER IVE _ KEY _ MAT ERIAL Ġ= Ġ 6 4 ĊĠĠĠĠĠĠĠ Ġprivate Ġval ĠIV Ġ= Ġint ArrayOf ( ĊĠĠĠĠĠĠĠĠĠĠĠĠ 0 x 6 A 0 9 E 6 6 7 , Ġ- 0 x 4 4 9 8 5 1 7 b , Ġ 0 x 3 C 6 EF 3 7 2 , Ġ- 0 x 5 ab 0 0 ac 6 , Ġ 0 x 5 1 0 E 5 2 7 F , Ġ- 0 x 6 4 fa 9 7 7 4 , Ġ 0 x 1 F 8 3 D 9 AB , Ġ 0 x 5 BE 0 CD 1 9 ĊĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠ Ġprivate Ġval ĠMSG _ PER MUT ATION Ġ= Ġint ArrayOf ( ĊĠĠĠĠĠĠĠĠĠĠĠĠ 2 , Ġ 6 , Ġ 3 , Ġ 1 0 , Ġ 7 , Ġ 0 , Ġ 4 , Ġ 1 3 , Ġ 1 , Ġ 1 1 , Ġ 1 2 , Ġ 5 , Ġ 9 , Ġ 1 4 , Ġ 1 5 , Ġ 8 ĊĠĠĠĠĠĠĠ Ġ) ĊĊĠĠĠĠĠĠĠ Ġprivate Ġfun Ġwrapping Add ( a : ĠInt , Ġb : ĠInt ): ĠInt Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġa Ġ+ Ġb ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġprivate Ġfun Ġrotate Right ( x : ĠInt , Ġlen : ĠInt ): ĠInt Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġx Ġ ush r Ġlen Ġor Ġ( x Ġshl Ġ 3 2 Ġ- Ġlen ) ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġprivate Ġfun Ġg ( state : ĠInt Array , Ġa : ĠInt , Ġb : ĠInt , Ġc : ĠInt , Ġd : ĠInt , Ġmx : ĠInt , Ġmy : ĠInt ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġstate [ a ] Ġ= Ġwrapping Add ( wrapping Add ( state [ a ], Ġstate [ b ]), Ġmx ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġstate [ d ] Ġ= Ġrotate Right ( state [ d ] Ġxor Ġstate [ a ], Ġ 1 6 ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġstate [ c ] Ġ= Ġwrapping Add ( state [ c ], Ġstate [ d ]) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġstate [ b ] Ġ= Ġrotate Right ( state [ b ] Ġxor Ġstate [ c ], Ġ 1 2 ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġstate [ a ] Ġ= Ġwrapping Add ( wrapping Add ( state [ a ], Ġstate [ b ]), Ġmy ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġstate [ d ] Ġ= Ġrotate Right ( state [ d ] Ġxor Ġstate [ a ], Ġ 8 ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġstate [ c ] Ġ= Ġwrapping Add ( state [ c ], Ġstate [ d ]) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġstate [ b ] Ġ= Ġrotate Right ( state [ b ] Ġxor Ġstate [ c ], Ġ 7 ) ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġprivate Ġfun Ġround Fn ( state : ĠInt Array , Ġm : ĠInt Array ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠMix Ġcolumns ĊĠĠĠĠĠĠĠĠĠĠĠ Ġg ( state , Ġ 0 , Ġ 4 , Ġ 8 , Ġ 1 2 , Ġm [ 0 ], Ġm [ 1 ]) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġg ( state , Ġ 1 , Ġ 5 , Ġ 9 , Ġ 1 3 , Ġm [ 2 ], Ġm [ 3 ]) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġg ( state , Ġ 2 , Ġ 6 , Ġ 1 0 , Ġ 1 4 , Ġm [ 4 ], Ġm [ 5 ]) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġg ( state , Ġ 3 , Ġ 7 , Ġ 1 1 , Ġ 1 5 , Ġm [ 6 ], Ġm [ 7 ]) ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠMix Ġdiag on als ĊĠĠĠĠĠĠĠĠĠĠĠ Ġg ( state , Ġ 0 , Ġ 5 , Ġ 1 0 , Ġ 1 5 , Ġm [ 8 ], Ġm [ 9 ]) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġg ( state , Ġ 1 , Ġ 6 , Ġ 1 1 , Ġ 1 2 , Ġm [ 1 0 ], Ġm [ 1 1 ]) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġg ( state , Ġ 2 , Ġ 7 , Ġ 8 , Ġ 1 3 , Ġm [ 1 2 ], Ġm [ 1 3 ]) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġg ( state , Ġ 3 , Ġ 4 , Ġ 9 , Ġ 1 4 , Ġm [ 1 4 ], Ġm [ 1 5 ]) ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġprivate Ġfun Ġperm ute ( m : ĠInt Array ): ĠInt Array Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġper muted Ġ= ĠInt Array ( 1 6 ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġfor Ġ( i Ġin Ġ 0 .. 1 5 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġper muted [ i ] Ġ= Ġm [ MSG _ PER MUT ATION [ i ]] ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġper muted ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġprivate Ġfun Ġcompress ( ĊĠĠĠĠĠĠĠĠĠĠĠ Ġchaining Value : ĠInt Array , ĊĠĠĠĠĠĠĠĠĠĠĠ Ġblock Words : ĠInt Array , ĊĠĠĠĠĠĠĠĠĠĠĠ Ġcounter : ĠLong , ĊĠĠĠĠĠĠĠĠĠĠĠ Ġblock Len : ĠInt , ĊĠĠĠĠĠĠĠĠĠĠĠ Ġflags : ĠInt ĊĠĠĠĠĠĠĠ Ġ): ĠInt Array Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġvar Ġblock Words Ġ= Ġblock Words ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġcounter Int Ġ= Ġ( counter Ġand Ġ 0 xffffffff L ). toInt () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġcounter Shift Ġ= Ġ( counter Ġshr Ġ 3 2 Ġand Ġ 0 xffffffff L ). toInt () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġstate Ġ= Ġint ArrayOf ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġchaining Value [ 0 ], ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġchaining Value [ 1 ], ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġchaining Value [ 2 ], ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġchaining Value [ 3 ], ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġchaining Value [ 4 ], ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġchaining Value [ 5 ], ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġchaining Value [ 6 ], ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġchaining Value [ 7 ], ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠIV [ 0 ], ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠIV [ 1 ], ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠIV [ 2 ], ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠIV [ 3 ], ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcounter Int , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcounter Shift , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġblock Len , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġflags ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġround Fn ( state , Ġblock Words ) Ġ// ĠRound Ġ 1 ĊĠĠĠĠĠĠĠĠĠĠĠ Ġblock Words Ġ= Ġperm ute ( block Words ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġround Fn ( state , Ġblock Words ) Ġ// ĠRound Ġ 2 ĊĠĠĠĠĠĠĠĠĠĠĠ Ġblock Words Ġ= Ġperm ute ( block Words ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġround Fn ( state , Ġblock Words ) Ġ// ĠRound Ġ 3 ĊĠĠĠĠĠĠĠĠĠĠĠ Ġblock Words Ġ= Ġperm ute ( block Words ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġround Fn ( state , Ġblock Words ) Ġ// ĠRound Ġ 4 ĊĠĠĠĠĠĠĠĠĠĠĠ Ġblock Words Ġ= Ġperm ute ( block Words ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġround Fn ( state , Ġblock Words ) Ġ// ĠRound Ġ 5 ĊĠĠĠĠĠĠĠĠĠĠĠ Ġblock Words Ġ= Ġperm ute ( block Words ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġround Fn ( state , Ġblock Words ) Ġ// ĠRound Ġ 6 ĊĠĠĠĠĠĠĠĠĠĠĠ Ġblock Words Ġ= Ġperm ute ( block Words ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġround Fn ( state , Ġblock Words ) Ġ// ĠRound Ġ 7 ĊĠĠĠĠĠĠĠĠĠĠĠ Ġfor Ġ( i Ġin Ġ 0 .. 7 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġstate [ i ] Ġ= Ġstate [ i ] Ġxor Ġstate [ i Ġ+ Ġ 8 ] ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġstate [ i Ġ+ Ġ 8 ] Ġ= Ġstate [ i Ġ+ Ġ 8 ] Ġxor Ġchaining Value [ i ] ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġstate ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġprivate Ġfun Ġwords From LE Bytes ( bytes : ĠByteArray ): ĠInt Array Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġwords Ġ= ĠInt Array ( bytes . size Ġ/ Ġ 4 ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġbuf Ġ= ĠByteBuffer . wrap ( bytes ). order ( Byte Order . LIT TLE _ ENDIAN ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġfor Ġ( i Ġin Ġwords . indices ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġwords [ i ] Ġ= Ġbuf . int ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġwords ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġ// ĠCombin es Ġthe Ġchaining Ġvalues Ġof Ġtwo Ġchildren Ġto Ġcreate Ġthe Ġparent Ġnode ĊĠĠĠĠĠĠĠ Ġprivate Ġfun Ġparent Node ( left Child CV : ĠInt Array ?, Ġright Child CV : ĠInt Array , Ġkey : ĠInt Array , Ġflags : ĠInt ): ĠNode Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġblock Words Ġ= ĠInt Array ( 1 6 ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġvar Ġi Ġ= Ġ 0 ĊĠĠĠĠĠĠĠĠĠĠĠ Ġfor Ġ( x Ġin Ġleft Child CV !! ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġblock Words [ i ] Ġ= Ġx ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġi Ġ+= Ġ 1 ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġfor Ġ( x Ġin Ġright Child CV ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġblock Words [ i ] Ġ= Ġx ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġi Ġ+= Ġ 1 ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĠNode ( key , Ġblock Words , Ġ 0 , ĠBLOCK _ LEN , ĠP ARENT Ġor Ġflags ) ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġprivate Ġfun Ġparent CV ( left Child CV : ĠInt Array ?, Ġright Child CV : ĠInt Array , Ġkey : ĠInt Array , Ġflags : ĠInt ): ĠInt Array Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġparent Node ( left Child CV , Ġright Child CV , Ġkey , Ġflags ). chaining Value () ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġprivate Ġfun Ġbytes To Hex ( bytes : ĠByteArray ): ĠString Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġhex Chars Ġ= ĠChar Array ( bytes . size Ġ* Ġ 2 ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġfor Ġ( j Ġin Ġbytes . indices ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġv : ĠInt Ġ= Ġbytes [ j ]. toInt () Ġand Ġ 0 xFF ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġhex Chars [ j Ġ* Ġ 2 ] Ġ= ĠHEX _ ARRAY [ v Ġ ush r Ġ 4 ] ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġhex Chars [ j Ġ* Ġ 2 Ġ+ Ġ 1 ] Ġ= ĠHEX _ ARRAY [ v Ġand Ġ 0 x 0 F ] ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĠString ( hex Chars ) ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġ/** ĊĠĠĠĠĠĠĠĠ Ġ* ĠConstruct Ġa ĠB LA KE 3 Ġbl ake 3 Ġhash er ĊĠĠĠĠĠĠĠĠ Ġ*/ ĊĠĠĠĠĠĠĠ Ġfun Ġnew Instance (): ĠS ML BL A KE 3 Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĠS ML BL A KE 3 () ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġ/** ĊĠĠĠĠĠĠĠĠ Ġ* ĠConstruct Ġa Ġnew ĠB LA KE 3 Ġkey ed Ġmode Ġhash er ĊĠĠĠĠĠĠĠĠ Ġ* Ġ@ param Ġkey ĠThe Ġ 3 2 Ġbyte Ġkey ĊĠĠĠĠĠĠĠĠ Ġ* Ġ@ throws ĠIllegalStateException ĠIf Ġthe Ġkey Ġis Ġnot Ġ 3 2 Ġbytes ĊĠĠĠĠĠĠĠĠ Ġ*/ ĊĠĠĠĠĠĠĠ Ġfun Ġnew Key ed Hash er ( key : ĠByteArray ): ĠS ML BL A KE 3 Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġcheck ( key . size Ġ== ĠKEY _ LEN ) Ġ{ Ġ" Invalid Ġkey Ġlength " Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĠS ML BL A KE 3 ( key ) ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġ/** ĊĠĠĠĠĠĠĠĠ Ġ* ĠConstruct Ġa Ġnew ĠB LA KE 3 Ġkey Ġder ivation Ġmode Ġhash er ĊĠĠĠĠĠĠĠĠ Ġ* ĠThe Ġcontext Ġstring Ġshould Ġbe Ġhardcoded , Ġglobally Ġunique , Ġand Ġapplication - specific . Ġ< br ></ br >< br ></ br > ĊĠĠĠĠĠĠĠĠ Ġ* ĠA Ġgood Ġdefault Ġformat Ġis Ġ* "[ application ] Ġ[ commit Ġtimestamp ] Ġ[ purpose ]" *, Ġ< br ></ br > ĊĠĠĠĠĠĠĠĠ Ġ* Ġeg Ġ" example . com Ġ 2 0 1 9 - 1 2 - 2 5 Ġ 1 6 : 1 8 : 0 3 Ġsession Ġtokens Ġv 1 " ĊĠĠĠĠĠĠĠĠ Ġ* Ġ@ param Ġcontext ĠContext Ġstring Ġused Ġto Ġderive Ġkeys . ĊĠĠĠĠĠĠĠĠ Ġ*/ ĊĠĠĠĠĠĠĠ Ġfun Ġnew Key Der ivation Hash er ( context : ĠString ): ĠS ML BL A KE 3 Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĠS ML BL A KE 3 ( context ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} Ċ } Ċ