Exemple #1
0
def test_wif_from_prvkey() -> None:
    prvkey = "0C28FCA386C7A227600B2FE50B7CAE11EC86D3BF1FBE471BE89827E19D72AA1D"
    test_vectors: List[Tuple[str, str, bool]] = [
        ("KwdMAjGmerYanjeui5SHS7JkmpZvVipYvB2LJGU1ZxJwYvP98617", "mainnet", True),
        ("cMzLdeGd5vEqxB8B6VFQoRopQ3sLAAvEzDAoQgvX54xwofSWj1fx", "testnet", True),
        ("5HueCGU8rMjxEXxiPuD5BDku4MkFqeZyd4dZ1jvhTVqvbTLvyTJ", "mainnet", False),
        ("91gGn1HgSap6CbU12F6z3pJri26xzp7Ay1VW6NHCoEayNXwRpu2", "testnet", False),
        (" KwdMAjGmerYanjeui5SHS7JkmpZvVipYvB2LJGU1ZxJwYvP98617", "mainnet", True),
        ("KwdMAjGmerYanjeui5SHS7JkmpZvVipYvB2LJGU1ZxJwYvP98617 ", "mainnet", True),
    ]
    for v in test_vectors:
        wif = wif_from_prvkey(prvkey, v[1], v[2])
        # FIXME clarify decode("ascii") and encode("ascii") everywhere
        assert v[0].strip() == wif.decode("ascii")
        q, network, compressed = prvkeyinfo_from_prvkey(v[0])
        assert q == int(prvkey, 16)
        assert network == v[1]
        assert compressed == v[2]

    bad_q = ec.n.to_bytes(ec.nsize, "big")
    with pytest.raises(ValueError, match="private key not in 1..n-1: "):
        wif_from_prvkey(bad_q, "mainnet", True)

    payload = b"\x80" + bad_q
    badwif = b58encode(payload)
    with pytest.raises(ValueError, match="not a private key: "):
        prvkeyinfo_from_prvkey(badwif)

    # not a private key: 33 bytes
    bad_q = 33 * b"\x02"
    with pytest.raises(ValueError, match="not a private key: "):
        wif_from_prvkey(bad_q, "mainnet", True)
    payload = b"\x80" + bad_q
    badwif = b58encode(payload)
    with pytest.raises(ValueError, match="not a private key: "):
        prvkeyinfo_from_prvkey(badwif)

    # Not a WIF: missing leading 0x80
    good_q = 32 * b"\x02"
    payload = b"\x81" + good_q
    badwif = b58encode(payload)
    with pytest.raises(ValueError, match="not a private key: "):
        prvkeyinfo_from_prvkey(badwif)

    # Not a compressed WIF: missing trailing 0x01
    payload = b"\x80" + good_q + b"\x00"
    badwif = b58encode(payload)
    with pytest.raises(ValueError, match="not a private key: "):
        prvkeyinfo_from_prvkey(badwif)

    # Not a WIF: wrong size (35)
    payload = b"\x80" + good_q + b"\x01\x00"
    badwif = b58encode(payload)
    with pytest.raises(ValueError, match="not a private key: "):
        prvkeyinfo_from_prvkey(badwif)
Exemple #2
0
def test_p2pkh_from_wif() -> None:
    seed = b"00" * 32  # better be a documented test case
    rxprv = bip32.rootxprv_from_seed(seed)
    path = "m/0h/0h/12"
    xprv = bip32.derive(rxprv, path)
    wif = wif_from_prvkey(xprv)
    assert wif == b"KyLk7s6Z1FtgYEVp3bPckPVnXvLUWNCcVL6wNt3gaT96EmzTKZwP"
    pubkey, _ = pubkeyinfo_from_prvkey(wif)
    address = p2pkh(pubkey)
    xpub = bip32.xpub_from_xprv(xprv)
    address2 = slip132.address_from_xpub(xpub)
    assert address == address2

    err_msg = "not a private key: "
    with pytest.raises(ValueError, match=err_msg):
        wif_from_prvkey(xpub)
def test_p2pkh_from_wif() -> None:
    seed = b"\x00" * 32  # better be a documented test case
    rxprv = bip32.rootxprv_from_seed(seed)
    path = "m/0h/0h/12"
    xprv = bip32.derive(rxprv, path)
    wif = wif_from_prvkey(xprv)
    assert wif == b"L2L1dqRmkmVtwStNf5wg8nnGaRn3buoQr721XShM4VwDbTcn9bpm"
    pubkey, _ = pubkeyinfo_from_prvkey(wif)
    address = p2pkh(pubkey)
    xpub = bip32.xpub_from_xprv(xprv)
    address2 = slip132.address_from_xpub(xpub)
    assert address == address2

    err_msg = "not a private key: "
    with pytest.raises(ValueError, match=err_msg):
        wif_from_prvkey(xpub)
Exemple #4
0
    def test_one_prvkey_multiple_addresses(self):

        msg = "Paolo is afraid of ephemeral random numbers"

        # Compressed WIF
        wif = b'Kx45GeUBSMPReYQwgXiKhG9FzNXrnCeutJp4yjTd5kKxCitadm3C'
        pubkey, network = pubkey_info_from_prvkey(wif)
        address1 = p2pkh(pubkey, network)
        address2 = p2wpkh_p2sh(pubkey, network)
        address3 = p2wpkh(pubkey, network)

        # sign with no address (or compressed P2PKH)
        sig1 = bms.sign(msg, wif)
        # True for Bitcoin Core
        self.assertTrue(bms.verify(msg, address1, sig1))
        # True for Electrum p2wpkh_p2sh
        self.assertTrue(bms.verify(msg, address2, sig1))
        # True for Electrum p2wpkh
        self.assertTrue(bms.verify(msg, address3, sig1))

        # sign with p2wpkh_p2sh address (BIP137)
        sig2 = bms.sign(msg, wif, address2)
        # False for Bitcoin Core
        self.assertFalse(bms.verify(msg, address1, sig2))
        # True for BIP137 p2wpkh_p2sh
        self.assertTrue(bms.verify(msg, address2, sig2))
        # False for BIP137 p2wpkh
        self.assertFalse(bms.verify(msg, address3, sig2))

        # sign with p2wpkh address (BIP137)
        sig3 = bms.sign(msg, wif, address3)
        # False for Bitcoin Core
        self.assertFalse(bms.verify(msg, address1, sig3))
        # False for BIP137 p2wpkh_p2sh
        self.assertFalse(bms.verify(msg, address2, sig3))
        # True for BIP137 p2wpkh
        self.assertTrue(bms.verify(msg, address3, sig3))

        # uncompressed WIF / P2PKH address
        q, network, _ = prvkey_info_from_prvkey(wif)
        wif2 = wif_from_prvkey(q, network, False)
        pubkey, network = pubkey_info_from_prvkey(wif2)
        address4 = p2pkh(pubkey, network)

        # sign with uncompressed P2PKH
        sig4 = bms.sign(msg, wif2, address4)
        # False for Bitcoin Core compressed p2pkh
        self.assertFalse(bms.verify(msg, address1, sig4))
        # False for BIP137 p2wpkh_p2sh
        self.assertFalse(bms.verify(msg, address2, sig4))
        # False for BIP137 p2wpkh
        self.assertFalse(bms.verify(msg, address3, sig4))
        # True for Bitcoin Core uncompressed p2pkh
        self.assertTrue(bms.verify(msg, address4, sig4))

        self.assertRaises(ValueError, bms.sign, msg, wif2, address1)
        self.assertRaises(ValueError, bms.sign, msg, wif, address4)
