示例#1
0
def test_sanity_tests():
    seed = bytes.fromhex(
        "1077a46dc8545d372f22d9e110ae6c5c2bf7620fe9c4c911f5404d112233e1aa270567dd3554092e051ba3ba86c303590b0309116ac89964ff284db2219d7511"
    )
    first_bip32 = BIP32.from_seed(seed)
    sec_bip32 = BIP32.from_xpriv(
        "xprv9s21ZrQH143K3o4KUs47P2x9afhH31ekMo2foNTYwrU9wwZ8g5EatR9bn6YmCacdvnHWMnPFUqieQrnunrzuF5UfgGbhbEW43zRnhpPDBUL"
    )
    assert first_bip32.get_master_xpriv() == sec_bip32.get_master_xpriv()
    assert first_bip32.get_master_xpub() == sec_bip32.get_master_xpub()
    # Fuzz it a bit
    for i in range(50):
        path = [int.from_bytes(os.urandom(3), "big") for _ in range(5)]
        h_path = [
            HARDENED_INDEX + int.from_bytes(os.urandom(3), "big")
            for _ in range(5)
        ]
        mixed_path = [int.from_bytes(os.urandom(3), "big") for _ in range(5)]
        for i in mixed_path:
            if int.from_bytes(os.urandom(32), "big") % 2:
                i += HARDENED_INDEX
        assert first_bip32.get_xpriv_from_path(
            path) == sec_bip32.get_xpriv_from_path(path)
        assert first_bip32.get_xpub_from_path(
            path) == sec_bip32.get_xpub_from_path(path)
        assert first_bip32.get_xpriv_from_path(
            h_path) == sec_bip32.get_xpriv_from_path(h_path)
        assert first_bip32.get_xpub_from_path(
            h_path) == sec_bip32.get_xpub_from_path(h_path)
        assert first_bip32.get_xpriv_from_path(
            mixed_path) == sec_bip32.get_xpriv_from_path(mixed_path)
        assert first_bip32.get_xpub_from_path(
            mixed_path) == sec_bip32.get_xpub_from_path(mixed_path)
    # Taken from iancoleman's website
    bip32 = BIP32.from_seed(
        bytes.fromhex(
            "ac8c2377e5cde867d7e420fbe04d8906309b70d51b8fe58d6844930621a9bc223929155dcfebb4da9d62c86ec0d15adf936a663f4f0cf39cbb0352e7dac073d6"
        ))
    assert bip32.get_master_xpriv() == bip32.get_xpriv_from_path(
        []
    ) == "xprv9s21ZrQH143K2GzaKJsW7DQsxeDpY3zqgusaSx6owWGC19k4mhwnVAsm4qPsCw43NkY2h1BzVLyxWHt9NKF86QRyBj53vModdGcNxtpD6KX"
    assert bip32.get_master_xpub() == bip32.get_xpub_from_path(
        []
    ) == "xpub661MyMwAqRbcEm53RLQWUMMcWg4JwWih48oBFLWRVqoAsx5DKFG32yCEv8iH29TWpmo5KTcpsjXcea6Zx4Hc6PAbGnHjEDCf3yHbj7qdpnf"
    # Sanity checks for m/0'/0'/14/0'/18
    xpriv = bip32.get_xpriv_from_path(
        [HARDENED_INDEX, HARDENED_INDEX, 14, HARDENED_INDEX, 18])
    xpub = bip32.get_xpub_from_path(
        [HARDENED_INDEX, HARDENED_INDEX, 14, HARDENED_INDEX, 18])
    assert xpriv == "xprvA2YVbLvEeKaPedw7F6RLwG3RgYnTq1xGCyDNMgZNWdEQnSUBQmKEuLyA6TSPsggt5xvyJHLD9L25tNLpQiP4Q8ZkQNo8ueAgeYj5zYq8hSm"
    assert xpub == "xpub6FXqzrT8Uh8gs81aM7xMJPzAEacxEUg7aC8yA4xz4xmPfEoKxJdVT9Hdwm3LwVQrSos2rhGDt8aGGHvdLr5LLAjK8pXFkbSpzGoGTXjd4z9"
    # Now if we our master is m/0'/0'/14, we should derive the same keys for
    # m/0'/18 !
    xpriv2 = bip32.get_xpriv_from_path([HARDENED_INDEX, HARDENED_INDEX, 14])
    assert xpriv2 == "xprv9yQJmvQMywM5i7UNuZ4RQ1A9rEMwAJCExPardkmBCB46S3vBqNEatSwLUrwLNLHBu1Kd9aGxGKDD5YAfs6hRzpYthciAHjtGadxgV2PeqY9"
    bip32 = BIP32.from_xpriv(xpriv2)
    assert bip32.get_master_xpriv() == xpriv2
    assert bip32.get_xpriv_from_path([HARDENED_INDEX, 18]) == xpriv
    assert bip32.get_xpub_from_path([HARDENED_INDEX, 18]) == xpub
