import Ġcom . ion spin . kotlin . crypto . auth . Auth Ċ import Ġcom . ion spin . kotlin . crypto . auth . crypto _ auth _ BYTES Ċ import Ġcom . ion spin . kotlin . crypto . auth . crypto _ auth _ KEY BYTES Ċ import Ġcom . ion spin . kotlin . crypto . util . encode ToU ByteArray Ċ import Ġkotlin . math . round ToInt Ċ Ċ sealed Ġclass ĠH K DF Error ( override Ġval Ġmessage : ĠString ): ĠError () Ċ class ĠH K DF Invalid Salt Error : ĠH K DF Error (" Salt Ġlength Ġmust Ġmatch Ġexactly Ġthe Ġkey Ġlength Ġof Ġthe ĠHMAC Ġfunction .") Ċ class ĠH K DF Invalid Len Error : ĠH K DF Error (" Length Ġof Ġlen Ġmust Ġnot Ġbe Ġlarger Ġthan Ġ 2 5 5 Ġtimes Ġthe Ġlength Ġof Ġthe Ġhash Ġoutput .") Ċ class ĠHMAC Calculation Failed Error ( message : ĠString ): ĠH K DF Error (" HMAC Ġcalculation Ġfailed : Ġ$ message ") ĊĊ Ċ /** Ċ This Ġfunction Ġcalculates Ġa Ġkey Ġusing Ġa ĠH K DF Ġ( RFC Ġ 5 8 6 9 ) Ġwhich Ġuses ĠHMAC - SHA - 5 1 2 / 2 5 6 . Ċ - ĠParameters : Ċ - Ġi km : ĠInput Ġkey ing Ġmaterial Ċ - Ġsalt : ĠA Ġnonce Ġused Ġto Ġseed Ġthe ĠH K DF , Ġwhich Ġmust Ġbe Ġ 3 2 Ġbytes Ġlong , Ġif Ġprovided Ġ( optional ) Ċ - Ġinfo : ĠContext Ġand Ġapplication Ġspecific Ġinformation Ġ( optional ) Ċ - ĠL : ĠLength Ġof Ġthe Ġoutput Ġkey ing Ġmaterial Ġin Ġbytes , Ġmust Ġnot Ġbe Ġlarger Ġthan Ġ 2 5 5 Ġ* Ġ 3 2 Ġbytes Ċ - ĠReturns : ĠOutput Ġkey ing Ġmaterial Ġof Ġlength ĠL Ġbytes Ċ Ġ*/ Ċ fun Ġderive HK DF Key ( ik m : ĠU ByteArray , Ġ_ salt : ĠU ByteArray ? Ġ= Ġnull , Ġinfo : ĠString Ġ= Ġ"", Ġlen : ĠInt ) Ġ: ĠU ByteArray Ġ{ ĊĠĠĠ Ġval Ġhash Output Length Ġ= Ġcrypto _ auth _ BYTES ĊĠĠĠ Ġval Ġsalt Ġ= Ġ_ salt Ġ?: ĠU ByteArray ( hash Output Length ) Ġ{ 0 . to U Byte ()} ĊĊĠĠĠ Ġif Ġ( len Ġ> Ġ 2 5 5 Ġ* Ġhash Output Length ) Ġ{ Ġthrow ĠH K DF Invalid Len Error () Ġ} ĊĠĠĠ Ġif Ġ( salt . size Ġ!= Ġcrypto _ auth _ KEY BYTES ) Ġ{ Ġthrow ĠH K DF Invalid Salt Error () Ġ} ĊĊĠĠĠ Ġ// ĠStep Ġ 1 : ĠExtract ĊĠĠĠ Ġval Ġpr k Ġ= Ġtry Ġ{ ĊĠĠĠĠĠĠĠ ĠAuth . auth H mac Sha 2 5 6 ( ik m , Ġsalt ) ĊĠĠĠ Ġ} Ġcatch Ġ( t : ĠThrowable ){ ĊĠĠĠĠĠĠĠ Ġthrow ĠHMAC Calculation Failed Error ( t . message !! ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ// ĠStep Ġ 2 : ĠExpand ĊĠĠĠ Ġval ĠN Ġ= Ġ( len . toDouble ()/ hash Output Length . toDouble ()). round ToInt () ĊĠĠĠ Ġval ĠT Ġ= Ġarray ListOf < U Byte >() ĊĊĠĠĠ Ġvar Ġlast Ti Ġ= Ġ ubyte ArrayOf () ĊĠĠĠ Ġfor Ġ( i Ġin Ġ 1 Ġ.. ĠN ) Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġmessage Ġ= Ġarray ListOf < U Byte >() ĊĠĠĠĠĠĠĠ Ġmessage . addAll ( last Ti ) ĊĠĠĠĠĠĠĠ Ġmessage . addAll ( info . encode ToU ByteArray ()) ĊĠĠĠĠĠĠĠ Ġmessage . add ( i . to U Byte ()) ĊĊĠĠĠĠĠĠĠ Ġval Ġcurrent Ti Ġ= Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠAuth . auth H mac Sha 2 5 6 ( message . to U ByteArray (), Ġpr k ) ĊĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( t : ĠThrowable ){ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġthrow ĠHMAC Calculation Failed Error ( t . message !! ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ ĠT . addAll ( current Ti ) ĊĠĠĠĠĠĠĠ Ġlast Ti Ġ= Ġcurrent Ti ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġreturn ĠT . sub List ( 0 , Ġlen ). to U ByteArray () Ċ }