Example #1
0
def test_slip132_test_vector() -> None:
    """SLIP132 test vector

    https://github.com/satoshilabs/slips/blob/master/slip-0132.md
    """
    mnemonic = "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about"
    kpath = "./0/0"
    test_vectors: List[Tuple[bytes, str, str, str, str]] = [
        (
            NETWORKS["mainnet"]["bip32_prv"],
            "m / 44h / 0h / 0h",
            "xprv9xpXFhFpqdQK3TmytPBqXtGSwS3DLjojFhTGht8gwAAii8py5X6pxeBnQ6ehJiyJ6nDjWGJfZ95WxByFXVkDxHXrqu53WCRGypk2ttuqncb",
            "xpub6BosfCnifzxcFwrSzQiqu2DBVTshkCXacvNsWGYJVVhhawA7d4R5WSWGFNbi8Aw6ZRc1brxMyWMzG3DSSSSoekkudhUd9yLb6qx39T9nMdj",
            "1LqBGSKuX5yYUonjxT5qGfpUsXKYYWeabA",
        ),
        (
            NETWORKS["mainnet"]["slip132_p2wpkh_p2sh_prv"],
            "m / 49h / 0h / 0h",
            "yprvAHwhK6RbpuS3dgCYHM5jc2ZvEKd7Bi61u9FVhYMpgMSuZS613T1xxQeKTffhrHY79hZ5PsskBjcc6C2V7DrnsMsNaGDaWev3GLRQRgV7hxF",
            "ypub6Ww3ibxVfGzLrAH1PNcjyAWenMTbbAosGNB6VvmSEgytSER9azLDWCxoJwW7Ke7icmizBMXrzBx9979FfaHxHcrArf3zbeJJJUZPf663zsP",
            "37VucYSaXLCAsxYyAPfbSi9eh4iEcbShgf",
        ),
        (
            NETWORKS["mainnet"]["slip132_p2wpkh_prv"],
            "m / 84h / 0h / 0h",
            "zprvAdG4iTXWBoARxkkzNpNh8r6Qag3irQB8PzEMkAFeTRXxHpbF9z4QgEvBRmfvqWvGp42t42nvgGpNgYSJA9iefm1yYNZKEm7z6qUWCroSQnE",
            "zpub6rFR7y4Q2AijBEqTUquhVz398htDFrtymD9xYYfG1m4wAcvPhXNfE3EfH1r1ADqtfSdVCToUG868RvUUkgDKf31mGDtKsAYz2oz2AGutZYs",
            "bc1qcr8te4kr609gcawutmrza0j4xv80jy8z306fyu",
        ),
    ]
    for version, der_path, prv, pub, addr_str in test_vectors:
        addr = addr_str.encode()
        rxprv = bip32.mxprv_from_bip39_mnemonic(mnemonic, "")
        mxprv = bip32.derive(rxprv, der_path, version)
        assert prv.encode() == mxprv
        mxpub = bip32.xpub_from_xprv(mxprv)
        assert pub.encode() == mxpub
        xpub = bip32.derive(mxpub, kpath)
        address = slip132.address_from_xpub(xpub)
        assert addr == address
        address = slip132.address_from_xkey(xpub)
        assert addr == address
        xprv = bip32.derive(mxprv, kpath)
        address = slip132.address_from_xkey(xprv)
        assert addr == address
        if version == NETWORKS["mainnet"]["bip32_prv"]:
            address = base58address.p2pkh(xpub)
            assert addr == address
            address = base58address.p2pkh(xprv)
            assert addr == address
        elif version == NETWORKS["mainnet"]["slip132_p2wpkh_p2sh_prv"]:
            address = base58address.p2wpkh_p2sh(xpub)
            assert addr == address
            address = base58address.p2wpkh_p2sh(xprv)
            assert addr == address
        elif version == NETWORKS["mainnet"]["slip132_p2wpkh_prv"]:
            address = bech32address.p2wpkh(xpub)
            assert addr == address
            address = bech32address.p2wpkh(xprv)
            assert addr == address