示例#2
0
def parse_key(key: str) -> BIP32:
    """
    Try to parse an extended key, whether it is in xpub, xpriv or mnemonic format.
    """
    try:
        private_key = BIP32.from_xpriv(key)
        print('🔑  Read master private key successfully')
        return private_key
    except Exception:
        pass

    try:
        public_key = BIP32.from_xpub(key)
        print('🔑  Read master public key successfully')
        return public_key
    except Exception:
        pass

    try:
        language = Mnemonic.detect_language(key)
        seed = Mnemonic(language).to_seed(key)
        private_key = BIP32.from_seed(seed)
        print('🔑  Read mnemonic successfully')
        return private_key
    except Exception:
        pass

    raise ValueError(
        'The key is invalid or the format isn\'t recognized. Make sure it\'s a mnemonic, xpriv or xpub.'
    )
示例#3
0
def test_vector_3():
    seed = bytes.fromhex(
        "4b381541583be4423346c643850da4b320e46a87ae3d2a4e6da11eba819cd4acba45d239319ac14f863b8d5ab5a0d0c64d2e8a1e7d1457df2e5a3c51c73235be"
    )
    bip32 = BIP32.from_seed(seed)
    # Chain m
    assert (
        bip32.get_xpub_from_path([]) ==
        "xpub661MyMwAqRbcEZVB4dScxMAdx6d4nFc9nvyvH3v4gJL378CSRZiYmhRoP7mBy6gSPSCYk6SzXPTf3ND1cZAceL7SfJ1Z3GC8vBgp2epUt13"
    )
    assert (
        bip32.get_xpriv_from_path([]) ==
        "xprv9s21ZrQH143K25QhxbucbDDuQ4naNntJRi4KUfWT7xo4EKsHt2QJDu7KXp1A3u7Bi1j8ph3EGsZ9Xvz9dGuVrtHHs7pXeTzjuxBrCmmhgC6"
    )
    assert (bip32.get_xpub_from_path("m") == bip32.get_xpub_from_path([]))
    assert (bip32.get_xpriv_from_path("m") == bip32.get_xpriv_from_path([]))
    # Chain m/0H
    assert (
        bip32.get_xpub_from_path([HARDENED_INDEX]) ==
        "xpub68NZiKmJWnxxS6aaHmn81bvJeTESw724CRDs6HbuccFQN9Ku14VQrADWgqbhhTHBaohPX4CjNLf9fq9MYo6oDaPPLPxSb7gwQN3ih19Zm4Y"
    )
    assert (
        bip32.get_xpriv_from_path([HARDENED_INDEX]) ==
        "xprv9uPDJpEQgRQfDcW7BkF7eTya6RPxXeJCqCJGHuCJ4GiRVLzkTXBAJMu2qaMWPrS7AANYqdq6vcBcBUdJCVVFceUvJFjaPdGZ2y9WACViL4L"
    )
    assert (bip32.get_xpub_from_path("m/0H") == bip32.get_xpub_from_path(
        [HARDENED_INDEX]))
    assert (bip32.get_xpriv_from_path("m/0H") == bip32.get_xpriv_from_path(
        [HARDENED_INDEX]))
示例#4
0
    def Init(self, request, context):

        node = Node()
        node.hsm_secret = request.hsm_secret.data

        # on chain wallet
        hkdf = HKDF(key=node.hsm_secret)
        r = hkdf.extract_key(info='bip32 seed'.encode(), length=32)
        logger.debug("bip32_key seed: %s" % r.hex())
        node.bip32_key = BIP32.from_seed(r, network=self.network)

        # node pubkey, node msg sign
        r = hkdf.extract_key(info='nodeid'.encode(), length=32)
        node.node_privkey = r
        node.node_pk = r
        logger.info("new node privkey %s" % r.hex())

        node_pk = coincurve.PrivateKey(secret=r)
        node.pubkey = node_pk.public_key.format()
        node.nodeid = binascii.hexlify(node.pubkey)
        logger.info("new node id %s" % node.nodeid)

        # channel secret_base
        node.secret_base = hkdf.extract_key(info='peer seed'.encode(),
                                            length=32)
        logger.debug("new channel secret base %s" % node.secret_base.hex())

        if not self.nodes.get(node.pubkey) or request.coldstart:
            self.nodes[node.pubkey] = node

        reply = remotesigner_pb2.InitReply()
        reply.node_id.data = node.pubkey
        return reply
