def test_is_xpublic_key_valid():
    assert is_xpublic_key_valid(
        decode_base58(
            "xpub68isDcaF29MCeYMdJ6ZypmjogsM6bgx3ssCZyRyT4JYqPZcSkEQtK"
            "x6ag1FHnirP8tz9VNAn7cuJhBKf63ijyw1FPg2Po36TcuX725Mom1X",
            checksum=True)) == True
    assert is_xpublic_key_valid(
        "tpubD6NzVbkrYhZ4YcS4zgyPcMzewmEkQ7CLs47HxSvAQ8AbH5wuJakF"
        "pxHwNyXDSmSDzNQmkKx2unk3xTDNN716cAKbgr6CyPm3hsAW4CqPVK2") == True
    assert is_xpublic_key_valid(
        "ypub6TZ8XHFAAptgVqYk8TMc2rqJrqVYYJwYnyinkpsLSJviSfRfzta"
        "Sx1kihDCsndWJYY6xEqmLaHFraTwDok8knAgrG1ipNwuwtdakQibcvzB") == True
    assert is_xpublic_key_valid(
        "upub57Wa4MvRPNyAivfs3RdRnBNn6jhkarina5xLFiBMvCH4NVqWUPQU"
        "pKeh5KZfvYXDyYXStKeUzhrMcQt4p9upL1pW2EFdY8eMJjPA8UKuxaL") == True
    assert is_xpublic_key_valid(
        "zpub6nPPpwv5KWSAM8jrxp9EEwvp2odzUvw3i6F1YDmDpKJbVmEuFYk"
        "1a5QriRATnYADxBDkzKMu2wcQTkYnXSYmaQNT8MRExrjSAMePoDv2d2R") == True
    assert is_xpublic_key_valid(
        "vpub5SLqN2bLY4WeaDrysnR3zGUHGhrCXUiHVCUZ375FJCewRbejj3a3"
        "SPJq6XXFvTB9PBeFdoF3TNCuVhVdXrKq8FW6tZx483TqaTSoWx3U88j") == True
    assert is_xpublic_key_valid(
        decode_base58(
            "vpuc5SLqN2bLY4WeaDrysnR3zGUHGhrCXUiHVCUZ375FJCewRbejj3a3"
            "SPJq6XXFvTB9PBeFdoF3TNCuVhVdXrKq8FW6tZx483TqaTSoWx3U88j",
            checksum=True)) == False
    assert is_xpublic_key_valid(
        "qpub5SLqN2bLY4WeaDrysnR3zGUHGhrCXUiHVCUZ375FJCewRbejj3a3SPJq6XXFvTB9PBeFdoF3TNCuVhVdXrKq8FW6tZx483TqaTSoWx3U88j"
    ) == False
    assert is_xpublic_key_valid("") == False
    assert is_xpublic_key_valid("1212qsdbfnn,i;p/") == False
def test_derive_xkey():
    root = "xprv9s21ZrQH143K39fFeGf2cWBTZ6NVj6ZsQ7nEK9f5pWqt4YwHPhnC" \
           "F3GtMsPNA9cCz1j8j9Zs493ejkzJqUWqwGqQ2J8iNc1jFtFPbie7bZ4"
    assert derive_xkey(decode_base58(root, checksum=True), "m/0") == "xprv9v7aNJTyjf9pZ2e1XwaKwTaiYqmwy9C43GPrczk9NauP4aWYqeKh" \
                                       "5UfE3ocfV92UGFKBbQNZib8TDtqD8y5axYQMUzVJzHXphdNF6Cc6YM3"
    assert derive_xkey(root, decode_path("m/0")) == "xprv9v7aNJTyjf9pZ2e1XwaKwTaiYqmwy9C43GPrczk9NauP4aWYqeKh" \
                                                    "5UfE3ocfV92UGFKBbQNZib8TDtqD8y5axYQMUzVJzHXphdNF6Cc6YM3"
    assert derive_xkey(root, "m/0'") == "xprv9v7aNJU85KgnkrGKiEJMTnZJMSpbAvQdcUGm2q4s7Z2ZPA9iTwNd" \
                                       "D92ESDXbxLt6WAsjaT5xHQNNgHBmwjgwscmPjE1dDuQ5rVC9Jowgu8q"
    assert derive_xkey(root, "m/1") == "xprv9v7aNJTyjf9pazc9j5X7CkK3t4ywxLzsWazZL9x8JE1f8f7dsv6" \
                                        "xjtWEZN2cahUYqaEkr27oyGfc7Y8KG18B55j7h57W3SdiAvXcztzB7MV"
    assert derive_xkey(root, "m/44'/0'/0'", base58=True) == "xprv9zAN5JC2upM319x3bsP9aa1jbE9MoyXNuSkm9rTggLBgUSHwsvigCr" \
                                               "wb3VJHpkb5KLteb9jwCpXnk7kS5ac3Av8Vn5UG2PgTdrxb9wPeipW"
    assert derive_xkey(root, "m/44'/0'/1'") == "xprv9zAN5JC2upM355bhe2xJWyzEVg7SD15PxVkN6FWPTjFPAkKoNoxPm" \
                                               "xvC76SK6k7HDc1WQhYaXYyEUTTuVLYbKomAna5pFbDJCMVzfKHfZUS"
    pub = "xpub6D9iUoivkBuLHZgAk4VJt7vy3hwvcToFKifxtdv124nN3YewvMGeKmE" \
          "fxLVZFLTCzQLS9NBwUzFVi66w5YnHM5o3y9GwQJSfroev539tkUZ"
    assert derive_xkey(pub, "m/0", hex=True) == decode_base58("xpub6FPUvcox6BxqQCt2GRHTdy5ehEKr3JRX1DjZTUutrRh8VsWNS6tfNZd5ZctuDZhm5d" \
                                      "RdepkwBgz77p8dVmNuMbBifts556S6jy3gERc3Tfy", checksum= True).hex()
    assert derive_xkey(pub, "m/0", hex=False) == decode_base58("xpub6FPUvcox6BxqQCt2GRHTdy5ehEKr3JRX1DjZTUutrRh8VsWNS6tfNZd5ZctuDZhm5d" \
                                      "RdepkwBgz77p8dVmNuMbBifts556S6jy3gERc3Tfy", checksum= True)
    assert derive_xkey(pub, "m/0/3/4") == "xpub6J7BeAMm9AYT56iBvZ8ceMksXimevjhcV9yCWM7UdkFZXWDvNHb7qLkFwwewtZp" \
                                          "8bVKhsqZfHfvZN6KpT59BuQy4e93pP3AoXk8uzCu8aPJ"
    with pytest.raises(ValueError):
        derive_xkey("xprq9s21ZrQH143K39fFeGf2cWBTZ6NVj6ZsQ7nEK9f5pWqt4YwHPhnC" \
                    "F3GtMsPNA9cCz1j8j9Zs493ejkzJqUWqwGqQ2J8iNc1jFtFPbie7bZ4", "m/0'")
