def test_hash_from_bech32() -> None:
    network = "testnet"
    wv = 0
    wp = 20 * b"\x05"
    addr = b32address_from_witness(wv, wp, network)
    _, wp2, n_2, _ = witness_from_b32address(addr)
    assert n_2 == network
    assert wp2 == wp

    # witness program length (21) is not 20 or 32
    addr = b"tb1qq5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5mpvsef"
    err_msg = "invalid witness program length for witness v0: "
    with pytest.raises(BTClibValueError, match=err_msg):
        witness_from_b32address(addr)
Example #2
0
    def test_p2wpkh(self):

        # https://github.com/bitcoin/bips/blob/master/bip-0173.mediawiki
        # leading/trailing spaces should be tolerated
        pub = " 0279BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2" "815B16F81798"
        addr = b"bc1qw508d6qejxtdg4y5r3zarvary0c5xw7kv8f3t4"
        self.assertEqual(addr, p2wpkh(pub))
        addr = b"tb1qw508d6qejxtdg4y5r3zarvary0c5xw7kxpjzsx"
        self.assertEqual(addr, p2wpkh(pub, "testnet"))

        # http://bitcoinscri.pt/pages/segwit_native_p2wpkh
        pub = "02 530c548d402670b13ad8887ff99c294e67fc18097d236d57880c69" "261b42def7"
        addr = b"bc1qg9stkxrszkdqsuj92lm4c7akvk36zvhqw7p6ck"
        self.assertEqual(addr, p2wpkh(pub))

        _, wp, _, _ = witness_from_b32address(addr)
        self.assertEqual(bytes(wp), hash160(pub))

        # Wrong size (65-bytes) for compressed SEC key
        uncompr_pub = bytes_from_point(point_from_octets(pub),
                                       compressed=False)
        self.assertRaises(ValueError, p2wpkh, uncompr_pub)
        # p2wpkh(uncompr_pub)

        # Wrong pubkey size: 34 instead of 33
        self.assertRaises(ValueError, p2wpkh, pub + "00")
        # p2wpkh(pub + '00')

        # Witness program length (21) is not 20
        self.assertRaises(ValueError, b32address_from_witness, 0,
                          hash160(pub) + b"\x00")
def test_p2wpkh() -> None:

    # https://github.com/bitcoin/bips/blob/master/bip-0173.mediawiki
    # leading/trailing spaces should be tolerated
    pub = " 02 79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798"
    addr = b"bc1qw508d6qejxtdg4y5r3zarvary0c5xw7kv8f3t4"
    assert addr == p2wpkh(pub)
    addr = b"tb1qw508d6qejxtdg4y5r3zarvary0c5xw7kxpjzsx"
    assert addr == p2wpkh(pub, "testnet")

    # http://bitcoinscri.pt/pages/segwit_native_p2wpkh
    pub = "02 530c548d402670b13ad8887ff99c294e67fc18097d236d57880c69261b42def7"
    addr = b"bc1qg9stkxrszkdqsuj92lm4c7akvk36zvhqw7p6ck"
    assert addr == p2wpkh(pub)

    _, wp, _, _ = witness_from_b32address(addr)
    assert bytes(wp) == hash160(pub)

    uncompr_pub = bytes_from_point(point_from_octets(pub), compressed=False)
    err_msg = "not a private or compressed public key: "
    with pytest.raises(BTClibValueError, match=err_msg):
        p2wpkh(uncompr_pub)
    with pytest.raises(BTClibValueError, match=err_msg):
        p2wpkh(pub + "00")

    err_msg = "invalid witness program length for witness v0: "
    with pytest.raises(BTClibValueError, match=err_msg):
        b32address_from_witness(0, hash160(pub) + b"\x00")