示例#5
0
def test_vector_1():
    seed = bytes.fromhex("000102030405060708090a0b0c0d0e0f")
    bip32 = BIP32.from_seed(seed)
    # Chain m
    assert (
        bip32.get_master_xpub() ==
        "xpub661MyMwAqRbcFtXgS5sYJABqqG9YLmC4Q1Rdap9gSE8NqtwybGhePY2gZ29ESFjqJoCu1Rupje8YtGqsefD265TMg7usUDFdp6W1EGMcet8"
    )
    assert (
        bip32.get_master_xpriv() ==
        "xprv9s21ZrQH143K3QTDL4LXw2F7HEK3wJUD2nW2nRk4stbPy6cq3jPPqjiChkVvvNKmPGJxWUtg6LnF5kejMRNNU3TGtRBeJgk33yuGBxrMPHi"
    )
    # Chain m/0H
    assert (
        bip32.get_xpub_from_path([HARDENED_INDEX]) ==
        "xpub68Gmy5EdvgibQVfPdqkBBCHxA5htiqg55crXYuXoQRKfDBFA1WEjWgP6LHhwBZeNK1VTsfTFUHCdrfp1bgwQ9xv5ski8PX9rL2dZXvgGDnw"
    )
    assert (
        bip32.get_xpriv_from_path([HARDENED_INDEX]) ==
        "xprv9uHRZZhk6KAJC1avXpDAp4MDc3sQKNxDiPvvkX8Br5ngLNv1TxvUxt4cV1rGL5hj6KCesnDYUhd7oWgT11eZG7XnxHrnYeSvkzY7d2bhkJ7"
    )
    # m/0H/1
    assert (
        bip32.get_xpub_from_path([HARDENED_INDEX, 1]) ==
        "xpub6ASuArnXKPbfEwhqN6e3mwBcDTgzisQN1wXN9BJcM47sSikHjJf3UFHKkNAWbWMiGj7Wf5uMash7SyYq527Hqck2AxYysAA7xmALppuCkwQ"
    )
    assert (
        bip32.get_xpriv_from_path([HARDENED_INDEX, 1]) ==
        "xprv9wTYmMFdV23N2TdNG573QoEsfRrWKQgWeibmLntzniatZvR9BmLnvSxqu53Kw1UmYPxLgboyZQaXwTCg8MSY3H2EU4pWcQDnRnrVA1xe8fs"
    )
    # m/0H/1/2H
    assert (
        bip32.get_xpub_from_path([HARDENED_INDEX, 1, HARDENED_INDEX + 2]) ==
        "xpub6D4BDPcP2GT577Vvch3R8wDkScZWzQzMMUm3PWbmWvVJrZwQY4VUNgqFJPMM3No2dFDFGTsxxpG5uJh7n7epu4trkrX7x7DogT5Uv6fcLW5"
    )
    assert (
        bip32.get_xpriv_from_path([HARDENED_INDEX, 1, HARDENED_INDEX + 2]) ==
        "xprv9z4pot5VBttmtdRTWfWQmoH1taj2axGVzFqSb8C9xaxKymcFzXBDptWmT7FwuEzG3ryjH4ktypQSAewRiNMjANTtpgP4mLTj34bhnZX7UiM"
    )
    # m/0H/1/2H/2
    assert (
        bip32.get_xpub_from_path([HARDENED_INDEX, 1, HARDENED_INDEX + 2, 2]) ==
        "xpub6FHa3pjLCk84BayeJxFW2SP4XRrFd1JYnxeLeU8EqN3vDfZmbqBqaGJAyiLjTAwm6ZLRQUMv1ZACTj37sR62cfN7fe5JnJ7dh8zL4fiyLHV"
    )
    assert (
        bip32.get_xpriv_from_path([HARDENED_INDEX, 1, HARDENED_INDEX + 2,
                                   2]) ==
        "xprvA2JDeKCSNNZky6uBCviVfJSKyQ1mDYahRjijr5idH2WwLsEd4Hsb2Tyh8RfQMuPh7f7RtyzTtdrbdqqsunu5Mm3wDvUAKRHSC34sJ7in334"
    )
    # m/0H/1/2H/2/1000000000
    assert (
        bip32.get_xpub_from_path(
            [HARDENED_INDEX, 1, HARDENED_INDEX + 2, 2, 1000000000]) ==
        "xpub6H1LXWLaKsWFhvm6RVpEL9P4KfRZSW7abD2ttkWP3SSQvnyA8FSVqNTEcYFgJS2UaFcxupHiYkro49S8yGasTvXEYBVPamhGW6cFJodrTHy"
    )
    assert (
        bip32.get_xpriv_from_path(
            [HARDENED_INDEX, 1, HARDENED_INDEX + 2, 2, 1000000000]) ==
        "xprvA41z7zogVVwxVSgdKUHDy1SKmdb533PjDz7J6N6mV6uS3ze1ai8FHa8kmHScGpWmj4WggLyQjgPie1rFSruoUihUZREPSL39UNdE3BBDu76"
    )
