83 lines
2.5 KiB
Python
83 lines
2.5 KiB
Python
|
#!/usr/bin/env python3
|
||
|
import sys; assert sys.version_info[0] >= 3, "Python 3 required."
|
||
|
|
||
|
import math
|
||
|
from random import Random
|
||
|
import struct
|
||
|
import base58
|
||
|
|
||
|
from ..bech32m import bech32_encode, bech32_decode, convertbits, Encoding
|
||
|
from ..output import render_args, render_tv, Some
|
||
|
from ..rand import Rand, randbytes
|
||
|
from ..hd_common import ZCASH_MAIN_COINTYPE, hardened
|
||
|
from .bip_0032 import ExtendedSecretKey
|
||
|
|
||
|
class HrpMismatch(Exception):
|
||
|
pass
|
||
|
|
||
|
class InvalidEncoding(Exception):
|
||
|
pass
|
||
|
|
||
|
def encode(hrp, p2pkh_bytes):
|
||
|
converted = convertbits(p2pkh_bytes, 8, 5)
|
||
|
return bech32_encode("tex", converted, Encoding.BECH32M)
|
||
|
|
||
|
def decode(hrp_expected, tex_addr):
|
||
|
(hrp, data, encoding) = bech32_decode(tex_addr)
|
||
|
if data is None or encoding != Encoding.BECH32M:
|
||
|
raise InvalidEncoding("ZIP 320 addresses must be encoded using Bech32m")
|
||
|
if hrp != hrp_expected:
|
||
|
raise HrpMismatch("Expected: " + hrp_expected + "; got " + hrp)
|
||
|
return bytes(convertbits(data, 5, 8, False))
|
||
|
|
||
|
def main():
|
||
|
args = render_args()
|
||
|
|
||
|
rng = Random(0xabad533d)
|
||
|
rand = Rand(randbytes(rng))
|
||
|
seed = bytes(range(32))
|
||
|
|
||
|
t_root_key = ExtendedSecretKey.master(seed)
|
||
|
t_purpose_key = t_root_key.child(hardened(44))
|
||
|
t_coin_key = t_purpose_key.child(hardened(ZCASH_MAIN_COINTYPE))
|
||
|
|
||
|
test_vectors = []
|
||
|
for account in range(0, 5):
|
||
|
for j in range(0, 3):
|
||
|
t_account_key = t_coin_key.child(hardened(account))
|
||
|
t_external_key = t_account_key.child(0)
|
||
|
t_index_key = t_external_key.child(j)
|
||
|
t_index_pubkey = t_index_key.public_key()
|
||
|
p2pkh_bytes = t_index_pubkey.address()
|
||
|
t_addr = base58.b58encode_check(bytes([0x1c, 0xb8]) + p2pkh_bytes).decode('utf-8')
|
||
|
|
||
|
tex_addr = encode("tex", p2pkh_bytes)
|
||
|
|
||
|
p2pkh_bytes_decoded = decode("tex", tex_addr)
|
||
|
assert p2pkh_bytes_decoded == p2pkh_bytes
|
||
|
|
||
|
test_vectors.append({
|
||
|
't_addr': t_addr,
|
||
|
'p2pkh_bytes': p2pkh_bytes,
|
||
|
'tex_addr': tex_addr,
|
||
|
'account': account,
|
||
|
'child_index': j,
|
||
|
})
|
||
|
|
||
|
render_tv(
|
||
|
args,
|
||
|
'transparent/zip_0320',
|
||
|
(
|
||
|
('t_addr', {'rust_type': '&\'static str'}),
|
||
|
('p2pkh_bytes', '[u8; 20]'),
|
||
|
('tex_addr', {'rust_type': '&\'static str'}),
|
||
|
('account', 'u32'),
|
||
|
('child_index', 'u32'),
|
||
|
),
|
||
|
test_vectors,
|
||
|
)
|
||
|
|
||
|
|
||
|
if __name__ == "__main__":
|
||
|
main()
|