Ejemplo n.º 1
1
def test_duplicate_xfp(N, offer_ms_import, need_keypress, test_ms_show_addr):
    # it's legit to have duplicate XFP values! Not hard to make either!

    # new wallet will all having same XFP, but different xpubs
    pk = BIP32Node.from_wallet_key(simulator_fixed_xprv)

    keys = [(simulator_fixed_xfp, pk, pk.subkey(45, is_hardened=True, as_private=False))]
    lst = [keys[0][-1]]
    for idx in range(N-1):
        h = BIP32Node.from_hwif(pk.hwif(as_private=True))        # deepcopy
        h._chain_code = b'chain code is 32 bytes: %08d' % idx
        subkey = h.subkey(45, is_hardened=True, as_private=False)
        lst.append(subkey)

        xfp = unpack("<I", pk.fingerprint())[0]
        keys.append( (xfp, h, subkey) )

    #print(lst)

    # bare, no fingerprints
    # - no xfps
    # - no meta data
    config = '\n'.join(sk.hwif(as_private=False) for sk in lst)
    title, story = offer_ms_import(config)
    assert f'Policy: {N} of {N}\n' in story
    need_keypress('y')

    test_ms_show_addr(N, keys)
Ejemplo n.º 2
0
    def sign_transaction(self, tx, master_password, path=''):
        """
        Args:
            tx: hex transaction to sign
            master_password: master password for BIP32 wallets. Can be either a
                master_secret or a wif
            path (Optional[str]): optional path to the leaf address of the
                BIP32 wallet. This allows us to retrieve private key for the
                leaf address if one was used to construct the transaction.
        Returns:
            signed transaction

        .. note:: Only BIP32 hierarchical deterministic wallets are currently
            supported.

        """
        netcode = 'XTN' if self.testnet else 'BTC'

        # TODO review
        # check if its a wif
        try:
            BIP32Node.from_text(master_password)
            return bitcoin.signall(tx, master_password)
        except (AttributeError, EncodingError):
            # if its not get the wif from the master secret
            return bitcoin.signall(tx, BIP32Node.from_master_secret(master_password, netcode=netcode).subkey_for_path(path).wif())
    def sign_transaction(self, tx, master_password, path=''):
        """
        Args:
            tx: hex transaction to sign
            master_password: master password for BIP32 wallets. Can be either a
                master_secret or a wif
            path (Optional[str]): optional path to the leaf address of the
                BIP32 wallet. This allows us to retrieve private key for the
                leaf address if one was used to construct the transaction.
        Returns:
            signed transaction

        .. note:: Only BIP32 hierarchical deterministic wallets are currently
            supported.

        """
        netcode = 'XTN' if self.testnet else 'BTC'

        # TODO review
        # check if its a wif
        try:
            BIP32Node.from_text(master_password)
            return bitcoin.signall(tx, master_password)
        except (AttributeError, EncodingError):
            # if its not get the wif from the master secret
            return bitcoin.signall(
                tx,
                BIP32Node.from_master_secret(
                    master_password,
                    netcode=netcode).subkey_for_path(path).wif())
Ejemplo n.º 4
0
def test_refill_main_wallet(spool_regtest, rpconn):
    src_wallet_passowrd = uuid1().hex.encode('utf-8')
    src_wallet = BIP32Node.from_master_secret(src_wallet_passowrd,
                                              netcode='XTN')
    dest_wallet_passowrd = uuid1().hex.encode('utf-8')
    dest_wallet = BIP32Node.from_master_secret(dest_wallet_passowrd,
                                               netcode='XTN')
    src_address = src_wallet.bitcoin_address()
    dest_address = dest_wallet.bitcoin_address()
    rpconn.importaddress(src_address)
    rpconn.importaddress(dest_address)
    rpconn.sendtoaddress(src_address, 1)
    rpconn.generate(1)
    txid = spool_regtest.refill_main_wallet(
        ('', src_address),
        dest_address,
        1,
        1,
        src_wallet_passowrd,
        min_confirmations=1,
    )
    rpconn.generate(1)
    raw_txid = rpconn.getrawtransaction(txid)
    raw_tx = rpconn.decoderawtransaction(raw_txid)
    values = (vout['value'] * 100000000 for vout in raw_tx['vout']
              if vout['scriptPubKey']['addresses'].pop() == dest_address)
    assert spool_regtest.FEE in values
    assert spool_regtest.TOKEN in values
    assert (rpconn.getreceivedbyaddress(dest_address) *
            100000000 == spool_regtest.FEE + spool_regtest.TOKEN)
    def test_bip32(self):
        master = "tpubD9q6vq9zdP3gbhpjs7n2TRvT7h4PeBhxg1Kv9jEc1XAss7429VenxvQTsJaZhzTk54gnsHRpgeeNMbm1QTag4Wf1QpQ3gy221GDuUCxgfeZ"

        key = BIP32Node.from_hwif(master)

        self.assertEqual(
            b2x(key.sec()),
            "022f6b9339309e89efb41ecabae60e1d40b7809596c68c03b05deb5a694e33cd26"
        )

        self.assertEqual(
            key.subkey_for_path("0").hwif(),
            "tpubDAtJthHcm9MJwmHp4r2UwSTmiDYZWHbQUMqySJ1koGxQpRNSaJdyL2Ab8wwtMm5DsMMk3v68299LQE6KhT8XPQWzxPLK5TbTHKtnrmjV8Gg"
        )
        self.assertEqual(
            key.subkey_for_path("0/0").hwif(),
            "tpubDDfqpEKGqEVa5FbdLtwezc6Xgn81teTFFVA69ZfJBHp4UYmUmhqVZMmqXeJBDahvySZrPjpwMy4gKfNfrxuFHmzo1r6srB4MrsDKWbwEw3d"
        )

        key = BIP32Node.from_master_secret(
            x("000102030405060708090a0b0c0d0e0f"), "XTN")

        self.assertEqual(
            key.subkey_for_path("0'/1/2'/2/1000000000").hwif(),
            "tpubDHNy3kAG39ThyiwwsgoKY4iRenXDRtce8qdCFJZXPMCJg5dsCUHayp84raLTpvyiNA9sXPob5rgqkKvkN8S7MMyXbnEhGJMW64Cf4vFAoaF"
        )
Ejemplo n.º 6
0
 def test_streams(self):
     m0 = BIP32Node.from_master_secret("foo bar baz".encode("utf8"))
     pm0 = m0.public_copy()
     self.assertEqual(m0.wallet_key(), pm0.wallet_key())
     m1 = m0.subkey()
     pm1 = pm0.subkey()
     for i in range(4):
         m = m1.subkey(i=i)
         pm = pm1.subkey(i=i)
         self.assertEqual(m.wallet_key(), pm.wallet_key())
         self.assertEqual(m.bitcoin_address(), pm.bitcoin_address())
         m2 = BIP32Node.from_wallet_key(m.wallet_key(as_private=True))
         m3 = m2.public_copy()
         self.assertEqual(m.wallet_key(as_private=True), m2.wallet_key(as_private=True))
         self.assertEqual(m.wallet_key(), m3.wallet_key())
         print(m.wallet_key(as_private=True))
         for j in range(2):
             k = m.subkey(i=j)
             k2 = BIP32Node.from_wallet_key(k.wallet_key(as_private=True))
             k3 = BIP32Node.from_wallet_key(k.wallet_key())
             k4 = k.public_copy()
             self.assertEqual(k.wallet_key(as_private=True), k2.wallet_key(as_private=True))
             self.assertEqual(k.wallet_key(), k2.wallet_key())
             self.assertEqual(k.wallet_key(), k3.wallet_key())
             self.assertEqual(k.wallet_key(), k4.wallet_key())
             print("   %s %s" % (k.bitcoin_address(), k.wif()))
Ejemplo n.º 7
0
def test_b9p_vectors(dev,
                     set_seed_words,
                     need_keypress,
                     vector,
                     pw='RoZert'[::-1].upper()):
    # Test all BIP39 vectors. Slow.
    _, words, cooked, xprv = vector

    seed = Mnemonic.to_seed(words, passphrase=pw)
    assert seed == a2b_hex(cooked)

    set_seed_words(words)

    dev.send_recv(CCProtocolPacker.bip39_passphrase(pw), timeout=None)

    need_keypress('y')

    xpub = None
    while xpub == None:
        time.sleep(0.050)
        xpub = dev.send_recv(CCProtocolPacker.get_passphrase_done(),
                             timeout=None)

    # check our math (ignore testnet vs. mainnet)
    got = BIP32Node.from_wallet_key(xpub)
    exp = BIP32Node.from_wallet_key(xprv)

    assert got.public_pair() == exp.public_pair()