Example #4
0
def test_b32address_from_witness() -> None:

    # self-consistency
    addr = b"bc1qg9stkxrszkdqsuj92lm4c7akvk36zvhqw7p6ck"
    wv, wp, network, _ = witness_from_b32address(addr)
    assert b32address_from_witness(wv, wp, network) == addr

    # string input
    addr_str = "bc1qg9stkxrszkdqsuj92lm4c7akvk36zvhqw7p6ck"
    wv, wp, network, _ = witness_from_b32address(addr_str)
    assert b32address_from_witness(wv, wp, network) == addr_str.encode()

    wp_ints = [i for i in wp]
    wp_ints[0] = -1
    with pytest.raises(ValueError, match="invalid value in _convertbits: "):
        _convertbits(wp_ints, 8, 5)
Example #5
0
    def test_b32address_from_witness(self):

        # self-consistency
        addr = b'bc1qg9stkxrszkdqsuj92lm4c7akvk36zvhqw7p6ck'
        wv, wp, network, _ = witness_from_b32address(addr)
        self.assertEqual(b32address_from_witness(wv, wp, network), addr)

        # invalid value -1
        wp = [i for i in wp]  # convert to List[int]
        wp[-1] = -1  # alter the last element with an invalid value
        self.assertRaises(ValueError, b32address_from_witness, wv, wp, network)
        #b32address_from_witness(wv, wp, network)

        # string input
        addr = 'bc1qg9stkxrszkdqsuj92lm4c7akvk36zvhqw7p6ck'
        wv, wp, network, _ = witness_from_b32address(addr)
        self.assertEqual(b32address_from_witness(wv, wp, network), addr.encode())
Example #6
0
def test_invalid_address() -> None:
    """Test whether invalid addresses fail to decode"""

    INVALID_ADDRESS: List[Tuple[str, str]] = [
        (
            "tc1qw508d6qejxtdg4y5r3zarvary0c5xw7kg3g4ty",
            "invalid value for network keyword 'p2w': ",
        ),
        (
            "bc1qw508d6qejxtdg4y5r3zarvary0c5xw7kv8f3t5",
            "invalid checksum in bech32 string: ",
        ),
        ("BC13W508D6QEJXTDG4Y5R3ZARVARY0C5XW7KN40WF2",
         "invalid witness version: "),
        ("bc1rw5uspcuh",
         "invalid witness program length for witness version zero: "),
        (
            "bc10w508d6qejxtdg4y5r3zarvary0c5xw7kw508d6qejxtdg4y5r3zarvary0c5xw7kw5rljs90",
            "invalid witness program length for witness version zero: ",
        ),
        (
            "BC1QR508D6QEJXTDG4Y5R3ZARVARYV98GJ9P",
            "invalid witness program length for witness version zero: ",
        ),
        (
            "tb1qrp33g0q5c5txsp9arysrx4k6zdkfs4nce4xj0gdcccefvpysxf3q0sL5k7",
            "mixed case in bech32 string: ",
        ),
        (
            "bc1zw508d6qejxtdg4y5r3zarvaryvqyzf3du",
            "zero padding of more than 4 bits in 8-to-5 conversion",
        ),
        (
            "tb1qrp33g0q5c5txsp9arysrx4k6zdkfs4nce4xj0gdcccefvpysxf3pjxtptv",
            "non-zero padding in 8-to-5 conversion",
        ),
        ("bc1gmk9yu", "empty data in bech32 address: "),
        (
            "bc1qqvpsxqcrqvpsxqcrqvpsxqcrqvpsxqcrqvpsxqcrqvpsxqcrqvpsxqcrqvpsxqcrqvpsxqcrqvpsxqcrqv0jstn5",
            "invalid bech32 address length: ",
        ),
    ]

    for a, err_msg in INVALID_ADDRESS:
        with pytest.raises(ValueError, match=err_msg):
            witness_from_b32address(a)