示例#6
0
def get_address(words, strange=10):
    address_list = []
    mnemo = Mnemonic("english")
    seed = mnemo.to_seed(words, passphrase="")
    bip32 = BIP32.from_seed(seed)
    for i in range(0, strange):
        path = "m/44'/313'/0'/0/%i" % i
        pab_key = bip32.get_pubkey_from_path(path)
        key = zilkey.ZilKey(public_key=pab_key.hex())
        address_list.append(key.address)
    return address_list
示例#7
0
    def __init__(self,
                 mnemonic: str,
                 language: str = "english",
                 passphrase: str = ""):
        """
        BIP44 HD wallet with a master mnemonic.

        :param mnemonic (str): The master mnemonic to derive keys
        :param language (str, optional): The mnemonic's language, default: "english"
        :param passphrase (str, optional): The mnemonic's passphrase, default: ""
        """
        self._seed = Mnemonic(language).to_seed(mnemonic, passphrase)
        self._bip32 = BIP32.from_seed(self._seed)
示例#8
0
def create_wallet(testnet=False):
    path = "m/44'/1'/0'/0/0" if testnet else "m/44'/0'/0'/0/0"

    mnemo = Mnemonic("english")
    words = mnemo.generate()
    seed = mnemo.to_seed(words, passphrase="")

    bip32 = BIP32.from_seed(seed)

    privkey = bip32.get_privkey_from_path(path)
    pubkey = base64.b64encode(bip32.get_pubkey_from_path(path)).decode('utf-8')
    definition = ['sig', {"pubkey": pubkey}]

    print(f"privkey: {privkey}")
    print(f"pubkey: {pubkey}")
    print(f"address: {get_chash_160(definition)}")
示例#9
0
    def from_mnemonic(cls, words: str, path="m/44'/494'/0'/0/0") -> PrivateKey:
        """
        Create a PrivateKey instance from a given mnemonic phrase and a HD derivation path.
        If path is not given, default to Band's HD prefix 494 and all other indexes being zeroes.

        :param words: the mnemonic phrase for recover private key
        :param path: the HD path that follows the BIP32 standard

        :return: Initialized PrivateKey object
        """
        seed = Mnemonic("english").to_seed(words)
        self = cls(_error_do_not_use_init_directly=True)
        self.signing_key = SigningKey.from_string(
            BIP32.from_seed(seed).get_privkey_from_path(path),
            curve=SECP256k1,
            hashfunc=hashlib.sha256,
        )
        return self
示例#10
0
文件: utils.py 项目: kloaec/re-vault
 def get_wallets(self, emergency_privkeys=None):
     """Get 4 vaults, one for each stakeholder. Spin up the servers."""
     bip32s = [BIP32.from_seed(os.urandom(32), "test") for _ in range(4)]
     xpubs = [bip32.get_master_xpub() for bip32 in bip32s]
     if emergency_privkeys is None:
         emergency_privkeys = [CKey(os.urandom(32)) for _ in range(4)]
     emergency_pubkeys = [k.pub for k in emergency_privkeys]
     self.vaults = []
     # Generate some random 'OK' addresses
     acked_addresses = [self.bitcoind.getnewaddress() for _ in range(5)]
     for bip32 in bip32s:
         xpriv = bip32.get_master_xpriv()
         conf = self.bitcoind.rpc.__btc_conf_file__
         cosigner_url = "http://localhost:{}".format(self.cosigning_port)
         sigserv_url = "http://localhost:{}".format(self.sigserver_port)
         self.vaults.append(
             Vault(xpriv, xpubs, emergency_pubkeys, conf, cosigner_url,
                   sigserv_url, acked_addresses))
     return self.vaults
