Browse Source

bitcoin.py: base58 address: make sure all public methods test checksum

Note: the checksum was already being checked in practically all cases, by the caller.
Moved the check here, to the lower level (but still public) method for sanity.
hard-fail-on-bad-server-string
SomberNight 5 years ago
parent
commit
5f6f7da2a1
No known key found for this signature in database GPG Key ID: B33B5F232C6271E9
  1. 7
      electrum/bitcoin.py
  2. 10
      electrum/tests/test_bitcoin.py

7
electrum/bitcoin.py

@ -328,7 +328,9 @@ def hash160_to_b58_address(h160: bytes, addrtype: int) -> str:
def b58_address_to_hash160(addr: str) -> Tuple[int, bytes]: def b58_address_to_hash160(addr: str) -> Tuple[int, bytes]:
addr = to_bytes(addr, 'ascii') addr = to_bytes(addr, 'ascii')
_bytes = base_decode(addr, base=58, length=25) _bytes = DecodeBase58Check(addr)
if len(_bytes) != 21:
raise Exception(f'expected 21 payload bytes in base58 address. got: {len(_bytes)}')
return _bytes[0], _bytes[1:21] return _bytes[0], _bytes[1:21]
@ -638,12 +640,13 @@ def is_segwit_address(addr: str, *, net=None) -> bool:
def is_b58_address(addr: str, *, net=None) -> bool: def is_b58_address(addr: str, *, net=None) -> bool:
if net is None: net = constants.net if net is None: net = constants.net
try: try:
# test length, checksum, encoding:
addrtype, h = b58_address_to_hash160(addr) addrtype, h = b58_address_to_hash160(addr)
except Exception as e: except Exception as e:
return False return False
if addrtype not in [net.ADDRTYPE_P2PKH, net.ADDRTYPE_P2SH]: if addrtype not in [net.ADDRTYPE_P2PKH, net.ADDRTYPE_P2SH]:
return False return False
return addr == hash160_to_b58_address(h, addrtype) return True
def is_address(addr: str, *, net=None) -> bool: def is_address(addr: str, *, net=None) -> bool:
if net is None: net = constants.net if net is None: net = constants.net

10
electrum/tests/test_bitcoin.py

@ -711,6 +711,16 @@ class Test_keyImport(ElectrumTestCase):
self.assertFalse(is_address("not an address")) self.assertFalse(is_address("not an address"))
def test_is_address_bad_checksums(self):
self.assertTrue(is_address('1819s5TxxbBtuRPr3qYskMVC8sb1pqapWx'))
self.assertFalse(is_address('1819s5TxxbBtuRPr3qYskMVC8sb1pqapWw'))
self.assertTrue(is_address('3LrjLVnngqnaJeo3BQwMBg34iqYsjZjQUe'))
self.assertFalse(is_address('3LrjLVnngqnaJeo3BQwMBg34iqYsjZjQUd'))
self.assertTrue(is_address('bc1qxq64lrwt02hm7tu25lr3hm9tgzh58snfe67yt6'))
self.assertFalse(is_address('bc1qxq64lrwt02hm7tu25lr3hm9tgzh58snfe67yt5'))
@needs_test_with_all_ecc_implementations @needs_test_with_all_ecc_implementations
def test_is_private_key(self): def test_is_private_key(self):
for priv_details in self.priv_pub_addr: for priv_details in self.priv_pub_addr:

Loading…
Cancel
Save