Ejemplo n.º 8
0
def test_refill_main_wallet(spool_regtest, rpconn):
    src_wallet_passowrd = uuid1().hex.encode('utf-8')
    src_wallet = BIP32Node.from_master_secret(src_wallet_passowrd,
                                              netcode='XTN')
    dest_wallet_passowrd = uuid1().hex.encode('utf-8')
    dest_wallet = BIP32Node.from_master_secret(dest_wallet_passowrd,
                                               netcode='XTN')
    src_address = src_wallet.bitcoin_address()
    dest_address = dest_wallet.bitcoin_address()
    rpconn.importaddress(src_address)
    rpconn.importaddress(dest_address)
    rpconn.sendtoaddress(src_address, 1)
    rpconn.generate(1)
    txid = spool_regtest.refill_main_wallet(
        ('', src_address),
        dest_address,
        1,
        1,
        src_wallet_passowrd,
        min_confirmations=1,
    )
    rpconn.generate(1)
    raw_txid = rpconn.getrawtransaction(txid)
    raw_tx = rpconn.decoderawtransaction(raw_txid)
    values = (vout['value'] * 100000000 for vout in raw_tx['vout'] if
              vout['scriptPubKey']['addresses'].pop() == dest_address)
    assert spool_regtest.FEE in values
    assert spool_regtest.TOKEN in values
    assert (rpconn.getreceivedbyaddress(dest_address) * 100000000 ==
            spool_regtest.FEE + spool_regtest.TOKEN)
Ejemplo n.º 9
0
    def init_wallet(self, identifier, passphrase):
        netcode = "XTN" if self.testnet else "BTC"

        data = self.get_wallet(identifier)

        primary_seed = Mnemonic.to_seed(data['primary_mnemonic'], passphrase)
        primary_private_key = BIP32Node.from_master_secret(primary_seed, netcode=netcode)

        backup_public_key = BIP32Node.from_hwif(data['backup_public_key'][0])

        checksum = self.create_checksum(primary_private_key)
        if checksum != data['checksum']:
            raise Exception("Checksum [%s] does not match expected checksum [%s], most likely due to incorrect password" % (checksum, data['checksum']))

        blocktrail_public_keys = data['blocktrail_public_keys']
        key_index = data['key_index']

        return Wallet(
            client=self,
            identifier=identifier,
            primary_mnemonic=data['primary_mnemonic'],
            primary_private_key=primary_private_key,
            backup_public_key=backup_public_key,
            blocktrail_public_keys=blocktrail_public_keys,
            key_index=key_index,
            testnet=self.testnet
        )
Ejemplo n.º 10
0
 def pycoinWallet(public_key=None,
                  public=True,
                  testnet=settings.BTC_TESTNET,
                  password=None):
     netcode = 'XTN' if testnet else 'BTC'
     if public:
         return BIP32Node.from_wallet_key(public_key)
     else:
         assert not password is None
         return BIP32Node.from_master_secret(password, netcode=netcode)
Ejemplo n.º 11
0
def test_export_electrum(mode, dev, cap_menu, pick_menu_item, goto_home,
                         cap_story, need_keypress, microsd_path):
    # lightly test electrum wallet export

    goto_home()
    pick_menu_item('Advanced')
    pick_menu_item('MicroSD Card')
    pick_menu_item('Export Wallet')
    pick_menu_item('Electrum Wallet')

    time.sleep(0.1)
    title, story = cap_story()

    assert 'This saves a skeleton Electrum wallet' in story

    need_keypress('y')

    time.sleep(0.1)
    pick_menu_item(mode)

    time.sleep(0.1)
    title, story = cap_story()

    assert 'wallet file written' in story
    fname = story.split('\n')[-1]

    need_keypress('y')

    path = microsd_path(fname)
    with open(path, 'rt') as fp:
        obj = json.load(fp)

        ks = obj['keystore']
        assert ks['ckcc_xfp'] == simulator_fixed_xfp

        assert ks['hw_type'] == 'coldcard'
        assert ks['type'] == 'hardware'

        deriv = ks['derivation']
        assert deriv.startswith('m/')
        assert int(deriv.split("/")[1][:-1]) in {44, 84, 49}  # weak

        xpub = ks['xpub']
        assert xpub[1:4] == 'pub'

        if xpub[0] in 'tx':
            # no slip132 here

            got = BIP32Node.from_wallet_key(xpub)
            expect = BIP32Node.from_wallet_key(
                simulator_fixed_xprv).subkey_for_path(deriv[2:])

            assert got.sec() == expect.sec()

    os.unlink(path)
Ejemplo n.º 12
0
def test_public(sim_execfile):
    "verify contents of public 'dump' file"
    from pycoin.key.BIP32Node import BIP32Node
    from pycoin.contrib.segwit_addr import encode as sw_encode
    from pycoin.contrib.segwit_addr import decode as sw_decode
    from pycoin.encoding import a2b_hashed_base58, hash160

    pub = sim_execfile('devtest/dump_public.py')
    assert 'Error' not in pub

    #print(pub)

    pub, dev = pub.split('#DEBUG#', 1)
    assert 'pub' in pub
    assert 'prv' not in pub
    assert 'prv' in dev

    lines = [i.strip() for i in pub.split('\n')]

    for ln in lines:
        if ln[1:4] == 'pub':
            node_pub = BIP32Node.from_wallet_key(ln)
            break

    node_prv = BIP32Node.from_wallet_key(dev.strip())

    # pub and private are linked
    assert node_prv.hwif(as_private=False) == node_pub.hwif()

    # check every path we derived
    count = 0
    for ln in lines:
        if ln[0:1] == 'm' and '=>' in ln:
            subpath, result = ln.split(' => ', 1)

            sk = node_prv.subkey_for_path(subpath[2:])

            if result[0:2] in {'tp', 'xp'}:
                expect = BIP32Node.from_wallet_key(result)
                assert sk.hwif(as_private=False) == result
            elif result[0] in '1mn':
                assert result == sk.address(False)
            elif result[0:3] in {'bc1', 'tb1'}:
                h20 = sk.hash160()
                assert result == sw_encode(result[0:2], 0, h20)
            elif result[0] in '23':
                h20 = hash160(b'\x00\x14' + sk.hash160())
                assert h20 == a2b_hashed_base58(result)[1:]
            else:
                raise ValueError(result)

            count += 1
            print("OK: %s" % ln)

    assert count > 12
Ejemplo n.º 13
0
    def doit(given_addr, path=None, addr_fmt=None, script=None):
        if not script:
            try:
                # prefer using xpub if we can
                mk = BIP32Node.from_wallet_key(master_xpub)
                sk = mk.subkey_for_path(path[2:])
            except PublicPrivateMismatchError:
                mk = BIP32Node.from_wallet_key(simulator_fixed_xprv)
                sk = mk.subkey_for_path(path[2:])


        if addr_fmt == AF_CLASSIC:
            # easy
            assert sk.address() == given_addr

        elif addr_fmt & AFC_PUBKEY:

            pkh = sk.hash160(use_uncompressed=False)

            if addr_fmt == AF_P2WPKH:
                hrp, data = bech32_decode(given_addr)
                decoded = convertbits(data[1:], 5, 8, False)
                assert hrp in {'tb', 'bc' }
                assert bytes(decoded[-20:]) == pkh
            else:
                assert addr_fmt == AF_P2WPKH_P2SH
                assert given_addr[0] in '23'
                expect = a2b_hashed_base58(given_addr)[1:]
                assert len(expect) == 20
                assert hash160(b'\x00\x14' + pkh) == expect

        elif addr_fmt & AFC_SCRIPT:
            assert script, 'need a redeem/witness script'
            if addr_fmt == AF_P2SH:
                assert given_addr[0] in '23'
                expect = a2b_hashed_base58(given_addr)[1:]
                assert hash160(script) == expect

            elif addr_fmt == AF_P2WSH:
                hrp, data = bech32_decode(given_addr)
                assert hrp in {'tb', 'bc' }
                decoded = convertbits(data[1:], 5, 8, False)
                assert bytes(decoded[-32:]) == sha256(script).digest()

            elif addr_fmt == AF_P2WSH_P2SH:
                assert given_addr[0] in '23'
                expect = a2b_hashed_base58(given_addr)[1:]
                assert hash160(b'\x00\x20' + sha256(script).digest()) == expect

            else:
                raise pytest.fail(f'not ready for {addr_fmt:x} yet')
        else:
            raise ValueError(addr_fmt)

        return sk if not script else None