示例#11
0
def test_vector_2():
    seed = bytes.fromhex(
        "fffcf9f6f3f0edeae7e4e1dedbd8d5d2cfccc9c6c3c0bdbab7b4b1aeaba8a5a29f9c999693908d8a8784817e7b7875726f6c696663605d5a5754514e4b484542"
    )
    bip32 = BIP32.from_seed(seed)
    # Chain m
    assert (
        bip32.get_master_xpub() ==
        "xpub661MyMwAqRbcFW31YEwpkMuc5THy2PSt5bDMsktWQcFF8syAmRUapSCGu8ED9W6oDMSgv6Zz8idoc4a6mr8BDzTJY47LJhkJ8UB7WEGuduB"
    )
    assert (
        bip32.get_master_xpriv() ==
        "xprv9s21ZrQH143K31xYSDQpPDxsXRTUcvj2iNHm5NUtrGiGG5e2DtALGdso3pGz6ssrdK4PFmM8NSpSBHNqPqm55Qn3LqFtT2emdEXVYsCzC2U"
    )
    # Chain m/0
    assert (
        bip32.get_xpub_from_path([0]) ==
        "xpub69H7F5d8KSRgmmdJg2KhpAK8SR3DjMwAdkxj3ZuxV27CprR9LgpeyGmXUbC6wb7ERfvrnKZjXoUmmDznezpbZb7ap6r1D3tgFxHmwMkQTPH"
    )
    assert (
        bip32.get_xpriv_from_path([0]) ==
        "xprv9vHkqa6EV4sPZHYqZznhT2NPtPCjKuDKGY38FBWLvgaDx45zo9WQRUT3dKYnjwih2yJD9mkrocEZXo1ex8G81dwSM1fwqWpWkeS3v86pgKt"
    )
    assert (bip32.get_xpriv_from_path("m/0") == bip32.get_xpriv_from_path([0]))
    assert (bip32.get_xpub_from_path("m/0") == bip32.get_xpub_from_path([0]))
    # Chain m/0/2147483647H
    assert (
        bip32.get_xpub_from_path([0, HARDENED_INDEX + 2147483647]) ==
        "xpub6ASAVgeehLbnwdqV6UKMHVzgqAG8Gr6riv3Fxxpj8ksbH9ebxaEyBLZ85ySDhKiLDBrQSARLq1uNRts8RuJiHjaDMBU4Zn9h8LZNnBC5y4a"
    )
    assert (
        bip32.get_xpriv_from_path([0, HARDENED_INDEX + 2147483647]) ==
        "xprv9wSp6B7kry3Vj9m1zSnLvN3xH8RdsPP1Mh7fAaR7aRLcQMKTR2vidYEeEg2mUCTAwCd6vnxVrcjfy2kRgVsFawNzmjuHc2YmYRmagcEPdU9"
    )
    assert (bip32.get_xpub_from_path("m/0/2147483647H") ==
            bip32.get_xpub_from_path([0, HARDENED_INDEX + 2147483647]))
    assert (bip32.get_xpriv_from_path("m/0/2147483647H") ==
            bip32.get_xpriv_from_path([0, HARDENED_INDEX + 2147483647]))
    # Chain m/0/2147483647H/1
    assert (
        bip32.get_xpub_from_path([0, HARDENED_INDEX + 2147483647, 1]) ==
        "xpub6DF8uhdarytz3FWdA8TvFSvvAh8dP3283MY7p2V4SeE2wyWmG5mg5EwVvmdMVCQcoNJxGoWaU9DCWh89LojfZ537wTfunKau47EL2dhHKon"
    )
    assert (
        bip32.get_xpriv_from_path([0, HARDENED_INDEX + 2147483647, 1]) ==
        "xprv9zFnWC6h2cLgpmSA46vutJzBcfJ8yaJGg8cX1e5StJh45BBciYTRXSd25UEPVuesF9yog62tGAQtHjXajPPdbRCHuWS6T8XA2ECKADdw4Ef"
    )
    assert (bip32.get_xpub_from_path("m/0/2147483647H/1") ==
            bip32.get_xpub_from_path([0, HARDENED_INDEX + 2147483647, 1]))
    assert (bip32.get_xpriv_from_path("m/0/2147483647H/1") ==
            bip32.get_xpriv_from_path([0, HARDENED_INDEX + 2147483647, 1]))
    # Chain m/0/2147483647H/1/2147483646H
    assert (
        bip32.get_xpub_from_path(
            [0, HARDENED_INDEX + 2147483647, 1,
             HARDENED_INDEX + 2147483646]) ==
        "xpub6ERApfZwUNrhLCkDtcHTcxd75RbzS1ed54G1LkBUHQVHQKqhMkhgbmJbZRkrgZw4koxb5JaHWkY4ALHY2grBGRjaDMzQLcgJvLJuZZvRcEL"
    )
    assert (
        bip32.get_xpriv_from_path(
            [0, HARDENED_INDEX + 2147483647, 1,
             HARDENED_INDEX + 2147483646]) ==
        "xprvA1RpRA33e1JQ7ifknakTFpgNXPmW2YvmhqLQYMmrj4xJXXWYpDPS3xz7iAxn8L39njGVyuoseXzU6rcxFLJ8HFsTjSyQbLYnMpCqE2VbFWc"
    )
    assert (bip32.get_xpub_from_path(
        "m/0/2147483647H/1/2147483646H") == bip32.get_xpub_from_path(
            [0, HARDENED_INDEX + 2147483647, 1, HARDENED_INDEX + 2147483646]))
    assert (bip32.get_xpriv_from_path(
        "m/0/2147483647H/1/2147483646H") == bip32.get_xpriv_from_path(
            [0, HARDENED_INDEX + 2147483647, 1, HARDENED_INDEX + 2147483646]))
    # Chain m/0/2147483647H/1/2147483646H/2
    assert (
        bip32.get_xpub_from_path([
            0, HARDENED_INDEX + 2147483647, 1, HARDENED_INDEX + 2147483646, 2
        ]) ==
        "xpub6FnCn6nSzZAw5Tw7cgR9bi15UV96gLZhjDstkXXxvCLsUXBGXPdSnLFbdpq8p9HmGsApME5hQTZ3emM2rnY5agb9rXpVGyy3bdW6EEgAtqt"
    )
    assert (
        bip32.get_xpriv_from_path([
            0, HARDENED_INDEX + 2147483647, 1, HARDENED_INDEX + 2147483646, 2
        ]) ==
        "xprvA2nrNbFZABcdryreWet9Ea4LvTJcGsqrMzxHx98MMrotbir7yrKCEXw7nadnHM8Dq38EGfSh6dqA9QWTyefMLEcBYJUuekgW4BYPJcr9E7j"
    )
    assert (bip32.get_xpub_from_path(
        "m/0/2147483647H/1/2147483646H/2") == bip32.get_xpub_from_path([
            0, HARDENED_INDEX + 2147483647, 1, HARDENED_INDEX + 2147483646, 2
        ]))
    assert (bip32.get_xpriv_from_path(
        "m/0/2147483647H/1/2147483646H/2") == bip32.get_xpriv_from_path([
            0, HARDENED_INDEX + 2147483647, 1, HARDENED_INDEX + 2147483646, 2
        ]))