Example #2
0
    def test_slip32_test_vector(self):
        """SLIP32 test vector

        https://github.com/satoshilabs/slips/blob/master/slip-0132.md
        """
        mnemonic = "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about"
        kpath = "./0/0"
        test_vectors = [
            [
                MAIN_xprv, "m / 44h / 0h / 0h",
                b'xprv9xpXFhFpqdQK3TmytPBqXtGSwS3DLjojFhTGht8gwAAii8py5X6pxeBnQ6ehJiyJ6nDjWGJfZ95WxByFXVkDxHXrqu53WCRGypk2ttuqncb',
                b'xpub6BosfCnifzxcFwrSzQiqu2DBVTshkCXacvNsWGYJVVhhawA7d4R5WSWGFNbi8Aw6ZRc1brxMyWMzG3DSSSSoekkudhUd9yLb6qx39T9nMdj',
                b'1LqBGSKuX5yYUonjxT5qGfpUsXKYYWeabA'
            ],
            [
                MAIN_yprv, "m / 49h / 0h / 0h",
                b'yprvAHwhK6RbpuS3dgCYHM5jc2ZvEKd7Bi61u9FVhYMpgMSuZS613T1xxQeKTffhrHY79hZ5PsskBjcc6C2V7DrnsMsNaGDaWev3GLRQRgV7hxF',
                b'ypub6Ww3ibxVfGzLrAH1PNcjyAWenMTbbAosGNB6VvmSEgytSER9azLDWCxoJwW7Ke7icmizBMXrzBx9979FfaHxHcrArf3zbeJJJUZPf663zsP',
                b'37VucYSaXLCAsxYyAPfbSi9eh4iEcbShgf'
            ],
            [
                MAIN_zprv, "m / 84h / 0h / 0h",
                b'zprvAdG4iTXWBoARxkkzNpNh8r6Qag3irQB8PzEMkAFeTRXxHpbF9z4QgEvBRmfvqWvGp42t42nvgGpNgYSJA9iefm1yYNZKEm7z6qUWCroSQnE',
                b'zpub6rFR7y4Q2AijBEqTUquhVz398htDFrtymD9xYYfG1m4wAcvPhXNfE3EfH1r1ADqtfSdVCToUG868RvUUkgDKf31mGDtKsAYz2oz2AGutZYs',
                b'bc1qcr8te4kr609gcawutmrza0j4xv80jy8z306fyu'
            ],
        ]
        for v in test_vectors:
            rxprv = bip32.rootxprv_from_bip39mnemonic(mnemonic, '', v[0])
            mxprv = bip32.derive(rxprv, v[1])
            self.assertEqual(v[2], mxprv)
            mxpub = bip32.xpub_from_xprv(mxprv)
            self.assertEqual(v[3], mxpub)
            xpub = bip32.derive(mxpub, kpath)
            address = slip32.address_from_xpub(xpub)
            self.assertEqual(v[4], address)
            address = slip32.address_from_xkey(xpub)
            self.assertEqual(v[4], address)
            xprv = bip32.derive(mxprv, kpath)
            address = slip32.address_from_xkey(xprv)
            self.assertEqual(v[4], address)
            if v[0] == MAIN_xprv:
                address = base58address.p2pkh(xpub)
                self.assertEqual(v[4], address)
                address = base58address.p2pkh(xprv)
                self.assertEqual(v[4], address)
            elif v[0] == MAIN_yprv:
                address = base58address.p2wpkh_p2sh(xpub)
                self.assertEqual(v[4], address)
                address = base58address.p2wpkh_p2sh(xprv)
                self.assertEqual(v[4], address)
            elif v[0] == MAIN_zprv:
                address = bech32address.p2wpkh(xpub)
                self.assertEqual(v[4], address)
                address = bech32address.p2wpkh(xprv)
                self.assertEqual(v[4], address)
def test_p2wpkh_p2sh() -> None:
    # https://matthewdowney.github.io/create-segwit-address.html
    pub = " 03 a1af804ac108a8a51782198c2d034b28bf90c8803f5a53f76276fa69a4eae77f"
    address = p2wpkh_p2sh(pub)
    assert address == b"36NvZTcMsMowbt78wPzJaHHWaNiyR73Y4g"
    address = p2wpkh_p2sh(pub, "testnet")
    assert address == b"2Mww8dCYPUpKHofjgcXcBCEGmniw9CoaiD2"

    # http://bitcoinscri.pt/pages/segwit_p2sh_p2wpkh
    pub = "02 f118cc409775419a931c57664d0c19c405e856ac0ee2f0e2a4137d8250531128"
    address = p2wpkh_p2sh(pub)
    assert address == b"3Mwz6cg8Fz81B7ukexK8u8EVAW2yymgWNd"
Example #4
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 #5
0
def test_p2wpkh() -> None:

    # self-consistency
    pubkey = "02 cc71eb30d653c0c3163990c47b976f3fb3f37cccdcbedb169a1dfef58bbfbfaf"
    payload = hash160(pubkey)
    scriptPubKey = script.encode([0, payload])
    assert scriptPubKey == p2wpkh(pubkey)

    # to the scriptPubKey in two steps (through payload)
    script_type = "p2wpkh"
    assert scriptPubKey == scriptPubKey_from_payload(script_type, payload)

    # back from the scriptPubKey to the payload
    assert (script_type, payload, 0) == payload_from_scriptPubKey(scriptPubKey)

    # bech32 address
    network = "mainnet"
    address = bech32address.p2wpkh(pubkey, network)
    assert address == address_from_scriptPubKey(scriptPubKey, network)
    wit_ver = 0
    assert address == b32address_from_witness(wit_ver, payload, network)

    # back from the address to the scriptPubKey
    assert (scriptPubKey, network) == scriptPubKey_from_address(address)

    # p2sh-wrapped base58 address
    address = base58address.p2wpkh_p2sh(pubkey, network)
    assert address == b58address_from_witness(payload, network)
Example #6
0
    def test_witness(self):

        pub = "03 a1af804ac108a8a51782198c2d034b28bf90c8803f5a53f76276fa69a4eae77f"
        b58addr = p2wpkh_p2sh(pub)
        _, h160, network, is_script_hash = h160_from_b58address(b58addr)
        self.assertEqual(network, 'mainnet')
        self.assertEqual(is_script_hash, True)  #?!?!?
        self.assertEqual(len(h160), 20)

        b58addr = _b58segwitaddress(hash160(to_pubkey_bytes(pub, True, ec)),
                                    network)
        _, h160_2, network, is_script_hash = h160_from_b58address(b58addr)
        self.assertEqual(network, 'mainnet')
        self.assertEqual(is_script_hash, True)  #?!?!?
        self.assertEqual(len(h160), 20)
        self.assertEqual(h160.hex(), h160_2.hex())

        wscript = "a8a58c2d034b28bf90c8803f5a53f769a4"
        b58addr = p2wsh_p2sh(wscript)
        _, h160, network, is_script_hash = h160_from_b58address(b58addr)
        self.assertEqual(network, 'mainnet')
        self.assertEqual(is_script_hash, True)  #?!?!?
        self.assertEqual(len(h160), 20)

        b58addr = _b58segwitaddress(sha256(wscript), network)
        _, h160_2, network, is_script_hash = h160_from_b58address(b58addr)
        self.assertEqual(network, 'mainnet')
        self.assertEqual(is_script_hash, True)  #?!?!?
        self.assertEqual(len(h160), 20)
        self.assertEqual(h160.hex(), h160_2.hex())

        # Invalid witness program length (19)
        self.assertRaises(ValueError, _b58segwitaddress, h160[:-1], network)