Exemple #5
0
    def test_msgsign_p2pkh(self):
        msg = "test message"
        # sigs are taken from (Electrum and) Bitcoin Core

        q = "ca978112ca1bbdcafac231b39a23dc4da786eff8147c4e72b9807785afee48bb"

        # uncompressed
        wif1u = wif_from_prvkey(q, "mainnet", False)
        self.assertEqual(
            wif1u, b"5KMWWy2d3Mjc8LojNoj8Lcz9B1aWu8bRofUgGwQk959Dw5h2iyw")
        pubkey1u, _ = pubkeyinfo_from_prvkey(wif1u)
        add1u = base58address.p2pkh(pubkey1u)
        self.assertEqual(add1u, b"1HUBHMij46Hae75JPdWjeZ5Q7KaL7EFRSD")
        sig1u = bms.sign(msg, wif1u)
        self.assertTrue(bms.verify(msg, add1u, sig1u))
        self.assertEqual(sig1u[0], 27)
        exp_sig1u = ("G/iew/NhHV9V9MdUEn/LFOftaTy1ivGPKPKyMlr8OSokNC755fAxpST"
                     "hNRivwTNsyY9vPUDTRYBPc2cmGd5d4y4=").encode()
        self.assertEqual(bms.serialize(*sig1u), exp_sig1u)

        # compressed
        wif1c = wif_from_prvkey(q, "mainnet", True)
        self.assertEqual(
            wif1c, b"L41XHGJA5QX43QRG3FEwPbqD5BYvy6WxUxqAMM9oQdHJ5FcRHcGk")
        pubkey1c, _ = pubkeyinfo_from_prvkey(wif1c)
        add1c = base58address.p2pkh(pubkey1c)
        self.assertEqual(add1c, b"14dD6ygPi5WXdwwBTt1FBZK3aD8uDem1FY")
        sig1c = bms.sign(msg, wif1c)
        self.assertTrue(bms.verify(msg, add1c, sig1c))
        self.assertEqual(sig1c[0], 31)
        exp_sig1c = ("H/iew/NhHV9V9MdUEn/LFOftaTy1ivGPKPKyMlr8OSokNC755fAxpST"
                     "hNRivwTNsyY9vPUDTRYBPc2cmGd5d4y4=").encode()
        self.assertEqual(bms.serialize(*sig1c), exp_sig1c)

        self.assertFalse(bms.verify(msg, add1c, sig1u))
        self.assertFalse(bms.verify(msg, add1u, sig1c))

        rf, r, s, = sig1c
        sig1c_malleated_rf = bms.serialize(rf + 1, r, s)
        self.assertFalse(bms.verify(msg, add1c, sig1c_malleated_rf))
        sig1c_malleated_s = bms.serialize(rf, r, ec.n - s)
        self.assertFalse(bms.verify(msg, add1c, sig1c_malleated_s))
        sig1c_malleated_rf_s = bms.serialize(rf + 1, r, ec.n - s)
        self.assertTrue(bms.verify(msg, add1c, sig1c_malleated_rf_s))
Exemple #6
0
    def test_msgsign_p2pkh(self):
        msg = 'test message'
        # sigs are taken from (Electrum and) Bitcoin Core

        # first private key
        q1 = 91634880152443617534842621287039938041581081254914058002978601050179556493499

        # uncompressed
        wif1u = wif_from_prvkey(q1, 'mainnet', False)
        self.assertEqual(
            wif1u, b'5KMWWy2d3Mjc8LojNoj8Lcz9B1aWu8bRofUgGwQk959Dw5h2iyw')
        pubkey1u, _ = pubkey_info_from_prvkey(wif1u)
        add1u = base58address.p2pkh(pubkey1u)
        self.assertEqual(add1u, b'1HUBHMij46Hae75JPdWjeZ5Q7KaL7EFRSD')
        sig1u = bms.sign(msg, wif1u)
        self.assertTrue(bms.verify(msg, add1u, sig1u))
        self.assertEqual(sig1u[0], 27)
        exp_sig1u = b'G/iew/NhHV9V9MdUEn/LFOftaTy1ivGPKPKyMlr8OSokNC755fAxpSThNRivwTNsyY9vPUDTRYBPc2cmGd5d4y4='
        self.assertEqual(bms.serialize(*sig1u), exp_sig1u)

        # compressed
        wif1c = wif_from_prvkey(q1, 'mainnet', True)
        self.assertEqual(
            wif1c, b'L41XHGJA5QX43QRG3FEwPbqD5BYvy6WxUxqAMM9oQdHJ5FcRHcGk')
        pubkey1c, _ = pubkey_info_from_prvkey(wif1c)
        add1c = base58address.p2pkh(pubkey1c)
        self.assertEqual(add1c, b'14dD6ygPi5WXdwwBTt1FBZK3aD8uDem1FY')
        sig1c = bms.sign(msg, wif1c)
        self.assertTrue(bms.verify(msg, add1c, sig1c))
        self.assertEqual(sig1c[0], 31)
        exp_sig1c = b'H/iew/NhHV9V9MdUEn/LFOftaTy1ivGPKPKyMlr8OSokNC755fAxpSThNRivwTNsyY9vPUDTRYBPc2cmGd5d4y4='
        self.assertEqual(bms.serialize(*sig1c), exp_sig1c)

        self.assertFalse(bms.verify(msg, add1c, sig1u))
        self.assertFalse(bms.verify(msg, add1u, sig1c))

        rf, r, s, = sig1c
        sig1c_malleated_rf = bms.serialize(rf + 1, r, s)
        self.assertFalse(bms.verify(msg, add1c, sig1c_malleated_rf))
        sig1c_malleated_s = bms.serialize(rf, r, ec.n - s)
        self.assertFalse(bms.verify(msg, add1c, sig1c_malleated_s))
        sig1c_malleated_rf_s = bms.serialize(rf + 1, r, ec.n - s)
        self.assertTrue(bms.verify(msg, add1c, sig1c_malleated_rf_s))
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
Exemple #8
0
def test_msgsign_p2pkh() -> None:
    msg = "test message"
    # sigs are taken from (Electrum and) Bitcoin Core

    q = "ca978112ca1bbdcafac231b39a23dc4da786eff8147c4e72b9807785afee48bb"

    # uncompressed
    wif1u = wif_from_prvkey(q, "mainnet", False)
    assert wif1u == b"5KMWWy2d3Mjc8LojNoj8Lcz9B1aWu8bRofUgGwQk959Dw5h2iyw"
    add1u = base58address.p2pkh(wif1u)
    assert add1u == b"1HUBHMij46Hae75JPdWjeZ5Q7KaL7EFRSD"
    sig1u = bms.sign(msg, wif1u)
    assert bms.verify(msg, add1u, sig1u)
    assert sig1u[0] == 27
    exp_sig1u = "G/iew/NhHV9V9MdUEn/LFOftaTy1ivGPKPKyMlr8OSokNC755fAxpSThNRivwTNsyY9vPUDTRYBPc2cmGd5d4y4="
    assert bms.encode(*sig1u) == exp_sig1u.encode()

    # compressed
    wif1c = wif_from_prvkey(q, "mainnet", True)
    assert wif1c == b"L41XHGJA5QX43QRG3FEwPbqD5BYvy6WxUxqAMM9oQdHJ5FcRHcGk"
    add1c = base58address.p2pkh(wif1c)
    assert add1c == b"14dD6ygPi5WXdwwBTt1FBZK3aD8uDem1FY"
    sig1c = bms.sign(msg, wif1c)
    assert bms.verify(msg, add1c, sig1c)
    assert sig1c[0] == 31
    exp_sig1c = "H/iew/NhHV9V9MdUEn/LFOftaTy1ivGPKPKyMlr8OSokNC755fAxpSThNRivwTNsyY9vPUDTRYBPc2cmGd5d4y4="
    assert bms.encode(*sig1c) == exp_sig1c.encode()

    assert not bms.verify(msg, add1c, sig1u)
    assert not bms.verify(msg, add1u, sig1c)

    rf, r, s = sig1c

    sig1c_malleated_rf = bms.encode(rf + 1, r, s)
    assert not bms.verify(msg, add1c, sig1c_malleated_rf)
    sig1c_malleated_s = bms.encode(rf, r, ec.n - s)
    assert not bms.verify(msg, add1c, sig1c_malleated_s)
    sig1c_malleated_rf_s = bms.encode(rf + 1, r, ec.n - s)
    assert bms.verify(msg, add1c, sig1c_malleated_rf_s)
Exemple #9
0
    def test_p2pkh_from_wif(self):
        seed = b"00" * 32  # better be random
        rxprv = bip32.rootxprv_from_seed(seed)
        path = "m/0h/0h/12"
        xprv = bip32.derive(rxprv, path)
        wif = wif_from_prvkey(xprv)
        self.assertEqual(
            wif, b'KyLk7s6Z1FtgYEVp3bPckPVnXvLUWNCcVL6wNt3gaT96EmzTKZwP')
        pubkey, _ = pubkey_info_from_prvkey(wif)
        address = p2pkh(pubkey)
        xpub = bip32.xpub_from_xprv(xprv)
        address2 = slip32.address_from_xpub(xpub)
        self.assertEqual(address, address2)

        self.assertRaises(ValueError, wif_from_prvkey, xpub)
