Example #1
0
def witness_from_address(b32addr: String) -> Tuple[int, bytes, str]:
    "Return the witness from a bech32 native SegWit address."

    if isinstance(b32addr, str):
        b32addr = b32addr.strip()

    # the following check was originally in b32decode
    # but it does not pertain there
    if len(b32addr) > 90:
        raise BTClibValueError(
            f"invalid bech32 address length: {len(b32addr)} > 90")

    hrp, data = b32decode(b32addr)

    # check that it is a known SegWit address type
    network = network_from_key_value("hrp", hrp)
    if network is None:
        raise BTClibValueError(f"invalid hrp: {hrp}")

    if len(data) == 0:
        raise BTClibValueError(f"empty data in bech32 address: {b32addr!r}")

    wit_ver = data[0]
    wit_prg = bytes(power_of_2_base_conversion(data[1:], 5, 8, False))
    return wit_ver, check_witness(wit_ver, wit_prg), network
Example #2
0
def test_bech32_insertion_issue() -> None:
    """Test documented bech32 insertion issue.

    https://github.com/sipa/bech32/issues/51
    https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2019-November/017443.html
    https://gist.github.com/sipa/a9845b37c1b298a7301c33a04090b2eb
    https://gist.github.com/sipa/a9845b37c1b298a7301c33a04090b2eb
    https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2020-October/018236.html
    https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2020-December/018292.html
    https://gist.github.com/sipa/14c248c288c3880a3b191f978a34508e

    """
    strings = ("ii2134hk2xmat79tp", "eyg5bsz1l2mrq5ypl40hp")
    for string in strings:
        for i in range(20):
            b32decode(string[:-1] + i * "q" + string[-1:])
Example #3
0
 def test_valid_checksum(self):
     """Test validation of valid checksums."""
     for test in VALID_CHECKSUM:
         _, _ = b32decode(test)
         pos = test.rfind('1')
         test = test[:pos + 1] + chr(ord(test[pos + 1]) ^ 1) + test[pos +
                                                                    2:]
         self.assertRaises(ValueError, b32decode, test)
def test_bechs32_checksum() -> None:
    "Test bech32 checksum."

    for test in VALID_CHECKSUM:
        b32decode(test)
        b32decode(test.encode("ascii"))
        pos = test.rfind("1")
        test = test[:pos + 1] + chr(ord(test[pos + 1]) ^ 1) + test[pos + 2:]
        with pytest.raises(BTClibValueError):
            b32decode(test)

    for addr, err_msg in INVALID_CHECKSUM:
        with pytest.raises(BTClibValueError, match=err_msg):
            b32decode(addr)
Example #5
0
def test_bech32() -> None:
    "Test bech32 checksum."

    valid_checksum = [
        "A12UEL5L",
        "a12uel5l",
        "an83characterlonghumanreadablepartthatcontainsthenumber1andtheexcludedcharactersbio1tt5tgs",
        "abcdef1qpzry9x8gf2tvdw0s3jn54khce6mua7lmqqqxw",
        "11qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqc8247j",
        "split1checkupstagehandshakeupstreamerranterredcaperred2y9e3w",
        "?1ezyfcl",
        # the next one would have been invalid with the 90 char limit
        "an84characterslonghumanreadablepartthatcontainsthenumber1andtheexcludedcharactersbio1569pvx",
    ]

    for test in valid_checksum:
        b32decode(test)
        b32decode(test.encode("ascii"))
        assert b32encode(*b32decode(test)).decode() == test.lower()
        pos = test.rfind("1")
        test = test[:pos + 1] + chr(ord(test[pos + 1]) ^ 1) + test[pos + 2:]
        with pytest.raises(BTClibValueError):
            b32decode(test)

    invalid_checksum = [
        ["\x20" + " 1nwldj5", r"HRP character out of range: *"],
        ["\x7F" + "1axkwrx", r"HRP character out of range: *"],
        ["\x80" + "1eym55h", r"HRP character out of range: *"],
        ["pzry9x0s0muk", r"no separator character: *"],
        ["1pzry9x0s0muk", r"empty HRP: *"],
        ["x1b4n0q5v", r"invalid data character: *"],
        ["li1dgmt3", r"too short checksum: *"],
        # Invalid character in checksum
        ["de1lg7wt\xff", r"invalid character in checksum: *"],
        # checksum calculated with uppercase form of HRP
        ["A1G7SGD8", r"invalid checksum: *"],
        ["10a06t8", r"empty HRP: *"],
        ["1qzzfhee", r"empty HRP: *"],
    ]

    for addr, err_msg in invalid_checksum:
        with pytest.raises(BTClibValueError, match=err_msg):
            b32decode(addr)