Exemple #1
0
def test_fingerprint() -> None:
    seed = "bfc4cbaad0ff131aa97fa30a48d09ae7df914bcc083af1e07793cd0a7c61a03f65d622848209ad3366a419f4718a80ec9037df107d8d12c19b83202de00a40ad"
    xprv = rootxprv_from_seed(seed)
    pf = fingerprint(xprv)  # xprv is automatically converted to xpub
    child_key = derive(xprv, 0x80000000)
    pf2 = BIP32KeyData.b58decode(child_key).parent_fingerprint
    assert pf == pf2
def mxprv_from_mnemonic(mnemonic: Mnemonic,
                        passphrase: Optional[str] = None,
                        network: str = "mainnet") -> str:
    "Return BIP32 root master extended private key from BIP39 mnemonic."

    seed = seed_from_mnemonic(mnemonic, passphrase or "")
    version = NETWORKS[network].bip32_prv
    return rootxprv_from_seed(seed, version)
def mxprv_from_mnemonic(mnemonic: Mnemonic,
                        passphrase: Optional[str] = None,
                        network: str = "mainnet") -> str:
    """Return BIP32 master extended private key from Electrum mnemonic.

    Note that for a "standard" mnemonic the derivation path is "m",
    for a "segwit" mnemonic it is "m/0h" instead.
    """
    version, seed = _seed_from_mnemonic(mnemonic, passphrase or "")

    if version == "standard":
        xversion = NETWORKS[network].bip32_prv
        return rootxprv_from_seed(seed, xversion)
    if version == "segwit":
        xversion = NETWORKS[network].slip132_p2wpkh_prv
        rootxprv = rootxprv_from_seed(seed, xversion)
        return derive(rootxprv, 0x80000000)  # "m/0h"
    raise BTClibValueError(f"unmanaged electrum mnemonic version: {version}")
Exemple #4
0
def test_bips_pr905() -> None:
    "https://github.com/bitcoin/bips/pull/905"

    seed = "57fb1e450b8afb95c62afbcd49e4100d6790e0822b8905608679180ac34ca0bd45bf7ccc6c5f5218236d0eb93afc78bd117b9f02a6b7df258ea182dfaef5aad7"
    xroot = rootxprv_from_seed(seed)
    der_path = "m/44H/60H/0H"
    xprv = "xprv9yqXG1Cns3YEQi6fsCJ7NGV5sHPiyZcbgLVst61dbLYyn7qy1G9aFtRmaYp481ounqnVf9Go2ymQ4gmxZLEwYSRhU868aDk4ZxzGvqHJVhe"
    assert derive(xroot, der_path) == xprv
    xpub = "xpub6CpsfWjghR6XdCB8yDq7jQRpRKEDP2LT3ZRUgURF9g5xevB7YoTpogkFRqq5nQtVSN8YCMZo2CD8u4zCaxRv85ctCWmzEi9gQ5DBhBFaTNo"
    assert xpub_from_xprv(xprv) == xpub
Exemple #5
0
def test_bip32_vectors() -> None:
    """BIP32 test vectors

    https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki
    """
    filename = path.join(data_folder, "bip32_test_vectors.json")
    with open(filename, "r") as file_:
        test_vectors = json.load(file_)

    for seed in test_vectors:
        mxprv = rootxprv_from_seed(seed)
        for der_path, xpub, xprv in test_vectors[seed]:
            assert xprv == derive(mxprv, der_path)
            assert xpub == xpub_from_xprv(xprv)
Exemple #6
0
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 = b58.wif_from_prv_key(xprv)
    assert wif == "L2L1dqRmkmVtwStNf5wg8nnGaRn3buoQr721XShM4VwDbTcn9bpm"
    pub_key, _ = pub_keyinfo_from_prv_key(wif)
    address = b58.p2pkh(pub_key)
    xpub = bip32.xpub_from_xprv(xprv)
    assert address == slip132.address_from_xpub(xpub)

    err_msg = "not a private key: "
    with pytest.raises(BTClibValueError, match=err_msg):
        b58.wif_from_prv_key(xpub)
