diff options
| author | polwex <polwex@sortug.com> | 2025-11-12 07:11:07 +0700 |
|---|---|---|
| committer | polwex <polwex@sortug.com> | 2025-11-12 07:11:07 +0700 |
| commit | 284ce9ce7d9f81e54e91f917329d48926487fbf4 (patch) | |
| tree | 7a156986323fd799e1457c8b7663806e32b2af7d /app/lib/bip | |
| parent | 7305d67ff7f9e78b73326ef0e1f68a9613d34205 (diff) | |
fixes to engagement handling
Diffstat (limited to 'app/lib/bip')
| -rw-r--r-- | app/lib/bip/b173.hoon | 145 |
1 files changed, 145 insertions, 0 deletions
diff --git a/app/lib/bip/b173.hoon b/app/lib/bip/b173.hoon new file mode 100644 index 0000000..e554597 --- /dev/null +++ b/app/lib/bip/b173.hoon @@ -0,0 +1,145 @@ +:: BIP173: Bech32 Addresses +:: https://github.com/bitcoin/bips/blob/master/bip-0173.mediawiki +:: +:: Heavily copies: +:: https://github.com/bitcoinjs/bech32/blob/master/index.js +:: +:: TODO not really working at generating npub/nsec keys from hex +/- sur=bitcoin +/+ bcu=bitcoin-utils +=, sur +=, bcu +|% +++ prefixes + ^- (map network tape) + (my [[%main "bc"] [%testnet "tb"] [%regtest "bcrt"] ~]) +++ charset "qpzry9x8gf2tvdw0s3jn54khce6mua7l" ++$ raw-decoded [hrp=tape data=(list @) checksum=(list @)] +:: below is a port of: https://github.com/bitcoinjs/bech32/blob/master/index.js +:: +++ polymod + |= values=(list @) + |^ ^- @ + =/ gen=(list @ux) + ~[0x3b6a.57b2 0x2650.8e6d 0x1ea1.19fa 0x3d42.33dd 0x2a14.62b3] + =/ chk=@ 1 + |- ?~ values chk + =/ top (rsh [0 25] chk) + =. chk + (mix i.values (lsh [0 5] (dis chk 0x1ff.ffff))) + $(values t.values, chk (update-chk chk top gen)) +:: + ++ update-chk + |= [chk=@ top=@ gen=(list @ux)] + =/ is (gulf 0 4) + |- ?~ is chk + ?: =(1 (dis 1 (rsh [0 i.is] top))) + $(is t.is, chk (mix chk (snag i.is gen))) + $(is t.is) + -- +:: +++ expand-hrp + |= hrp=tape + ^- (list @) + =/ front (turn hrp |=(p=@tD (rsh [0 5] p))) + =/ back (turn hrp |=(p=@tD (dis 31 p))) + (zing ~[front ~[0] back]) +:: +++ verify-checksum + |= [hrp=tape data-and-checksum=(list @)] + ^- ? + %- |=(a=@ =(1 a)) + %- polymod + (weld (expand-hrp hrp) data-and-checksum) +:: +++ checksum + |= [hrp=tape data=(list @)] + ^- (list @) + :: xor 1 with the polymod + :: + =/ pmod=@ + %+ mix 1 + %- polymod + (zing ~[(expand-hrp hrp) data (reap 6 0)]) + %+ turn (gulf 0 5) + |=(i=@ (dis 31 (rsh [0 (mul 5 (sub 5 i))] pmod))) +:: +++ charset-to-value + |= c=@tD + ^- (unit @) + (find ~[c] charset) +++ value-to-charset + |= value=@ + ^- (unit @tD) + ?: (gth value 31) ~ + `(snag value charset) +:: +++ is-valid + |= [bech=tape last-1-pos=@] ^- ? + ?& ?|(=((cass bech) bech) =((cuss bech) bech)) :: to upper or to lower is same as bech + (gte last-1-pos 1) + (lte (add last-1-pos 7) (lent bech)) + (lte (lent bech) 90) + (levy bech |=(c=@tD (gte c 33))) + (levy bech |=(c=@tD (lte c 126))) + == +:: data should be 5bit words +:: +++ encode-raw + |= [hrp=tape data=(list @)] + ^- cord + =/ combined=(list @) + (weld data (checksum hrp data)) + %- crip + (zing ~[hrp "1" (tape (murn combined value-to-charset))]) +++ decode-raw + |= body=cord + ^- (unit raw-decoded) + =/ bech (cass (trip body)) :: to lowercase + =/ pos (flop (fand "1" bech)) + ?~ pos ~ + =/ last-1=@ i.pos + ?. (is-valid bech last-1) :: check bech32 validity (not segwit validity or checksum) + ~ + =/ hrp (scag last-1 bech) + =/ encoded-data-and-checksum=(list @) + (slag +(last-1) bech) + =/ data-and-checksum=(list @) + %+ murn encoded-data-and-checksum + charset-to-value + ?. =((lent encoded-data-and-checksum) (lent data-and-checksum)) :: ensure all were in CHARSET + ~ + ?. (verify-checksum hrp data-and-checksum) + ~ + =/ checksum-pos (sub (lent data-and-checksum) 6) + `[hrp (scag checksum-pos data-and-checksum) (slag checksum-pos data-and-checksum)] +:: +from-address: BIP173 bech32 address encoding to hex +:: https://github.com/bitcoin/bips/blob/master/bip-0173.mediawiki +:: expects to drop a leading 5-bit 0 (the witness version) +:: +++ from-address + |= body=cord + ^- hexb + ~| "Invalid bech32 address" + =/ d=(unit raw-decoded) (decode-raw body) + ?> ?=(^ d) + =/ bs=bits (from-atoms:bit 5 data.u.d) + =/ byt-len=@ (div (sub wid.bs 5) 8) + ?> =(5^0b0 (take:bit 5 bs)) + ?> ?| =(20 byt-len) + =(32 byt-len) + == + [byt-len `@ux`dat:(take:bit (mul 8 byt-len) (drop:bit 5 bs))] +:: pubkey is the 33 byte ECC compressed public key +:: +++ encode-pubkey + |= [=network pubkey=byts] + ^- (unit cord) + ?. =(33 wid.pubkey) + ~|('pubkey must be a 33 byte ECC compressed public key' !!) + =/ prefix (~(get by prefixes) network) + ?~ prefix ~ + :- ~ + %+ encode-raw u.prefix + [0v0 (to-atoms:bit 5 [160 `@ub`dat:(hash-160 pubkey)])] +-- |
