示例#1
0
def test_bip39():
    lang = "en"
    mnem = "abandon abandon atom trust ankle walnut oil across awake bunker divorce abstract"

    raw_entr = bytes.fromhex("0000003974d093eda670121023cd0000")
    mnemonic = bip39.mnemonic_from_entropy(raw_entr, lang)
    assert mnemonic == mnem

    r = bip39.entropy_from_mnemonic(mnemonic, lang)
    size = (len(r) + 7) // 8
    r = int(r, 2).to_bytes(size, byteorder="big")
    assert r == raw_entr

    wrong_mnemonic = mnemonic + " abandon"
    err_msg = "Wrong number of words: "
    with pytest.raises(ValueError, match=err_msg):
        bip39.entropy_from_mnemonic(wrong_mnemonic, lang)

    wr_m = "abandon abandon atom trust ankle walnut oil across awake bunker divorce oil"
    err_msg = "invalid checksum: "
    with pytest.raises(ValueError, match=err_msg):
        bip39.entropy_from_mnemonic(wr_m, lang)

    # Invalid number of bits (130) for BIP39 entropy; must be in ...
    binstr_entropy = "01" * 65  # 130 bits
    err_msg = "Invalid number of bits for BIP39 entropy: "
    with pytest.raises(ValueError, match=err_msg):
        bip39._entropy_checksum(binstr_entropy)
示例#2
0
    def test_bip39(self):
        lang = "en"
        raw_entr = bytes.fromhex("0000003974d093eda670121023cd0000")
        mnemonic = bip39.mnemonic_from_entropy(raw_entr, lang)
        self.assertEqual(mnemonic, "abandon abandon atom trust ankle walnut oil across awake bunker divorce abstract")
        r = bip39.entropy_from_mnemonic(mnemonic, lang)
        size = (len(r)+7) // 8
        r = int(r, 2).to_bytes(size, 'big')
        self.assertEqual(r, raw_entr)

        passphrase = ''

        rootxprv = bip39.rootxprv_from_mnemonic(mnemonic, passphrase, bip32.PRV_VERSION[0])
        exp = b'xprv9s21ZrQH143K3ZxBCax3Wu25iWt3yQJjdekBuGrVa5LDAvbLeCT99U59szPSFdnMe5szsWHbFyo8g5nAFowWJnwe8r6DiecBXTVGHG124G1'
        self.assertEqual(rootxprv, exp)

        rootxprv2 = bip39.rootxprv_from_entropy(raw_entr, passphrase, lang, bip32.PRV_VERSION[0])
        self.assertEqual(rootxprv2, rootxprv)

        rootxprv = bip39.rootxprv_from_mnemonic(mnemonic, passphrase, bip32.PRV_VERSION[0])
        exp = b'xprv9s21ZrQH143K3ZxBCax3Wu25iWt3yQJjdekBuGrVa5LDAvbLeCT99U59szPSFdnMe5szsWHbFyo8g5nAFowWJnwe8r6DiecBXTVGHG124G1'
        self.assertEqual(rootxprv, exp)

        rootxprv2 = bip39.rootxprv_from_entropy(raw_entr, passphrase, lang, bip32.PRV_VERSION[0])
        self.assertEqual(rootxprv2, rootxprv)

        # mnemonic with wrong number of bits
        wrong_mnemonic = mnemonic + " abandon"
        self.assertRaises(ValueError, bip39.entropy_from_mnemonic, wrong_mnemonic, lang)
        #bip39_entropy_from_mnemonic(wrong_mnemonic, lang)

        # invalid mnemonic checksum
        wrong_mnemonic = "abandon abandon atom trust ankle walnut oil across awake bunker divorce walnut"
        self.assertRaises(ValueError, bip39.entropy_from_mnemonic, wrong_mnemonic, lang)