Example #7
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)
Example #8
0
    def test_p2w_p2sh(self):

        pubkey = "03 a1af804ac108a8a51782198c2d034b28bf90c8803f5a53f76276fa69a4eae77f"
        h160pubkey, network = hash160_from_pubkey(pubkey)
        b58addr = p2wpkh_p2sh(pubkey, network)
        b58addr2 = b58address_from_witness(h160pubkey, network)
        self.assertEqual(b58addr2, b58addr)
        script = encode(['OP_DUP', 'OP_HASH160', h160pubkey,
                         'OP_EQUALVERIFY', 'OP_CHECKSIG'])
        h256script = hash256_from_script(script)
        b58addr = p2wsh_p2sh(script, network)
        b58addr2 = b58address_from_witness(h256script, network)
        self.assertEqual(b58addr2, b58addr)

        # Invalid witness program length (19)
        self.assertRaises(ValueError, b58address_from_witness,
                          h256script[:-1], network)
Example #9
0
    def test_p2wpkh(self):

        script_type = "p2wpkh"

        # self-consistency
        pubkey = "02" "cc71eb30d653c0c3163990c47b976f3fb3f37cccdcbedb169a1dfef58bbfbfaf"
        payload = hash160(pubkey)
        script = encode([0, payload])

        # straight to the scriptPubKey
        scriptPubKey = p2wpkh(pubkey)
        self.assertEqual(scriptPubKey.hex(), script.hex())

        # to the scriptPubKey in two steps (through payload)
        scriptPubKey = scriptPubKey_from_payload(script_type, payload)
        self.assertEqual(scriptPubKey.hex(), script.hex())

        # back from the scriptPubKey to the payload
        script_type2, payload2, m2 = payload_from_scriptPubKey(scriptPubKey)
        self.assertEqual(script_type, script_type2)
        self.assertEqual(0, m2)
        self.assertEqual(payload.hex(), payload2.hex())
        script_type2, payload2, m2 = payload_from_scriptPubKey(script)
        self.assertEqual(script_type, script_type2)
        self.assertEqual(0, m2)
        self.assertEqual(payload.hex(), payload2.hex())

        # data -> payload is not invertible (hash functions)

        # bech32 address
        network = "mainnet"
        address = bech32address.p2wpkh(pubkey, network)
        address2 = address_from_scriptPubKey(scriptPubKey, network)
        self.assertEqual(address, address2)
        address2 = b32address_from_witness(0, payload, network)
        self.assertEqual(address, address2)

        scriptPubKey2, network2 = scriptPubKey_from_address(address)
        self.assertEqual(scriptPubKey2, scriptPubKey)
        self.assertEqual(network2, network)

        # p2sh-wrapped base58 address
        address = base58address.p2wpkh_p2sh(pubkey, network)
        address2 = b58address_from_witness(payload, network)
        self.assertEqual(address, address2)
Example #10
0
    def test_segwit(self):

        msg = "test"
        wif = "L4xAvhKR35zFcamyHME2ZHfhw5DEyeJvEMovQHQ7DttPTM8NLWCK"
        pubkey, _ = pubkeyinfo_from_prvkey(wif)
        p2pkh = base58address.p2pkh(pubkey)
        p2wpkh = bech32address.p2wpkh(pubkey)
        p2wpkh_p2sh = base58address.p2wpkh_p2sh(pubkey)

        # p2pkh base58 address (Core, Electrum, BIP137)
        exp_sig = ("IBFyn+h9m3pWYbB4fBFKlRzBD4eJKojgCIZSNdhLKKHPSV2/WkeV7R7IO"
                   "I0dpo3uGAEpCz9eepXLrA5kF35MXuU=").encode()
        self.assertTrue(bms.verify(msg, p2pkh, exp_sig))
        sig = bms.sign(msg, wif)  # no address: p2pkh assumed
        self.assertTrue(bms.verify(msg, p2pkh, sig))
        self.assertEqual(bms.serialize(*sig), exp_sig)

        # p2wpkh-p2sh base58 address (Electrum)
        self.assertTrue(bms.verify(msg, p2wpkh_p2sh, sig))

        # p2wpkh bech32 address (Electrum)
        self.assertTrue(bms.verify(msg, p2wpkh, sig))

        # p2wpkh-p2sh base58 address (BIP137)
        # different first letter in sig because of different rf
        exp_sig = ("JBFyn+h9m3pWYbB4fBFKlRzBD4eJKojgCIZSNdhLKKHPSV2/WkeV7R7IO"
                   "I0dpo3uGAEpCz9eepXLrA5kF35MXuU=").encode()
        self.assertTrue(bms.verify(msg, p2wpkh_p2sh, exp_sig))
        sig = bms.sign(msg, wif, p2wpkh_p2sh)
        self.assertTrue(bms.verify(msg, p2wpkh_p2sh, sig))
        self.assertEqual(bms.serialize(*sig), exp_sig)

        # p2wpkh bech32 address (BIP137)
        # different first letter in sig because of different rf
        exp_sig = ("KBFyn+h9m3pWYbB4fBFKlRzBD4eJKojgCIZSNdhLKKHPSV2/WkeV7R7IO"
                   "I0dpo3uGAEpCz9eepXLrA5kF35MXuU=").encode()
        self.assertTrue(bms.verify(msg, p2wpkh, exp_sig))
        sig = bms.sign(msg, wif, p2wpkh)
        self.assertTrue(bms.verify(msg, p2wpkh, sig))
        self.assertEqual(bms.serialize(*sig), exp_sig)