def test_xprivate_to_xpublic_key():
    m = "debate pattern hotel silly grit must bronze athlete kitten salute salmon cat control hungry little"
    seed = mnemonic_to_seed(m)
    xPriv = create_master_xprivate_key(seed, hex=True)
    xp = "xpub661MyMwAqRbcFRtq6C9uK3bk7pmqc5ahhqDjxx6dfge6njx6jU9EhFwpLf" \
         "iE6tQv8gjuez5PkQfxTZw4UUwwkut34JRYLWpJLNGPcUCGxj8"
    assert xp == xprivate_to_xpublic_key(xPriv)
    xPriv = create_master_xprivate_key(seed)
    assert xp == xprivate_to_xpublic_key(xPriv)
    xp = "xpub661iyMwAqRbcFRtq6C9uK3bk7pmqc5ahhqDjxx6dfge6njx6jU9EhFwpLf" \
         "iE6tQv8gjuez5PkQfxTZw4UUwwkut34JRYLWpJLNGPcUCGxj8"
    with pytest.raises(ValueError):
        xprivate_to_xpublic_key(xp)
    with pytest.raises(TypeError):
        xprivate_to_xpublic_key(5656)

    p = "0488adez000000000000000000591dc86e17ddeda60b0bcbd4ada7ded84009c979d7a6c90e19106a51420b08d900a5" \
        "595efba1a78dade67a53672ae52f2855e513b1bbc7381195e77ce6800da7f0"
    with pytest.raises(ValueError):
        xprivate_to_xpublic_key(p)
    xPriv = "tprv8ZgxMBicQKsPf9QH73JoCxLYNjipEn1SHkWWfvsryrNCSbh8gBvfeTg5Crq" \
            "qTpsEQZFBUxH8NuQ5EJz8EDHC261tgtvnfBNze2Jteoxhi47"
    assert "tpubD6NzVbkrYhZ4YcS4zgyPcMzewmEkQ7CLs47HxSvAQ8AbH5wuJakFpxHwNyXD" \
           "SmSDzNQmkKx2unk3xTDNN716cAKbgr6CyPm3hsAW4CqPVK2" == xprivate_to_xpublic_key(xPriv)

    assert decode_base58("tpubD6NzVbkrYhZ4YcS4zgyPcMzewmEkQ7CLs47HxSvAQ8AbH5wuJakFpxHwNyXD" \
                         "SmSDzNQmkKx2unk3xTDNN716cAKbgr6CyPm3hsAW4CqPVK2",
                         checksum=True).hex() == xprivate_to_xpublic_key(xPriv, hex=True)

    assert decode_base58("tpubD6NzVbkrYhZ4YcS4zgyPcMzewmEkQ7CLs47HxSvAQ8AbH5wuJakFpxHwNyXD" \
                         "SmSDzNQmkKx2unk3xTDNN716cAKbgr6CyPm3hsAW4CqPVK2",
                         checksum=True) == xprivate_to_xpublic_key(xPriv, base58=False, hex=False)
def test_derive_child_xpublic_key():
    xpub = "xpub661MyMwAqRbcFgWfEhiJneL1x2YcwTqMMvpx54rbY3oXsPvMLJnUZo8tsxpGFsUrFW" \
            "9zMFKAGzaDDy1pR2uoohh1CW24Se1vkSnXRMqPV9R"
    assert "xpub68weA6at5vJ4Mzrpr7a6ZUvSkusBWEQLnFpgXMY1EWHNNpHgkSnX6HJwwSjN7z" \
           "9PFrgTLK6gtWZ37o3b2ZAQSc4V9GdxdjVTjymSVit5Sai"  == \
           encode_base58(derive_child_xpublic_key(decode_base58(xpub, checksum=True), 0), checksum=True)


    assert "xpub68weA6at5vJ5fuUhS2bUgtse4cswz9VpU3UJAY93oUwpP8P4oDhTtGKizXsosJH99RWnnyD9txQ" \
           "XBAcyAEiykRDAoyHLCcpW2vkrnsSymDQ"   == \
           encode_base58(derive_child_xpublic_key(decode_base58(xpub, checksum=True), 30), checksum=True)

    with pytest.raises(ValueError):
        derive_child_xpublic_key(decode_base58(xpub, checksum=True),
                                 30 | 0x80000000)
Exemple #5
0
def private_to_public_key(private_key, compressed=True, hex=True):
    """
    Get public key from private key using ECDSA secp256k1

    :param private_key: private key in WIF, HEX or bytes.
    :param compressed: (optional) flag of public key compressed format, by default set to True.
                       In case private_key in WIF format, this flag is set in accordance with 
                       the key format specified in WIF string.
    :param hex:  (optional) if set to True return key in HEX format, by default is True.
    :return: 33/65 bytes public key in HEX or bytes string.
    """
    if not isinstance(private_key, bytes):
        if isinstance(private_key, bytearray):
            private_key = bytes(private_key)
        elif isinstance(private_key, str):
            try:
                if private_key[0] in (MAINNET_PRIVATE_KEY_UNCOMPRESSED_PREFIX,
                                      TESTNET_PRIVATE_KEY_UNCOMPRESSED_PREFIX):
                    compressed = False
                h = decode_base58(private_key)
                if double_sha256(h[:-4])[:4] != h[-4:]:
                    raise Exception()
                private_key = h[1:33]
            except:
                try:
                    private_key = bytes_from_hex(private_key)
                except:
                    raise ValueError("private key HEX or WIF invalid")
        else:
            raise ValueError("private key must be a bytes or WIF or hex encoded string")
        if len(private_key) != 32:
            raise ValueError("private key length invalid")
    pub = __secp256k1_ec_pubkey_create__(private_key, bool(compressed))
    return pub.hex() if hex else pub
def test_is_xprivate_key_valid():
    assert is_xprivate_key_valid(
        decode_base58(
            "xprv9xPgprbtHAtyKqFegHcy7WoUJ7tTsrL3D36Zf4LcXCCNEWfszpQR"
            "eMWMdSpjE9qosHonUirqo418nd6vG46yi34nbHQ8wvWjLLjzMBFKNqM",
            checksum=True)) == True
    assert is_xprivate_key_valid(
        "tprv8ZgxMBicQKsPf9QH73JoCxLYNjipEn1SHkWWfvsryrNCSbh8gBv"
        "feTg5CrqqTpsEQZFBUxH8NuQ5EJz8EDHC261tgtvnfBNze2Jteoxhi47") == True
    assert is_xprivate_key_valid(
        "yprvAJXHiBz6oBHZouVo25rgayS7ss1FGAkAsPMrtpTX7DrAHqocTrus"
        "QmMNuA2VoJyxJ9jsfAQFRFoRrDFKAhNoVgvhLYSZ5LWqQJy7fYUzRW8") == True
    assert is_xprivate_key_valid(
        "uprv8tXDerPXZ1QsWSbPwQ6RR3S3YhsGBPzwCs2jTKmkMrk5VhWMvr6"
        "EGXLDE4oRTjX9pCMzERsgqZkd7bbgwuhCpKhVZEdDF6CUukNY3RLytkD") == True
    assert is_xprivate_key_valid(
        "zprvAc4DSBwiaXyw2RdtM1CDXgzUe4BMm6K33G91Dr8PHCx8LiJLW8jY"
        "tUpdfrjuDy9ega3Pyg3xiNiEZCL3hSw1JWRzKxnz7k9hsnsH8R1Ckwk") == True
    assert is_xprivate_key_valid(
        "vprv9DMUxX4ShgxMMjnWmkt3d8XYig1i81zS7yYxEifdjs7xYoKbBWF"
        "ntazMFGm1TeB5DqUnyuUFJE7AztDFfc7DcZP6RaKdq11yBUSBRvwZLXe") == True
    assert is_xprivate_key_valid(
        "qprv9DMUxX4ShgxMMjnWmkt3d8XYig1i81zS7yYxEifdjs7xYoKbBWFn"
        "tazMFGm1TeB5DqUnyuUFJE7AztDFfc7DcZP6RaKdq11yBUSBRvwZLXe") == False
    assert is_xprivate_key_valid("") == False
    assert is_xprivate_key_valid("1212qsdbfnn,i;p/") == False
