|
3 | 3 | # Distributed under the MIT software license, see the accompanying
|
4 | 4 | # file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
5 | 5 | '''
|
6 |
| -Generate valid and invalid base58 address and private key test vectors. |
| 6 | +Generate valid and invalid base58/bech32(m) address and private key test vectors. |
7 | 7 |
|
8 | 8 | Usage:
|
9 |
| - PYTHONPATH=../../test/functional/test_framework ./gen_key_io_test_vectors.py valid 50 > ../../src/test/data/key_io_valid.json |
10 |
| - PYTHONPATH=../../test/functional/test_framework ./gen_key_io_test_vectors.py invalid 50 > ../../src/test/data/key_io_invalid.json |
| 9 | + PYTHONPATH=../../test/functional/test_framework ./gen_key_io_test_vectors.py valid 70 > ../../src/test/data/key_io_valid.json |
| 10 | + PYTHONPATH=../../test/functional/test_framework ./gen_key_io_test_vectors.py invalid 70 > ../../src/test/data/key_io_invalid.json |
11 | 11 | '''
|
12 | 12 | # 2012 Wladimir J. van der Laan
|
13 | 13 | # Released under MIT License
|
14 | 14 | import os
|
15 | 15 | from itertools import islice
|
16 | 16 | from base58 import b58encode_chk, b58decode_chk, b58chars
|
17 | 17 | import random
|
18 |
| -from segwit_addr import bech32_encode, decode_segwit_address, convertbits, CHARSET |
| 18 | +from segwit_addr import bech32_encode, decode_segwit_address, convertbits, CHARSET, Encoding |
19 | 19 |
|
20 | 20 | # key types
|
21 | 21 | PUBKEY_ADDRESS = 0
|
|
32 | 32 | OP_0 = 0x00
|
33 | 33 | OP_1 = 0x51
|
34 | 34 | OP_2 = 0x52
|
| 35 | +OP_3 = 0x53 |
35 | 36 | OP_16 = 0x60
|
36 | 37 | OP_DUP = 0x76
|
37 | 38 | OP_EQUAL = 0x87
|
|
44 | 45 | script_suffix = (OP_EQUAL,)
|
45 | 46 | p2wpkh_prefix = (OP_0, 20)
|
46 | 47 | p2wsh_prefix = (OP_0, 32)
|
| 48 | +p2tr_prefix = (OP_1, 32) |
47 | 49 |
|
48 | 50 | metadata_keys = ['isPrivkey', 'chain', 'isCompressed', 'tryCaseFlip']
|
49 | 51 | # templates for valid sequences
|
|
54 | 56 | ((SCRIPT_ADDRESS,), 20, (), (False, 'main', None, None), script_prefix, script_suffix),
|
55 | 57 | ((PUBKEY_ADDRESS_TEST,), 20, (), (False, 'test', None, None), pubkey_prefix, pubkey_suffix),
|
56 | 58 | ((SCRIPT_ADDRESS_TEST,), 20, (), (False, 'test', None, None), script_prefix, script_suffix),
|
| 59 | + ((PUBKEY_ADDRESS_TEST,), 20, (), (False, 'signet', None, None), pubkey_prefix, pubkey_suffix), |
| 60 | + ((SCRIPT_ADDRESS_TEST,), 20, (), (False, 'signet', None, None), script_prefix, script_suffix), |
57 | 61 | ((PUBKEY_ADDRESS_REGTEST,), 20, (), (False, 'regtest', None, None), pubkey_prefix, pubkey_suffix),
|
58 | 62 | ((SCRIPT_ADDRESS_REGTEST,), 20, (), (False, 'regtest', None, None), script_prefix, script_suffix),
|
59 | 63 | ((PRIVKEY,), 32, (), (True, 'main', False, None), (), ()),
|
60 | 64 | ((PRIVKEY,), 32, (1,), (True, 'main', True, None), (), ()),
|
61 | 65 | ((PRIVKEY_TEST,), 32, (), (True, 'test', False, None), (), ()),
|
62 | 66 | ((PRIVKEY_TEST,), 32, (1,), (True, 'test', True, None), (), ()),
|
| 67 | + ((PRIVKEY_TEST,), 32, (), (True, 'signet', False, None), (), ()), |
| 68 | + ((PRIVKEY_TEST,), 32, (1,), (True, 'signet', True, None), (), ()), |
63 | 69 | ((PRIVKEY_REGTEST,), 32, (), (True, 'regtest', False, None), (), ()),
|
64 | 70 | ((PRIVKEY_REGTEST,), 32, (1,), (True, 'regtest', True, None), (), ())
|
65 | 71 | ]
|
66 | 72 | # templates for valid bech32 sequences
|
67 | 73 | bech32_templates = [
|
68 |
| - # hrp, version, witprog_size, metadata, output_prefix |
69 |
| - ('bc', 0, 20, (False, 'main', None, True), p2wpkh_prefix), |
70 |
| - ('bc', 0, 32, (False, 'main', None, True), p2wsh_prefix), |
71 |
| - ('bc', 1, 2, (False, 'main', None, True), (OP_1, 2)), |
72 |
| - ('tb', 0, 20, (False, 'test', None, True), p2wpkh_prefix), |
73 |
| - ('tb', 0, 32, (False, 'test', None, True), p2wsh_prefix), |
74 |
| - ('tb', 2, 16, (False, 'test', None, True), (OP_2, 16)), |
75 |
| - ('bcrt', 0, 20, (False, 'regtest', None, True), p2wpkh_prefix), |
76 |
| - ('bcrt', 0, 32, (False, 'regtest', None, True), p2wsh_prefix), |
77 |
| - ('bcrt', 16, 40, (False, 'regtest', None, True), (OP_16, 40)) |
| 74 | + # hrp, version, witprog_size, metadata, encoding, output_prefix |
| 75 | + ('bc', 0, 20, (False, 'main', None, True), Encoding.BECH32, p2wpkh_prefix), |
| 76 | + ('bc', 0, 32, (False, 'main', None, True), Encoding.BECH32, p2wsh_prefix), |
| 77 | + ('bc', 1, 32, (False, 'main', None, True), Encoding.BECH32M, p2tr_prefix), |
| 78 | + ('bc', 2, 2, (False, 'main', None, True), Encoding.BECH32M, (OP_2, 2)), |
| 79 | + ('tb', 0, 20, (False, 'test', None, True), Encoding.BECH32, p2wpkh_prefix), |
| 80 | + ('tb', 0, 32, (False, 'test', None, True), Encoding.BECH32, p2wsh_prefix), |
| 81 | + ('tb', 1, 32, (False, 'test', None, True), Encoding.BECH32M, p2tr_prefix), |
| 82 | + ('tb', 3, 16, (False, 'test', None, True), Encoding.BECH32M, (OP_3, 16)), |
| 83 | + ('tb', 0, 20, (False, 'signet', None, True), Encoding.BECH32, p2wpkh_prefix), |
| 84 | + ('tb', 0, 32, (False, 'signet', None, True), Encoding.BECH32, p2wsh_prefix), |
| 85 | + ('tb', 1, 32, (False, 'signet', None, True), Encoding.BECH32M, p2tr_prefix), |
| 86 | + ('tb', 3, 32, (False, 'signet', None, True), Encoding.BECH32M, (OP_3, 32)), |
| 87 | + ('bcrt', 0, 20, (False, 'regtest', None, True), Encoding.BECH32, p2wpkh_prefix), |
| 88 | + ('bcrt', 0, 32, (False, 'regtest', None, True), Encoding.BECH32, p2wsh_prefix), |
| 89 | + ('bcrt', 1, 32, (False, 'regtest', None, True), Encoding.BECH32M, p2tr_prefix), |
| 90 | + ('bcrt', 16, 40, (False, 'regtest', None, True), Encoding.BECH32M, (OP_16, 40)) |
78 | 91 | ]
|
79 | 92 | # templates for invalid bech32 sequences
|
80 | 93 | bech32_ng_templates = [
|
81 |
| - # hrp, version, witprog_size, invalid_bech32, invalid_checksum, invalid_char |
82 |
| - ('tc', 0, 20, False, False, False), |
83 |
| - ('tb', 17, 32, False, False, False), |
84 |
| - ('bcrt', 3, 1, False, False, False), |
85 |
| - ('bc', 15, 41, False, False, False), |
86 |
| - ('tb', 0, 16, False, False, False), |
87 |
| - ('bcrt', 0, 32, True, False, False), |
88 |
| - ('bc', 0, 16, True, False, False), |
89 |
| - ('tb', 0, 32, False, True, False), |
90 |
| - ('bcrt', 0, 20, False, False, True) |
| 94 | + # hrp, version, witprog_size, encoding, invalid_bech32, invalid_checksum, invalid_char |
| 95 | + ('tc', 0, 20, Encoding.BECH32, False, False, False), |
| 96 | + ('bt', 1, 32, Encoding.BECH32M, False, False, False), |
| 97 | + ('tb', 17, 32, Encoding.BECH32M, False, False, False), |
| 98 | + ('bcrt', 3, 1, Encoding.BECH32M, False, False, False), |
| 99 | + ('bc', 15, 41, Encoding.BECH32M, False, False, False), |
| 100 | + ('tb', 0, 16, Encoding.BECH32, False, False, False), |
| 101 | + ('bcrt', 0, 32, Encoding.BECH32, True, False, False), |
| 102 | + ('bc', 0, 16, Encoding.BECH32, True, False, False), |
| 103 | + ('tb', 0, 32, Encoding.BECH32, False, True, False), |
| 104 | + ('bcrt', 0, 20, Encoding.BECH32, False, False, True), |
| 105 | + ('bc', 0, 20, Encoding.BECH32M, False, False, False), |
| 106 | + ('tb', 0, 32, Encoding.BECH32M, False, False, False), |
| 107 | + ('bcrt', 0, 20, Encoding.BECH32M, False, False, False), |
| 108 | + ('bc', 1, 32, Encoding.BECH32, False, False, False), |
| 109 | + ('tb', 2, 16, Encoding.BECH32, False, False, False), |
| 110 | + ('bcrt', 16, 20, Encoding.BECH32, False, False, False), |
91 | 111 | ]
|
92 | 112 |
|
93 | 113 | def is_valid(v):
|
@@ -127,8 +147,9 @@ def gen_valid_bech32_vector(template):
|
127 | 147 | hrp = template[0]
|
128 | 148 | witver = template[1]
|
129 | 149 | witprog = bytearray(os.urandom(template[2]))
|
130 |
| - dst_prefix = bytearray(template[4]) |
131 |
| - rv = bech32_encode(hrp, [witver] + convertbits(witprog, 8, 5)) |
| 150 | + encoding = template[4] |
| 151 | + dst_prefix = bytearray(template[5]) |
| 152 | + rv = bech32_encode(hrp, [witver] + convertbits(witprog, 8, 5), encoding) |
132 | 153 | return rv, dst_prefix + witprog
|
133 | 154 |
|
134 | 155 | def gen_valid_vectors():
|
@@ -186,22 +207,23 @@ def gen_invalid_bech32_vector(template):
|
186 | 207 | hrp = template[0]
|
187 | 208 | witver = template[1]
|
188 | 209 | witprog = bytearray(os.urandom(template[2]))
|
| 210 | + encoding = template[3] |
189 | 211 |
|
190 | 212 | if no_data:
|
191 |
| - rv = bech32_encode(hrp, []) |
| 213 | + rv = bech32_encode(hrp, [], encoding) |
192 | 214 | else:
|
193 | 215 | data = [witver] + convertbits(witprog, 8, 5)
|
194 |
| - if template[3] and not no_data: |
| 216 | + if template[4] and not no_data: |
195 | 217 | if template[2] % 5 in {2, 4}:
|
196 | 218 | data[-1] |= 1
|
197 | 219 | else:
|
198 | 220 | data.append(0)
|
199 |
| - rv = bech32_encode(hrp, data) |
| 221 | + rv = bech32_encode(hrp, data, encoding) |
200 | 222 |
|
201 |
| - if template[4]: |
| 223 | + if template[5]: |
202 | 224 | i = len(rv) - random.randrange(1, 7)
|
203 | 225 | rv = rv[:i] + random.choice(CHARSET.replace(rv[i], '')) + rv[i + 1:]
|
204 |
| - if template[5]: |
| 226 | + if template[6]: |
205 | 227 | i = len(hrp) + 1 + random.randrange(0, len(rv) - len(hrp) - 4)
|
206 | 228 | rv = rv[:i] + rv[i:i + 4].upper() + rv[i + 4:]
|
207 | 229 |
|
|
0 commit comments