Example #7
0
 def test_valid_address(self):
     """Test whether valid addresses decode to the correct output"""
     for a, hexscript in VALID_BC_ADDRESS + VALID_TB_ADDRESS:
         self.assertTrue(has_segwit_prefix(a))
         witvers, witprog, network, _ = witness_from_b32address(a)
         script_pubkey = [witvers, witprog]
         self.assertEqual(encode(script_pubkey).hex(), hexscript)
         address = b32address_from_witness(witvers, witprog, network)
         self.assertEqual(a.lower().strip(), address.decode('ascii'))
Example #8
0
    def test_hash_from_bech32(self):
        network = "testnet"
        wv = 0
        wp = 20 * b"\x05"
        addr = b32address_from_witness(wv, wp, network)
        _, wp2, n2, _ = witness_from_b32address(addr)
        self.assertEqual(n2, network)
        self.assertEqual(wp2, wp)

        # witness program length (21) is not 20 or 32
        addr = "tb1qq5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5mpvsef"
        self.assertRaises(ValueError, witness_from_b32address, addr)
Example #9
0
    def test_p2wsh_address(self):

        # https://github.com/bitcoin/bips/blob/master/bip-0173.mediawiki
        pub = "02 79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798"
        witness_script = [pub, 'OP_CHECKSIG']
        witness_script_bytes = encode(witness_script)

        addr = b'tb1qrp33g0q5c5txsp9arysrx4k6zdkfs4nce4xj0gdcccefvpysxf3q0sl5k7'
        self.assertEqual(addr, p2wsh_address(witness_script_bytes, 'testnet'))
        _, wp, _, _ = witness_from_b32address(addr)
        self.assertEqual(bytes(wp), sha256(witness_script_bytes))

        addr = b'bc1qrp33g0q5c5txsp9arysrx4k6zdkfs4nce4xj0gdcccefvpysxf3qccfmv3'
        self.assertEqual(addr, p2wsh_address(witness_script_bytes))
        _, wp, _, _ = witness_from_b32address(addr)
        self.assertEqual(bytes(wp), sha256(witness_script_bytes))

        self.assertEqual(witness_from_b32address(addr)[1], sha256(witness_script_bytes))

        # witness program length (35) is not 32
        self.assertRaises(ValueError, b32address_from_witness, 0, witness_script_bytes[1:])
Example #10
0
def test_address_from_wif() -> None:

    q = 0x19E14A7B6A307F426A94F8114701E7C8E774E7F9A47E2C2035DB29A206321725

    test_cases: List[Tuple[bool, str, str, str]] = [
        (
            False,
            "mainnet",
            "5J1geo9kcAUSM6GJJmhYRX1eZEjvos9nFyWwPstVziTVueRJYvW",
            "1LPM8SZ4RQDMZymUmVSiSSvrDfj1UZY9ig",
        ),
        (
            True,
            "mainnet",
            "Kx621phdUCp6sgEXPSHwhDTrmHeUVrMkm6T95ycJyjyxbDXkr162",
            "1HJC7kFvXHepkSzdc8RX6khQKkAyntdfkB",
        ),
        (
            False,
            "testnet",
            "91nKEXyJCPYaK9maw7bTJ7ZcCu6dy2gybvNtUWF1LTCYggzhZgy",
            "mzuJRVe3ERecM6F6V4R6GN9B5fKiPC9HxF",
        ),
        (
            True,
            "testnet",
            "cNT1UjhUuGWN37hnmr754XxvPWwtAJTSq8bcCQ4pUrdxqxbA1iU1",
            "mwp9QoLuLK65XZUFKhPtvfujBjmgkZnmPx",
        ),
    ]
    for compressed, network, wif, address in test_cases:
        assert wif.encode() == wif_from_prvkey(q, network, compressed)
        assert prvkeyinfo_from_prvkey(wif) == (q, network, compressed)
        b58 = p2pkh(wif)
        assert b58 == address.encode()
        _, payload, net, is_script = h160_from_b58address(b58)
        assert net == network
        assert not is_script
        if compressed:
            b32 = p2wpkh(wif)
            assert (payload, network,
                    is_script) == witness_from_b32address(b32)[1:]
            b = p2wpkh_p2sh(wif)
            _, payload2, net, is_script = h160_from_b58address(b)
            assert is_script
            assert (hash160(b"\x00\x14" + payload), network) == (payload2, net)
        else:
            err_msg = "not a private or compressed public key: "
            with pytest.raises(ValueError, match=err_msg):
                p2wpkh(wif)  # type: ignore
            with pytest.raises(ValueError, match=err_msg):
                p2wpkh_p2sh(wif)  # type: ignore