示例#12
0
def test_sanity_tests():
    seed = bytes.fromhex(
        "1077a46dc8545d372f22d9e110ae6c5c2bf7620fe9c4c911f5404d112233e1aa270567dd3554092e051ba3ba86c303590b0309116ac89964ff284db2219d7511"
    )
    first_bip32 = BIP32.from_seed(seed)
    sec_bip32 = BIP32.from_xpriv(
        "xprv9s21ZrQH143K3o4KUs47P2x9afhH31ekMo2foNTYwrU9wwZ8g5EatR9bn6YmCacdvnHWMnPFUqieQrnunrzuF5UfgGbhbEW43zRnhpPDBUL"
    )
    assert first_bip32.get_master_xpriv() == sec_bip32.get_master_xpriv()
    assert first_bip32.get_master_xpub() == sec_bip32.get_master_xpub()
    # Fuzz it a bit
    for i in range(50):
        path = [int.from_bytes(os.urandom(3), "big") for _ in range(5)]
        h_path = [
            HARDENED_INDEX + int.from_bytes(os.urandom(3), "big")
            for _ in range(5)
        ]
        mixed_path = [int.from_bytes(os.urandom(3), "big") for _ in range(5)]
        for i in mixed_path:
            if int.from_bytes(os.urandom(32), "big") % 2:
                i += HARDENED_INDEX
        assert first_bip32.get_xpriv_from_path(
            path) == sec_bip32.get_xpriv_from_path(path)
        assert first_bip32.get_xpub_from_path(
            path) == sec_bip32.get_xpub_from_path(path)
        assert first_bip32.get_xpriv_from_path(
            h_path) == sec_bip32.get_xpriv_from_path(h_path)
        assert first_bip32.get_xpub_from_path(
            h_path) == sec_bip32.get_xpub_from_path(h_path)
        assert first_bip32.get_xpriv_from_path(
            mixed_path) == sec_bip32.get_xpriv_from_path(mixed_path)
        assert first_bip32.get_xpub_from_path(
            mixed_path) == sec_bip32.get_xpub_from_path(mixed_path)
    # Taken from iancoleman's website
    bip32 = BIP32.from_seed(
        bytes.fromhex(
            "ac8c2377e5cde867d7e420fbe04d8906309b70d51b8fe58d6844930621a9bc223929155dcfebb4da9d62c86ec0d15adf936a663f4f0cf39cbb0352e7dac073d6"
        ))
    assert bip32.get_master_xpriv() == bip32.get_xpriv_from_path(
        []
    ) == "xprv9s21ZrQH143K2GzaKJsW7DQsxeDpY3zqgusaSx6owWGC19k4mhwnVAsm4qPsCw43NkY2h1BzVLyxWHt9NKF86QRyBj53vModdGcNxtpD6KX"
    assert bip32.get_master_xpub() == bip32.get_xpub_from_path(
        []
    ) == "xpub661MyMwAqRbcEm53RLQWUMMcWg4JwWih48oBFLWRVqoAsx5DKFG32yCEv8iH29TWpmo5KTcpsjXcea6Zx4Hc6PAbGnHjEDCf3yHbj7qdpnf"
    # Sanity checks for m/0'/0'/14/0'/18
    xpriv = bip32.get_xpriv_from_path(
        [HARDENED_INDEX, HARDENED_INDEX, 14, HARDENED_INDEX, 18])
    xpub = bip32.get_xpub_from_path(
        [HARDENED_INDEX, HARDENED_INDEX, 14, HARDENED_INDEX, 18])
    assert xpriv == "xprvA2YVbLvEeKaPedw7F6RLwG3RgYnTq1xGCyDNMgZNWdEQnSUBQmKEuLyA6TSPsggt5xvyJHLD9L25tNLpQiP4Q8ZkQNo8ueAgeYj5zYq8hSm"
    assert xpub == "xpub6FXqzrT8Uh8gs81aM7xMJPzAEacxEUg7aC8yA4xz4xmPfEoKxJdVT9Hdwm3LwVQrSos2rhGDt8aGGHvdLr5LLAjK8pXFkbSpzGoGTXjd4z9"
    # Now if we our master is m/0'/0'/14, we should derive the same keys for
    # m/0'/18 !
    xpriv2 = bip32.get_xpriv_from_path([HARDENED_INDEX, HARDENED_INDEX, 14])
    assert xpriv2 == "xprv9yQJmvQMywM5i7UNuZ4RQ1A9rEMwAJCExPardkmBCB46S3vBqNEatSwLUrwLNLHBu1Kd9aGxGKDD5YAfs6hRzpYthciAHjtGadxgV2PeqY9"
    bip32 = BIP32.from_xpriv(xpriv2)
    assert bip32.get_master_xpriv() == xpriv2
    assert bip32.get_xpriv_from_path([HARDENED_INDEX, 18]) == xpriv
    assert bip32.get_xpub_from_path([HARDENED_INDEX, 18]) == xpub
    # We should recognize the networks..
    # .. for xprivs:
    bip32 = BIP32.from_xpriv(
        "xprv9wHokC2KXdTSpEepFcu53hMDUHYfAtTaLEJEMyxBPAMf78hJg17WhL5FyeDUQH5KWmGjGgEb2j74gsZqgupWpPbZgP6uFmP8MYEy5BNbyET"
    )
    assert bip32.network == "main"
    bip32 = BIP32.from_xpriv(
        "tprv8ZgxMBicQKsPeCBsMzQCCb5JcW4S49MVL3EwhdZMF1RF71rgisZU4ZRvrHX6PZQEiNUABDLvYqpx8Lsccq8aGGR59qHAoLoE3iXYuDa8JTP"
    )
    assert bip32.network == "test"
    # .. for xpubs:
    bip32 = BIP32.from_xpub(
        "xpub6AHA9hZDN11k2ijHMeS5QqHx2KP9aMBRhTDqANMnwVtdyw2TDYRmF8PjpvwUFcL1Et8Hj59S3gTSMcUQ5gAqTz3Wd8EsMTmF3DChhqPQBnU"
    )
    assert bip32.network == "main"
    bip32 = BIP32.from_xpub(
        "tpubD6NzVbkrYhZ4WN3WiKRjeo2eGyYNiKNg8vcQ1UjLNJJaDvoFhmR1XwJsbo5S4vicSPoWQBThR3Rt8grXtP47c1AnoiXMrEmFdRZupxJzH1j"
    )
    assert bip32.network == "test"
    # We should create valid network encoding..
    assert BIP32.from_seed(os.urandom(32),
                           "test").get_master_xpub().startswith("tpub")
    assert BIP32.from_seed(os.urandom(32),
                           "test").get_master_xpriv().startswith("tprv")
    assert BIP32.from_seed(os.urandom(32),
                           "main").get_master_xpub().startswith("xpub")
    assert BIP32.from_seed(os.urandom(32),
                           "main").get_master_xpriv().startswith("xprv")