Example #11
0
def test_p2w_p2sh() -> None:

    pubkey = "03 a1af804ac108a8a51782198c2d034b28bf90c8803f5a53f76276fa69a4eae77f"
    h160pubkey, network = hash160_from_key(pubkey)
    b58addr = p2wpkh_p2sh(pubkey, network)
    b58addr2 = b58address_from_witness(h160pubkey, network)
    assert b58addr2 == b58addr

    scriptPubKey: List[ScriptToken] = [
        "OP_DUP",
        "OP_HASH160",
        h160pubkey,
        "OP_EQUALVERIFY",
        "OP_CHECKSIG",
    ]
    h256script = hash256_from_script(scriptPubKey)
    b58addr = p2wsh_p2sh(scriptPubKey, network)
    b58addr2 = b58address_from_witness(h256script, network)
    assert b58addr2 == b58addr

    err_msg = "invalid witness program length for witness version zero: "
    with pytest.raises(ValueError, match=err_msg):
        b58address_from_witness(h256script[:-1], network)
Example #12
0
def test_segwit() -> None:

    msg = "test"
    wif = "L4xAvhKR35zFcamyHME2ZHfhw5DEyeJvEMovQHQ7DttPTM8NLWCK"
    b58_p2pkh = base58address.p2pkh(wif)
    b58_p2wpkh = bech32address.p2wpkh(wif)
    b58_p2wpkh_p2sh = base58address.p2wpkh_p2sh(wif)

    # p2pkh base58 address (Core, Electrum, BIP137)
    exp_sig = "IBFyn+h9m3pWYbB4fBFKlRzBD4eJKojgCIZSNdhLKKHPSV2/WkeV7R7IOI0dpo3uGAEpCz9eepXLrA5kF35MXuU="
    assert bms.verify(msg, b58_p2pkh, exp_sig)
    sig = bms.sign(msg, wif)  # no address: p2pkh assumed
    assert bms.verify(msg, b58_p2pkh, sig)
    assert bms.encode(*sig) == exp_sig.encode()

    # p2wpkh-p2sh base58 address (Electrum)
    assert bms.verify(msg, b58_p2wpkh_p2sh, sig)

    # p2wpkh bech32 address (Electrum)
    assert bms.verify(msg, b58_p2wpkh, sig)

    # p2wpkh-p2sh base58 address (BIP137)
    # different first letter in sig because of different rf
    exp_sig = "JBFyn+h9m3pWYbB4fBFKlRzBD4eJKojgCIZSNdhLKKHPSV2/WkeV7R7IOI0dpo3uGAEpCz9eepXLrA5kF35MXuU="
    assert bms.verify(msg, b58_p2wpkh_p2sh, exp_sig)
    sig = bms.sign(msg, wif, b58_p2wpkh_p2sh)
    assert bms.verify(msg, b58_p2wpkh_p2sh, sig)
    assert bms.encode(*sig) == exp_sig.encode()

    # p2wpkh bech32 address (BIP137)
    # different first letter in sig because of different rf
    exp_sig = "KBFyn+h9m3pWYbB4fBFKlRzBD4eJKojgCIZSNdhLKKHPSV2/WkeV7R7IOI0dpo3uGAEpCz9eepXLrA5kF35MXuU="
    assert bms.verify(msg, b58_p2wpkh, exp_sig)
    sig = bms.sign(msg, wif, b58_p2wpkh)
    assert bms.verify(msg, b58_p2wpkh, sig)
    assert bms.encode(*sig) == exp_sig.encode()
Example #13
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)
Example #14
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])
Example #15
0
from btclib.bech32address import p2wpkh
from btclib.bms import encode, sign, verify
from btclib.to_prvkey import prvkeyinfo_from_prvkey
from btclib.to_pubkey import pubkeyinfo_from_prvkey

msg = "Paolo is afraid of ephemeral random numbers"
print("\n0. Message:", msg)

wif = b"Kx45GeUBSMPReYQwgXiKhG9FzNXrnCeutJp4yjTd5kKxCitadm3C"
print("1. Compressed WIF:", wif.decode())
pubkey, network = pubkeyinfo_from_prvkey(wif)

print("2. Addresses")
address1 = p2pkh(pubkey)
print("      p2pkh:", address1.decode())
address2 = p2wpkh_p2sh(pubkey)
print("p2wpkh_p2sh:", address2.decode())
address3 = p2wpkh(pubkey)
print("     p2wpkh:", address3.decode())

