urbit/lib/btc-address.hoon
2021-05-26 18:30:11 -07:00

73 lines
1.8 KiB
Plaintext

|%
+$ pubkey (list @ux)
+$ chaincode (list @ux)
+$ parsed-xpub [cc=chaincode pubk=pubkey]
+$ il-ir [il=(list @ux) ir=(list @ux)]
:: b[ytes]rip: 0x6261 -> ~[98 97]
::
++ big-endian-brip
|= a=@ux
^- (list @ux)
(flop (rip 3 a))
:: b[ytes]rap: ~[98 97] -> 0x6261
::
++ big-endian-brap
|= bytes=(list @ux)
^- @ux
(swp 3 (rap 3 bytes))
::
++ pubkey-to-point
|= =pubkey
^- pont:secp:crypto
~& >> "compressed pubkey length: {<(lent pubkey)>}"
%- decompress-point:secp256k1:secp:crypto
(big-endian-brap pubkey)
::
++ is-point
|= =pubkey ^- ?
-:(mule |.((pubkey-to-point pubkey)))
::
++ parse-xpub
|= xpub=tape
^- (unit parsed-xpub)
=/ as-atom=@ux
(de-base58:mimes:html xpub)
=/ bytes=(list @ux)
(big-endian-brip as-atom)
~& >> "parse-xpub, depth: {<(snag 4 bytes)>}"
=/ pp=parsed-xpub
[(swag [13 32] bytes) (swag [45 33] bytes)]
?: (is-point pubk.pp)
`pp
~
::
++ compute-i
|= [=parsed-xpub index=@ud]
^- il-ir
~| 'Public key cannot use a hardened index'
?> (lth index (bex 31))
:: "append" index to pubkey as 4 bytes
=/ data=@
%+ add
(lsh 3 4 (big-endian-brap pubk.parsed-xpub))
index
=/ chaincode=@
(big-endian-brap cc.parsed-xpub)
=/ i=(list @ux)
(big-endian-brip (hmac-sha512:hmac:crypto chaincode data))
=/ il=(list @ux) (swag [0 32] i)
=/ ir=(list @ux) (swag [32 32] i)
[il ir]
++ child-from-xpub
|= [xpub=tape index=@ud]
=, secp256k1:secp:crypto
=/ upx=(unit parsed-xpub)
(parse-xpub xpub)
?~ upx ~
=/ px=parsed-xpub u.upx
=/ is (compute-i px index)
(compress-point (jc-add (priv-to-pub (big-endian-brap il.is)) (pubkey-to-point pubk.px)))
--
:: `@ux`(compress-point:secp256k1:secp:crypto (jc-add:secp256k1:secp:crypto (pubkey-to-point:btca pubk.u.px) x))