// ĠCopyright Ġ( c ) Ġ 2 0 2 0 ĠFigure ĠTechnologies ĠInc . Ċ // ĠThe Ġcontents Ġof Ġthis Ġfile Ġwere Ġderived Ġfrom Ġan Ġimplementation Ċ // Ġby Ġthe Ġbt cs uite Ġdevelopers Ġhttps :// github . com / bt cs uite / btc util . Ċ Ċ // ĠCopyright Ġ( c ) Ġ 2 0 1 7 ĠThe Ġbt cs uite Ġdevelopers Ċ // ĠUse Ġof Ġthis Ġsource Ġcode Ġis Ġgoverned Ġby Ġan ĠI SC Ċ // Ġlicense Ġthat Ġcan Ġbe Ġfound Ġin Ġthe ĠLICENSE Ġfile . Ċ Ċ package Ġio . pro venance . digital currency . con sort ium . wallet . hd wallet Ċ Ċ import Ġcom . google . common . io . Base Encoding Ċ Ċ infix Ġfun ĠU Byte . sh l ( bit Count : ĠInt ) Ġ= Ġ(( this . toInt () Ġshl Ġbit Count ) Ġand Ġ 0 xff ). to U Byte () Ċ infix Ġfun ĠU Byte . shr ( bit Count : ĠInt ) Ġ= Ġ( this . toInt () Ġshr Ġbit Count ). to U Byte () Ċ Ċ /** Ċ Ġ* ĠGiven Ġan Ġarray Ġof Ġbytes , Ġassociate Ġan ĠH RP Ġand Ġreturn Ġa ĠBe ch 3 2 Data Ġinstance . Ċ Ġ*/ Ċ fun ĠByteArray . toBe ch 3 2 Data ( hr p : ĠString Ġ= ĠBe ch 3 2 . PRO VEN ANCE _ MAIN NET _ ACCOUNT _ PREFIX ) Ġ= ĊĠĠĠ ĠBe ch 3 2 Data ( hr p , ĠBe ch 3 2 . convert Bits ( this , Ġ 8 , Ġ 5 , Ġtrue )) Ċ Ċ /** Ċ Ġ* ĠBe ch 3 2 ĠData Ġencoding Ġinstance Ġcontaining Ġdata Ġfor Ġencoding Ġas Ġwell Ġas Ġa Ġhuman Ġreadable Ġprefix Ċ Ġ*/ Ċ data Ġclass ĠBe ch 3 2 Data ( val Ġh rp : ĠString , Ġval Ġfive Bit Data : ĠByteArray ) Ġ{ ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠThe Ġencaps ulated Ġdata Ġas Ġtypical Ġ 8 bit Ġbytes . ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġval Ġdata Ġ= ĠBe ch 3 2 . convert Bits ( five Bit Data , Ġ 5 , Ġ 8 , Ġfalse ) ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠThe Ġencaps ulated Ġdata Ġreturned Ġas Ġa ĠHex adecimal Ġstring ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġprivate Ġval Ġhex Data Ġ= ĠBase Encoding . base 1 6 (). encode ( this . data ) ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠAddress Ġis Ġthe ĠBe ch 3 2 Ġencoded Ġvalue Ġof Ġthe Ġdata Ġprefixed Ġwith Ġthe Ġhuman Ġreadable Ġportion Ġand ĊĠĠĠĠ Ġ* Ġprotected Ġby Ġan Ġappended Ġchecksum . ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġval Ġaddress Ġ= ĠBe ch 3 2 . encode ( hr p , Ġfive Bit Data ) ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠThe ĠBe ch 3 2 ĠAddress ĠtoString Ġprints Ġstate Ġinformation Ġfor Ġdebugging Ġpurposes . ĊĠĠĠĠ Ġ* Ġ@ see Ġaddress () Ġfor Ġthe Ġbe ch 3 2 Ġencoded Ġaddress Ġstring Ġoutput . ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġoverride Ġfun ĠtoString (): ĠString Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn Ġ" be ch 3 2 Ġ: Ġ${ this . address }\ nh uman : Ġ${ this . hr p } Ġ\ n bytes : Ġ${ this . hex Data }" ĊĠĠĠĠĠĠĠ Ġ/* ĊĠĠĠĠĠĠĠ Ġbe ch 3 2 Ġ: Ġpro venance 1 gx 5 8 vp 8 pr yh 3 j kv xn kv z md 0 hq mq q ny qx rt v he q ĊĠĠĠĠĠĠĠ Ġhuman : Ġpro venance ĊĠĠĠĠĠĠĠ Ġbytes : Ġ 4 1 A 8 7 6 0 4 E 1 1 9 2 F 1 9 5 9 8 6 9 D 9 8 2 DB 5 F 7 0 6 C 0 0 9 9 0 0 6 ĊĠĠĠĠĠĠĠĠ Ġ*/ ĊĠĠĠ Ġ} Ċ } Ċ Ċ /** Ċ Ġ* ĠB IP 1 7 3 Ġcompliant Ġprocessing Ġfunctions Ġfor Ġhandling ĠBe ch 3 2 Ġencoding Ġfor Ġaddresses Ċ Ġ*/ Ċ class ĠBe ch 3 2 Ġ{ ĊĊĠĠĠ Ġcompanion Ġobject Ġ{ ĊĠĠĠĠĠĠĠ Ġprivate Ġconst Ġval Ġcharset Ġ= Ġ" qp z ry 9 x 8 gf 2 tv dw 0 s 3 jn 5 4 kh ce 6 m ua 7 l " ĊĠĠĠĠĠĠĠ Ġprivate Ġval Ġgen Ġ= Ġint ArrayOf ( 0 x 3 b 6 a 5 7 b 2 , Ġ 0 x 2 6 5 0 8 e 6 d , Ġ 0 x 1 ea 1 1 9 fa , Ġ 0 x 3 d 4 2 3 3 dd , Ġ 0 x 2 a 1 4 6 2 b 3 ) ĊĊĠĠĠĠĠĠĠ Ġprivate Ġconst Ġval ĠPRO VEN ANCE _ MAIN NET _ PREFIX Ġ= Ġ" pb " ĊĠĠĠĠĠĠĠ Ġconst Ġval ĠPRO VEN ANCE _ MAIN NET _ ACCOUNT _ PREFIX Ġ= ĠPRO VEN ANCE _ MAIN NET _ PREFIX ĊĊĠĠĠĠĠĠĠ Ġ// ĠTest Ġnet Ġaccount Ġprefixes Ġare Ġbroken Ġout Ġseparately Ġso Ġkeys / accounts Ġused Ġfor Ġtest Ġcan Ġbe Ġeasily Ġidentified ĊĊĠĠĠĠĠĠĠ Ġprivate Ġconst Ġval ĠPRO VEN ANCE _ TEST NET _ PREFIX Ġ= Ġ" tp " ĊĠĠĠĠĠĠĠ Ġconst Ġval ĠPRO VEN ANCE _ TEST NET _ ACCOUNT _ PREFIX Ġ= ĠPRO VEN ANCE _ TEST NET _ PREFIX ĊĊĠĠĠĠĠĠĠ Ġ/** ĊĠĠĠĠĠĠĠĠ Ġ* ĠConvert Bits Ġre groups Ġbytes Ġwith Ġto Bits Ġset Ġbased Ġon Ġreading Ġgroups Ġof Ġbits Ġas Ġa Ġcontinuous Ġstream Ġgroup Ġby Ġfrom Bits . ĊĠĠĠĠĠĠĠĠ Ġ* ĠThis Ġprocess Ġis Ġused Ġto Ġconvert Ġfrom Ġbase 6 4 Ġ( from Ġ 8 ) Ġto Ġbase 3 2 Ġ( to Ġ 5 ) Ġor Ġthe Ġinverse . ĊĠĠĠĠĠĠĠĠ Ġ*/ ĊĠĠĠĠĠĠĠ Ġfun Ġconvert Bits ( data : ĠByteArray , Ġfrom Bits : ĠInt , Ġto Bits : ĠInt , Ġpad : ĠBoolean ): ĠByteArray Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġrequire ( from Bits Ġin Ġ 1 .. 8 Ġ&& Ġto Bits Ġin Ġ 1 .. 8 ) Ġ{ Ġ" only Ġbit Ġgroups Ġbetween Ġ 1 Ġand Ġ 8 Ġare Ġsupported " Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġresulting Ġbytes Ġwith Ġeach Ġcontaining Ġthe Ġto Bits Ġbits Ġfrom Ġthe Ġinput Ġset . ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġre grouped Ġ= Ġarray ListOf < Byte >() ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġvar Ġnext Byte Ġ= Ġ 0 . to U Byte () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġvar Ġfilled Bits Ġ= Ġ 0 ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġdata . forEach Ġ{ Ġd Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġdiscard Ġunused Ġbits . ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġvar Ġb Ġ= Ġ( d . to U Byte () Ġshl Ġ( 8 Ġ- Ġfrom Bits )) ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠHow Ġmany Ġbits Ġremain Ġto Ġextract Ġfrom Ġinput Ġdata . ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġvar Ġremain From Bits Ġ= Ġfrom Bits ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġwhile Ġ( remain From Bits Ġ> Ġ 0 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠHow Ġmany Ġbits Ġremain Ġto Ġbe Ġcopied Ġin ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġremain To Bits Ġ= Ġto Bits Ġ- Ġfilled Bits ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġwe Ġextract Ġthe Ġremaining Ġbits Ġunless Ġthat Ġis Ġmore Ġthan Ġwe Ġneed . ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġto Extract Ġ= Ġremain From Bits . take Unless Ġ{ Ġremain To Bits Ġ< Ġremain From Bits Ġ} Ġ?: Ġremain To Bits ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcheck ( to Extract Ġ>= Ġ 0 ) Ġ{ Ġ" extract Ġshould Ġbe Ġpositive " Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġmove Ġexisting Ġbits Ġto Ġthe Ġleft Ġto Ġmake Ġroom Ġfor Ġbits Ġto Extract , Ġcopy Ġin Ġbits Ġto Ġextract ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġnext Byte Ġ= Ġ( next Byte Ġshl Ġto Extract ) Ġor Ġ( b Ġshr Ġ( 8 Ġ- Ġto Extract )) ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġdiscard Ġextracted Ġbits Ġand Ġupdate Ġposition Ġcounters ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġb Ġ= Ġb Ġshl Ġto Extract ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġremain From Bits Ġ-= Ġto Extract ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġfilled Bits Ġ+= Ġto Extract ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġif Ġwe Ġhave Ġa Ġcomplete Ġgroup Ġthen Ġreset . ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( filled Bits Ġ== Ġto Bits ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġre grouped . add ( next Byte . to Byte ()) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġfilled Bits Ġ= Ġ 0 ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġnext Byte Ġ= Ġ 0 . to U Byte () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġpad Ġany Ġun finished Ġgroups Ġas Ġrequired ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( pad Ġ&& Ġfilled Bits Ġ> Ġ 0 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġnext Byte Ġ= Ġnext Byte Ġshl Ġ( to Bits Ġ- Ġfilled Bits ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġre grouped . add ( next Byte . to Byte ()) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġfilled Bits Ġ= Ġ 0 ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġnext Byte Ġ= Ġ 0 . to U Byte () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġcheck Ġfor Ġany Ġincomplete Ġgroups Ġthat Ġare Ġmore Ġthan Ġ 4 Ġbits Ġor Ġnot Ġall Ġzeros ĊĠĠĠĠĠĠĠĠĠĠĠ Ġrequire ( filled Bits Ġ== Ġ 0 Ġ|| Ġ( filled Bits Ġ<= Ġ 4 Ġ&& Ġnext Byte Ġ== Ġ 0 . to U Byte ())) Ġ{ Ġ" invalid Ġincomplete Ġgroup " Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġre grouped . toByteArray () ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġ/** ĊĠĠĠĠĠĠĠĠ Ġ* ĠEn codes Ġdata Ġ 5 - bit Ġbytes Ġ( data ) Ġwith Ġa Ġgiven Ġhuman Ġreadable Ġportion Ġ( hr p ) Ġinto Ġa Ġbe ch 3 2 Ġstring . ĊĠĠĠĠĠĠĠĠ Ġ* Ġ@ see Ġconvert Bits Ġfor Ġconversion Ġor Ġide ally Ġuse Ġthe ĠBe ch 3 2 Data Ġextension Ġfunctions ĊĠĠĠĠĠĠĠĠ Ġ*/ ĊĠĠĠĠĠĠĠ Ġfun Ġencode ( hr p : ĠString , Ġfive Bit Data : ĠByteArray ): ĠString Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġ( five Bit Data . plus ( checksum ( hr p , Ġfive Bit Data . to Typed Array ())). map Ġ{ Ġb Ġ-> Ġcharset [ b . toInt ()] Ġ}) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. join ToString ("", Ġh rp Ġ+ Ġ" 1 ") ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġ/** ĊĠĠĠĠĠĠĠĠ Ġ* ĠCalculates Ġa Ġbe ch 3 2 Ġchecksum Ġbased Ġon ĠB IP Ġ 1 7 3 Ġspecification ĊĠĠĠĠĠĠĠĠ Ġ*/ ĊĠĠĠĠĠĠĠ Ġprivate Ġfun Ġchecksum ( hr p : ĠString , Ġdata : ĠArray < Byte >): ĠByteArray Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġvalues Ġ= Ġexpand H rp ( hr p ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. plus ( data . map Ġ{ Ġd Ġ-> Ġd . toInt () Ġ}) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. plus ( Array ( 6 ) Ġ{ Ġ 0 Ġ}. to IntArray ()) ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġpoly Ġ= Ġpoly mod ( values ) Ġxor Ġ 1 ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġ( 0 .. 5 ). map Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ(( poly Ġshr Ġ( 5 Ġ* Ġ( 5 Ġ- Ġit ))) Ġand Ġ 3 1 ). to Byte () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ}. toByteArray () ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġ/** ĊĠĠĠĠĠĠĠĠ Ġ* ĠExp ands Ġthe Ġhuman Ġreadable Ġprefix Ġper ĠB IP 1 7 3 Ġfor ĠCheck sum Ġencoding ĊĠĠĠĠĠĠĠĠ Ġ*/ ĊĠĠĠĠĠĠĠ Ġprivate Ġfun Ġexpand H rp ( hr p : ĠString ) Ġ= ĊĠĠĠĠĠĠĠĠĠĠĠ Ġh rp . map Ġ{ Ġc Ġ-> Ġc . toInt () Ġshr Ġ 5 Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. plus ( 0 ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. plus ( hr p . map Ġ{ Ġc Ġ-> Ġc . toInt () Ġand Ġ 3 1 Ġ}) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. to IntArray () ĊĊĠĠĠĠĠĠĠ Ġ/** ĊĠĠĠĠĠĠĠĠ Ġ* ĠPol ynomial Ġdivision Ġfunction Ġfor Ġchecksum Ġcalculation . Ġ ĠFor Ġdetails Ġsee ĠB IP 1 7 3 ĊĠĠĠĠĠĠĠĠ Ġ*/ ĊĠĠĠĠĠĠĠ Ġprivate Ġfun Ġpoly mod ( values : ĠInt Array ): ĠInt Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġvar Ġchk Ġ= Ġ 1 ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġvalues . map Ġ{ Ġvalue Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġb Ġ= Ġchk Ġshr Ġ 2 5 ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġchk Ġ= Ġ(( chk Ġand Ġ 0 x 1 ffffff ) Ġshl Ġ 5 ) Ġxor Ġvalue ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ( 0 .. 4 ). map Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ((( b Ġshr Ġit ) Ġand Ġ 1 ) Ġ== Ġ 1 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġchk Ġ= Ġchk Ġxor Ġgen [ it ] ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ}. let Ġ{ Ġchk Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} Ċ } Ċ