From 4e52009e889fca6cc7f8f2905c9b3ea2250ea429 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Vejpustek?= Date: Wed, 27 Nov 2024 15:59:01 +0100 Subject: [PATCH] fixup! feat(core):: support sortedmulti --- core/src/apps/bitcoin/multisig.py | 6 ++++-- core/src/apps/bitcoin/sign_tx/change_detector.py | 9 +-------- core/src/apps/bitcoin/sign_tx/matchcheck.py | 7 ------- 3 files changed, 5 insertions(+), 17 deletions(-) diff --git a/core/src/apps/bitcoin/multisig.py b/core/src/apps/bitcoin/multisig.py index ecb2fa8613..205fccc392 100644 --- a/core/src/apps/bitcoin/multisig.py +++ b/core/src/apps/bitcoin/multisig.py @@ -30,11 +30,13 @@ def multisig_fingerprint(multisig: MultisigRedeemScriptType) -> bytes: raise DataError("Invalid multisig parameters") if multisig.pubkeys_order == MultisigPubkeysOrder.LEXICOGRAPHIC: - pubnodes = sorted(pubnodes, key=lambda n: n.public_key + n.chain_code) + # If the order of pubkeys is lexicographic, we don't want the fingerprint to depend on the order of the pubnodes, so we sort the pubnodes before hashing. + pubnodes.sort(key=lambda n: n.public_key + n.chain_code) h = HashWriter(sha256()) write_uint32(h, m) write_uint32(h, n) + write_uint32(h, multisig.pubkeys_order) for d in pubnodes: write_uint32(h, d.depth) write_uint32(h, d.fingerprint) @@ -92,7 +94,7 @@ def multisig_get_pubkeys(multisig: MultisigRedeemScriptType) -> list[bytes]: multisig_get_pubkey(hd.node, hd.address_n) for hd in multisig.pubkeys ] if multisig.pubkeys_order == MultisigPubkeysOrder.LEXICOGRAPHIC: - pubkeys = sorted(pubkeys) + pubkeys.sort() return pubkeys diff --git a/core/src/apps/bitcoin/sign_tx/change_detector.py b/core/src/apps/bitcoin/sign_tx/change_detector.py index acddac1b5e..ae8995846f 100644 --- a/core/src/apps/bitcoin/sign_tx/change_detector.py +++ b/core/src/apps/bitcoin/sign_tx/change_detector.py @@ -19,7 +19,6 @@ class ChangeDetector: from .matchcheck import ( MultisigChecker, MultisigFingerprintChecker, - PubkeysOrderChecker, ScriptTypeChecker, WalletPathChecker, ) @@ -30,9 +29,6 @@ class ChangeDetector: # Checksum of multisig inputs, used to validate change-output. self.multisig_fingerprint = MultisigFingerprintChecker() - # Whether all inputs use sorted pubkeys or all inputs use unsorted pubkeys, used to validate change-output. - self.pubkeys_order = PubkeysOrderChecker() - # Common prefix of input paths, used to validate change-output. self.wallet_path = WalletPathChecker() @@ -45,14 +41,12 @@ class ChangeDetector: self.script_type.add_input(txi) self.multisig_fingerprint.add_input(txi) self.multisig.add_input(txi) - self.pubkeys_order.add_input(txi) def check_input(self, txi: TxInput) -> None: self.wallet_path.check_input(txi) self.script_type.check_input(txi) self.multisig_fingerprint.check_input(txi) self.multisig.check_input(txi) - self.pubkeys_order.check_input(txi) def output_is_change(self, txo: TxOutput) -> bool: if txo.script_type not in common.CHANGE_OUTPUT_SCRIPT_TYPES: @@ -60,8 +54,7 @@ class ChangeDetector: if txo.multisig: if not ( - self.pubkeys_order.output_matches(txo) - and self.multisig_fingerprint.output_matches(txo) + self.multisig_fingerprint.output_matches(txo) and common.multisig_uses_single_path( txo.multisig ) # An address that uses different derivation paths for different xpubs diff --git a/core/src/apps/bitcoin/sign_tx/matchcheck.py b/core/src/apps/bitcoin/sign_tx/matchcheck.py index 906a6a3aac..3cedb75034 100644 --- a/core/src/apps/bitcoin/sign_tx/matchcheck.py +++ b/core/src/apps/bitcoin/sign_tx/matchcheck.py @@ -107,13 +107,6 @@ class MultisigFingerprintChecker(MatchChecker): return multisig.multisig_fingerprint(txio.multisig) -class PubkeysOrderChecker(MatchChecker): - def attribute_from_tx(self, txio: TxInput | TxOutput) -> Any: - if not txio.multisig: - return None - return txio.multisig.pubkeys_order - - class MultisigChecker(MatchChecker): def attribute_from_tx(self, txio: TxInput | TxOutput) -> Any: return txio.multisig is not None