Exemple #7
0
def is_wif_valid(wif):
    """
    Check is private key in WIF format string is valid.

    :param wif: private key in WIF format string.
    :return: boolean.
    """
    if not isinstance(wif, str):
        raise TypeError("invalid wif key")
    if wif[0] not in PRIVATE_KEY_PREFIX_LIST:
        return False
    try:
        h = decode_base58(wif)
    except:
        return False
    checksum = h[-4:]
    if wif[0] in (MAINNET_PRIVATE_KEY_UNCOMPRESSED_PREFIX,
                  TESTNET_PRIVATE_KEY_UNCOMPRESSED_PREFIX):
        if len(h) != 37:
            return False
    elif len(h) != 38:
        return False
    if double_sha256(h[:-4])[:4] != checksum:
        return False
    return True
Exemple #8
0
def is_xpublic_key_valid(key):
    """
    Check the extended private key is valid according to BIP-0032.

    :param key: extended private key in BASE58, HEX or bytes string format.
    :return: boolean.
    """
    if isinstance(key, str):
        try:
            key = decode_base58(key, verify_checksum=True)
        except:
            try:
                key = bytes.fromhex(key)
            except:
                pass
    if not isinstance(key, bytes) or len(key) != 78:
        return False

    if key[:4] not in [
            MAINNET_XPUBLIC_KEY_PREFIX, TESTNET_XPUBLIC_KEY_PREFIX,
            MAINNET_M49_XPUBLIC_KEY_PREFIX, TESTNET_M49_XPUBLIC_KEY_PREFIX,
            MAINNET_M84_XPUBLIC_KEY_PREFIX, TESTNET_M84_XPUBLIC_KEY_PREFIX
    ]:
        return False
    return True
def test_create_master_xprivate_key():
    e = "6afd4fd96ca02d0b7038429b77e8b32042fc205d031144054086130e8d83d981"
    xp = "xprv9s21ZrQH143K4LAkSUTJ3JiZ4cJc1FyRxCbPoWTQVssiezx3gpav8iJdHgg" \
         "BTTUv37iQUrfNDYpGmTSP6zwFD2kJAFiUzpewivZUD6Jqdai"
    assert xp == create_master_xprivate_key(
        mnemonic_to_seed(entropy_to_mnemonic(e)))
    assert decode_base58(xp, checksum=True) == create_master_xprivate_key(
        mnemonic_to_seed(entropy_to_mnemonic(e)), base58=False)
def test_public_from_xpublic_key():
    pub = "xpub6BP3EN8n7YTGYKL7nK9yUekCr9ixHK3taG2ATSkE5XjM7K12YMigC9pqUhj" \
          "2K2f4TRg8xvDfqpHsWsjBHoMdJ6QF9dfSeKALRiTFAi9dA5T"
    assert public_from_xpublic_key(pub) == \
           "02832b4cd1990dc9ffb7624bdc33e19061836f237f5ccd8730777a10bfca88944c"

    assert public_from_xpublic_key(decode_base58(pub, checksum=True))== \
           "02832b4cd1990dc9ffb7624bdc33e19061836f237f5ccd8730777a10bfca88944c"

    assert public_from_xpublic_key(decode_base58(pub, checksum=True).hex())== \
           "02832b4cd1990dc9ffb7624bdc33e19061836f237f5ccd8730777a10bfca88944c"
    with pytest.raises(TypeError):
        public_from_xpublic_key(423432)
    pub = "xpus6BP3EN8n7YTGYKL7nK9yUekCr9ixHK3taG2ATSkE5XjM7K12YMigC9pqUhj" \
          "2K2f4TRg8xvDfqpHsWsjBHoMdJ6QF9dfSeKALRiTFAi9dA5T"
    with pytest.raises(ValueError):
        public_from_xpublic_key(pub)
Exemple #11
0
def bip32_xkey_to_path_xkey(key, path_type, base58=True, hex=False):
    if path_type not in ("BIP44", "BIP49", "BIP84"):
        raise ValueError("unsupported path type %s" % path_type)

    if isinstance(key, str):
        try:
            key = decode_base58(key, verify_checksum=True)
        except:
            try:
                key = bytes.fromhex(key)
            except:
                pass
    if not isinstance(key, bytes) or len(key) != 78:
        raise ValueError("invalid key")

    if key[:4] == TESTNET_XPRIVATE_KEY_PREFIX:
        if path_type == "BIP44":
            key = TESTNET_M44_XPRIVATE_KEY_PREFIX + key[4:]
        elif path_type == "BIP49":
            key = TESTNET_M49_XPRIVATE_KEY_PREFIX + key[4:]
        else:
            key = TESTNET_M84_XPRIVATE_KEY_PREFIX + key[4:]

    elif key[:4] == MAINNET_XPRIVATE_KEY_PREFIX:
        if path_type == "BIP44":
            key = MAINNET_M44_XPRIVATE_KEY_PREFIX + key[4:]
        elif path_type == "BIP49":
            key = MAINNET_M49_XPRIVATE_KEY_PREFIX + key[4:]
        else:
            key = MAINNET_M84_XPRIVATE_KEY_PREFIX + key[4:]

    elif key[:4] == TESTNET_XPUBLIC_KEY_PREFIX:
        if path_type == "BIP44":
            key = TESTNET_M44_XPUBLIC_KEY_PREFIX + key[4:]
        elif path_type == "BIP49":
            key = TESTNET_M49_XPUBLIC_KEY_PREFIX + key[4:]
        else:
            key = TESTNET_M84_XPUBLIC_KEY_PREFIX + key[4:]

    elif key[:4] == MAINNET_XPUBLIC_KEY_PREFIX:
        if path_type == "BIP44":
            key = MAINNET_M44_XPUBLIC_KEY_PREFIX + key[4:]
        elif path_type == "BIP49":
            key = MAINNET_M49_XPUBLIC_KEY_PREFIX + key[4:]
        else:
            key = MAINNET_M84_XPUBLIC_KEY_PREFIX + key[4:]
    else:
        raise ValueError("invalid extended key")

    if hex:

        return key.hex()
    elif base58:
        return encode_base58(key, checksum=True)
    else:
        return key
def test_derive_child_xprivate_key():
    xpriv = "xprv9s21ZrQH143K3CSC8gBJRWPHPzi8Y17VzhuMGgSyyiGYzbbCnmUE1zpR2iQCz" \
            "VGPGAQBy2m7LTEtPAvfB6p2ECoQBAWtQYgYHpn1UFQv6Mi"
    assert "xprv9uxHkb3zFYjmC9AshDxocSv8SWphDkWq7VpNauF8hhGNMuqK2o4AKhhhuFADy1H5pVVAdZJCnyDmjZBZm" \
           "gUR8aciXXELWfU6tCF4BCrhz5m" == \
           encode_base58(derive_child_xprivate_key(decode_base58(xpriv, checksum=True), 1), checksum=True)


    assert "xprv9uxHkb3zFYjm9WnMk636CLyiCt2h6mgVR2u5iy8PgAkPW1xYCuUGYUzU6A4HWS7hDhKVQufiymoj9oYjqg" \
           "1h7331YjwVTfSBN97gSo65DiV"  == \
           encode_base58(derive_child_xprivate_key(decode_base58(xpriv, checksum=True), 0), checksum=True)

    assert "xprv9uxHkb3zFYzv3TK97XAQ5YykGBuFgMo5mKzjvQKuzbPf3FBeVgTC2ozTtspLBU2X4HWWFDocpB1sHjSX" \
           "Jby89m6cKhLhWUdhUWdF4o39kw4"  == \
           encode_base58(derive_child_xprivate_key(decode_base58(xpriv, checksum=True), 20000), checksum=True)

    assert "xprv9uxHkb3zFzs4rMGo9d25NcHCyePGswYHY6fMk76DzbZ5iCucy7VtdjYa1o4n28bnnGLW4ComhMjNiUKx" \
           "bgq6p6vc9zwHfHb1fvdhAvsURty" == \
           encode_base58(derive_child_xprivate_key(decode_base58(xpriv, checksum=True), 2000000), checksum=True)
