/* Ċ Ġ* ĠCopyright Ġ 2 0 2 0 ĠAC IN Q ĠSAS Ċ Ġ* Ċ Ġ* Ġ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 Ġfr . ac in q . bitcoin Ċ Ċ import Ġfr . ac in q . bitcoin . Determin istic Wallet . hard ened Ċ import Ġfr . ac in q . bitcoin . crypto . Pack Ċ import Ġfr . ac in q . bitcoin . io . ByteArray Input Ċ import Ġfr . ac in q . bitcoin . io . ByteArray Output Ċ import Ġfr . ac in q . bitcoin . io . Output Ċ import Ġkotlin . jvm . Jvm Field Ċ import Ġkotlin . jvm . Jvm Static Ċ Ċ /** Ċ Ġ* Ġsee Ġhttps :// github . com / bitcoin / b ips / blob / master / bip - 0 0 3 2 . medi aw iki Ċ Ġ*/ Ċ @ Opt In ( Experimental Unsigned Types :: class ) Ċ public Ġobject ĠDetermin istic Wallet Ġ{ ĊĠĠĠ Ġpublic Ġconst Ġval Ġhard ened Key Index : ĠLong Ġ= Ġ 0 x 8 0 0 0 0 0 0 0 L ĊĊĠĠĠ Ġ@ Jvm Static ĊĠĠĠ Ġpublic Ġfun Ġhard ened ( index : ĠLong ): ĠLong Ġ= Ġhard ened Key Index Ġ+ Ġindex ĊĊĠĠĠ Ġ@ Jvm Static ĊĠĠĠ Ġpublic Ġfun Ġis Hard ened ( index : ĠLong ): ĠBoolean Ġ= Ġindex Ġ>= Ġhard ened Key Index ĊĊĠĠĠ Ġpublic Ġdata Ġclass ĠExtended PrivateKey ( ĊĠĠĠĠĠĠĠ Ġ@ Jvm Field Ġval Ġsecret key bytes : ĠByte Vector 3 2 , ĊĠĠĠĠĠĠĠ Ġ@ Jvm Field Ġval Ġchain code : ĠByte Vector 3 2 , ĊĠĠĠĠĠĠĠ Ġ@ Jvm Field Ġval Ġdepth : ĠInt , ĊĠĠĠĠĠĠĠ Ġ@ Jvm Field Ġval Ġpath : ĠKey Path , ĊĠĠĠĠĠĠĠ Ġ@ Jvm Field Ġval Ġparent : ĠLong ĊĠĠĠ Ġ) Ġ{ ĊĠĠĠĠĠĠĠ Ġinit Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġrequire ( Crypto . is Priv Key Valid ( secret key bytes . toByteArray ())) Ġ{ Ġ" private Ġkey Ġis Ġinvalid " Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġrequire ( depth Ġ!= Ġ 0 Ġ|| Ġparent Ġ== Ġ 0 L ) Ġ{ Ġ" zero Ġdepth Ġwith Ġnon - zero Ġparent Ġfingerprint " Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġrequire ( depth Ġ!= Ġ 0 Ġ|| Ġpath . last Child Number Ġ== Ġ 0 L ) Ġ{ Ġ" zero Ġdepth Ġwith Ġnon - zero Ġchild Ġnumber " Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġval ĠprivateKey : ĠPrivate Key Ġget () Ġ= ĠPrivate Key ( secret key bytes ) ĊĠĠĠĠĠĠĠ Ġval ĠpublicKey : ĠPublicKey Ġget () Ġ= ĠprivateKey . publicKey () ĊĊĠĠĠĠĠĠĠ Ġ/** ĊĠĠĠĠĠĠĠĠ Ġ* ĠWe Ġavoid Ġaccidentally Ġlogging Ġextended Ġprivate Ġkeys . ĊĠĠĠĠĠĠĠĠ Ġ* ĠYou Ġshould Ġuse Ġan Ġexplicit Ġmethod Ġif Ġyou Ġwant Ġto Ġconvert Ġthe Ġextended Ġprivate Ġkey Ġto Ġa Ġstring Ġrepresentation . ĊĠĠĠĠĠĠĠĠ Ġ*/ ĊĠĠĠĠĠĠĠ Ġoverride Ġfun ĠtoString (): ĠString Ġ= Ġ"< extended _ private _ key >" ĊĊĠĠĠĠĠĠĠ Ġpublic Ġcompanion Ġobject Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ@ Jvm Static ĊĠĠĠĠĠĠĠĠĠĠĠ Ġpublic Ġfun Ġdecode ( input : ĠString , Ġparent Path : ĠKey Path Ġ= ĠKey Path . empty ): ĠPair < Int , ĠExtended PrivateKey > Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġ( prefix , Ġbin ) Ġ= ĠBase 5 8 Check . decode With Int Prefix ( input ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġrequire ( prefix Ġ== Ġx prv Ġ|| Ġprefix Ġ== Ġy prv Ġ|| Ġprefix Ġ== Ġz prv Ġ|| Ġprefix Ġ== Ġt prv Ġ|| Ġprefix Ġ== Ġup rv Ġ|| Ġprefix Ġ== Ġv prv ) Ġ{ Ġ" invalid Ġprefix " Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġbis Ġ= ĠByteArray Input ( bin ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġdepth Ġ= Ġbis . read () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġparent Ġ= ĠPack . int 3 2 BE ( bis ). to Long () Ġand Ġ 0 xffffffff ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġchild Number Ġ= ĠPack . int 3 2 BE ( bis ). to Long () Ġand Ġ 0 xffffffff ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġchain code Ġ= ĠByteArray ( 3 2 ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġbis . read ( chain code , Ġ 0 ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġrequire ( bis . read () Ġ== Ġ 0 ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġsecret Key Bytes Ġ= ĠByteArray ( 3 2 ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġbis . read ( secret Key Bytes , Ġ 0 ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĠPair ( prefix , ĠExtended PrivateKey ( secret Key Bytes . byte Vector 3 2 (), Ġchain code . byte Vector 3 2 (), Ġdepth , Ġparent Path . derive ( child Number ), Ġparent )) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġpublic Ġdata Ġclass ĠExtended PublicKey ( ĊĠĠĠĠĠĠĠ Ġ@ Jvm Field Ġval Ġpublic key bytes : ĠByte Vector , ĊĠĠĠĠĠĠĠ Ġ@ Jvm Field Ġval Ġchain code : ĠByte Vector 3 2 , ĊĠĠĠĠĠĠĠ Ġ@ Jvm Field Ġval Ġdepth : ĠInt , ĊĠĠĠĠĠĠĠ Ġ@ Jvm Field Ġval Ġpath : ĠKey Path , ĊĠĠĠĠĠĠĠ Ġ@ Jvm Field Ġval Ġparent : ĠLong ĊĠĠĠ Ġ) Ġ{ ĊĠĠĠĠĠĠĠ Ġinit Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġrequire ( public key bytes . size () Ġ== Ġ 3 3 ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġrequire ( Crypto . is PubKey Valid ( public key bytes . toByteArray ())) Ġ{ Ġ" public Ġkey Ġis Ġinvalid " Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġrequire ( depth Ġ!= Ġ 0 Ġ|| Ġparent Ġ== Ġ 0 L ) Ġ{ Ġ" zero Ġdepth Ġwith Ġnon - zero Ġparent Ġfingerprint " Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġrequire ( depth Ġ!= Ġ 0 Ġ|| Ġpath . last Child Number Ġ== Ġ 0 L ) Ġ{ Ġ" zero Ġdepth Ġwith Ġnon - zero Ġchild Ġnumber " Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġval ĠpublicKey : ĠPublicKey Ġget () Ġ= ĠPublicKey ( public key bytes ) ĊĊĠĠĠĠĠĠĠ Ġpublic Ġcompanion Ġobject Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ@ Jvm Static ĊĠĠĠĠĠĠĠĠĠĠĠ Ġpublic Ġfun Ġdecode ( input : ĠString , Ġparent Path : ĠKey Path Ġ= ĠKey Path . empty ): ĠPair < Int , ĠExtended PublicKey > Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġ( prefix , Ġbin ) Ġ= ĠBase 5 8 Check . decode With Int Prefix ( input ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġrequire ( prefix Ġ== Ġx pub Ġ|| Ġprefix Ġ== Ġy pub Ġ|| Ġprefix Ġ== Ġz pub Ġ|| Ġprefix Ġ== Ġt pub Ġ|| Ġprefix Ġ== Ġup ub Ġ|| Ġprefix Ġ== Ġv pub ) Ġ{ Ġ" invalid Ġprefix " Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġbis Ġ= ĠByteArray Input ( bin ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġdepth Ġ= Ġbis . read () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġparent Ġ= ĠPack . int 3 2 BE ( bis ). to Long () Ġand Ġ 0 xffffffff ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġchild Number Ġ= ĠPack . int 3 2 BE ( bis ). to Long () Ġand Ġ 0 xffffffff ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġchain code Ġ= ĠByteArray ( 3 2 ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġbis . read ( chain code , Ġ 0 ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval ĠpublicKey Bytes Ġ= ĠByteArray ( 3 3 ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġbis . read ( publicKey Bytes , Ġ 0 ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĠPair ( prefix , ĠExtended PublicKey ( publicKey Bytes . byte Vector (), Ġchain code . byte Vector 3 2 (), Ġdepth , Ġparent Path . derive ( child Number ), Ġparent )) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ Jvm Static ĊĠĠĠ Ġpublic Ġfun Ġencode ( input : ĠExtended PrivateKey , Ġtest net : ĠBoolean ): ĠString Ġ= Ġencode ( input , Ġif Ġ( test net ) Ġt prv Ġelse Ġx prv ) ĊĊĠĠĠ Ġ@ Jvm Static ĊĠĠĠ Ġpublic Ġfun Ġencode ( input : ĠExtended PrivateKey , Ġprefix : ĠInt ): ĠString Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġout Ġ= ĠByteArray Output () ĊĠĠĠĠĠĠĠ Ġout . write ( input . depth ) ĊĠĠĠĠĠĠĠ ĠPack . writeInt 3 2 BE ( input . parent . toInt (), Ġout ) ĊĠĠĠĠĠĠĠ ĠPack . writeInt 3 2 BE ( input . path . last Child Number . toInt (), Ġout ) ĊĠĠĠĠĠĠĠ Ġout . write ( input . chain code . toByteArray ()) ĊĠĠĠĠĠĠĠ Ġout . write ( 0 ) ĊĠĠĠĠĠĠĠ Ġout . write ( input . secret key bytes . toByteArray ()) ĊĠĠĠĠĠĠĠ Ġval Ġbuffer Ġ= Ġout . toByteArray () ĊĠĠĠĠĠĠĠ Ġreturn ĠBase 5 8 Check . encode ( prefix , Ġbuffer ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ Jvm Static ĊĠĠĠ Ġpublic Ġfun Ġencode ( input : ĠExtended PublicKey , Ġtest net : ĠBoolean ): ĠString Ġ= Ġencode ( input , Ġif Ġ( test net ) Ġt pub Ġelse Ġx pub ) ĊĊĠĠĠ Ġ@ Jvm Static ĊĠĠĠ Ġpublic Ġfun Ġencode ( input : ĠExtended PublicKey , Ġprefix : ĠInt ): ĠString Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġout Ġ= ĠByteArray Output () ĊĠĠĠĠĠĠĠ Ġwrite ( input , Ġout ) ĊĠĠĠĠĠĠĠ Ġval Ġbuffer Ġ= Ġout . toByteArray () ĊĠĠĠĠĠĠĠ Ġreturn ĠBase 5 8 Check . encode ( prefix , Ġbuffer ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ Jvm Static ĊĠĠĠ Ġpublic Ġfun Ġwrite ( input : ĠExtended PublicKey , Ġout : ĠOutput ) Ġ{ ĊĠĠĠĠĠĠĠ Ġout . write ( input . depth ) ĊĠĠĠĠĠĠĠ ĠPack . writeInt 3 2 BE ( input . parent . toInt (), Ġout ) ĊĠĠĠĠĠĠĠ ĠPack . writeInt 3 2 BE ( input . path . last Child Number . toInt (), Ġout ) ĊĠĠĠĠĠĠĠ Ġout . write ( input . chain code . toByteArray ()) ĊĠĠĠĠĠĠĠ Ġout . write ( input . public key bytes . toByteArray ()) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* Ġ@ param Ġseed Ġrandom Ġseed ĊĠĠĠĠ Ġ* Ġ@ return Ġa Ġ" master " Ġprivate Ġkey ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġ@ Jvm Static ĊĠĠĠ Ġpublic Ġfun Ġgenerate ( seed : ĠByteArray ): ĠExtended PrivateKey Ġ{ ĊĠĠĠĠĠĠĠ Ġval ĠI Ġ= ĠCrypto . hmac 5 1 2 (" Bitcoin Ġseed ". encode To ByteArray (), Ġseed ) ĊĠĠĠĠĠĠĠ Ġval ĠIL Ġ= ĠI . take ( 3 2 ). toByteArray (). byte Vector 3 2 () ĊĠĠĠĠĠĠĠ Ġval ĠIR Ġ= ĠI . take Last ( 3 2 ). toByteArray (). byte Vector 3 2 () ĊĠĠĠĠĠĠĠ Ġreturn ĠExtended PrivateKey ( IL , ĠIR , Ġdepth Ġ= Ġ 0 , Ġpath Ġ= ĠKey Path . empty , Ġparent Ġ= Ġ 0 L ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* Ġ@ param Ġseed Ġrandom Ġseed ĊĠĠĠĠ Ġ* Ġ@ return Ġa Ġ" master " Ġprivate Ġkey ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġ@ Jvm Static ĊĠĠĠ Ġpublic Ġfun Ġgenerate ( seed : ĠByte Vector ): ĠExtended PrivateKey Ġ= Ġgenerate ( seed . toByteArray ()) ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* Ġ@ param Ġinput Ġextended Ġprivate Ġkey ĊĠĠĠĠ Ġ* Ġ@ return Ġthe Ġpublic Ġkey Ġfor Ġthis Ġprivate Ġkey ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġ@ Jvm Static ĊĠĠĠ Ġpublic Ġfun ĠpublicKey ( input : ĠExtended PrivateKey ): ĠExtended PublicKey Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn ĠExtended PublicKey ( input . publicKey . value , Ġinput . chain code , Ġdepth Ġ= Ġinput . depth , Ġpath Ġ= Ġinput . path , Ġparent Ġ= Ġinput . parent ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* Ġ@ param Ġinput Ġextended Ġpublic Ġkey ĊĠĠĠĠ Ġ* Ġ@ return Ġthe Ġfingerprint Ġfor Ġthis Ġpublic Ġkey ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġ@ Jvm Static ĊĠĠĠ Ġpublic Ġfun Ġfingerprint ( input : ĠExtended PublicKey ): ĠLong Ġ= ĠPack . int 3 2 LE ( ByteArray Input ( Crypto . hash 1 6 0 ( input . public key bytes ). take ( 4 ). reversed (). toByteArray ())). to Long () ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* Ġ@ param Ġinput Ġextended Ġprivate Ġkey ĊĠĠĠĠ Ġ* Ġ@ return Ġthe Ġfingerprint Ġfor Ġthis Ġprivate Ġkey Ġ( which Ġis Ġbased Ġon Ġthe Ġcorresponding Ġpublic Ġkey ) ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġ@ Jvm Static ĊĠĠĠ Ġpublic Ġfun Ġfingerprint ( input : ĠExtended PrivateKey ): ĠLong Ġ= Ġfingerprint ( publicKey ( input )) ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* Ġ@ param Ġparent Ġextended Ġprivate Ġkey ĊĠĠĠĠ Ġ* Ġ@ param Ġindex Ġ Ġindex Ġof Ġthe Ġchild Ġkey ĊĠĠĠĠ Ġ* Ġ@ return Ġthe Ġderived Ġprivate Ġkey Ġat Ġthe Ġspecified Ġindex ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġ@ Jvm Static ĊĠĠĠ Ġpublic Ġfun Ġderive PrivateKey ( parent : ĠExtended PrivateKey , Ġindex : ĠLong ): ĠExtended PrivateKey Ġ{ ĊĠĠĠĠĠĠĠ Ġval ĠI Ġ= Ġif Ġ( is Hard ened ( index )) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġdata Ġ= ĠarrayOf ( 0 . to Byte ()). toByteArray () Ġ+ Ġparent . secret key bytes . toByteArray () Ġ+ ĠPack . writeInt 3 2 BE ( index . toInt ()) ĊĠĠĠĠĠĠĠĠĠĠĠ ĠCrypto . hmac 5 1 2 ( parent . chain code . toByteArray (), Ġdata ) ĊĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġdata Ġ= ĠpublicKey ( parent ). public key bytes . toByteArray () Ġ+ ĠPack . writeInt 3 2 BE ( index . toInt ()) ĊĠĠĠĠĠĠĠĠĠĠĠ ĠCrypto . hmac 5 1 2 ( parent . chain code . toByteArray (), Ġdata ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġval ĠIL Ġ= ĠI . take ( 3 2 ). toByteArray () ĊĠĠĠĠĠĠĠ Ġval ĠIR Ġ= ĠI . take Last ( 3 2 ). toByteArray () ĊĠĠĠĠĠĠĠ Ġrequire ( Crypto . is Priv Key Valid ( IL )) Ġ{ Ġ" cannot Ġgenerate Ġchild Ġprivate Ġkey : ĠIL Ġis Ġinvalid " Ġ} ĊĊĠĠĠĠĠĠĠ Ġval Ġkey Ġ= ĠPrivate Key ( IL ) Ġ+ Ġparent . privateKey ĊĠĠĠĠĠĠĠ Ġrequire ( Crypto . is Priv Key Valid ( key . value . toByteArray ())) Ġ{ Ġ" cannot Ġgenerate Ġchild Ġprivate Ġkey : Ġresulting Ġprivate Ġkey Ġis Ġinvalid " Ġ} ĊĠĠĠĠĠĠĠ Ġreturn ĠExtended PrivateKey ( ĊĠĠĠĠĠĠĠĠĠĠĠ Ġsecret key bytes Ġ= Ġkey . value , ĊĠĠĠĠĠĠĠĠĠĠĠ Ġchain code Ġ= ĠIR . byte Vector 3 2 (), ĊĠĠĠĠĠĠĠĠĠĠĠ Ġdepth Ġ= Ġparent . depth Ġ+ Ġ 1 , ĊĠĠĠĠĠĠĠĠĠĠĠ Ġpath Ġ= Ġparent . path . derive ( index ), ĊĠĠĠĠĠĠĠĠĠĠĠ Ġparent Ġ= Ġfingerprint ( parent ) ĊĠĠĠĠĠĠĠ Ġ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* Ġ@ param Ġparent Ġextended Ġpublic Ġkey ĊĠĠĠĠ Ġ* Ġ@ param Ġindex Ġ Ġindex Ġof Ġthe Ġchild Ġkey ĊĠĠĠĠ Ġ* Ġ@ return Ġthe Ġderived Ġpublic Ġkey Ġat Ġthe Ġspecified Ġindex ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġ@ Jvm Static ĊĠĠĠ Ġpublic Ġfun Ġderive PublicKey ( parent : ĠExtended PublicKey , Ġindex : ĠLong ): ĠExtended PublicKey Ġ{ ĊĠĠĠĠĠĠĠ Ġrequire (! is Hard ened ( index )) Ġ{ Ġ" Cannot Ġderive Ġpublic Ġkeys Ġfrom Ġpublic Ġhard ened Ġkeys " Ġ} ĊĊĠĠĠĠĠĠĠ Ġval ĠI Ġ= ĠCrypto . hmac 5 1 2 ( ĊĠĠĠĠĠĠĠĠĠĠĠ Ġparent . chain code . toByteArray (), ĊĠĠĠĠĠĠĠĠĠĠĠ Ġparent . public key bytes . toByteArray () Ġ+ ĠPack . writeInt 3 2 BE ( index . toInt ()) ĊĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠ Ġval ĠIL Ġ= ĠI . take ( 3 2 ). toByteArray () ĊĠĠĠĠĠĠĠ Ġval ĠIR Ġ= ĠI . take Last ( 3 2 ). toByteArray () ĊĠĠĠĠĠĠĠ Ġrequire ( Crypto . is Priv Key Valid ( IL )) Ġ{ Ġ" cannot Ġgenerate Ġchild Ġpublic Ġkey : ĠIL Ġis Ġinvalid " Ġ} ĊĊĠĠĠĠĠĠĠ Ġval ĠKi Ġ= ĠPrivate Key ( IL ). publicKey () Ġ+ Ġparent . publicKey ĊĠĠĠĠĠĠĠ Ġrequire ( Crypto . is PubKey Valid ( Ki . value . toByteArray ())) Ġ{ Ġ" cannot Ġgenerate Ġchild Ġpublic Ġkey : Ġresulting Ġpublic Ġkey Ġis Ġinvalid " Ġ} ĊĠĠĠĠĠĠĠ Ġreturn ĠExtended PublicKey ( ĊĠĠĠĠĠĠĠĠĠĠĠ Ġpublic key bytes Ġ= ĠKi . value , ĊĠĠĠĠĠĠĠĠĠĠĠ Ġchain code Ġ= ĠIR . byte Vector 3 2 (), ĊĠĠĠĠĠĠĠĠĠĠĠ Ġdepth Ġ= Ġparent . depth Ġ+ Ġ 1 , ĊĠĠĠĠĠĠĠĠĠĠĠ Ġpath Ġ= Ġparent . path . derive ( index ), ĊĠĠĠĠĠĠĠĠĠĠĠ Ġparent Ġ= Ġfingerprint ( parent ) ĊĠĠĠĠĠĠĠ Ġ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ Jvm Static ĊĠĠĠ Ġpublic Ġfun Ġderive PrivateKey ( parent : ĠExtended PrivateKey , Ġchain : ĠList < Long >): ĠExtended PrivateKey Ġ= ĊĠĠĠĠĠĠĠ Ġchain . fold ( parent , ĠDetermin istic Wallet :: derive PrivateKey ) ĊĊĠĠĠ Ġ@ Jvm Static ĊĠĠĠ Ġpublic Ġfun Ġderive PrivateKey ( parent : ĠExtended PrivateKey , Ġkey Path : ĠKey Path ): ĠExtended PrivateKey Ġ= ĊĠĠĠĠĠĠĠ Ġderive PrivateKey ( parent , Ġkey Path . path ) ĊĊĠĠĠ Ġ@ Jvm Static ĊĠĠĠ Ġpublic Ġfun Ġderive PrivateKey ( parent : ĠExtended PrivateKey , Ġkey Path : ĠString ): ĠExtended PrivateKey Ġ= ĊĠĠĠĠĠĠĠ Ġderive PrivateKey ( parent , ĠKey Path . from Path ( key Path )) ĊĊĠĠĠ Ġ@ Jvm Static ĊĠĠĠ Ġpublic Ġfun Ġderive PublicKey ( parent : ĠExtended PublicKey , Ġchain : ĠList < Long >): ĠExtended PublicKey Ġ= ĊĠĠĠĠĠĠĠ Ġchain . fold ( parent , ĠDetermin istic Wallet :: derive PublicKey ) ĊĊĠĠĠ Ġ@ Jvm Static ĊĠĠĠ Ġpublic Ġfun Ġderive PublicKey ( parent : ĠExtended PublicKey , Ġkey Path : ĠKey Path ): ĠExtended PublicKey Ġ= ĊĠĠĠĠĠĠĠ Ġderive PublicKey ( parent , Ġkey Path . path ) ĊĊĠĠĠ Ġ@ Jvm Static ĊĠĠĠ Ġpublic Ġfun Ġderive PublicKey ( parent : ĠExtended PublicKey , Ġkey Path : ĠString ): ĠExtended PublicKey Ġ= ĊĠĠĠĠĠĠĠ Ġderive PublicKey ( parent , ĠKey Path . from Path ( key Path )) ĊĊĠĠĠ Ġ// Ġp 2 pk h Ġmain net ĊĠĠĠ Ġpublic Ġconst Ġval Ġx prv : ĠInt Ġ= Ġ 0 x 0 4 8 8 ade 4 ĊĠĠĠ Ġpublic Ġconst Ġval Ġx pub : ĠInt Ġ= Ġ 0 x 0 4 8 8 b 2 1 e ĊĊĠĠĠ Ġ// Ġp 2 sh - of - p 2 w pk h Ġmain net ĊĠĠĠ Ġpublic Ġconst Ġval Ġy prv : ĠInt Ġ= Ġ 0 x 0 4 9 d 7 8 7 8 ĊĠĠĠ Ġpublic Ġconst Ġval Ġy pub : ĠInt Ġ= Ġ 0 x 0 4 9 d 7 cb 2 ĊĊĠĠĠ Ġ// Ġp 2 w pk h Ġmain net ĊĠĠĠ Ġpublic Ġconst Ġval Ġz prv : ĠInt Ġ= Ġ 0 x 0 4 b 2 4 3 0 c ĊĠĠĠ Ġpublic Ġconst Ġval Ġz pub : ĠInt Ġ= Ġ 0 x 0 4 b 2 4 7 4 6 ĊĊĠĠĠ Ġ// Ġp 2 pk h Ġtest net ĊĠĠĠ Ġpublic Ġconst Ġval Ġt prv : ĠInt Ġ= Ġ 0 x 0 4 3 5 8 3 9 4 ĊĠĠĠ Ġpublic Ġconst Ġval Ġt pub : ĠInt Ġ= Ġ 0 x 0 4 3 5 8 7 cf ĊĊĠĠĠ Ġ// Ġp 2 sh - of - p 2 w pk h Ġtest net ĊĠĠĠ Ġpublic Ġconst Ġval Ġup rv : ĠInt Ġ= Ġ 0 x 0 4 4 a 4 e 2 8 ĊĠĠĠ Ġpublic Ġconst Ġval Ġup ub : ĠInt Ġ= Ġ 0 x 0 4 4 a 5 2 6 2 ĊĊĠĠĠ Ġ// Ġp 2 w pk h Ġtest net ĊĠĠĠ Ġpublic Ġconst Ġval Ġv prv : ĠInt Ġ= Ġ 0 x 0 4 5 f 1 8 bc ĊĠĠĠ Ġpublic Ġconst Ġval Ġv pub : ĠInt Ġ= Ġ 0 x 0 4 5 f 1 cf 6 Ċ } Ċ Ċ public Ġdata Ġclass ĠKey Path (@ Jvm Field Ġval Ġpath : ĠList < Long >) Ġ{ ĊĠĠĠ Ġpublic Ġconstructor ( path : ĠString ) Ġ: Ġthis ( compute Path ( path )) ĊĊĠĠĠ Ġpublic Ġval Ġlast Child Number : ĠLong Ġget () Ġ= Ġif Ġ( path . isEmpty ()) Ġ 0 L Ġelse Ġpath . last () ĊĊĠĠĠ Ġpublic Ġfun Ġderive ( number : ĠLong ): ĠKey Path Ġ= ĠKey Path ( path Ġ+ ĠlistOf ( number )) ĊĊĠĠĠ Ġpublic Ġfun Ġappend ( index : ĠLong ): ĠKey Path Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn ĠKey Path ( path Ġ+ ĠlistOf ( index )) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġpublic Ġfun Ġappend ( indexes : ĠList < Long >): ĠKey Path Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn ĠKey Path ( path Ġ+ Ġindexes ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġpublic Ġfun Ġappend ( that : ĠKey Path ): ĠKey Path Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn ĠKey Path ( path Ġ+ Ġthat . path ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun ĠtoString (): ĠString Ġ= Ġpath . map Ġ{ Ġchild Number ToString ( it ) Ġ}. fold (" m ") Ġ{ Ġa , Ġb Ġ-> Ġ"$ a /$ b " Ġ} ĊĊĠĠĠ Ġpublic Ġcompanion Ġobject Ġ{ ĊĠĠĠĠĠĠĠ Ġpublic Ġval Ġempty : ĠKey Path Ġ= ĠKey Path ( listOf ()) ĊĊĠĠĠĠĠĠĠ Ġ@ Jvm Static ĊĠĠĠĠĠĠĠ Ġpublic Ġfun Ġcompute Path ( path : ĠString ): ĠList < Long > Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġfun Ġto Number ( value : ĠString ): ĠLong Ġ= Ġif Ġ( value . last () Ġ== Ġ'\' ') Ġhard ened ( value . drop Last ( 1 ). to Long ()) Ġelse Ġvalue . to Long () ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġpath 1 Ġ= Ġpath . remove Prefix (" m "). remove Prefix ("/") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġif Ġ( path 1 . isEmpty ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠlistOf () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġpath 1 . split ('/ '). map Ġ{ Ġto Number ( it ) Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġ@ Jvm Static ĊĠĠĠĠĠĠĠ Ġpublic Ġfun Ġfrom Path ( path : ĠString ): ĠKey Path Ġ= ĠKey Path ( path ) ĊĊĠĠĠĠĠĠĠ Ġpublic Ġfun Ġchild Number ToString ( child Number : ĠLong ): ĠString Ġ= Ġif Ġ( Determin istic Wallet . is Hard ened ( child Number )) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ(( child Number Ġ- ĠDetermin istic Wallet . hard ened Key Index ). toString () Ġ+ Ġ"' ") ĊĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġchild Number . toString () ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} Ċ }