/* Ċ Ġ* ĠCopyright Ġ( c ) Ġ 2 0 0 0 - 2 0 2 1 ĠThe ĠLeg ion Ġof Ġthe ĠBo unc y ĠCast le ĠInc . Ġ( https :// www . bouncycastle . org ) Ċ Ġ* Ċ Ġ* ĠPermission Ġis Ġhereby Ġgranted , Ġfree Ġof Ġcharge , Ġto Ġany Ġperson Ġobtaining Ċ Ġ* Ġa Ġcopy Ġof Ġthis Ġsoftware Ġand Ġassociated Ġdocumentation Ġfiles Ġ( the Ċ Ġ* Ġ" Software "), Ġto Ġdeal Ġin Ġthe ĠSoftware Ġwithout Ġrestriction , Ġincluding Ċ Ġ* Ġwithout Ġlimitation Ġthe Ġrights Ġto Ġuse , Ġcopy , Ġmodify , Ġmerge , Ġpublish , Ċ Ġ* Ġdistribute , Ġsublicense , Ġand / or Ġsell Ġcopies Ġof Ġthe ĠSoftware , Ġand Ġto Ċ Ġ* Ġpermit Ġpersons Ġto Ġwhom Ġthe ĠSoftware Ġis Ġfurnished Ġto Ġdo Ġso , Ġsubject Ġto Ċ Ġ* Ġthe Ġfollowing Ġconditions : Ċ Ġ* Ċ Ġ* ĠThe Ġabove Ġcopyright Ġnotice Ġand Ġthis Ġpermission Ġnotice Ġshall Ġbe Ċ Ġ* Ġincluded Ġin Ġall Ġcopies Ġor Ġsubstantial Ġportions Ġof Ġthe ĠSoftware . Ċ Ġ* Ċ Ġ* ĠTHE ĠSOFTWARE ĠIS ĠPROVIDED Ġ" AS ĠIS ", ĠWITHOUT ĠWARRANTY ĠOF ĠANY ĠKIND , Ċ Ġ* ĠEXPRESS ĠOR ĠIMPLIED , ĠINCLUDING ĠBUT ĠNOT ĠLIMITED ĠTO ĠTHE ĠWARRANTIES ĠOF Ċ Ġ* ĠMERCHANTABILITY , ĠFITNESS ĠFOR ĠA ĠPARTICULAR ĠPURPOSE ĠAND ĠNONINFRINGEMENT . Ċ Ġ* ĠIN ĠNO ĠEVENT ĠSHALL ĠTHE ĠAUTHORS ĠOR ĠCOPYRIGHT ĠHOLDERS ĠBE ĠLIABLE ĠFOR ĠANY Ċ Ġ* ĠCLAIM , ĠDAMAGES ĠOR ĠOTHER ĠLIABILITY , ĠWHETHER ĠIN ĠAN ĠACTION ĠOF ĠCONTRACT , Ċ Ġ* ĠTORT ĠOR ĠOTHERWISE , ĠARISING ĠFROM , ĠOUT ĠOF ĠOR ĠIN ĠCONNECTION ĠWITH ĠTHE Ċ Ġ* ĠSOFTWARE ĠOR ĠTHE ĠUSE ĠOR ĠOTHER ĠDEALINGS ĠIN ĠTHE ĠSOFTWARE . Ċ Ġ* Ċ Ġ* ĠTranslation Ġto ĠKotlin : Ċ Ġ* Ċ Ġ* ĠCopyright Ġ 2 0 2 1 ĠApp mat t us ĠLimited Ċ Ġ* Ċ Ġ* ĠLicensed Ġunder Ġthe ĠApache ĠLicense , ĠVersion Ġ 2 . 0 Ġ( the Ġ" License "); Ċ Ġ* Ġyou Ġmay Ġnot Ġuse Ġthis Ġfile Ġexcept Ġin Ġcompliance Ġwith Ġthe ĠLicense . Ċ Ġ* ĠYou Ġmay Ġobtain Ġa Ġcopy Ġof Ġthe ĠLicense Ġat Ċ Ġ* Ċ Ġ* Ġhttp :// www . apache . org / licenses / LICENSE - 2 . 0 Ċ Ġ* Ċ Ġ* ĠUnless Ġrequired Ġby Ġapplicable Ġlaw Ġor Ġagreed Ġto Ġin Ġwriting , Ġsoftware Ċ Ġ* Ġdistributed Ġunder Ġthe ĠLicense Ġis Ġdistributed Ġon Ġan Ġ" AS ĠIS " ĠBASIS , Ċ Ġ* ĠWITHOUT ĠWARRANTIES ĠOR ĠCONDITIONS ĠOF ĠANY ĠKIND , Ġeither Ġexpress Ġor Ġimplied . Ċ Ġ* ĠSee Ġthe ĠLicense Ġfor Ġthe Ġspecific Ġlanguage Ġgoverning Ġpermissions Ġand Ċ Ġ* Ġlimitations Ġunder Ġthe ĠLicense . Ċ Ġ*/ Ċ Ċ package Ġcom . app mat t us . crypto . internal . core . bouncycastle . bl ake 2 Ċ Ċ /* Ċ ĠThe ĠB LA KE 2 Ġcrypto graphic Ġhash Ġfunction Ġwas Ġdesigned Ġby ĠJean - Ċ ĠPhil ippe ĠA um ass on , ĠSam uel ĠNe ves , ĠZ ook o ĠWil co x - O ' He arn , Ġand ĠChristian Ċ ĠW inner le in . ĊĊ ĠReference ĠImplementation Ġand ĠDescription Ġcan Ġbe Ġfound Ġat : Ġhttps :// bl ake 2 . net / Ċ ĠInternet ĠDraft : Ġhttps :// tools . ietf . org / html / draft - sa ar inen - bl ake 2 - 0 2 Ċ ĠThis Ġimplementation Ġdoes Ġnot Ġsupport Ġthe ĠTree ĠHash ing ĠMode . ĊĊĠĠ ĠFor Ġun keyed Ġhashing , Ġdevelopers Ġad ap ting ĠB LA KE 2 Ġto ĠASN . 1 Ġ- Ġbased ĊĠĠ Ġmessage Ġformats ĠSHO ULD Ġuse Ġthe ĠO ID Ġtree Ġat Ġx Ġ= Ġ 1 . 3 . 6 . 1 . 4 . 1 . 1 7 2 2 . 1 2 . 2 . ĊĠĠĠĠĠĠĠĠ ĠAlgorithm ĠĠĠĠ Ġ| ĠTarget Ġ| ĠCollision Ġ| ĠHash Ġ| ĠHash ĠASN . 1 Ġ| ĊĠĠĠĠĠĠĠĠĠĠĠ ĠIdentifier Ġ| Ġ ĠArch Ġ Ġ| Ġ ĠSecurity Ġ| Ġ Ġnn Ġ Ġ| ĠO ID ĠS uffix Ġ| ĊĠĠĠĠĠĠĠ Ġ--------------- + --------+ -----------+ ------+ ------------+ ĊĠĠĠĠĠĠĠĠ Ġid - bl ake 2 b 1 6 0 Ġ| Ġ 6 4 - bit Ġ| ĠĠĠ 2 ** 8 0 ĠĠ Ġ| ĠĠ 2 0 Ġ Ġ| ĠĠ Ġx . 1 . 2 0 ĠĠ Ġ| ĊĠĠĠĠĠĠĠĠ Ġid - bl ake 2 b 2 5 6 Ġ| Ġ 6 4 - bit Ġ| ĠĠĠ 2 ** 1 2 8 Ġ Ġ| ĠĠ 3 2 Ġ Ġ| ĠĠ Ġx . 1 . 3 2 ĠĠ Ġ| ĊĠĠĠĠĠĠĠĠ Ġid - bl ake 2 b 3 8 4 Ġ| Ġ 6 4 - bit Ġ| ĠĠĠ 2 ** 1 9 2 Ġ Ġ| ĠĠ 4 8 Ġ Ġ| ĠĠ Ġx . 1 . 4 8 ĠĠ Ġ| ĊĠĠĠĠĠĠĠĠ Ġid - bl ake 2 b 5 1 2 Ġ| Ġ 6 4 - bit Ġ| ĠĠĠ 2 ** 2 5 6 Ġ Ġ| ĠĠ 6 4 Ġ Ġ| ĠĠ Ġx . 1 . 6 4 ĠĠ Ġ| ĊĠĠĠĠĠĠĠ Ġ--------------- + --------+ -----------+ ------+ ------------+ Ċ Ġ*/ Ċ Ċ import Ġcom . app mat t us . crypto . Algorithm Ċ import Ġcom . app mat t us . crypto . Digest Ċ import Ġcom . app mat t us . crypto . internal . core . circular Right Long Ċ import Ġcom . app mat t us . crypto . internal . core . decode LE Long Ċ import Ġcom . app mat t us . crypto . internal . core . encode LE Long Ċ Ċ /** Ċ Ġ* ĠImplementation Ġof Ġthe Ġcrypto graphic Ġhash Ġfunction ĠBl ak be 2 b . Ċ Ġ* Ċ Ġ* ĠBl ake 2 b Ġoffers Ġa Ġbuilt - in Ġkey ing Ġmechanism Ġto Ġbe Ġused Ġdirectly Ċ Ġ* Ġfor Ġauthentication Ġ(" Prefix - MAC ") Ġrather Ġthan Ġa ĠHMAC Ġconstruction . Ċ Ġ* Ċ Ġ* ĠBl ake 2 b Ġoffers Ġa Ġbuilt - in Ġsupport Ġfor Ġa Ġsalt Ġfor Ġrandom ized Ġhashing Ċ Ġ* Ġand Ġa Ġpersonal Ġstring Ġfor Ġdefining Ġa Ġunique Ġhash Ġfunction Ġfor Ġeach Ġapplication . Ċ Ġ* Ċ Ġ* ĠB LA KE 2 b Ġis Ġoptimized Ġfor Ġ 6 4 - bit Ġplatforms Ġand Ġproduces Ġdigest s Ġof Ġany Ġsize Ċ Ġ* Ġbetween Ġ 1 Ġand Ġ 6 4 Ġbytes . Ċ Ġ*/ Ċ @ Suppress (" Magic Number ", Ġ" Long Parameter List ", Ġ" Too Many Functions ") Ċ internal Ġclass ĠBl ake 2 b Ġ: ĠDigest < Bl ake 2 b > Ġ{ ĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* Ġreturn Ġthe Ġsize , Ġin Ġbytes , Ġof Ġthe Ġdigest Ġproduced Ġby Ġthis Ġmessage Ġdigest . ĊĠĠĠĠ Ġ* ĊĠĠĠĠ Ġ* Ġ@ return Ġthe Ġsize , Ġin Ġbytes , Ġof Ġthe Ġdigest Ġproduced Ġby Ġthis Ġmessage Ġdigest . ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġ// ĠGeneral Ġparameters : ĊĠĠĠ Ġprivate Ġvar Ġdigest Size Ġ= Ġ 6 4 Ġ// Ġ 1 - Ġ 6 4 Ġbytes ĊĠĠĠ Ġprivate Ġvar Ġkey Length Ġ= Ġ 0 Ġ// Ġ 0 Ġ- Ġ 6 4 Ġbytes Ġfor Ġkey ed Ġhashing Ġfor ĠMAC ĊĠĠĠ Ġprivate Ġvar Ġsalt : ĠByteArray ? Ġ= Ġnull Ġ// Ġnew Ġbyte [ 1 6 ]; ĊĠĠĠ Ġprivate Ġvar Ġpersonal ization : ĠByteArray ? Ġ= Ġnull Ġ// Ġnew Ġbyte [ 1 6 ]; ĊĊĠĠĠ Ġ// Ġthe Ġkey ĊĠĠĠ Ġprivate Ġvar Ġkey : ĠByteArray ? Ġ= Ġnull ĊĊĠĠĠ Ġ// ĠTree Ġhashing Ġparameters : ĊĠĠĠ Ġ// ĠBecause Ġthis Ġclass Ġdoes Ġnot Ġimplement Ġthe ĠTree ĠHash ing ĠMode , ĊĠĠĠ Ġ// Ġthese Ġparameters Ġcan Ġbe Ġtreated Ġas Ġconstants Ġ( see Ġinit () Ġfunction ) ĊĠĠĠ Ġ/* Ċĉ Ġ* Ġprivate Ġint Ġfan out Ġ= Ġ 1 ; Ġ// Ġ 0 - 2 5 5 Ġprivate Ġint Ġdepth Ġ= Ġ 1 ; Ġ// Ġ 1 Ġ- Ġ 2 5 5 Ċĉ Ġ* Ġprivate Ġint Ġleaf Length = Ġ 0 ; Ġprivate Ġlong Ġnode Offset Ġ= Ġ 0 L ; Ġprivate Ġint Ċĉ Ġ* Ġnode Depth Ġ= Ġ 0 ; Ġprivate Ġint Ġinner Hash Length Ġ= Ġ 0 ; Ċĉ Ġ*/ ĊĠĠĠ Ġ// Ġwhenever Ġthis Ġbuffer Ġoverflow s , Ġit Ġwill Ġbe Ġprocessed ĊĠĠĠ Ġ// Ġin Ġthe Ġcompress () Ġfunction . ĊĠĠĠ Ġ// ĠFor Ġperformance Ġissues , Ġlong Ġmessages Ġwill Ġnot Ġuse Ġthis Ġbuffer . ĊĠĠĠ Ġprivate Ġvar Ġbuffer : ĠByteArray ? Ġ= Ġnull Ġ// Ġnew Ġbyte [ BLOCK _ LENGTH _ BYTES ]; ĊĊĠĠĠ Ġ// ĠPosition Ġof Ġlast Ġinserted Ġbyte : ĊĠĠĠ Ġprivate Ġvar Ġbuffer Pos Ġ= Ġ 0 Ġ// Ġa Ġvalue Ġfrom Ġ 0 Ġup Ġto Ġ 1 2 8 ĊĠĠĠ Ġprivate Ġval Ġinternal State Ġ= ĠLong Array ( 1 6 ) Ġ// ĠIn Ġthe ĠBl ake 2 b Ġpaper Ġit Ġis ĊĊĠĠĠ Ġ// Ġcalled : Ġv ĊĠĠĠ Ġprivate Ġvar Ġchain Value : ĠLong Array ? Ġ= Ġnull Ġ// Ġstate Ġvector , Ġin Ġthe ĠBl ake 2 b Ġpaper Ġit ĊĊĠĠĠ Ġ// Ġis Ġcalled : Ġh ĊĠĠĠ Ġprivate Ġvar Ġt 0 Ġ= Ġ 0 L Ġ// Ġholds Ġlast Ġsignificant Ġbits , Ġcounter Ġ( counts Ġbytes ) ĊĠĠĠ Ġprivate Ġvar Ġt 1 Ġ= Ġ 0 L Ġ// Ġcounter : ĠLength Ġup Ġto Ġ 2 ^ 1 2 8 Ġare Ġsupported ĊĠĠĠ Ġprivate Ġvar Ġf 0 Ġ= Ġ 0 L Ġ// Ġfinal ization Ġflag , Ġfor Ġlast Ġblock : Ġ~ 0 L ĊĊĠĠĠ Ġconstructor ( digest : ĠBl ake 2 b ) Ġ{ ĊĠĠĠĠĠĠĠ Ġbuffer Pos Ġ= Ġdigest . buffer Pos ĊĠĠĠĠĠĠĠ Ġbuffer Ġ= Ġdigest . buffer ?. copyOf () ĊĠĠĠĠĠĠĠ Ġkey Length Ġ= Ġdigest . key Length ĊĠĠĠĠĠĠĠ Ġkey Ġ= Ġdigest . key ?. copyOf () ĊĠĠĠĠĠĠĠ Ġdigest Size Ġ= Ġdigest . digest Size ĊĠĠĠĠĠĠĠ Ġchain Value Ġ= Ġdigest . chain Value ?. copyOf () ĊĠĠĠĠĠĠĠ Ġpersonal ization Ġ= Ġdigest . personal ization ?. copyOf () ĊĠĠĠĠĠĠĠ Ġsalt Ġ= Ġdigest . salt ?. copyOf () ĊĠĠĠĠĠĠĠ Ġt 0 Ġ= Ġdigest . t 0 ĊĠĠĠĠĠĠĠ Ġt 1 Ġ= Ġdigest . t 1 ĊĠĠĠĠĠĠĠ Ġf 0 Ġ= Ġdigest . f 0 ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠBasic Ġsized Ġconstructor Ġ- Ġsize Ġin Ġbits . ĊĠĠĠĠ Ġ* ĊĠĠĠĠ Ġ* Ġ@ param Ġdigest Size Ġsize Ġof Ġthe Ġdigest Ġin Ġbits ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġ// ĠFor ĠTree ĠHash ing ĠMode , Ġnot Ġused Ġhere : ĊĠĠĠ Ġ// Ġprivate Ġlong Ġf 1 Ġ= Ġ 0 L ; Ġ// Ġfinal ization Ġflag , Ġfor Ġlast Ġnode : Ġ~ 0 L ĊĠĠĠ Ġconstructor ( digest Size : ĠInt Ġ= Ġ 5 1 2 ) Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ( digest Size Ġ< Ġ 8 Ġ|| Ġdigest Size Ġ> Ġ 5 1 2 Ġ|| Ġdigest Size Ġ% Ġ 8 Ġ!= Ġ 0 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġthrow ĠIllegalArgumentException ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ" BL A KE 2 b Ġdigest Ġbit Ġlength Ġmust Ġbe Ġa Ġmultiple Ġof Ġ 8 Ġand Ġnot Ġgreater Ġthan Ġ 5 1 2 " ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġbuffer Ġ= ĠByteArray ( block Length ) ĊĠĠĠĠĠĠĠ Ġkey Length Ġ= Ġ 0 ĊĠĠĠĠĠĠĠ Ġthis . digest Size Ġ= Ġdigest Size Ġ/ Ġ 8 ĊĠĠĠĠĠĠĠ Ġinit () ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠBl ake 2 b Ġfor Ġauthentication Ġ(" Prefix - MAC Ġmode "). ĊĠĠĠĠ Ġ* ĠAfter Ġcalling Ġthe Ġdo Final () Ġmethod , Ġthe Ġkey Ġwill ĊĠĠĠĠ Ġ* Ġremain Ġto Ġbe Ġused Ġfor Ġfurther Ġcomput ations Ġof ĊĠĠĠĠ Ġ* Ġthis Ġinstance . ĊĠĠĠĠ Ġ* ĠThe Ġkey Ġcan Ġbe Ġoverwritten Ġusing Ġthe Ġclear Key () Ġmethod . ĊĠĠĠĠ Ġ* ĊĠĠĠĠ Ġ* Ġ@ param Ġkey ĠA Ġkey Ġup Ġto Ġ 6 4 Ġbytes Ġor Ġnull ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġconstructor ( key : ĠByteArray ?) Ġ{ ĊĠĠĠĠĠĠĠ Ġbuffer Ġ= ĠByteArray ( block Length ) ĊĠĠĠĠĠĠĠ Ġif Ġ( key Ġ!= Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġthis . key Ġ= Ġkey . copy Into ( ByteArray ( key . size ), Ġ 0 , Ġ 0 , Ġkey . size ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( key . size Ġ> Ġ 6 4 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġthrow ĠIllegalArgumentException ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ" Keys Ġ> Ġ 6 4 Ġare Ġnot Ġsupported " ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġkey Length Ġ= Ġkey . size ĊĠĠĠĠĠĠĠĠĠĠĠ Ġkey . copy Into ( buffer !! , Ġ 0 , Ġ 0 , Ġkey . size ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġbuffer Pos Ġ= Ġblock Length Ġ// Ġzero Ġpadding ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġdigest Size Ġ= Ġ 6 4 ĊĠĠĠĠĠĠĠ Ġinit () ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠBl ake 2 b Ġwith Ġkey , Ġrequired Ġdigest Ġlength Ġ( in Ġbytes ), Ġsalt Ġand Ġpersonal ization . ĊĠĠĠĠ Ġ* ĠAfter Ġcalling Ġthe Ġdo Final () Ġmethod , Ġthe Ġkey , Ġthe Ġsalt Ġand Ġthe Ġpersonal Ġstring ĊĠĠĠĠ Ġ* Ġwill Ġremain Ġand Ġmight Ġbe Ġused Ġfor Ġfurther Ġcomput ations Ġwith Ġthis Ġinstance . ĊĠĠĠĠ Ġ* ĠThe Ġkey Ġcan Ġbe Ġoverwritten Ġusing Ġthe Ġclear Key () Ġmethod , Ġthe Ġsalt Ġ( pep per ) ĊĠĠĠĠ Ġ* Ġcan Ġbe Ġoverwritten Ġusing Ġthe Ġclear Salt () Ġmethod . ĊĠĠĠĠ Ġ* ĊĠĠĠĠ Ġ* Ġ@ param Ġkey ĠĠĠĠĠĠĠĠĠĠĠĠ ĠA Ġkey Ġup Ġto Ġ 6 4 Ġbytes Ġor Ġnull ĊĠĠĠĠ Ġ* Ġ@ param Ġdigest Size ĠĠĠĠĠ Ġsize Ġof Ġthe Ġdigest Ġin Ġbits ĊĠĠĠĠ Ġ* Ġ@ param Ġsalt ĠĠĠĠĠĠĠĠĠĠĠĠ 1 6 Ġbytes Ġor Ġnull ĊĠĠĠĠ Ġ* Ġ@ param Ġpersonal ization Ġ 1 6 Ġbytes Ġor Ġnull ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġconstructor ( key : ĠByteArray ?, Ġdigest Size : ĠInt , Ġsalt : ĠByteArray ?, Ġpersonal ization : ĠByteArray ?) Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ( digest Size Ġ< Ġ 8 Ġ|| Ġdigest Size Ġ> Ġ 5 1 2 Ġ|| Ġdigest Size Ġ% Ġ 8 Ġ!= Ġ 0 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġthrow ĠIllegalArgumentException ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ" BL A KE 2 b Ġdigest Ġbit Ġlength Ġmust Ġbe Ġa Ġmultiple Ġof Ġ 8 Ġand Ġnot Ġgreater Ġthan Ġ 5 1 2 " ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġthis . digest Size Ġ= Ġdigest Size Ġ/ Ġ 8 ĊĊĠĠĠĠĠĠĠ Ġbuffer Ġ= ĠByteArray ( block Length ) ĊĠĠĠĠĠĠĠ Ġif Ġ( salt Ġ!= Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( salt . size Ġ!= Ġ 1 6 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġthrow ĠIllegalArgumentException ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ" salt Ġlength Ġmust Ġbe Ġexactly Ġ 1 6 Ġbytes " ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġthis . salt Ġ= Ġsalt . copy Into ( ByteArray ( 1 6 ), Ġ 0 , Ġ 0 , Ġsalt . size ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġif Ġ( personal ization Ġ!= Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( personal ization . size Ġ!= Ġ 1 6 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġthrow ĠIllegalArgumentException ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ" personal ization Ġlength Ġmust Ġbe Ġexactly Ġ 1 6 Ġbytes " ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġthis . personal ization Ġ= Ġpersonal ization . copy Into ( ByteArray ( 1 6 ), Ġ 0 , Ġ 0 , Ġpersonal ization . size ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġif Ġ( key Ġ!= Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġthis . key Ġ= Ġkey . copy Into ( ByteArray ( key . size ), Ġ 0 , Ġ 0 , Ġkey . size ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( key . size Ġ> Ġ 6 4 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġthrow ĠIllegalArgumentException ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ" Keys Ġ> Ġ 6 4 Ġare Ġnot Ġsupported " ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġkey Length Ġ= Ġkey . size ĊĠĠĠĠĠĠĠĠĠĠĠ Ġkey . copy Into ( buffer !! , Ġ 0 , Ġ 0 , Ġkey . size ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġbuffer Pos Ġ= Ġblock Length Ġ// Ġzero Ġpadding ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġinit () ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ// Ġinitialize Ġchain Value ĊĠĠĠ Ġprivate Ġfun Ġinit () Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ( chain Value Ġ== Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġchain Value Ġ= ĠLong Array ( 8 ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġchain Value ! ![ 0 ] Ġ= Ġ( bl ake 2 b _ IV [ 0 ] ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġxor Ġ( digest Size . to Long () Ġor Ġ( key Length . to Long () Ġshl Ġ 8 ) Ġor Ġ 0 x 1 0 1 0 0 0 0 L )) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġ 0 x 1 0 1 0 0 0 0 Ġ= Ġ(( fan out Ġ<< Ġ 1 6 ) Ġ| Ġ( depth Ġ<< Ġ 2 4 ) Ġ| Ġ( leaf Length Ġ<< ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġ 3 2 )); ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġwith Ġfan out Ġ= Ġ 1 ; Ġdepth Ġ= Ġ 0 ; Ġleaf Length Ġ= Ġ 0 ; ĊĠĠĠĠĠĠĠĠĠĠĠ Ġchain Value ! ![ 1 ] Ġ= Ġbl ake 2 b _ IV [ 1 ] Ġ// Ġ^ Ġnode Offset ; Ġwith Ġnode Offset Ġ= Ġ 0 ; ĊĠĠĠĠĠĠĠĠĠĠĠ Ġchain Value ! ![ 2 ] Ġ= Ġbl ake 2 b _ IV [ 2 ] Ġ// Ġ^ Ġ( Ġnode Depth Ġ| Ġ( inner Hash Length Ġ<< ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġ 8 ) Ġ); ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġwith Ġnode Depth Ġ= Ġ 0 ; Ġinner Hash Length Ġ= Ġ 0 ; ĊĠĠĠĠĠĠĠĠĠĠĠ Ġchain Value ! ![ 3 ] Ġ= Ġbl ake 2 b _ IV [ 3 ] ĊĠĠĠĠĠĠĠĠĠĠĠ Ġchain Value ! ![ 4 ] Ġ= Ġbl ake 2 b _ IV [ 4 ] ĊĠĠĠĠĠĠĠĠĠĠĠ Ġchain Value ! ![ 5 ] Ġ= Ġbl ake 2 b _ IV [ 5 ] ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( salt Ġ!= Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġchain Value ! ![ 4 ] Ġ= Ġchain Value ! ![ 4 ] Ġxor Ġdecode LE Long ( salt !! , Ġ 0 ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġchain Value ! ![ 5 ] Ġ= Ġchain Value ! ![ 5 ] Ġxor Ġdecode LE Long ( salt !! , Ġ 8 ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġchain Value ! ![ 6 ] Ġ= Ġbl ake 2 b _ IV [ 6 ] ĊĠĠĠĠĠĠĠĠĠĠĠ Ġchain Value ! ![ 7 ] Ġ= Ġbl ake 2 b _ IV [ 7 ] ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( personal ization Ġ!= Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġchain Value ! ![ 6 ] Ġ= Ġchain Value ! ![ 6 ] Ġxor Ġdecode LE Long ( personal ization !! , Ġ 0 ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġchain Value ! ![ 7 ] Ġ= Ġchain Value ! ![ 7 ] Ġxor Ġdecode LE Long ( personal ization !! , Ġ 8 ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġinitialize Internal State () Ġ{ ĊĠĠĠĠĠĠĠ Ġ// Ġinitialize Ġv : ĊĠĠĠĠĠĠĠ Ġchain Value !!. copy Into ( internal State , Ġ 0 , Ġ 0 , Ġchain Value !!. size ) ĊĠĠĠĠĠĠĠ Ġbl ake 2 b _ IV . copy Into ( internal State , Ġchain Value !!. size , Ġ 0 , Ġ 4 ) ĊĊĠĠĠĠĠĠĠ Ġinternal State [ 1 2 ] Ġ= Ġt 0 Ġxor Ġbl ake 2 b _ IV [ 4 ] ĊĠĠĠĠĠĠĠ Ġinternal State [ 1 3 ] Ġ= Ġt 1 Ġxor Ġbl ake 2 b _ IV [ 5 ] ĊĠĠĠĠĠĠĠ Ġinternal State [ 1 4 ] Ġ= Ġf 0 Ġxor Ġbl ake 2 b _ IV [ 6 ] ĊĠĠĠĠĠĠĠ Ġinternal State [ 1 5 ] Ġ= Ġbl ake 2 b _ IV [ 7 ] Ġ// Ġ^ Ġf 1 Ġwith Ġf 1 Ġ= Ġ 0 ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* Ġupdate Ġthe Ġmessage Ġdigest Ġwith Ġa Ġsingle Ġbyte . ĊĠĠĠĠ Ġ* ĊĠĠĠĠ Ġ* Ġ@ param Ġinput Ġthe Ġinput Ġbyte Ġto Ġbe Ġentered . ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġoverride Ġfun Ġupdate ( input : ĠByte ) Ġ{ ĊĠĠĠĠĠĠĠ Ġ// Ġprocess Ġthe Ġbuffer Ġif Ġfull Ġelse Ġadd Ġto Ġbuffer : ĊĠĠĠĠĠĠĠ Ġval Ġremaining Length Ġ= Ġblock Length Ġ- Ġbuffer Pos ĊĠĠĠĠĠĠĠ Ġif Ġ( remaining Length Ġ== Ġ 0 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġfull Ġbuffer ĊĠĠĠĠĠĠĠĠĠĠĠ Ġt 0 Ġ+= Ġblock Length . to Long () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( t 0 Ġ== Ġ 0 L ) Ġ{ Ġ// Ġif Ġmessage Ġ> Ġ 2 ^ 6 4 ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġt 1 ++ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġcompress ( buffer !! , Ġ 0 ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġbuffer !!. fill ( 0 ) Ġ// Ġclear Ġbuffer ĊĠĠĠĠĠĠĠĠĠĠĠ Ġbuffer ! ![ 0 ] Ġ= Ġinput ĊĠĠĠĠĠĠĠĠĠĠĠ Ġbuffer Pos Ġ= Ġ 1 ĊĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġbuffer ! ![ buffer Pos ] Ġ= Ġinput ĊĠĠĠĠĠĠĠĠĠĠĠ Ġbuffer Pos ++ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* Ġupdate Ġthe Ġmessage Ġdigest Ġwith Ġa Ġblock Ġof Ġbytes . ĊĠĠĠĠ Ġ* ĊĠĠĠĠ Ġ* Ġ@ param Ġinput Ġthe Ġbyte Ġarray Ġcontaining Ġthe Ġdata . ĊĠĠĠĠ Ġ* Ġ@ param Ġoffset Ġ Ġthe Ġoffset Ġinto Ġthe Ġbyte Ġarray Ġwhere Ġthe Ġdata Ġstarts . ĊĠĠĠĠ Ġ* Ġ@ param Ġlength ĠĠĠĠ Ġthe Ġlength Ġof Ġthe Ġdata . ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġoverride Ġfun Ġupdate ( input : ĠByteArray , Ġoffset : ĠInt , Ġlength : ĠInt ) Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ( length Ġ== Ġ 0 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġvar Ġremaining Length Ġ= Ġ 0 Ġ// Ġleft Ġbytes Ġof Ġbuffer ĊĊĠĠĠĠĠĠĠ Ġif Ġ( buffer Pos Ġ!= Ġ 0 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġcomm enced , Ġincomplete Ġbuffer ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġcomplete Ġthe Ġbuffer : ĊĠĠĠĠĠĠĠĠĠĠĠ Ġremaining Length Ġ= Ġblock Length Ġ- Ġbuffer Pos ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( remaining Length Ġ< Ġlength ) Ġ{ Ġ// Ġfull Ġbuffer Ġ+ Ġat Ġleast Ġ 1 Ġbyte ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġinput . copy Into ( buffer !! , Ġbuffer Pos , Ġoffset , Ġoffset Ġ+ Ġremaining Length ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġt 0 Ġ+= Ġblock Length . to Long () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( t 0 Ġ== Ġ 0 L ) Ġ{ Ġ// Ġif Ġmessage Ġ> Ġ 2 ^ 6 4 ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġt 1 ++ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcompress ( buffer !! , Ġ 0 ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġbuffer Pos Ġ= Ġ 0 ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġclear Ġbuffer ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġbuffer ?. fill ( 0 ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġinput . copy Into ( buffer !! , Ġbuffer Pos , Ġoffset , Ġoffset Ġ+ Ġlength ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġbuffer Pos Ġ+= Ġlength ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġ// Ġprocess Ġblocks Ġexcept Ġlast Ġblock Ġ( also Ġif Ġlast Ġblock Ġis Ġfull ) ĊĠĠĠĠĠĠĠ Ġval Ġblock Wise Last Pos Ġ= Ġoffset Ġ+ Ġlength Ġ- Ġblock Length ĊĠĠĠĠĠĠĠ Ġvar Ġmessage Pos : ĠInt Ġ= Ġoffset Ġ+ Ġremaining Length ĊĠĠĠĠĠĠĠ Ġwhile Ġ( message Pos Ġ< Ġblock Wise Last Pos ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġblock Ġwise Ġ 1 2 8 Ġbytes ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġwithout Ġbuffer : ĊĠĠĠĠĠĠĠĠĠĠĠ Ġt 0 Ġ+= Ġblock Length . to Long () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( t 0 Ġ== Ġ 0 L ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġt 1 ++ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġcompress ( input , Ġmessage Pos ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġmessage Pos Ġ+= Ġblock Length ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġ// Ġfill Ġthe Ġbuffer Ġwith Ġleft Ġbytes , Ġthis Ġmight Ġbe Ġa Ġfull Ġblock ĊĠĠĠĠĠĠĠ Ġinput . copy Into ( buffer !! , Ġ 0 , Ġmessage Pos , Ġoffset Ġ+ Ġlength ) ĊĠĠĠĠĠĠĠ Ġbuffer Pos Ġ+= Ġoffset Ġ+ Ġlength Ġ- Ġmessage Pos ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* Ġclose Ġthe Ġdigest , Ġproducing Ġthe Ġfinal Ġdigest Ġvalue . ĠThe Ġdo Final ĊĠĠĠĠ Ġ* Ġcall Ġleaves Ġthe Ġdigest Ġreset . ĊĠĠĠĠ Ġ* ĠKey , Ġsalt Ġand Ġpersonal Ġstring Ġremain . ĊĠĠĠĠ Ġ* ĊĠĠĠĠ Ġ* Ġ@ param Ġout ĠĠĠĠĠĠ Ġthe Ġarray Ġthe Ġdigest Ġis Ġto Ġbe Ġcopied Ġinto . ĊĠĠĠĠ Ġ* Ġ@ param Ġout Offset Ġthe Ġoffset Ġinto Ġthe Ġout Ġarray Ġthe Ġdigest Ġis Ġto Ġstart Ġat . ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġfun Ġdo Final ( out : ĠByteArray ?, Ġout Offset : ĠInt ): ĠInt Ġ{ ĊĠĠĠĠĠĠĠ Ġf 0 Ġ= Ġ- 0 x 1 L ĊĠĠĠĠĠĠĠ Ġt 0 Ġ+= Ġbuffer Pos . to Long () ĊĠĠĠĠĠĠĠ Ġif Ġ( buffer Pos Ġ> Ġ 0 Ġ&& Ġt 0 Ġ== Ġ 0 L ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġt 1 ++ ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġcompress ( buffer !! , Ġ 0 ) ĊĠĠĠĠĠĠĠ Ġbuffer ?. fill ( 0 ) Ġ// ĠHold s Ġeventually Ġthe Ġkey Ġif Ġinput Ġis Ġnull ĊĠĠĠĠĠĠĠ Ġinternal State . fill ( 0 L ) ĊĠĠĠĠĠĠĠ Ġvar Ġi Ġ= Ġ 0 ĊĠĠĠĠĠĠĠ Ġwhile Ġ( i Ġ< Ġchain Value !!. size Ġ&& Ġi Ġ* Ġ 8 Ġ< Ġdigest Size ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġbytes Ġ= ĠByteArray ( 8 ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġencode LE Long ( chain Value ! ![ i ], Ġbytes , Ġ 0 ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( i Ġ* Ġ 8 Ġ< Ġdigest Size Ġ- Ġ 8 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġbytes . copy Into ( out !! , Ġout Offset Ġ+ Ġi Ġ* Ġ 8 , Ġ 0 , Ġ 8 ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġbytes . copy Into ( out !! , Ġout Offset Ġ+ Ġi Ġ* Ġ 8 , Ġ 0 , Ġdigest Size Ġ- Ġi Ġ* Ġ 8 ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġi ++ ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġchain Value ?. fill ( 0 L ) ĊĠĠĠĠĠĠĠ Ġreset () ĊĠĠĠĠĠĠĠ Ġreturn Ġdigest Size ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠReset Ġthe Ġdigest Ġback Ġto Ġit 's Ġinitial Ġstate . ĊĠĠĠĠ Ġ* ĠThe Ġkey , Ġthe Ġsalt Ġand Ġthe Ġpersonal Ġstring Ġwill ĊĠĠĠĠ Ġ* Ġremain Ġfor Ġfurther Ġcomput ations . ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġoverride Ġfun Ġreset () Ġ{ ĊĠĠĠĠĠĠĠ Ġbuffer Pos Ġ= Ġ 0 ĊĠĠĠĠĠĠĠ Ġf 0 Ġ= Ġ 0 L ĊĠĠĠĠĠĠĠ Ġt 0 Ġ= Ġ 0 L ĊĠĠĠĠĠĠĠ Ġt 1 Ġ= Ġ 0 L ĊĠĠĠĠĠĠĠ Ġchain Value Ġ= Ġnull ĊĠĠĠĠĠĠĠ Ġbuffer ?. fill ( 0 ) ĊĠĠĠĠĠĠĠ Ġif Ġ( key Ġ!= Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġkey !!. copy Into ( buffer !! , Ġ 0 , Ġ 0 , Ġkey !!. size ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġbuffer Pos Ġ= Ġblock Length Ġ// Ġzero Ġpadding ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġinit () ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġcompress ( message : ĠByteArray , Ġmessage Pos : ĠInt ) Ġ{ ĊĠĠĠĠĠĠĠ Ġinitialize Internal State () ĊĠĠĠĠĠĠĠ Ġval Ġm Ġ= ĠLong Array ( 1 6 ) ĊĠĠĠĠĠĠĠ Ġfor Ġ( j Ġin Ġ 0 .. 1 5 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġm [ j ] Ġ= Ġdecode LE Long ( message , Ġmessage Pos Ġ+ Ġj Ġ* Ġ 8 ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġfor Ġ( round Ġin Ġ 0 Ġuntil ĠRO UN DS ) Ġ{ ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠG Ġapply Ġto Ġcolumns Ġof Ġinternal State : m [ bl ake 2 b _ sigma [ round ][ 2 Ġ* ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġblock Pos ]] Ġ/ + 1 ĊĠĠĠĠĠĠĠĠĠĠĠ Ġg ( m [ bl ake 2 b _ sigma [ round ][ 0 ]. toInt ()], Ġm [ bl ake 2 b _ sigma [ round ][ 1 ]. toInt ()], Ġ 0 , Ġ 4 , Ġ 8 , Ġ 1 2 ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġg ( m [ bl ake 2 b _ sigma [ round ][ 2 ]. toInt ()], Ġm [ bl ake 2 b _ sigma [ round ][ 3 ]. toInt ()], Ġ 1 , Ġ 5 , Ġ 9 , Ġ 1 3 ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġg ( m [ bl ake 2 b _ sigma [ round ][ 4 ]. toInt ()], Ġm [ bl ake 2 b _ sigma [ round ][ 5 ]. toInt ()], Ġ 2 , Ġ 6 , Ġ 1 0 , Ġ 1 4 ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġg ( m [ bl ake 2 b _ sigma [ round ][ 6 ]. toInt ()], Ġm [ bl ake 2 b _ sigma [ round ][ 7 ]. toInt ()], Ġ 3 , Ġ 7 , Ġ 1 1 , Ġ 1 5 ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠG Ġapply Ġto Ġdiag on als Ġof Ġinternal State : ĊĠĠĠĠĠĠĠĠĠĠĠ Ġg ( m [ bl ake 2 b _ sigma [ round ][ 8 ]. toInt ()], Ġm [ bl ake 2 b _ sigma [ round ][ 9 ]. toInt ()], Ġ 0 , Ġ 5 , Ġ 1 0 , Ġ 1 5 ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġg ( m [ bl ake 2 b _ sigma [ round ][ 1 0 ]. toInt ()], Ġm [ bl ake 2 b _ sigma [ round ][ 1 1 ]. toInt ()], Ġ 1 , Ġ 6 , Ġ 1 1 , Ġ 1 2 ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġg ( m [ bl ake 2 b _ sigma [ round ][ 1 2 ]. toInt ()], Ġm [ bl ake 2 b _ sigma [ round ][ 1 3 ]. toInt ()], Ġ 2 , Ġ 7 , Ġ 8 , Ġ 1 3 ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġg ( m [ bl ake 2 b _ sigma [ round ][ 1 4 ]. toInt ()], Ġm [ bl ake 2 b _ sigma [ round ][ 1 5 ]. toInt ()], Ġ 3 , Ġ 4 , Ġ 9 , Ġ 1 4 ) ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġ// Ġupdate Ġchain Ġvalues : ĊĠĠĠĠĠĠĠ Ġfor Ġ( offset Ġin Ġchain Value !!. indices ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġchain Value ! ![ offset ] Ġ= Ġchain Value ! ![ offset ] Ġxor Ġinternal State [ offset ] Ġxor Ġinternal State [ offset Ġ+ Ġ 8 ] ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġg ( m 1 : ĠLong , Ġm 2 : ĠLong , Ġpos A : ĠInt , Ġpos B : ĠInt , Ġpos C : ĠInt , Ġpos D : ĠInt ) Ġ{ ĊĠĠĠĠĠĠĠ Ġinternal State [ pos A ] Ġ= Ġinternal State [ pos A ] Ġ+ Ġinternal State [ pos B ] Ġ+ Ġm 1 ĊĠĠĠĠĠĠĠ Ġinternal State [ pos D ] Ġ= Ġcircular Right Long ( internal State [ pos D ] Ġxor Ġinternal State [ pos A ], Ġ 3 2 ) ĊĠĠĠĠĠĠĠ Ġinternal State [ pos C ] Ġ= Ġinternal State [ pos C ] Ġ+ Ġinternal State [ pos D ] ĊĠĠĠĠĠĠĠ Ġinternal State [ pos B ] Ġ= Ġcircular Right Long ( internal State [ pos B ] Ġxor Ġinternal State [ pos C ], Ġ 2 4 ) Ġ// Ġreplaces Ġ 2 5 Ġof ĠB LA KE ĊĠĠĠĠĠĠĠ Ġinternal State [ pos A ] Ġ= Ġinternal State [ pos A ] Ġ+ Ġinternal State [ pos B ] Ġ+ Ġm 2 ĊĠĠĠĠĠĠĠ Ġinternal State [ pos D ] Ġ= Ġcircular Right Long ( internal State [ pos D ] Ġxor Ġinternal State [ pos A ], Ġ 1 6 ) ĊĠĠĠĠĠĠĠ Ġinternal State [ pos C ] Ġ= Ġinternal State [ pos C ] Ġ+ Ġinternal State [ pos D ] ĊĠĠĠĠĠĠĠ Ġinternal State [ pos B ] Ġ= Ġcircular Right Long ( internal State [ pos B ] Ġxor Ġinternal State [ pos C ], Ġ 6 3 ) Ġ// Ġreplaces Ġ 1 1 Ġof ĠB LA KE ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠOver write Ġthe Ġkey ĊĠĠĠĠ Ġ* Ġif Ġit Ġis Ġno Ġlonger Ġused Ġ( zero ization ) ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġfun Ġclear Key () Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ( key Ġ!= Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġkey ?. fill ( 0 ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġbuffer ?. fill ( 0 ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠOver write Ġthe Ġsalt Ġ( pep per ) Ġif Ġit ĊĠĠĠĠ Ġ* Ġis Ġsecret Ġand Ġno Ġlonger Ġused Ġ( zero ization ) ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġfun Ġclear Salt () Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ( salt Ġ!= Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġsalt ?. fill ( 0 ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠReturn Ġthe Ġsize Ġin Ġbytes Ġof Ġthe Ġinternal Ġbuffer Ġthe Ġdigest Ġapplies Ġit 's Ġcompression ĊĠĠĠĠ Ġ* Ġfunction Ġto . ĊĠĠĠĠ Ġ* ĊĠĠĠĠ Ġ* Ġ@ return Ġbyte Ġlength Ġof Ġthe Ġdigest s Ġinternal Ġbuffer . ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġoverride Ġval Ġblock Length : ĠInt ĊĠĠĠĠĠĠĠ Ġget () Ġ= Ġ 1 2 8 ĊĊĠĠĠ Ġcompanion Ġobject Ġ{ ĊĠĠĠĠĠĠĠ Ġ// ĠBl ake 2 b ĠInitialization ĠVector : ĊĠĠĠĠĠĠĠ Ġprivate Ġval Ġbl ake 2 b _ IV Ġ= Ġlong ArrayOf ( ĊĠĠĠĠĠĠĠĠĠĠĠĠ 0 x 6 a 0 9 e 6 6 7 f 3 bcc 9 0 8 L , Ġ- 0 x 4 4 9 8 5 1 7 a 7 b 3 5 5 8 c 5 L , Ġ 0 x 3 c 6 ef 3 7 2 fe 9 4 f 8 2 b L , ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ- 0 x 5 ab 0 0 ac 5 a 0 e 2 c 9 0 f L , Ġ 0 x 5 1 0 e 5 2 7 fade 6 8 2 d 1 L , Ġ- 0 x 6 4 fa 9 7 7 3 d 4 c 1 9 3 e 1 L , ĊĠĠĠĠĠĠĠĠĠĠĠĠ 0 x 1 f 8 3 d 9 ab fb 4 1 bd 6 b L , Ġ 0 x 5 be 0 cd 1 9 1 3 7 e 2 1 7 9 L ĊĠĠĠĠĠĠĠ Ġ) ĊĊĠĠĠĠĠĠĠ Ġ// ĠMessage Ġword Ġper mutations : ĊĠĠĠĠĠĠĠ Ġprivate Ġval Ġbl ake 2 b _ sigma Ġ= ĠarrayOf ( ĊĠĠĠĠĠĠĠĠĠĠĠ Ġbyte ArrayOf ( 0 , Ġ 1 , Ġ 2 , Ġ 3 , Ġ 4 , Ġ 5 , Ġ 6 , Ġ 7 , Ġ 8 , Ġ 9 , Ġ 1 0 , Ġ 1 1 , Ġ 1 2 , Ġ 1 3 , Ġ 1 4 , Ġ 1 5 ), ĊĠĠĠĠĠĠĠĠĠĠĠ Ġbyte ArrayOf ( 1 4 , Ġ 1 0 , Ġ 4 , Ġ 8 , Ġ 9 , Ġ 1 5 , Ġ 1 3 , Ġ 6 , Ġ 1 , Ġ 1 2 , Ġ 0 , Ġ 2 , Ġ 1 1 , Ġ 7 , Ġ 5 , Ġ 3 ), ĊĠĠĠĠĠĠĠĠĠĠĠ Ġbyte ArrayOf ( 1 1 , Ġ 8 , Ġ 1 2 , Ġ 0 , Ġ 5 , Ġ 2 , Ġ 1 5 , Ġ 1 3 , Ġ 1 0 , Ġ 1 4 , Ġ 3 , Ġ 6 , Ġ 7 , Ġ 1 , Ġ 9 , Ġ 4 ), ĊĠĠĠĠĠĠĠĠĠĠĠ Ġbyte ArrayOf ( 7 , Ġ 9 , Ġ 3 , Ġ 1 , Ġ 1 3 , Ġ 1 2 , Ġ 1 1 , Ġ 1 4 , Ġ 2 , Ġ 6 , Ġ 5 , Ġ 1 0 , Ġ 4 , Ġ 0 , Ġ 1 5 , Ġ 8 ), ĊĠĠĠĠĠĠĠĠĠĠĠ Ġbyte ArrayOf ( 9 , Ġ 0 , Ġ 5 , Ġ 7 , Ġ 2 , Ġ 4 , Ġ 1 0 , Ġ 1 5 , Ġ 1 4 , Ġ 1 , Ġ 1 1 , Ġ 1 2 , Ġ 6 , Ġ 8 , Ġ 3 , Ġ 1 3 ), ĊĠĠĠĠĠĠĠĠĠĠĠ Ġbyte ArrayOf ( 2 , Ġ 1 2 , Ġ 6 , Ġ 1 0 , Ġ 0 , Ġ 1 1 , Ġ 8 , Ġ 3 , Ġ 4 , Ġ 1 3 , Ġ 7 , Ġ 5 , Ġ 1 5 , Ġ 1 4 , Ġ 1 , Ġ 9 ), ĊĠĠĠĠĠĠĠĠĠĠĠ Ġbyte ArrayOf ( 1 2 , Ġ 5 , Ġ 1 , Ġ 1 5 , Ġ 1 4 , Ġ 1 3 , Ġ 4 , Ġ 1 0 , Ġ 0 , Ġ 7 , Ġ 6 , Ġ 3 , Ġ 9 , Ġ 2 , Ġ 8 , Ġ 1 1 ), ĊĠĠĠĠĠĠĠĠĠĠĠ Ġbyte ArrayOf ( 1 3 , Ġ 1 1 , Ġ 7 , Ġ 1 4 , Ġ 1 2 , Ġ 1 , Ġ 3 , Ġ 9 , Ġ 5 , Ġ 0 , Ġ 1 5 , Ġ 4 , Ġ 8 , Ġ 6 , Ġ 2 , Ġ 1 0 ), ĊĠĠĠĠĠĠĠĠĠĠĠ Ġbyte ArrayOf ( 6 , Ġ 1 5 , Ġ 1 4 , Ġ 9 , Ġ 1 1 , Ġ 3 , Ġ 0 , Ġ 8 , Ġ 1 2 , Ġ 2 , Ġ 1 3 , Ġ 7 , Ġ 1 , Ġ 4 , Ġ 1 0 , Ġ 5 ), ĊĠĠĠĠĠĠĠĠĠĠĠ Ġbyte ArrayOf ( 1 0 , Ġ 2 , Ġ 8 , Ġ 4 , Ġ 7 , Ġ 6 , Ġ 1 , Ġ 5 , Ġ 1 5 , Ġ 1 1 , Ġ 9 , Ġ 1 4 , Ġ 3 , Ġ 1 2 , Ġ 1 3 , Ġ 0 ), ĊĠĠĠĠĠĠĠĠĠĠĠ Ġbyte ArrayOf ( 0 , Ġ 1 , Ġ 2 , Ġ 3 , Ġ 4 , Ġ 5 , Ġ 6 , Ġ 7 , Ġ 8 , Ġ 9 , Ġ 1 0 , Ġ 1 1 , Ġ 1 2 , Ġ 1 3 , Ġ 1 4 , Ġ 1 5 ), ĊĠĠĠĠĠĠĠĠĠĠĠ Ġbyte ArrayOf ( 1 4 , Ġ 1 0 , Ġ 4 , Ġ 8 , Ġ 9 , Ġ 1 5 , Ġ 1 3 , Ġ 6 , Ġ 1 , Ġ 1 2 , Ġ 0 , Ġ 2 , Ġ 1 1 , Ġ 7 , Ġ 5 , Ġ 3 ) ĊĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠ Ġprivate Ġconst Ġval ĠRO UN DS Ġ= Ġ 1 2 Ġ// Ġto Ġuse Ġfor ĠC aten as ĠH ' ĊĊĠĠĠĠĠĠĠ Ġfun Ġcreate ( parameters : ĠAlgorithm . Bl ake 2 b ): ĠBl ake 2 b Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġwhen Ġ( parameters ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠAlgorithm . Bl ake 2 b . Key ed Ġ-> ĠBl ake 2 b ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġparameters . key , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġparameters . output Size Bits , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġparameters . salt , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġparameters . personal isation ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġelse Ġ-> ĠBl ake 2 b ( parameters . output Size Bits ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġupdate ( input : ĠByteArray ) Ġ{ ĊĠĠĠĠĠĠĠ Ġupdate ( input , Ġ 0 , Ġinput . size ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġdigest (): ĠByteArray Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġdigest Ġ= ĠByteArray ( digest Size ) ĊĠĠĠĠĠĠĠ Ġdo Final ( digest , Ġ 0 ) ĊĠĠĠĠĠĠĠ Ġreturn Ġdigest ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġdigest ( input : ĠByteArray ): ĠByteArray Ġ{ ĊĠĠĠĠĠĠĠ Ġupdate ( input ) ĊĠĠĠĠĠĠĠ Ġreturn Ġdigest () ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġdigest ( output : ĠByteArray , Ġoffset : ĠInt , Ġlength : ĠInt ): ĠInt Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġdigest Ġ= Ġdigest () ĊĊĠĠĠĠĠĠĠ Ġif Ġ( length Ġ< Ġdigest . size ) Ġthrow ĠIllegalArgumentException (" partial Ġdigest s Ġnot Ġreturned ") ĊĠĠĠĠĠĠĠ Ġif Ġ( output . size Ġ- Ġoffset Ġ< Ġdigest . size ) Ġthrow ĠIllegalArgumentException (" ins ufficient Ġspace Ġin Ġthe Ġoutput Ġbuffer Ġto Ġstore Ġthe Ġdigest ") ĊĊĠĠĠĠĠĠĠ Ġdigest . copy Into ( output , Ġoffset , Ġ 0 , Ġdigest . size ) ĊĊĠĠĠĠĠĠĠ Ġreturn Ġdigest . size ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġval Ġdigest Length : ĠInt ĊĠĠĠĠĠĠĠ Ġget () Ġ= Ġdigest Size ĊĊĠĠĠ Ġoverride Ġfun Ġcopy (): ĠBl ake 2 b Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn ĠBl ake 2 b ( this ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun ĠtoString () Ġ= Ġ" BL A KE 2 b " Ċ } Ċ