Ejemplo n.º 14
0
    def sign_transaction(self, tx, master_password, path=''):
        # master_password can be either a master_secret or a wif
        netcode = 'XTN' if self.testnet else 'BTC'

        # check if its a wif
        try:
            BIP32Node.from_text(master_password)
            return pybitcointools.signall(tx, master_password)
        except EncodingError:
            # if its not get the wif from the master secret
            return pybitcointools.signall(tx, BIP32Node.from_master_secret(master_password, netcode=netcode).subkey_for_path(path).wif())
Ejemplo n.º 15
0
 def pycoinPassword(user, password):
     # check if password is a wif. It it is return it witouth appending the email
     try:
         BIP32Node.from_text(password)
         return password
     except EncodingError:
         # backwards compatibility for collision of public wallets with same password
         if user.date_joined > datetime(2014, 12, 15).replace(tzinfo=pytz.UTC) \
                 and not user == util.mainAdminUser():
             return password + user.email
         return password
Ejemplo n.º 16
0
 def treegen(value, entropy=False):
     if entropy:
         # this method also takes a netcode parameter, but we don't care
         # what network pycoin thinks this node is, because we only use it
         # for key derivation.
         return BIP32Node.from_master_secret(unhexlify(value))
     else:
         # this method will infer a network from the header bytes. We
         # don't care right now for the same reason as above, but we will
         # if Gem's API stops returning 'xpub' as the pubkey header bytes
         # because if pycoin doesn't recognize a header it will error.
         return BIP32Node.from_hwif(value)
Ejemplo n.º 17
0
    def doit(M, addr_fmt=None, do_import=True):
        passwords = ['Me', 'Myself', 'And I', '']

        if 0:
            # WORKING, but slow .. and it's constant data
            keys = []
            for pw in passwords:
                xfp = set_bip39_pw(pw)

                sk = dev.send_recv(CCProtocolPacker.get_xpub("m/45'"))
                node = BIP32Node.from_wallet_key(sk)

                keys.append((xfp, None, node))

            assert len(set(x for x,_,_ in keys)) == 4, keys
            pprint(keys)
        else:
            # Much, FASTER!
            assert dev.is_simulator
            keys = [(3503269483, None,
                        BIP32Node.from_hwif('tpubD9429UXFGCTKJ9NdiNK4rC5ygqSUkginycYHccqSg5gkmyQ7PZRHNjk99M6a6Y3NY8ctEUUJvCu6iCCui8Ju3xrHRu3Ez1CKB4ZFoRZDdP9')),
                     (2389277556, None,
                        BIP32Node.from_hwif('tpubD97nVL37v5tWyMf9ofh5rznwhh1593WMRg6FT4o6MRJkKWANtwAMHYLrcJFsFmPfYbY1TE1LLQ4KBb84LBPt1ubvFwoosvMkcWJtMwvXgSc')),
                 (3190206587, None,
                        BIP32Node.from_hwif('tpubD9ArfXowvGHnuECKdGXVKDMfZVGdephVWg8fWGWStH3VKHzT4ph3A4ZcgXWqFu1F5xGTfxncmrnf3sLC86dup2a8Kx7z3xQ3AgeNTQeFxPa')),
                (1130956047, None,
                        BIP32Node.from_hwif('tpubD8NXmKsmWp3a3DXhbihAYbYLGaRNVdTnr6JoSxxfXYQcmwVtW2hv8QoDwng6JtEonmJoL3cNEwfd2cLXMpGezwZ2vL2dQ7259bueNKj9C8n')),
            ]

        if do_import:
            # render as a file for import
            config = f"name: Myself-{M}\npolicy: {M} / 4\n\n"

            if addr_fmt:
                config += f'format: {addr_fmt.upper()}\n'

            config += '\n'.join('%s: %s' % (xfp2str(xfp), sk.hwif()) for xfp, _, sk in keys)
            #print(config)

            title, story = offer_ms_import(config)
            #print(story)

            # dont care if update or create; accept it.
            time.sleep(.1)
            need_keypress('y')

        def select_wallet(idx):
            # select to specific pw
            xfp = set_bip39_pw(passwords[idx])
            assert xfp == keys[idx][0]

        return (keys, select_wallet)
Ejemplo n.º 18
0
    def doit(M, N, unique=0):
        keys = []

        for i in range(N-1):
            pk = BIP32Node.from_master_secret(b'CSW is a fraud %d - %d' % (i, unique), 'XTN')

            xfp = unpack("<I", pk.fingerprint())[0]

            sub = pk.subkey(45, is_hardened=True, as_private=True)
            keys.append((xfp, pk, sub))

        pk = BIP32Node.from_wallet_key(simulator_fixed_xprv)
        keys.append((simulator_fixed_xfp, pk, pk.subkey(45, is_hardened=True, as_private=True)))

        return keys
Ejemplo n.º 19
0
    def sign_transaction(self, tx, master_password, path=''):
        # master_password can be either a master_secret or a wif
        netcode = 'XTN' if self.testnet else 'BTC'

        # check if its a wif
        try:
            BIP32Node.from_text(master_password)
            return pybitcointools.signall(tx, master_password)
        except EncodingError:
            # if its not get the wif from the master secret
            return pybitcointools.signall(
                tx,
                BIP32Node.from_master_secret(
                    master_password,
                    netcode=netcode).subkey_for_path(path).wif())
Ejemplo n.º 20
0
def test_refill_fuel(spool_regtest, rpconn):
    src_wallet_passowrd = uuid1().hex.encode('utf-8')
    src_wallet = BIP32Node.from_master_secret(src_wallet_passowrd,
                                              netcode='XTN')
    dest_wallet_passowrd = uuid1().hex.encode('utf-8')
    dest_wallet = BIP32Node.from_master_secret(dest_wallet_passowrd,
                                               netcode='XTN')
    src_address = src_wallet.bitcoin_address()
    dest_address = dest_wallet.bitcoin_address()
    rpconn.importaddress(src_address)
    rpconn.importaddress(dest_address)
    rpconn.sendtoaddress(src_address, spool_regtest.FEE/100000000)
    rpconn.sendtoaddress(src_address, spool_regtest.FEE/100000000)
    rpconn.sendtoaddress(
        src_address, spool_regtest.TOKEN/100000000)
    rpconn.generate(1)
    txid = spool_regtest.refill(
        ('', src_address),
        dest_address,
        1,
        1,
        src_wallet_passowrd,
        min_confirmations=1,
    )
    rpconn.generate(1)
    raw_txid = rpconn.getrawtransaction(txid)
    raw_tx = rpconn.decoderawtransaction(raw_txid)
    values = (vout['value'] * 100000000 for vout in raw_tx['vout'] if
              vout['scriptPubKey']['addresses'].pop() == dest_address)
    values = []
    asm = None
    for vout in raw_tx['vout']:
        try:
            addr = vout['scriptPubKey']['addresses'].pop()
        except KeyError:
            asm = vout['scriptPubKey']['asm']
        else:
            if addr == dest_address:
                values.append(vout['value'] * 100000000)

    assert spool_regtest.FEE in values
    assert spool_regtest.TOKEN in values
    assert asm.split(' ')[0] == 'OP_RETURN'
    assert asm.split(' ')[1] == '4153435249424553504f4f4c30314655454c'
    assert spool_regtest.FEE in values
    assert spool_regtest.TOKEN in values
    assert (rpconn.getreceivedbyaddress(dest_address) * 100000000 ==
            spool_regtest.FEE + spool_regtest.TOKEN)
Ejemplo n.º 21
0
def search(target_xfp):
    k = BIP32Node.from_hwif(
        "tprv8ZgxMBicQKsPeXJHL3vPPgTAEqQ5P2FD9qDeCQT4Cp1EMY5QkwMPWFxHdxHrxZhhcVRJ2m7BNWTz9Xre68y7mX5vCdMJ5qXMUfnrZ2si2X4"
    )

    pid = os.getpid()
    target_xfp = h2b_rev(target_xfp)

    # test by going -33 here.
    #sec_exp = k._secret_exponent - 33
    sec_exp = k._secret_exponent + (pid * int(1e40))

    i = 0
    last_xfp = None
    while 1:
        i += 1
        sec_exp += 1

        public_pair = ecdsa.public_pair_for_secret_exponent(
            ecdsa.generator_secp256k1, sec_exp)

        xfp = public_pair_to_hash160_sec(public_pair, compressed=True)[:4]

        if i <= 5:
            # checking code (slow)
            b = BIP32Node(netcode='BTC',
                          chain_code=bytes(32),
                          secret_exponent=sec_exp)
            chk = b.fingerprint()
            assert b._secret_exponent == sec_exp
            assert xfp == chk, (xfp, chk)

        assert xfp != last_xfp, 'repeat xfp!'
        last_xfp = xfp

        if xfp == target_xfp:
            print(f"\n\nFOUND: sec_exp = {sec_exp}\n")
            b = BIP32Node(netcode='BTC',
                          chain_code=bytes(32),
                          secret_exponent=sec_exp)
            chk = b.fingerprint()
            assert b._secret_exponent == sec_exp
            assert xfp == chk, (xfp, chk)
            print(b.hwif(), end='\n\n')
            return

        if not (i % 27):
            print('  %6d %9d' % (pid, i), end='\r')