Example #11
0
def test_p2wsh():

    # https://github.com/bitcoin/bips/blob/master/bip-0173.mediawiki
    pub = "02 79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D" "959F2815B16F81798"
    witness_script = [pub, "OP_CHECKSIG"]
    witness_script_bytes = encode(witness_script)

    addr = b"tb1qrp33g0q5c5txsp9arysrx4k6zdkfs4nce4xj0gdcccefvpysxf3q0sl5k7"
    assert addr == p2wsh(witness_script_bytes, "testnet")
    _, wp, _, _ = witness_from_b32address(addr)
    assert bytes(wp) == sha256(witness_script_bytes)

    addr = b"bc1qrp33g0q5c5txsp9arysrx4k6zdkfs4nce4xj0gdcccefvpysxf3qccfmv3"
    assert addr == p2wsh(witness_script_bytes)
    _, wp, _, _ = witness_from_b32address(addr)
    assert bytes(wp) == sha256(witness_script_bytes)

    assert witness_from_b32address(addr)[1] == sha256(witness_script_bytes)

    errMsg = r"witness program length \(35\) is not 20 or 32"
    with pytest.raises(ValueError, match=errMsg):
        b32address_from_witness(0, witness_script_bytes)
def test_p2wsh() -> None:

    # https://github.com/bitcoin/bips/blob/master/bip-0173.mediawiki
    pub = "02 79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798"
    script_pubkey: List[ScriptToken] = [pub, "OP_CHECKSIG"]
    witness_script_bytes = script.serialize(script_pubkey)

    addr = b"tb1qrp33g0q5c5txsp9arysrx4k6zdkfs4nce4xj0gdcccefvpysxf3q0sl5k7"
    assert addr == p2wsh(witness_script_bytes, "testnet")
    _, wp, _, _ = witness_from_b32address(addr)
    assert bytes(wp) == sha256(witness_script_bytes)

    addr = b"bc1qrp33g0q5c5txsp9arysrx4k6zdkfs4nce4xj0gdcccefvpysxf3qccfmv3"
    assert addr == p2wsh(witness_script_bytes)
    _, wp, _, _ = witness_from_b32address(addr)
    assert bytes(wp) == sha256(witness_script_bytes)

    assert witness_from_b32address(addr)[1] == sha256(witness_script_bytes)

    err_msg = "invalid witness program length for witness v0: "
    with pytest.raises(BTClibValueError, match=err_msg):
        b32address_from_witness(0, witness_script_bytes)