Exemple #10
0
    def test_info_from_prvkey(self):

        xprv = (
            "xprv9s21ZrQH143K3QTDL4LXw2F7HEK3wJUD2nW2nRk4stbPy6cq3jPPqjiC"
            "hkVvvNKmPGJxWUtg6LnF5kejMRNNU3TGtRBeJgk33yuGBxrMPHi").encode()
        xprv_str = xprv.decode("ascii")
        xprv_dict = bip32.deserialize(xprv)
        wif = wif_from_prvkey(xprv)
        wif_str = wif.decode("ascii")
        ref_tuple = (xprv_dict["q"], "mainnet", True)

        # BIP32
        self.assertEqual(ref_tuple, prvkeyinfo_from_prvkey(xprv, "mainnet"))
        self.assertEqual(ref_tuple, prvkeyinfo_from_prvkey(xprv))
        self.assertEqual(ref_tuple, prvkeyinfo_from_prvkey(xprv_str))
        self.assertEqual(ref_tuple,
                         prvkeyinfo_from_prvkey(" " + xprv_str + " "))
        self.assertEqual(ref_tuple, prvkeyinfo_from_prvkey(xprv_dict))

        # Invalid decoded size: 6 bytes instead of 82
        xpub = "notakey"
        self.assertRaises(ValueError, prvkeyinfo_from_prvkey, xpub)
        # prvkeyinfo_from_prvkey(xpub)

        # xkey is not a private one
        xpub = (
            "xpub661MyMwAqRbcFtXgS5sYJABqqG9YLmC4Q1Rdap9gSE8NqtwybGhePY2g"
            "Z29ESFjqJoCu1Rupje8YtGqsefD265TMg7usUDFdp6W1EGMcet8").encode()
        self.assertRaises(ValueError, prvkeyinfo_from_prvkey, xpub)
        # prvkeyinfo_from_prvkey(xpub)

        # xkey is not a private one
        xpub_dict = bip32.deserialize(xpub)
        self.assertRaises(ValueError, prvkeyinfo_from_prvkey, xpub_dict)
        # prvkeyinfo_from_prvkey(xpub_dict)

        # WIF keys (bytes or string)
        self.assertEqual(ref_tuple, prvkeyinfo_from_prvkey(wif))
        self.assertEqual(ref_tuple, prvkeyinfo_from_prvkey(wif_str))
        self.assertEqual(ref_tuple,
                         prvkeyinfo_from_prvkey(" " + wif_str + " "))
Exemple #11
0
    def test_pubkeyinfo_from_key(self):

        # prvkeys
        xprv = (
            "xprv9s21ZrQH143K3QTDL4LXw2F7HEK3wJUD2nW2nRk4stbPy6cq3jPPqjiC"
            "hkVvvNKmPGJxWUtg6LnF5kejMRNNU3TGtRBeJgk33yuGBxrMPHi").encode()
        xprv_str = xprv.decode("ascii")
        xprv_dict = bip32.deserialize(xprv)
        q, network, _ = _prvkeyinfo_from_xprv(xprv)
        ec = NETWORKS[network]["curve"]
        q_bytes = q.to_bytes(ec.nsize, "big")
        wif1 = wif_from_prvkey(q, network, True)
        wif2 = wif_from_prvkey(q, network, False)

        # pubkeys
        Q = mult(q, ec.G, ec)
        xpub = bip32.xpub_from_xprv(xprv)
        xpub_str = xpub.decode("ascii")
        xpub_dict = bip32.deserialize(xpub)
        Q_compr = xpub_dict["key"]
        Q_compr_hexstr = Q_compr.hex()
        Q_uncompr = bytes_from_point(Q, ec, False)
        Q_uncompr_hexstr = Q_uncompr.hex()

        # int prvkey, compressed result
        self.assertEqual(pubkeyinfo_from_key(q)[0], Q_compr)
        self.assertEqual(pubkeyinfo_from_key(q_bytes)[0], Q_compr)

        # int prvkey, uncompressed result
        self.assertEqual(
            pubkeyinfo_from_key(q, compressed=False)[0], Q_uncompr)
        self.assertEqual(
            pubkeyinfo_from_key(q_bytes, compressed=False)[0], Q_uncompr)

        # compressed wif prvkey, both results
        self.assertEqual(pubkeyinfo_from_key(wif1)[0], Q_compr)
        self.assertRaises(ValueError,
                          pubkeyinfo_from_key,
                          wif1,
                          compressed=False)

        # uncompressed wif prvkey, both results
        self.assertRaises(ValueError,
                          pubkeyinfo_from_key,
                          wif2,
                          compressed=True)
        self.assertEqual(pubkeyinfo_from_key(wif2)[0], Q_uncompr)

        # (compressed) BIP32 prvkey, compressed results
        self.assertEqual(pubkeyinfo_from_key(xprv)[0], Q_compr)
        self.assertEqual(pubkeyinfo_from_key(xprv_str)[0], Q_compr)
        self.assertEqual(pubkeyinfo_from_key(" " + xprv_str + " ")[0], Q_compr)
        self.assertEqual(pubkeyinfo_from_key(xprv_dict)[0], Q_compr)

        # (compressed) BIP32 prvkey, uncompressed result
        self.assertRaises(ValueError,
                          pubkeyinfo_from_key,
                          xprv,
                          compressed=False)
        self.assertRaises(ValueError,
                          pubkeyinfo_from_key,
                          xprv_str,
                          compressed=False)
        self.assertRaises(ValueError,
                          pubkeyinfo_from_key,
                          " " + xprv_str + " ",
                          compressed=False)
        self.assertRaises(ValueError,
                          pubkeyinfo_from_key,
                          xprv_dict,
                          compressed=False)

        # (compressed) BIP32 pubkey, compressed results
        self.assertEqual(pubkeyinfo_from_key(xpub)[0], Q_compr)
        self.assertEqual(pubkeyinfo_from_key(xpub_str)[0], Q_compr)
        self.assertEqual(pubkeyinfo_from_key(" " + xpub_str + " ")[0], Q_compr)
        self.assertEqual(pubkeyinfo_from_key(xpub_dict)[0], Q_compr)

        # (compressed) BIP32 pubkey, uncompressed result
        self.assertRaises(ValueError,
                          pubkeyinfo_from_key,
                          xpub,
                          compressed=False)
        self.assertRaises(ValueError,
                          pubkeyinfo_from_key,
                          xpub_str,
                          compressed=False)
        self.assertRaises(ValueError,
                          pubkeyinfo_from_key,
                          " " + xpub_str + " ",
                          compressed=False)
        self.assertRaises(ValueError,
                          pubkeyinfo_from_key,
                          xpub_dict,
                          compressed=False)

        # compressed SEC Octets (pubkey), compressed results
        self.assertEqual(pubkeyinfo_from_key(Q_compr)[0], Q_compr)
        self.assertEqual(pubkeyinfo_from_key(Q_compr_hexstr)[0], Q_compr)
        self.assertEqual(
            pubkeyinfo_from_key(" " + Q_compr_hexstr + " ")[0], Q_compr)

        # compressed SEC Octets (pubkey), uncompressed results
        self.assertRaises(ValueError,
                          pubkeyinfo_from_key,
                          Q_compr,
                          compressed=False)
        self.assertRaises(ValueError,
                          pubkeyinfo_from_key,
                          Q_compr_hexstr,
                          compressed=False)
        self.assertRaises(
            ValueError,
            pubkeyinfo_from_key,
            " " + Q_compr_hexstr + " ",
            compressed=False,
        )
        self.assertRaises(ValueError, pubkeyinfo_from_key, b"\x00" + Q_compr)
        self.assertRaises(ValueError, pubkeyinfo_from_key,
                          Q_compr_hexstr + "00")

        # uncompressed SEC Octets (pubkey), uncompressed results
        self.assertEqual(pubkeyinfo_from_key(Q_uncompr)[0], Q_uncompr)
        self.assertEqual(pubkeyinfo_from_key(Q_uncompr_hexstr)[0], Q_uncompr)
        self.assertEqual(
            pubkeyinfo_from_key(" " + Q_uncompr_hexstr + " ")[0], Q_uncompr)

        # uncompressed SEC Octets (pubkey), compressed results
        self.assertRaises(ValueError,
                          pubkeyinfo_from_key,
                          Q_uncompr,
                          compressed=True)
        self.assertRaises(ValueError,
                          pubkeyinfo_from_key,
                          Q_uncompr_hexstr,
                          compressed=True)
        self.assertRaises(
            ValueError,
            pubkeyinfo_from_key,
            " " + Q_uncompr_hexstr + " ",
            compressed=True,
        )
        self.assertRaises(ValueError, pubkeyinfo_from_key, b"\x00" + Q_uncompr)
        self.assertRaises(ValueError, pubkeyinfo_from_key,
                          Q_uncompr_hexstr + "00")

        # native tuple input, both results
        self.assertEqual(pubkeyinfo_from_key(Q)[0], Q_compr)
        self.assertEqual(
            pubkeyinfo_from_key(Q, compressed=False)[0], Q_uncompr)

        # pubkeyinfo_from_pubkey does not accept prvkey inputs
        self.assertRaises(TypeError, pubkeyinfo_from_pubkey, q)
        self.assertRaises(ValueError, pubkeyinfo_from_pubkey, q_bytes)
        self.assertRaises(ValueError, pubkeyinfo_from_pubkey, xprv)
        self.assertRaises(ValueError, pubkeyinfo_from_pubkey, xprv_str)
        self.assertRaises(ValueError, pubkeyinfo_from_pubkey, xprv_dict)
        self.assertRaises(ValueError, pubkeyinfo_from_pubkey, wif1)
        self.assertRaises(ValueError, pubkeyinfo_from_pubkey, wif2)

        # Not a public key:
        xpub_dict_bad = copy.copy(xpub_dict)
        xpub_dict_bad["key"] = b"\x00" + xpub_dict["key"][1:]
        self.assertRaises(ValueError, _pubkeyinfo_from_xpub, xpub_dict_bad)
        # _pubkeyinfo_from_xpub(xpub_dict_bad)

        # Invalid point: 7 is not a field element
        Q = INF
        self.assertRaises(ValueError, pubkeyinfo_from_key, Q)
        Q_compr = b"\x02" + Q[0].to_bytes(ec.psize, "big")
        self.assertRaises(ValueError, pubkeyinfo_from_key, Q_compr)
        Q_uncompr = (b"\x04" + Q[0].to_bytes(ec.psize, "big") +
                     Q[1].to_bytes(ec.psize, "big"))
        self.assertRaises(ValueError, pubkeyinfo_from_key, Q_uncompr)
        Q_compr_hexstr = Q_compr.hex()
        self.assertRaises(ValueError, pubkeyinfo_from_key, Q_compr_hexstr)
        Q_uncompr_hexstr = Q_uncompr.hex()
        self.assertRaises(ValueError, pubkeyinfo_from_key, Q_uncompr_hexstr)
        t = xpub_dict["version"]
        t += xpub_dict["depth"].to_bytes(1, "big")
        t += xpub_dict["parent_fingerprint"]
        t += xpub_dict["index"]
        t += xpub_dict["chain_code"]
        t += Q_compr
        xpub = b58encode(t, 78)
        self.assertRaises(ValueError, pubkeyinfo_from_key, xpub)
        xpub_str = xpub.decode("ascii")
        self.assertRaises(ValueError, pubkeyinfo_from_key, xpub_str)