示例#3
0
    def test_bip39(self):
        lang = "en"
        raw_entr = bytes.fromhex("0000003974d093eda670121023cd0000")
        mnemonic = bip39.mnemonic_from_entropy(raw_entr, lang)
        self.assertEqual(
            mnemonic,
            "abandon abandon atom trust ankle walnut oil across awake bunker divorce abstract"
        )
        r = bip39.entropy_from_mnemonic(mnemonic, lang)
        size = (len(r) + 7) // 8
        r = int(r, 2).to_bytes(size, byteorder='big')
        self.assertEqual(r, raw_entr)

        # mnemonic with wrong number of words
        wrong_mnemonic = mnemonic + " abandon"
        self.assertRaises(ValueError, bip39.entropy_from_mnemonic,
                          wrong_mnemonic, lang)
        #bip39_entropy_from_mnemonic(wrong_mnemonic, lang)

        # invalid mnemonic checksum
        wr_m = "abandon abandon atom trust ankle walnut oil across awake bunker divorce walnut"
        self.assertRaises(ValueError, bip39.entropy_from_mnemonic, wr_m, lang)
        #bip39_entropy_from_mnemonic(wrong_mnemonic, lang)

        # Invalid number of bits (130) for BIP39 entropy; must be in ...
        binstr_entropy = '01' * 65  # 130 bits
        self.assertRaises(ValueError, bip39._entropy_checksum, binstr_entropy)
示例#4
0
    def test_vectors(self):
        """BIP39 test vectors
           https://github.com/trezor/python-mnemonic/blob/master/vectors.json
        """
        fname = "bip39_test_vectors.json"
        filename = path.join(path.dirname(__file__), "test_data", fname)
        with open(filename, "r") as f:
            test_vectors = json.load(f)["english"]
        for test_vector in test_vectors:
            lang = "en"
            entropy = bytes.fromhex(test_vector[0])
            mnemonic = bip39.mnemonic_from_entropy(entropy, lang)
            self.assertEqual(mnemonic.split(), test_vector[1].split())

            raw_entr = bip39.entropy_from_mnemonic(mnemonic, lang)
            size = (len(raw_entr) + 7) // 8
            raw_entr = int(raw_entr, 2).to_bytes(size, byteorder="big")
            self.assertEqual(raw_entr, entropy)

            seed = bip39.seed_from_mnemonic(mnemonic, "TREZOR").hex()
            self.assertEqual(seed, test_vector[2])
示例#5
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__), "test_data", fname)
    with open(filename, "r") as file_:
        bip39_test_vectors = json.load(file_)["english"]

    lang = "en"
    # test_vector[3], i.e. the bip32 master private key, is tested in bip32
    for entr, mnemonic, seed, _ 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")
示例#6
0
    def test_vectors(self):
        """BIP39 test vectors
           https://github.com/trezor/python-mnemonic/blob/master/vectors.json
        """
        filename = "bip39_test_vectors.json"
        path_to_filename = os.path.join(os.path.dirname(__file__), "./data/",
                                        filename)
        with open(path_to_filename, 'r') as f:
            test_vectors = json.load(f)["english"]
        f.closed
        for test_vector in test_vectors:
            lang = "en"
            test_vector[0] = bytes.fromhex(test_vector[0])
            mnemonic = bip39.mnemonic_from_entropy(test_vector[0], lang)
            self.assertEqual(mnemonic, test_vector[1])

            raw_entr = bip39.entropy_from_mnemonic(mnemonic, lang)
            size = (len(raw_entr) + 7) // 8
            raw_entr = int(raw_entr, 2).to_bytes(size, 'big')
            self.assertEqual(raw_entr, test_vector[0])

            seed = bip39.seed_from_mnemonic(mnemonic, "TREZOR").hex()
            self.assertEqual(seed, test_vector[2])