Ejemplo n.º 22
0
    def __init__(self, pkey=None, secret=None):

        if secret is not None:
            pkey = format(
                BIP32Node.from_master_secret(
                    secret.encode('utf-8')).secret_exponent(), "064x")

        elif pkey is None:
            try:
                pkey = format(
                    BIP32Node.from_master_secret(
                        urandom(4096)).secret_exponent(), '064x')
            except NotImplementedError as e:
                raise ValueError('No randomness source found: %s' % e)

        self.keypair = Key(secret_exponent=int(pkey, 16))
Ejemplo n.º 23
0
def create_key(asset, netcode="BTC"):
    secure_random_data = os.urandom(32)
    key = BIP32Node.from_master_secret(secure_random_data, netcode=netcode)
    return {
        "asset": asset, "pubkey": b2h(key.sec()),
        "wif": key.wif(), "address": key.address(),
    }
Ejemplo n.º 24
0
Archivo: Key.py Proyecto: Zibbo/pycoin
    def from_text(class_, text, is_compressed=True):
        """
        This function will accept a BIP0032 wallet string, a WIF, or a bitcoin address.

        The "is_compressed" parameter is ignored unless a public address is passed in.
        """

        data = a2b_hashed_base58(text)
        netcode, key_type = netcode_and_type_for_data(data)
        data = data[1:]

        if key_type in ("pub32", "prv32"):
            # TODO: fix this... it doesn't belong here
            from pycoin.key.BIP32Node import BIP32Node
            return BIP32Node.from_wallet_key(text)

        if key_type == 'wif':
            is_compressed = (len(data) > 32)
            if is_compressed:
                data = data[:-1]
            return Key(
                secret_exponent=from_bytes_32(data),
                prefer_uncompressed=not is_compressed, netcode=netcode)
        if key_type == 'address':
            return Key(hash160=data, is_compressed=is_compressed, netcode=netcode)
        raise EncodingError("unknown text: %s" % text)
Ejemplo n.º 25
0
def test_create_sign_push_transaction(transactions, rpcconn):
    alice = BIP32Node.from_master_secret(b"alice-secret", netcode="XTN").bitcoin_address()
    bob = BIP32Node.from_master_secret(b"bob-secret", netcode="XTN").bitcoin_address()
    rpcconn.importaddress(alice)
    rpcconn.importaddress(bob)
    rpcconn.sendtoaddress(alice, 3)
    rpcconn.generate(1)
    raw_tx = transactions.create(alice, (bob, 200000000), min_confirmations=1)
    assert raw_tx
    signed_tx = transactions.sign(raw_tx, b"alice-secret")
    assert signed_tx
    bob_before = rpcconn.getreceivedbyaddress(bob)
    pushed_tx = transactions.push(signed_tx)
    assert pushed_tx
    rpcconn.generate(1)  # pack the transaction into a block
    assert rpcconn.getreceivedbyaddress(bob) - bob_before == 2
Ejemplo n.º 26
0
def test_get_addresses(rpconn, piece_hashes, spool_regtest, transactions):
    from spool import Spool
    from spool.spoolex import BlockchainSpider
    sender_password = uuid1().hex.encode('utf-8')
    sender_wallet = BIP32Node.from_master_secret(sender_password,
                                                 netcode='XTN')
    sender_address = sender_wallet.bitcoin_address()
    rpconn.importaddress(sender_address)
    rpconn.sendtoaddress(sender_address, Spool.FEE/100000000)
    rpconn.sendtoaddress(sender_address, Spool.TOKEN/100000000)
    rpconn.sendtoaddress(sender_address, Spool.TOKEN/100000000)
    rpconn.sendtoaddress(sender_address, Spool.TOKEN/100000000)
    rpconn.generate(1)
    receiver_address = rpconn.getnewaddress()
    # TODO do not rely on Spool
    txid = spool_regtest.transfer(
        ('', sender_address),
        receiver_address,
        piece_hashes,
        sender_password,
        5,
        min_confirmations=1,
    )
    decoded_raw_transfer_tx = transactions.get(txid)
    addresses = BlockchainSpider._get_addresses(decoded_raw_transfer_tx)
    assert len(addresses) == 3
    assert addresses[0] == sender_address
    assert addresses[1] == receiver_address
    assert addresses[2] == piece_hashes[0]
Ejemplo n.º 27
0
def master_xpub(dev):
    r = dev.send_recv(CCProtocolPacker.get_xpub('m'), timeout=None, encrypt=1)

    assert r[1:4] == 'pub', r

    if r[0:4] == dev.master_xpub[0:4]:
        assert r == dev.master_xpub
    elif dev.master_xpub:
        # testnet vs. mainnet difference
        from pycoin.key.BIP32Node import BIP32Node
        a = BIP32Node.from_wallet_key(r)
        b = BIP32Node.from_wallet_key(dev.master_xpub)

        assert a.secret_exponent() == b.secret_exponent()

    return r
Ejemplo n.º 28
0
    def doit(given_addr, path, addr_fmt):
        mk = BIP32Node.from_wallet_key(master_xpub)
        sk = mk.subkey_for_path(path[2:])

        if addr_fmt == AF_CLASSIC:
            # easy
            assert sk.address() == given_addr

        elif addr_fmt & AFC_PUBKEY:

            pkh = sk.hash160(use_uncompressed=False)

            if addr_fmt == AF_P2WPKH:
                hrp, data = bech32_decode(given_addr)
                decoded = convertbits(data[1:], 5, 8, False)
                assert hrp in {'tb', 'bc'}
                assert bytes(decoded[-20:]) == pkh
            else:
                assert addr_fmt == AF_P2WPKH_P2SH
                assert given_addr[0] in '23'
                expect = a2b_hashed_base58(given_addr)[1:]
                assert len(expect) == 20
                assert hash160(b'\x00\x14' + pkh) == expect

        elif addr_fmt & AFC_SCRIPT:
            raise pytest.fail('multisig/p2sh addr not handled')
        else:
            raise ValueError(addr_fmt)
Ejemplo n.º 29
0
def test_sign_msg_microsd_good(sign_on_microsd, master_xpub, msg, path, addr_vs_path, addr_fmt=AF_CLASSIC):

    # cases we expect to work
    sig, addr = sign_on_microsd(msg, path)

    raw = b64decode(sig)
    assert 40 <= len(raw) <= 65

    if addr_fmt != AF_CLASSIC:
        # TODO
        # - need bech32 decoder here
        # - pycoin can't do signature decode
        if addr_fmt & AFC_BECH32:
            assert '1' in addr
        return

    if path is None:
        path = 'm'

    if "'" not in path and 'p' not in path:
        # check expected addr was used
        mk = BIP32Node.from_wallet_key(master_xpub)
        sk = mk.subkey_for_path(path[2:])

        addr_vs_path(addr, path, addr_fmt)
    
        # verify signature
        assert verify_message(sk, sig, message=msg) == True
    else:
        # just verify signature
        assert verify_message(addr, sig, message=msg) == True
Ejemplo n.º 30
0
 def create_bip32node(self, slug, random_bytes):
     bip32_node = BIP32Node.from_master_secret(random_bytes)
     bip32_text = bip32_node.as_text(as_private=True)
     c = self._exec_sql(
         "insert into BIP32Key (slug, as_text) values (?, ?)", slug,
         bip32_text)
     return self.bip32node_for_slug(slug)
Ejemplo n.º 31
0
def test_import_prv(goto_home, pick_menu_item, cap_story, need_keypress, unit_test, cap_menu, word_menu_entry, get_secrets, microsd_path, multiple_runs, reset_seed_words):
    
    unit_test('devtest/clear_seed.py')

    fname = 'test-%d.txt' % os.getpid()
    path = microsd_path(fname)

    from pycoin.key.BIP32Node import BIP32Node
    node = BIP32Node.from_master_secret(os.urandom(32))
    open(path, 'wt').write(node.hwif(as_private=True)+'\n')
    print("Created: %s" % path)

    m = cap_menu()
    assert m[0] == 'New Wallet'    
    pick_menu_item('Import Existing')
    pick_menu_item('Import XPRV')

    title, body = cap_story()
    assert 'Select file' in body
    need_keypress('y'); time.sleep(.01) 

    pick_menu_item(fname)
    unit_test('devtest/abort_ux.py')

    v = get_secrets()

    assert v['xpub'] == node.hwif()
    assert v['xprv'] == node.hwif(as_private=True)

    reset_seed_words()