Exemple #12
0
    def test_point_from_key(self):

        # prvkeys
        xprv = b"xprv9s21ZrQH143K3QTDL4LXw2F7HEK3wJUD2nW2nRk4stbPy6cq3jPPqjiChkVvvNKmPGJxWUtg6LnF5kejMRNNU3TGtRBeJgk33yuGBxrMPHi"
        xprv_str = xprv.decode('ascii')
        xprv_dict = bip32.deserialize(xprv)
        q, network, _ = _prvkey_info_from_xprv(xprv)
        ec = curve_from_network(network)
        q_bytes = q.to_bytes(ec.psize, 'big')
        wif1 = wif_from_prvkey(q, network, True)
        wif2 = wif_from_prvkey(q, network, False)

        # pubkeys
        Q = mult(q, ec.G, ec)
        xpub = bip32.xpub_from_xprv(xprv)
        xpub_str = xpub.decode('ascii')
        xpub_dict = bip32.deserialize(xpub)
        Q_compr = xpub_dict['key']
        Q_compr_hexstr = Q_compr.hex()
        Q_uncompr = bytes_from_point(Q, ec, False)
        Q_uncompr_hexstr = Q_uncompr.hex()

        # int prvkey
        self.assertEqual(point_from_key(q, ec), Q)
        self.assertEqual(point_from_key(q_bytes, ec), Q)

        # wif prvkey
        self.assertEqual(point_from_key(wif1, ec), Q)
        self.assertEqual(point_from_key(wif2, ec), Q)

        # BIP32 prvkey
        self.assertEqual(point_from_key(xprv, ec), Q)
        self.assertEqual(point_from_key(xprv_str, ec), Q)
        self.assertEqual(point_from_key(' ' + xprv_str + ' ', ec), Q)
        self.assertEqual(point_from_key(xprv_dict, ec), Q)

        # BIP32 pubkey
        self.assertEqual(point_from_key(xpub, ec), Q)
        self.assertEqual(point_from_key(xpub_str, ec), Q)
        self.assertEqual(point_from_key(' ' + xpub_str + ' ', ec), Q)
        self.assertEqual(point_from_key(xpub_dict, ec), Q)

        # compressed SEC Octets (bytes or hex-string, with 02 or 03 prefix)
        self.assertEqual(point_from_key(Q_compr, ec), Q)
        self.assertRaises(ValueError, point_from_key,
                          b'\x00' + Q_compr, ec)
        self.assertEqual(point_from_key(Q_compr_hexstr, ec), Q)
        self.assertEqual(point_from_key(' ' + Q_compr_hexstr + ' ', ec), Q)
        self.assertRaises(ValueError, point_from_key,
                          Q_compr_hexstr + '00', ec)

        # uncompressed SEC Octets (bytes or hex-string, with 04 prefix)
        self.assertEqual(point_from_key(Q_uncompr, ec), Q)
        self.assertRaises(ValueError, point_from_key,
                          b'\x00' + Q_uncompr, ec)
        self.assertEqual(point_from_key(Q_uncompr_hexstr, ec), Q)
        self.assertEqual(point_from_key(
            ' ' + Q_uncompr_hexstr + ' ', ec), Q)
        self.assertRaises(ValueError, point_from_key,
                          Q_uncompr_hexstr + '00', ec)

        # native tuple
        self.assertEqual(point_from_key(Q, ec), Q)

        # Invalid point: 7 is not a field element
        Q = INF
        self.assertRaises(ValueError, point_from_key, Q, ec)
        Q_compr = b'\x02' + Q[0].to_bytes(ec.psize, 'big')
        self.assertRaises(ValueError, point_from_key, Q_compr, ec)
        Q_uncompr = b'\x04' + \
            Q[0].to_bytes(ec.psize, 'big') + Q[1].to_bytes(ec.psize, 'big')
        self.assertRaises(ValueError, point_from_key, Q_uncompr, ec)
        Q_compr_hexstr = Q_compr.hex()
        self.assertRaises(ValueError, point_from_key, Q_compr_hexstr, ec)
        Q_uncompr_hexstr = Q_uncompr.hex()
        self.assertRaises(ValueError, point_from_key, Q_uncompr_hexstr, ec)
        t = xpub_dict['version']
        t += xpub_dict['depth'].to_bytes(1, 'big')
        t += xpub_dict['parent_fingerprint']
        t += xpub_dict['index']
        t += xpub_dict['chain_code']
        t += Q_compr
        xpub = b58encode(t)
        self.assertRaises(ValueError, point_from_key, xpub, ec)
        xpub_str = xpub.decode('ascii')
        self.assertRaises(ValueError, point_from_key, xpub_str, ec)

        # pubkey input
        self.assertRaises(ValueError, point_from_pubkey, xprv, ec)
        self.assertRaises(ValueError, point_from_pubkey, xprv_dict, ec)