Example #13
0
    def test_valid_address(self):
        """Test whether valid addresses decode to the correct output"""

        VALID_BC_ADDRESS = [
            [
                "BC1QW508D6QEJXTDG4Y5R3ZARVARY0C5XW7KV8F3T4",
                "0014751e76e8199196d454941c45d1b3a323f1433bd6",
            ],
            [
                ("bc1pw508d6qejxtdg4y5r3zarvary0c5xw7kw508d6qejxtdg4y5r3zarva"
                 "ry0c5xw7k7grplx"),
                ("5128751e76e8199196d454941c45d1b3a323f1433bd6751e76e8199196d"
                 "454941c45d1b3a323f1433bd6"),
            ],
            ["BC1SW50QA3JX3S", "6002751e"],
            [
                "bc1zw508d6qejxtdg4y5r3zarvaryvg6kdaj",
                "5210751e76e8199196d454941c45d1b3a323",
            ],
            [
                " bc1zw508d6qejxtdg4y5r3zarvaryvg6kdaj",  # extra leading space
                "5210751e76e8199196d454941c45d1b3a323",
            ],
        ]
        VALID_TB_ADDRESS = [
            [
                ("tb1qrp33g0q5c5txsp9arysrx4k6zdkfs4nce4xj0gdcccefvpysxf3q0s"
                 "l5k7"),
                ("00201863143c14c5166804bd19203356da136c985678cd4d27a1b8c6329"
                 "604903262"),
            ],
            [
                ("tb1qqqqqp399et2xygdj5xreqhjjvcmzhxw4aywxecjdzew6hylgvsesrx"
                 "h6hy"),
                ("0020000000c4a5cad46221b2a187905e5266362b99d5e91c6ce24d165da"
                 "b93e86433"),
            ],
        ]

        for a, hexscript in VALID_BC_ADDRESS + VALID_TB_ADDRESS:
            witvers, witprog, network, _ = witness_from_b32address(a)
            script_pubkey = [witvers, witprog]
            self.assertEqual(encode(script_pubkey).hex(), hexscript)
            address = b32address_from_witness(witvers, witprog, network)
            self.assertEqual(a.lower().strip(), address.decode("ascii"))
def test_valid_address() -> None:
    """Test whether valid addresses decode to the correct output"""

    valid_bc_addresses: List[Tuple[str, str]] = [
        (
            "BC1QW508D6QEJXTDG4Y5R3ZARVARY0C5XW7KV8F3T4",
            "0014751e76e8199196d454941c45d1b3a323f1433bd6",
        ),
        (
            "bc1pw508d6qejxtdg4y5r3zarvary0c5xw7kw508d6qejxtdg4y5r3zarvary0c5xw7k7grplx",
            "5128751e76e8199196d454941c45d1b3a323f1433bd6751e76e8199196d454941c45d1b3a323f1433bd6",
        ),
        ("BC1SW50QA3JX3S", "6002751e"),
        (
            "bc1zw508d6qejxtdg4y5r3zarvaryvg6kdaj",
            "5210751e76e8199196d454941c45d1b3a323",
        ),
        (
            " bc1zw508d6qejxtdg4y5r3zarvaryvg6kdaj",  # extra leading space
            "5210751e76e8199196d454941c45d1b3a323",
        ),
    ]
    valid_tb_addresses: List[Tuple[str, str]] = [
        (
            "tb1qrp33g0q5c5txsp9arysrx4k6zdkfs4nce4xj0gdcccefvpysxf3q0sl5k7",
            "00201863143c14c5166804bd19203356da136c985678cd4d27a1b8c6329604903262",
        ),
        (
            "tb1qqqqqp399et2xygdj5xreqhjjvcmzhxw4aywxecjdzew6hylgvsesrxh6hy",
            "0020000000c4a5cad46221b2a187905e5266362b99d5e91c6ce24d165dab93e86433",
        ),
    ]

    for address, hexscript in valid_bc_addresses + valid_tb_addresses:
        witvers, witprog, network, _ = witness_from_b32address(address)
        script_pubkey: List[ScriptToken] = [witvers, witprog]
        assert script.serialize(script_pubkey).hex() == hexscript
        addr = b32address_from_witness(witvers, witprog, network)
        assert address.lower().strip() == addr.decode("ascii")