Ejemplo n.º 32
0
 def generate_xpriv(self, root_seed) -> str:
     BIP32Node = self._network.ui._bip32node_class
     master_key = BIP32Node.from_master_secret(root_seed)
     account_key = master_key.subkey_for_path(
         f"44p/{self._currency_number}p/0p")
     account_xpriv = self._get_priv(account_key)
     return account_xpriv
Ejemplo n.º 33
0
Archivo: Key.py Proyecto: wpr101/pycoin
    def from_text(class_, text, is_compressed=True):
        """
        This function will accept a BIP0032 wallet string, a WIF, or a bitcoin address.

        The "is_compressed" parameter is ignored unless a public address is passed in.
        """

        data = a2b_hashed_base58(text)
        netcode, key_type, length = netcode_and_type_for_data(data)
        data = data[1:]

        if key_type in ("pub32", "prv32"):
            # TODO: fix this... it doesn't belong here
            from pycoin.key.BIP32Node import BIP32Node
            return BIP32Node.from_wallet_key(text)

        if key_type == 'wif':
            is_compressed = (len(data) > 32)
            if is_compressed:
                data = data[:-1]
            return Key(
                secret_exponent=from_bytes_32(data),
                prefer_uncompressed=not is_compressed, netcode=netcode)
        if key_type == 'address':
            return Key(hash160=data, is_compressed=is_compressed, netcode=netcode)
        raise EncodingError("unknown text: %s" % text)
Ejemplo n.º 34
0
 def __init__(self,
              puzzle_scripts,
              generator,
              bip32_prv_prefix=None,
              bip32_pub_prefix=None,
              wif_prefix=None,
              sec_prefix=None,
              address_prefix=None,
              pay_to_script_prefix=None,
              bech32_hrp=None):
     self._script_info = puzzle_scripts
     self._key_class = Key.make_subclass(ui_context=self,
                                         generator=generator)
     self._electrum_class = ElectrumWallet.make_subclass(
         ui_context=self, generator=generator)
     self._bip32node_class = BIP32Node.make_subclass(ui_context=self,
                                                     generator=generator)
     self._parsers = [
         WIFParser(generator, wif_prefix, address_prefix, self._key_class),
         ElectrumParser(generator, self._electrum_class),
         BIP32Parser(generator, bip32_prv_prefix, bip32_pub_prefix,
                     self._bip32node_class),
         Hash160Parser(address_prefix, self._key_class),
         SECParser(generator, sec_prefix, self._key_class),
         AddressParser(puzzle_scripts, address_prefix, pay_to_script_prefix,
                       bech32_hrp)
     ]
     self._bip32_prv_prefix = bip32_prv_prefix
     self._bip32_pub_prefix = bip32_pub_prefix
     self._wif_prefix = wif_prefix
     self._sec_prefix = sec_prefix
     self._address_prefix = address_prefix
     self._pay_to_script_prefix = pay_to_script_prefix
     self._bech32_hrp = bech32_hrp
Ejemplo n.º 35
0
    def mitm_verify(self, sig, expected_xpub):
        # First try with Pycoin
        try:
            from pycoin.key.BIP32Node import BIP32Node
            from pycoin.contrib.msg_signing import verify_message
            from pycoin.encoding import from_bytes_32
            from base64 import b64encode

            mk = BIP32Node.from_wallet_key(expected_xpub)
            return verify_message(mk,
                                  b64encode(sig),
                                  msg_hash=from_bytes_32(self.session_key))
        except ImportError:
            pass

        # If Pycoin is not available, do it using ecdsa
        from ecdsa import BadSignatureError, SECP256k1, VerifyingKey
        pubkey, chaincode = decode_xpub(expected_xpub)
        vk = VerifyingKey.from_string(get_pubkey_string(pubkey),
                                      curve=SECP256k1)
        try:
            ok = vk.verify_digest(sig[1:], self.session_key)
        except BadSignatureError:
            ok = False

        return ok
Ejemplo n.º 36
0
    def __init__(self, private={}, public={}, private_seeds={}):
        # It is possible to distinguish between private and public seeds
        # based on the string content.  Consider modifying this function
        # to take merely one dict of seeds.  Trees should still be stored
        # separately.
        self.trees = {}
        self.private_trees = {}
        self.public_trees = {}

        def treegen(value, entropy=False):
            if entropy:
                # this method also takes a netcode parameter, but we don't care
                # what network pycoin thinks this node is, because we only use it
                # for key derivation.
                return BIP32Node.from_master_secret(unhexlify(value))
            else:
                # this method will infer a network from the header bytes. We
                # don't care right now for the same reason as above, but we will
                # if Gem's API stops returning 'xpub' as the pubkey header bytes
                # because if pycoin doesn't recognize a header it will error.
                return BIP32Node.from_hwif(value)

        for name, seed in iteritems(private):
            tree = treegen(seed)
            self.private_trees[name] = self.trees[name] = tree

        for name, seed in iteritems(private_seeds):
            tree = treegen(seed, True)
            self.private_trees[name] = self.trees[name] = tree

        for name, seed in iteritems(public):
            tree = BIP32Node.from_hwif(seed)
            self.public_trees[name] = self.trees[name] = tree
Ejemplo n.º 37
0
def test_stub_menu(sim_execfile, goto_address_explorer, need_keypress,
                   cap_menu, mk_common_derivations, parse_display_screen,
                   validate_address):
    # For a given wallet, ensure the explorer shows the correct stub addresses
    node_prv = BIP32Node.from_wallet_key(
        sim_execfile('devtest/dump_private.py').strip())
    common_derivs = mk_common_derivations(node_prv.netcode())

    # capture menu address stubs
    goto_address_explorer()
    need_keypress('4')
    time.sleep(.01)
    m = cap_menu()

    for idx, (path, addr_format) in enumerate(common_derivs):
        # derive index=0 address
        subpath = path.format(account=0, change=0,
                              idx=0)  # e.g. "m/44'/1'/0'/0/0"
        sk = node_prv.subkey_for_path(subpath[2:])

        # capture full index=0 address from display screen & validate it
        goto_address_explorer(click_idx=idx)
        addr_dict = parse_display_screen(0, 10)
        if subpath not in addr_dict:
            raise Exception(
                'Subpath ("%s") not found in address explorer display' %
                subpath)
        expected_addr = addr_dict[subpath]
        validate_address(expected_addr, sk)

        # validate that stub is correct
        [start, end] = m[idx].split('-')
        assert expected_addr.startswith(start)
        assert expected_addr.endswith(end)
Ejemplo n.º 38
0
def prefix_transforms_for_network(network):
    def _create_bip32(_):
        max_retries = 64
        for _ in range(max_retries):
            try:
                return BIP32Node.from_master_secret(get_entropy(), netcode=network)
            except ValueError as e:
                continue
        # Probably a bug if we get here
        raise RuntimeError("can't create BIP32 key")

    return (
        ("P:", lambda s: BIP32Node.from_master_secret(s.encode("utf8"), netcode=network)),
        ("H:", lambda s: BIP32Node.from_master_secret(h2b(s), netcode=network)),
        ("E:", lambda s: key_from_text(s)),
        ("create", _create_bip32),
    )
 def bip32node_for_slug(self, slug):
     c = self._exec_sql("select id, as_text from BIP32Key where slug=?", slug)
     r = c.fetchone()
     if r is None:
         return None
     bip32_node = BIP32Node.from_hwif(r[1])
     bip32_node.id = r[0]
     return bip32_node
Ejemplo n.º 40
0
 def test_testnet(self):
     # WARNING: these values have not been verified independently. TODO: do so
     master = BIP32Node.from_master_secret(h2b("000102030405060708090a0b0c0d0e0f"), netcode='XTN')
     self.assertEqual(
         master.wallet_key(as_private=True),
         "tprv8ZgxMBicQKsPeDgjzdC36fs6bMjGApWDNLR9erAXMs5skhMv36j9MV5ecvfavji5kh"
         "qjWaWSFhN3YcCUUdiKH6isR4Pwy3U5y5egddBr16m")
     self.assertEqual(master.bitcoin_address(), "mkHGce7dctSxHgaWSSbmmrRWsZfzz7MxMk")
     self.assertEqual(master.wif(), "cVPXTF2TnozE1PenpP3x9huctiATZmp27T9Ue1d8nqLSExoPwfN5")
Ejemplo n.º 41
0
 def create(self):
     network = "BTC"
     if not self.proxy.use_production:
         network = "XTN"
     entropy = "".join([chr(random.getrandbits(8)) for i in range(32)])
     key = BIP32Node.from_master_secret(entropy, network)
     private = key.wallet_key(as_private=True).encode("utf-8")
     public = key.wallet_key(as_private=False).encode("utf-8")
     return {"xpub": public, "xprv": private}