Exemple #13
0
    def test_bytes_from_key(self):

        # prvkeys
        xprv = b"xprv9s21ZrQH143K3QTDL4LXw2F7HEK3wJUD2nW2nRk4stbPy6cq3jPPqjiChkVvvNKmPGJxWUtg6LnF5kejMRNNU3TGtRBeJgk33yuGBxrMPHi"
        xprv_str = xprv.decode('ascii')
        xprv_dict = bip32.deserialize(xprv)
        q, network, _ = _prvkey_info_from_xprv(xprv)
        ec = curve_from_network(network)
        q_bytes = q.to_bytes(ec.psize, 'big')
        wif1 = wif_from_prvkey(q, network, True)
        wif2 = wif_from_prvkey(q, network, False)

        # pubkeys
        Q = mult(q, ec.G, ec)
        xpub = bip32.xpub_from_xprv(xprv)
        xpub_str = xpub.decode('ascii')
        xpub_dict = bip32.deserialize(xpub)
        Q_compr = xpub_dict['key']
        Q_compr_hexstr = Q_compr.hex()
        Q_uncompr = bytes_from_point(Q, ec, False)
        Q_uncompr_hexstr = Q_uncompr.hex()

        # int prvkey, compressed result
        self.assertEqual(bytes_from_key(q)[0], Q_compr)
        self.assertEqual(bytes_from_key(q_bytes)[0], Q_compr)

        # int prvkey, uncompressed result
        self.assertEqual(bytes_from_key(q, compressed=False)[0], Q_uncompr)
        self.assertEqual(bytes_from_key(
            q_bytes, compressed=False)[0], Q_uncompr)

        # compressed wif prvkey, both results
        self.assertEqual(bytes_from_key(wif1)[0], Q_compr)
        self.assertRaises(ValueError, bytes_from_key, wif1, compressed=False)

        # uncompressed wif prvkey, both results
        self.assertRaises(ValueError, bytes_from_key, wif2, compressed=True)
        self.assertEqual(bytes_from_key(wif2)[0], Q_uncompr)

        # (compressed) BIP32 prvkey, compressed results
        self.assertEqual(bytes_from_key(xprv)[0], Q_compr)
        self.assertEqual(bytes_from_key(xprv_str)[0], Q_compr)
        self.assertEqual(bytes_from_key(' ' + xprv_str + ' ')[0], Q_compr)
        self.assertEqual(bytes_from_key(xprv_dict)[0], Q_compr)

        # (compressed) BIP32 prvkey, uncompressed result
        self.assertRaises(ValueError, bytes_from_key, xprv, compressed=False)
        self.assertRaises(ValueError, bytes_from_key,
                          xprv_str, compressed=False)
        self.assertRaises(ValueError, bytes_from_key,
                          ' ' + xprv_str + ' ', compressed=False)
        self.assertRaises(ValueError, bytes_from_key,
                          xprv_dict, compressed=False)

        # (compressed) BIP32 pubkey, compressed results
        self.assertEqual(bytes_from_key(xpub)[0], Q_compr)
        self.assertEqual(bytes_from_key(xpub_str)[0], Q_compr)
        self.assertEqual(bytes_from_key(' ' + xpub_str + ' ')[0], Q_compr)
        self.assertEqual(bytes_from_key(xpub_dict)[0], Q_compr)

        # (compressed) BIP32 pubkey, uncompressed result
        self.assertRaises(ValueError, bytes_from_key, xpub, compressed=False)
        self.assertRaises(ValueError, bytes_from_key,
                          xpub_str, compressed=False)
        self.assertRaises(ValueError, bytes_from_key,
                          ' ' + xpub_str + ' ', compressed=False)
        self.assertRaises(ValueError, bytes_from_key,
                          xpub_dict, compressed=False)

        # compressed SEC Octets (pubkey), compressed results
        self.assertEqual(bytes_from_key(Q_compr)[0], Q_compr)
        self.assertEqual(bytes_from_key(Q_compr_hexstr)[0], Q_compr)
        self.assertEqual(bytes_from_key(
            ' ' + Q_compr_hexstr + ' ')[0], Q_compr)

        # compressed SEC Octets (pubkey), uncompressed results
        self.assertRaises(ValueError, bytes_from_key,
                          Q_compr, compressed=False)
        self.assertRaises(ValueError, bytes_from_key,
                          Q_compr_hexstr, compressed=False)
        self.assertRaises(ValueError, bytes_from_key,
                          ' ' + Q_compr_hexstr + ' ', compressed=False)
        self.assertRaises(ValueError, bytes_from_key, b'\x00' + Q_compr)
        self.assertRaises(ValueError, bytes_from_key, Q_compr_hexstr + '00')

        # uncompressed SEC Octets (pubkey), uncompressed results
        self.assertEqual(bytes_from_key(Q_uncompr)[0], Q_uncompr)
        self.assertEqual(bytes_from_key(Q_uncompr_hexstr)[0], Q_uncompr)
        self.assertEqual(bytes_from_key(
            ' ' + Q_uncompr_hexstr + ' ')[0], Q_uncompr)

        # uncompressed SEC Octets (pubkey), compressed results
        self.assertRaises(ValueError, bytes_from_key,
                          Q_uncompr, compressed=True)
        self.assertRaises(ValueError, bytes_from_key,
                          Q_uncompr_hexstr, compressed=True)
        self.assertRaises(ValueError, bytes_from_key,
                          ' ' + Q_uncompr_hexstr + ' ', compressed=True)
        self.assertRaises(ValueError, bytes_from_key, b'\x00' + Q_uncompr)
        self.assertRaises(ValueError, bytes_from_key, Q_uncompr_hexstr + '00')

        # native tuple input, both results
        self.assertEqual(bytes_from_key(Q)[0], Q_compr)
        self.assertEqual(bytes_from_key(Q, compressed=False)[0], Q_uncompr)

        # bytes_from_pubkey does not accept prvkey inputs
        self.assertRaises(TypeError, bytes_from_pubkey, q)
        self.assertRaises(ValueError, bytes_from_pubkey, q_bytes)
        self.assertRaises(ValueError, bytes_from_pubkey, xprv)
        self.assertRaises(ValueError, bytes_from_pubkey, xprv_str)
        self.assertRaises(ValueError, bytes_from_pubkey, xprv_dict)
        self.assertRaises(ValueError, bytes_from_pubkey, wif1)
        self.assertRaises(ValueError, bytes_from_pubkey, wif2)

        # Not a public key:
        xpub_dict_bad = copy.copy(xpub_dict)
        xpub_dict_bad['key'] = b'\x00' + xpub_dict['key'][1:]
        self.assertRaises(ValueError, _bytes_from_xpub, xpub_dict_bad)
        # _bytes_from_xpub(xpub_dict_bad)

        # Invalid point: 7 is not a field element
        Q = INF
        self.assertRaises(ValueError, bytes_from_key, Q)
        Q_compr = b'\x02' + Q[0].to_bytes(ec.psize, 'big')
        self.assertRaises(ValueError, bytes_from_key, Q_compr)
        Q_uncompr = b'\x04' + \
            Q[0].to_bytes(ec.psize, 'big') + Q[1].to_bytes(ec.psize, 'big')
        self.assertRaises(ValueError, bytes_from_key, Q_uncompr)
        Q_compr_hexstr = Q_compr.hex()
        self.assertRaises(ValueError, bytes_from_key, Q_compr_hexstr)
        Q_uncompr_hexstr = Q_uncompr.hex()
        self.assertRaises(ValueError, bytes_from_key, Q_uncompr_hexstr)
        t = xpub_dict['version']
        t += xpub_dict['depth'].to_bytes(1, 'big')
        t += xpub_dict['parent_fingerprint']
        t += xpub_dict['index']
        t += xpub_dict['chain_code']
        t += Q_compr
        xpub = b58encode(t)
        self.assertRaises(ValueError, bytes_from_key, xpub)
        xpub_str = xpub.decode('ascii')
        self.assertRaises(ValueError, bytes_from_key, xpub_str)
Exemple #14
0
print(f"rf3: {sig3[0]}")
print(f" r3: {hex(sig3[1]).upper()}")
print(f" s3: {hex(sig3[2]).upper()}")

bsmsig3 = encode(*sig3)
print("4. Serialized signature:")
print(bsmsig3.decode())

