def derive( self, node_path: list, curve_name: str = "secp256k1") -> Union[bip32.HDNode, Slip21Node]: if "ed25519" in curve_name and not _path_hardened(node_path): raise wire.DataError("Forbidden key path") # find the root node index root_index = 0 for curve, *path in self.namespaces: prefix = node_path[:len(path)] suffix = node_path[len(path):] if curve == curve_name and path == prefix: break root_index += 1 else: raise wire.DataError("Forbidden key path") # create the root node if not cached root = self.roots[root_index] if root is None: if curve_name != "slip21": root = bip32.from_seed(self.seed, curve_name) else: root = Slip21Node(self.seed) root.derive_path(path) self.roots[root_index] = root # derive child node from the root node = root.clone() node.derive_path(suffix) return node
def test_p2wpkh_in_p2sh_node_derive_address(self): coin = coins.by_name('Testnet') seed = bip39.seed(' '.join(['all'] * 12), '') root = bip32.from_seed(seed, 'secp256k1') node = node_derive( root, [49 | 0x80000000, 1 | 0x80000000, 0 | 0x80000000, 1, 0]) address = address_p2wpkh_in_p2sh(node.public_key(), coin.address_type_p2sh) self.assertEqual(address, '2N1LGaGg836mqSQqiuUBLfcyGBhyZbremDX') node = node_derive( root, [49 | 0x80000000, 1 | 0x80000000, 0 | 0x80000000, 1, 1]) address = address_p2wpkh_in_p2sh(node.public_key(), coin.address_type_p2sh) self.assertEqual(address, '2NFWLCJQBSpz1oUJwwLpX8ECifFWGznBVqs') node = node_derive( root, [49 | 0x80000000, 1 | 0x80000000, 0 | 0x80000000, 0, 0]) address = address_p2wpkh_in_p2sh(node.public_key(), coin.address_type_p2sh) self.assertEqual(address, '2N4Q5FhU2497BryFfUgbqkAJE87aKHUhXMp')
def derive(self, path: paths.Bip32Path) -> bip32.HDNode: self.verify_path(path) return self._derive_with_cache( prefix_len=3, path=path, new_root=lambda: bip32.from_seed(self.seed, self.curve), )
def test_bip143_preimage_testdata(self): seed = bip39.seed( 'alcohol woman abuse must during monitor noble actual mixed trade anger aisle', '') root = bip32.from_seed(seed, 'secp256k1') coin = coins.by_name(self.tx.coin_name) bip143 = Bip143() bip143.add_prevouts(self.inp1) bip143.add_sequence(self.inp1) for txo in [self.out1, self.out2]: txo_bin = TxOutputBinType() txo_bin.amount = txo.amount txo_bin.script_pubkey = output_derive_script(txo, coin, root) bip143.add_output(txo_bin) # test data public key hash result = bip143.preimage_hash( coin, self.tx, self.inp1, unhexlify('79091972186c449eb1ded22b78e40d009bdf0089'), 0x01) self.assertEqual( hexlify(result), b'64f3b0f4dd2bb3aa1ce8566d220cc74dda9df97d8490cc81d89d735c92e59fb6' )
def derive_node_without_passphrase(path: Bip32Path, curve_name: str = "secp256k1" ) -> bip32.HDNode: seed = _get_seed_without_passphrase() node = bip32.from_seed(seed, curve_name) node.derive_path(path) return node
def test_get_public_key_scheme(self): mnemonic = "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about" seed = bip39.seed(mnemonic, '') derivation_paths = [ [0x80000000 | 44, 0x80000000 | 194, 0x80000000, 0, 0], [0x80000000 | 44, 0x80000000 | 194, 0x80000000, 0, 1], [0x80000000 | 44, 0x80000000 | 194], [0x80000000 | 44, 0x80000000 | 194, 0x80000000, 0, 0x80000000], ] public_keys = [ b'0315c358024ce46767102578947584c4342a6982b922d454f63588effa34597197', b'029622eff7248c4d298fe28f2df19ee0d5f7674f678844e05c31d1a5632412869e', b'02625f33c10399703e95e41bd5054beef3ab893dcc7df2bb9bdcee48359b29069d', b'037c9b7d24d42589941cca3f4debc75b37c0e7b881e6eb00d2e674958debe3bbc3', ] wif_keys = [ 'EOS6zpSNY1YoLxNt2VsvJjoDfBueU6xC1M1ERJw1UoekL1NHn8KNA', 'EOS62cPUiWnLqbUjiBMxbEU4pm4Hp5X3RGk4KMTadvZNygjX72yHW', 'EOS5dp8aCFoFwrKo6KuUfos1hwMfZGkiZUbaF2CyuD4chyBEN2wQK', 'EOS7n7TXwR4Y3DtPt2ji6akhQi5uw4SruuPArvoNJso84vhwPQt1G', ] for index, path in enumerate(derivation_paths): node = bip32.from_seed(seed, 'secp256k1') node.derive_path(path) wif, public_key = _get_public_key(node) self.assertEqual(hexlify(public_key), public_keys[index]) self.assertEqual(wif, wif_keys[index]) self.assertEqual(_public_key_to_wif(public_key), wif_keys[index])
def test_preimage_testdata(self): seed = bip39.seed( 'alcohol woman abuse must during monitor noble actual mixed trade anger aisle', '') root = bip32.from_seed(seed, 'secp256k1') coin = coins.by_name(self.tx.coin_name) bip143 = Bip143() bip143.add_prevouts(self.inp1) bip143.add_prevouts(self.inp2) bip143.add_sequence(self.inp1) bip143.add_sequence(self.inp2) for txo in [self.out1, self.out2]: txo_bin = TxOutputBinType() txo_bin.amount = txo.amount txo_bin.script_pubkey = output_derive_script(txo, coin, root) bip143.add_output(txo_bin) # test data public key hash # only for input 2 - input 1 is not segwit result = bip143.preimage_hash( self.tx, self.inp2, unhexlify('1d0f172a0ecb48aee1be1f2687d2963ae33f71a1')) self.assertEqual( hexlify(result), b'c37af31116d1b27caf68aae9e3ac82f1477929014d5b917657d0eb49478cb670' )
async def get_keychain(ctx: wire.Context) -> Keychain: if mnemonic.is_bip39(): return await _get_keychain_bip39(ctx) else: # derive the root node via SLIP-0023 https://github.com/satoshilabs/slips/blob/master/slip-0022.md seed = await get_seed(ctx) return Keychain(bip32.from_seed(seed, "ed25519 cardano seed"))
async def derive_node(ctx: wire.Context, path: list, curve_name: str = _DEFAULT_CURVE) -> bip32.HDNode: seed = await _get_cached_seed(ctx) node = bip32.from_seed(seed, curve_name) node.derive_path(path) return node
def derive(self, node_path: list, curve_name: str = "secp256k1") -> bip32.HDNode: # find the root node index root_index = 0 for curve, *path in self.namespaces: prefix = node_path[:len(path)] suffix = node_path[len(path):] if curve == curve_name and path == prefix: break root_index += 1 else: raise wire.DataError("Forbidden key path") # create the root node if not cached root = self.roots[root_index] if root is None: root = bip32.from_seed(self.seed, curve_name) root.derive_path(path) self.roots[root_index] = root # TODO check for ed25519? # derive child node from the root node = root.clone() node.derive_path(suffix) return node
def set_seed(seed): from trezor.crypto import bip32 from trezor.crypto.hashlib import blake2s node = bip32.from_seed(seed, 'secp256k1') state = blake2s(node.public_key()).digest() global _seed, _state _seed, _state = seed, state
def test_p2pkh_node_derive_address(self): coin = coins.by_name('Groestlcoin') seed = bip39.seed(' '.join(['all'] * 12), '') root = bip32.from_seed(seed, coin.curve_name) node = node_derive( root, [44 | 0x80000000, 17 | 0x80000000, 0 | 0x80000000, 1, 0]) address = node.address(coin.address_type) # generate in trezor-crypto self.assertEqual(address, 'FmRaqvVBRrAp2Umfqx9V1ectZy8gw54QDN') address = address_pkh(node.public_key(), coin) # generate in trezor-core self.assertEqual(address, 'FmRaqvVBRrAp2Umfqx9V1ectZy8gw54QDN') node = node_derive( root, [44 | 0x80000000, 17 | 0x80000000, 0 | 0x80000000, 1, 1]) address = node.address(coin.address_type) self.assertEqual(address, 'Fmhtxeh7YdCBkyQF7AQG4QnY8y3rJg89di') address = address_pkh(node.public_key(), coin) self.assertEqual(address, 'Fmhtxeh7YdCBkyQF7AQG4QnY8y3rJg89di') node = node_derive( root, [44 | 0x80000000, 17 | 0x80000000, 0 | 0x80000000, 0, 0]) address = node.address(coin.address_type) self.assertEqual(address, 'Fj62rBJi8LvbmWu2jzkaUX1NFXLEqDLoZM') address = address_pkh(node.public_key(), coin) self.assertEqual(address, 'Fj62rBJi8LvbmWu2jzkaUX1NFXLEqDLoZM')
def get_root_without_passphrase(curve_name=_DEFAULT_CURVE): from . import storage if not storage.is_initialized(): raise Exception('Device is not initialized') seed = bip39.seed(storage.get_mnemonic(), '') root = bip32.from_seed(seed, curve_name) return root
def test_p2pkh_txweight(self): coin = coins.by_name('Bitcoin') seed = bip39.seed(' '.join(['all'] * 12), '') root = bip32.from_seed(seed, 'secp256k1') inp1 = TxInputType(address_n=[0], # 14LmW5k4ssUrtbAB4255zdqv3b4w1TuX9e # amount=390000, prev_hash=unhexlify('d5f65ee80147b4bcc70b75e4bbf2d7382021b871bd8867ef8fa525ef50864882'), prev_index=0, amount=None, script_type=InputScriptType.SPENDADDRESS, sequence=None, multisig=None) out1 = TxOutputType(address='1MJ2tj2ThBE62zXbBYA5ZaN3fdve5CPAz1', amount=390000 - 10000, script_type=OutputScriptType.PAYTOADDRESS, address_n=[], multisig=None) calculator = TxWeightCalculator(1, 1) calculator.add_input(inp1) calculator.add_output(signing.output_derive_script(out1, coin, root)) serialized_tx = '010000000182488650ef25a58fef6788bd71b8212038d7f2bbe4750bc7bcb44701e85ef6d5000000006b4830450221009a0b7be0d4ed3146ee262b42202841834698bb3ee39c24e7437df208b8b7077102202b79ab1e7736219387dffe8d615bbdba87e11477104b867ef47afed1a5ede7810121023230848585885f63803a0a8aecdd6538792d5c539215c91698e315bf0253b43dffffffff0160cc0500000000001976a914de9b2a8da088824e8fe51debea566617d851537888ac00000000' tx_weight = len(serialized_tx) / 2 * 4 # non-segwit tx's weight is simple length*4 self.assertEqual(calculator.get_total(), tx_weight)
def test_under_threshold(self): coin_bitcoin = coins.by_name('Bitcoin') ptx1 = TransactionType(version=1, lock_time=0, inputs_cnt=2, outputs_cnt=1) pinp1 = TxInputType(script_sig=unhexlify('483045022072ba61305fe7cb542d142b8f3299a7b10f9ea61f6ffaab5dca8142601869d53c0221009a8027ed79eb3b9bc13577ac2853269323434558528c6b6a7e542be46e7e9a820141047a2d177c0f3626fc68c53610b0270fa6156181f46586c679ba6a88b34c6f4874686390b4d92e5769fbb89c8050b984f4ec0b257a0e5c4ff8bd3b035a51709503'), prev_hash=unhexlify('c16a03f1cf8f99f6b5297ab614586cacec784c2d259af245909dedb0e39eddcf'), prev_index=1, script_type=None, sequence=None) pinp2 = TxInputType(script_sig=unhexlify('48304502200fd63adc8f6cb34359dc6cca9e5458d7ea50376cbd0a74514880735e6d1b8a4c0221008b6ead7fe5fbdab7319d6dfede3a0bc8e2a7c5b5a9301636d1de4aa31a3ee9b101410486ad608470d796236b003635718dfc07c0cac0cfc3bfc3079e4f491b0426f0676e6643a39198e8e7bdaffb94f4b49ea21baa107ec2e237368872836073668214'), prev_hash=unhexlify('1ae39a2f8d59670c8fc61179148a8e61e039d0d9e8ab08610cb69b4a19453eaf'), prev_index=1, script_type=None, sequence=None) pout1 = TxOutputBinType(script_pubkey=unhexlify('76a91424a56db43cf6f2b02e838ea493f95d8d6047423188ac'), amount=390000, address_n=None) inp1 = TxInputType(address_n=[0], # 14LmW5k4ssUrtbAB4255zdqv3b4w1TuX9e # amount=390000, prev_hash=unhexlify('d5f65ee80147b4bcc70b75e4bbf2d7382021b871bd8867ef8fa525ef50864882'), prev_index=0, amount=None, multisig=None, script_type=None, sequence=None) out1 = TxOutputType(address='1MJ2tj2ThBE62zXbBYA5ZaN3fdve5CPAz1', amount=390000 - 90000, # fee increased to 90000, slightly less than the threshold script_type=OutputScriptType.PAYTOADDRESS, address_n=None) tx = SignTx(coin_name=None, version=None, lock_time=None, inputs_count=1, outputs_count=1) messages = [ None, TxRequest(request_type=TXINPUT, details=TxRequestDetailsType(request_index=0, tx_hash=None)), TxAck(tx=TransactionType(inputs=[inp1])), TxRequest(request_type=TXMETA, details=TxRequestDetailsType(request_index=None, tx_hash=unhexlify('d5f65ee80147b4bcc70b75e4bbf2d7382021b871bd8867ef8fa525ef50864882')), serialized=None), TxAck(tx=ptx1), TxRequest(request_type=TXINPUT, details=TxRequestDetailsType(request_index=0, tx_hash=unhexlify('d5f65ee80147b4bcc70b75e4bbf2d7382021b871bd8867ef8fa525ef50864882')), serialized=None), TxAck(tx=TransactionType(inputs=[pinp1])), TxRequest(request_type=TXINPUT, details=TxRequestDetailsType(request_index=1, tx_hash=unhexlify('d5f65ee80147b4bcc70b75e4bbf2d7382021b871bd8867ef8fa525ef50864882')), serialized=None), TxAck(tx=TransactionType(inputs=[pinp2])), TxRequest(request_type=TXOUTPUT, details=TxRequestDetailsType(request_index=0, tx_hash=unhexlify('d5f65ee80147b4bcc70b75e4bbf2d7382021b871bd8867ef8fa525ef50864882')), serialized=None), TxAck(tx=TransactionType(bin_outputs=[pout1])), TxRequest(request_type=TXOUTPUT, details=TxRequestDetailsType(request_index=0, tx_hash=None), serialized=None), TxAck(tx=TransactionType(outputs=[out1])), signing.UiConfirmOutput(out1, coin_bitcoin), True, signing.UiConfirmTotal(300000, 90000, coin_bitcoin), True, TxRequest(request_type=TXINPUT, details=TxRequestDetailsType(request_index=0, tx_hash=None), serialized=None), ] seed = bip39.seed('alcohol woman abuse must during monitor noble actual mixed trade anger aisle', '') root = bip32.from_seed(seed, 'secp256k1') signer = signing.sign_tx(tx, root) for request, response in chunks(messages, 2): self.assertEqualEx(signer.send(request), response)
def derive_node_without_passphrase(path, curve_name=_DEFAULT_CURVE): if not storage.is_initialized(): raise Exception('Device is not initialized') seed = bip39.seed(storage.get_mnemonic(), '') node = bip32.from_seed(seed, curve_name) node.derive_path(path) return node
def derive_node_without_passphrase(path: list, curve_name: str = "secp256k1" ) -> bip32.HDNode: if not storage.is_initialized(): raise Exception("Device is not initialized") seed = mnemonic.get_seed(progress_bar=False) node = bip32.from_seed(seed, curve_name) node.derive_path(path) return node
def root_fingerprint(self) -> int: if self._root_fingerprint is None: # derive m/0' to obtain root_fingerprint n = self._derive_with_cache( prefix_len=0, path=[0 | paths.HARDENED], new_root=lambda: bip32.from_seed(self.seed, self.curve), ) self._root_fingerprint = n.fingerprint() return self._root_fingerprint
def derive_node_without_passphrase(path: list, curve_name: str = _DEFAULT_CURVE ) -> bip32.HDNode: if not storage.is_initialized(): raise Exception("Device is not initialized") seed = bip39.seed(storage.get_mnemonic(), "") node = bip32.from_seed(seed, curve_name) node.derive_path(path) return node
def derive_node_without_passphrase( path: list, curve_name: str = "secp256k1" ) -> bip32.HDNode: if not storage.is_initialized(): raise Exception("Device is not initialized") seed = cache.get(cache.APP_COMMON_SEED_WITHOUT_PASSPHRASE) if seed is None: seed = mnemonic.get_seed(progress_bar=False) cache.set(cache.APP_COMMON_SEED_WITHOUT_PASSPHRASE, seed) node = bip32.from_seed(seed, curve_name) node.derive_path(path) return node
def test_slip39_128(self): mnemonics = [ "extra extend academic bishop cricket bundle tofu goat apart victim " "enlarge program behavior permit course armed jerky faint language modern", "extra extend academic acne away best indicate impact square oasis " "prospect painting voting guest either argue username racism enemy eclipse", "extra extend academic arcade born dive legal hush gross briefing " "talent drug much home firefly toxic analysis idea umbrella slice" ] passphrase = b"TREZOR" identifier, exponent, ems = slip39.recover_ems(mnemonics) master_secret = slip39.decrypt(ems, passphrase, exponent, identifier) node = bip32.from_seed(master_secret, "ed25519 cardano seed") node.derive_cardano(0x80000000 | 44) node.derive_cardano(0x80000000 | 1815) keychain = Keychain([0x80000000 | 44, 0x80000000 | 1815], node) # 44'/1815'/0'/0/i derivation_paths = [ [0x80000000 | 44, 0x80000000 | 1815, 0x80000000, 0, 0], [0x80000000 | 44, 0x80000000 | 1815, 0x80000000, 0, 1], [0x80000000 | 44, 0x80000000 | 1815, 0x80000000, 0, 2] ] public_keys = [ b'bc043d84b8b891d49890edb6aced6f2d78395f255c5b6aea8878b913f83e8579', b'24c4fe188a39103db88818bc191fd8571eae7b284ebcbdf2462bde97b058a95c', b'831a63d381a8dab1e6e1ee991a4300fc70687aae5f97f4fcf92ed1b6c2bd99de' ] chain_codes = [ b"dc3f0d2b5cccb822335ef6213fd133f4ca934151ec44a6000aee43b8a101078c", b"6f7a744035f4b3ddb8f861c18446169643cc3ae85e271b4b4f0eda05cf84c65b", b"672d6af4707aba201b7940231e83dd357f92f8851b3dfdc224ef311e1b64cdeb" ] xpub_keys = [ "bc043d84b8b891d49890edb6aced6f2d78395f255c5b6aea8878b913f83e8579dc3f0d2b5cccb822335ef6213fd133f4ca934151ec44a6000aee43b8a101078c", "24c4fe188a39103db88818bc191fd8571eae7b284ebcbdf2462bde97b058a95c6f7a744035f4b3ddb8f861c18446169643cc3ae85e271b4b4f0eda05cf84c65b", "831a63d381a8dab1e6e1ee991a4300fc70687aae5f97f4fcf92ed1b6c2bd99de672d6af4707aba201b7940231e83dd357f92f8851b3dfdc224ef311e1b64cdeb" ] for index, derivation_path in enumerate(derivation_paths): key = _get_public_key(keychain, derivation_path) self.assertEqual(hexlify(key.node.public_key), public_keys[index]) self.assertEqual(hexlify(key.node.chain_code), chain_codes[index]) self.assertEqual(key.xpub, xpub_keys[index])
def test_slip39_256(self): mnemonics = [ "hobo romp academic axis august founder knife legal recover alien expect " "emphasis loan kitchen involve teacher capture rebuild trial numb spider forward " "ladle lying voter typical security quantity hawk legs idle leaves gasoline", "hobo romp academic agency ancestor industry argue sister scene midst graduate " "profile numb paid headset airport daisy flame express scene usual welcome " "quick silent downtown oral critical step remove says rhythm venture aunt" ] passphrase = b"TREZOR" identifier, exponent, ems = slip39.recover_ems(mnemonics) master_secret = slip39.decrypt(ems, passphrase, exponent, identifier) node = bip32.from_seed(master_secret, "ed25519 cardano seed") node.derive_cardano(0x80000000 | 44) node.derive_cardano(0x80000000 | 1815) keychain = Keychain([0x80000000 | 44, 0x80000000 | 1815], node) # 44'/1815'/0'/0/i derivation_paths = [ [0x80000000 | 44, 0x80000000 | 1815, 0x80000000, 0, 0], [0x80000000 | 44, 0x80000000 | 1815, 0x80000000, 0, 1], [0x80000000 | 44, 0x80000000 | 1815, 0x80000000, 0, 2] ] public_keys = [ b"967a9a041ad1379e31c2c7f2aa4bc2b3f7769341c0ea89ccfb12a904f2e10877", b"6f3805bbc1b7a75afa95dffec331671f3c4662800615e80d2ec1202a9d874c86", b"7f145b50ef07fb9accc40ee07a01fe93ceb6fa07d5a9f20fc3c8a48246dd4d02", ] chain_codes = [ b"7b15d8d9006afe3cd7e04f375a1126a8c7c7c07c59a6f0c5b0310f4245f4edbb", b"44baf30fd549e6a1e05f99c2a2c8971aea8894ee8d9c5fc2c5ae6ee839a56b2d", b"e67d2864614ada5eec8fb8ee1225a94a6fb0a1b3c347c854ec3037351c6a0fc7", ] xpub_keys = [ "967a9a041ad1379e31c2c7f2aa4bc2b3f7769341c0ea89ccfb12a904f2e108777b15d8d9006afe3cd7e04f375a1126a8c7c7c07c59a6f0c5b0310f4245f4edbb", "6f3805bbc1b7a75afa95dffec331671f3c4662800615e80d2ec1202a9d874c8644baf30fd549e6a1e05f99c2a2c8971aea8894ee8d9c5fc2c5ae6ee839a56b2d", "7f145b50ef07fb9accc40ee07a01fe93ceb6fa07d5a9f20fc3c8a48246dd4d02e67d2864614ada5eec8fb8ee1225a94a6fb0a1b3c347c854ec3037351c6a0fc7", ] for index, derivation_path in enumerate(derivation_paths): key = _get_public_key(keychain, derivation_path) self.assertEqual(hexlify(key.node.public_key), public_keys[index]) self.assertEqual(hexlify(key.node.chain_code), chain_codes[index]) self.assertEqual(key.xpub, xpub_keys[index])
async def get_keychain(ctx: wire.Context) -> Keychain: if not device.is_initialized(): raise wire.NotInitialized("Device is not initialized") passphrase = await get_passphrase(ctx) if mnemonic.is_bip39(): # derive the root node from mnemonic and passphrase via Cardano Icarus algorithm root = bip32.from_mnemonic_cardano(mnemonic.get_secret().decode(), passphrase) else: # derive the root node via SLIP-0023 seed = mnemonic.get_seed(passphrase) root = bip32.from_seed(seed, "ed25519 cardano seed") keychain = Keychain(root) return keychain
def test_p2wpkh_in_p2sh_node_derive_address(self): coin = coins.by_name('Groestlcoin Testnet') seed = bip39.seed(' '.join(['all'] * 12), '') root = bip32.from_seed(seed, coin.curve_name) node = node_derive(root, [49 | 0x80000000, 1 | 0x80000000, 0 | 0x80000000, 1, 0]) address = address_p2wpkh_in_p2sh(node.public_key(), coin) self.assertEqual(address, '2N1LGaGg836mqSQqiuUBLfcyGBhyZYBtBZ7') node = node_derive(root, [49 | 0x80000000, 1 | 0x80000000, 0 | 0x80000000, 1, 1]) address = address_p2wpkh_in_p2sh(node.public_key(), coin) self.assertEqual(address, '2NFWLCJQBSpz1oUJwwLpX8ECifFWGxQyzGu') node = node_derive(root, [49 | 0x80000000, 1 | 0x80000000, 0 | 0x80000000, 0, 0]) address = address_p2wpkh_in_p2sh(node.public_key(), coin) self.assertEqual(address, '2N4Q5FhU2497BryFfUgbqkAJE87aKDv3V3e')
def test_outputs(self): seed = bip39.seed('alcohol woman abuse must during monitor noble actual mixed trade anger aisle', '') root = bip32.from_seed(seed, 'secp256k1') coin = coins.by_name(self.tx.coin_name) bip143 = Bip143() for txo in [self.out1, self.out2]: txo_bin = TxOutputBinType() txo_bin.amount = txo.amount txo_bin.script_pubkey = output_derive_script(txo, coin, root) bip143.add_output(txo_bin) self.assertEqual(hexlify(bip143.get_outputs_hash(coin)), b'863ef3e1a92afbfdb97f31ad0fc7683ee943e9abcf2501590ff8f6551f47e5e5')
def test_bip143_outputs(self): seed = bip39.seed('alcohol woman abuse must during monitor noble actual mixed trade anger aisle', '') root = bip32.from_seed(seed, 'secp256k1') coin = coins.by_name(self.tx.coin_name) bip143 = Bip143() for txo in [self.out1, self.out2]: txo_bin = TxOutputBinType() txo_bin.amount = txo.amount txo_bin.script_pubkey = output_derive_script(txo, coin, root) bip143.add_output(txo_bin) self.assertEqual(hexlify(bip143.get_outputs_hash()), b'de984f44532e2173ca0d64314fcefe6d30da6f8cf27bafa706da61df8a226c83')
def test_p2wpkh_node_derive_address(self): coin = coins.by_name('Groestlcoin') seed = bip39.seed(' '.join(['all'] * 12), '') root = bip32.from_seed(seed, coin.curve_name) node = node_derive(root, [84 | 0x80000000, 17 | 0x80000000, 0 | 0x80000000, 1, 0]) address = address_p2wpkh(node.public_key(), coin) self.assertEqual(address, 'grs1qzfpwn55tvkxcw0xwfa0g8k2gtlzlgkcq3z000e') node = node_derive(root, [84 | 0x80000000, 17 | 0x80000000, 0 | 0x80000000, 1, 1]) address = address_p2wpkh(node.public_key(), coin) self.assertEqual(address, 'grs1qxsgwl66tx7tsuwfm4kk5c5dh6tlfpr4qjqg6gg') node = node_derive(root, [84 | 0x80000000, 17 | 0x80000000, 0 | 0x80000000, 0, 0]) address = address_p2wpkh(node.public_key(), coin) self.assertEqual(address, 'grs1qw4teyraux2s77nhjdwh9ar8rl9dt7zww8r6lne')
async def get_keychain(ctx: wire.Context) -> Keychain: if not device.is_initialized(): raise wire.NotInitialized("Device is not initialized") if mnemonic.is_bip39(): passphrase = await get_passphrase(ctx) # derive the root node from mnemonic and passphrase via Cardano Icarus algorithm secret_bytes = mnemonic.get_secret() assert secret_bytes is not None root = bip32.from_mnemonic_cardano(secret_bytes.decode(), passphrase) else: # derive the root node via SLIP-0023 https://github.com/satoshilabs/slips/blob/master/slip-0022.md seed = await get_seed(ctx) root = bip32.from_seed(seed, "ed25519 cardano seed") keychain = Keychain(root) return keychain
def test_p2wpkh_in_p2sh_txweight(self): coin = coins.by_name('Testnet') seed = bip39.seed(' '.join(['all'] * 12), '') root = bip32.from_seed(seed, 'secp256k1') inp1 = TxInputType( # 49'/1'/0'/1/0" - 2N1LGaGg836mqSQqiuUBLfcyGBhyZbremDX address_n=[49 | 0x80000000, 1 | 0x80000000, 0 | 0x80000000, 1, 0], amount=123456789, prev_hash=unhexlify( '20912f98ea3ed849042efed0fdac8cb4fc301961c5988cba56902d8ffb61c337' ), prev_index=0, script_type=InputScriptType.SPENDP2SHWITNESS, sequence=0xffffffff, multisig=None, ) out1 = TxOutputType( address='mhRx1CeVfaayqRwq5zgRQmD7W5aWBfD5mC', amount=12300000, script_type=OutputScriptType.PAYTOADDRESS, address_n=[], multisig=None, ) out2 = TxOutputType( address='2N1LGaGg836mqSQqiuUBLfcyGBhyZbremDX', script_type=OutputScriptType.PAYTOADDRESS, amount=123456789 - 11000 - 12300000, address_n=[], multisig=None, ) calculator = TxWeightCalculator(1, 2) calculator.add_input(inp1) calculator.add_output(signing.output_derive_script(out1, coin, root)) calculator.add_output(signing.output_derive_script(out2, coin, root)) self.assertEqual(calculator.get_total(), 670)
def test_native_p2wpkh_txweight(self): coin = coins.by_name('Testnet') seed = bip39.seed(' '.join(['all'] * 12), '') root = bip32.from_seed(seed, 'secp256k1') inp1 = TxInputType( # 49'/1'/0'/0/0" - tb1qqzv60m9ajw8drqulta4ld4gfx0rdh82un5s65s address_n=[49 | 0x80000000, 1 | 0x80000000, 0 | 0x80000000, 0, 0], amount=12300000, prev_hash=unhexlify( '09144602765ce3dd8f4329445b20e3684e948709c5cdcaf12da3bb079c99448a' ), prev_index=0, script_type=InputScriptType.SPENDWITNESS, sequence=0xffffffff, multisig=None, ) out1 = TxOutputType( address='2N4Q5FhU2497BryFfUgbqkAJE87aKHUhXMp', amount=5000000, script_type=OutputScriptType.PAYTOADDRESS, address_n=[], multisig=None, ) out2 = TxOutputType( address='tb1q694ccp5qcc0udmfwgp692u2s2hjpq5h407urtu', script_type=OutputScriptType.PAYTOADDRESS, amount=12300000 - 11000 - 5000000, address_n=[], multisig=None, ) calculator = TxWeightCalculator(1, 2) calculator.add_input(inp1) calculator.add_output(signing.output_derive_script(out1, coin, root)) calculator.add_output(signing.output_derive_script(out2, coin, root)) self.assertEqual(calculator.get_total(), 566)