Example #15
0
    def test_address_from_wif(self):
        # uncompressed mainnet
        wif1 = "5J1geo9kcAUSM6GJJmhYRX1eZEjvos9nFyWwPstVziTVueRJYvW"
        pubkey, network = pubkey_info_from_prvkey(wif1)
        b58 = p2pkh(pubkey)
        self.assertEqual(b58, b'1LPM8SZ4RQDMZymUmVSiSSvrDfj1UZY9ig')
        self.assertRaises(ValueError, p2wpkh, pubkey)
        self.assertRaises(ValueError, p2wpkh_p2sh, pubkey)

        # compressed mainnet
        wif2 = "Kx621phdUCp6sgEXPSHwhDTrmHeUVrMkm6T95ycJyjyxbDXkr162"
        pubkey, network = pubkey_info_from_prvkey(wif2)
        b58 = p2pkh(pubkey)
        self.assertEqual(b58, b'1HJC7kFvXHepkSzdc8RX6khQKkAyntdfkB')
        b32 = p2wpkh(pubkey)
        self.assertEqual(h160_from_b58address(
            b58)[1:], witness_from_b32address(b32)[1:])
        h160 = h160_from_b58address(b58)[1]
        b = p2wpkh_p2sh(pubkey)
        self.assertEqual(hash160(b'\x00\x14' + h160),
                         h160_from_b58address(b)[1])

        self.assertEqual(prvkey_info_from_prvkey(
            wif1)[0], prvkey_info_from_prvkey(wif2)[0])

        # uncompressed testnet
        wif1 = "91gGn1HgSap6CbU12F6z3pJri26xzp7Ay1VW6NHCoEayNXwRpu2"
        pubkey, network = pubkey_info_from_prvkey(wif1)
        b58 = p2pkh(pubkey, network, None)
        self.assertEqual(b58, b'mvgbzkCSgKbYgaeG38auUzR7otscEGi8U7')
        self.assertRaises(ValueError, p2wpkh, pubkey)
        self.assertRaises(ValueError, p2wpkh_p2sh, pubkey)

        # compressed testnet
        wif2 = "cMzLdeGd5vEqxB8B6VFQoRopQ3sLAAvEzDAoQgvX54xwofSWj1fx"
        pubkey, network = pubkey_info_from_prvkey(wif2)
        b58 = p2pkh(pubkey, network, None)
        self.assertEqual(b58, b'n1KSZGmQgB8iSZqv6UVhGkCGUbEdw8Lm3Q')
        b32 = p2wpkh(pubkey, network)
        self.assertEqual(h160_from_b58address(
            b58)[1:], witness_from_b32address(b32)[1:])
        h160 = h160_from_b58address(b58)[1]
        b = p2wpkh_p2sh(pubkey, network)
        self.assertEqual(hash160(b'\x00\x14' + h160),
                         h160_from_b58address(b)[1])

        self.assertEqual(prvkey_info_from_prvkey(
            wif1)[0], prvkey_info_from_prvkey(wif2)[0])

        # uncompressed mainnet, trailing/leading spaces in string
        wif1 = "  5J1geo9kcAUSM6GJJmhYRX1eZEjvos9nFyWwPstVziTVueRJYvW"
        pubkey, network = pubkey_info_from_prvkey(wif1)
        b58 = p2pkh(pubkey)
        self.assertEqual(b58, b'1LPM8SZ4RQDMZymUmVSiSSvrDfj1UZY9ig')
        self.assertRaises(ValueError, p2wpkh, pubkey)
        self.assertRaises(ValueError, p2wpkh_p2sh, pubkey)

        # compressed mainnet, trailing/leading spaces in string
        wif2 = "Kx621phdUCp6sgEXPSHwhDTrmHeUVrMkm6T95ycJyjyxbDXkr162  "
        pubkey, network = pubkey_info_from_prvkey(wif2)
        b58 = p2pkh(pubkey)
        self.assertEqual(b58, b'1HJC7kFvXHepkSzdc8RX6khQKkAyntdfkB')
        b32 = p2wpkh(pubkey)
        self.assertEqual(h160_from_b58address(
            b58)[1:], witness_from_b32address(b32)[1:])
        h160 = h160_from_b58address(b58)[1]
        b = p2wpkh_p2sh(pubkey)
        self.assertEqual(hash160(b'\x00\x14' + h160),
                         h160_from_b58address(b)[1])