print("\n3. Sign message with no address (or with compressed p2pkh address):")
sig1 = sign(msg, wif)
print(f"rf1: {sig1[0]}")
print(f" r1: {hex(sig1[1]).upper()}")
print(f" s1: {hex(sig1[2]).upper()}")

bsmsig1 = encode(*sig1)
print("4. Serialized signature:")
print(bsmsig1.decode())

print("5. Verify signature")
Example #16
0
    def test_exceptions(self):

        msg = 'test'
        wif = 'KwELaABegYxcKApCb3kJR9ymecfZZskL9BzVUkQhsqFiUKftb4tu'
        pubkey, _ = pubkey_info_from_prvkey(wif)
        address = base58address.p2pkh(pubkey)
        exp_sig = b'IHdKsFF1bUrapA8GMoQUbgI+Ad0ZXyX1c/yAZHmJn5hSNBi7J+TrI1615FG3g9JEOPGVvcfDWIFWrg2exLNtoVc='
        self.assertTrue(bms.verify(msg, address, exp_sig))

        # Invalid recovery flag: 26
        _, r, s = bms.deserialize(exp_sig)
        self.assertRaises(ValueError, bms.serialize, 26, r, s)
        #bms.serialize(26, r, s)

        # short exp_sig
        exp_sig = b'IHdKsFF1bUrapA8GMoQUbgI+Ad0ZXyX1c/yAZHmJn5hNBi7J+TrI1615FG3g9JEOPGVvcfDWIFWrg2exLoVc='
        self.assertRaises(ValueError, bms._verify, msg, address, exp_sig)
        self.assertFalse(bms.verify(msg, address, exp_sig))

        # Invalid recovery flag: 26
        exp_sig = b'GpNLHqEKSzwXV+KwwBfQthQ848mn5qSkmGDXpqshDuPYJELOnSuRYGQQgBR4PpI+w2tJdD4v+hxElvAaUSqv2eU='
        self.assertRaises(ValueError, bms._verify, msg, address, exp_sig)
        self.assertFalse(bms.verify(msg, address, exp_sig))
        #bms._verify(msg, address, exp_sig)

        # Invalid recovery flag: 66
        exp_sig = b'QpNLHqEKSzwXV+KwwBfQthQ848mn5qSkmGDXpqshDuPYJELOnSuRYGQQgBR4PpI+w2tJdD4v+hxElvAaUSqv2eU='
        self.assertRaises(ValueError, bms._verify, msg, address, exp_sig)
        self.assertFalse(bms.verify(msg, address, exp_sig))
        #bms._verify(msg, address, exp_sig)

        # Pubkey mismatch: compressed wif, uncompressed address
        wif = 'Ky1XfDK2v6wHPazA6ECaD8UctEoShXdchgABjpU9GWGZDxVRDBMJ'
        address = '19f7adDYqhHSJm2v7igFWZAqxXHj1vUa3T'
        self.assertRaises(ValueError, bms.sign, msg, wif, address)
        #bms.sign(msg, wif, address)

        # Pubkey mismatch: uncompressed wif, compressed address
        wif = '5JDopdKaxz5bXVYXcAnfno6oeSL8dpipxtU1AhfKe3Z58X48srn'
        address = '1DAag8qiPLHh6hMFVu9qJQm9ro1HtwuyK5'
        self.assertRaises(ValueError, bms.sign, msg, wif, address)
        #bms.sign(msg, wif, address)

        msg = 'test'
        wif = 'L4xAvhKR35zFcamyHME2ZHfhw5DEyeJvEMovQHQ7DttPTM8NLWCK'
        pubkey, _ = pubkey_info_from_prvkey(wif)
        p2pkh = base58address.p2pkh(pubkey)
        p2wpkh = bech32address.p2wpkh(pubkey)
        p2wpkh_p2sh = base58address.p2wpkh_p2sh(pubkey)

        wif = 'Ky1XfDK2v6wHPazA6ECaD8UctEoShXdchgABjpU9GWGZDxVRDBMJ'
        # Mismatch between p2pkh address and key pair
        self.assertRaises(ValueError, bms.sign, msg, wif, p2pkh)
        # bms.sign(msg, wif, p2pkh)

        # Mismatch between p2wpkh address and key pair
        self.assertRaises(ValueError, bms.sign, msg, wif, p2wpkh)
        # bms.sign(msg, wif, p2wpkh)

        # Mismatch between p2wpkh_p2sh address and key pair
        self.assertRaises(ValueError, bms.sign, msg, wif, p2wpkh_p2sh)
        # bms.sign(msg, wif, p2wpkh_p2sh)

        # Invalid recovery flag (39) for base58 address
        exp_sig = b'IHdKsFF1bUrapA8GMoQUbgI+Ad0ZXyX1c/yAZHmJn5hSNBi7J+TrI1615FG3g9JEOPGVvcfDWIFWrg2exLNtoVc='
        _, r, s = bms.deserialize(exp_sig)
        sig = bms.serialize(39, r, s)
        self.assertRaises(ValueError, bms._verify, msg, p2pkh, sig)
        #bms._verify(msg, p2pkh, sig)

        # Invalid recovery flag (35) for bech32 address
        exp_sig = b'IBFyn+h9m3pWYbB4fBFKlRzBD4eJKojgCIZSNdhLKKHPSV2/WkeV7R7IOI0dpo3uGAEpCz9eepXLrA5kF35MXuU='
        _, r, s = bms.deserialize(exp_sig)
        sig = bms.serialize(35, r, s)
        self.assertRaises(ValueError, bms._verify, msg, p2wpkh, sig)
