92 lines
3.0 KiB
Python
92 lines
3.0 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, ZCASH_TEST_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(hrp, 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))
|
|
|
|
ADDRESS_CONSTANTS = {
|
|
"mainnet": { "coin_type": ZCASH_MAIN_COINTYPE, "p2pkh_lead": [0x1c, 0xb8], "tex_hrp": "tex" },
|
|
"testnet": { "coin_type": ZCASH_TEST_COINTYPE, "p2pkh_lead": [0x1d, 0x25], "tex_hrp": "textest" },
|
|
"regtest": { "coin_type": ZCASH_TEST_COINTYPE, "p2pkh_lead": [0x1d, 0x25], "tex_hrp": "texregtest" },
|
|
}
|
|
|
|
def main():
|
|
args = render_args()
|
|
|
|
network = "mainnet"
|
|
constants = ADDRESS_CONSTANTS[network]
|
|
|
|
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(constants["coin_type"]))
|
|
|
|
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(constants["p2pkh_lead"]) + p2pkh_bytes).decode('utf-8')
|
|
|
|
tex_addr = encode(constants["tex_hrp"], p2pkh_bytes)
|
|
|
|
p2pkh_bytes_decoded = decode(constants["tex_hrp"], 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,
|
|
'zcash_test_vectors/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()
|