async def sign_typed_data(ctx: Context, msg: EthereumSignTypedData, keychain: Keychain) -> EthereumTypedDataSignature: await paths.validate_path(ctx, keychain, msg.address_n) data_hash = await generate_typed_data_hash(ctx, msg.primary_type, msg.metamask_v4_compat) node = keychain.derive(msg.address_n) signature = secp256k1.sign(node.private_key(), data_hash, False, secp256k1.CANONICAL_SIG_ETHEREUM) return EthereumTypedDataSignature( address=address_from_bytes(node.ethereum_pubkeyhash()), signature=signature[1:] + signature[0:1], )
async def get_address( ctx: wire.Context, msg: GetAddress, keychain: Keychain, coin: CoinInfo ) -> Address: await validate_path( ctx, addresses.validate_full_path, keychain, msg.address_n, coin.curve_name, coin=coin, script_type=msg.script_type, ) node = keychain.derive(msg.address_n) address = addresses.get_address(msg.script_type, coin, node, msg.multisig) address_short = addresses.address_short(coin, address) if msg.script_type == InputScriptType.SPENDWITNESS: address_qr = address.upper() # bech32 address elif coin.cashaddr_prefix is not None: address_qr = address.upper() # cashaddr address else: address_qr = address # base58 address if msg.show_display: if msg.multisig: if msg.multisig.nodes: pubnodes = msg.multisig.nodes else: pubnodes = [hd.node for hd in msg.multisig.pubkeys] multisig_index = multisig_pubkey_index(msg.multisig, node.public_key()) desc = "Multisig %d of %d" % (msg.multisig.m, len(pubnodes)) while True: if await show_address(ctx, address_short, desc=desc): break if await show_qr(ctx, address_qr, desc=desc, cancel="XPUBs"): break if await show_xpubs(ctx, coin, pubnodes, multisig_index): break else: desc = address_n_to_str(msg.address_n) while True: if await show_address(ctx, address_short, desc=desc): break if await show_qr(ctx, address_qr, desc=desc): break return Address(address=address)
def test_legacy_multisig_txweight(self): coin = coins.by_name('Bitcoin') seed = bip39.seed(' '.join(['all'] * 12), '') keychain = Keychain(seed, coin.curve_name, [AlwaysMatchingSchema]) nodes = [] for index in range(1, 4): node = keychain.derive([ 48 | 0x80000000, 0 | 0x80000000, index | 0x80000000, 0 | 0x80000000 ]) nodes.append( HDNodeType( depth=node.depth(), child_num=node.child_num(), fingerprint=node.fingerprint(), chain_code=node.chain_code(), public_key=node.public_key(), )) multisig = MultisigRedeemScriptType(nodes=nodes, address_n=[0, 0], signatures=[b"", b"", b""], m=2) inp1 = TxInput( address_n=[48 | 0x80000000, 0 | 0x80000000, 1 | 0x80000000, 0, 0], amount=100000, prev_hash=unhexlify( 'c6091adf4c0c23982a35899a6e58ae11e703eacd7954f588ed4b9cdefc4dba52' ), prev_index=1, script_type=InputScriptType.SPENDMULTISIG, multisig=multisig, ) out1 = TxOutput( address="12iyMbUb4R2K3gre4dHSrbu5azG5KaqVss", amount=100000, script_type=OutputScriptType.PAYTOADDRESS, ) calculator = TxWeightCalculator() calculator.add_input(inp1) calculator.add_output(output_derive_script(out1.address, coin)) # 010000000152ba4dfcde9c4bed88f55479cdea03e711ae586e9a89352a98230c4cdf1a09c601000000fdfe00004830450221009276eea820aa54a24bd9f1a056cb09a15f50c0816570a7c7878bd1c5ee7248540220677d200aec5e2f25bcf4000bdfab3faa9e1746d7f80c4ae4bfa1f5892eb5dcbf01483045022100c2a9fbfbff1be87036d8a6a22745512b158154f7f3d8f4cad4ba7ed130b37b83022058f5299b4c26222588dcc669399bd88b6f2bc6e04b48276373683853187a4fd6014c69522103dc0ff15b9c85c0d2c87099758bf47d36229c2514aeefcf8dea123f0f93c679762102bfe426e8671601ad46d54d09ee15aa035610d36d411961c87474908d403fbc122102a5d57129c6c96df663ad29492aa18605dad97231e043be8a92f9406073815c5d53aeffffffff01a0860100000000001976a91412e8391ad256dcdc023365978418d658dfecba1c88ac00000000 self.assertEqual(calculator.get_total(), 4 * 341)
async def get_address(ctx: Context, msg: TezosGetAddress, keychain: Keychain) -> TezosAddress: await paths.validate_path(ctx, keychain, msg.address_n) node = keychain.derive(msg.address_n) pk = seed.remove_ed25519_prefix(node.public_key()) pkh = hashlib.blake2b(pk, outlen=helpers.PUBLIC_KEY_HASH_SIZE).digest() address = helpers.base58_encode_check( pkh, prefix=helpers.TEZOS_ED25519_ADDRESS_PREFIX) if msg.show_display: title = paths.address_n_to_str(msg.address_n) await show_address(ctx, address=address, title=title) return TezosAddress(address=address)
async def get_address(ctx: Context, msg: StellarGetAddress, keychain: Keychain) -> StellarAddress: await paths.validate_path(ctx, keychain, msg.address_n) node = keychain.derive(msg.address_n) pubkey = seed.remove_ed25519_prefix(node.public_key()) address = helpers.address_from_public_key(pubkey) if msg.show_display: title = paths.address_n_to_str(msg.address_n) await show_address(ctx, address=address, case_sensitive=False, title=title) return StellarAddress(address=address)
def test_bip143_preimage_testdata(self): seed = bip39.seed('alcohol woman abuse must during monitor noble actual mixed trade anger aisle', '') coin = coins.by_name(self.tx.coin_name) bip143 = Bip143Hash() bip143.add_input(self.inp1) for txo in [self.out1, self.out2]: script_pubkey = output_derive_script(txo.address, coin) txo_bin = PrevOutput(amount=txo.amount, script_pubkey=script_pubkey) bip143.add_output(txo_bin, script_pubkey) keychain = Keychain(seed, coin.curve_name, [AlwaysMatchingSchema]) node = keychain.derive(self.inp1.address_n) # test data public key hash result = bip143.preimage_hash(self.inp1, [node.public_key()], 1, self.tx, coin, SIGHASH_ALL) self.assertEqual(hexlify(result), b'6e28aca7041720995d4acf59bbda64eef5d6f23723d23f2e994757546674bbd9')
async def get_address(ctx: Context, msg: RippleGetAddress, keychain: Keychain) -> RippleAddress: await paths.validate_path(ctx, keychain, msg.address_n) node = keychain.derive(msg.address_n) pubkey = node.public_key() address = address_from_public_key(pubkey) if msg.show_display: title = paths.address_n_to_str(msg.address_n) await show_address(ctx, address=address, address_qr=address, title=title) return RippleAddress(address=address)
async def get_address(ctx, msg: BinanceGetAddress, keychain: Keychain): HRP = "bnb" await paths.validate_path(ctx, keychain, msg.address_n) node = keychain.derive(msg.address_n) pubkey = node.public_key() address = address_from_public_key(pubkey, HRP) if msg.show_display: title = paths.address_n_to_str(msg.address_n) await show_address(ctx, address=address, address_qr=address, title=title) return BinanceAddress(address=address)
def test_segwit_multisig_txweight(self): coin = coins.by_name('Testnet') seed = bip39.seed(' '.join(['all'] * 12), '') keychain = Keychain(seed, coin.curve_name, [AlwaysMatchingSchema]) nodes = [] for index in range(1, 4): node = keychain.derive( [49 | 0x80000000, 1 | 0x80000000, index | 0x80000000]) nodes.append( HDNodeType( depth=node.depth(), child_num=node.child_num(), fingerprint=node.fingerprint(), chain_code=node.chain_code(), public_key=node.public_key(), )) multisig = MultisigRedeemScriptType(nodes=nodes, address_n=[0, 0], signatures=[b"", b"", b""], m=2) inp1 = TxInput( address_n=[49 | 0x80000000, 1 | 0x80000000, 1 | 0x80000000, 0, 0], prev_hash=unhexlify( 'c9348040bbc2024e12dcb4a0b4806b0398646b91acf314da028c3f03dd0179fc' ), prev_index=1, script_type=InputScriptType.SPENDP2SHWITNESS, multisig=multisig, amount=1610436, ) out1 = TxOutput( address= "tb1qch62pf820spe9mlq49ns5uexfnl6jzcezp7d328fw58lj0rhlhasge9hzy", amount=1605000, script_type=OutputScriptType.PAYTOADDRESS, ) calculator = TxWeightCalculator() calculator.add_input(inp1) calculator.add_output(output_derive_script(out1.address, coin)) # 01000000000101be0210025c5be68a473f6a38bf53b53bc88d5c46567616026dc056e72b92319c01000000232200208d398cfb58a1d9cdb59ccbce81559c095e8c6f4a3e64966ca385078d9879f95effffffff01887d180000000000220020c5f4a0a4ea7c0392efe0a9670a73264cffa90b19107cd8a8e9750ff93c77fdfb0400483045022100dd6342c65197af27d7894d8b8b88b16b568ee3b5ebfdc55fdfb7caa9650e3b4c02200c7074a5bcb0068f63d9014c7cd2b0490aba75822d315d41aad444e9b86adf5201483045022100e7e6c2d21109512ba0609e93903e84bfb7731ac3962ee2c1cad54a7a30ff99a20220421497930226c39fc3834e8d6da3fc876516239518b0e82e2dc1e3c46271a17c01695221021630971f20fa349ba940a6ba3706884c41579cd760c89901374358db5dd545b92102f2ff4b353702d2bb03d4c494be19d77d0ab53d16161b53fbcaf1afeef4ad0cb52103e9b6b1c691a12ce448f1aedbbd588e064869c79fbd760eae3b8cd8a5f1a224db53ae00000000 self.assertEqual(calculator.get_total(), 4 * 129 + 256)
async def get_address(ctx, msg: BinanceGetAddress, keychain: Keychain): HRP = "bnb" await paths.validate_path(ctx, keychain, msg.address_n) node = keychain.derive(msg.address_n) pubkey = node.public_key() address = address_from_public_key(pubkey, HRP) if msg.show_display: desc = address_n_to_str(msg.address_n) while True: if await show_address(ctx, address, desc=desc): break if await show_qr(ctx, address, desc=desc): break return BinanceAddress(address=address)
async def sign_message(ctx: Context, msg: EthereumSignMessage, keychain: Keychain) -> EthereumMessageSignature: await paths.validate_path(ctx, keychain, msg.address_n) await confirm_signverify(ctx, "ETH", decode_message(msg.message)) node = keychain.derive(msg.address_n) signature = secp256k1.sign( node.private_key(), message_digest(msg.message), False, secp256k1.CANONICAL_SIG_ETHEREUM, ) return EthereumMessageSignature( address=address_from_bytes(node.ethereum_pubkeyhash()), signature=signature[1:] + bytearray([signature[0]]), )
async def get_address(ctx: Context, msg: EthereumGetAddress, keychain: Keychain) -> EthereumAddress: await paths.validate_path(ctx, keychain, msg.address_n) node = keychain.derive(msg.address_n) if len(msg.address_n) > 1: # path has slip44 network identifier network = networks.by_slip44(msg.address_n[1] & 0x7FFF_FFFF) else: network = None address = address_from_bytes(node.ethereum_pubkeyhash(), network) if msg.show_display: title = paths.address_n_to_str(msg.address_n) await show_address(ctx, address=address, title=title) return EthereumAddress(address=address)
def sign_digest(msg: EthereumSignTx, keychain: Keychain, digest: bytes) -> EthereumTxRequest: node = keychain.derive(msg.address_n) signature = secp256k1.sign(node.private_key(), digest, False, secp256k1.CANONICAL_SIG_ETHEREUM) req = EthereumTxRequest() req.signature_v = signature[0] if msg.chain_id > MAX_CHAIN_ID: req.signature_v -= 27 else: req.signature_v += 2 * msg.chain_id + 8 req.signature_r = signature[1:33] req.signature_s = signature[33:] return req
def test_p2wpkh_in_p2sh_gen_proof(self): # SLIP-0019 test vector 2 coin = coins.by_name('Bitcoin') seed = bip39.seed(' '.join(['all'] * 12), '') keychain = Keychain(seed, coin.curve_name, [AlwaysMatchingSchema], slip21_namespaces=[[b"SLIP-0019"]]) commitment_data = b"" node = keychain.derive( [49 | HARDENED, 0 | HARDENED, 0 | HARDENED, 1, 0]) address = address_p2wpkh_in_p2sh(node.public_key(), coin) script_pubkey = scripts.output_derive_script(address, coin) ownership_id = ownership.get_identifier(script_pubkey, keychain) self.assertEqual( ownership_id, unhexlify( "92caf0b8daf78f1d388dbbceaec34bd2dabc31b217e32343663667f6694a3f46" )) proof, signature = ownership.generate_proof( node=node, script_type=InputScriptType.SPENDP2SHWITNESS, multisig=None, coin=coin, user_confirmed=False, ownership_ids=[ownership_id], script_pubkey=script_pubkey, commitment_data=commitment_data, ) self.assertEqual( signature, unhexlify( "30440220484072ca317663dd685d372115a9d2ff43d9afc6d352c10445a94e555e12154602202d3ffee5f780dbc74e67fcc4bcbc75a9816ed00df1142d571014724af9959355" )) self.assertEqual( proof, unhexlify( "534c0019000192caf0b8daf78f1d388dbbceaec34bd2dabc31b217e32343663667f6694a3f4617160014e0cffbee1925a411844f44c3b8d81365ab51d036024730440220484072ca317663dd685d372115a9d2ff43d9afc6d352c10445a94e555e12154602202d3ffee5f780dbc74e67fcc4bcbc75a9816ed00df1142d571014724af9959355012103a961687895a78da9aef98eed8e1f2a3e91cfb69d2f3cf11cbd0bb1773d951928" )) self.assertFalse( ownership.verify_nonownership(proof, script_pubkey, commitment_data, keychain, coin))
def test_p2wpkh_in_p2sh_gen_proof(self): coin = coins.by_name('Bitcoin') seed = bip39.seed(' '.join(['all'] * 12), '') keychain = Keychain(seed, coin.curve_name, [AlwaysMatchingSchema], slip21_namespaces=[[b"SLIP-0019"]]) commitment_data = b"" node = keychain.derive( [49 | HARDENED, 0 | HARDENED, 0 | HARDENED, 1, 0]) address = address_p2wpkh_in_p2sh(node.public_key(), coin) script_pubkey = scripts.output_derive_script(address, coin) ownership_id = ownership.get_identifier(script_pubkey, keychain) self.assertEqual( ownership_id, unhexlify( "92caf0b8daf78f1d388dbbceaec34bd2dabc31b217e32343663667f6694a3f46" )) proof, signature = ownership.generate_proof( node=node, script_type=InputScriptType.SPENDP2SHWITNESS, multisig=None, coin=coin, user_confirmed=False, ownership_ids=[ownership_id], script_pubkey=script_pubkey, commitment_data=commitment_data, ) self.assertEqual( signature, unhexlify( "3045022100a37330dca699725db613dd1b30059843d1248340642162a0adef114509c9849402201126c9044b998065d40b44fd2399b52c409794bbc3bfdd358cd5fb450c94316d" )) self.assertEqual( proof, unhexlify( "534c0019000192caf0b8daf78f1d388dbbceaec34bd2dabc31b217e32343663667f6694a3f4617160014e0cffbee1925a411844f44c3b8d81365ab51d03602483045022100a37330dca699725db613dd1b30059843d1248340642162a0adef114509c9849402201126c9044b998065d40b44fd2399b52c409794bbc3bfdd358cd5fb450c94316d012103a961687895a78da9aef98eed8e1f2a3e91cfb69d2f3cf11cbd0bb1773d951928" )) self.assertFalse( ownership.verify_nonownership(proof, script_pubkey, commitment_data, keychain, coin))
def test_p2wpkh_gen_proof(self): # SLIP-0019 test vector 1 coin = coins.by_name('Bitcoin') seed = bip39.seed(' '.join(['all'] * 12), '') keychain = Keychain(seed, coin.curve_name, [AlwaysMatchingSchema], slip21_namespaces=[[b"SLIP-0019"]]) commitment_data = b"" node = keychain.derive( [84 | HARDENED, 0 | HARDENED, 0 | HARDENED, 1, 0]) address = address_p2wpkh(node.public_key(), coin) script_pubkey = scripts.output_derive_script(address, coin) ownership_id = ownership.get_identifier(script_pubkey, keychain) self.assertEqual( ownership_id, unhexlify( "a122407efc198211c81af4450f40b235d54775efd934d16b9e31c6ce9bad5707" )) proof, signature = ownership.generate_proof( node=node, script_type=InputScriptType.SPENDWITNESS, multisig=None, coin=coin, user_confirmed=False, ownership_ids=[ownership_id], script_pubkey=script_pubkey, commitment_data=commitment_data, ) self.assertEqual( signature, unhexlify( "3045022100c0dc28bb563fc5fea76cacff75dba9cb4122412faae01937cdebccfb065f9a7002202e980bfbd8a434a7fc4cd2ca49da476ce98ca097437f8159b1a386b41fcdfac5" )) self.assertEqual( proof, unhexlify( "534c00190001a122407efc198211c81af4450f40b235d54775efd934d16b9e31c6ce9bad57070002483045022100c0dc28bb563fc5fea76cacff75dba9cb4122412faae01937cdebccfb065f9a7002202e980bfbd8a434a7fc4cd2ca49da476ce98ca097437f8159b1a386b41fcdfac50121032ef68318c8f6aaa0adec0199c69901f0db7d3485eb38d9ad235221dc3d61154b" )) self.assertFalse( ownership.verify_nonownership(proof, script_pubkey, commitment_data, keychain, coin))
def test_p2pkh_gen_proof(self): # SLIP-0019 test vector 3 coin = coins.by_name('Bitcoin') seed = bip39.seed(' '.join(['all'] * 12), 'TREZOR') keychain = Keychain(seed, coin.curve_name, [AlwaysMatchingSchema], slip21_namespaces=[[b"SLIP-0019"]]) commitment_data = b"" node = keychain.derive( [44 | HARDENED, 0 | HARDENED, 0 | HARDENED, 1, 0]) address = node.address(coin.address_type) script_pubkey = scripts.output_derive_script(address, coin) ownership_id = ownership.get_identifier(script_pubkey, keychain) self.assertEqual( ownership_id, unhexlify( "ccc49ac5fede0efc80725fbda8b763d4e62a221c51cc5425076cffa7722c0bda" )) proof, signature = ownership.generate_proof( node=node, script_type=InputScriptType.SPENDADDRESS, multisig=None, coin=coin, user_confirmed=False, ownership_ids=[ownership_id], script_pubkey=script_pubkey, commitment_data=commitment_data, ) self.assertEqual( signature, unhexlify( "3045022100e818002d0a85438a7f2140503a6aa0a6af6002fa956d0101fd3db24e776e546f0220430fd59dc1498bc96ab6e71a4829b60224828cf1fc35edc98e0973db203ca3f0" )) self.assertEqual( proof, unhexlify( "534c00190001ccc49ac5fede0efc80725fbda8b763d4e62a221c51cc5425076cffa7722c0bda6b483045022100e818002d0a85438a7f2140503a6aa0a6af6002fa956d0101fd3db24e776e546f0220430fd59dc1498bc96ab6e71a4829b60224828cf1fc35edc98e0973db203ca3f0012102f63159e21fbcb54221ec993def967ad2183a9c243c8bff6e7d60f4d5ed3b386500" )) self.assertFalse( ownership.verify_nonownership(proof, script_pubkey, commitment_data, keychain, coin))
async def sign_tx(ctx: wire.Context, msg: EosSignTx, keychain: Keychain) -> EosSignedTx: if not msg.num_actions: raise wire.DataError("No actions") await paths.validate_path(ctx, keychain, msg.address_n) node = keychain.derive(msg.address_n) sha = HashWriter(sha256()) await _init(ctx, sha, msg) await _actions(ctx, sha, msg.num_actions) writers.write_uvarint(sha, 0) writers.write_bytes_fixed(sha, bytearray(32), 32) digest = sha.get_digest() signature = secp256k1.sign(node.private_key(), digest, True, secp256k1.CANONICAL_SIG_EOS) return EosSignedTx(signature=base58_encode("SIG_", "K1", signature))
def test_p2tr_gen_proof(self): # SLIP-0019 test vector 5 coin = coins.by_name('Bitcoin') seed = bip39.seed(' '.join(['all'] * 12), '') keychain = Keychain(seed, coin.curve_name, [AlwaysMatchingSchema], slip21_namespaces=[[b"SLIP-0019"]]) commitment_data = b"" node = keychain.derive( [86 | HARDENED, 0 | HARDENED, 0 | HARDENED, 1, 0]) address = address_p2tr(node.public_key(), coin) script_pubkey = scripts.output_derive_script(address, coin) ownership_id = ownership.get_identifier(script_pubkey, keychain) self.assertEqual( ownership_id, unhexlify( "dc18066224b9e30e306303436dc18ab881c7266c13790350a3fe415e438135ec" )) proof, signature = ownership.generate_proof( node=node, script_type=InputScriptType.SPENDTAPROOT, multisig=None, coin=coin, user_confirmed=False, ownership_ids=[ownership_id], script_pubkey=script_pubkey, commitment_data=commitment_data, ) self.assertEqual( signature, unhexlify( "1b553e5b9cc787b531bbc78417aea901272b4ea905136a2babc4d6ca471549743b5e0e39ddc14e620b254e42faa7f6d5bd953e97aa231d764d21bc5a58e8b7d9" )) self.assertEqual( proof, unhexlify( "534c00190001dc18066224b9e30e306303436dc18ab881c7266c13790350a3fe415e438135ec0001401b553e5b9cc787b531bbc78417aea901272b4ea905136a2babc4d6ca471549743b5e0e39ddc14e620b254e42faa7f6d5bd953e97aa231d764d21bc5a58e8b7d9" )) self.assertFalse( ownership.verify_nonownership(proof, script_pubkey, commitment_data, keychain, coin))
def test_p2pkh_gen_proof(self): coin = coins.by_name('Bitcoin') seed = bip39.seed(' '.join(['all'] * 12), 'TREZOR') keychain = Keychain(seed, coin.curve_name, [AlwaysMatchingSchema], slip21_namespaces=[[b"SLIP-0019"]]) commitment_data = b"" node = keychain.derive( [44 | HARDENED, 0 | HARDENED, 0 | HARDENED, 1, 0]) address = node.address(coin.address_type) script_pubkey = scripts.output_derive_script(address, coin) ownership_id = ownership.get_identifier(script_pubkey, keychain) self.assertEqual( ownership_id, unhexlify( "ccc49ac5fede0efc80725fbda8b763d4e62a221c51cc5425076cffa7722c0bda" )) proof, signature = ownership.generate_proof( node=node, script_type=InputScriptType.SPENDADDRESS, multisig=None, coin=coin, user_confirmed=False, ownership_ids=[ownership_id], script_pubkey=script_pubkey, commitment_data=commitment_data, ) self.assertEqual( signature, unhexlify( "304402206682f40a12f3609a308acb872888470a07760f2f4790ee4ff62665a39c02a5fc022026f3f38a7c2b2668c2eff9cc1e712c7f254926a482bae411ad18947eba9fd21c" )) self.assertEqual( proof, unhexlify( "534c00190001ccc49ac5fede0efc80725fbda8b763d4e62a221c51cc5425076cffa7722c0bda6a47304402206682f40a12f3609a308acb872888470a07760f2f4790ee4ff62665a39c02a5fc022026f3f38a7c2b2668c2eff9cc1e712c7f254926a482bae411ad18947eba9fd21c012102f63159e21fbcb54221ec993def967ad2183a9c243c8bff6e7d60f4d5ed3b386500" )) self.assertFalse( ownership.verify_nonownership(proof, script_pubkey, commitment_data, keychain, coin))
def test_p2wpkh_gen_proof(self): coin = coins.by_name('Bitcoin') seed = bip39.seed(' '.join(['all'] * 12), '') keychain = Keychain(seed, coin.curve_name, [AlwaysMatchingSchema], slip21_namespaces=[[b"SLIP-0019"]]) commitment_data = b"" node = keychain.derive( [84 | HARDENED, 0 | HARDENED, 0 | HARDENED, 1, 0]) address = address_p2wpkh(node.public_key(), coin) script_pubkey = scripts.output_derive_script(address, coin) ownership_id = ownership.get_identifier(script_pubkey, keychain) self.assertEqual( ownership_id, unhexlify( "a122407efc198211c81af4450f40b235d54775efd934d16b9e31c6ce9bad5707" )) proof, signature = ownership.generate_proof( node=node, script_type=InputScriptType.SPENDWITNESS, multisig=None, coin=coin, user_confirmed=False, ownership_ids=[ownership_id], script_pubkey=script_pubkey, commitment_data=commitment_data, ) self.assertEqual( signature, unhexlify( "3045022100e5eaf2cb0a473b4545115c7b85323809e75cb106175ace38129fd62323d73df30220363dbc7acb7afcda022b1f8d97acb8f47c42043cfe0595583aa26e30bc8b3bb5" )) self.assertEqual( proof, unhexlify( "534c00190001a122407efc198211c81af4450f40b235d54775efd934d16b9e31c6ce9bad57070002483045022100e5eaf2cb0a473b4545115c7b85323809e75cb106175ace38129fd62323d73df30220363dbc7acb7afcda022b1f8d97acb8f47c42043cfe0595583aa26e30bc8b3bb50121032ef68318c8f6aaa0adec0199c69901f0db7d3485eb38d9ad235221dc3d61154b" )) self.assertFalse( ownership.verify_nonownership(proof, script_pubkey, commitment_data, keychain, coin))
def test_preimage_testdata(self): seed = bip39.seed('alcohol woman abuse must during monitor noble actual mixed trade anger aisle', '') coin = coins.by_name(self.tx.coin_name) sig_hasher = BitcoinSigHasher() sig_hasher.add_input(self.inp1, b"") sig_hasher.add_input(self.inp2, b"") for txo in [self.out1, self.out2]: script_pubkey = output_derive_script(txo.address, coin) txo_bin = PrevOutput(amount=txo.amount, script_pubkey=script_pubkey) sig_hasher.add_output(txo_bin, script_pubkey) keychain = Keychain(seed, coin.curve_name, [AlwaysMatchingSchema]) node = keychain.derive(self.inp2.address_n) # test data public key hash # only for input 2 - input 1 is not segwit result = sig_hasher.hash143(self.inp2, [node.public_key()], 1, self.tx, coin, SigHashType.SIGHASH_ALL) self.assertEqual(hexlify(result), b'2fa3f1351618b2532228d7182d3221d95c21fd3d496e7e22e9ded873cf022a8b')
async def get_address(ctx: Context, msg: NEMGetAddress, keychain: Keychain) -> NEMAddress: validate_network(msg.network) await validate_path(ctx, keychain, msg.address_n, check_path(msg.address_n, msg.network)) node = keychain.derive(msg.address_n) address = node.nem_address(msg.network) if msg.show_display: title = address_n_to_str(msg.address_n) await show_address( ctx, address=address, address_qr=address.upper(), title=title, network=get_network_str(msg.network), ) return NEMAddress(address=address)
def test_preimage_testdata(self): seed = bip39.seed('alcohol woman abuse must during monitor noble actual mixed trade anger aisle', '') coin = coins.by_name(self.tx.coin_name) bip143 = Bitcoin(self.tx, None, coin, BasicApprover(self.tx, coin)) bip143.hash143_add_input(self.inp1) bip143.hash143_add_input(self.inp2) for txo in [self.out1, self.out2]: txo_bin = TxOutputBinType() txo_bin.amount = txo.amount script_pubkey = output_derive_script(txo.address, coin) bip143.hash143_add_output(txo_bin, script_pubkey) keychain = Keychain(seed, coin.curve_name, [[]]) node = keychain.derive(self.inp2.address_n) # test data public key hash # only for input 2 - input 1 is not segwit result = bip143.hash143_preimage_hash(self.inp2, [node.public_key()], 1) self.assertEqual(hexlify(result), b'2fa3f1351618b2532228d7182d3221d95c21fd3d496e7e22e9ded873cf022a8b')
async def get_ownership_id( ctx: wire.Context, msg: GetOwnershipId, keychain: Keychain, coin: CoinInfo ) -> OwnershipId: await validate_path( ctx, keychain, msg.address_n, validate_path_against_script_type(coin, msg), ) if msg.script_type not in common.INTERNAL_INPUT_SCRIPT_TYPES: raise wire.DataError("Invalid script type") if msg.script_type in common.SEGWIT_INPUT_SCRIPT_TYPES and not coin.segwit: raise wire.DataError("Segwit not enabled on this coin") node = keychain.derive(msg.address_n) address = addresses.get_address(msg.script_type, coin, node, msg.multisig) script_pubkey = scripts.output_derive_script(address, coin) ownership_id = get_identifier(script_pubkey, keychain) return OwnershipId(ownership_id=ownership_id)
async def sign_message(ctx: wire.Context, msg: SignMessage, keychain: Keychain, coin: CoinInfo) -> MessageSignature: message = msg.message address_n = msg.address_n script_type = msg.script_type or InputScriptType.SPENDADDRESS await validate_path(ctx, keychain, address_n, validate_path_against_script_type(coin, msg)) node = keychain.derive(address_n) address = get_address(script_type, coin, node) await confirm_signverify( ctx, coin.coin_shortcut, decode_message(message), address_short(coin, address), verify=False, ) seckey = node.private_key() digest = message_digest(coin, message) signature = secp256k1.sign(seckey, digest) if script_type == InputScriptType.SPENDADDRESS: script_type_info = 0 elif script_type == InputScriptType.SPENDP2SHWITNESS: script_type_info = 4 elif script_type == InputScriptType.SPENDWITNESS: script_type_info = 8 else: raise wire.ProcessError("Unsupported script type") # Add script type information to the recovery byte. if script_type_info != 0 and not msg.no_script_type: signature = bytes([signature[0] + script_type_info]) + signature[1:] return MessageSignature(address=address, signature=signature)
async def sign_tx(ctx, envelope, keychain: Keychain): # create transaction message -> sign it -> create signature/pubkey message -> serialize all if envelope.msg_count > 1: raise wire.DataError("Multiple messages not supported.") await paths.validate_path(ctx, helpers.validate_full_path, keychain, envelope.address_n, CURVE) node = keychain.derive(envelope.address_n) tx_req = BinanceTxRequest() msg = await ctx.call_any( tx_req, MessageType.BinanceCancelMsg, MessageType.BinanceOrderMsg, MessageType.BinanceTransferMsg, ) if envelope.source is None or envelope.source < 0: raise wire.DataError("Source missing or invalid.") msg_json = helpers.produce_json_for_signing(envelope, msg) if isinstance(msg, BinanceTransferMsg): await layout.require_confirm_transfer(ctx, msg) elif isinstance(msg, BinanceOrderMsg): await layout.require_confirm_order(ctx, msg) elif isinstance(msg, BinanceCancelMsg): await layout.require_confirm_cancel(ctx, msg) else: raise ValueError("input message unrecognized, is of type " + type(msg).__name__) signature_bytes = generate_content_signature(msg_json.encode(), node.private_key()) return BinanceSignedTx(signature=signature_bytes, public_key=node.public_key())
def test_bip143_preimage_testdata(self): seed = bip39.seed( 'alcohol woman abuse must during monitor noble actual mixed trade anger aisle', '') coin = coins.by_name(self.tx.coin_name) bip143 = Bitcoin(self.tx, None, coin, BasicApprover(self.tx, coin)) bip143.hash143_add_input(self.inp1) for txo in [self.out1, self.out2]: txo_bin = TxOutputBinType() txo_bin.amount = txo.amount script_pubkey = output_derive_script(txo.address, coin) bip143.hash143_add_output(txo_bin, script_pubkey) keychain = Keychain(seed, coin.curve_name, [[]]) node = keychain.derive(self.inp1.address_n) # test data public key hash result = bip143.hash143_preimage_hash(self.inp1, [node.public_key()], 1) self.assertEqual( hexlify(result), b'6e28aca7041720995d4acf59bbda64eef5d6f23723d23f2e994757546674bbd9' )
async def get_address(ctx: Context, msg: EthereumGetAddress, keychain: Keychain) -> EthereumAddress: await paths.validate_path(ctx, keychain, msg.address_n) node = keychain.derive(msg.address_n) seckey = node.private_key() public_key = secp256k1.publickey(seckey, False) # uncompressed address_bytes = sha3_256(public_key[1:], keccak=True).digest()[12:] if len(msg.address_n) > 1: # path has slip44 network identifier network = networks.by_slip44(msg.address_n[1] & 0x7FFF_FFFF) else: network = None address = address_from_bytes(address_bytes, network) if msg.show_display: title = paths.address_n_to_str(msg.address_n) await show_address(ctx, address=address, address_qr=address, title=title) return EthereumAddress(address=address)
async def sign_tx(ctx: Context, msg: StellarSignTx, keychain: Keychain) -> StellarSignedTx: await paths.validate_path(ctx, keychain, msg.address_n) node = keychain.derive(msg.address_n) pubkey = seed.remove_ed25519_prefix(node.public_key()) if msg.num_operations == 0: raise ProcessError("Stellar: At least one operation is required") w = bytearray() await _init(ctx, w, pubkey, msg) await _timebounds(ctx, w, msg.timebounds_start, msg.timebounds_end) await _memo(ctx, w, msg) await _operations(ctx, w, msg.num_operations) await _final(ctx, w, msg) # sign digest = sha256(w).digest() signature = ed25519.sign(node.private_key(), digest) # Add the public key for verification that the right account was used for signing return StellarSignedTx(public_key=pubkey, signature=signature)