Example #17
0
    def test_testnet_versions(self):

        # data cross-checked with Electrum and
        # https://jlopp.github.io/xpub-converter/

        # 128 bits
        raw_entr = bytes.fromhex("6" * 32)
        # 12 words
        mnemonic = bip39.mnemonic_from_entropy(raw_entr, "en")
        seed = bip39.seed_from_mnemonic(mnemonic, "")

        # p2pkh BIP44
        # m / 44h / coin_typeh / accounth / change / address_index
        path = "m/44h/1h/0h"
        version = NETWORKS["testnet"]["bip32_prv"]
        rootprv = rootxprv_from_seed(seed, version)
        xprv = derive(rootprv, path)
        xpub = xpub_from_xprv(xprv)
        exp = "tpubDChqWo2Xi2wNsxyJBE8ipcTJHLKWcqeeNUKBVTpUCNPZkHzHTm3qKAeHqgCou1t8PAY5ZnJ9QDa6zXSZxmjDnhiBpgZ7f6Yv88wEm5HXVbm"
        self.assertEqual(xpub.decode(), exp)
        # first addresses
        xpub_ext = derive(xpub, "./0/0")  # external
        address = p2pkh(xpub_ext)
        exp_address = b"moutHSzeFWViMNEcvBxKzNCMj2kca8MvE1"
        self.assertEqual(address, exp_address)
        xpub_int = derive(xpub, "./1/0")  # internal
        address = p2pkh(xpub_int)
        exp_address = b"myWcXdNais9ExumnGKnNoJwoihQKfNPG9i"
        self.assertEqual(address, exp_address)

        # legacy segwit (p2wsh-p2sh)
        # m / 49h / coin_typeh / accounth / change / address_index
        path = "m/49h/1h/0h"
        version = NETWORKS["testnet"]["slip32_p2wsh_p2sh_prv"]
        rootprv = rootxprv_from_seed(seed, version)
        xprv = derive(rootprv, path)
        xpub = xpub_from_xprv(xprv)
        exp = "upub5Dj8j7YrwodV68mt58QmNpSzjqjso2WMXEpLGLSvskKccGuXhCh3dTedkzVLAePA617UyXAg2vdswJXTYjU4qjMJaHU79GJVVJCAiy9ezZ2"
        self.assertEqual(xpub.decode(), exp)
        # first addresses
        xpub_ext = derive(xpub, "./0/0")  # external
        address = p2wpkh_p2sh(xpub_ext)
        exp_address = b"2Mw8tQ6uT6mHhybarVhjgomUhHQJTeV9A2c"
        self.assertEqual(address, exp_address)
        xpub_int = derive(xpub, "./1/0")  # internal
        address = p2wpkh_p2sh(xpub_int)
        exp_address = b"2N872CRJ3E1CzWjfixXr3aeC3hkF5Cz4kWb"
        self.assertEqual(address, exp_address)

        # legacy segwit (p2wsh-p2sh)
        # m / 49h / coin_typeh / accounth / change / address_index
        path = "m/49h/1h/0h"
        version = NETWORKS["testnet"]["slip32_p2wpkh_p2sh_prv"]
        rootprv = rootxprv_from_seed(seed, version)
        xprv = derive(rootprv, path)
        xpub = xpub_from_xprv(xprv)
        exp = "Upub5QdDrMHJWmBrWhwG1nskCtnoTdn91PBwqWU1BbiUFXA2ETUSTc5KiaWZZhSoj5c4KUBTr7Anv92P4U9Dqxd1zDTyQkaWYfmVP2U3Js1W5cG"
        self.assertEqual(xpub.decode(), exp)

        # native segwit (p2wpkh)
        # m / 84h / coin_typeh / accounth / change / address_index
        path = "m/84h/1h/0h"
        version = NETWORKS["testnet"]["slip32_p2wpkh_prv"]
        rootprv = rootxprv_from_seed(seed, version)
        xprv = derive(rootprv, path)
        xpub = xpub_from_xprv(xprv)
        exp = "vpub5ZhJmduYY7M5J2qCJgSW7hunX6zJrr5WuNg2kKt321HseZEYxqJc6Zso47aNXQw3Wf3sA8kppbfsxnLheUNXcL3xhzeBHLNp8fTVBN6DnJF"
        self.assertEqual(xpub.decode(), exp)
        # first addresses
        xpub_ext = derive(xpub, "./0/0")  # external
        # explicit network is required to discriminate from testnet
        address = p2wpkh(xpub_ext, "regtest")
        exp_address = b"bcrt1qv8lcnmj09rpdqwgl025h2deygur64z4hqf7me5"
        self.assertEqual(address, exp_address)
        xpub_int = derive(xpub, "./1/0")  # internal
        # explicit network is required to discriminate from testnet
        address = p2wpkh(xpub_int, "regtest")
        exp_address = b"bcrt1qqhxvky4y6qkwpvdzqjkdafmj20vs5trmt6y8w5"
        self.assertEqual(address, exp_address)

        # native segwit (p2wsh)
        # m / 84h / coin_typeh / accounth / change / address_index
        path = "m/84h/1h/0h"
        version = NETWORKS["testnet"]["slip32_p2wsh_prv"]
        rootprv = rootxprv_from_seed(seed, version)
        xprv = derive(rootprv, path)
        xpub = xpub_from_xprv(xprv)
        exp = "Vpub5kbPtsdz74uSibzaFLuUwnFbEu2a5Cm7DeKhfb9aPn8HGjoTjEgtBgjirpXr5r9wk87r2ikwhp4P5wxTwhXUkpAdYTkagjqp2PjMmGPBESU"
        self.assertEqual(xpub.decode(), exp)