Ejemplo n.º 42
0
 def _create_bip32(_):
     max_retries = 64
     for _ in range(max_retries):
         try:
             return BIP32Node.from_master_secret(get_entropy(), netcode=network)
         except ValueError as e:
             continue
     # Probably a bug if we get here
     raise RuntimeError("can't create BIP32 key")
Ejemplo n.º 43
0
 def create_new_address(self):
     n = n_addresses.incr()
     bip32node = BIP32Node.from_hwif(xpub.get())
     subkey = bip32node.subkey(0).subkey(n)  # match electrum path
     new_address = subkey.address()
     addr_to_uid[new_address] = self.uid
     uid_to_addr[self.uid] = new_address
     all_addresses.add(new_address)
     return True
Ejemplo n.º 44
0
 def _create(_):
     max_retries = 64
     for _ in range(max_retries):
         try:
             return BIP32Node.from_master_secret(get_entropy(), netcode=args.network)
         except ValueError as e:
             continue
     # Probably a bug if we get here
     raise e
Ejemplo n.º 45
0
def cosign_spend_request(xprvkey_or_wallet, req_keys, inputs, xpub_check):
    """
        Sign the inputs of a transaction, given the sighashs and subkey paths for each input

    Args:
        xprvkey_or_wallet = 111-char base58 encoded serialization of BIP32 wallet
                            or pycoin.key.BIP32Node object (w/ private key)

        req_keys = dictionary: key is subpath ('a/b/c', but only 'a' for now as a string)
                    value is tuple: (address, public pair) ... optional checking data

        inputs = list of by transaction input: (subpath, sighash_all value)

    Returns:
        list of 3-tuples: (der-encoded signature, sighash, subpath)

    """

    # We need just these features from pycoin <https://github.com/richardkiss/pycoin>
    from pycoin import ecdsa
    from pycoin.key.BIP32Node import BIP32Node
    from pycoin.tx.script import der

    # We need a BIP32 "wallet" for the root of all keys.
    if isinstance(xprvkey_or_wallet, basestring):
        wallet = BIP32Node.from_wallet_key(xprvkey_or_wallet.strip())
    else:
        wallet = xprvkey_or_wallet

    # Verify we are looking at the right extended private key
    check = wallet.hwif(as_private=False)[-len(xpub_check) :]
    if check != xpub_check:
        raise ValueError("This private key isn't the right one for xpub...%s" % xpub_check)

    # Make the right subkey for each inputs
    wallets = {}
    for sp, (addr_check, ppair) in req_keys.items():
        w = wallet.subkey_for_path(sp)
        assert w.bitcoin_address() == addr_check
        assert w.public_pair() == tuple(ppair)
        wallets[sp] = w

    # Generate a signature for each input required
    sigs = []
    SIGHASH_ALL = 1
    order = ecdsa.generator_secp256k1.order()
    for sp, sighash in inputs:
        sighash_int = int(sighash, 16)
        r, s = ecdsa.sign(ecdsa.generator_secp256k1, wallets[sp].secret_exponent(), sighash_int)
        if s + s > order:
            s = order - s
        sig = der.sigencode_der(r, s) + chr(SIGHASH_ALL)
        sigs.append((sig.encode("hex"), sighash, sp))

    return sigs
Ejemplo n.º 46
0
    def test_vector_1(self):
        master = BIP32Node.from_master_secret(h2b("000102030405060708090a0b0c0d0e0f"))
        self.assertEqual(master.wallet_key(as_private=True), "xprv9s21ZrQH143K3QTDL4LXw2F7HEK3wJUD2nW2nRk4stbPy6cq3jPPqjiChkVvvNKmPGJxWUtg6LnF5kejMRNNU3TGtRBeJgk33yuGBxrMPHi")
        self.assertEqual(master.bitcoin_address(), "15mKKb2eos1hWa6tisdPwwDC1a5J1y9nma")
        self.assertEqual(master.wif(), "L52XzL2cMkHxqxBXRyEpnPQZGUs3uKiL3R11XbAdHigRzDozKZeW")

        self.assertEqual(master.wallet_key(), "xpub661MyMwAqRbcFtXgS5sYJABqqG9YLmC4Q1Rdap9gSE8NqtwybGhePY2gZ29ESFjqJoCu1Rupje8YtGqsefD265TMg7usUDFdp6W1EGMcet8")

        m0p = master.subkey(is_hardened=True)
        self.assertEqual(m0p.wallet_key(), "xpub68Gmy5EdvgibQVfPdqkBBCHxA5htiqg55crXYuXoQRKfDBFA1WEjWgP6LHhwBZeNK1VTsfTFUHCdrfp1bgwQ9xv5ski8PX9rL2dZXvgGDnw")
        self.assertEqual(m0p.wallet_key(as_private=True), "xprv9uHRZZhk6KAJC1avXpDAp4MDc3sQKNxDiPvvkX8Br5ngLNv1TxvUxt4cV1rGL5hj6KCesnDYUhd7oWgT11eZG7XnxHrnYeSvkzY7d2bhkJ7")
        self.assertEqual(master.subkey_for_path("0p").wallet_key(), m0p.wallet_key())

        pub_mp0 = master.subkey(is_hardened=True, as_private=False)
        self.assertEqual(pub_mp0.wallet_key(), m0p.wallet_key())
        self.assertEqual(master.subkey_for_path("0p.pub").wallet_key(), pub_mp0.wallet_key())

        m0p1 = m0p.subkey(i=1)
        self.assertEqual(m0p1.wallet_key(), "xpub6ASuArnXKPbfEwhqN6e3mwBcDTgzisQN1wXN9BJcM47sSikHjJf3UFHKkNAWbWMiGj7Wf5uMash7SyYq527Hqck2AxYysAA7xmALppuCkwQ")
        self.assertEqual(m0p1.wallet_key(as_private=True), "xprv9wTYmMFdV23N2TdNG573QoEsfRrWKQgWeibmLntzniatZvR9BmLnvSxqu53Kw1UmYPxLgboyZQaXwTCg8MSY3H2EU4pWcQDnRnrVA1xe8fs")
        self.assertEqual(master.subkey_for_path("0p/1").wallet_key(), m0p1.wallet_key())

        pub_m0p1 = m0p.subkey(i=1, as_private=False)
        self.assertEqual(pub_m0p1.wallet_key(), m0p1.wallet_key())
        self.assertEqual(master.subkey_for_path("0p/1.pub").wallet_key(), pub_m0p1.wallet_key())

        m0p1_1_2p = m0p1.subkey(i=2, is_hardened=True)
        self.assertEqual(m0p1_1_2p.wallet_key(), "xpub6D4BDPcP2GT577Vvch3R8wDkScZWzQzMMUm3PWbmWvVJrZwQY4VUNgqFJPMM3No2dFDFGTsxxpG5uJh7n7epu4trkrX7x7DogT5Uv6fcLW5")
        self.assertEqual(m0p1_1_2p.wallet_key(as_private=True), "xprv9z4pot5VBttmtdRTWfWQmoH1taj2axGVzFqSb8C9xaxKymcFzXBDptWmT7FwuEzG3ryjH4ktypQSAewRiNMjANTtpgP4mLTj34bhnZX7UiM")
        self.assertEqual(master.subkey_for_path("0p/1/2p").wallet_key(), m0p1_1_2p.wallet_key())

        pub_m0p1_1_2p = m0p1.subkey(i=2, as_private=False, is_hardened=True)
        self.assertEqual(pub_m0p1_1_2p.wallet_key(), m0p1_1_2p.wallet_key())
        self.assertEqual(master.subkey_for_path("0p/1/2p.pub").wallet_key(), pub_m0p1_1_2p.wallet_key())

        m0p1_1_2p_2 = m0p1_1_2p.subkey(i=2)
        self.assertEqual(m0p1_1_2p_2.wallet_key(), "xpub6FHa3pjLCk84BayeJxFW2SP4XRrFd1JYnxeLeU8EqN3vDfZmbqBqaGJAyiLjTAwm6ZLRQUMv1ZACTj37sR62cfN7fe5JnJ7dh8zL4fiyLHV")
        self.assertEqual(m0p1_1_2p_2.wallet_key(as_private=True), "xprvA2JDeKCSNNZky6uBCviVfJSKyQ1mDYahRjijr5idH2WwLsEd4Hsb2Tyh8RfQMuPh7f7RtyzTtdrbdqqsunu5Mm3wDvUAKRHSC34sJ7in334")
        self.assertEqual(master.subkey_for_path("0p/1/2p/2").wallet_key(), m0p1_1_2p_2.wallet_key())

        pub_m0p1_1_2p_2 = m0p1_1_2p.subkey(i=2, as_private=False)
        self.assertEqual(pub_m0p1_1_2p_2.wallet_key(), m0p1_1_2p_2.wallet_key())
        self.assertEqual(master.subkey_for_path("0p/1/2p/2.pub").wallet_key(), pub_m0p1_1_2p_2.wallet_key())

        m0p1_1_2p_2_1000000000 = m0p1_1_2p_2.subkey(i=1000000000)
        self.assertEqual(m0p1_1_2p_2_1000000000.wallet_key(), "xpub6H1LXWLaKsWFhvm6RVpEL9P4KfRZSW7abD2ttkWP3SSQvnyA8FSVqNTEcYFgJS2UaFcxupHiYkro49S8yGasTvXEYBVPamhGW6cFJodrTHy")
        self.assertEqual(m0p1_1_2p_2_1000000000.wallet_key(as_private=True), "xprvA41z7zogVVwxVSgdKUHDy1SKmdb533PjDz7J6N6mV6uS3ze1ai8FHa8kmHScGpWmj4WggLyQjgPie1rFSruoUihUZREPSL39UNdE3BBDu76")
        self.assertEqual(master.subkey_for_path("0p/1/2p/2/1000000000").wallet_key(), m0p1_1_2p_2_1000000000.wallet_key())

        pub_m0p1_1_2p_2_1000000000 = m0p1_1_2p_2.subkey(i=1000000000, as_private=False)
        self.assertEqual(pub_m0p1_1_2p_2_1000000000.wallet_key(), m0p1_1_2p_2_1000000000.wallet_key())
        self.assertEqual(master.subkey_for_path("0p/1/2p/2/1000000000.pub").wallet_key(), pub_m0p1_1_2p_2_1000000000.wallet_key())