Exemple #13
0
def test_decode_base58():
    assert decode_base58("") == b""
    assert decode_base58("1Bitapsw1aT8hkLXFtXwZQfHgNwNJEyJJ1", True) == \
           "00759d5f2b6d12712fef6f0f24c56804193e1aeac176c1faae"
    assert decode_base58("1Bitapsw1aT8hkLXFtXwZQfHgNwNJEyJJ1", False).hex() == \
           "00759d5f2b6d12712fef6f0f24c56804193e1aeac176c1faae"
    assert decode_base58("1Bitapsw1aT8hkLXFtXwZQfHgNwNJEyJJ1", checksum=True).hex() == \
           "00759d5f2b6d12712fef6f0f24c56804193e1aeac1"
    assert decode_base58("1Bitapsw1aT8hkLXFtXwZQfHgNwNJEyJJ1", verify_checksum=True).hex() == \
           "00759d5f2b6d12712fef6f0f24c56804193e1aeac1"

    with pytest.raises(Exception):
        decode_base58("1Bitapsw1aT8hkLXFtXwZQfHgNwNJEyJJ2",
                      verify_checksum=True)
    with pytest.raises(Exception):
        decode_base58(876)
Exemple #14
0
def wif_to_private_key(h, hex=True):
    """
    Decode WIF private key to bytes string or HEX encoded string

    :param hex:  (optional) if set to True return key in HEX format, by default is True.
    :return: Private key HEX encoded string or raw bytes string.
    """
    if not is_wif_valid(h):
        raise TypeError("invalid wif key")
    h = decode_base58(h)
    return h[1:33].hex() if hex else h[1:33]
Exemple #15
0
def wif_to_private_key(h, hex=True):
    """
    Decode WIF private key to bytes string or HEX encoded string

    :param hex:  (optional) if set to True return key in HEX format, by default is True.
    :return: Private key HEX encoded string or raw bytes string.
    """
    h = decode_base58(h)
    if double_sha256(h[:-4])[:4] != h[-4:]:
        raise TypeError("invalid wif key")
    return h[1:33].hex() if hex else h[1:33]
def test_private_from_xprivate_key():
    priv = "xprv9xPgprbtHAtyKqFegHcy7WoUJ7tTsrL3D36Zf4LcXCCNEWfszpQReMWMdSpjE9qo" \
          "sHonUirqo418nd6vG46yi34nbHQ8wvWjLLjzMBFKNqM"
    assert private_from_xprivate_key(priv) == \
           "L2BfXTBFwabUYoGkXKeR34f3TBpcThLtnC8yf6ZURvM952x8sWmz"

    assert private_from_xprivate_key(decode_base58(priv, checksum=True))== \
           "L2BfXTBFwabUYoGkXKeR34f3TBpcThLtnC8yf6ZURvM952x8sWmz"

    assert private_from_xprivate_key(decode_base58(priv, checksum=True).hex(), hex=True)== \
           wif_to_private_key("L2BfXTBFwabUYoGkXKeR34f3TBpcThLtnC8yf6ZURvM952x8sWmz", hex=True)
    assert private_from_xprivate_key(decode_base58(priv, checksum=True).hex(), wif=False)== \
           wif_to_private_key("L2BfXTBFwabUYoGkXKeR34f3TBpcThLtnC8yf6ZURvM952x8sWmz", hex=False)
    with pytest.raises(TypeError):
        private_from_xprivate_key(423432)
    pub = "xpus6BP3EN8n7YTGYKL7nK9yUekCr9ixHK3taG2ATSkE5XjM7K12YMigC9pqUhj" \
          "2K2f4TRg8xvDfqpHsWsjBHoMdJ6QF9dfSeKALRiTFAi9dA5T"
    with pytest.raises(ValueError):
        private_from_xprivate_key(pub)

    priv = "tprv8ZgxMBicQKsPf9QH73JoCxLYNjipEn1SHkWWfvsryrNCSbh8gBvfeTg5Crqq" \
           "TpsEQZFBUxH8NuQ5EJz8EDHC261tgtvnfBNze2Jteoxhi47"
    assert private_from_xprivate_key(priv) == \
           "cNu63US2f9jLLwDeD9321q1S5xviXCxSyem2GkFJjcF8DTWxqteC"
Exemple #17
0
def xprivate_to_xpublic_key(xprivate_key, base58=True, hex=False):
    """
    Get extended public key from extended private key using ECDSA secp256k1

    :param str,bytes key: extended private key in base58, HEX or bytes string. 
    :param boolean base58: (optional) return result as base58 encoded string, by default True.
    :param boolean hex: (optional) return result as HEX encoded string, by default False.
                        In case True base58 flag value will be ignored.
    :return: extended public key  in base58, HEX or bytes string format.
    """
    if isinstance(xprivate_key, str):
        try:
            if len(xprivate_key) == 156:
                xprivate_key = bytes.fromhex(xprivate_key)
            else:
                xprivate_key = decode_base58(xprivate_key, checksum=True)
        except:
            raise ValueError("invalid extended private key")
    if not isinstance(xprivate_key, bytes):
        raise TypeError(
            "extended private key should be base58 string or bytes")
    if xprivate_key[:4] == TESTNET_XPRIVATE_KEY_PREFIX:
        prefix = TESTNET_XPUBLIC_KEY_PREFIX
    elif xprivate_key[:4] == MAINNET_XPRIVATE_KEY_PREFIX:
        prefix = MAINNET_XPUBLIC_KEY_PREFIX
    elif xprivate_key[:4] == MAINNET_M49_XPRIVATE_KEY_PREFIX:
        prefix = MAINNET_M49_XPUBLIC_KEY_PREFIX
    elif xprivate_key[:4] == TESTNET_M49_XPRIVATE_KEY_PREFIX:
        prefix = TESTNET_M49_XPUBLIC_KEY_PREFIX
    elif xprivate_key[:4] == MAINNET_M84_XPRIVATE_KEY_PREFIX:
        prefix = MAINNET_M84_XPUBLIC_KEY_PREFIX
    elif xprivate_key[:4] == TESTNET_M84_XPRIVATE_KEY_PREFIX:
        prefix = TESTNET_M84_XPUBLIC_KEY_PREFIX
    else:
        raise ValueError("invalid extended private key")

    key = b"".join([
        prefix, xprivate_key[4:45],
        private_to_public_key(xprivate_key[46:], hex=False)
    ])
    if hex:
        return key.hex()
    elif base58:
        key = b"".join([key, double_sha256(key)[:4]])
        return encode_base58(key)
    else:
        return key
Exemple #18
0
def address_to_hash(address, hex=True):
    """
    Get address hash from base58 or bech32 address format.

    :param address: address in base58 or bech32 format.
    :param hex:  (optional) If set to True return key in HEX format, by default is True.
    :return: script in HEX or bytes string.
    """
    if address[0] in ADDRESS_PREFIX_LIST:
        h = decode_base58(address)[1:-4]
    elif address.split("1")[0] in (MAINNET_SEGWIT_ADDRESS_PREFIX,
                                   TESTNET_SEGWIT_ADDRESS_PREFIX):
        address = address.split("1")[1]
        h = rebase_5_to_8(rebase_32_to_5(address)[1:-6], False)
    else:
        return None
    return h.hex() if hex else h