print("5. Verify signature")
print("Bitcoin Core p2pkh:", verify(msg, address1, sig3))
print("BIP137 p2wpkh_p2sh:", verify(msg, address2, sig3))
print("BIP137 p2wpkh     :", verify(msg, address3, sig3))

# uncompressed WIF / P2PKH address
q, network, _ = prvkeyinfo_from_prvkey(wif)
wif2 = wif_from_prvkey(q, network, compressed=False)
print("\n1. Uncompressed WIF          :", wif2.decode())
pubkey, network = pubkeyinfo_from_prvkey(wif2)

address4 = p2pkh(pubkey)
print("2. Uncompressed P2PKH address:", address4.decode())

print("3. Sign message with uncompressed p2pkh:")
sig4 = sign(msg, wif2, address4)
print(f"rf4: {sig4[0]}")
print(f" r4: {hex(sig4[1]).upper()}")
print(f" s4: {hex(sig4[2]).upper()}")

bsmsig4 = encode(*sig4)
print("4. Serialized signature:")
print(bsmsig4.decode())
Exemple #15
0
def test_one_prvkey_multiple_addresses() -> None:

    msg = "Paolo is afraid of ephemeral random numbers"

    # Compressed WIF
    wif = b"Kx45GeUBSMPReYQwgXiKhG9FzNXrnCeutJp4yjTd5kKxCitadm3C"
    addr_p2pkh_compressed = p2pkh(wif)
    addr_p2wpkh_p2sh = p2wpkh_p2sh(wif)
    addr_p2wpkh = p2wpkh(wif)

    # sign with no address
    sig1 = bms.sign(msg, wif)
    # True for Bitcoin Core
    bms.assert_as_valid(msg, addr_p2pkh_compressed, sig1)
    assert bms.verify(msg, addr_p2pkh_compressed, sig1)
    # True for Electrum p2wpkh_p2sh
    bms.assert_as_valid(msg, addr_p2wpkh_p2sh, sig1)
    assert bms.verify(msg, addr_p2wpkh_p2sh, sig1)
    # True for Electrum p2wpkh
    bms.assert_as_valid(msg, addr_p2wpkh, sig1)
    assert bms.verify(msg, addr_p2wpkh, sig1)

    # sign with no p2pkh address
    sig1 = bms.sign(msg, wif, addr_p2pkh_compressed)
    # True for Bitcoin Core
    bms.assert_as_valid(msg, addr_p2pkh_compressed, sig1)
    assert bms.verify(msg, addr_p2pkh_compressed, sig1)
    # True for Electrum p2wpkh_p2sh
    bms.assert_as_valid(msg, addr_p2wpkh_p2sh, sig1)
    assert bms.verify(msg, addr_p2wpkh_p2sh, sig1)
    # True for Electrum p2wpkh
    bms.assert_as_valid(msg, addr_p2wpkh, sig1)
    assert bms.verify(msg, addr_p2wpkh, sig1)

    err_msg = "invalid recovery flag: "

    # sign with p2wpkh_p2sh address (BIP137)
    sig2 = bms.sign(msg, wif, addr_p2wpkh_p2sh)
    # False for Bitcoin Core
    with pytest.raises(BTClibValueError, match=err_msg):
        bms.assert_as_valid(msg, addr_p2pkh_compressed, sig2)
    assert not bms.verify(msg, addr_p2pkh_compressed, sig2)
    # True for BIP137 p2wpkh_p2sh
    bms.assert_as_valid(msg, addr_p2wpkh_p2sh, sig2)
    assert bms.verify(msg, addr_p2wpkh_p2sh, sig2)
    # False for BIP137 p2wpkh
    with pytest.raises(BTClibValueError, match=err_msg):
        bms.assert_as_valid(msg, addr_p2wpkh, sig2)
    assert not bms.verify(msg, addr_p2wpkh, sig2)

    # sign with p2wpkh address (BIP137)
    sig3 = bms.sign(msg, wif, addr_p2wpkh)
    # False for Bitcoin Core
    with pytest.raises(BTClibValueError, match=err_msg):
        bms.assert_as_valid(msg, addr_p2pkh_compressed, sig3)
    assert not bms.verify(msg, addr_p2pkh_compressed, sig3)
    # False for BIP137 p2wpkh_p2sh
    with pytest.raises(BTClibValueError, match=err_msg):
        bms.assert_as_valid(msg, addr_p2wpkh_p2sh, sig3)
    assert not bms.verify(msg, addr_p2wpkh_p2sh, sig3)
    # True for BIP137 p2wpkh
    bms.assert_as_valid(msg, addr_p2wpkh, sig3)
    assert bms.verify(msg, addr_p2wpkh, sig3)

    # uncompressed WIF / p2pkh address
    q, network, _ = prvkeyinfo_from_prvkey(wif)
    wif2 = wif_from_prvkey(q, network, False)
    addr_p2pkh_uncompressed = p2pkh(wif2)

    # sign with uncompressed p2pkh
    sig4 = bms.sign(msg, wif2, addr_p2pkh_uncompressed)
    # False for Bitcoin Core compressed p2pkh
    with pytest.raises(BTClibValueError, match="wrong p2pkh address: "):
        bms.assert_as_valid(msg, addr_p2pkh_compressed, sig4)
    assert not bms.verify(msg, addr_p2pkh_compressed, sig4)
    # False for BIP137 p2wpkh_p2sh
    # FIXME: puzzling error message
    # it should have been "wrong p2wpkh-p2sh address: "
    with pytest.raises(BTClibValueError, match="wrong p2pkh address: "):
        bms.assert_as_valid(msg, addr_p2wpkh_p2sh, sig4)
    assert not bms.verify(msg, addr_p2wpkh_p2sh, sig4)
    # False for BIP137 p2wpkh
    with pytest.raises(BTClibValueError, match=err_msg):
        bms.assert_as_valid(msg, addr_p2wpkh, sig4)
    assert not bms.verify(msg, addr_p2wpkh, sig4)
    # True for Bitcoin Core uncompressed p2pkh
    bms.assert_as_valid(msg, addr_p2pkh_uncompressed, sig4)
    assert bms.verify(msg, addr_p2pkh_uncompressed, sig4)

    # unrelated different wif
    wif3 = b"KwdMAjGmerYanjeui5SHS7JkmpZvVipYvB2LJGU1ZxJwYvP98617"
    addr_p2pkh_compressed = p2pkh(wif3)
    addr_p2wpkh_p2sh = p2wpkh_p2sh(wif3)
    addr_p2wpkh = p2wpkh(wif3)

    # False for Bitcoin Core compressed p2pkh
    with pytest.raises(BTClibValueError, match="wrong p2pkh address: "):
        bms.assert_as_valid(msg, addr_p2pkh_compressed, sig1)
    assert not bms.verify(msg, addr_p2pkh_compressed, sig1)
    # False for BIP137 p2wpkh_p2sh
    with pytest.raises(BTClibValueError, match="wrong p2wpkh-p2sh address: "):
        bms.assert_as_valid(msg, addr_p2wpkh_p2sh, sig1)
    assert not bms.verify(msg, addr_p2wpkh_p2sh, sig1)
    # False for BIP137 p2wpkh
    with pytest.raises(BTClibValueError, match="wrong p2wpkh address: "):
        bms.assert_as_valid(msg, addr_p2wpkh, sig1)
    assert not bms.verify(msg, addr_p2wpkh, sig1)

    # FIXME: puzzling error message
    err_msg = "not a private or compressed public key for mainnet: "
    with pytest.raises(BTClibValueError, match=err_msg):
        bms.sign(msg, wif2, addr_p2pkh_compressed)

    err_msg = "mismatch between private key and address"
    with pytest.raises(BTClibValueError, match=err_msg):
        bms.sign(msg, wif, addr_p2pkh_uncompressed)
