package Ġbit co ink it Ċ Ċ import Ġbit co ink it . Utils . double Digest Ċ import Ġjava . lang . StringBuilder Ċ import Ġjava . math . BigInteger Ċ import Ġjava . util .* Ċ Ċ /** Ċ Ġ* ĠA ĠH ierarchical ĠDetermin istic Ġkey Ċ Ġ*/ Ċ class ĠHD Key Ġ: ĠEC Key Ġ{ ĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠReturn Ġthe Ġchain Ġcode ĊĠĠĠĠ Ġ* ĊĠĠĠĠ Ġ* Ġ@ return ĠChain Ġcode ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠChain Ġcode ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġval Ġchain Code : ĠByteArray ĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠReturn Ġthe Ġparent ĊĠĠĠĠ Ġ* ĊĠĠĠĠ Ġ* Ġ@ return ĠParent Ġor Ġnull Ġif Ġthis Ġis Ġthe Ġroot Ġkey ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠHD Ġkey Ġparent Ġ( null Ġif Ġroot Ġkey ) ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġval Ġparent : ĠHD Key ? ĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠReturn Ġthe Ġchild Ġnumber ĊĠĠĠĠ Ġ* ĊĠĠĠĠ Ġ* Ġ@ return ĠChild Ġnumber ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠChild Ġnumber ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġval Ġchild Number : ĠInt ĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠCheck Ġif Ġthe Ġkey Ġis Ġhard ened ĊĠĠĠĠ Ġ* ĊĠĠĠĠ Ġ* Ġ@ return ĠTRUE Ġif Ġthe Ġkey Ġis Ġhard ened ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠHard ened Ġkey ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġval Ġis Hard ened : ĠBoolean ĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠReturn Ġthe Ġhierarchy Ġdepth ĊĠĠĠĠ Ġ* ĊĠĠĠĠ Ġ* Ġ@ return ĠH ierarchy Ġdepth Ġ( root Ġkey Ġis Ġdepth Ġ 0 ) ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠDepth Ġ( root Ġkey Ġis Ġdepth Ġ 0 ) ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġval Ġdepth : ĠInt ĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠReturn Ġthe Ġparent Ġfingerprint ĊĠĠĠĠ Ġ* ĊĠĠĠĠ Ġ* Ġ@ return ĠParent Ġfingerprint ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠParent Ġfingerprint Ġor Ġ 0 Ġif Ġroot Ġkey ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġval Ġparent Fingerprint : ĠInt ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠCreate Ġa Ġnew ĠHD Ġkey Ġfrom Ġa Ġprivate Ġkey ĊĠĠĠĠ Ġ* ĊĠĠĠĠ Ġ* Ġ@ param Ġpriv Key ĠĠĠĠ ĠPrivate Ġkey ĊĠĠĠĠ Ġ* Ġ@ param Ġchain Code ĠĠ ĠChain Ġcode ĊĠĠĠĠ Ġ* Ġ@ param Ġparent ĠĠĠĠĠ ĠParent Ġor Ġnull Ġif Ġno Ġparent ĊĠĠĠĠ Ġ* Ġ@ param Ġchild Number ĠChild Ġnumber Ġ( first Ġchild Ġis Ġ 0 ) ĊĠĠĠĠ Ġ* Ġ@ param Ġis Hard ened Ġ ĠTRUE Ġif Ġthe Ġchild Ġis Ġhard ened ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġconstructor ( priv Key : ĠBigInteger , Ġchain Code : ĠByteArray , Ġparent : ĠHD Key ?, Ġchild Number : ĠInt , Ġis Hard ened : ĠBoolean ) Ġ: Ġsuper ( priv Key , ĠEC Key . Companion . public Point From Private ( priv Key ), Ġtrue ) Ġ{ ĊĠĠĠĠĠĠĠ Ġrequire ( priv Key Bytes !!. size Ġ<= Ġ 3 3 ) Ġ{ Ġ" Private Ġkey Ġis Ġlonger Ġthan Ġ 3 3 Ġbytes " Ġ} ĊĠĠĠĠĠĠĠ Ġrequire ( chain Code . size Ġ== Ġ 3 2 ) Ġ{ Ġ" Chain Ġcode Ġis Ġnot Ġ 3 2 Ġbytes " Ġ} ĊĠĠĠĠĠĠĠ Ġcheck ( pub Key . size Ġ== Ġ 3 3 ) Ġ{ Ġ" Public Ġkey Ġis Ġnot Ġcompressed " Ġ} ĊĠĠĠĠĠĠĠ Ġthis . chain Code Ġ= ĠArrays . copyOf Range ( chain Code , Ġ 0 , Ġchain Code . size ) ĊĠĠĠĠĠĠĠ Ġthis . parent Ġ= Ġparent ĊĠĠĠĠĠĠĠ Ġthis . is Hard ened Ġ= Ġis Hard ened ĊĠĠĠĠĠĠĠ Ġthis . child Number Ġ= Ġchild Number ĊĠĠĠĠĠĠĠ Ġdepth Ġ= Ġif Ġ( parent Ġ!= Ġnull ) Ġparent . depth Ġ+ Ġ 1 Ġelse Ġ 0 ĊĠĠĠĠĠĠĠ Ġparent Fingerprint Ġ= Ġparent ?. fingerprint Ġ?: Ġ 0 ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠCreate Ġa Ġnew ĠHD Ġkey Ġfrom Ġa Ġpublic Ġkey . Ġ ĠThe ĠHD Ġkey Ġwill Ġnot Ġhave Ġa Ġprivate ĊĠĠĠĠ Ġ* Ġkey . ĊĠĠĠĠ Ġ* ĊĠĠĠĠ Ġ* Ġ@ param Ġpub Key ĠĠĠĠĠ ĠPublic Ġkey ĊĠĠĠĠ Ġ* Ġ@ param Ġchain Code ĠĠ ĠChain Ġcode ĊĠĠĠĠ Ġ* Ġ@ param Ġparent ĠĠĠĠĠ ĠParent Ġor Ġnull Ġif Ġno Ġparent ĊĠĠĠĠ Ġ* Ġ@ param Ġchild Number ĠChild Ġnumber Ġ( first Ġchild Ġis Ġ 0 ) ĊĠĠĠĠ Ġ* Ġ@ param Ġis Hard ened Ġ ĠTRUE Ġif Ġthe Ġchild Ġis Ġhard ened ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġconstructor ( pub Key : ĠByteArray , Ġchain Code : ĠByteArray , Ġparent : ĠHD Key ?, Ġchild Number : ĠInt , Ġis Hard ened : ĠBoolean ) Ġ: Ġsuper ( pub Key ) Ġ{ ĊĠĠĠĠĠĠĠ Ġrequire ( pub Key . size Ġ== Ġ 3 3 ) Ġ{ Ġ" Public Ġkey Ġis Ġnot Ġcompressed " Ġ} ĊĠĠĠĠĠĠĠ Ġrequire ( chain Code . size Ġ== Ġ 3 2 ) Ġ{ Ġ" Chain Ġcode Ġis Ġnot Ġ 3 2 Ġbytes " Ġ} ĊĠĠĠĠĠĠĠ Ġthis . chain Code Ġ= ĠArrays . copyOf Range ( chain Code , Ġ 0 , Ġchain Code . size ) ĊĠĠĠĠĠĠĠ Ġthis . parent Ġ= Ġparent ĊĠĠĠĠĠĠĠ Ġthis . is Hard ened Ġ= Ġis Hard ened ĊĠĠĠĠĠĠĠ Ġthis . child Number Ġ= Ġchild Number ĊĠĠĠĠĠĠĠ Ġdepth Ġ= Ġif Ġ( parent Ġ!= Ġnull ) Ġparent . depth Ġ+ Ġ 1 Ġelse Ġ 0 ĊĠĠĠĠĠĠĠ Ġparent Fingerprint Ġ= Ġparent ?. fingerprint Ġ?: Ġ 0 ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠReturn Ġprivate Ġkey Ġpadded Ġto Ġ 3 3 Ġbytes ĊĠĠĠĠ Ġ* ĊĠĠĠĠ Ġ* Ġ@ return ĠP added Ġprivate Ġkey ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġval Ġpadded Priv Key Bytes : ĠByteArray ĊĠĠĠĠĠĠĠ Ġget () Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġpriv Key Bytes Ġ= Ġpriv Key Bytes ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġpadded Bytes Ġ= ĠByteArray ( 3 3 ) ĊĠĠĠĠĠĠĠĠĠĠĠ ĠSystem . arraycopy ( priv Key Bytes !! , Ġ 0 , Ġpadded Bytes , Ġ 3 3 Ġ- Ġpriv Key Bytes . size , Ġpriv Key Bytes . size ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġpadded Bytes ĊĠĠĠĠĠĠĠ Ġ}// ĊĠĠĠ Ġ// ĠThe Ġfingerprint Ġis Ġthe Ġfirst Ġ 3 2 Ġbits Ġof ĠHASH 1 6 0 ( pub Key ) ĊĠĠĠ Ġ// ĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠReturn Ġthe Ġpublic Ġkey Ġfingerprint ĊĠĠĠĠ Ġ* ĊĠĠĠĠ Ġ* Ġ@ return ĠF ingerprint ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġval Ġfingerprint : ĠInt ĊĠĠĠĠĠĠĠ Ġget () Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠThe Ġfingerprint Ġis Ġthe Ġfirst Ġ 3 2 Ġbits Ġof ĠHASH 1 6 0 ( pub Key ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġpub Key Hash Ġ= Ġpub Key Hash ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġpub Key Hash ! ![ 0 ]. toInt () Ġand Ġ 2 5 5 Ġshl Ġ 2 4 Ġor Ġ( pub Key Hash [ 1 ]. toInt () Ġand Ġ 2 5 5 Ġshl Ġ 1 6 ) Ġor ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ( pub Key Hash [ 2 ]. toInt () Ġand Ġ 2 5 5 Ġshl Ġ 8 ) Ġor Ġ( pub Key Hash [ 3 ]. toInt () Ġand Ġ 2 5 5 ) ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠAdd Ġthe Ġ 4 - byte Ġchecksum Ġto Ġthe Ġserialized Ġkey ĊĠĠĠĠ Ġ* ĊĠĠĠĠ Ġ* Ġ@ param Ġinput ĠSerialized Ġkey ĊĠĠĠĠ Ġ* Ġ@ return ĠKey Ġplus Ġchecksum ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġprivate Ġfun Ġadd Checksum ( input : ĠByteArray ): ĠByteArray Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġinput Length Ġ= Ġinput . size ĊĠĠĠĠĠĠĠ Ġval Ġchecksum med Ġ= ĠByteArray ( input Length Ġ+ Ġ 4 ) ĊĠĠĠĠĠĠĠ ĠSystem . arraycopy ( input , Ġ 0 , Ġchecksum med , Ġ 0 , Ġinput Length ) ĊĠĠĠĠĠĠĠ Ġval Ġchecksum : ĠByteArray Ġ= Ġdouble Digest ( input ) ĊĠĠĠĠĠĠĠ ĠSystem . arraycopy ( checksum , Ġ 0 , Ġchecksum med , Ġinput Length , Ġ 4 ) ĊĠĠĠĠĠĠĠ Ġreturn Ġchecksum med ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠGet Ġthe Ġpath Ġfrom Ġthe Ġroot Ġkey ĊĠĠĠĠ Ġ* ĊĠĠĠĠ Ġ* Ġ@ return ĠList Ġof Ġnode Ġnumbers ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġval Ġpath : ĠMutable List < Int > ĊĠĠĠĠĠĠĠ Ġget () Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġpath : ĠMutable List < Int > ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( parent Ġ!= Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġpath Ġ= Ġparent . path ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġpath . add ( child Number ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġpath Ġ= ĠArrayList () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġpath ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠGet Ġstring Ġrepresentation Ġof Ġthis Ġkey ĊĠĠĠĠ Ġ* ĊĠĠĠĠ Ġ* Ġ@ return ĠPath Ġstring ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġoverride Ġfun ĠtoString (): ĠString Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġsb Ġ= ĠStringBuilder () ĊĠĠĠĠĠĠĠ Ġreturn Ġif Ġ( parent Ġ!= Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġparent Path Ġ= Ġparent . toString () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġsb . append ( parent Path ). append ("/ "). append ( child Number ). append ( if Ġ( is Hard ened ) Ġ"'" Ġelse Ġ"") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġsb . toString () ĊĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ" m " ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġcompanion Ġobject Ġ{ ĊĠĠĠĠĠĠĠ Ġ/** ĊĠĠĠĠĠĠĠĠ Ġ* ĠChild Ġis Ġhard ened ĊĠĠĠĠĠĠĠĠ Ġ*/ ĊĠĠĠĠĠĠĠ Ġconst Ġval ĠH ARD EN ED _ FLAG Ġ= Ġ- 0 x 8 0 0 0 0 0 0 0 ĊĠĠĠ Ġ} Ċ }