segwit_addr: bech32 decode without checksum option

This commit is contained in:
Sander van Grieken
2024-05-28 12:00:58 +02:00
committed by f321x
parent 09a09057f6
commit 65fb739584
2 changed files with 18 additions and 6 deletions
+11 -6
View File
@@ -43,6 +43,9 @@ class DecodedBech32(NamedTuple):
data: Optional[Sequence[int]] # 5-bit ints
INVALID_BECH32 = DecodedBech32(None, None, None)
def bech32_polymod(values):
"""Internal function that computes the Bech32 checksum."""
generator = [0x3b6a57b2, 0x26508e6d, 0x1ea119fa, 0x3d4233dd, 0x2a1462b3]
@@ -85,26 +88,28 @@ def bech32_encode(encoding: Encoding, hrp: str, data: List[int]) -> str:
return hrp + '1' + ''.join([CHARSET[d] for d in combined])
def bech32_decode(bech: str, *, ignore_long_length=False) -> DecodedBech32:
def bech32_decode(bech: str, *, ignore_long_length=False, with_checksum=True) -> DecodedBech32:
"""Validate a Bech32/Bech32m string, and determine HRP and data."""
bech_lower = bech.lower()
if bech_lower != bech and bech.upper() != bech:
return DecodedBech32(None, None, None)
return INVALID_BECH32
pos = bech.rfind('1')
if pos < 1 or pos + 7 > len(bech) or (not ignore_long_length and len(bech) > 90):
return DecodedBech32(None, None, None)
return INVALID_BECH32
# check that HRP only consists of sane ASCII chars
if any(ord(x) < 33 or ord(x) > 126 for x in bech[:pos+1]):
return DecodedBech32(None, None, None)
return INVALID_BECH32
bech = bech_lower
hrp = bech[:pos]
try:
data = [CHARSET_INVERSE[x] for x in bech[pos + 1:]]
except KeyError:
return DecodedBech32(None, None, None)
return INVALID_BECH32
if not with_checksum:
return DecodedBech32(encoding=None, hrp=hrp, data=data)
encoding = bech32_verify_checksum(hrp, data)
if encoding is None:
return DecodedBech32(None, None, None)
return INVALID_BECH32
return DecodedBech32(encoding=encoding, hrp=hrp, data=data[:-6])
+7
View File
@@ -660,6 +660,13 @@ class Test_bitcoin(ElectrumTestCase):
self.assertEqual(DecodedBech32(None, None, None),
segwit_addr.bech32_decode('1p2gdwpf'))
# without checksum
bolt12_str = 'lno1pqps7sjqpgtyzm3qv4uxzmtsd3jjqer9wd3hy6tsw35k7msjzfpy7nz5yqcnygrfdej82um5wf5k2uckyypwa3eyt44h6txtxquqh7lz5djge4afgfjn7k4rgrkuag0jsd5xvxg'
self.assertEqual(DecodedBech32(None, None, None),
segwit_addr.bech32_decode(bolt12_str, with_checksum=True, ignore_long_length=True))
self.assertEqual(DecodedBech32(None, 'lno', [1, 0, 1, 16, 30, 16, 18, 0, 1, 8, 11, 4, 2, 27, 17, 0, 12, 21, 28, 6, 2, 27, 11, 16, 13, 17, 18, 18, 0, 25, 3, 5, 14, 13, 17, 23, 4, 26, 11, 16, 14, 17, 20, 22, 30, 27, 16, 18, 2, 9, 1, 4, 30, 19, 2, 20, 4, 0, 24, 19, 4, 8, 3, 9, 13, 25, 18, 7, 10, 28, 27, 20, 14, 9, 20, 22, 10, 28, 24, 22, 4, 4, 1, 14, 29, 17, 25, 4, 11, 21, 21, 23, 26, 11, 6, 11, 6, 0, 28, 0, 23, 30, 31, 2, 20, 13, 18, 8, 25, 21, 29, 9, 8, 9, 18, 19, 30, 22, 21, 3, 8, 3, 22, 28, 29, 8, 15, 18, 16, 13, 20, 6, 12, 6, 8]),
segwit_addr.bech32_decode(bolt12_str, with_checksum=False, ignore_long_length=True))
class Test_xprv_xpub(ElectrumTestCase):