def make_xpub(xpub, s) -> str: rootnode = BIP32Node.from_xkey(xpub) child_pubkey, child_chaincode = bip32._CKD_pub( parent_pubkey=rootnode.eckey.get_public_key_bytes(compressed=True), parent_chaincode=rootnode.chaincode, child_index=s) child_node = BIP32Node(xtype=rootnode.xtype, eckey=ecc.ECPubkey(child_pubkey), chaincode=child_chaincode) return child_node.to_xpub()
def get_xkeys(self, seed, t, passphrase, derivation): assert is_any_2fa_seed_type(t) xtype = 'standard' if t == '2fa' else 'p2wsh' bip32_seed = Mnemonic.mnemonic_to_seed(seed, passphrase) rootnode = BIP32Node.from_rootseed(bip32_seed, xtype=xtype) child_node = rootnode.subkey_at_private_derivation(derivation) return child_node.to_xprv(), child_node.to_xpub()
def update(self, window): wallet = window.wallet if type(wallet) != Multisig_Wallet: return if self.listener is None: self.print_error("starting listener") self.listener = Listener(self) self.listener.start() elif self.listener: self.print_error("shutting down listener") self.listener.stop() self.listener = None self.keys = [] self.cosigner_list = [] for key, keystore in wallet.keystores.items(): xpub = keystore.get_master_public_key() pubkey = BIP32Node.from_xkey(xpub).eckey.get_public_key_bytes( compressed=True) _hash = bh2u(crypto.sha256d(pubkey)) if not keystore.is_watching_only(): self.keys.append((key, _hash, window)) else: self.cosigner_list.append((window, xpub, pubkey, _hash)) if self.listener: self.listener.set_keyhashes([t[1] for t in self.keys])
def get_xpub(self, bip32_path, xtype): self.checkDevice() # bip32_path is of the form 44'/0'/1' # S-L-O-W - we don't handle the fingerprint directly, so compute # it manually from the previous node # This only happens once so it's bearable #self.get_client() # prompt for the PIN before displaying the dialog if necessary #self.handler.show_message("Computing master public key") if xtype in ['p2wpkh', 'p2wsh'] and not self.supports_native_segwit(): raise UserFacingException(MSG_NEEDS_FW_UPDATE_SEGWIT) if xtype in ['p2wpkh-p2sh', 'p2wsh-p2sh'] and not self.supports_segwit(): raise UserFacingException(MSG_NEEDS_FW_UPDATE_SEGWIT) splitPath = bip32_path.split('/') if splitPath[0] == 'm': splitPath = splitPath[1:] bip32_path = bip32_path[2:] fingerprint = 0 if len(splitPath) > 1: prevPath = "/".join(splitPath[0:len(splitPath) - 1]) nodeData = self.dongleObject.getWalletPublicKey(prevPath) publicKey = compress_public_key(nodeData['publicKey']) h = hashlib.new('ripemd160') h.update(hashlib.sha256(publicKey).digest()) fingerprint = unpack(">I", h.digest()[0:4])[0] nodeData = self.dongleObject.getWalletPublicKey(bip32_path) publicKey = compress_public_key(nodeData['publicKey']) depth = len(splitPath) lastChild = splitPath[len(splitPath) - 1].split('\'') childnum = int(lastChild[0]) if len(lastChild) == 1 else 0x80000000 | int(lastChild[0]) return BIP32Node(xtype=xtype, eckey=ecc.ECPubkey(publicKey), chaincode=nodeData['chainCode'], depth=depth, fingerprint=self.i4b(fingerprint), child_number=self.i4b(childnum)).to_xpub()
def mitm_verify(self, sig, expect_xpub): # verify a signature (65 bytes) over the session key, using the master bip32 node # - customized to use specific EC library of Electrum. pubkey = BIP32Node.from_xkey(expect_xpub).eckey try: pubkey.verify_message_hash(sig[1:65], self.session_key) return True except: return False
def _make_node_path(self, xpub, address_n): bip32node = BIP32Node.from_xkey(xpub) node = HDNodeType( depth=bip32node.depth, fingerprint=int.from_bytes(bip32node.fingerprint, 'big'), child_num=int.from_bytes(bip32node.child_number, 'big'), chain_code=bip32node.chaincode, public_key=bip32node.eckey.get_public_key_bytes(compressed=True), ) return HDNodePathType(node=node, address_n=address_n)
def get_xpub(self, bip32_path, xtype): address_n = self.expand_path(bip32_path) creating = False node = self.get_public_node(address_n, creating).node return BIP32Node(xtype=xtype, eckey=ecc.ECPubkey(node.public_key), chaincode=node.chain_code, depth=node.depth, fingerprint=self.i4b(node.fingerprint), child_number=self.i4b(node.child_num)).to_xpub()
def get_xpub(self, bip32_path, xtype, creating=False): address_n = parse_path(bip32_path) with self.run_flow(creating_wallet=creating): node = trezorlib.btc.get_public_node(self.client, address_n).node return BIP32Node(xtype=xtype, eckey=ecc.ECPubkey(node.public_key), chaincode=node.chain_code, depth=node.depth, fingerprint=self.i4b(node.fingerprint), child_number=self.i4b(node.child_num)).to_xpub()
def get_signing_xpub(xtype): if not constants.net.TESTNET: xpub = "xpub661MyMwAqRbcGnMkaTx2594P9EDuiEqMq25PM2aeG6UmwzaohgA6uDmNsvSUV8ubqwA3Wpste1hg69XHgjUuCD5HLcEp2QPzyV1HMrPppsL" else: xpub = "tpubD6NzVbkrYhZ4XdmyJQcCPjQfg6RXVUzGFhPjZ7uvRC8JLcS7Hw1i7UTpyhp9grHpak4TyK2hzBJrujDVLXQ6qB5tNpVx9rC6ixijUXadnmY" if xtype not in ('standard', 'p2wsh'): raise NotImplementedError('xtype: {}'.format(xtype)) if xtype == 'standard': return xpub node = BIP32Node.from_xkey(xpub) return node._replace(xtype=xtype).to_xpub()
def make_billing_address(wallet, num, addr_type): long_id, short_id = wallet.get_user_id() xpub = make_xpub(get_billing_xpub(), long_id) usernode = BIP32Node.from_xkey(xpub) child_node = usernode.subkey_at_public_derivation([num]) pubkey = child_node.eckey.get_public_key_bytes(compressed=True) if addr_type == 'legacy': return bitcoin.public_key_to_p2pkh(pubkey) elif addr_type == 'segwit': return bitcoin.public_key_to_p2wpkh(pubkey) else: raise ValueError(f'unexpected billing type: {addr_type}')
def get_xpub(self, bip32_path, xtype): assert xtype in self.plugin.SUPPORTED_XTYPES reply = self._get_xpub(bip32_path) if reply: xpub = reply['xpub'] # Change type of xpub to the requested type. The firmware # only ever returns the mainnet standard type, but it is agnostic # to the type when signing. if xtype != 'standard' or constants.net.TESTNET: node = BIP32Node.from_xkey(xpub, net=constants.BitcoinMainnet) xpub = node._replace(xtype=xtype).to_xpub() return xpub else: raise Exception('no reply')
def get_xpub(self, bip32_path, xtype): assert xtype in ColdcardPlugin.SUPPORTED_XTYPES print_error('[coldcard]', 'Derive xtype = %r' % xtype) xpub = self.dev.send_recv(CCProtocolPacker.get_xpub(bip32_path), timeout=5000) # TODO handle timeout? # change type of xpub to the requested type try: node = BIP32Node.from_xkey(xpub) except InvalidMasterKeyVersionBytes: raise UserFacingException( _('Invalid xpub magic. Make sure your {} device is set to the correct chain.' ).format(self.device)) from None if xtype != 'standard': xpub = node._replace(xtype=xtype).to_xpub() return xpub
def on_receive(self, keyhash, message): self.print_error("signal arrived for", keyhash) for key, _hash, window in self.keys: if _hash == keyhash: break else: self.print_error("keyhash not found") return wallet = window.wallet if isinstance(wallet.keystore, keystore.Hardware_KeyStore): window.show_warning( _('An encrypted transaction was retrieved from cosigning pool.' ) + '\n' + _('However, hardware wallets do not support message decryption, ' 'which makes them not compatible with the current design of cosigner pool.' )) return elif wallet.has_keystore_encryption(): password = window.password_dialog( _('An encrypted transaction was retrieved from cosigning pool.' ) + '\n' + _('Please enter your password to decrypt it.')) if not password: return else: password = None if not window.question( _("An encrypted transaction was retrieved from cosigning pool." ) + '\n' + _("Do you want to open it now?")): return xprv = wallet.keystore.get_master_private_key(password) if not xprv: return try: privkey = BIP32Node.from_xkey(xprv).eckey message = bh2u(privkey.decrypt_message(message)) except Exception as e: traceback.print_exc(file=sys.stdout) window.show_error(_('Error decrypting message') + ':\n' + str(e)) return self.listener.clear(keyhash) tx = transaction.Transaction(message) show_transaction(tx, window, prompt_if_unsaved=True)
def f(xprv): rootnode = BIP32Node.from_xkey(xprv) key = rootnode.subkey_at_private_derivation((0, 0)).eckey sig = key.sign_message(message, True) return base64.b64encode(sig).decode()