Use Bech32m encoding for v1+ segwit addresses · ElementsProject/elements@b3df66f
@@ -15,7 +15,7 @@
1515from itertools import islice
1616from base58 import b58encode_chk, b58decode_chk, b58chars
1717import 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
19192020# key types
2121PUBKEY_ADDRESS = 0
@@ -32,6 +32,7 @@
3232OP_0 = 0x00
3333OP_1 = 0x51
3434OP_2 = 0x52
35+OP_3 = 0x53
3536OP_16 = 0x60
3637OP_DUP = 0x76
3738OP_EQUAL = 0x87
@@ -44,6 +45,7 @@
4445script_suffix = (OP_EQUAL,)
4546p2wpkh_prefix = (OP_0, 20)
4647p2wsh_prefix = (OP_0, 32)
48+p2tr_prefix = (OP_1, 32)
47494850metadata_keys = ['isPrivkey', 'chain', 'isCompressed', 'tryCaseFlip']
4951# templates for valid sequences
@@ -65,29 +67,39 @@
6567]
6668# templates for valid bech32 sequences
6769bech32_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))
70+# hrp, version, witprog_size, metadata, encoding, output_prefix
71+ ('bc', 0, 20, (False, 'main', None, True), Encoding.BECH32, p2wpkh_prefix),
72+ ('bc', 0, 32, (False, 'main', None, True), Encoding.BECH32, p2wsh_prefix),
73+ ('bc', 1, 32, (False, 'main', None, True), Encoding.BECH32M, p2tr_prefix),
74+ ('bc', 2, 2, (False, 'main', None, True), Encoding.BECH32M, (OP_2, 2)),
75+ ('tb', 0, 20, (False, 'test', None, True), Encoding.BECH32, p2wpkh_prefix),
76+ ('tb', 0, 32, (False, 'test', None, True), Encoding.BECH32, p2wsh_prefix),
77+ ('tb', 1, 32, (False, 'test', None, True), Encoding.BECH32M, p2tr_prefix),
78+ ('tb', 3, 16, (False, 'test', None, True), Encoding.BECH32M, (OP_3, 16)),
79+ ('bcrt', 0, 20, (False, 'regtest', None, True), Encoding.BECH32, p2wpkh_prefix),
80+ ('bcrt', 0, 32, (False, 'regtest', None, True), Encoding.BECH32, p2wsh_prefix),
81+ ('bcrt', 1, 32, (False, 'regtest', None, True), Encoding.BECH32M, p2tr_prefix),
82+ ('bcrt', 16, 40, (False, 'regtest', None, True), Encoding.BECH32M, (OP_16, 40))
7883]
7984# templates for invalid bech32 sequences
8085bech32_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)
86+# hrp, version, witprog_size, encoding, invalid_bech32, invalid_checksum, invalid_char
87+ ('tc', 0, 20, Encoding.BECH32, False, False, False),
88+ ('bt', 1, 32, Encoding.BECH32M, False, False, False),
89+ ('tb', 17, 32, Encoding.BECH32M, False, False, False),
90+ ('bcrt', 3, 1, Encoding.BECH32M, False, False, False),
91+ ('bc', 15, 41, Encoding.BECH32M, False, False, False),
92+ ('tb', 0, 16, Encoding.BECH32, False, False, False),
93+ ('bcrt', 0, 32, Encoding.BECH32, True, False, False),
94+ ('bc', 0, 16, Encoding.BECH32, True, False, False),
95+ ('tb', 0, 32, Encoding.BECH32, False, True, False),
96+ ('bcrt', 0, 20, Encoding.BECH32, False, False, True),
97+ ('bc', 0, 20, Encoding.BECH32M, False, False, False),
98+ ('tb', 0, 32, Encoding.BECH32M, False, False, False),
99+ ('bcrt', 0, 20, Encoding.BECH32M, False, False, False),
100+ ('bc', 1, 32, Encoding.BECH32, False, False, False),
101+ ('tb', 2, 16, Encoding.BECH32, False, False, False),
102+ ('bcrt', 16, 20, Encoding.BECH32, False, False, False),
91103]
9210493105def is_valid(v):
@@ -127,8 +139,9 @@ def gen_valid_bech32_vector(template):
127139hrp = template[0]
128140witver = template[1]
129141witprog = bytearray(os.urandom(template[2]))
130-dst_prefix = bytearray(template[4])
131-rv = bech32_encode(hrp, [witver] + convertbits(witprog, 8, 5))
142+encoding = template[4]
143+dst_prefix = bytearray(template[5])
144+rv = bech32_encode(hrp, [witver] + convertbits(witprog, 8, 5), encoding)
132145return rv, dst_prefix + witprog
133146134147def gen_valid_vectors():
@@ -186,22 +199,23 @@ def gen_invalid_bech32_vector(template):
186199hrp = template[0]
187200witver = template[1]
188201witprog = bytearray(os.urandom(template[2]))
202+encoding = template[3]
189203190204if no_data:
191-rv = bech32_encode(hrp, [])
205+rv = bech32_encode(hrp, [], encoding)
192206else:
193207data = [witver] + convertbits(witprog, 8, 5)
194-if template[3] and not no_data:
208+if template[4] and not no_data:
195209if template[2] % 5 in {2, 4}:
196210data[-1] |= 1
197211else:
198212data.append(0)
199-rv = bech32_encode(hrp, data)
213+rv = bech32_encode(hrp, data, encoding)
200214201-if template[4]:
215+if template[5]:
202216i = len(rv) - random.randrange(1, 7)
203217rv = rv[:i] + random.choice(CHARSET.replace(rv[i], '')) + rv[i + 1:]
204-if template[5]:
218+if template[6]:
205219i = len(hrp) + 1 + random.randrange(0, len(rv) - len(hrp) - 4)
206220rv = rv[:i] + rv[i:i + 4].upper() + rv[i + 4:]
207221