diff --git a/src/apps/wallet/sign_tx/scripts.py b/src/apps/wallet/sign_tx/scripts.py index 7a4bb03cc7..1b55fd3f1b 100644 --- a/src/apps/wallet/sign_tx/scripts.py +++ b/src/apps/wallet/sign_tx/scripts.py @@ -158,8 +158,9 @@ def get_p2wsh_witness(multisig: MultisigRedeemScriptType, signature: bytes, sign for s in signatures: append_signature(w, s, sighash) # size of the witness included - redeem_script = script_multisig(multisig_get_pubkeys(multisig), multisig.m) - + # redeem script + pubkeys = multisig_get_pubkeys(multisig) + redeem_script = script_multisig(pubkeys, multisig.m) write_varint(w, len(redeem_script)) write_bytes(w, redeem_script) return w @@ -167,22 +168,28 @@ def get_p2wsh_witness(multisig: MultisigRedeemScriptType, signature: bytes, sign # -------------------------- Multisig -------------------------- -def input_script_multisig(current_signature, other_signatures, pubkeys, m: int, sighash: int): +def input_script_multisig(multisig: MultisigRedeemScriptType, signature: bytes, signature_index: int, sighash: int): + + signatures = multisig.signatures # other signatures + if len(signatures[signature_index]) > 0: + raise ScriptsError('One of the multisig signatures occupies the current signature\'s spot') + signatures[signature_index] = signature # our signature + w = bytearray() # starts with OP_FALSE because of an old OP_CHECKMULTISIG bug, # which consumes one additional item on the stack # see https://bitcoin.org/en/developer-guide#standard-transactions w.append(0x00) - for s in other_signatures: + + for s in signatures: if len(s): append_signature(w, s, sighash) - append_signature(w, current_signature, sighash) - # redeem script - redeem_script = script_multisig(pubkeys, m) + pubkeys = multisig_get_pubkeys(multisig) + redeem_script = script_multisig(pubkeys, multisig.m) write_op_push(w, len(redeem_script)) - write_bytes(w, script_multisig(pubkeys, m)) + write_bytes(w, redeem_script) return w diff --git a/src/apps/wallet/sign_tx/signing.py b/src/apps/wallet/sign_tx/signing.py index 4af12dee0a..bac784595e 100644 --- a/src/apps/wallet/sign_tx/signing.py +++ b/src/apps/wallet/sign_tx/signing.py @@ -504,8 +504,9 @@ def input_derive_script(coin: CoinType, i: TxInputType, pubkey: bytes, signature if i.script_type == InputScriptType.SPENDP2SHWITNESS: # p2wpkh or p2wsh using p2sh if i.multisig: # p2wsh in p2sh - return input_script_p2wsh_in_p2sh(output_script_multisig_p2wsh(multisig_get_pubkeys(i.multisig), - i.multisig.m)) + pubkeys = multisig_get_pubkeys(i.multisig) + script_hash = output_script_multisig_p2wsh(pubkeys, i.multisig.m) + return input_script_p2wsh_in_p2sh(script_hash) # p2wpkh in p2sh return input_script_p2wpkh_in_p2sh(ecdsa_hash_pubkey(pubkey)) @@ -514,8 +515,12 @@ def input_derive_script(coin: CoinType, i: TxInputType, pubkey: bytes, signature # multisig elif i.script_type == InputScriptType.SPENDMULTISIG: - return input_script_multisig(signature, i.multisig.signatures, multisig_get_pubkeys(i.multisig), i.multisig.m, - get_hash_type(coin)) + signature_index = multisig_pubkey_index(i.multisig, pubkey) + if signature_index is None: + raise SigningError(FailureType.DataError, + 'Pubkey not found in multisig script') + return input_script_multisig( + i.multisig, signature, signature_index, get_hash_type(coin)) else: raise SigningError(FailureType.ProcessError, 'Invalid script type')