Example #18
0
    def test_mainnet_versions(self):

        # data cross-checked with Electrum and
        # https://jlopp.github.io/xpub-converter/

        # 128 bits
        raw_entr = bytes.fromhex("6" * 32)
        # 12 words
        mnemonic = bip39.mnemonic_from_entropy(raw_entr, "en")
        seed = bip39.seed_from_mnemonic(mnemonic, "")

        # p2pkh BIP44
        # m / 44h / coin_typeh / accounth / change / address_index
        path = "m/44h/0h/0h"
        version = NETWORKS["mainnet"]["bip32_prv"]
        rootprv = rootxprv_from_seed(seed, version)
        xprv = derive(rootprv, path)
        xpub = xpub_from_xprv(xprv)
        exp = "xpub6C3uWu5Go5q62JzJpbjyCLYRGLYvexFeiepZTsYZ6SRexARkNfjG7GKtQVuGR3KHsyKsAwv7Hz3iNucPp6pfHiLvBczyK1j5CtBtpHB3NKx"
        self.assertEqual(xpub.decode(), exp)
        # first addresses
        xpub_ext = derive(xpub, "./0/0")  # external
        address = p2pkh(xpub_ext)
        exp_address = b"1DDKKVHoFWGfctyEEJvrusqq6ipEaieGCq"
        self.assertEqual(address, exp_address)
        xpub_int = derive(xpub, "./1/0")  # internal
        address = p2pkh(xpub_int)
        exp_address = b"1FhKoffreKHzhtBMVW9NSsg3ZF148JPGoR"
        self.assertEqual(address, exp_address)

        # legacy segwit (p2wsh-p2sh)
        # m / 49h / coin_typeh / accounth / change / address_index
        path = "m/49h/0h/0h"
        version = NETWORKS["mainnet"]["slip32_p2wsh_p2sh_prv"]
        rootprv = rootxprv_from_seed(seed, version)
        xprv = derive(rootprv, path)
        xpub = xpub_from_xprv(xprv)
        exp = "ypub6YBGdYufCVeoPVmNXfdrWhaBCXsQoLKNetNmD9bPTrKmnKVmiyU8f1uJqwGdmBb8kbAZpHoYfXQTLbWpkXc4skQDAreeCUXdbX9k8vtiHsN"
        self.assertEqual(xpub.decode(), exp)
        # first addresses
        xpub_ext = derive(xpub, "./0/0")  # external
        address = p2wpkh_p2sh(xpub_ext)
        exp_address = b"3FmNAiTCWe5kPMgc4dtSgEdY8VuaCiJEH8"
        self.assertEqual(address, exp_address)
        xpub_int = derive(xpub, "./1/0")  # internal
        address = p2wpkh_p2sh(xpub_int)
        exp_address = b"34FLgkoRYX5Q5fqiZCZDwsK5GpXxmFuLJN"
        self.assertEqual(address, exp_address)

        # legacy segwit (p2wpkh-p2sh)
        # m / 49h / coin_typeh / accounth / change / address_index
        path = "m/49h/0h/0h"
        version = NETWORKS["mainnet"]["slip32_p2wpkh_p2sh_prv"]
        rootprv = rootxprv_from_seed(seed, version)
        xprv = derive(rootprv, path)
        xpub = xpub_from_xprv(xprv)
        exp = "Ypub6j5Mkne6mTDAp4vkUL6qLmuyvKug1gzxyA2S8QrvqdABQW4gVNrQk8mEeeE7Kcp2z4EYgsofYjnxTm8b3km22EWt1Km3bszdVFRcipc6rXu"
        self.assertEqual(xpub.decode(), exp)

        # native segwit (p2wpkh)
        # m / 84h / coin_typeh / accounth / change / address_index
        path = "m/84h/0h/0h"
        version = NETWORKS["mainnet"]["slip32_p2wpkh_prv"]
        rootprv = rootxprv_from_seed(seed, version)
        xprv = derive(rootprv, path)
        xpub = xpub_from_xprv(xprv)
        exp = "zpub6qg3Uc1BAQkQvcBUYMmZHSzbsshSon3FvJ8yvH3ZZMjFNvJkwSji8UUwghiF3wvpvSvcNWVP8kfUhc2V2RwGp6pTC3ouj6njj956f26TniN"
        self.assertEqual(xpub.decode(), exp)
        # first addresses
        xpub_ext = derive(xpub, "./0/0")  # external
        address = p2wpkh(xpub_ext)
        exp_address = b"bc1q0hy024867ednvuhy9en4dggflt5w9unw4ztl5a"
        self.assertEqual(address, exp_address)
        xpub_int = derive(xpub, "./1/0")  # internal
        address = p2wpkh(xpub_int)
        exp_address = b"bc1qy4x03jyl88h2zeg7l287xhv2xrwk4c3ztfpjd2"
        self.assertEqual(address, exp_address)

        # native segwit (p2wsh)
        # m / 84h / coin_typeh / accounth / change / address_index
        path = "m/84h/0h/0h"
        version = NETWORKS["mainnet"]["slip32_p2wsh_prv"]
        rootprv = rootxprv_from_seed(seed, version)
        xprv = derive(rootprv, path)
        xpub = xpub_from_xprv(xprv)
        exp = "Zpub72a8bqjcjNJnMBLrV2EY7XLQbfji28irEZneqYK6w8Zf16sfhr7zDbLsVQficP9j9uzbF6VW1y3ypmeFKf6Dxaw82WvK8WFjcsLyEvMNZjF"
        self.assertEqual(xpub.decode(), exp)