Exemple #19
0
def xkey_type(key):
    if isinstance(key, str):
        key = decode_base58(key, checksum=True)
    if len(key) != 78:
        raise Exception("invalid extended key")
    prefix = key[:4]
    if prefix in (MAINNET_XPRIVATE_KEY_PREFIX, MAINNET_M49_XPRIVATE_KEY_PREFIX,
                  MAINNET_M84_XPRIVATE_KEY_PREFIX, TESTNET_XPRIVATE_KEY_PREFIX,
                  TESTNET_M49_XPRIVATE_KEY_PREFIX,
                  TESTNET_M84_XPRIVATE_KEY_PREFIX):
        return "private"
    if prefix in (MAINNET_XPUBLIC_KEY_PREFIX, MAINNET_M49_XPUBLIC_KEY_PREFIX,
                  MAINNET_M84_XPUBLIC_KEY_PREFIX, TESTNET_XPUBLIC_KEY_PREFIX,
                  TESTNET_M49_XPUBLIC_KEY_PREFIX,
                  TESTNET_M84_XPUBLIC_KEY_PREFIX):
        return "public"
    raise ValueError("invalid extended key")
Exemple #20
0
def xkey_network_type(key):
    if isinstance(key, str):
        key = decode_base58(key, checksum=True)
    if len(key) != 78:
        raise Exception("invalid extended key")
    prefix = key[:4]
    if prefix in (MAINNET_XPRIVATE_KEY_PREFIX, MAINNET_M49_XPRIVATE_KEY_PREFIX,
                  MAINNET_M84_XPRIVATE_KEY_PREFIX, MAINNET_XPUBLIC_KEY_PREFIX,
                  MAINNET_M49_XPUBLIC_KEY_PREFIX,
                  MAINNET_M84_XPUBLIC_KEY_PREFIX):
        return "mainnet"
    if prefix in (TESTNET_XPRIVATE_KEY_PREFIX, TESTNET_M49_XPRIVATE_KEY_PREFIX,
                  TESTNET_M84_XPRIVATE_KEY_PREFIX, TESTNET_XPUBLIC_KEY_PREFIX,
                  TESTNET_M49_XPUBLIC_KEY_PREFIX,
                  TESTNET_M84_XPUBLIC_KEY_PREFIX):
        return "testnet"
    raise Exception("invalid extended key")
Exemple #21
0
def xkey_derivation_type(key):
    if isinstance(key, str):
        key = decode_base58(key, checksum=True)
    if len(key) != 78:
        return False
    prefix = key[:4]
    if prefix in (MAINNET_XPRIVATE_KEY_PREFIX, TESTNET_XPRIVATE_KEY_PREFIX,
                  MAINNET_XPUBLIC_KEY_PREFIX, TESTNET_XPUBLIC_KEY_PREFIX):
        return "BIP44"
    if prefix in (MAINNET_M49_XPRIVATE_KEY_PREFIX,
                  TESTNET_M49_XPRIVATE_KEY_PREFIX,
                  MAINNET_M49_XPUBLIC_KEY_PREFIX,
                  TESTNET_M49_XPUBLIC_KEY_PREFIX):
        return "BIP49"
    if prefix in (MAINNET_M84_XPRIVATE_KEY_PREFIX,
                  TESTNET_M84_XPRIVATE_KEY_PREFIX,
                  MAINNET_M84_XPUBLIC_KEY_PREFIX,
                  TESTNET_M84_XPUBLIC_KEY_PREFIX):
        return "BIP84"
    return "custom"
Exemple #22
0
def public_from_xpublic_key(xpublic_key, hex=True):
    """
    Get public key from extended public key

    :param bytes xpublic_key: extended public in base58, HEX or bytes string format.
    :param boolean base58: (optional) return result as base58 encoded string, by default True.
    :param boolean hex: (optional) return result as HEX encoded string, by default False.
                        In case True base58 flag value will be ignored.
    :return: public key  in HEX or bytes string format.
    """
    if isinstance(xpublic_key, str):
        if len(xpublic_key) == 156:
            xpublic_key = bytes.fromhex(xpublic_key)
        else:
            xpublic_key = decode_base58(xpublic_key, checksum=True)
    if not isinstance(xpublic_key, bytes):
        raise TypeError("xpublic_key should be HEX, Base58 or bytes string")
    if xpublic_key[:4] not in [
            MAINNET_XPUBLIC_KEY_PREFIX, TESTNET_XPUBLIC_KEY_PREFIX
    ]:
        raise ValueError("invalid extended public key")

    return xpublic_key[45:].hex() if hex else xpublic_key[45:]
Exemple #23
0
def path_xkey_to_bip32_xkey(key, base58=True, hex=False):
    if isinstance(key, str):
        try:
            key = decode_base58(key, verify_checksum=True)
        except:
            try:
                key = bytes.fromhex(key)
            except:
                pass

    if not isinstance(key, bytes) or len(key) != 78:
        raise ValueError("invalid extended key")

    if key[:4] in (MAINNET_XPUBLIC_KEY_PREFIX, TESTNET_XPUBLIC_KEY_PREFIX,
                   MAINNET_XPRIVATE_KEY_PREFIX, TESTNET_XPRIVATE_KEY_PREFIX):
        pass
    elif key[:4] in (MAINNET_M49_XPUBLIC_KEY_PREFIX,
                     MAINNET_M84_XPUBLIC_KEY_PREFIX):
        key = MAINNET_XPUBLIC_KEY_PREFIX + key[4:]
    elif key[:4] in (TESTNET_M49_XPUBLIC_KEY_PREFIX,
                     TESTNET_M84_XPUBLIC_KEY_PREFIX):
        key = TESTNET_XPUBLIC_KEY_PREFIX + key[4:]
    elif key[:4] in (MAINNET_M49_XPRIVATE_KEY_PREFIX,
                     MAINNET_M84_XPRIVATE_KEY_PREFIX):
        key = MAINNET_XPRIVATE_KEY_PREFIX + key[4:]
    elif key[:4] in (TESTNET_M49_XPRIVATE_KEY_PREFIX,
                     TESTNET_M84_XPRIVATE_KEY_PREFIX):
        key = TESTNET_XPRIVATE_KEY_PREFIX + key[4:]
    else:
        raise ValueError("invalid extended key")

    if hex:
        return key.hex()
    elif base58:
        return encode_base58(key, checksum=True)
    else:
        return key
Exemple #24
0
def derive_xkey(xkey, path, base58=None, hex=None, sub_path=False):
    """
    Child Key derivation for extended private/public keys
    
    :param bytes xkey: extended private/public in base58, HEX or bytes string format.
    :param list path_level: list of derivation path levels. For hardened derivation use HARDENED_KEY flag.
    :param boolean base58: (optional) return result as base58 encoded string, by default True.
    :param boolean hex: (optional) return result as HEX encoded string, by default False.
                        In case True base58 flag value will be ignored.
    :return: extended child private/public key  in base58, HEX or bytes string format.
    """
    if isinstance(path, str):
        path = decode_path(path, sub_path=sub_path)
    if isinstance(xkey, str):
        xkey = decode_base58(xkey, checksum=True)
    key_type = xkey_type(xkey)

    if key_type == 'private':
        for i in path:
            xkey = derive_child_xprivate_key(xkey, i)

    elif key_type == 'public':
        for i in path:
            xkey = derive_child_xpublic_key(xkey, i)
    else:
        raise ValueError("invalid extended key")

    if base58 is None and hex is None:
        base58 = True
        hex = False

    if hex:
        return xkey.hex()
    elif base58:
        return encode_base58(xkey, checksum=True)
    else:
        return xkey