Exemple #16
0
    def test_wif_from_prvkey(self):
        prvkey = "0C28FCA386C7A227600B2FE50B7CAE11EC86D3BF1FBE471BE89827E19D72AA1D"
        test_vectors = [
            [
                "KwdMAjGmerYanjeui5SHS7JkmpZvVipYvB2LJGU1ZxJwYvP98617",
                "mainnet", True
            ],
            [
                "cMzLdeGd5vEqxB8B6VFQoRopQ3sLAAvEzDAoQgvX54xwofSWj1fx",
                "testnet", True
            ],
            [
                "5HueCGU8rMjxEXxiPuD5BDku4MkFqeZyd4dZ1jvhTVqvbTLvyTJ",
                "mainnet", False
            ],
            [
                "91gGn1HgSap6CbU12F6z3pJri26xzp7Ay1VW6NHCoEayNXwRpu2",
                "testnet", False
            ],
            [
                " KwdMAjGmerYanjeui5SHS7JkmpZvVipYvB2LJGU1ZxJwYvP98617",
                "mainnet", True
            ],
            [
                "KwdMAjGmerYanjeui5SHS7JkmpZvVipYvB2LJGU1ZxJwYvP98617 ",
                "mainnet", True
            ],
        ]
        for v in test_vectors:
            wif = wif_from_prvkey(prvkey, v[1], v[2])
            self.assertEqual(v[0].strip(), wif.decode("ascii"))
            q, network, compressed = prvkeyinfo_from_prvkey(v[0])
            self.assertEqual(q, int(prvkey, 16))
            self.assertEqual(network, v[1])
            self.assertEqual(compressed, v[2])

        # not a 32-bytes private key
        badq = 33 * b"\x02"
        self.assertRaises(ValueError, wif_from_prvkey, badq, "mainnet", True)
        # wif_from_prvkey(badq, 'mainnet', True)

        # private key not in (0, n)
        badq = ec.n
        self.assertRaises(ValueError, wif_from_prvkey, badq, "mainnet", True)
        # wif_from_prvkey(badq, 'mainnet', True)

        # Not a private key WIF: missing leading 0x80
        payload = b"\x81" + badq.to_bytes(ec.nsize, "big")
        badwif = b58encode(payload)
        self.assertRaises(ValueError, prvkeyinfo_from_prvkey, badwif)
        # prvkeyinfo_from_prvkey(badwif)

        # Not a compressed WIF: missing trailing 0x01
        payload = b"\x80" + badq.to_bytes(ec.nsize, "big") + b"\x00"
        badwif = b58encode(payload)
        self.assertRaises(ValueError, prvkeyinfo_from_prvkey, badwif)
        # prvkeyinfo_from_prvkey(badwif)

        # Not a WIF: wrong size (35)
        payload = b"\x80" + badq.to_bytes(ec.nsize, "big") + b"\x01\x00"
        badwif = b58encode(payload)
        self.assertRaises(ValueError, prvkeyinfo_from_prvkey, badwif)
        # prvkeyinfo_from_prvkey(badwif)

        # Not a WIF: private key not in (0, n)
        payload = b"\x80" + badq.to_bytes(ec.nsize, "big")
        badwif = b58encode(payload)
        self.assertRaises(ValueError, prvkeyinfo_from_prvkey, badwif)
Exemple #17
0
    def test_int_from_prvkey(self):

        # BIP32
        xprv = b"xprv9s21ZrQH143K3QTDL4LXw2F7HEK3wJUD2nW2nRk4stbPy6cq3jPPqjiChkVvvNKmPGJxWUtg6LnF5kejMRNNU3TGtRBeJgk33yuGBxrMPHi"
        xprv_str = xprv.decode('ascii')
        xprv_dict = bip32.deserialize(xprv)
        # WIF
        wif = wif_from_prvkey(xprv)
        wif_str = wif.decode('ascii')
        # bytes
        qbytes = xprv_dict['key'][1:]
        qhex = qbytes.hex()
        # int
        q = xprv_dict['q']
        self.assertEqual(q, int_from_prvkey(q))
        # bytes
        self.assertEqual(q, int_from_prvkey(qbytes))
        self.assertRaises(ValueError, int_from_prvkey, b'\x00' + qbytes)
        self.assertEqual(q, int_from_prvkey(qhex))
        self.assertEqual(q, int_from_prvkey(' ' + qhex + ' '))
        self.assertRaises(ValueError, int_from_prvkey, qhex + '00')
        # WIF
        self.assertEqual(q, int_from_prvkey(wif))
        self.assertRaises(ValueError, int_from_prvkey, wif + b'\x00')
        self.assertEqual(q, int_from_prvkey(wif_str))
        self.assertEqual(q, int_from_prvkey(' ' + wif_str + ' '))
        # BIP32
        self.assertEqual(q, int_from_prvkey(xprv))
        self.assertRaises(ValueError, int_from_prvkey, xprv + b'\x00')
        self.assertEqual(q, int_from_prvkey(xprv_str))
        self.assertEqual(q, int_from_prvkey(' ' + xprv_str + ' '))
        self.assertEqual(q, int_from_prvkey(xprv_dict))

        # wrong private key int
        q = ec.n
        self.assertRaises(ValueError, int_from_prvkey, q)
        # bytes
        qbytes = q.to_bytes(32, byteorder='big')
        qhex = qbytes.hex()
        self.assertRaises(ValueError, int_from_prvkey, qbytes)
        self.assertRaises(ValueError, int_from_prvkey, qhex)
        # WIF
        t = b'\x80' + qbytes + b'\x01'
        wif = b58encode(t)
        wif_str = wif.decode('ascii')
        self.assertRaises(ValueError, int_from_prvkey, wif)
        self.assertRaises(ValueError, int_from_prvkey, wif_str)
        # BIP32
        t = xprv_dict['version']
        t += xprv_dict['depth'].to_bytes(1, 'big')
        t += xprv_dict['parent_fingerprint']
        t += xprv_dict['index']
        t += xprv_dict['chain_code']
        t += b'\x00' + qbytes
        xprv = b58encode(t)
        xprv_str = xprv.decode('ascii')
        self.assertRaises(ValueError, int_from_prvkey, xprv)
        self.assertRaises(ValueError, int_from_prvkey, xprv_str)

        # wrong private key int
        q = 0
        self.assertRaises(ValueError, int_from_prvkey, q)
        # bytes
        qbytes = q.to_bytes(32, byteorder='big')
        qhex = qbytes.hex()
        self.assertRaises(ValueError, int_from_prvkey, qbytes)
        self.assertRaises(ValueError, int_from_prvkey, qhex)
        # WIF
        t = b'\x80' + qbytes + b'\x01'
        wif = b58encode(t)
        wif_str = wif.decode('ascii')
        self.assertRaises(ValueError, int_from_prvkey, wif)
        self.assertRaises(ValueError, int_from_prvkey, wif_str)
        # BIP32
        t = xprv_dict['version']
        t += xprv_dict['depth'].to_bytes(1, 'big')
        t += xprv_dict['parent_fingerprint']
        t += xprv_dict['index']
        t += xprv_dict['chain_code']
        t += b'\x00' + qbytes
        xprv = b58encode(t)
        xprv_str = xprv.decode('ascii')
        self.assertRaises(ValueError, int_from_prvkey, xprv)
        self.assertRaises(ValueError, int_from_prvkey, xprv_str)

        # pub key
        xpub = b'xpub661MyMwAqRbcFtXgS5sYJABqqG9YLmC4Q1Rdap9gSE8NqtwybGhePY2gZ29ESFjqJoCu1Rupje8YtGqsefD265TMg7usUDFdp6W1EGMcet8'
        self.assertRaises(ValueError, int_from_prvkey, xpub)
