package Ġcom . ion spin . kotlin . crypto . symmetric Ċ Ċ import Ġcom . ion spin . kotlin . crypto . symmetric . Latin D ances Common . little Endian In verted Ċ import Ġcom . ion spin . kotlin . crypto . util .* Ċ Ċ /** Ċ Ġ* ĠCreated Ġby ĠU gl jes a ĠJ ovan ov ic Ċ Ġ* Ġug lj es a . j ovan ov ic @ ion spin . com Ċ Ġ* Ġon Ġ 1 4 - Jun - 2 0 2 0 Ċ Ġ*/ Ċ internal Ġclass ĠSal sa 2 0 Pure Ġ{ ĊĠĠĠ Ġcompanion Ġobject Ġ{ ĊĠĠĠĠĠĠĠ Ġfun Ġquarter Round ( input : ĠUInt Array , Ġy 0 position : ĠInt , Ġy 1 position : ĠInt , Ġy 2 position : ĠInt , Ġy 3 position : ĠInt ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġinput [ y 1 position ] Ġ= Ġinput [ y 1 position ] Ġxor Ġ(( input [ y 0 position ] Ġ+ Ġinput [ y 3 position ]) Ġrotate Left Ġ 7 ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġinput [ y 2 position ] Ġ= Ġinput [ y 2 position ] Ġxor Ġ(( input [ y 1 position ] Ġ+ Ġinput [ y 0 position ]) Ġrotate Left Ġ 9 ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġinput [ y 3 position ] Ġ= Ġinput [ y 3 position ] Ġxor Ġ(( input [ y 2 position ] Ġ+ Ġinput [ y 1 position ]) Ġrotate Left Ġ 1 3 ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġinput [ y 0 position ] Ġ= Ġinput [ y 0 position ] Ġxor Ġ(( input [ y 3 position ] Ġ+ Ġinput [ y 2 position ]) Ġrotate Left Ġ 1 8 ) ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġfun Ġrow Round ( input : ĠUInt Array ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġquarter Round ( input , Ġ 0 , Ġ 1 , Ġ 2 , Ġ 3 ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġquarter Round ( input , Ġ 5 , Ġ 6 , Ġ 7 , Ġ 4 ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġquarter Round ( input , Ġ 1 0 , Ġ 1 1 , Ġ 8 , Ġ 9 ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġquarter Round ( input , Ġ 1 5 , Ġ 1 2 , Ġ 1 3 , Ġ 1 4 ) ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġfun Ġcolumn Round ( input : ĠUInt Array ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġquarter Round ( input , Ġ 0 , Ġ 4 , Ġ 8 , Ġ 1 2 ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġquarter Round ( input , Ġ 5 , Ġ 9 , Ġ 1 3 , Ġ 1 ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġquarter Round ( input , Ġ 1 0 , Ġ 1 4 , Ġ 2 , Ġ 6 ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġquarter Round ( input , Ġ 1 5 , Ġ 3 , Ġ 7 , Ġ 1 1 ) ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġfun Ġdouble Round ( input : ĠUInt Array ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġcolumn Round ( input ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġrow Round ( input ) ĊĠĠĠĠĠĠĠ Ġ} ĊĊĊĊĠĠĠĠĠĠĠ Ġfun Ġhash ( initialState : ĠUInt Array ): ĠU ByteArray Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġstate Ġ= ĠinitialState . copyOf () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġfor Ġ( i Ġin Ġ 0 Ġuntil Ġ 1 0 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġdouble Round ( state ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġresult Ġ= ĠU ByteArray ( 6 4 ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġfor Ġ( i Ġin Ġ 0 Ġuntil Ġ 1 6 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlittle Endian In verted ( initialState [ i ] Ġ+ Ġstate [ i ], Ġresult , Ġi Ġ* Ġ 4 ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġresult ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġinternal Ġvar Ġsigma 0 _ 3 2 _ uint Ġ= Ġ 1 6 3 4 7 6 0 8 0 5 U Ġ// ubyte ArrayOf ( 1 0 1 U , Ġ 1 2 0 U , Ġ 1 1 2 U , Ġ 9 7 U ) ĊĠĠĠĠĠĠĠ Ġinternal Ġvar Ġsigma 1 _ 3 2 _ uint Ġ= Ġ 8 5 7 7 6 0 8 7 8 U Ġ// ubyte ArrayOf ( 1 1 0 U , Ġ 1 0 0 U , Ġ 3 2 U , Ġ 5 1 U ) ĊĠĠĠĠĠĠĠ Ġinternal Ġvar Ġsigma 2 _ 3 2 _ uint Ġ= Ġ 2 0 3 6 4 7 7 2 3 4 U Ġ// ubyte ArrayOf ( 5 0 U , Ġ 4 5 U , Ġ 9 8 U , Ġ 1 2 1 U ) ĊĠĠĠĠĠĠĠ Ġinternal Ġvar Ġsigma 3 _ 3 2 _ uint Ġ= Ġ 1 7 9 7 2 8 5 2 3 6 U Ġ// ubyte ArrayOf ( 1 1 6 U , Ġ 1 0 1 U , Ġ 3 2 U , Ġ 1 0 7 U ) ĊĊĠĠĠĠĠĠĠ Ġval Ġsigma 0 _ 3 2 Ġ= Ġ ubyte ArrayOf ( 1 0 1 U , Ġ 1 2 0 U , Ġ 1 1 2 U , Ġ 9 7 U ) ĊĠĠĠĠĠĠĠ Ġval Ġsigma 1 _ 3 2 Ġ= Ġ ubyte ArrayOf ( 1 1 0 U , Ġ 1 0 0 U , Ġ 3 2 U , Ġ 5 1 U ) ĊĠĠĠĠĠĠĠ Ġval Ġsigma 2 _ 3 2 Ġ= Ġ ubyte ArrayOf ( 5 0 U , Ġ 4 5 U , Ġ 9 8 U , Ġ 1 2 1 U ) ĊĠĠĠĠĠĠĠ Ġval Ġsigma 3 _ 3 2 Ġ= Ġ ubyte ArrayOf ( 1 1 6 U , Ġ 1 0 1 U , Ġ 3 2 U , Ġ 1 0 7 U ) ĊĊĠĠĠĠĠĠĠ Ġval Ġtau 0 _ 1 6 Ġ= Ġ ubyte ArrayOf ( 1 0 1 U , Ġ 1 2 0 U , Ġ 1 1 2 U , Ġ 9 7 U ) ĊĠĠĠĠĠĠĠ Ġval Ġtau 1 _ 1 6 Ġ= Ġ ubyte ArrayOf ( 1 1 0 U , Ġ 1 0 0 U , Ġ 3 2 U , Ġ 4 9 U ) ĊĠĠĠĠĠĠĠ Ġval Ġtau 2 _ 1 6 Ġ= Ġ ubyte ArrayOf ( 5 4 U , Ġ 4 5 U , Ġ 9 8 U , Ġ 1 2 1 U ) ĊĠĠĠĠĠĠĠ Ġval Ġtau 3 _ 1 6 Ġ= Ġ ubyte ArrayOf ( 1 1 6 U , Ġ 1 0 1 U , Ġ 3 2 U , Ġ 1 0 7 U ) ĊĊĠĠĠĠĠĠĠ Ġfun Ġexpansion 1 6 ( k : ĠU ByteArray , Ġn : ĠU ByteArray ) Ġ: ĠU ByteArray Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġhash (( tau 0 _ 1 6 Ġ+ Ġk Ġ+ Ġtau 1 _ 1 6 Ġ+ Ġn Ġ+ Ġtau 2 _ 1 6 Ġ+ Ġk Ġ+ Ġtau 3 _ 1 6 ). from LittleEndian To UInt ()) ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġfun Ġexpansion 3 2 ( key Ġ: U ByteArray , Ġnonce Ġ: ĠU ByteArray ) Ġ: ĠU ByteArray Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġhash (( sigma 0 _ 3 2 Ġ+ Ġkey . slice ( 0 Ġuntil Ġ 1 6 ) Ġ+ Ġsigma 1 _ 3 2 Ġ+ Ġnonce Ġ+ Ġsigma 2 _ 3 2 Ġ+ Ġkey . slice ( 1 6 Ġuntil Ġ 3 2 ) Ġ+ Ġsigma 3 _ 3 2 ). from LittleEndian To UInt ()) ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġfun Ġencrypt ( key Ġ: ĠU ByteArray , Ġnonce : ĠU ByteArray , Ġmessage : ĠU ByteArray ) Ġ: ĠU ByteArray Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġciphertext Ġ= ĠU ByteArray ( message . size ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġstate Ġ= ĠUInt Array ( 1 6 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġwhen Ġ( it ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ 0 Ġ-> Ġsigma 0 _ 3 2 _ uint ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ 1 Ġ-> Ġkey . from LittleEndian Array To UInt With Position ( 0 ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ 2 Ġ-> Ġkey . from LittleEndian Array To UInt With Position ( 4 ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ 3 Ġ-> Ġkey . from LittleEndian Array To UInt With Position ( 8 ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ 4 Ġ-> Ġkey . from LittleEndian Array To UInt With Position ( 1 2 ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ 5 Ġ-> Ġsigma 1 _ 3 2 _ uint ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ 6 Ġ-> Ġnonce . from LittleEndian Array To UInt With Position ( 0 ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ 7 Ġ-> Ġnonce . from LittleEndian Array To UInt With Position ( 4 ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ 8 Ġ-> Ġ 0 U ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ 9 Ġ-> Ġ 0 U ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ 1 0 Ġ-> Ġsigma 2 _ 3 2 _ uint ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ 1 1 Ġ-> Ġkey . from LittleEndian Array To UInt With Position ( 1 6 ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ 1 2 Ġ-> Ġkey . from LittleEndian Array To UInt With Position ( 2 0 ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ 1 3 Ġ-> Ġkey . from LittleEndian Array To UInt With Position ( 2 4 ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ 1 4 Ġ-> Ġkey . from LittleEndian Array To UInt With Position ( 2 8 ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ 1 5 Ġ-> Ġsigma 3 _ 3 2 _ uint ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġelse Ġ-> Ġ 0 U ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġblocks Ġ= Ġmessage . size Ġ/ Ġ 6 4 ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġremainder Ġ= Ġmessage . size Ġ% Ġ 6 4 ĊĠĠĠĠĠĠĠĠĠĠĠ Ġfor Ġ( i Ġin Ġ 0 Ġuntil Ġblocks ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġhash ( state ). xor With Positions And Insert Into Array ( 0 , Ġ 6 4 , Ġmessage , Ġi Ġ* Ġ 6 4 , Ġciphertext , Ġi Ġ* Ġ 6 4 ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġstate [ 8 ] Ġ+= Ġ 1 U ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( state [ 8 ] Ġ== Ġ 0 U ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġstate [ 9 ] Ġ+= Ġ 1 U ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġhash ( state ). xor With Positions And Insert Into Array ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ 0 , Ġremainder , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġmessage , Ġblocks Ġ* Ġ 6 4 , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġciphertext , Ġblocks Ġ* Ġ 6 4 ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġstate . overwrite With Zero es () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġciphertext ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġfun Ġdecrypt ( key Ġ: ĠU ByteArray , Ġnonce : ĠU ByteArray , Ġciphertext : ĠU ByteArray ) Ġ: ĠU ByteArray Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġencrypt ( key , Ġnonce , Ġciphertext ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} Ċ Ċ }