Ejemplo n.º 47
0
    def test_repr(self):
        from pycoin.key import Key
        netcode = 'XTN'
        key = Key(secret_exponent=273, netcode=netcode)
        wallet = BIP32Node.from_master_secret(bytes(key.wif().encode('ascii')), netcode)

        address = wallet.address()
        pub_k = wallet.from_text(address)
        self.assertEqual(repr(pub_k),  '<myb5gZNXePNf2E2ksrjnHRFCwyuvt7oEay>')

        wif = wallet.wif()
        priv_k = wallet.from_text(wif)
        self.assertEqual(repr(priv_k), 'private_for <03ad094b1dc9fdce5d3648ca359b4e210a89d049532fdd39d9ccdd8ca393ac82f4>')
Ejemplo n.º 48
0
    def __init__(self, password, testnet=False):
        """
        Create a BIP32 wallet.

        Addresses return by the wallet are of the form (path, address)

        :password: master secret for the wallet
        :testnet: testnet flag. Defaults to false
        :returns: instance of the Wallet

        """
        netcode = 'XTN' if testnet else 'BTC'
        self.wallet = BIP32Node.from_master_secret(password, netcode=netcode)
        self.root_address = ('', self.wallet.address())
Ejemplo n.º 49
0
 def __init__(self):
     conf = read_config_file("ew.conf")
     if conf['entropy']:
         entropy = binascii.unhexlify(conf['entropy'])
     else:
         mnemo = Mnemonic('english')
         entropy = mnemo.to_entropy(conf['passphrase'])
     print("entropy=" + entropy.hex())
     master = BIP32Node.from_master_secret(entropy, 'BTC')
     print("master address=" + master.address())
     # /m/4544288'/0'/0'/0/0  alias
     alias = master.subkey(i=EW_DERIVATION, is_hardened=True).subkey(i=0, is_hardened=True).subkey(i=0, is_hardened=True).subkey(i=0, is_hardened=False).subkey(i=0, is_hardened=False)
     self.address = alias.address()
     print("alias address=" + self.address)
     self.key = CBitcoinSecret(alias.wif())
Ejemplo n.º 50
0
def olsign(key, proposal, url, upload, html, output):

    if not url and not proposal:
        raise click.BadParameter(
            "Need a URL to fetch proposal from (--url), or the file itself (-i file.json)")


    # get the proposal JSON
    try:
        if url:
            proposal = requests.get(url).json()
        else:
            proposal = simplejson.load(proposal)
    except JSONDecodeError:
        raise click.UsageError("Does not contain valid JSON")

    # unwrap signature, checking it as we go
    proposal = check_sig_and_unwrap(proposal)

    click.echo('''
   Co-signing as: {cosigner}
Required xpubkey: ...{xpubkey_check}
'''.format(**proposal))

    # unpack their private key (to test if suitable)
    wallet = BIP32Node.from_wallet_key(key.read().strip())
    check = wallet.hwif(as_private = False)[-8:]
    if check != proposal['xpubkey_check']:
        raise click.UsageError('This private key is not the one we need as this co-signer.')
    
    #pprint(proposal.keys())

    # present a summary of what will happen
    if html: show_page(proposal)

    sigs = do_signing(wallet, proposal['req_keys'], proposal['inputs'])

    package = package_for_ck(wallet, proposal, sigs)

    if output:
        output.write(package)
        click.echo("Wrote result to: %s" % output.name)

    if upload:
        upload_to_ck(package)

    if not output and not upload:
        click.echo("JSON response:\n\n%s" % package)
def generate_revocation_addresses(config):
    key_path = config.key_path if config.key_path else ''
    output_handle = open(config.output_file, 'w') if config.output_file else sys.stdout

    try:
        key = BIP32Node.from_text(config.extended_public_key)
    except:
        print('The extended public (or private) key seems invalid.')
        sys.exit()
    key_path_batch = key.subkey_for_path(key_path)
    for i in range(config.number_of_addresses):
        subkey = key_path_batch.subkey(i)
        output_handle.write("{0}\n".format(subkey.address(config.use_uncompressed)))

    if output_handle is not sys.stdout:
        output_handle.close()
Ejemplo n.º 52
0
    def __init__(self, w3, mnemonic, index):
        self.w3 = w3
        master_key = BIP32Node.from_master_secret(
            Mnemonic("english").to_seed(mnemonic))
        purpose_subtree = master_key.subkey(i=44, is_hardened=True)
        coin_type_subtree = purpose_subtree.subkey(i=60, is_hardened=True)
        account_subtree = coin_type_subtree.subkey(i=0, is_hardened=True)
        change_subtree = account_subtree.subkey(i=0)
        account = change_subtree.subkey(i=index)
        self.private_key = account.secret_exponent().to_bytes(32, 'big')

        public_key = ecdsa.SigningKey.from_string(string=self.private_key,
                                                  curve=ecdsa.SECP256k1,
                                                  hashfunc=hashlib.sha256).get_verifying_key()

        self.address = self.w3.toChecksumAddress(
            "0x" + self.w3.sha3(hexstr=public_key.to_string().hex())[12:].hex())
Ejemplo n.º 53
0
    def __init__(self, password, testnet=False):
        """
        Initializes a BIP32 wallet.

        Addresses returned by the wallet are of the form ``(path, address)``.

        Args:
            password (bytes): Master secret for the wallet. The password can
                also be passed as a string (``str``).
            testnet (bool): Wwether to use the bitcoin testnet or mainnet.
                Defaults to ``False``.

        """
        netcode = 'XTN' if testnet else 'BTC'
        if isinstance(password, str):
            password = password.encode()
        self.wallet = BIP32Node.from_master_secret(password, netcode=netcode)
        self.root_address = ('', self.wallet.address())
def get_new_address(wallet_num):
    passphrase = sha256(b"%s" % random.randint(0, 2**30)).hexdigest()
    wallet = BIP32Node.from_master_secret(passphrase)
    ret = dump_node(wallet)
    children = []
    # Now build up some random paths
    # Just go five deep
    path = "m"
    for depth in range(5):
        child_number = random.randint(0, 0x80000000)
        path = "%s/%s" % (path, child_number)
        prime = random.choice([True, False])
        if prime:
            path += "'"
        children.append(
            {"path": path,
             "child": dump_node(wallet.subkey_for_path(path[2:]))})
    ret['children'] = children
    return ret