Exemple #7
0
def test_derive_from_account() -> None:

    seed = "bfc4cbaad0ff131aa97fa30a48d09ae7df914bcc083af1e07793cd0a7c61a03f65d622848209ad3366a419f4718a80ec9037df107d8d12c19b83202de00a40ad"
    rmxprv = rootxprv_from_seed(seed)

    der_path = "m / 44 h / 0 h"
    mxpub = xpub_from_xprv(derive(rmxprv, der_path))

    test_vectors = [
        [0, 0],
        [0, 1],
        [0, 2],
        [1, 0],
        [1, 1],
        [1, 2],
    ]

    for branch, index in test_vectors:
        full_path = der_path + f"/{branch}/{index}"
        addr = p2pkh(derive(rmxprv, full_path))
        assert addr == p2pkh(derive_from_account(mxpub, branch, index))

    err_msg = "invalid private derivation at branch level"
    with pytest.raises(BTClibValueError, match=err_msg):
        derive_from_account(mxpub, 0x80000000, 0, True)

    err_msg = "too high branch: "
    with pytest.raises(BTClibValueError, match=err_msg):
        derive_from_account(mxpub, 0xFFFF + 1, 0)

    err_msg = "invalid branch: "
    with pytest.raises(BTClibValueError, match=err_msg):
        derive_from_account(mxpub, 2, 0)

    err_msg = "invalid private derivation at address index level"
    with pytest.raises(BTClibValueError, match=err_msg):
        derive_from_account(mxpub, 0, 0x80000000)

    err_msg = "too high address index: "
    with pytest.raises(BTClibValueError, match=err_msg):
        derive_from_account(mxpub, 0, 0xFFFF + 1)

    der_path = "m / 44 h / 0"
    mxpub = xpub_from_xprv(derive(rmxprv, der_path))
    err_msg = "unhardened account/master key"
    with pytest.raises(BTClibValueError, match=err_msg):
        derive_from_account(mxpub, 0, 0)
Exemple #8
0
def test_vectors() -> None:
    """BIP39 test vectors

    https://github.com/trezor/python-mnemonic/blob/master/vectors.json
    """
    fname = "bip39_test_vectors.json"
    filename = path.join(path.dirname(__file__), "_data", fname)
    with open(filename, "r", encoding="ascii") as file_:
        bip39_test_vectors = json.load(file_)["english"]

    lang = "en"
    for entr, mnemonic, seed, xprv in bip39_test_vectors:
        entropy = bytes.fromhex(entr)
        # clean up mnemonic from spurious whitespaces
        mnemonic = " ".join(mnemonic.split())
        assert mnemonic == bip39.mnemonic_from_entropy(entropy, lang)
        assert seed == bip39.seed_from_mnemonic(mnemonic, "TREZOR").hex()

        raw_entr = bip39.entropy_from_mnemonic(mnemonic, lang)
        size = (len(raw_entr) + 7) // 8
        assert entropy == int(raw_entr, 2).to_bytes(size, byteorder="big", signed=False)
        assert bip32.rootxprv_from_seed(seed) == xprv
Exemple #9
0
def test_exceptions() -> None:

    with pytest.raises(BTClibValueError, match="not a private or public key: "):
        # invalid checksum
        xprv = "xppp9s21ZrQH143K2oxHiQ5f7D7WYgXD9h6HAXDBuMoozDGGiYHWsq7TLBj2yvGuHTLSPCaFmUyN1v3fJRiY2A4YuNSrqQMPVLZKt76goL6LP7L"
        p2pkh(xprv)

    with pytest.raises(BTClibValueError, match="not a private key: "):
        xpub = "xpub6H1LXWLaKsWFhvm6RVpEL9P4KfRZSW7abD2ttkWP3SSQvnyA8FSVqNTEcYFgJS2UaFcxupHiYkro49S8yGasTvXEYBVPamhGW6cFJodrTHy"
        xpub_from_xprv(xpub)

    seed = "5b56c417303faa3fcba7e57400e120a0"
    with pytest.raises(BTClibValueError, match="unknown extended key version: "):
        version = b"\x04\x88\xAD\xE5"
        rootxprv_from_seed(seed, version)

    with pytest.raises(BTClibValueError, match="too many bits for seed: "):
        rootxprv_from_seed(seed * 5)

    with pytest.raises(BTClibValueError, match="too few bits for seed: "):
        rootxprv_from_seed(seed[:-2])