Exemple #25
0
def private_from_xprivate_key(xprivate_key, wif=True, hex=False):
    """
    Get private key from extended private key

    :param bytes xprivate_key: extended public in base58, HEX or bytes string format.
    :param boolean wif: (optional) return result as WIF format, by default True.
    :param boolean hex: (optional) return result as HEX encoded string, by default False.
                        In case True WIF flag value will be ignored.
    :return: private key  in HEX or bytes string format.
    """
    if isinstance(xprivate_key, str):
        if len(xprivate_key) == 156:
            xprivate_key = bytes.fromhex(xprivate_key)
        else:
            xprivate_key = decode_base58(xprivate_key, checksum=True)
    if not isinstance(xprivate_key, bytes):
        raise TypeError("xprivate_key should be HEX, Base58 or bytes string")

    prefix = xprivate_key[:4]

    if prefix in (MAINNET_XPRIVATE_KEY_PREFIX, MAINNET_M44_XPRIVATE_KEY_PREFIX,
                  MAINNET_M49_XPRIVATE_KEY_PREFIX,
                  MAINNET_M84_XPRIVATE_KEY_PREFIX):
        testnet = False
    elif prefix in (TESTNET_XPRIVATE_KEY_PREFIX,
                    TESTNET_M44_XPRIVATE_KEY_PREFIX,
                    TESTNET_M49_XPRIVATE_KEY_PREFIX,
                    TESTNET_M84_XPRIVATE_KEY_PREFIX):
        testnet = True
    else:
        raise ValueError("invalid extended private key")

    if hex:
        return xprivate_key[46:].hex()
    elif wif:
        return private_key_to_wif(xprivate_key[46:], testnet=testnet)
    return xprivate_key[46:].hex() if hex else xprivate_key[46:]
Exemple #26
0
def is_address_valid(address, testnet=False):
    """
    Check is address valid.

    :param address: address in base58 or bech32 format.
    :param testnet: (optional) flag for testnet network, by default is False.
    :return: boolean.
    """
    if not address or type(address) != str:
        return False
    if address[0] in (MAINNET_ADDRESS_PREFIX, MAINNET_SCRIPT_ADDRESS_PREFIX,
                      TESTNET_ADDRESS_PREFIX, TESTNET_ADDRESS_PREFIX_2,
                      TESTNET_SCRIPT_ADDRESS_PREFIX):
        if testnet:
            if address[0] not in (TESTNET_ADDRESS_PREFIX,
                                  TESTNET_ADDRESS_PREFIX_2,
                                  TESTNET_SCRIPT_ADDRESS_PREFIX):
                return False
        else:
            if address[0] not in (MAINNET_ADDRESS_PREFIX,
                                  MAINNET_SCRIPT_ADDRESS_PREFIX):
                return False
        h = decode_base58(address)
        if len(h) != 25:
            return False
        checksum = h[-4:]
        if double_sha256(h[:-4])[:4] != checksum:
            return False
        return True
    elif address[:2].lower() in (TESTNET_SEGWIT_ADDRESS_PREFIX,
                                 MAINNET_SEGWIT_ADDRESS_PREFIX):
        if len(address) not in (42, 62):
            return False
        try:
            prefix, payload = address.split('1')
        except:
            return False
        upp = True if prefix[0].isupper() else False
        for i in payload[1:]:
            if upp:
                if not i.isupper() or i not in base32charset_upcase:
                    return False
            else:
                if i.isupper() or i not in base32charset:
                    return False
        payload = payload.lower()
        prefix = prefix.lower()
        if testnet:
            if prefix != TESTNET_SEGWIT_ADDRESS_PREFIX:
                return False
            stripped_prefix = TESTNET_SEGWIT_ADDRESS_BYTE_PREFIX
        else:
            if prefix != MAINNET_SEGWIT_ADDRESS_PREFIX:
                return False
            stripped_prefix = MAINNET_SEGWIT_ADDRESS_BYTE_PREFIX
        d = rebase_32_to_5(payload)
        address_hash = d[:-6]
        checksum = d[-6:]
        checksum2 = bech32_polymod(
            b"%s%s%s" % (stripped_prefix, address_hash, b"\x00" * 6))
        checksum2 = rebase_8_to_5(checksum2.to_bytes(5, "big"))[2:]
        if checksum != checksum2:
            return False
        return True