Example #19
0
def test_exceptions() -> None:

    msg = "test"
    wif = "KwELaABegYxcKApCb3kJR9ymecfZZskL9BzVUkQhsqFiUKftb4tu"
    address = base58address.p2pkh(wif)
    exp_sig = "IHdKsFF1bUrapA8GMoQUbgI+Ad0ZXyX1c/yAZHmJn5hSNBi7J+TrI1615FG3g9JEOPGVvcfDWIFWrg2exLNtoVc="
    assert bms.verify(msg, address, exp_sig)

    _, r, s = bms.decode(exp_sig)
    err_msg = "invalid recovery flag: "
    with pytest.raises(BTClibValueError, match=err_msg):
        bms.encode(26, r, s)

    exp_sig = "IHdKsFF1bUrapA8GMoQUbgI+Ad0ZXyX1c/yAZHmJn5hNBi7J+TrI1615FG3g9JEOPGVvcfDWIFWrg2exLoVc="
    err_msg = "wrong signature length: "
    with pytest.raises(BTClibValueError, match=err_msg):
        bms.assert_as_valid(msg, address, exp_sig)
    assert not bms.verify(msg, address, exp_sig)

    exp_sig = "GpNLHqEKSzwXV+KwwBfQthQ848mn5qSkmGDXpqshDuPYJELOnSuRYGQQgBR4PpI+w2tJdD4v+hxElvAaUSqv2eU="
    err_msg = "invalid recovery flag: "
    with pytest.raises(BTClibValueError, match=err_msg):
        bms.assert_as_valid(msg, address, exp_sig)
    assert not bms.verify(msg, address, exp_sig)
    exp_sig = "QpNLHqEKSzwXV+KwwBfQthQ848mn5qSkmGDXpqshDuPYJELOnSuRYGQQgBR4PpI+w2tJdD4v+hxElvAaUSqv2eU="
    with pytest.raises(BTClibValueError, match=err_msg):
        bms.assert_as_valid(msg, address, exp_sig)
    assert not bms.verify(msg, address, exp_sig)

    # compressed wif, uncompressed address
    wif = "Ky1XfDK2v6wHPazA6ECaD8UctEoShXdchgABjpU9GWGZDxVRDBMJ"
    address = b"19f7adDYqhHSJm2v7igFWZAqxXHj1vUa3T"
    err_msg = "mismatch between private key and address"
    with pytest.raises(BTClibValueError, match=err_msg):
        bms.sign(msg, wif, address)

    # uncompressed wif, compressed address
    wif = "5JDopdKaxz5bXVYXcAnfno6oeSL8dpipxtU1AhfKe3Z58X48srn"
    address = b"1DAag8qiPLHh6hMFVu9qJQm9ro1HtwuyK5"
    err_msg = "not a private or compressed public key for mainnet: "
    # FIXME puzzling error message
    with pytest.raises(BTClibValueError, match=err_msg):
        bms.sign(msg, wif, address)

    msg = "test"
    wif = "L4xAvhKR35zFcamyHME2ZHfhw5DEyeJvEMovQHQ7DttPTM8NLWCK"
    b58_p2pkh = base58address.p2pkh(wif)
    b58_p2wpkh = bech32address.p2wpkh(wif)
    b58_p2wpkh_p2sh = base58address.p2wpkh_p2sh(wif)

    wif = "Ky1XfDK2v6wHPazA6ECaD8UctEoShXdchgABjpU9GWGZDxVRDBMJ"
    err_msg = "mismatch between private key and address"
    with pytest.raises(BTClibValueError, match=err_msg):
        bms.sign(msg, wif, b58_p2pkh)
    with pytest.raises(BTClibValueError, match=err_msg):
        bms.sign(msg, wif, b58_p2wpkh)
    with pytest.raises(BTClibValueError, match=err_msg):
        bms.sign(msg, wif, b58_p2wpkh_p2sh)

    # Invalid recovery flag (39) for base58 address
    exp_sig = "IHdKsFF1bUrapA8GMoQUbgI+Ad0ZXyX1c/yAZHmJn5hSNBi7J+TrI1615FG3g9JEOPGVvcfDWIFWrg2exLNtoVc="
    _, r, s = bms.decode(exp_sig)
    sig = bms.encode(39, r, s)
    err_msg = "invalid recovery flag: "
    with pytest.raises(BTClibValueError, match=err_msg):
        bms.assert_as_valid(msg, b58_p2pkh, sig)

    # Invalid recovery flag (35) for bech32 address
    exp_sig = "IBFyn+h9m3pWYbB4fBFKlRzBD4eJKojgCIZSNdhLKKHPSV2/WkeV7R7IOI0dpo3uGAEpCz9eepXLrA5kF35MXuU="
    _, r, s = bms.decode(exp_sig)
    sig = bms.encode(35, r, s)
    err_msg = "invalid recovery flag: "
    with pytest.raises(BTClibValueError, match=err_msg):
        bms.assert_as_valid(msg, b58_p2wpkh, sig)