Exemple #18
0
    def test_point_from_key(self):

        # prvkeys
        xprv = (
            "xprv9s21ZrQH143K3QTDL4LXw2F7HEK3wJUD2nW2nRk4stbPy6cq3jPPqjiC"
            "hkVvvNKmPGJxWUtg6LnF5kejMRNNU3TGtRBeJgk33yuGBxrMPHi").encode()
        xprv_str = xprv.decode("ascii")
        xprv_dict = bip32.deserialize(xprv)
        q, network, _ = _prvkeyinfo_from_xprv(xprv)
        ec = NETWORKS[network]["curve"]
        q_bytes = q.to_bytes(ec.nsize, "big")
        wif1 = wif_from_prvkey(q, network, True)
        wif2 = wif_from_prvkey(q, network, False)

        # pubkeys
        Q = mult(q, ec.G, ec)
        xpub = bip32.xpub_from_xprv(xprv)
        xpub_str = xpub.decode("ascii")
        xpub_dict = bip32.deserialize(xpub)
        Q_compr = xpub_dict["key"]
        Q_compr_hexstr = Q_compr.hex()
        Q_uncompr = bytes_from_point(Q, ec, False)
        Q_uncompr_hexstr = Q_uncompr.hex()

        # int prvkey
        self.assertEqual(point_from_key(q, ec), Q)
        self.assertEqual(point_from_key(q_bytes, ec), Q)

        # wif prvkey
        self.assertEqual(point_from_key(wif1, ec), Q)
        self.assertEqual(point_from_key(wif2, ec), Q)

        # BIP32 prvkey
        self.assertEqual(point_from_key(xprv, ec), Q)
        self.assertEqual(point_from_key(xprv_str, ec), Q)
        self.assertEqual(point_from_key(" " + xprv_str + " ", ec), Q)
        self.assertEqual(point_from_key(xprv_dict, ec), Q)

        # BIP32 pubkey
        self.assertEqual(point_from_key(xpub, ec), Q)
        self.assertEqual(point_from_key(xpub_str, ec), Q)
        self.assertEqual(point_from_key(" " + xpub_str + " ", ec), Q)
        self.assertEqual(point_from_key(xpub_dict, ec), Q)

        # compressed SEC Octets (bytes or hex-string, with 02 or 03 prefix)
        self.assertEqual(point_from_key(Q_compr, ec), Q)
        self.assertRaises(ValueError, point_from_key, b"\x00" + Q_compr, ec)
        self.assertEqual(point_from_key(Q_compr_hexstr, ec), Q)
        self.assertEqual(point_from_key(" " + Q_compr_hexstr + " ", ec), Q)
        self.assertRaises(ValueError, point_from_key, Q_compr_hexstr + "00",
                          ec)

        # uncompressed SEC Octets (bytes or hex-string, with 04 prefix)
        self.assertEqual(point_from_key(Q_uncompr, ec), Q)
        self.assertRaises(ValueError, point_from_key, b"\x00" + Q_uncompr, ec)
        self.assertEqual(point_from_key(Q_uncompr_hexstr, ec), Q)
        self.assertEqual(point_from_key(" " + Q_uncompr_hexstr + " ", ec), Q)
        self.assertRaises(ValueError, point_from_key, Q_uncompr_hexstr + "00",
                          ec)

        # native tuple
        self.assertEqual(point_from_key(Q, ec), Q)

        # Invalid point: 7 is not a field element
        Q = INF
        self.assertRaises(ValueError, point_from_key, Q, ec)
        Q_compr = b"\x02" + Q[0].to_bytes(ec.psize, "big")
        self.assertRaises(ValueError, point_from_key, Q_compr, ec)
        Q_uncompr = (b"\x04" + Q[0].to_bytes(ec.psize, "big") +
                     Q[1].to_bytes(ec.psize, "big"))
        self.assertRaises(ValueError, point_from_key, Q_uncompr, ec)
        Q_compr_hexstr = Q_compr.hex()
        self.assertRaises(ValueError, point_from_key, Q_compr_hexstr, ec)
        Q_uncompr_hexstr = Q_uncompr.hex()
        self.assertRaises(ValueError, point_from_key, Q_uncompr_hexstr, ec)
        t = xpub_dict["version"]
        t += xpub_dict["depth"].to_bytes(1, "big")
        t += xpub_dict["parent_fingerprint"]
        t += xpub_dict["index"]
        t += xpub_dict["chain_code"]
        t += Q_compr
        xpub = b58encode(t, 78)
        self.assertRaises(ValueError, point_from_key, xpub, ec)
        xpub_str = xpub.decode("ascii")
        self.assertRaises(ValueError, point_from_key, xpub_str, ec)

        # pubkey input
        self.assertRaises(ValueError, point_from_pubkey, xprv, ec)
        self.assertRaises(ValueError, point_from_pubkey, xprv_dict, ec)
Exemple #19
0
    def test_int_from_prvkey(self):

        # BIP32
        xprv = (
            "xprv9s21ZrQH143K3QTDL4LXw2F7HEK3wJUD2nW2nRk4stbPy6cq3jPPqjiC"
            "hkVvvNKmPGJxWUtg6LnF5kejMRNNU3TGtRBeJgk33yuGBxrMPHi").encode()
        xprv_str = xprv.decode("ascii")
        xprv_dict = bip32.deserialize(xprv)
        # WIF
        wif = wif_from_prvkey(xprv)
        wif_str = wif.decode("ascii")
        # bytes
        qbytes = xprv_dict["key"][1:]
        qhex = qbytes.hex()
        # int
        q = xprv_dict["q"]
        self.assertEqual(q, int_from_prvkey(q))
        # bytes
        self.assertEqual(q, int_from_prvkey(qbytes))
        self.assertRaises(ValueError, int_from_prvkey, b"\x00" + qbytes)
        self.assertEqual(q, int_from_prvkey(qhex))
        self.assertEqual(q, int_from_prvkey(" " + qhex + " "))
        self.assertRaises(ValueError, int_from_prvkey, qhex + "00")
        # WIF
        self.assertEqual(q, int_from_prvkey(wif))
        self.assertRaises(ValueError, int_from_prvkey, wif + b"\x00")
        self.assertEqual(q, int_from_prvkey(wif_str))
        self.assertEqual(q, int_from_prvkey(" " + wif_str + " "))
        # BIP32
        self.assertEqual(q, int_from_prvkey(xprv))
        self.assertRaises(ValueError, int_from_prvkey, xprv + b"\x00")
        self.assertEqual(q, int_from_prvkey(xprv_str))
        self.assertEqual(q, int_from_prvkey(" " + xprv_str + " "))
        self.assertEqual(q, int_from_prvkey(xprv_dict))

        # wrong private key int
        q = ec.n
        self.assertRaises(ValueError, int_from_prvkey, q)
        # bytes
        qbytes = q.to_bytes(32, byteorder="big")
        qhex = qbytes.hex()
        self.assertRaises(ValueError, int_from_prvkey, qbytes)
        self.assertRaises(ValueError, int_from_prvkey, qhex)
        # WIF
        t = b"\x80" + qbytes + b"\x01"
        wif = b58encode(t)
        wif_str = wif.decode("ascii")
        self.assertRaises(ValueError, int_from_prvkey, wif)
        self.assertRaises(ValueError, int_from_prvkey, wif_str)
        # BIP32
        t = xprv_dict["version"]
        t += xprv_dict["depth"].to_bytes(1, "big")
        t += xprv_dict["parent_fingerprint"]
        t += xprv_dict["index"]
        t += xprv_dict["chain_code"]
        t += b"\x00" + qbytes
        xprv = b58encode(t, 78)
        xprv_str = xprv.decode("ascii")
        self.assertRaises(ValueError, int_from_prvkey, xprv)
        self.assertRaises(ValueError, int_from_prvkey, xprv_str)

        # wrong private key int
        q = 0
        self.assertRaises(ValueError, int_from_prvkey, q)
        # bytes
        qbytes = q.to_bytes(32, byteorder="big")
        qhex = qbytes.hex()
        self.assertRaises(ValueError, int_from_prvkey, qbytes)
        self.assertRaises(ValueError, int_from_prvkey, qhex)
        # WIF
        t = b"\x80" + qbytes + b"\x01"
        wif = b58encode(t)
        wif_str = wif.decode("ascii")
        self.assertRaises(ValueError, int_from_prvkey, wif)
        self.assertRaises(ValueError, int_from_prvkey, wif_str)
        # BIP32
        t = xprv_dict["version"]
        t += xprv_dict["depth"].to_bytes(1, "big")
        t += xprv_dict["parent_fingerprint"]
        t += xprv_dict["index"]
        t += xprv_dict["chain_code"]
        t += b"\x00" + qbytes
        xprv = b58encode(t, 78)
        xprv_str = xprv.decode("ascii")
        self.assertRaises(ValueError, int_from_prvkey, xprv)
        self.assertRaises(ValueError, int_from_prvkey, xprv_str)

        # pub key
        xpub = (
            "xpub661MyMwAqRbcFtXgS5sYJABqqG9YLmC4Q1Rdap9gSE8NqtwybGhePY2g"
            "Z29ESFjqJoCu1Rupje8YtGqsefD265TMg7usUDFdp6W1EGMcet8").encode()
        self.assertRaises(ValueError, int_from_prvkey, xpub)