示例#13
0
    def setup_device(self, mnemonic, passphrase, wallet_manager, testnet):
        seed = Mnemonic.to_seed(mnemonic)
        xprv = seed_to_hd_master_key(seed, testnet=testnet)
        wallet_name = os.path.join(wallet_manager.cli_path + '_hotstorage', self.alias)
        wallet_manager.cli.createwallet(wallet_name, False, True)
        cli = wallet_manager.cli.wallet(wallet_name)
        # TODO: Maybe more than 1000? Maybe add mechanism to add more later.
        ## NOTE: This will work only on the network the device was added, so hot devices should be filtered out by network.
        coin = int(testnet)
        cli.importmulti([
            { 'desc': AddChecksum('sh(wpkh({}/49h/{}h/0h/0/*))'.format(xprv, coin)), 'range': 1000, 'timestamp': 'now'},
            { 'desc': AddChecksum('sh(wpkh({}/49h/{}h/0h/1/*))'.format(xprv, coin)), 'range': 1000, 'timestamp': 'now'},
            { 'desc': AddChecksum('wpkh({}/84h/{}h/0h/0/*)'.format(xprv, coin)), 'range': 1000, 'timestamp': 'now'},
            { 'desc': AddChecksum('wpkh({}/84h/{}h/0h/1/*)'.format(xprv, coin)), 'range': 1000, 'timestamp': 'now'},
            { 'desc': AddChecksum('sh(wpkh({}/48h/{}h/0h/1h/0/*))'.format(xprv, coin)), 'range': 1000, 'timestamp': 'now'},
            { 'desc': AddChecksum('sh(wpkh({}/48h/{}h/0h/1h/1/*))'.format(xprv, coin)), 'range': 1000, 'timestamp': 'now'},
            { 'desc': AddChecksum('wpkh({}/48h/{}h/0h/2h/0/*)'.format(xprv, coin)), 'range': 1000, 'timestamp': 'now'},
            { 'desc': AddChecksum('wpkh({}/48h/{}h/0h/2h/1/*)'.format(xprv, coin)), 'range': 1000, 'timestamp': 'now'},
        ])
        if passphrase:
            cli.encryptwallet(passphrase)

        bip32 = BIP32.from_seed(seed)
        xpubs = ""
        master_fpr = get_xpub_fingerprint(bip32.get_xpub_from_path('m/0h')).hex()

        if not testnet:
            # Nested Segwit
            xpub = bip32.get_xpub_from_path('m/49h/0h/0h')
            ypub = convert_xpub_prefix(xpub, b'\x04\x9d\x7c\xb2')
            xpubs += "[%s/49'/0'/0']%s\n" % (master_fpr, ypub)
            # native Segwit
            xpub = bip32.get_xpub_from_path('m/84h/0h/0h')
            zpub = convert_xpub_prefix(xpub, b'\x04\xb2\x47\x46')
            xpubs += "[%s/84'/0'/0']%s\n" % (master_fpr, zpub)
            # Multisig nested Segwit
            xpub = bip32.get_xpub_from_path('m/48h/0h/0h/1h')
            Ypub = convert_xpub_prefix(xpub, b'\x02\x95\xb4\x3f')
            xpubs += "[%s/48'/0'/0'/1']%s\n" % (master_fpr, Ypub)
            # Multisig native Segwit
            xpub = bip32.get_xpub_from_path('m/48h/0h/0h/2h')
            Zpub = convert_xpub_prefix(xpub, b'\x02\xaa\x7e\xd3')
            xpubs += "[%s/48'/0'/0'/2']%s\n" % (master_fpr, Zpub)
        else:
            # Testnet nested Segwit
            xpub = bip32.get_xpub_from_path('m/49h/1h/0h')
            upub = convert_xpub_prefix(xpub, b'\x04\x4a\x52\x62')
            xpubs += "[%s/49'/1'/0']%s\n" % (master_fpr, upub)
            # Testnet native Segwit
            xpub = bip32.get_xpub_from_path('m/84h/1h/0h')
            vpub = convert_xpub_prefix(xpub, b'\x04\x5f\x1c\xf6')
            xpubs += "[%s/84'/1'/0']%s\n" % (master_fpr, vpub)
            # Testnet multisig nested Segwit
            xpub = bip32.get_xpub_from_path('m/48h/1h/0h/1h')
            Upub = convert_xpub_prefix(xpub, b'\x02\x42\x89\xef')
            xpubs += "[%s/48'/1'/0'/1']%s\n" % (master_fpr, Upub)
            # Testnet multisig native Segwit
            xpub = bip32.get_xpub_from_path('m/48h/1h/0h/2h')
            Vpub = convert_xpub_prefix(xpub, b'\x02\x57\x54\x83')
            xpubs += "[%s/48'/1'/0'/2']%s\n" % (master_fpr, Vpub)

        keys, failed = Key.parse_xpubs(xpubs)
        if len(failed) > 0:
            # TODO: This should never occur, but just in case, we must make sure to catch it properly so it doesn't crash the app no matter what.
            raise Exception("Failed to parse these xpubs:\n" + "\n".join(failed))
        else:
            self.add_keys(keys)