unified_address: updates for large UAs/UVKs.

Signed-off-by: Daira Hopwood <daira@jacaranda.org>
This commit is contained in:
Daira Hopwood 2021-08-30 19:25:20 +01:00
parent 71e2a355c4
commit 29cae03b12
1 changed files with 33 additions and 32 deletions

View File

@ -4,17 +4,18 @@ import sys; assert sys.version_info[0] >= 3, "Python 3 required."
import math import math
import struct import struct
from pyblake2 import blake2b
from bech32m import bech32_encode, bech32_decode, convertbits, Encoding from bech32m import bech32_encode, bech32_decode, convertbits, Encoding
from tv_output import render_args, render_tv, Some from tv_output import render_args, render_tv, Some
from tv_rand import Rand from tv_rand import Rand
from zc_utils import write_compact_size, parse_compact_size
from f4jumble import f4jumble, f4jumble_inv from f4jumble import f4jumble, f4jumble_inv
import sapling_key_components import sapling_key_components
import orchard_key_components import orchard_key_components
def tlv(typecode, value): def tlv(typecode, value):
return b"".join([bytes([typecode, len(value)]), value]) return b"".join([write_compact_size(typecode), write_compact_size(len(value)), value])
def padding(hrp): def padding(hrp):
assert(len(hrp) <= 16) assert(len(hrp) <= 16)
@ -51,46 +52,46 @@ def decode_unified(addr_str):
suffix = decoded[-16:] suffix = decoded[-16:]
# check trailing padding bytes # check trailing padding bytes
assert suffix == padding(hrp) assert suffix == padding(hrp)
decoded = decoded[:-16] rest = decoded[:-16]
s = 0 s = 0
acc = []
result = {} result = {}
for b in decoded: while len(rest) > 0:
if s == 0: if s == 0:
receiver_type = b (receiver_type, receiver_type_len) = parse_compact_size(rest)
rest = rest[receiver_type_len:]
s = 1 s = 1
elif s == 1: elif s == 1:
receiver_len = b (receiver_len, receiver_len_len) = parse_compact_size(rest)
rest = rest[receiver_len_len:]
expected_len = {0: 20, 1: 20, 2: 43, 3: 43}.get(receiver_type) expected_len = {0: 20, 1: 20, 2: 43, 3: 43}.get(receiver_type)
if expected_len is not None: if expected_len is not None:
assert receiver_len == expected_len, "incorrect receiver length" assert receiver_len == expected_len, "incorrect receiver length"
s = 2 s = 2
elif s == 2: elif s == 2:
if len(acc) < receiver_len: assert len(rest) >= receiver_len
acc.append(b) (receiver, rest) = (rest[:receiver_len], rest[receiver_len:])
if len(acc) == receiver_len:
if receiver_type == 0 or receiver_type == 1:
assert not ('transparent' in result), "duplicate transparent receiver detected"
assert len(acc) == 20
result['transparent'] = bytes(acc)
acc = []
s = 0
elif receiver_type == 2: if receiver_type == 0 or receiver_type == 1:
assert not ('sapling' in result), "duplicate sapling receiver detected" assert not ('transparent' in result), "duplicate transparent receiver detected"
assert len(acc) == 43 assert len(receiver) == 20
result['sapling'] = bytes(acc) result['transparent'] = receiver
acc = [] s = 0
s = 0
elif receiver_type == 2:
assert not ('sapling' in result), "duplicate sapling receiver detected"
assert len(receiver) == 43
result['sapling'] = receiver
s = 0
elif receiver_type == 3:
assert not ('orchard' in result), "duplicate orchard receiver detected"
assert len(receiver) == 43
result['orchard'] = receiver
s = 0
elif receiver_type == 3:
assert not ('orchard' in result), "duplicate orchard receiver detected"
assert len(acc) == 43
result['orchard'] = bytes(acc)
acc = []
s = 0
return result return result
@ -130,13 +131,13 @@ def main():
orchard_default_d = orchard_fvk.default_d() orchard_default_d = orchard_fvk.default_d()
orchard_default_pk_d = orchard_fvk.default_pkd() orchard_default_pk_d = orchard_fvk.default_pkd()
orchard_raw_addr = b"".join([orchard_default_d[:11], bytes(orchard_default_pk_d)[:32]]) orchard_raw_addr = b"".join([orchard_default_d[:11], bytes(orchard_default_pk_d)[:32]])
else: else:
orchard_raw_addr = None orchard_raw_addr = None
is_p2pkh = rand.bool() is_p2pkh = rand.bool()
receivers = [ receivers = [
orchard_raw_addr, orchard_raw_addr,
sapling_raw_addr, sapling_raw_addr,
(is_p2pkh, t_addr) (is_p2pkh, t_addr)
] ]
ua = encode_unified(receivers) ua = encode_unified(receivers)