示例#7
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)
示例#8
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)
示例#9
0
    def test_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, '')

        ##### TESTNET

        # p2pkh BIP44 m / 44' / coin_type' / account' / change / address_index
        path = "m/44h/1h/0h"
        version = bip32.TEST_tprv
        rootprv = bip32.rootxprv_from_seed(seed, version)
        xprv = bip32.derive(rootprv, path)
        xpub = bip32.xpub_from_xprv(xprv)
        exp = b'tpubDChqWo2Xi2wNsxyJBE8ipcTJHLKWcqeeNUKBVTpUCNPZkHzHTm3qKAeHqgCou1t8PAY5ZnJ9QDa6zXSZxmjDnhiBpgZ7f6Yv88wEm5HXVbm'
        self.assertEqual(xpub, exp)
        # first addresses
        xpub_ext = bip32.derive(xpub, "./0/0")  # external
        address = bip32.p2pkh_address_from_xpub(xpub_ext)
        exp_address = b'moutHSzeFWViMNEcvBxKzNCMj2kca8MvE1'
        self.assertEqual(address, exp_address)
        xpub_int = bip32.derive(xpub, "./1/0")  # internal
        address = bip32.p2pkh_address_from_xpub(xpub_int)
        exp_address = b'myWcXdNais9ExumnGKnNoJwoihQKfNPG9i'
        self.assertEqual(address, exp_address)

        # legacy segwit (p2wpkh-p2sh) m / 49'/ coin_type' / account' / change / address_index
        path = "m/49h/1h/0h"
        version = bip32.TEST_uprv
        rootprv = bip32.rootxprv_from_seed(seed, version)
        xprv = bip32.derive(rootprv, path)
        xpub = bip32.xpub_from_xprv(xprv)
        exp = b'upub5Dj8j7YrwodV68mt58QmNpSzjqjso2WMXEpLGLSvskKccGuXhCh3dTedkzVLAePA617UyXAg2vdswJXTYjU4qjMJaHU79GJVVJCAiy9ezZ2'
        self.assertEqual(xpub, exp)
        # first addresses
        xpub_ext = bip32.derive(xpub, "./0/0")  # external
        # TODO: address = bip32.p2pkh_address_from_xpub(xpub_ext)
        exp_address = b'2Mw8tQ6uT6mHhybarVhjgomUhHQJTeV9A2c'
        # TODO: self.assertEqual(address, exp_address)
        xpub_int = bip32.derive(xpub, "./1/0")  # internal
        # TODO: address = bip32.p2pkh_address_from_xpub(xpub_int)
        exp_address = b'2N872CRJ3E1CzWjfixXr3aeC3hkF5Cz4kWb'
        # TODO: self.assertEqual(address, exp_address)

        # multi-sig version
        version = bip32.TEST_Uprv
        rootprv = bip32.rootxprv_from_seed(seed, version)
        xprv = bip32.derive(rootprv, path)
        xpub = bip32.xpub_from_xprv(xprv)
        exp = b'Upub5QdDrMHJWmBrWhwG1nskCtnoTdn91PBwqWU1BbiUFXA2ETUSTc5KiaWZZhSoj5c4KUBTr7Anv92P4U9Dqxd1zDTyQkaWYfmVP2U3Js1W5cG'
        self.assertEqual(xpub, exp)

        # native segwit (p2wpkh) m / 84'/ coin_type' / account' / change / address_index
        path = "m/84h/1h/0h"
        version = bip32.TEST_vprv
        rootprv = bip32.rootxprv_from_seed(seed, version)
        xprv = bip32.derive(rootprv, path)
        xpub = bip32.xpub_from_xprv(xprv)
        exp = b'vpub5ZhJmduYY7M5J2qCJgSW7hunX6zJrr5WuNg2kKt321HseZEYxqJc6Zso47aNXQw3Wf3sA8kppbfsxnLheUNXcL3xhzeBHLNp8fTVBN6DnJF'
        self.assertEqual(xpub, exp)
        # first addresses
        xpub_ext = bip32.derive(xpub, "./0/0")  # external
        # FIXME: address = bip32.p2pkh_address_from_xpub(xpub_ext)
        exp_address = b'bcrt1qv8lcnmj09rpdqwgl025h2deygur64z4hqf7me5'
        # FIXME: self.assertEqual(address, exp_address)
        xpub_int = bip32.derive(xpub, "./1/0")  # internal
        # FIXME: address = bip32.p2pkh_address_from_xpub(xpub_int)
        exp_address = b'bcrt1qqhxvky4y6qkwpvdzqjkdafmj20vs5trmt6y8w5'
        # FIXME: self.assertEqual(address, exp_address)

        # multi-sig version
        version = bip32.TEST_Vprv
        rootprv = bip32.rootxprv_from_seed(seed, version)
        xprv = bip32.derive(rootprv, path)
        xpub = bip32.xpub_from_xprv(xprv)
        exp = b'Vpub5kbPtsdz74uSibzaFLuUwnFbEu2a5Cm7DeKhfb9aPn8HGjoTjEgtBgjirpXr5r9wk87r2ikwhp4P5wxTwhXUkpAdYTkagjqp2PjMmGPBESU'
        self.assertEqual(xpub, exp)

        ##### MAINNET

        # p2pkh BIP44 m / 44' / coin_type' / account' / change / address_index
        path = "m/44h/0h/0h"
        version = bip32.MAIN_xprv
        rootprv = bip32.rootxprv_from_seed(seed, version)
        xprv = bip32.derive(rootprv, path)
        xpub = bip32.xpub_from_xprv(xprv)
        exp = b'xpub6C3uWu5Go5q62JzJpbjyCLYRGLYvexFeiepZTsYZ6SRexARkNfjG7GKtQVuGR3KHsyKsAwv7Hz3iNucPp6pfHiLvBczyK1j5CtBtpHB3NKx'
        self.assertEqual(xpub, exp)
        # first addresses
        xpub_ext = bip32.derive(xpub, "./0/0")  # external
        address = bip32.p2pkh_address_from_xpub(xpub_ext)
        exp_address = b'1DDKKVHoFWGfctyEEJvrusqq6ipEaieGCq'
        self.assertEqual(address, exp_address)
        xpub_int = bip32.derive(xpub, "./1/0")  # internal
        address = bip32.p2pkh_address_from_xpub(xpub_int)
        exp_address = b'1FhKoffreKHzhtBMVW9NSsg3ZF148JPGoR'
        self.assertEqual(address, exp_address)

        # legacy segwit (p2wpkh-p2sh) m / 49'/ coin_type' / account' / change / address_index
        path = "m/49h/0h/0h"
        version = bip32.MAIN_yprv
        rootprv = bip32.rootxprv_from_seed(seed, version)
        xprv = bip32.derive(rootprv, path)
        xpub = bip32.xpub_from_xprv(xprv)
        exp = b'ypub6YBGdYufCVeoPVmNXfdrWhaBCXsQoLKNetNmD9bPTrKmnKVmiyU8f1uJqwGdmBb8kbAZpHoYfXQTLbWpkXc4skQDAreeCUXdbX9k8vtiHsN'
        self.assertEqual(xpub, exp)
        # first addresses
        xpub_ext = bip32.derive(xpub, "./0/0")  # external
        # FIXME: address = bip32.p2pkh_address_from_xpub(xpub_ext)
        exp_address = b'3FmNAiTCWe5kPMgc4dtSgEdY8VuaCiJEH8'
        # FIXME: self.assertEqual(address, exp_address)
        xpub_int = bip32.derive(xpub, "./1/0")  # internal
        # FIXME: address = bip32.p2pkh_address_from_xpub(xpub_int)
        exp_address = b'34FLgkoRYX5Q5fqiZCZDwsK5GpXxmFuLJN'
        # FIXME: self.assertEqual(address, exp_address)

        # multi-sig version
        version = bip32.MAIN_Yprv
        rootprv = bip32.rootxprv_from_seed(seed, version)
        xprv = bip32.derive(rootprv, path)
        xpub = bip32.xpub_from_xprv(xprv)
        exp = b'Ypub6j5Mkne6mTDAp4vkUL6qLmuyvKug1gzxyA2S8QrvqdABQW4gVNrQk8mEeeE7Kcp2z4EYgsofYjnxTm8b3km22EWt1Km3bszdVFRcipc6rXu'
        self.assertEqual(xpub, exp)

        # native segwit (p2wpkh) m / 84'/ coin_type' / account' / change / address_index
        path = "m/84h/0h/0h"
        version = bip32.MAIN_zprv
        rootprv = bip32.rootxprv_from_seed(seed, version)
        xprv = bip32.derive(rootprv, path)
        xpub = bip32.xpub_from_xprv(xprv)
        exp = b'zpub6qg3Uc1BAQkQvcBUYMmZHSzbsshSon3FvJ8yvH3ZZMjFNvJkwSji8UUwghiF3wvpvSvcNWVP8kfUhc2V2RwGp6pTC3ouj6njj956f26TniN'
        self.assertEqual(xpub, exp)
        # first addresses
        xpub_ext = bip32.derive(xpub, "./0/0")  # external
        # FIXME: address = bip32.p2pkh_address_from_xpub(xpub_ext)
        exp_address = b'bc1q0hy024867ednvuhy9en4dggflt5w9unw4ztl5a'
        # FIXME: self.assertEqual(address, exp_address)
        xpub_int = bip32.derive(xpub, "./1/0")  # internal
        # FIXME: address = bip32.p2pkh_address_from_xpub(xpub_int)
        exp_address = b'bc1qy4x03jyl88h2zeg7l287xhv2xrwk4c3ztfpjd2'
        # FIXME: self.assertEqual(address, exp_address)

        # multi-sig version
        version = bip32.MAIN_Zprv
        rootprv = bip32.rootxprv_from_seed(seed, version)
        xprv = bip32.derive(rootprv, path)
        xpub = bip32.xpub_from_xprv(xprv)
        exp = b'Zpub72a8bqjcjNJnMBLrV2EY7XLQbfji28irEZneqYK6w8Zf16sfhr7zDbLsVQficP9j9uzbF6VW1y3ypmeFKf6Dxaw82WvK8WFjcsLyEvMNZjF'
        self.assertEqual(xpub, exp)