def test_path_xkey_to_bip32_xkey():
    assert path_xkey_to_bip32_xkey(decode_base58("xpub68isDcaF29MCeYMdJ6ZypmjogsM6bgx3ssCZyRyT4JYqPZcS"
                                   "kEQtKx6ag1FHnirP8tz9VNAn7cuJhBKf63ijyw1FPg2Po36TcuX725Mom1X",
                                                 checksum=True)) == \
                                   "xpub68isDcaF29MCeYMdJ6ZypmjogsM6bgx3ssCZyRyT4JYqPZcSkE" \
                                   "QtKx6ag1FHnirP8tz9VNAn7cuJhBKf63ijyw1FPg2Po36TcuX725Mom1X"
    assert path_xkey_to_bip32_xkey(decode_base58("xpub68isDcaF29MCeYMdJ6ZypmjogsM6bgx3ssCZyRyT4JYqPZcS"
                                   "kEQtKx6ag1FHnirP8tz9VNAn7cuJhBKf63ijyw1FPg2Po36TcuX725Mom1X",
                                                 checksum=True).hex()) == \
                                   "xpub68isDcaF29MCeYMdJ6ZypmjogsM6bgx3ssCZyRyT4JYqPZcSkE" \
                                   "QtKx6ag1FHnirP8tz9VNAn7cuJhBKf63ijyw1FPg2Po36TcuX725Mom1X"

    with pytest.raises(ValueError):
        path_xkey_to_bip32_xkey("oeirfhoiwjefoiwe223")

    with pytest.raises(ValueError):
        path_xkey_to_bip32_xkey(
            decode_base58(
                "xpuw68isDcaF29MCeYMdJ6ZypmjogsM6bgx3ssCZyRyT4JYqPZcS"
                "kEQtKx6ag1FHnirP8tz9VNAn7cuJhBKf63ijyw1FPg2Po36TcuX725Mom1X",
                checksum=True).hex())

    assert path_xkey_to_bip32_xkey("tpubD6NzVbkrYhZ4YcS4zgyPcMzewmEkQ7CLs47HxSvAQ8AbH5wuJa"
                                   "kFpxHwNyXDSmSDzNQmkKx2unk3xTDNN716cAKbgr6CyPm3hsAW4CqPVK2") == \
                                   "tpubD6NzVbkrYhZ4YcS4zgyPcMzewmEkQ7CLs47HxSvAQ8AbH5wuJakFp" \
                                   "xHwNyXDSmSDzNQmkKx2unk3xTDNN716cAKbgr6CyPm3hsAW4CqPVK2"

    assert path_xkey_to_bip32_xkey("ypub6TZ8XHFAAptgVqYk8TMc2rqJrqVYYJwYnyinkpsLSJviSfRfztaS"
                                   "x1kihDCsndWJYY6xEqmLaHFraTwDok8knAgrG1ipNwuwtdakQibcvzB") == \
                                   "xpub68isDcaF29MCeYMdJ6ZypmjogsM6bgx3ssCZyRyT4JYqPZcSkEQt" \
                                   "Kx6ag1FHnirP8tz9VNAn7cuJhBKf63ijyw1FPg2Po36TcuX725Mom1X"

    assert path_xkey_to_bip32_xkey("upub57Wa4MvRPNyAivfs3RdRnBNn6jhkarina5xLFiBMvCH4NVqWUPQU"
                                   "pKeh5KZfvYXDyYXStKeUzhrMcQt4p9upL1pW2EFdY8eMJjPA8UKuxaL") == \
                                   "tpubD6NzVbkrYhZ4YcS4zgyPcMzewmEkQ7CLs47HxSvAQ8AbH5wuJakF" \
                                   "pxHwNyXDSmSDzNQmkKx2unk3xTDNN716cAKbgr6CyPm3hsAW4CqPVK2"

    assert path_xkey_to_bip32_xkey("zpub6nPPpwv5KWSAM8jrxp9EEwvp2odzUvw3i6F1YDmDpKJbVmEuFYk1"
                                   "a5QriRATnYADxBDkzKMu2wcQTkYnXSYmaQNT8MRExrjSAMePoDv2d2R") == \
                                   "xpub68isDcaF29MCeYMdJ6ZypmjogsM6bgx3ssCZyRyT4JYqPZcSkEQt" \
                                   "Kx6ag1FHnirP8tz9VNAn7cuJhBKf63ijyw1FPg2Po36TcuX725Mom1X"

    assert path_xkey_to_bip32_xkey("vpub5SLqN2bLY4WeaDrysnR3zGUHGhrCXUiHVCUZ375FJCewRbejj3a3"
                                   "SPJq6XXFvTB9PBeFdoF3TNCuVhVdXrKq8FW6tZx483TqaTSoWx3U88j") == \
                                   "tpubD6NzVbkrYhZ4YcS4zgyPcMzewmEkQ7CLs47HxSvAQ8AbH5wuJakF" \
                                   "pxHwNyXDSmSDzNQmkKx2unk3xTDNN716cAKbgr6CyPm3hsAW4CqPVK2"

    assert path_xkey_to_bip32_xkey("xprv9xPgprbtHAtyKqFegHcy7WoUJ7tTsrL3D36Zf4LcXCCNEWfszpQR"
                                   "eMWMdSpjE9qosHonUirqo418nd6vG46yi34nbHQ8wvWjLLjzMBFKNqM") == \
                                   "xprv9xPgprbtHAtyKqFegHcy7WoUJ7tTsrL3D36Zf4LcXCCNEWfszpQR" \
                                   "eMWMdSpjE9qosHonUirqo418nd6vG46yi34nbHQ8wvWjLLjzMBFKNqM"

    assert path_xkey_to_bip32_xkey("tprv8ZgxMBicQKsPf9QH73JoCxLYNjipEn1SHkWWfvsryrNCSbh8gBvf"
                                   "eTg5CrqqTpsEQZFBUxH8NuQ5EJz8EDHC261tgtvnfBNze2Jteoxhi47") == \
                                   "tprv8ZgxMBicQKsPf9QH73JoCxLYNjipEn1SHkWWfvsryrNCSbh8gBvfe" \
                                   "Tg5CrqqTpsEQZFBUxH8NuQ5EJz8EDHC261tgtvnfBNze2Jteoxhi47"

    assert path_xkey_to_bip32_xkey("yprvAJXHiBz6oBHZouVo25rgayS7ss1FGAkAsPMrtpTX7DrAHqocTrus"
                                   "QmMNuA2VoJyxJ9jsfAQFRFoRrDFKAhNoVgvhLYSZ5LWqQJy7fYUzRW8") == \
                                   "xprv9yh2QXKBeVk5xcJgBj54NtLchtroKYkfxGqe7RZdjDUHEjzPDCkJ" \
                                   "nhhEsx4uoQL2tWd4ugogxbSsxvdkSzxnhTF6UCk8VRhM8auUGwuyZMC"

    assert path_xkey_to_bip32_xkey("uprv8tXDerPXZ1QsWSbPwQ6RR3S3YhsGBPzwCs2jTKmkMrk5VhWMvr6E"
                                   "GXLDE4oRTjX9pCMzERsgqZkd7bbgwuhCpKhVZEdDF6CUukNY3RLytkD") == \
                                   "tprv8ZgxMBicQKsPf9QH73JoCxLYNjipEn1SHkWWfvsryrNCSbh8gBvfe" \
                                   "Tg5CrqqTpsEQZFBUxH8NuQ5EJz8EDHC261tgtvnfBNze2Jteoxhi47"

    assert path_xkey_to_bip32_xkey("zprvAc4DSBwiaXyw2RdtM1CDXgzUe4BMm6K33G91Dr8PHCx8LiJLW8jY"
                                   "tUpdfrjuDy9ega3Pyg3xiNiEZCL3hSw1JWRzKxnz7k9hsnsH8R1Ckwk") == \
                                   "xprv9xPgprbtHAtyKqFegHcy7WoUJ7tTsrL3D36Zf4LcXCCNEWfszpQR" \
                                   "eMWMdSpjE9qosHonUirqo418nd6vG46yi34nbHQ8wvWjLLjzMBFKNqM"

    assert path_xkey_to_bip32_xkey("vprv9DMUxX4ShgxMMjnWmkt3d8XYig1i81zS7yYxEifdjs7xYoKbBWFnta"
                                   "zMFGm1TeB5DqUnyuUFJE7AztDFfc7DcZP6RaKdq11yBUSBRvwZLXe",
                                   hex=True) == \
                                   decode_base58("tprv8ZgxMBicQKsPf9QH73JoCxLYNjipEn1SHkWWfvsryrNCSbh8gBvfe" \
                                                 "Tg5CrqqTpsEQZFBUxH8NuQ5EJz8EDHC261tgtvnfBNze2Jteoxhi47",
                                                 checksum=True).hex()

    assert path_xkey_to_bip32_xkey("vprv9DMUxX4ShgxMMjnWmkt3d8XYig1i81zS7yYxEifdjs7xYoKbBWFnta"
                                   "zMFGm1TeB5DqUnyuUFJE7AztDFfc7DcZP6RaKdq11yBUSBRvwZLXe",
                                   base58=False) == \
                                   decode_base58("tprv8ZgxMBicQKsPf9QH73JoCxLYNjipEn1SHkWWfvsryrNCSbh8gBvfe" \
                                                 "Tg5CrqqTpsEQZFBUxH8NuQ5EJz8EDHC261tgtvnfBNze2Jteoxhi47",
                                                 checksum=True)
