From b3a383efac3240161d9a80612e1e8f3f7af336b4 Mon Sep 17 00:00:00 2001 From: Andrew Kozlik Date: Wed, 12 Oct 2022 16:32:44 +0200 Subject: [PATCH] chore(core): Move node derivation outside of input_derive_script(). --- core/src/apps/bitcoin/sign_tx/bitcoin.py | 19 +++++++++++++------ core/src/apps/bitcoin/sign_tx/decred.py | 5 +++-- core/src/apps/zcash/signer.py | 6 +++--- 3 files changed, 19 insertions(+), 11 deletions(-) diff --git a/core/src/apps/bitcoin/sign_tx/bitcoin.py b/core/src/apps/bitcoin/sign_tx/bitcoin.py index 7fb76b303c..4ac28360e3 100644 --- a/core/src/apps/bitcoin/sign_tx/bitcoin.py +++ b/core/src/apps/bitcoin/sign_tx/bitcoin.py @@ -160,8 +160,6 @@ class Bitcoin: # STAGE_REQUEST_1_INPUT in legacy progress.advance() txi = await helpers.request_tx_input(self.tx_req, i, self.coin) - script_pubkey = self.input_derive_script(txi) - self.tx_info.add_input(txi, script_pubkey) if txi.script_type not in ( InputScriptType.SPENDTAPROOT, InputScriptType.EXTERNAL, @@ -172,13 +170,18 @@ class Bitcoin: self.segwit.add(i) if input_is_external(txi): + node = None self.external.add(i) if txi.witness or txi.script_sig: self.presigned.add(i) writers.write_tx_input_check(h_presigned_inputs_check, txi) await self.process_external_input(txi, script_pubkey) else: - await self.process_internal_input(txi) + node = self.keychain.derive(txi.address_n) + await self.process_internal_input(txi, node) + + script_pubkey = self.input_derive_script(txi, node) + self.tx_info.add_input(txi, script_pubkey) if txi.orig_hash: await self.process_original_input(txi, script_pubkey) @@ -324,7 +327,7 @@ class Bitcoin: progress.assert_finished() await helpers.request_tx_finish(self.tx_req) - async def process_internal_input(self, txi: TxInput) -> None: + async def process_internal_input(self, txi: TxInput, node: bip32.HDNode) -> None: if txi.script_type not in common.INTERNAL_INPUT_SCRIPT_TYPES: raise wire.DataError("Wrong input script type") @@ -903,12 +906,16 @@ class Bitcoin: # scriptPubKey derivation # === - def input_derive_script(self, txi: TxInput) -> bytes: + def input_derive_script( + self, txi: TxInput, node: bip32.HDNode | None = None + ) -> bytes: if input_is_external(txi): assert txi.script_pubkey is not None # checked in sanitize_tx_input return txi.script_pubkey - node = self.keychain.derive(txi.address_n) + if node is None: + node = self.keychain.derive(txi.address_n) + address = addresses.get_address(txi.script_type, self.coin, node, txi.multisig) return scripts.output_derive_script(address, self.coin) diff --git a/core/src/apps/bitcoin/sign_tx/decred.py b/core/src/apps/bitcoin/sign_tx/decred.py index fc2f235c70..b4ebab5772 100644 --- a/core/src/apps/bitcoin/sign_tx/decred.py +++ b/core/src/apps/bitcoin/sign_tx/decred.py @@ -28,6 +28,7 @@ OUTPUT_SCRIPT_NULL_SSTXCHANGE = ( if TYPE_CHECKING: from typing import Sequence + from trezor.crypto import bip32 from trezor.messages import ( SignTx, TxInput, @@ -181,8 +182,8 @@ class Decred(Bitcoin): if self.serialize: self.write_tx_footer(self.serialized_tx, self.tx_info.tx) - async def process_internal_input(self, txi: TxInput) -> None: - await super().process_internal_input(txi) + async def process_internal_input(self, txi: TxInput, node: bip32.HDNode) -> None: + await super().process_internal_input(txi, node) # Decred serializes inputs early. if self.serialize: diff --git a/core/src/apps/zcash/signer.py b/core/src/apps/zcash/signer.py index 66136e0a5f..b848057542 100644 --- a/core/src/apps/zcash/signer.py +++ b/core/src/apps/zcash/signer.py @@ -71,10 +71,10 @@ class Zcash(Bitcoinlike): await self.sign_nonsegwit_bip143_input(i_sign) def sign_bip143_input(self, i: int, txi: TxInput) -> tuple[bytes, bytes]: - signature_digest = self.tx_info.sig_hasher.hash_zip244( - txi, self.input_derive_script(txi) - ) node = self.keychain.derive(txi.address_n) + signature_digest = self.tx_info.sig_hasher.hash_zip244( + txi, self.input_derive_script(txi, node) + ) signature = ecdsa_sign(node, signature_digest) return node.public_key(), signature