示例#10
0
# Copyright (C) 2020 The btclib developers
#
# This file is part of btclib. It is subject to the license terms in the
# LICENSE file found in the top-level directory of this distribution.
#
# No part of btclib including this file, may be copied, modified, propagated,
# or distributed except according to the terms contained in the LICENSE file.

import secrets

from btclib import bip32, bip39, electrum

entropy = secrets.randbits(256)

bip39_mnemonic = bip39.mnemonic_from_entropy(entropy)
print()
print(bip39_mnemonic)
rxprv = bip32.mxprv_from_bip39_mnemonic(bip39_mnemonic)
rxpub = bip32.xpub_from_xprv(rxprv)
# warning: first level should always be hardened
# or any (depth=1) child private key would compromise rxprv
path = "m/0h"
xprv = bip32.derive(rxprv, path)
print(path + f" : {xprv!r}")

electrum_mnemonic = electrum.mnemonic_from_entropy(entropy)
print()
print(electrum_mnemonic)
mxprv = bip32.mxprv_from_electrum_mnemonic(electrum_mnemonic)
mxpub = bip32.xpub_from_xprv(mxprv)
示例#11
0
def test_addresses() -> None:

    # 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")

    # m / purpose h / coin_type h / account h / change / address_index
    test_vectors: List[Tuple[str, str, str]] = [
        # coin_type = 0 -> mainnet
        (
            "m/44h/0h/0h",
            "bip32_prv",  # p2pkh or p2sh
            "xpub6C3uWu5Go5q62JzJpbjyCLYRGLYvexFeiepZTsYZ6SRexARkNfjG7GKtQVuGR3KHsyKsAwv7Hz3iNucPp6pfHiLvBczyK1j5CtBtpHB3NKx",
        ),
        (
            "m/49h/0h/0h",
            "slip132_p2wpkh_p2sh_prv",  # p2wpkh-p2sh (p2sh-wrapped legacy-segwit p2wpkh)
            "ypub6YBGdYufCVeoPVmNXfdrWhaBCXsQoLKNetNmD9bPTrKmnKVmiyU8f1uJqwGdmBb8kbAZpHoYfXQTLbWpkXc4skQDAreeCUXdbX9k8vtiHsN",
        ),
        (
            "m/49h/0h/0h",
            "slip132_p2wsh_p2sh_prv",  # p2wsh-p2sh (p2sh-wrapped legacy-segwit p2wsh)
            "Ypub6j5Mkne6mTDAp4vkUL6qLmuyvKug1gzxyA2S8QrvqdABQW4gVNrQk8mEeeE7Kcp2z4EYgsofYjnxTm8b3km22EWt1Km3bszdVFRcipc6rXu",
        ),
        (
            "m/84h/0h/0h",
            "slip132_p2wpkh_prv",  # p2wpkh (native-segwit p2wpkh)
            "zpub6qg3Uc1BAQkQvcBUYMmZHSzbsshSon3FvJ8yvH3ZZMjFNvJkwSji8UUwghiF3wvpvSvcNWVP8kfUhc2V2RwGp6pTC3ouj6njj956f26TniN",
        ),
        (
            "m/84h/0h/0h",
            "slip132_p2wsh_prv",  # p2wsh (native-segwit p2wsh)
            "Zpub72a8bqjcjNJnMBLrV2EY7XLQbfji28irEZneqYK6w8Zf16sfhr7zDbLsVQficP9j9uzbF6VW1y3ypmeFKf6Dxaw82WvK8WFjcsLyEvMNZjF",
        ),
        # coin_type = 1 -> testnet
        (
            "m/44h/1h/0h",
            "bip32_prv",  # p2pkh BIP44
            "tpubDChqWo2Xi2wNsxyJBE8ipcTJHLKWcqeeNUKBVTpUCNPZkHzHTm3qKAeHqgCou1t8PAY5ZnJ9QDa6zXSZxmjDnhiBpgZ7f6Yv88wEm5HXVbm",
        ),
        (
            "m/49h/1h/0h",
            "slip132_p2wpkh_p2sh_prv",  # p2wpkh-p2sh (p2sh-wrapped legacy-segwit p2wpkh)
            "upub5Dj8j7YrwodV68mt58QmNpSzjqjso2WMXEpLGLSvskKccGuXhCh3dTedkzVLAePA617UyXAg2vdswJXTYjU4qjMJaHU79GJVVJCAiy9ezZ2",
        ),
        (
            "m/49h/1h/0h",
            "slip132_p2wsh_p2sh_prv",  # p2wsh-p2sh (p2sh-wrapped legacy-segwit p2wsh)
            "Upub5QdDrMHJWmBrWhwG1nskCtnoTdn91PBwqWU1BbiUFXA2ETUSTc5KiaWZZhSoj5c4KUBTr7Anv92P4U9Dqxd1zDTyQkaWYfmVP2U3Js1W5cG",
        ),
        (
            "m/84h/1h/0h",
            "slip132_p2wpkh_prv",  # p2wpkh (native-segwit p2wpkh)
            "vpub5ZhJmduYY7M5J2qCJgSW7hunX6zJrr5WuNg2kKt321HseZEYxqJc6Zso47aNXQw3Wf3sA8kppbfsxnLheUNXcL3xhzeBHLNp8fTVBN6DnJF",
        ),
        (
            "m/84h/1h/0h",
            "slip132_p2wsh_prv",  # p2wsh (native-segwit p2wsh)
            "Vpub5kbPtsdz74uSibzaFLuUwnFbEu2a5Cm7DeKhfb9aPn8HGjoTjEgtBgjirpXr5r9wk87r2ikwhp4P5wxTwhXUkpAdYTkagjqp2PjMmGPBESU",
        ),
    ]

    for der_path, addr_type, mxpub in test_vectors:
        der_path_elements = der_path.split("/")

        network = "testnet" if der_path_elements[2] == "1h" else "mainnet"
        rootprv = bip32.mxprv_from_bip39_mnemonic(mnemonic, "", network)

        # FIXME: do not ignore
        version = NETWORKS[network][addr_type]  # type: ignore
        xprv = bip32.derive(rootprv, der_path, version)
        assert mxpub.encode() == bip32.xpub_from_xprv(xprv)

        # a non-private version cannot be forced on a private key
        pub_version = NETWORKS[network]["bip32_pub"]
        err_msg = "invalid non-private version forced on a private key: "
        with pytest.raises(ValueError, match=err_msg):
            bip32.derive(rootprv, der_path, pub_version)

        # just changing the public version with no derivation does work
        bip32.derive(mxpub, ".", pub_version)
        err_msg = "invalid non-public version forced on a public key: "
        with pytest.raises(ValueError, match=err_msg):
            bip32.derive(mxpub, ".", version)
