package Ġbit co ink it Ċ Ċ import Ġbit co ink it . Utils . double Digest Ċ import Ġorg . bouncycastle . asn 1 . ASN 1 InputStream Ċ import Ġorg . bouncycastle . asn 1 . ASN 1 Integer Ċ import Ġorg . bouncycastle . asn 1 . DER Sequence Generator Ċ import Ġorg . bouncycastle . asn 1 . DL Sequence Ċ import Ġorg . bouncycastle . crypto . digest s . SHA 2 5 6 Digest Ċ import Ġorg . bouncycastle . crypto . ec . Custom Named Cur ves Ċ import Ġorg . bouncycastle . crypto . params . ECD omain Parameters Ċ import Ġorg . bouncycastle . crypto . params . E CP rivate Key Parameters Ċ import Ġorg . bouncycastle . crypto . sign ers . EC DS AS ign er Ċ import Ġorg . bouncycastle . crypto . sign ers . H Mac D SA K Calculator Ċ import Ġorg . bouncycastle . math . ec . EC Algorithms Ċ import Ġorg . bouncycastle . math . ec . EC Point Ċ import Ġorg . bouncycastle . math . ec . Fixed Point Com b Multiplier Ċ import Ġorg . bouncycastle . math . ec . custom . sec . Sec P 2 5 6 K 1 Curve Ċ import Ġorg . bouncycastle . util . en coders . Base 6 4 Ċ import Ġjava . io . ByteArray OutputStream Ċ import Ġjava . io . IOException Ċ import Ġjava . lang . Class CastException Ċ import Ġjava . lang . IllegalArgumentException Ċ import Ġjava . lang . IllegalStateException Ċ import Ġjava . lang . RuntimeException Ċ import Ġjava . math . BigInteger Ċ import Ġjava . nio . charset . StandardCharsets Ċ import Ġjava . security . Secure Random Ċ import Ġjava . util .* Ċ import Ġkotlin . experimental . and Ċ Ċ /** Ċ Ġ* ĠEC Key Ġsupports Ġel li ptic Ġcurve Ġcrypto graphic Ġoperations Ġusing Ġa Ġpublic / private Ċ Ġ* Ġkey Ġpair . Ġ ĠA Ġprivate Ġkey Ġis Ġrequired Ġto Ġcreate Ġa Ġsignature Ġand Ġa Ġpublic Ġkey Ġis Ċ Ġ* Ġrequired Ġto Ġverify Ġa Ġsignature . Ġ ĠThe Ġprivate Ġkey Ġis Ġalways Ġencrypted Ġusing ĠAES Ċ Ġ* Ġwhen Ġit Ġis Ġserialized Ġfor Ġstorage Ġon Ġexternal Ġmedia . Ċ Ġ*/ Ċ open Ġclass ĠEC Key Ġ@ Jvm Over loads Ġconstructor ( ĊĠĠĠ Ġpub Key : ĠByteArray ?, ĊĠĠĠ Ġ/** ĠPrivate Ġkey Ġ Ġ*/ ĊĠĠĠ Ġval Ġpriv Key : ĠBigInteger ? Ġ= Ġnull , Ġpub : ĠEC Point ? Ġ= ĠCUR VE . curve . decode Point ( pub Key ), Ġcompressed : ĠBoolean Ġ= Ġfalse Ċ ) Ġ{ ĊĠĠĠ Ġcompanion Ġobject Ġ{ ĊĠĠĠĠĠĠĠ Ġ/** ĠEl li ptic Ġcurve Ġparameters Ġ( secp 2 5 6 k 1 Ġcurve ) Ġ Ġ*/ ĊĠĠĠĠĠĠĠ Ġval ĠCUR VE _ PARAMS Ġ= ĠCustom Named Cur ves . get ByName (" secp 2 5 6 k 1 ") ĊĠĠĠĠĠĠĠ Ġval ĠCUR VE : ĠE CD omain Parameters Ġ= ĠE CD omain Parameters ( CUR VE _ PARAMS . curve , ĠCUR VE _ PARAMS . g , ĠCUR VE _ PARAMS . n , ĠCUR VE _ PARAMS . h ) ĊĠĠĠĠĠĠĠ Ġ/** ĠHalf - curve Ġorder Ġfor Ġgenerating Ġcanonical ĠS Ġ Ġ*/ ĊĠĠĠĠĠĠĠ Ġval ĠHAL F _ CUR VE _ ORDER : ĠBigInteger Ġ= ĠCUR VE _ PARAMS . n . shift Right ( 1 ) ĊĊĠĠĠĠĠĠĠ Ġ/** ĠStr ong Ġrandom Ġnumber Ġgenerator Ġ Ġ*/ ĊĠĠĠĠĠĠĠ Ġprivate Ġval Ġsecure Random Ġ= ĠSecure Random () ĊĊĠĠĠĠĠĠĠ Ġ/** ĠSigned Ġmessage Ġheader Ġ Ġ*/ ĊĠĠĠĠĠĠĠ Ġprivate Ġconst Ġval ĠBIT CO IN _ SIGNED _ MESSAGE _ HEADER Ġ= Ġ" Bitcoin ĠSigned ĠMessage :\ n " ĊĊĠĠĠĠĠĠĠ Ġ/** ĊĠĠĠĠĠĠĠĠ Ġ* ĠCreate Ġthe Ġpublic Ġkey Ġfrom Ġthe Ġprivate Ġkey ĊĠĠĠĠĠĠĠĠ Ġ* ĊĠĠĠĠĠĠĠĠ Ġ* Ġ@ param ĠĠĠĠĠĠ Ġpriv Key ĠĠĠĠĠĠĠĠĠĠĠĠ ĠPrivate Ġkey ĊĠĠĠĠĠĠĠĠ Ġ* Ġ@ param ĠĠĠĠĠĠ Ġcompressed ĠĠĠĠĠĠĠĠĠ ĠTRUE Ġto Ġgenerate Ġa Ġcompressed Ġpublic Ġkey ĊĠĠĠĠĠĠĠĠ Ġ* Ġ@ return ĠPublic Ġkey ĊĠĠĠĠĠĠĠĠ Ġ*/ ĊĠĠĠĠĠĠĠ Ġfun Ġpub Key From Priv Key ( priv Key : ĠBigInteger , Ġcompressed : ĠBoolean ): ĠByteArray Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġpublic Point From Private ( priv Key ). get Encoded ( compressed ) ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġfun Ġfrom Public Only ( pub : ĠByteArray ?): ĠEC Key Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĠEC Key ( pub , ĠCUR VE . curve . decode Point ( pub )) ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġfun Ġfrom Private ( priv Key Bytes : ĠByteArray ?): ĠEC Key Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġfrom Private ( BigInteger ( 1 , Ġpriv Key Bytes )) ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġfun Ġfrom Private ( priv Key Bytes : ĠByteArray ?, Ġcompressed : ĠBoolean ): ĠEC Key Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġpriv Key Ġ= ĠBigInteger ( 1 , Ġpriv Key Bytes ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġpoint Ġ= Ġpublic Point From Private ( priv Key ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĠEC Key ( priv Key , Ġpoint , Ġcompressed ) ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġ@ Jvm Over loads ĊĠĠĠĠĠĠĠ Ġfun Ġfrom Private ( priv Key : ĠBigInteger , Ġcompressed : ĠBoolean Ġ= Ġtrue ): ĠEC Key Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġpoint Ġ= Ġpublic Point From Private ( priv Key ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĠEC Key ( null , Ġpriv Key , Ġpoint , Ġcompressed ) ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġ/** ĊĠĠĠĠĠĠĠĠ Ġ* ĠChecks Ġif Ġthe Ġpublic Ġkey Ġis Ġcanonical ĊĠĠĠĠĠĠĠĠ Ġ* ĊĠĠĠĠĠĠĠĠ Ġ* Ġ@ param ĠĠĠĠĠĠ Ġpub Key Bytes ĠĠĠĠĠĠĠĠ ĠPublic Ġkey ĊĠĠĠĠĠĠĠĠ Ġ* Ġ@ return ĠTRUE Ġif Ġthe Ġkey Ġis Ġcanonical ĊĠĠĠĠĠĠĠĠ Ġ*/ ĊĠĠĠĠĠĠĠ Ġfun Ġis PubKey Canonical ( pub Key Bytes : ĠByteArray ): ĠBoolean Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( pub Key Bytes . size Ġ< Ġ 3 3 ) Ġreturn Ġfalse ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( pub Key Bytes [ 0 ] Ġ== Ġ 0 x 0 4 . to Byte ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠUn compressed Ġpub key ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( pub Key Bytes . size Ġ!= Ġ 6 5 ) Ġreturn Ġfalse ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġif Ġ( pub Key Bytes [ 0 ] Ġ== Ġ 0 x 0 2 . to Byte () Ġ|| Ġpub Key Bytes [ 0 ] Ġ== Ġ 0 x 0 3 . to Byte ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠComp ressed Ġpub key ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( pub Key Bytes . size Ġ!= Ġ 3 3 ) Ġreturn Ġfalse ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġreturn Ġfalse ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġtrue ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġ/** ĊĠĠĠĠĠĠĠĠ Ġ* ĠChecks Ġif Ġthe Ġsignature Ġis ĠD ER - encoded ĊĠĠĠĠĠĠĠĠ Ġ* ĊĠĠĠĠĠĠĠĠ Ġ* Ġ@ param ĠĠĠĠĠĠ Ġencoded Sig ĠĠĠĠĠĠĠĠĠ ĠEn coded Ġsignature ĊĠĠĠĠĠĠĠĠ Ġ* Ġ@ return ĠTRUE Ġif Ġthe Ġsignature Ġis ĠD ER - encoded ĊĠĠĠĠĠĠĠĠ Ġ*/ ĊĠĠĠĠĠĠĠ Ġfun Ġis Signature Canonical ( encoded Sig : ĠByteArray ): ĠBoolean Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠD ER - encoding Ġrequires Ġthat Ġthere Ġis Ġonly Ġone Ġrepresentation Ġfor Ġa Ġgiven ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġencoding . Ġ ĠThis Ġmeans Ġthat Ġno Ġpad Ġbytes Ġare Ġinserted Ġfor Ġnumeric Ġvalues . ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠAn ĠASN . 1 Ġsequence Ġis Ġidentified Ġby Ġ 0 x 3 0 Ġand Ġeach Ġprimitive Ġby Ġa Ġtype Ġfield . ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠAn Ġinteger Ġis Ġidentified Ġas Ġ 0 x 0 2 . Ġ ĠEach Ġfield Ġtype Ġis Ġfollowed Ġby Ġa Ġfield Ġlength . ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠFor Ġvalid ĠR Ġand ĠS Ġvalues , Ġthe Ġlength Ġis Ġa Ġsingle Ġbyte Ġsince ĠR Ġand ĠS Ġare Ġboth ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġ 3 2 - byte Ġor Ġ 3 3 - byte Ġvalues Ġ( a Ġleading Ġzero Ġbyte Ġis Ġadded Ġto Ġensure Ġa Ġpositive ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġvalue Ġif Ġthe Ġsign Ġbit Ġwould Ġotherwise Ġbet Ġset ). ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠBitcoin Ġapp ends Ġthat Ġhash Ġtype Ġto Ġthe Ġend Ġof Ġthe ĠD ER - encoded Ġsignature . Ġ ĠWe Ġrequire ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġthis Ġto Ġbe Ġa Ġsingle Ġbyte Ġfor Ġa Ġcanonical Ġsignature . ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠThe Ġlength Ġis Ġencoded Ġin Ġthe Ġlower Ġ 7 Ġbits Ġfor Ġlengths Ġbetween Ġ 0 Ġand Ġ 1 2 7 Ġand Ġthe Ġupper Ġbit Ġis Ġ 0 . ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠLong er Ġlength Ġhave Ġthe Ġupper Ġbit Ġset Ġto Ġ 1 Ġand Ġthe Ġlower Ġ 7 Ġbits Ġcontain Ġthe Ġnumber Ġof Ġbytes ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġin Ġthe Ġlength . ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠAn ĠASN . 1 Ġsequence Ġis Ġ 0 x 3 0 Ġfollowed Ġby Ġthe Ġlength ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( encoded Sig . size Ġ< Ġ 2 Ġ|| Ġencoded Sig [ 0 ] Ġ!= Ġ 0 x 3 0 . to Byte () Ġ|| Ġencoded Sig [ 1 ] Ġand Ġ 0 x 8 0 . to Byte () Ġ!= Ġ 0 . to Byte ()) Ġreturn Ġfalse ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠGet Ġlength Ġof Ġsequence ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġlength Ġ= Ġ( encoded Sig [ 1 ]. toInt () Ġand Ġ 0 x 7 f ) Ġ+ Ġ 2 ĊĠĠĠĠĠĠĠĠĠĠĠ Ġvar Ġoffset Ġ= Ġ 2 ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠCheck ĠR ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( offset Ġ+ Ġ 2 Ġ> Ġlength Ġ|| Ġencoded Sig [ offset ] Ġ!= Ġ 0 x 0 2 . to Byte () Ġ|| Ġencoded Sig [ offset Ġ+ Ġ 1 ] Ġand Ġ 0 x 8 0 . to Byte () Ġ!= Ġ 0 . to Byte ()) Ġreturn Ġfalse ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġr Length Ġ= Ġencoded Sig [ offset Ġ+ Ġ 1 ]. toInt () Ġand Ġ 0 x 7 f ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( offset Ġ+ Ġr Length Ġ+ Ġ 2 Ġ> Ġlength ) Ġreturn Ġfalse ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( encoded Sig [ offset Ġ+ Ġ 2 ] Ġ== Ġ 0 x 0 0 . to Byte () Ġ&& Ġencoded Sig [ offset Ġ+ Ġ 3 ] Ġand Ġ 0 x 8 0 . to Byte () Ġ== Ġ 0 . to Byte ()) Ġreturn Ġfalse ĊĠĠĠĠĠĠĠĠĠĠĠ Ġoffset Ġ+= Ġr Length Ġ+ Ġ 2 ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠCheck ĠS ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( offset Ġ+ Ġ 2 Ġ> Ġlength Ġ|| Ġencoded Sig [ offset ] Ġ!= Ġ 0 x 0 2 . to Byte () Ġ|| Ġencoded Sig [ offset Ġ+ Ġ 1 ] Ġand Ġ 0 x 8 0 . to Byte () Ġ!= Ġ 0 . to Byte ()) Ġreturn Ġfalse ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġs Length Ġ= Ġencoded Sig [ offset Ġ+ Ġ 1 ]. toInt () Ġand Ġ 0 x 7 f ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( offset Ġ+ Ġs Length Ġ+ Ġ 2 Ġ> Ġlength ) Ġreturn Ġfalse ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( encoded Sig [ offset Ġ+ Ġ 2 ] Ġ== Ġ 0 x 0 0 . to Byte () Ġ&& Ġencoded Sig [ offset Ġ+ Ġ 3 ] Ġand Ġ 0 x 8 0 . to Byte () Ġ== Ġ 0 . to Byte ()) Ġreturn Ġfalse ĊĠĠĠĠĠĠĠĠĠĠĠ Ġoffset Ġ+= Ġs Length Ġ+ Ġ 2 ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠThere Ġmust Ġbe Ġa Ġsingle Ġbyte Ġappended Ġto Ġthe Ġsignature ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġoffset Ġ== Ġencoded Sig . size Ġ- Ġ 1 ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġ/** ĊĠĠĠĠĠĠĠĠ Ġ* ĊĠĠĠĠĠĠĠĠ Ġ* ĠGiven Ġthe Ġcomponents Ġof Ġa Ġsignature Ġand Ġa Ġselector Ġvalue , Ġrecover Ġand Ġreturn Ġthe Ġpublic Ġkey ĊĠĠĠĠĠĠĠĠ Ġ* Ġthat Ġgenerated Ġthe Ġsignature Ġaccording Ġto Ġthe Ġalgorithm Ġin ĠSE C 1 v 2 Ġsection Ġ 4 . 1 . 6 . ĊĠĠĠĠĠĠĠĠ Ġ* ĊĠĠĠĠĠĠĠĠ Ġ* ĊĠĠĠĠĠĠĠĠ Ġ* ĠThe Ġrec ID Ġis Ġan Ġindex Ġfrom Ġ 0 Ġto Ġ 3 Ġwhich Ġindicates Ġwhich Ġof Ġthe Ġ 4 Ġpossible Ġkeys Ġis Ġthe Ġcorrect Ġone . ĊĠĠĠĠĠĠĠĠ Ġ* ĠBecause Ġthe Ġkey Ġrecovery Ġoperation Ġyields Ġmultiple Ġpotential Ġkeys , Ġthe Ġcorrect Ġkey Ġmust Ġeither Ġbe ĊĠĠĠĠĠĠĠĠ Ġ* Ġstored Ġalong side Ġthe Ġsignature , Ġor Ġyou Ġmust Ġbe Ġwilling Ġto Ġtry Ġeach Ġrec Id Ġin Ġturn Ġuntil Ġyou Ġfind Ġone ĊĠĠĠĠĠĠĠĠ Ġ* Ġthat Ġoutputs Ġthe Ġkey Ġyou Ġare Ġexpecting . ĊĠĠĠĠĠĠĠĠ Ġ* ĊĠĠĠĠĠĠĠĠ Ġ* ĊĠĠĠĠĠĠĠĠ Ġ* ĠIf Ġthis Ġmethod Ġreturns Ġnull , Ġit Ġmeans Ġrecovery Ġwas Ġnot Ġpossible Ġand Ġrec ID Ġshould Ġbe Ġiter ated . ĊĠĠĠĠĠĠĠĠ Ġ* ĊĠĠĠĠĠĠĠĠ Ġ* ĊĠĠĠĠĠĠĠĠ Ġ* ĠGiven Ġthe Ġabove Ġtwo Ġpoints , Ġa Ġcorrect Ġusage Ġof Ġthis Ġmethod Ġis Ġinside Ġa Ġfor Ġloop Ġfrom Ġ 0 Ġto Ġ 3 , Ġand Ġif Ġthe ĊĠĠĠĠĠĠĠĠ Ġ* Ġoutput Ġis Ġnull ĠOR Ġa Ġkey Ġthat Ġis Ġnot Ġthe Ġone Ġyou Ġexpect , Ġyou Ġtry Ġagain Ġwith Ġthe Ġnext Ġrec ID . ĊĠĠĠĠĠĠĠĠ Ġ* ĊĠĠĠĠĠĠĠĠ Ġ* Ġ@ param ĠĠĠĠĠĠ Ġrec ID ĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠWhich Ġpossible Ġkey Ġto Ġrecover . ĊĠĠĠĠĠĠĠĠ Ġ* Ġ@ param ĠĠĠĠĠĠ Ġsig ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠR Ġand ĠS Ġcomponents Ġof Ġthe Ġsignature ĊĠĠĠĠĠĠĠĠ Ġ* Ġ@ param ĠĠĠĠĠĠ Ġe ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠThe Ġdouble ĠSHA - 2 5 6 Ġhash Ġof Ġthe Ġoriginal Ġmessage ĊĠĠĠĠĠĠĠĠ Ġ* Ġ@ param ĠĠĠĠĠĠ Ġcompressed ĠĠĠĠĠĠĠĠĠ ĠWhether Ġor Ġnot Ġthe Ġoriginal Ġpublic Ġkey Ġwas Ġcompressed ĊĠĠĠĠĠĠĠĠ Ġ* Ġ@ return ĠAn ĠEC Key Ġcontaining Ġonly Ġthe Ġpublic Ġpart , Ġor Ġnull Ġif Ġrecovery Ġwasn 't Ġpossible ĊĠĠĠĠĠĠĠĠ Ġ*/ ĊĠĠĠĠĠĠĠ Ġfun Ġrecover From Signature ( rec ID : ĠInt , Ġsig : ĠEC DS AS ign ature , Ġe : ĠBigInteger ?, Ġcompressed : ĠBoolean ): ĠEC Key ? Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġn Ġ= ĠCUR VE . n ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġi Ġ= ĠBigInteger . valueOf ( rec ID . to Long () Ġ/ Ġ 2 ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġx Ġ= Ġsig . r !!. add ( i . multiply ( n )) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠĠ ĠConvert Ġthe Ġinteger Ġx Ġto Ġan Ġoct et Ġstring ĠX Ġof Ġlength Ġm len Ġusing Ġthe Ġconversion Ġroutine ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠĠĠĠĠĠĠ Ġspecified Ġin ĠSection Ġ 2 . 3 . 7 , Ġwhere Ġm len Ġ= Ġâ Į Ī ( log 2 Ġp )/ 8 â Į ī Ġor Ġm len Ġ= Ġâ Į Ī m / 8 â Į ī . ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠĠ ĠConvert Ġthe Ġoct et Ġstring Ġ( 1 6 Ġset Ġbinary Ġdigits )|| X Ġto Ġan Ġel li ptic Ġcurve Ġpoint ĠR Ġusing Ġthe ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠĠĠĠĠĠĠ Ġconversion Ġroutine Ġspecified Ġin ĠSection Ġ 2 . 3 . 4 . ĠIf Ġthis Ġconversion Ġroutine Ġoutputs Ġ' invalid ', Ġthen ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠĠĠĠĠĠĠ Ġdo Ġanother Ġiteration . ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠMore Ġconcise ly , Ġwhat Ġthese Ġpoints Ġmean Ġis Ġto Ġuse ĠX Ġas Ġa Ġcompressed Ġpublic Ġkey . ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġcurve Ġ= ĠCUR VE . curve Ġas ĠSec P 2 5 6 K 1 Curve ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġprime Ġ= Ġcurve . q ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( x . compareTo ( prime ) Ġ>= Ġ 0 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġnull ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠComp ressed Ġkeys Ġrequire Ġyou Ġto Ġknow Ġan Ġextra Ġbit Ġof Ġdata Ġabout Ġthe Ġy - coordinate Ġas ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġthere Ġare Ġtwo Ġpossib ilities . Ġ ĠSo Ġit 's Ġencoded Ġin Ġthe Ġrec ID . ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval ĠR Ġ= Ġde compress Key ( x , Ġrec ID Ġand Ġ 1 Ġ== Ġ 1 ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ(! R . multiply ( n ). is Infinity ) Ġreturn Ġnull ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠĠ ĠFor Ġk Ġfrom Ġ 1 Ġto Ġ 2 Ġdo Ġthe Ġfollowing . ĠĠ Ġ( loop Ġis Ġoutside Ġthis Ġfunction Ġvia Ġiter ating Ġrec Id ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠĠĠĠ ĠCompute Ġa Ġcandidate Ġpublic Ġkey Ġas : ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠĠĠĠĠĠ ĠQ Ġ= Ġmi ( r ) Ġ* Ġ( s R Ġ- Ġe G ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠWhere Ġmi ( x ) Ġis Ġthe Ġmodular Ġmultip lic ative Ġinverse . ĠWe Ġtransform Ġthis Ġinto Ġthe Ġfollowing : ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠQ Ġ= Ġ( mi ( r ) Ġ* Ġs Ġ** ĠR ) Ġ+ Ġ( mi ( r ) Ġ* Ġ- e Ġ** ĠG ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠWhere Ġ- e Ġis Ġthe Ġmodular Ġadd itive Ġinverse Ġof Ġe , Ġthat Ġis Ġz Ġsuch Ġthat Ġz Ġ+ Ġe Ġ= Ġ 0 Ġ( mod Ġn ). ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠIn Ġthe Ġabove Ġequation , Ġ** Ġis Ġpoint Ġmultiplication Ġand Ġ+ Ġis Ġpoint Ġaddition Ġ( the ĠEC Ġgroup Ġoperator ). ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠWe Ġcan Ġfind Ġthe Ġadd itive Ġinverse Ġby Ġsubtract ing Ġe Ġfrom Ġzero Ġthen Ġtaking Ġthe Ġmod . ĠFor Ġexample Ġthe Ġadd itive ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġinverse Ġof Ġ 3 Ġmodulo Ġ 1 1 Ġis Ġ 8 Ġbecause Ġ 3 Ġ+ Ġ 8 Ġmod Ġ 1 1 Ġ= Ġ 0 , Ġand Ġ- 3 Ġmod Ġ 1 1 Ġ= Ġ 8 . ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġe Inv Ġ= ĠBigInteger . ZERO . subtract ( e ). mod ( n ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġr Inv Ġ= Ġsig . r !!. mod Inverse ( n ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġsr Inv Ġ= Ġr Inv . multiply ( sig . s ). mod ( n ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġe Inv r Inv Ġ= Ġr Inv . multiply ( e Inv ). mod ( n ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġq Ġ= ĠEC Algorithms . sum Of Two Multip lies ( CUR VE . g , Ġe Inv r Inv , ĠR , Ġsr Inv ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĠEC Key ( q . get Encoded ( compressed ), Ġq ) ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġ/** ĊĠĠĠĠĠĠĠĠ Ġ* ĠDe compress Ġa Ġcompressed Ġpublic Ġkey Ġ( x Ġcoordinate Ġand Ġlow - bit Ġof Ġy - coordinate ). ĊĠĠĠĠĠĠĠĠ Ġ* ĊĠĠĠĠĠĠĠĠ Ġ* Ġ@ param ĠĠĠĠĠĠ Ġx BN ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠX - coordinate ĊĠĠĠĠĠĠĠĠ Ġ* Ġ@ param ĠĠĠĠĠĠ Ġy Bit ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠSign Ġof ĠY - coordinate ĊĠĠĠĠĠĠĠĠ Ġ* Ġ@ return ĠUn compressed Ġpublic Ġkey ĊĠĠĠĠĠĠĠĠ Ġ*/ ĊĠĠĠĠĠĠĠ Ġprivate Ġfun Ġde compress Key ( xB N : ĠBigInteger , Ġy Bit : ĠBoolean ): ĠEC Point Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġcurve Ġ= ĠCUR VE . curve Ġas ĠSec P 2 5 6 K 1 Curve ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġx Ġ= Ġcurve . from BigInteger ( xB N ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġalpha Ġ= Ġx . multiply ( x . square (). add ( curve . a )). add ( curve . b ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġbeta Ġ= Ġalpha . sqrt () Ġ?: Ġthrow ĠIllegalArgumentException (" Invalid Ġpoint Ġcompression ") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġec Point : ĠEC Point ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġn Beta Ġ= Ġbeta . to BigInteger () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġec Point Ġ= Ġif Ġ( n Beta . test Bit ( 0 ) Ġ== Ġy Bit ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcurve . create Point ( x . to BigInteger (), Ġn Beta ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġy Ġ= Ġcurve . from BigInteger ( curve . q . subtract ( n Beta )) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcurve . create Point ( x . to BigInteger (), Ġy . to BigInteger ()) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġec Point ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ/** ĊĠĠĠĠĠĠĠĠ Ġ* ĠGet Ġthe Ġpublic Ġkey ĠEC Point Ġfrom Ġthe Ġprivate Ġkey ĊĠĠĠĠĠĠĠĠ Ġ* ĊĠĠĠĠĠĠĠĠ Ġ* Ġ@ param ĠĠĠĠĠĠ Ġpriv Key ĠĠĠĠĠĠĠĠĠĠĠĠ ĠPrivate Ġkey ĊĠĠĠĠĠĠĠĠ Ġ* Ġ@ return ĠPublic Ġkey ĠEC Point ĊĠĠĠĠĠĠĠĠ Ġ*/ ĊĠĠĠĠĠĠĠ Ġ// ĠĠĠ Ġstatic ĠEC Point Ġpublic Point From Private ( BigInteger Ġpriv Key ) Ġ{ ĊĠĠĠĠĠĠĠ Ġ// ĠĠĠĠĠĠĠ ĠBigInteger Ġadj Key ; ĊĠĠĠĠĠĠĠ Ġ// ĠĠĠĠĠĠĠ Ġif Ġ( priv Key . bit Length () Ġ> ĠCUR VE . getN (). bit Length ()) Ġ{ ĊĠĠĠĠĠĠĠ Ġ// ĠĠĠĠĠĠĠĠĠĠĠ Ġadj Key Ġ= Ġpriv Key . mod ( CUR VE . getN ()); ĊĠĠĠĠĠĠĠ Ġ// ĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠ Ġ// ĠĠĠĠĠĠĠĠĠĠĠ Ġadj Key Ġ= Ġpriv Key ; ĊĠĠĠĠĠĠĠ Ġ// ĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ// ĠĠĠĠĠĠĠ Ġreturn ĠCUR VE . get G (). multiply ( adj Key ); ĊĠĠĠĠĠĠĠ Ġ// ĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ/** ĊĠĠĠĠĠĠĠĠ Ġ* ĠReturns Ġpublic Ġkey Ġbytes Ġfrom Ġthe Ġgiven Ġprivate Ġkey . ĠTo Ġconvert Ġa Ġbyte Ġarray Ġinto Ġa ĠBigInteger , Ġuse Ġ< tt > ĊĠĠĠĠĠĠĠĠ Ġ* Ġnew ĠBigInteger ( 1 , Ġbytes );</ tt > ĊĠĠĠĠĠĠĠĠ Ġ*/ ĊĠĠĠĠĠĠĠ Ġfun ĠpublicKey From Private ( priv Key : ĠBigInteger , Ġcompressed : ĠBoolean ): ĠByteArray Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġpoint Ġ= Ġpublic Point From Private ( priv Key ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġpoint . get Encoded ( compressed ) ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġ/** ĊĠĠĠĠĠĠĠĠ Ġ* ĠReturns Ġpublic Ġkey Ġpoint Ġfrom Ġthe Ġgiven Ġprivate Ġkey . ĠTo Ġconvert Ġa Ġbyte Ġarray Ġinto Ġa ĠBigInteger , Ġuse Ġ< tt > ĊĠĠĠĠĠĠĠĠ Ġ* Ġnew ĠBigInteger ( 1 , Ġbytes );</ tt > ĊĠĠĠĠĠĠĠĠ Ġ*/ ĊĠĠĠĠĠĠĠ Ġfun Ġpublic Point From Private ( priv Key : ĠBigInteger ): ĠEC Point Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ/* ĊĠĠĠĠĠĠĠĠ Ġ* ĠFIXME : ĠFixed Point Com b Multiplier Ġcurrently Ġdoesn 't Ġsupport Ġscal ars Ġlonger Ġthan Ġthe Ġgroup Ġorder , ĊĠĠĠĠĠĠĠĠ Ġ* Ġbut Ġthat Ġcould Ġchange Ġin Ġfuture Ġversions . ĊĠĠĠĠĠĠĠĠ Ġ*/ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġvar Ġpriv Key Ġ= Ġpriv Key ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( priv Key . bit Length () Ġ> ĠCUR VE . n . bit Length ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġpriv Key Ġ= Ġpriv Key . mod ( CUR VE . n ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĠFixed Point Com b Multiplier (). multiply ( CUR VE . g , Ġpriv Key ) ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġprivate Ġfun Ġget Point With Compression ( point : ĠEC Point , Ġcompressed : ĠBoolean ): ĠEC Point Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġvar Ġpoint Ġ= Ġpoint ĊĠĠĠĠĠĠĠĠĠĠĠ Ġpoint Ġ= Ġpoint . normalize () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġx Ġ= Ġpoint . affine X Coord . to BigInteger () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġy Ġ= Ġpoint . affine Y Coord . to BigInteger () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĠCUR VE . curve . create Point ( x , Ġy ) ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġfun Ġfrom Bytes ( b 1 : ĠByte , Ġb 2 : ĠByte , Ġb 3 : ĠByte , Ġb 4 : ĠByte ): ĠInt Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġb 1 . toInt () Ġshl Ġ 2 4 Ġor Ġ( b 2 . toInt () Ġand Ġ 0 xFF Ġshl Ġ 1 6 ) Ġor Ġ( b 3 . toInt () Ġand Ġ 0 xFF Ġshl Ġ 8 ) Ġor Ġ( b 4 . toInt () Ġand Ġ 0 xFF ) ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠ Ġ} ĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠReturns Ġthe Ġkey Ġlabel ĊĠĠĠĠ Ġ* ĊĠĠĠĠ Ġ* Ġ@ return ĠKey Ġlabel ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠSets Ġthe Ġkey Ġlabel ĊĠĠĠĠ Ġ* ĊĠĠĠĠ Ġ* Ġ@ param ĠĠĠĠĠĠ Ġlabel ĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠKey Ġlabel ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġ/** ĠKey Ġlabel Ġ Ġ*/ ĊĠĠĠ Ġvar Ġlabel Ġ= Ġ"" ĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠReturns Ġthe Ġpublic Ġkey Ġ( as Ġused Ġin Ġtransaction Ġscript Sig s ). Ġ ĠA Ġcompressed ĊĠĠĠĠ Ġ* Ġpublic Ġkey Ġis Ġ 3 3 Ġbytes Ġand Ġstarts Ġwith Ġ' 0 2 ' Ġor Ġ' 0 3 ' Ġwhile Ġan Ġun compressed ĊĠĠĠĠ Ġ* Ġpublic Ġkey Ġis Ġ 6 5 Ġbytes Ġand Ġstarts Ġwith Ġ' 0 4 '. ĊĠĠĠĠ Ġ* ĊĠĠĠĠ Ġ* Ġ@ return ĠPublic Ġkey ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġ/** ĠPublic Ġkey Ġ Ġ*/ ĊĠĠĠ Ġval Ġpub Key : ĠByteArray ĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠReturns Ġthe Ġpublic Ġkey Ġhash Ġas Ġused Ġin Ġaddresses . Ġ ĠThe Ġhash Ġis Ġ 2 0 Ġbytes . ĊĠĠĠĠ Ġ* ĊĠĠĠĠ Ġ* Ġ@ return ĠPublic Ġkey Ġhash ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġ/** ĠPublic Ġkey Ġhash Ġ Ġ*/ ĊĠĠĠ Ġval Ġpub Key Hash : ĠByteArray Ġby Ġlazy Ġ{ ĠUtils . sha 2 5 6 Hash 1 6 0 ( pub Key ) Ġ} ĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠReturns Ġthe Ġpublic Ġkey Ġchecksum Ġas Ġused Ġin Ġaddresses . Ġ ĠThe Ġhash Ġis Ġ 4 Ġbytes . ĊĠĠĠĠ Ġ* ĊĠĠĠĠ Ġ* Ġ@ return ĠPublic Ġkey Ġhash ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġ/** ĠPublic Ġkey Ġchecksum Ġ Ġ*/ ĊĠĠĠ Ġval Ġpub Key Checksum : ĠByteArray Ġby Ġlazy Ġ{ ĠArrays . copyOf Range ( Utils . ri pe md 1 6 0 ( pub Key !! ), Ġ 0 , Ġ 4 ) Ġ} ĊĊĠĠĠ Ġ/** ĠP 2 SH - P 2 W PK H Ġscript Ġhash Ġ Ġ*/ Ċ // ĠĠĠ Ġprivate Ġval Ġscript Hash : ĠByteArray ĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠReturns Ġthe Ġprivate Ġkey ĊĠĠĠĠ Ġ* ĊĠĠĠĠ Ġ* Ġ@ return ĠPrivate Ġkey Ġor Ġnull Ġif Ġthere Ġis Ġno Ġprivate Ġkey ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠReturns Ġthe Ġkey Ġcreation Ġtime ĊĠĠĠĠ Ġ* ĊĠĠĠĠ Ġ* Ġ@ return ĠKey Ġcreation Ġtime Ġ( seconds ) ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠSets Ġthe Ġkey Ġcreation Ġtime ĊĠĠĠĠ Ġ* ĊĠĠĠĠ Ġ* Ġ@ param ĠĠĠĠĠĠ Ġcreation Time Seconds ĠĠĠĠĠĠĠ ĠKey Ġcreation Ġtime Ġ( seconds ) ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġ/** ĠKey Ġcreation Ġtime Ġ( seconds ) Ġ Ġ*/ ĊĠĠĠ Ġvar Ġcreation Time Seconds : ĠLong ĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠChecks Ġif Ġthe Ġpublic Ġkey Ġis Ġcompressed ĊĠĠĠĠ Ġ* ĊĠĠĠĠ Ġ* Ġ@ return ĠTRUE Ġif Ġthe Ġpublic Ġkey Ġis Ġcompressed ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġ/** ĠComp ressed Ġpublic Ġkey Ġ Ġ*/ ĊĠĠĠ Ġvar Ġis Compressed Ġ= Ġfalse ĊĠĠĠ Ġprotected Ġval Ġpub : ĠLazy EC Point ĊĊĠĠĠ Ġconstructor ( pub Key : ĠByteArray ?, Ġpub : ĠEC Point ?) Ġ: Ġthis ( pub Key , Ġnull , Ġpub , Ġfalse ) Ġ{} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠCreates Ġan ĠEC Key Ġpublic / private Ġkey Ġpair Ġusing Ġthe Ġsupplied Ġprivate Ġkey . Ġ ĠThe ĊĠĠĠĠ Ġ* Ġ' compressed ' Ġparameter Ġdetermines Ġthe Ġtype Ġof Ġpublic Ġkey Ġcreated . ĊĠĠĠĠ Ġ* ĊĠĠĠĠ Ġ* Ġ@ param ĠĠĠĠĠĠ Ġpriv Key ĠĠĠĠĠĠĠĠĠĠĠĠ ĠPrivate Ġkey ĊĠĠĠĠ Ġ* Ġ@ param ĠĠĠĠĠĠ Ġcompressed ĠĠĠĠĠĠĠĠĠ ĠTRUE Ġto Ġcreate Ġa Ġcompressed Ġpublic Ġkey ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġconstructor ( priv Key : ĠBigInteger ?, Ġpub : ĠEC Point ?, Ġcompressed : ĠBoolean ) Ġ: Ġthis ( null , Ġpriv Key , Ġpub , Ġcompressed ) Ġ{} ĊĊĠĠĠ Ġval Ġpub Key Point : ĠEC Point ĊĠĠĠĠĠĠĠ Ġget () Ġ= Ġpub . get () ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠReturn Ġthe Ġprivate Ġkey Ġbytes ĊĠĠĠĠ Ġ* ĊĠĠĠĠ Ġ* Ġ@ return ĠPrivate Ġkey Ġbytes Ġor Ġnull Ġif Ġthere Ġis Ġno Ġprivate Ġkey ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġval Ġpriv Key Bytes : ĠByteArray ? ĊĠĠĠĠĠĠĠ Ġget () Ġ= Ġif Ġ( priv Key Ġ!= Ġnull ) ĠUtils . big Integer ToBytes ( priv Key , Ġ 3 2 ) Ġelse Ġnull ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠChecks Ġif Ġthere Ġis Ġa Ġprivate Ġkey ĊĠĠĠĠ Ġ* ĊĠĠĠĠ Ġ* Ġ@ return ĠTRUE Ġif Ġthere Ġis Ġa Ġprivate Ġkey ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġfun Ġhas Priv Key (): ĠBoolean Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn Ġpriv Key Ġ!= Ġnull ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠCreates Ġa Ġsignature Ġfor Ġthe Ġsupplied Ġcontents Ġusing Ġthe Ġprivate Ġkey ĊĠĠĠĠ Ġ* ĊĠĠĠĠ Ġ* Ġ@ param ĠĠ Ġinput ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠSHA 2 5 6 Ġhash Ġof Ġcontents Ġto Ġbe ĊĠĠĠĠ Ġ* Ġ@ return Ġ Ġsigned ĠE CD SA Ġsignature ĊĠĠĠĠ Ġ* Ġ@ throws Ġ ĠEC Exception ĠĠĠĠĠĠĠĠĠĠĠĠ ĠUnable Ġto Ġcreate Ġsignature ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġ@ Throws ( EC Exception :: class ) ĊĠĠĠ Ġfun Ġsign ( input : ĠByteArray ): ĠEC DS AS ign ature Ġ{ ĊĠĠĠĠĠĠĠ ĠcheckNotNull ( priv Key ) Ġ{ Ġ" No Ġprivate Ġkey Ġavailable " Ġ} ĊĠĠĠĠĠĠĠ Ġ// ĊĠĠĠĠĠĠĠ Ġ// ĠCreate Ġthe Ġsignature ĊĠĠĠĠĠĠĠ Ġ// ĊĠĠĠĠĠĠĠ Ġval Ġsig s : ĠArray < BigInteger > Ġ= Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġsigner Ġ= ĠEC DS AC an onical Signer ( H Mac D SA K Calculator ( SHA 2 5 6 Digest ())) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġpriv Key Params Ġ= ĠE CP rivate Key Parameters ( priv Key , ĠCUR VE ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġsigner . init ( true , Ġpriv Key Params ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġsigner . generate Signature ( input ) ĊĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( exc : ĠRuntimeException ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġthrow ĠEC Exception (" Exception Ġwhile Ġcreating Ġsignature ", Ġexc ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ// ĊĠĠĠĠĠĠĠ Ġ// ĠCreate Ġa Ġcanonical Ġsignature Ġby Ġadjust ing Ġthe ĠS Ġcomponent Ġto Ġbe Ġless Ġthan Ġor Ġequal Ġto ĊĠĠĠĠĠĠĠ Ġ// Ġhalf Ġthe Ġcurve Ġorder . ĊĠĠĠĠĠĠĠ Ġ// ĊĠĠĠĠĠĠĠ Ġif Ġ( sigs [ 1 ]. compareTo ( HALF _ CUR VE _ ORDER ) Ġ> Ġ 0 ) Ġsig s [ 1 ] Ġ= ĠCUR VE . n . subtract ( sigs [ 1 ]) ĊĠĠĠĠĠĠĠ Ġreturn ĠEC DS AS ign ature ( sigs [ 0 ], Ġsig s [ 1 ]) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠCreates Ġa Ġsignature Ġfor Ġthe Ġsupplied Ġcontents Ġusing Ġthe Ġprivate Ġkey ĊĠĠĠĠ Ġ* ĊĠĠĠĠ Ġ* Ġ@ param ĠĠ Ġcontents ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠContents Ġto Ġbe Ġsigned ĊĠĠĠĠ Ġ* Ġ@ return Ġ ĠE CD SA Ġsignature ĊĠĠĠĠ Ġ* Ġ@ throws Ġ ĠEC Exception ĠĠĠĠĠĠĠĠĠĠĠĠ ĠUnable Ġto Ġcreate Ġsignature ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġ@ Throws ( EC Exception :: class ) ĊĠĠĠ Ġfun Ġcreate EC DS AS ign ature ( contents : ĠByteArray ): ĠEC DS AS ign ature Ġ{ ĊĠĠĠĠĠĠĠ ĠcheckNotNull ( priv Key ) Ġ{ Ġ" No Ġprivate Ġkey Ġavailable " Ġ} ĊĠĠĠĠĠĠĠ Ġ// ĊĠĠĠĠĠĠĠ Ġ// ĠGet Ġthe Ġdouble ĠSHA - 2 5 6 Ġhash Ġof Ġthe Ġsigned Ġcontents ĊĠĠĠĠĠĠĠ Ġ// ĊĠĠĠĠĠĠĠ Ġval Ġcontents Hash : ĠByteArray Ġ= Ġdouble Digest ( contents ) ĊĠĠĠĠĠĠĠ Ġ// ĊĠĠĠĠĠĠĠ Ġ// ĠCreate Ġthe Ġsignature ĊĠĠĠĠĠĠĠ Ġ// ĊĠĠĠĠĠĠĠ Ġval Ġsig s : ĠArray < BigInteger > ĊĠĠĠĠĠĠĠ Ġsig s Ġ= Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġsigner Ġ= ĠEC DS AS ign er ( H Mac D SA K Calculator ( SHA 2 5 6 Digest ())) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġpriv Key Params Ġ= ĠE CP rivate Key Parameters ( priv Key , ĠCUR VE ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġsigner . init ( true , Ġpriv Key Params ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġsigner . generate Signature ( contents Hash ) ĊĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( exc : ĠRuntimeException ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġthrow ĠEC Exception (" Exception Ġwhile Ġcreating Ġsignature ", Ġexc ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ// ĊĠĠĠĠĠĠĠ Ġ// ĠCreate Ġa Ġcanonical Ġsignature Ġby Ġadjust ing Ġthe ĠS Ġcomponent Ġto Ġbe Ġless Ġthan Ġor Ġequal Ġto ĊĠĠĠĠĠĠĠ Ġ// Ġhalf Ġthe Ġcurve Ġorder . ĊĠĠĠĠĠĠĠ Ġ// ĊĠĠĠĠĠĠĠ Ġif Ġ( sigs [ 1 ]. compareTo ( HALF _ CUR VE _ ORDER ) Ġ> Ġ 0 ) Ġsig s [ 1 ] Ġ= ĠCUR VE . n . subtract ( sigs [ 1 ]) ĊĠĠĠĠĠĠĠ Ġreturn ĠEC DS AS ign ature ( sigs [ 0 ], Ġsig s [ 1 ]) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ Throws ( EC Exception :: class ) ĊĠĠĠ Ġfun Ġcreate Signature ( contents : ĠByteArray ): ĠByteArray ? Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn Ġcreate EC DS AS ign ature ( contents ). encode To DER () ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠSign s Ġa Ġmessage Ġusing Ġthe Ġprivate Ġkey ĊĠĠĠĠ Ġ* ĊĠĠĠĠ Ġ* Ġ@ param ĠĠ Ġmessage ĠĠĠĠĠĠĠĠĠĠĠĠ ĠMessage Ġto Ġbe Ġsigned ĊĠĠĠĠ Ġ* Ġ@ return Ġ ĠBase 6 4 - encoded Ġsignature Ġstring ĊĠĠĠĠ Ġ* Ġ@ throws Ġ ĠEC Exception ĠĠĠĠĠĠĠĠ ĠUnable Ġto Ġsign Ġthe Ġmessage ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġ@ Throws ( EC Exception :: class ) ĊĠĠĠ Ġfun Ġsign Message ( message : ĠString ): ĠString Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġencoded Signature : ĠString ĊĠĠĠĠĠĠĠ ĠcheckNotNull ( priv Key ) Ġ{ Ġ" No Ġprivate Ġkey Ġavailable " Ġ} ĊĠĠĠĠĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠFormat Ġthe Ġmessage Ġfor Ġsigning ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĊĠĠĠĠĠĠĠĠĠĠĠ Ġvar Ġcontents : ĠByteArray ĊĠĠĠĠĠĠĠĠĠĠĠ ĠByteArrayOutputStream ( message . length Ġ* Ġ 2 ). use Ġ{ Ġout Stream Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġheader Bytes Ġ= ĠBIT CO IN _ SIGNED _ MESSAGE _ HEADER . toByteArray ( StandardCharsets . UTF _ 8 ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġout Stream . write ( Utils . encode ( header Bytes . size . to Long ())) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġout Stream . write ( header Bytes ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġmessage Bytes Ġ= Ġmessage . toByteArray ( StandardCharsets . UTF _ 8 ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġout Stream . write ( Utils . encode ( message Bytes . size . to Long ())) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġout Stream . write ( message Bytes ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcontents Ġ= Ġout Stream . toByteArray () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠCreate Ġthe Ġsignature ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġsig Ġ= Ġcreate EC DS AS ign ature ( contents ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠGet Ġthe ĠRec ID Ġused Ġto Ġrecover Ġthe Ġpublic Ġkey Ġfrom Ġthe Ġsignature ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġe : ĠBigInteger Ġ= ĠBigInteger ( 1 , Ġdouble Digest ( contents )) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġvar Ġrec ID Ġ= Ġ- 1 ĊĠĠĠĠĠĠĠĠĠĠĠ Ġfor Ġ( i Ġin Ġ 0 .. 3 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġk Ġ= Ġrecover From Signature ( i , Ġsig , Ġe , Ġis Compressed ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( k Ġ!= Ġnull Ġ&& ĠArrays . equals ( k . pub Key , Ġpub Key )) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġrec ID Ġ= Ġi ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġbreak ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( rec ID Ġ== Ġ- 1 ) Ġthrow ĠEC Exception (" Unable Ġto Ġrecover Ġpublic Ġkey Ġfrom Ġsignature ") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠThe Ġmessage Ġsignature Ġconsists Ġof Ġa Ġheader Ġbyte Ġfollowed Ġby Ġthe ĠR Ġand ĠS Ġvalues ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġheader Byte Ġ= Ġrec ID Ġ+ Ġ 2 7 Ġ+ Ġif Ġ( is Compressed ) Ġ 4 Ġelse Ġ 0 ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġsig Data Ġ= ĠByteArray ( 6 5 ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġsig Data [ 0 ] Ġ= Ġheader Byte . to Byte () ĊĠĠĠĠĠĠĠĠĠĠĠ ĠSystem . arraycopy ( Utils . big Integer ToBytes ( sig . r , Ġ 3 2 ) !! , Ġ 0 , Ġsig Data , Ġ 1 , Ġ 3 2 ) ĊĠĠĠĠĠĠĠĠĠĠĠ ĠSystem . arraycopy ( Utils . big Integer ToBytes ( sig . s , Ġ 3 2 ) !! , Ġ 0 , Ġsig Data , Ġ 3 3 , Ġ 3 2 ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠCreate Ġa ĠBase - 6 4 Ġencoded Ġstring Ġfor Ġthe Ġmessage Ġsignature ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĊĠĠĠĠĠĠĠĠĠĠĠ Ġencoded Signature Ġ= ĠString ( Base 6 4 . encode ( sig Data ), ĠStandard Charsets . UTF _ 8 ) ĊĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( exc : ĠIOException ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġthrow ĠIllegalStateException (" Unexpected ĠIOException ", Ġexc ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġreturn Ġencoded Signature ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠSign s Ġa Ġhashed Ġbytes Ġusing Ġthe Ġprivate Ġkey ĊĠĠĠĠ Ġ* ĊĠĠĠĠ Ġ* Ġ@ param ĠĠ Ġhashed ĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠHas hed Ġbytes Ġto Ġbe Ġsigned ĊĠĠĠĠ Ġ* Ġ@ return ĠĠ 6 5 Ġbyte Ġlength Ġsigned Ġsignature ĊĠĠĠĠ Ġ* Ġ@ throws Ġ ĠEC Exception ĠĠĠĠĠĠĠĠ ĠUnable Ġto Ġsign Ġthe Ġhashed Ġbytes ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġ@ Throws ( EC Exception :: class ) ĊĠĠĠ Ġfun Ġsign Only ( hashed : ĠByteArray ): ĠByteArray Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġsigned Ġ= Ġsign ( hashed ) ĊĠĠĠĠĠĠĠ Ġvar Ġrec Id Ġ= Ġ- 1 ĊĠĠĠĠĠĠĠ Ġfor Ġ( i Ġin Ġ 0 .. 3 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġk Ġ= Ġrecover From Signature ( i , Ġsigned , ĠBigInteger ( 1 , Ġhashed ), Ġis Compressed ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( k Ġ!= Ġnull Ġ&& ĠArrays . equals ( k . pub Key , Ġpub Key )) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġrec Id Ġ= Ġi ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġbreak ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġif Ġ( rec Id Ġ== Ġ- 1 ) Ġthrow ĠRuntimeException (" Could Ġnot Ġconstruct Ġa Ġrecover able Ġkey . ĠThis Ġshould Ġnever Ġhappen .") ĊĠĠĠĠĠĠĠ Ġval Ġheader Byte Ġ= Ġrec Id Ġ+ Ġ 2 7 Ġ+ Ġif Ġ( is Compressed ) Ġ 4 Ġelse Ġ 0 ĊĠĠĠĠĠĠĠ Ġval Ġsig Data Ġ= ĠByteArray ( 6 5 ) ĊĠĠĠĠĠĠĠ Ġsig Data [ 0 ] Ġ= Ġheader Byte . to Byte () ĊĠĠĠĠĠĠĠ ĠSystem . arraycopy ( Utils . big Integer ToBytes ( signed . r , Ġ 3 2 ) !! , Ġ 0 , Ġsig Data , Ġ 1 , Ġ 3 2 ) ĊĠĠĠĠĠĠĠ ĠSystem . arraycopy ( Utils . big Integer ToBytes ( signed . s , Ġ 3 2 ) !! , Ġ 0 , Ġsig Data , Ġ 3 3 , Ġ 3 2 ) ĊĠĠĠĠĠĠĠ Ġreturn Ġsig Data ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠChecks Ġif Ġtwo Ġobjects Ġare Ġequal ĊĠĠĠĠ Ġ* ĊĠĠĠĠ Ġ* Ġ@ param ĠĠ Ġobj ĠĠĠĠĠĠĠĠĠĠĠĠ ĠThe Ġobject Ġto Ġcheck ĊĠĠĠĠ Ġ* Ġ@ return Ġ ĠTRUE Ġif Ġthe Ġobject Ġis Ġequal ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġoverride Ġfun Ġequals ( obj : ĠAny ?): ĠBoolean Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn Ġobj Ġis ĠEC Key Ġ&& ĠArrays . equals ( pub Key , Ġobj . pub Key ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠReturns Ġthe Ġhash Ġcode Ġfor Ġthis Ġobject ĊĠĠĠĠ Ġ* ĊĠĠĠĠ Ġ* Ġ@ return ĠHash Ġcode ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġ// ĠĠĠ Ġ@ Override ĊĠĠĠ Ġ// ĠĠĠ Ġpublic Ġint ĠhashCode () Ġ{ ĊĠĠĠ Ġ// ĠĠĠĠĠĠĠ Ġreturn ĠArrays . hashCode ( pub Key ); ĊĠĠĠ Ġ// ĠĠĠ Ġ} ĊĠĠĠ Ġ// ĠFIXME : Ġ 2 0 2 1 / 8 / 1 8 Ġfix Ġhash code ĊĠĠĠ Ġoverride Ġfun ĠhashCode (): ĠInt Ġ{ ĊĠĠĠĠĠĠĠ Ġ// ĠPublic Ġkeys Ġare Ġrandom Ġalready Ġso Ġwe Ġcan Ġjust Ġuse Ġa Ġpart Ġof Ġthem Ġas Ġthe Ġhash code . ĠRead Ġfrom Ġthe Ġstart Ġto ĊĠĠĠĠĠĠĠ Ġ// Ġavoid Ġpicking Ġup Ġthe Ġtype Ġcode Ġ( compressed Ġvs Ġun compressed ) Ġwhich Ġis Ġtack ed Ġon Ġthe Ġend . ĊĠĠĠĠĠĠĠ Ġval Ġbits Ġ= Ġpub Key ĊĠĠĠĠĠĠĠ Ġreturn Ġfrom Bytes ( bits [ 0 ], Ġbits [ 1 ], Ġbits [ 2 ], Ġbits [ 3 ]) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠEC DS AS ign ature Ġis Ġan Ġel li ptic Ġcurve Ġdigital Ġsignature Ġconsisting Ġof Ġthe ĊĠĠĠĠ Ġ* ĠR Ġand ĠS Ġvalues . ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġclass ĠEC DS AS ign ature Ġ{ ĊĠĠĠĠĠĠĠ Ġ/** ĊĠĠĠĠĠĠĠĠ Ġ* ĠReturns Ġthe ĠR Ġvalue ĊĠĠĠĠĠĠĠĠ Ġ* ĊĠĠĠĠĠĠĠĠ Ġ* Ġ@ return ĠR Ġcomponent ĊĠĠĠĠĠĠĠĠ Ġ*/ ĊĠĠĠĠĠĠĠ Ġ/** ĊĠĠĠĠĠĠĠĠ Ġ* ĠR Ġand ĠS Ġcomponents Ġof Ġthe Ġdigital Ġsignature ĊĠĠĠĠĠĠĠĠ Ġ*/ ĊĠĠĠĠĠĠĠ Ġvar Ġr : ĠBigInteger ? Ġ= Ġnull ĊĠĠĠĠĠĠĠĠĠĠĠ Ġprivate Ġset ĊĊĠĠĠĠĠĠĠ Ġ/** ĊĠĠĠĠĠĠĠĠ Ġ* ĠReturns Ġthe ĠS Ġvalue ĊĠĠĠĠĠĠĠĠ Ġ* ĊĠĠĠĠĠĠĠĠ Ġ* Ġ@ return ĠS Ġcomponent ĊĠĠĠĠĠĠĠĠ Ġ*/ ĊĠĠĠĠĠĠĠ Ġvar Ġs : ĠBigInteger ? Ġ= Ġnull ĊĠĠĠĠĠĠĠĠĠĠĠ Ġprivate Ġset ĊĊĠĠĠĠĠĠĠ Ġ/** ĊĠĠĠĠĠĠĠĠ Ġ* ĠCreates Ġa Ġdigital Ġsignature Ġfrom Ġthe ĠR Ġand ĠS Ġvalues ĊĠĠĠĠĠĠĠĠ Ġ* ĊĠĠĠĠĠĠĠĠ Ġ* Ġ@ param Ġr ĠR Ġvalue ĊĠĠĠĠĠĠĠĠ Ġ* Ġ@ param Ġs ĠS Ġvalue ĊĠĠĠĠĠĠĠĠ Ġ*/ ĊĠĠĠĠĠĠĠ Ġconstructor ( r : ĠBigInteger ?, Ġs : ĠBigInteger ?) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġthis . r Ġ= Ġr ĊĠĠĠĠĠĠĠĠĠĠĠ Ġthis . s Ġ= Ġs ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġ/** ĊĠĠĠĠĠĠĠĠ Ġ* ĠCreates Ġa Ġdigital Ġsignature Ġfrom Ġthe ĠD ER - encoded Ġvalues ĊĠĠĠĠĠĠĠĠ Ġ* ĊĠĠĠĠĠĠĠĠ Ġ* Ġ@ param Ġencoded Stream ĠD ER - encoded Ġvalue ĊĠĠĠĠĠĠĠĠ Ġ* Ġ@ throws ĠEC Exception ĠUnable Ġto Ġdecode Ġthe Ġstream ĊĠĠĠĠĠĠĠĠ Ġ*/ ĊĠĠĠĠĠĠĠ Ġconstructor ( encoded Stream : ĠByteArray ?) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠASN 1 InputStream ( encoded Stream ). use Ġ{ Ġdecoder Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġseq Ġ= Ġdecoder . read Object () Ġas ĠDL Sequence ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġr Ġ= Ġ( seq . getObject At ( 0 ) Ġas ĠASN 1 Integer ). positive Value ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġs Ġ= Ġ( seq . getObject At ( 1 ) Ġas ĠASN 1 Integer ). positive Value ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( exc : ĠClass CastException ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġthrow ĠEC Exception (" Unable Ġto Ġdecode Ġsignature ", Ġexc ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( exc : ĠIOException ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġthrow ĠEC Exception (" Unable Ġto Ġdecode Ġsignature ", Ġexc ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġ/** ĊĠĠĠĠĠĠĠĠ Ġ* ĠEn codes ĠR Ġand ĠS Ġas Ġa ĠD ER - encoded Ġbyte Ġstream ĊĠĠĠĠĠĠĠĠ Ġ* ĊĠĠĠĠĠĠĠĠ Ġ* Ġ@ return ĠD ER - encoded Ġbyte Ġstream ĊĠĠĠĠĠĠĠĠ Ġ*/ ĊĠĠĠĠĠĠĠ Ġfun Ġencode To DER (): ĠByteArray ? Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġvar Ġencoded Bytes : ĠByteArray ? Ġ= Ġnull ĊĠĠĠĠĠĠĠĠĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠByteArrayOutputStream ( 7 2 ). use Ġ{ Ġout Stream Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġseq Ġ= ĠD ER Sequence Generator ( out Stream ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġseq . add Object ( ASN 1 Integer ( r )) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġseq . add Object ( ASN 1 Integer ( s )) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġseq . close () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġencoded Bytes Ġ= Ġout Stream . toByteArray () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( exc : ĠIOException ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġthrow ĠIllegalStateException (" Unexpected ĠIOException ", Ġexc ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġencoded Bytes ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġ/** ĊĠĠĠĠĠĠĠĠ Ġ* ĠReturns Ġtrue Ġif Ġthe ĠS Ġcomponent Ġis Ġ" low ", Ġthat Ġmeans Ġit Ġis Ġbelow Ġ[ EC Key . HALF _ CUR VE _ ORDER ]. ĠSee Ġ[ B IP 6 2 ]( https :// github . com / bitcoin / b ips / blob / master / bip - 0 0 6 2 . medi aw iki # Low _ S _ values _ in _ signatures ). ĊĠĠĠĠĠĠĠĠ Ġ*/ ĊĠĠĠĠĠĠĠ Ġval Ġis Canonical : ĠBoolean ĊĠĠĠĠĠĠĠĠĠĠĠ Ġget () Ġ= Ġs !!. compareTo ( HALF _ CUR VE _ ORDER ) Ġ<= Ġ 0 ĊĊĠĠĠĠĠĠĠ Ġ/** ĊĠĠĠĠĠĠĠĠ Ġ* ĠWill Ġautomatically Ġadjust Ġthe ĠS Ġcomponent Ġto Ġbe Ġless Ġthan Ġor Ġequal Ġto Ġhalf Ġthe Ġcurve Ġorder , Ġif Ġnecessary . ĊĠĠĠĠĠĠĠĠ Ġ* ĠThis Ġis Ġrequired Ġbecause Ġfor Ġevery Ġsignature Ġ( r , s ) Ġthe Ġsignature Ġ( r , Ġ- s Ġ( mod ĠN )) Ġis Ġa Ġvalid Ġsignature Ġof ĊĠĠĠĠĠĠĠĠ Ġ* Ġthe Ġsame Ġmessage . ĠHowever , Ġwe Ġdis like Ġthe Ġability Ġto Ġmodify Ġthe Ġbits Ġof Ġa ĠBitcoin Ġtransaction Ġafter Ġit 's ĊĠĠĠĠĠĠĠĠ Ġ* Ġbeen Ġsigned , Ġas Ġthat Ġviol ates Ġvarious Ġassumed Ġin variants . ĠThus Ġin Ġfuture Ġonly Ġone Ġof Ġthose Ġforms Ġwill Ġbe ĊĠĠĠĠĠĠĠĠ Ġ* Ġconsidered Ġlegal Ġand Ġthe Ġother Ġwill Ġbe Ġb anned . ĊĠĠĠĠĠĠĠĠ Ġ*/ ĊĠĠĠĠĠĠĠ Ġfun Ġto Canonical ised (): ĠEC DS AS ign ature Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġif Ġ(! is Canonical ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠThe Ġorder Ġof Ġthe Ġcurve Ġis Ġthe Ġnumber Ġof Ġvalid Ġpoints Ġthat Ġexist Ġon Ġthat Ġcurve . ĠIf ĠS Ġis Ġin Ġthe Ġupper ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġhalf Ġof Ġthe Ġnumber Ġof Ġvalid Ġpoints , Ġthen Ġbring Ġit Ġback Ġto Ġthe Ġlower Ġhalf . ĠOtherwise , Ġimagine Ġthat ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠĠĠ ĠN Ġ= Ġ 1 0 ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠĠĠ Ġs Ġ= Ġ 8 , Ġso Ġ(- 8 Ġ% Ġ 1 0 Ġ== Ġ 2 ) Ġthus Ġboth Ġ( r , Ġ 8 ) Ġand Ġ( r , Ġ 2 ) Ġare Ġvalid Ġsolutions . ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠĠĠĠ 1 0 Ġ- Ġ 8 Ġ== Ġ 2 , Ġgiving Ġus Ġalways Ġthe Ġlatter Ġsolution , Ġwhich Ġis Ġcanonical . ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠEC DS AS ign ature ( r , ĠCUR VE . n . subtract ( s )) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġthis ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠCreates Ġan ĠEC Key Ġwith Ġthe Ġsupplied Ġpublic / private Ġkey Ġpair . Ġ ĠThe Ġprivate Ġkey Ġmay Ġbe ĊĠĠĠĠ Ġ* Ġnull Ġif Ġyou Ġonly Ġwant Ġto Ġuse Ġthis ĠEC Key Ġto Ġverify Ġsignatures . Ġ ĠThe Ġpublic Ġkey Ġwill ĊĠĠĠĠ Ġ* Ġbe Ġgenerated Ġfrom Ġthe Ġprivate Ġkey Ġif Ġit Ġis Ġnot Ġprovided Ġ( the Ġ' compressed ' Ġparameter ĊĠĠĠĠ Ġ* Ġdetermines Ġthe Ġtype Ġof Ġpublic Ġkey Ġcreated ) ĊĠĠĠĠ Ġ* Ġ@ param ĠĠĠĠĠĠ Ġpub Key ĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠPublic Ġkey Ġor Ġnull ĊĠĠĠĠ Ġ* Ġ@ param ĠĠĠĠĠĠ Ġpriv Key ĠĠĠĠĠĠĠĠĠĠĠĠ ĠPrivate Ġkey Ġor Ġnull ĊĠĠĠĠ Ġ* Ġ@ param Ġpub ĊĠĠĠĠ Ġ* Ġ@ param ĠĠĠĠĠĠ Ġcompressed ĠĠĠĠĠĠĠĠĠ ĠTRUE Ġto Ġcreate Ġa Ġcompressed Ġpublic Ġkey ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠCreates Ġan ĠEC Key Ġwith Ġjust Ġa Ġpublic Ġkey ĊĠĠĠĠ Ġ* ĊĠĠĠĠ Ġ* Ġ@ param ĠĠĠĠĠĠ Ġpub Key ĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠPublic Ġkey ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġinit Ġ{ ĊĠĠĠĠĠĠĠ Ġthis . pub Ġ= ĠLazy EC Point ( pub ) ĊĠĠĠĠĠĠĠ Ġif Ġ( pub Key Ġ!= Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġthis . pub Key Ġ= ĠArrays . copyOf Range ( pub Key , Ġ 0 , Ġpub Key . size ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġis Compressed Ġ= Ġpub Key . size Ġ== Ġ 3 3 ĊĠĠĠĠĠĠĠ Ġ} Ġelse Ġif Ġ( priv Key Ġ!= Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġthis . pub Key Ġ= Ġpub Key From Priv Key ( priv Key , Ġcompressed ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġis Compressed Ġ= Ġcompressed ĊĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġthrow ĠIllegalArgumentException (" You Ġmust Ġprovide Ġat Ġleast Ġa Ġprivate Ġkey Ġor Ġa Ġpublic Ġkey ") ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġcreation Time Seconds Ġ= ĠSystem . currentTimeMillis () Ġ/ Ġ 1 0 0 0 ĊĠĠĠ Ġ} Ċ }