def test_bip32_xkey_to_path_xkey():
    assert bip32_xkey_to_path_xkey(decode_base58("xpub68isDcaF29MCeYMdJ6ZypmjogsM6bgx3ssCZyRyT4JYqPZcSkEQtKx6ag1FHnir"
                                   "P8tz9VNAn7cuJhBKf63ijyw1FPg2Po36TcuX725Mom1X", checksum=True), "BIP44") == \
                                   "xpub68isDcaF29MCeYMdJ6ZypmjogsM6bgx3ssCZyRyT4JYqPZcSkEQtKx6ag1FHnir" \
                                   "P8tz9VNAn7cuJhBKf63ijyw1FPg2Po36TcuX725Mom1X"
    assert bip32_xkey_to_path_xkey(decode_base58("xpub68isDcaF29MCeYMdJ6ZypmjogsM6bgx3ssCZyRyT4JYqPZcSkEQtKx6ag1FHnir"
                                   "P8tz9VNAn7cuJhBKf63ijyw1FPg2Po36TcuX725Mom1X", checksum=True).hex(), "BIP44") == \
                                   "xpub68isDcaF29MCeYMdJ6ZypmjogsM6bgx3ssCZyRyT4JYqPZcSkEQtKx6ag1FHnir" \
                                   "P8tz9VNAn7cuJhBKf63ijyw1FPg2Po36TcuX725Mom1X"

    assert bip32_xkey_to_path_xkey("tpubD6NzVbkrYhZ4YcS4zgyPcMzewmEkQ7CLs47HxSvAQ8AbH5wuJakFpxHwNyXDSmS"
                                   "DzNQmkKx2unk3xTDNN716cAKbgr6CyPm3hsAW4CqPVK2", "BIP44") == \
                                   "tpubD6NzVbkrYhZ4YcS4zgyPcMzewmEkQ7CLs47HxSvAQ8AbH5wuJakFpxHwNyXDSmS" \
                                   "DzNQmkKx2unk3xTDNN716cAKbgr6CyPm3hsAW4CqPVK2"

    assert bip32_xkey_to_path_xkey("xpub68isDcaF29MCeYMdJ6ZypmjogsM6bgx3ssCZyRyT4JYqPZcSkEQtKx6ag1FHnir"
                                   "P8tz9VNAn7cuJhBKf63ijyw1FPg2Po36TcuX725Mom1X", "BIP49") == \
                                   "ypub6TZ8XHFAAptgVqYk8TMc2rqJrqVYYJwYnyinkpsLSJviSfRfztaSx1kihDCsndW" \
                                   "JYY6xEqmLaHFraTwDok8knAgrG1ipNwuwtdakQibcvzB"

    assert bip32_xkey_to_path_xkey("tpubD6NzVbkrYhZ4YcS4zgyPcMzewmEkQ7CLs47HxSvAQ8AbH5wuJakFpxHwNyXDSmS"
                                   "DzNQmkKx2unk3xTDNN716cAKbgr6CyPm3hsAW4CqPVK2", "BIP49") == \
                                   "upub57Wa4MvRPNyAivfs3RdRnBNn6jhkarina5xLFiBMvCH4NVqWUPQUpKeh5KZfvYXD" \
                                   "yYXStKeUzhrMcQt4p9upL1pW2EFdY8eMJjPA8UKuxaL"

    assert bip32_xkey_to_path_xkey("xpub68isDcaF29MCeYMdJ6ZypmjogsM6bgx3ssCZyRyT4JYqPZcSkEQtKx6ag1FHnirP"
                                   "8tz9VNAn7cuJhBKf63ijyw1FPg2Po36TcuX725Mom1X", "BIP84") == \
                                   "zpub6nPPpwv5KWSAM8jrxp9EEwvp2odzUvw3i6F1YDmDpKJbVmEuFYk1a5QriRATnYAD" \
                                   "xBDkzKMu2wcQTkYnXSYmaQNT8MRExrjSAMePoDv2d2R"

    assert bip32_xkey_to_path_xkey("tpubD6NzVbkrYhZ4YcS4zgyPcMzewmEkQ7CLs47HxSvAQ8AbH5wuJakFpxHwNyXDSmSD"
                                   "zNQmkKx2unk3xTDNN716cAKbgr6CyPm3hsAW4CqPVK2", "BIP84") == \
                                   "vpub5SLqN2bLY4WeaDrysnR3zGUHGhrCXUiHVCUZ375FJCewRbejj3a3SPJq6XXFvTB9P" \
                                   "BeFdoF3TNCuVhVdXrKq8FW6tZx483TqaTSoWx3U88j"

    assert bip32_xkey_to_path_xkey("xprv9xPgprbtHAtyKqFegHcy7WoUJ7tTsrL3D36Zf4LcXCCNEWfszpQReMWMdSpjE9qos"
                                   "HonUirqo418nd6vG46yi34nbHQ8wvWjLLjzMBFKNqM", "BIP44") == \
                                   "xprv9xPgprbtHAtyKqFegHcy7WoUJ7tTsrL3D36Zf4LcXCCNEWfszpQReMWMdSpjE9qos" \
                                   "HonUirqo418nd6vG46yi34nbHQ8wvWjLLjzMBFKNqM"

    assert bip32_xkey_to_path_xkey("tprv8ZgxMBicQKsPf9QH73JoCxLYNjipEn1SHkWWfvsryrNCSbh8gBvfeTg5CrqqTpsEQ"
                                   "ZFBUxH8NuQ5EJz8EDHC261tgtvnfBNze2Jteoxhi47", "BIP44") == \
                                   "tprv8ZgxMBicQKsPf9QH73JoCxLYNjipEn1SHkWWfvsryrNCSbh8gBvfeTg5CrqqTpsEQ" \
                                   "ZFBUxH8NuQ5EJz8EDHC261tgtvnfBNze2Jteoxhi47"

    assert bip32_xkey_to_path_xkey("xprv9xPgprbtHAtyKqFegHcy7WoUJ7tTsrL3D36Zf4LcXCCNEWfszpQReMWMdSpjE9qos"
                                   "HonUirqo418nd6vG46yi34nbHQ8wvWjLLjzMBFKNqM", "BIP49") == \
                                   "yprvAHDx8XGoRrSTB8SmWeQbKbtyU62upUKY89cnSTEVuCaFHcV7FUZzGRAVeenKE4VjG" \
                                   "vvbECTQFiMgfuiUykWzWGkPTd6ZXqLDc4odjkNZA2Z"

    assert bip32_xkey_to_path_xkey("tprv8ZgxMBicQKsPf9QH73JoCxLYNjipEn1SHkWWfvsryrNCSbh8gBvfeTg5CrqqTpsEQ"
                                   "ZFBUxH8NuQ5EJz8EDHC261tgtvnfBNze2Jteoxhi47", "BIP49") == \
                                   "uprv8tXDerPXZ1QsWSbPwQ6RR3S3YhsGBPzwCs2jTKmkMrk5VhWMvr6EGXLDE4oRTjX9p" \
                                   "CMzERsgqZkd7bbgwuhCpKhVZEdDF6CUukNY3RLytkD"

    assert bip32_xkey_to_path_xkey("xprv9xPgprbtHAtyKqFegHcy7WoUJ7tTsrL3D36Zf4LcXCCNEWfszpQReMWMdSpjE9qos"
                                   "HonUirqo418nd6vG46yi34nbHQ8wvWjLLjzMBFKNqM", "BIP84") == \
                                   "zprvAc4DSBwiaXyw2RdtM1CDXgzUe4BMm6K33G91Dr8PHCx8LiJLW8jYtUpdfrjuDy9eg" \
                                   "a3Pyg3xiNiEZCL3hSw1JWRzKxnz7k9hsnsH8R1Ckwk"

    assert bip32_xkey_to_path_xkey("tprv8ZgxMBicQKsPf9QH73JoCxLYNjipEn1SHkWWfvsryrNCSbh8gBvfeTg5CrqqTpsEQ"
                                   "ZFBUxH8NuQ5EJz8EDHC261tgtvnfBNze2Jteoxhi47", "BIP84", hex=True) == \
                                   decode_base58("vprv9DMUxX4ShgxMMjnWmkt3d8XYig1i81zS7yYxEifdjs7xYoKbBWF"
                                                 "ntazMFGm1TeB5DqUnyuUFJE7AztDFfc7DcZP6RaKdq11yBUSBRvwZLXe",
                                                 checksum=True).hex()

    assert bip32_xkey_to_path_xkey("tprv8ZgxMBicQKsPf9QH73JoCxLYNjipEn1SHkWWfvsryrNCSbh8gBvfeTg5CrqqTpsEQ"
                                   "ZFBUxH8NuQ5EJz8EDHC261tgtvnfBNze2Jteoxhi47", "BIP84", base58=False) == \
                                   decode_base58("vprv9DMUxX4ShgxMMjnWmkt3d8XYig1i81zS7yYxEifdjs7xYoKbBWF"
                                                 "ntazMFGm1TeB5DqUnyuUFJE7AztDFfc7DcZP6RaKdq11yBUSBRvwZLXe",
                                                 checksum=True)
    with pytest.raises(ValueError):
        bip32_xkey_to_path_xkey(
            "tprv8ZgxMBicQKsPf9QH73JoCxLYNjipEn1SHkWWfvsryrNCSbh8gBvfeTg5CrqqTpsEQ"
            "ZFBUxH8NuQ5EJz8EDHC261tgtvnfBNze2Jteoxhi47", "BIP88")
    with pytest.raises(ValueError):
        bip32_xkey_to_path_xkey("kjsdhfkjzxzvx][ewhf34h8322u32oeu2oh2",
                                "BIP84")

    with pytest.raises(ValueError):
        bip32_xkey_to_path_xkey(
            decode_base58(
                "pprv9xPgprbtHAtyKqFegHcy7WoUJ7tTsrL3D36Zf4LcXCCNEWfszpQReMWMdSpjE9qos"
                "HonUirqo418nd6vG46yi34nbHQ8wvWjLLjzMBFKNqM",
                checksum=True), "BIP84")