示例#12
0
 def test_zeroleadingbit(self):
     bip39.mnemonic_from_entropy(secrets.randbits(127), 'en')
示例#13
0
def test_zeroleadingbit():
    # it should not throw an error
    bip39.mnemonic_from_entropy(secrets.randbits(127), "en")
示例#14
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 / 44' / coin_type' / account' / change / address_index
        path = "m/44h/1h/0h"
        version = bip32.TEST_tprv
        rootprv = bip32.rootxprv_from_seed(seed, version)
        xprv = bip32.derive(rootprv, path)
        xpub = bip32.xpub_from_xprv(xprv)
        exp = b'tpubDChqWo2Xi2wNsxyJBE8ipcTJHLKWcqeeNUKBVTpUCNPZkHzHTm3qKAeHqgCou1t8PAY5ZnJ9QDa6zXSZxmjDnhiBpgZ7f6Yv88wEm5HXVbm'
        self.assertEqual(xpub, exp)
        # first addresses
        xpub_ext = bip32.derive(xpub, "./0/0")  # external
        address = bip32.p2pkh_address_from_xpub(xpub_ext)
        exp_address = b'moutHSzeFWViMNEcvBxKzNCMj2kca8MvE1'
        self.assertEqual(address, exp_address)
        xpub_int = bip32.derive(xpub, "./1/0")  # internal
        address = bip32.p2pkh_address_from_xpub(xpub_int)
        exp_address = b'myWcXdNais9ExumnGKnNoJwoihQKfNPG9i'
        self.assertEqual(address, exp_address)

        # legacy segwit (p2wpkh-p2sh) m / 49'/ coin_type' / account' / change / address_index
        path = "m/49h/1h/0h"
        version = bip32.TEST_uprv
        rootprv = bip32.rootxprv_from_seed(seed, version)
        xprv = bip32.derive(rootprv, path)
        xpub = bip32.xpub_from_xprv(xprv)
        exp = b'upub5Dj8j7YrwodV68mt58QmNpSzjqjso2WMXEpLGLSvskKccGuXhCh3dTedkzVLAePA617UyXAg2vdswJXTYjU4qjMJaHU79GJVVJCAiy9ezZ2'
        self.assertEqual(xpub, exp)
        # first addresses
        xpub_ext = bip32.derive(xpub, "./0/0")  # external
        address = bip32.p2wpkh_p2sh_address_from_xpub(xpub_ext)
        exp_address = b'2Mw8tQ6uT6mHhybarVhjgomUhHQJTeV9A2c'
        self.assertEqual(address, exp_address)
        xpub_int = bip32.derive(xpub, "./1/0")  # internal
        address = bip32.p2wpkh_p2sh_address_from_xpub(xpub_int)
        exp_address = b'2N872CRJ3E1CzWjfixXr3aeC3hkF5Cz4kWb'
        self.assertEqual(address, exp_address)

        # legacy segwit (p2wsh-p2sh) m / 49'/ coin_type' / account' / change / address_index
        path = "m/49h/1h/0h"
        version = bip32.TEST_Uprv
        rootprv = bip32.rootxprv_from_seed(seed, version)
        xprv = bip32.derive(rootprv, path)
        xpub = bip32.xpub_from_xprv(xprv)
        exp = b'Upub5QdDrMHJWmBrWhwG1nskCtnoTdn91PBwqWU1BbiUFXA2ETUSTc5KiaWZZhSoj5c4KUBTr7Anv92P4U9Dqxd1zDTyQkaWYfmVP2U3Js1W5cG'
        self.assertEqual(xpub, exp)

        # native segwit (p2wpkh) m / 84'/ coin_type' / account' / change / address_index
        path = "m/84h/1h/0h"
        version = bip32.TEST_vprv
        rootprv = bip32.rootxprv_from_seed(seed, version)
        xprv = bip32.derive(rootprv, path)
        xpub = bip32.xpub_from_xprv(xprv)
        exp = b'vpub5ZhJmduYY7M5J2qCJgSW7hunX6zJrr5WuNg2kKt321HseZEYxqJc6Zso47aNXQw3Wf3sA8kppbfsxnLheUNXcL3xhzeBHLNp8fTVBN6DnJF'
        self.assertEqual(xpub, exp)
        # first addresses
        xpub_ext = bip32.derive(xpub, "./0/0")  # external
        address = bip32.p2wpkh_address_from_xpub(xpub_ext)
        # this is regtest, not testnet!!
        exp_address = b'bcrt1qv8lcnmj09rpdqwgl025h2deygur64z4hqf7me5'
        # FIXME: self.assertEqual(address, exp_address)
        xpub_int = bip32.derive(xpub, "./1/0")  # internal
        address = bip32.p2wpkh_address_from_xpub(xpub_int)
        # this is regtest, not testnet!!
        exp_address = b'bcrt1qqhxvky4y6qkwpvdzqjkdafmj20vs5trmt6y8w5'
        # FIXME: self.assertEqual(address, exp_address)

        # native segwit (p2wsh) m / 84'/ coin_type' / account' / change / address_index
        path = "m/84h/1h/0h"
        version = bip32.TEST_Vprv
        rootprv = bip32.rootxprv_from_seed(seed, version)
        xprv = bip32.derive(rootprv, path)
        xpub = bip32.xpub_from_xprv(xprv)
        exp = b'Vpub5kbPtsdz74uSibzaFLuUwnFbEu2a5Cm7DeKhfb9aPn8HGjoTjEgtBgjirpXr5r9wk87r2ikwhp4P5wxTwhXUkpAdYTkagjqp2PjMmGPBESU'
        self.assertEqual(xpub, exp)