Ejemplo n.º 55
0
    def test_is_public_private_bip32_valid(self):
        WALLET_KEYS = ["foo", "1", "2", "3", "4", "5"]

        # not all networks support BIP32 yet
        for netcode in "BTC XTN DOGE".split():
            for wk in WALLET_KEYS:
                wallet = BIP32Node.from_master_secret(wk.encode("utf8"), netcode=netcode)
                text = wallet.wallet_key(as_private=True)
                self.assertEqual(is_private_bip32_valid(text, allowable_netcodes=NETWORK_NAMES), netcode)
                self.assertEqual(is_public_bip32_valid(text, allowable_netcodes=NETWORK_NAMES), None)
                a = text[:-1] + chr(ord(text[-1])+1)
                self.assertEqual(is_private_bip32_valid(a, allowable_netcodes=NETWORK_NAMES), None)
                self.assertEqual(is_public_bip32_valid(a, allowable_netcodes=NETWORK_NAMES), None)
                text = wallet.wallet_key(as_private=False)
                self.assertEqual(is_private_bip32_valid(text, allowable_netcodes=NETWORK_NAMES), None)
                self.assertEqual(is_public_bip32_valid(text, allowable_netcodes=NETWORK_NAMES), netcode)
                a = text[:-1] + chr(ord(text[-1])+1)
                self.assertEqual(is_private_bip32_valid(a, allowable_netcodes=NETWORK_NAMES), None)
                self.assertEqual(is_public_bip32_valid(a, allowable_netcodes=NETWORK_NAMES), None)
Ejemplo n.º 56
0
 def evaluate_key_input(self, txt):
     self.ext_key_widget.clear()
     self.subkey_widget.clear()
     txt = str(txt)
     if not txt:
         return self.invalid_key_label.setVisible(False)
     # Variable substitution.
     elif txt.startswith('$'):
         return
     try:
         key = BIP32Node.from_hwif(txt)
     except Exception as e:
         self.invalid_key_label.setVisible(True)
     else:
         self.invalid_key_label.setVisible(False)
         self.ext_key_widget.set_key(key)
         self.derive_child()
     finally:
         self.ext_key_widget.mapper.setCurrentIndex(0)
Ejemplo n.º 57
0
    def test_vector_2(self):
        master = BIP32Node.from_master_secret(h2b("fffcf9f6f3f0edeae7e4e1dedbd8d5d2cfccc9c6c3c0bdbab7b4b1aeaba8a5a29f9c999693908d8a8784817e7b7875726f6c696663605d5a5754514e4b484542"))
        self.assertEqual(master.wallet_key(as_private=True), "xprv9s21ZrQH143K31xYSDQpPDxsXRTUcvj2iNHm5NUtrGiGG5e2DtALGdso3pGz6ssrdK4PFmM8NSpSBHNqPqm55Qn3LqFtT2emdEXVYsCzC2U")

        self.assertEqual(master.wallet_key(), "xpub661MyMwAqRbcFW31YEwpkMuc5THy2PSt5bDMsktWQcFF8syAmRUapSCGu8ED9W6oDMSgv6Zz8idoc4a6mr8BDzTJY47LJhkJ8UB7WEGuduB")

        m0 = master.subkey()
        self.assertEqual(m0.wallet_key(), "xpub69H7F5d8KSRgmmdJg2KhpAK8SR3DjMwAdkxj3ZuxV27CprR9LgpeyGmXUbC6wb7ERfvrnKZjXoUmmDznezpbZb7ap6r1D3tgFxHmwMkQTPH")
        self.assertEqual(m0.wallet_key(as_private=True), "xprv9vHkqa6EV4sPZHYqZznhT2NPtPCjKuDKGY38FBWLvgaDx45zo9WQRUT3dKYnjwih2yJD9mkrocEZXo1ex8G81dwSM1fwqWpWkeS3v86pgKt")
        pub_m0 = master.subkey(as_private=False)
        self.assertEqual(pub_m0.wallet_key(), m0.wallet_key())

        m0_2147483647p = m0.subkey(i=2147483647, is_hardened=True)
        self.assertEqual(m0_2147483647p.wallet_key(), "xpub6ASAVgeehLbnwdqV6UKMHVzgqAG8Gr6riv3Fxxpj8ksbH9ebxaEyBLZ85ySDhKiLDBrQSARLq1uNRts8RuJiHjaDMBU4Zn9h8LZNnBC5y4a")
        self.assertEqual(m0_2147483647p.wallet_key(as_private=True), "xprv9wSp6B7kry3Vj9m1zSnLvN3xH8RdsPP1Mh7fAaR7aRLcQMKTR2vidYEeEg2mUCTAwCd6vnxVrcjfy2kRgVsFawNzmjuHc2YmYRmagcEPdU9")
        pub_m0_2147483647p = m0.subkey(i=2147483647, is_hardened=True, as_private=False)
        self.assertEqual(pub_m0_2147483647p.wallet_key(), m0_2147483647p.wallet_key())

        m0_2147483647p_1 = m0_2147483647p.subkey(i=1)
        self.assertEqual(m0_2147483647p_1.wallet_key(), "xpub6DF8uhdarytz3FWdA8TvFSvvAh8dP3283MY7p2V4SeE2wyWmG5mg5EwVvmdMVCQcoNJxGoWaU9DCWh89LojfZ537wTfunKau47EL2dhHKon")
        self.assertEqual(m0_2147483647p_1.wallet_key(as_private=True), "xprv9zFnWC6h2cLgpmSA46vutJzBcfJ8yaJGg8cX1e5StJh45BBciYTRXSd25UEPVuesF9yog62tGAQtHjXajPPdbRCHuWS6T8XA2ECKADdw4Ef")
        pub_m0_2147483647p_1 = m0_2147483647p.subkey(i=1, as_private=False)
        self.assertEqual(pub_m0_2147483647p_1.wallet_key(), m0_2147483647p_1.wallet_key())
        pub_m0_2147483647p_1 = pub_m0_2147483647p.subkey(i=1, as_private=False)
        self.assertEqual(pub_m0_2147483647p_1.wallet_key(), m0_2147483647p_1.wallet_key())

        m0_2147483647p_1_2147483646p = m0_2147483647p_1.subkey(i=2147483646, is_hardened=True)
        self.assertEqual(m0_2147483647p_1_2147483646p.wallet_key(), "xpub6ERApfZwUNrhLCkDtcHTcxd75RbzS1ed54G1LkBUHQVHQKqhMkhgbmJbZRkrgZw4koxb5JaHWkY4ALHY2grBGRjaDMzQLcgJvLJuZZvRcEL")
        self.assertEqual(m0_2147483647p_1_2147483646p.wallet_key(as_private=True), "xprvA1RpRA33e1JQ7ifknakTFpgNXPmW2YvmhqLQYMmrj4xJXXWYpDPS3xz7iAxn8L39njGVyuoseXzU6rcxFLJ8HFsTjSyQbLYnMpCqE2VbFWc")
        pub_m0_2147483647p_1_2147483646p = m0_2147483647p_1.subkey(i=2147483646, as_private=False, is_hardened=True)
        self.assertEqual(pub_m0_2147483647p_1_2147483646p.wallet_key(), m0_2147483647p_1_2147483646p.wallet_key())

        m0_2147483647p_1_2147483646p_2 = m0_2147483647p_1_2147483646p.subkey(i=2)
        self.assertEqual(m0_2147483647p_1_2147483646p_2.wif(), "L3WAYNAZPxx1fr7KCz7GN9nD5qMBnNiqEJNJMU1z9MMaannAt4aK")
        self.assertEqual(m0_2147483647p_1_2147483646p_2.wallet_key(), "xpub6FnCn6nSzZAw5Tw7cgR9bi15UV96gLZhjDstkXXxvCLsUXBGXPdSnLFbdpq8p9HmGsApME5hQTZ3emM2rnY5agb9rXpVGyy3bdW6EEgAtqt")
        self.assertEqual(m0_2147483647p_1_2147483646p_2.wallet_key(as_private=True), "xprvA2nrNbFZABcdryreWet9Ea4LvTJcGsqrMzxHx98MMrotbir7yrKCEXw7nadnHM8Dq38EGfSh6dqA9QWTyefMLEcBYJUuekgW4BYPJcr9E7j")
        pub_m0_2147483647p_1_2147483646p_2 = m0_2147483647p_1_2147483646p.subkey(i=2, as_private=False)
        self.assertEqual(pub_m0_2147483647p_1_2147483646p_2.wallet_key(), m0_2147483647p_1_2147483646p_2.wallet_key())
        pub_m0_2147483647p_1_2147483646p_2 = pub_m0_2147483647p_1_2147483646p.subkey(i=2, as_private=False)
        self.assertEqual(pub_m0_2147483647p_1_2147483646p_2.wallet_key(), m0_2147483647p_1_2147483646p_2.wallet_key())
        self.assertEqual(master.subkey_for_path("0/2147483647p/1/2147483646p/2").wallet_key(), m0_2147483647p_1_2147483646p_2.wallet_key())
        self.assertEqual(master.subkey_for_path("0/2147483647p/1/2147483646p/2.pub").wallet_key(), pub_m0_2147483647p_1_2147483646p_2.wallet_key())