diff --git a/core/src/apps/wallet/sign_tx/__init__.py b/core/src/apps/wallet/sign_tx/__init__.py index d8e833b9e..565e87761 100644 --- a/core/src/apps/wallet/sign_tx/__init__.py +++ b/core/src/apps/wallet/sign_tx/__init__.py @@ -14,7 +14,6 @@ from apps.wallet.sign_tx import ( multisig, progress, scripts, - segwit_bip143, ) if not utils.BITCOIN_ONLY: @@ -52,7 +51,6 @@ async def sign_tx(ctx: wire.Context, msg: SignTx, keychain: seed.Keychain) -> Tx multisig.MultisigError, addresses.AddressError, scripts.ScriptsError, - segwit_bip143.Bip143Error, ) as e: raise wire.Error(*e.args) if isinstance(req, TxRequest): diff --git a/core/src/apps/wallet/sign_tx/bitcoin.py b/core/src/apps/wallet/sign_tx/bitcoin.py index fb43b8650..88703a287 100644 --- a/core/src/apps/wallet/sign_tx/bitcoin.py +++ b/core/src/apps/wallet/sign_tx/bitcoin.py @@ -20,7 +20,6 @@ from apps.wallet.sign_tx import ( multisig, progress, scripts, - segwit_bip143, tx_weight, writers, ) @@ -113,10 +112,12 @@ class Bitcoin: self.h_confirmed = self.create_hash_writer() # not a real tx hash # BIP-0143 transaction hashing - self.hash143 = self.create_hash143() + self.init_hash143() - def create_hash143(self) -> segwit_bip143.Bip143: - return segwit_bip143.Bip143() + def init_hash143(self) -> None: + self.h_prevouts = HashWriter(sha256()) + self.h_sequence = HashWriter(sha256()) + self.h_outputs = HashWriter(sha256()) def create_hash_writer(self) -> HashWriter: return HashWriter(sha256()) @@ -194,7 +195,7 @@ class Bitcoin: self.wallet_path.add_input(txi) self.multisig_fingerprint.add_input(txi) writers.write_tx_input_check(self.h_confirmed, txi) - self.hash143.add_input(txi) # all inputs are included (non-segwit as well) + self.hash143_add_input(txi) # all inputs are included (non-segwit as well) if not addresses.validate_full_path(txi.address_n, self.coin, txi.script_type): await helpers.confirm_foreign_address(txi.address_n) @@ -231,7 +232,7 @@ class Bitcoin: raise SigningError(FailureType.ActionCancelled, "Output cancelled") writers.write_tx_output(self.h_confirmed, txo_bin) - self.hash143.add_output(txo_bin) + self.hash143_add_output(txo_bin) self.total_out += txo_bin.amount def on_negative_fee(self) -> None: @@ -267,12 +268,8 @@ class Bitcoin: node = self.keychain.derive(txi.address_n, self.coin.curve_name) public_key = node.public_key() - hash143_hash = self.hash143.preimage_hash( - self.coin, - self.tx, - txi, - addresses.ecdsa_hash_pubkey(public_key, self.coin), - self.get_hash_type(), + hash143_hash = self.hash143_preimage_hash( + txi, addresses.ecdsa_hash_pubkey(public_key, self.coin) ) signature = ecdsa_sign(node, hash143_hash) @@ -438,7 +435,7 @@ class Bitcoin: # Validations to perform on the UTXO when checking the previous transaction output amount. pass - # TX Helpers + # Tx Helpers # === def get_hash_type(self) -> int: @@ -472,7 +469,7 @@ class Bitcoin: self.tx_req.serialized.signature_index = index self.tx_req.serialized.signature = signature - # TX Outputs + # Tx Outputs # === def output_derive_script(self, txo: TxOutputType) -> bytes: @@ -512,6 +509,71 @@ class Bitcoin: txi, self.coin, self.get_hash_type(), pubkey, signature ) + # BIP-0143 + # === + + def hash143_add_input(self, txi: TxInputType) -> None: + writers.write_bytes_reversed( + self.h_prevouts, txi.prev_hash, writers.TX_HASH_SIZE + ) + writers.write_uint32(self.h_prevouts, txi.prev_index) + writers.write_uint32(self.h_sequence, txi.sequence) + + def hash143_add_output(self, txo_bin: TxOutputBinType) -> None: + writers.write_tx_output(self.h_outputs, txo_bin) + + def get_prevouts_hash(self) -> bytes: + return writers.get_tx_hash(self.h_prevouts, double=self.coin.sign_hash_double) + + def get_sequence_hash(self) -> bytes: + return writers.get_tx_hash(self.h_sequence, double=self.coin.sign_hash_double) + + def get_outputs_hash(self) -> bytes: + return writers.get_tx_hash(self.h_outputs, double=self.coin.sign_hash_double) + + def hash143_preimage_hash(self, txi: TxInputType, pubkeyhash: bytes) -> bytes: + h_preimage = HashWriter(sha256()) + + # nVersion + writers.write_uint32(h_preimage, self.tx.version) + + # hashPrevouts + writers.write_bytes_fixed( + h_preimage, self.get_prevouts_hash(), writers.TX_HASH_SIZE + ) + + # hashSequence + writers.write_bytes_fixed( + h_preimage, self.get_sequence_hash(), writers.TX_HASH_SIZE + ) + + # outpoint + writers.write_bytes_reversed(h_preimage, txi.prev_hash, writers.TX_HASH_SIZE) + writers.write_uint32(h_preimage, txi.prev_index) + + # scriptCode + script_code = scripts.bip143_derive_script_code(txi, pubkeyhash) + writers.write_bytes_prefixed(h_preimage, script_code) + + # amount + writers.write_uint64(h_preimage, txi.amount) + + # nSequence + writers.write_uint32(h_preimage, txi.sequence) + + # hashOutputs + writers.write_bytes_fixed( + h_preimage, self.get_outputs_hash(), writers.TX_HASH_SIZE + ) + + # nLockTime + writers.write_uint32(h_preimage, self.tx.lock_time) + + # nHashType + writers.write_uint32(h_preimage, self.get_hash_type()) + + return writers.get_tx_hash(h_preimage, double=self.coin.sign_hash_double) + def input_is_segwit(txi: TxInputType) -> bool: return txi.script_type in helpers.SEGWIT_INPUT_SCRIPT_TYPES diff --git a/core/src/apps/wallet/sign_tx/decred.py b/core/src/apps/wallet/sign_tx/decred.py index b39e2a7f9..496247659 100644 --- a/core/src/apps/wallet/sign_tx/decred.py +++ b/core/src/apps/wallet/sign_tx/decred.py @@ -14,7 +14,6 @@ from apps.common import coininfo, seed from apps.wallet.sign_tx import addresses, helpers, multisig, progress, scripts, writers from apps.wallet.sign_tx.bitcoin import Bitcoin from apps.wallet.sign_tx.common import SigningError, ecdsa_sign -from apps.wallet.sign_tx.segwit_bip143 import Bip143 DECRED_SERIALIZE_FULL = const(0 << 16) DECRED_SERIALIZE_NO_WITNESS = const(1 << 16) @@ -26,35 +25,6 @@ if False: from typing import Union -class DecredPrefixHasher(Bip143): - """ - While Decred does not have the exact same implementation as bip143/zip143, - the semantics for using the prefix hash of transactions are close enough - that a pseudo-bip143 class can be used. - """ - - def __init__(self, tx: SignTx): - self.h_prefix = HashWriter(blake256()) - writers.write_uint32(self.h_prefix, tx.version | DECRED_SERIALIZE_NO_WITNESS) - writers.write_varint(self.h_prefix, tx.inputs_count) - - def add_input(self, txi: TxInputType) -> None: - writers.write_tx_input_decred(self.h_prefix, txi) - - def add_output_count(self, tx: SignTx) -> None: - writers.write_varint(self.h_prefix, tx.outputs_count) - - def add_output(self, txo_bin: TxOutputBinType) -> None: - writers.write_tx_output(self.h_prefix, txo_bin) - - def add_locktime_expiry(self, tx: SignTx) -> None: - writers.write_uint32(self.h_prefix, tx.lock_time) - writers.write_uint32(self.h_prefix, tx.expiry) - - def get_prefix_hash(self) -> bytes: - return self.h_prefix.get_digest() - - class Decred(Bitcoin): def __init__( self, tx: SignTx, keychain: seed.Keychain, coin: coininfo.CoinInfo @@ -62,23 +32,25 @@ class Decred(Bitcoin): ensure(coin.decred) super().__init__(tx, keychain, coin) - def create_hash143(self) -> Bip143: - return DecredPrefixHasher(self.tx) # pseudo BIP-0143 prefix hashing + self.write_tx_header(self.serialized_tx, self.tx, has_segwit=False) + writers.write_varint(self.serialized_tx, self.tx.inputs_count) + + def init_hash143(self) -> None: + self.h_prefix = self.create_hash_writer() + writers.write_uint32( + self.h_prefix, self.tx.version | DECRED_SERIALIZE_NO_WITNESS + ) + writers.write_varint(self.h_prefix, self.tx.inputs_count) def create_hash_writer(self) -> HashWriter: return HashWriter(blake256()) - async def step1_process_inputs(self) -> None: - self.write_tx_header(self.serialized_tx, self.tx, has_segwit=False) - writers.write_varint(self.serialized_tx, self.tx.inputs_count) - await super().step1_process_inputs() - async def step2_confirm_outputs(self) -> None: writers.write_varint(self.serialized_tx, self.tx.outputs_count) - self.hash143.add_output_count(self.tx) + writers.write_varint(self.h_prefix, self.tx.outputs_count) await super().step2_confirm_outputs() - self.hash143.add_locktime_expiry(self.tx) self.write_tx_footer(self.serialized_tx, self.tx) + self.write_tx_footer(self.h_prefix, self.tx) async def process_input(self, i: int, txi: TxInputType) -> None: await super().process_input(i, txi) @@ -95,14 +67,13 @@ class Decred(Bitcoin): "Cannot send to output with script version != 0", ) txo_bin.decred_script_version = txo.decred_script_version - writers.write_tx_output(self.serialized_tx, txo_bin) - await super().confirm_output(i, txo, txo_bin) + writers.write_tx_output(self.serialized_tx, txo_bin) async def step4_serialize_inputs(self) -> None: writers.write_varint(self.serialized_tx, self.tx.inputs_count) - prefix_hash = self.hash143.get_prefix_hash() + prefix_hash = self.h_prefix.get_digest() for i_sign in range(self.tx.inputs_count): progress.advance() @@ -179,6 +150,12 @@ class Decred(Bitcoin): "Cannot use utxo that has script_version != 0", ) + def hash143_add_input(self, txi: TxInputType) -> None: + writers.write_tx_input_decred(self.h_prefix, txi) + + def hash143_add_output(self, txo_bin: TxOutputBinType) -> None: + writers.write_tx_output(self.h_prefix, txo_bin) + def write_tx_input(self, w: writers.Writer, txi: TxInputType) -> None: writers.write_tx_input_decred(w, txi) diff --git a/core/src/apps/wallet/sign_tx/scripts.py b/core/src/apps/wallet/sign_tx/scripts.py index f6d22f684..2c2df11f5 100644 --- a/core/src/apps/wallet/sign_tx/scripts.py +++ b/core/src/apps/wallet/sign_tx/scripts.py @@ -111,6 +111,31 @@ def output_derive_script(txo: TxOutputType, coin: CoinInfo) -> bytes: raise ScriptsError(FailureType.DataError, "Invalid address type") +# see https://github.com/bitcoin/bips/blob/master/bip-0143.mediawiki#specification +# item 5 for details +def bip143_derive_script_code(txi: TxInputType, pubkeyhash: bytes) -> bytearray: + + if txi.multisig: + return output_script_multisig( + multisig_get_pubkeys(txi.multisig), txi.multisig.m + ) + + p2pkh = ( + txi.script_type == InputScriptType.SPENDWITNESS + or txi.script_type == InputScriptType.SPENDP2SHWITNESS + or txi.script_type == InputScriptType.SPENDADDRESS + ) + if p2pkh: + # for p2wpkh in p2sh or native p2wpkh + # the scriptCode is a classic p2pkh + return output_script_p2pkh(pubkeyhash) + + else: + raise ScriptsError( + FailureType.DataError, "Unknown input script type for bip143 script code", + ) + + # P2PKH, P2SH # === # https://github.com/bitcoin/bips/blob/master/bip-0016.mediawiki diff --git a/core/src/apps/wallet/sign_tx/segwit_bip143.py b/core/src/apps/wallet/sign_tx/segwit_bip143.py deleted file mode 100644 index 9501f4394..000000000 --- a/core/src/apps/wallet/sign_tx/segwit_bip143.py +++ /dev/null @@ -1,115 +0,0 @@ -from trezor.crypto.hashlib import sha256 -from trezor.messages import FailureType, InputScriptType -from trezor.messages.SignTx import SignTx -from trezor.messages.TxInputType import TxInputType -from trezor.messages.TxOutputBinType import TxOutputBinType -from trezor.utils import HashWriter, ensure - -from apps.common.coininfo import CoinInfo -from apps.wallet.sign_tx.multisig import multisig_get_pubkeys -from apps.wallet.sign_tx.scripts import output_script_multisig, output_script_p2pkh -from apps.wallet.sign_tx.writers import ( - TX_HASH_SIZE, - get_tx_hash, - write_bytes_fixed, - write_bytes_prefixed, - write_bytes_reversed, - write_tx_output, - write_uint32, - write_uint64, -) - - -class Bip143Error(ValueError): - pass - - -class Bip143: - def __init__(self) -> None: - self.h_prevouts = HashWriter(sha256()) - self.h_sequence = HashWriter(sha256()) - self.h_outputs = HashWriter(sha256()) - - def add_input(self, txi: TxInputType) -> None: - write_bytes_reversed(self.h_prevouts, txi.prev_hash, TX_HASH_SIZE) - write_uint32(self.h_prevouts, txi.prev_index) - write_uint32(self.h_sequence, txi.sequence) - - def add_output_count(self, tx: SignTx) -> None: - pass - - def add_output(self, txo_bin: TxOutputBinType) -> None: - write_tx_output(self.h_outputs, txo_bin) - - def add_locktime_expiry(self, tx: SignTx) -> None: - pass - - def get_prevouts_hash(self, coin: CoinInfo) -> bytes: - return get_tx_hash(self.h_prevouts, double=coin.sign_hash_double) - - def get_sequence_hash(self, coin: CoinInfo) -> bytes: - return get_tx_hash(self.h_sequence, double=coin.sign_hash_double) - - def get_outputs_hash(self, coin: CoinInfo) -> bytes: - return get_tx_hash(self.h_outputs, double=coin.sign_hash_double) - - def get_prefix_hash(self) -> bytes: - pass - - def preimage_hash( - self, - coin: CoinInfo, - tx: SignTx, - txi: TxInputType, - pubkeyhash: bytes, - sighash: int, - ) -> bytes: - h_preimage = HashWriter(sha256()) - - ensure(not coin.overwintered) - - write_uint32(h_preimage, tx.version) # nVersion - # hashPrevouts - write_bytes_fixed(h_preimage, self.get_prevouts_hash(coin), TX_HASH_SIZE) - # hashSequence - write_bytes_fixed(h_preimage, self.get_sequence_hash(coin), TX_HASH_SIZE) - - write_bytes_reversed(h_preimage, txi.prev_hash, TX_HASH_SIZE) # outpoint - write_uint32(h_preimage, txi.prev_index) # outpoint - - script_code = derive_script_code(txi, pubkeyhash) # scriptCode - write_bytes_prefixed(h_preimage, script_code) - - write_uint64(h_preimage, txi.amount) # amount - write_uint32(h_preimage, txi.sequence) # nSequence - # hashOutputs - write_bytes_fixed(h_preimage, self.get_outputs_hash(coin), TX_HASH_SIZE) - write_uint32(h_preimage, tx.lock_time) # nLockTime - write_uint32(h_preimage, sighash) # nHashType - - return get_tx_hash(h_preimage, double=coin.sign_hash_double) - - -# see https://github.com/bitcoin/bips/blob/master/bip-0143.mediawiki#specification -# item 5 for details -def derive_script_code(txi: TxInputType, pubkeyhash: bytes) -> bytearray: - - if txi.multisig: - return output_script_multisig( - multisig_get_pubkeys(txi.multisig), txi.multisig.m - ) - - p2pkh = ( - txi.script_type == InputScriptType.SPENDWITNESS - or txi.script_type == InputScriptType.SPENDP2SHWITNESS - or txi.script_type == InputScriptType.SPENDADDRESS - ) - if p2pkh: - # for p2wpkh in p2sh or native p2wpkh - # the scriptCode is a classic p2pkh - return output_script_p2pkh(pubkeyhash) - - else: - raise Bip143Error( - FailureType.DataError, "Unknown input script type for bip143 script code", - ) diff --git a/core/src/apps/wallet/sign_tx/zcash.py b/core/src/apps/wallet/sign_tx/zcash.py index 75dceacfa..2355bc151 100644 --- a/core/src/apps/wallet/sign_tx/zcash.py +++ b/core/src/apps/wallet/sign_tx/zcash.py @@ -15,7 +15,6 @@ from apps.wallet.sign_tx.bitcoinlike import Bitcoinlike from apps.wallet.sign_tx.common import SigningError from apps.wallet.sign_tx.multisig import multisig_get_pubkeys from apps.wallet.sign_tx.scripts import output_script_multisig, output_script_p2pkh -from apps.wallet.sign_tx.segwit_bip143 import Bip143 from apps.wallet.sign_tx.writers import ( TX_HASH_SIZE, get_tx_hash, @@ -34,167 +33,28 @@ if False: OVERWINTERED = const(0x80000000) -def derive_script_code(txi: TxInputType, pubkeyhash: bytes) -> bytearray: - - if txi.multisig: - return output_script_multisig( - multisig_get_pubkeys(txi.multisig), txi.multisig.m - ) - - p2pkh = txi.script_type == InputScriptType.SPENDADDRESS - if p2pkh: - return output_script_p2pkh(pubkeyhash) - - else: - raise SigningError( - FailureType.DataError, "Unknown input script type for zip143 script code" - ) - - -class Zip143(Bip143): - def __init__(self, branch_id: int) -> None: - self.branch_id = branch_id - self.h_prevouts = HashWriter(blake2b(outlen=32, personal=b"ZcashPrevoutHash")) - self.h_sequence = HashWriter(blake2b(outlen=32, personal=b"ZcashSequencHash")) - self.h_outputs = HashWriter(blake2b(outlen=32, personal=b"ZcashOutputsHash")) - - def get_prevouts_hash(self, coin: CoinInfo) -> bytes: - return get_tx_hash(self.h_prevouts) - - def get_sequence_hash(self, coin: CoinInfo) -> bytes: - return get_tx_hash(self.h_sequence) - - def get_outputs_hash(self, coin: CoinInfo) -> bytes: - return get_tx_hash(self.h_outputs) - - def preimage_hash( - self, - coin: CoinInfo, - tx: SignTx, - txi: TxInputType, - pubkeyhash: bytes, - sighash: int, - ) -> bytes: - h_preimage = HashWriter( - blake2b( - outlen=32, personal=b"ZcashSigHash" + struct.pack(" bytes: - h_preimage = HashWriter( - blake2b( - outlen=32, personal=b"ZcashSigHash" + struct.pack(" None: ensure(coin.overwintered) super().__init__(tx, keychain, coin) - def create_hash143(self) -> Bip143: if self.tx.version == 3: - branch_id = self.tx.branch_id or 0x5BA81B19 # Overwinter - return Zip143(branch_id) # ZIP-0143 transaction hashing + if not self.tx.branch_id: + self.tx.branch_id = 0x5BA81B19 # Overwinter elif self.tx.version == 4: - branch_id = self.tx.branch_id or 0x76B809BB # Sapling - return Zip243(branch_id) # ZIP-0243 transaction hashing + if not self.tx.branch_id: + self.tx.branch_id = 0x76B809BB # Sapling else: raise SigningError( FailureType.DataError, "Unsupported version for overwintered transaction", ) + def init_hash143(self) -> None: + self.h_prevouts = HashWriter(blake2b(outlen=32, personal=b"ZcashPrevoutHash")) + self.h_sequence = HashWriter(blake2b(outlen=32, personal=b"ZcashSequencHash")) + self.h_outputs = HashWriter(blake2b(outlen=32, personal=b"ZcashOutputsHash")) + async def step7_finish(self) -> None: self.write_tx_footer(self.serialized_tx, self.tx) @@ -227,3 +87,98 @@ class Overwintered(Bitcoinlike): # nVersion | fOverwintered write_uint32(w, tx.version | OVERWINTERED) write_uint32(w, tx.version_group_id) # nVersionGroupId + + # ZIP-0143 / ZIP-0243 + # === + + def get_prevouts_hash(self) -> bytes: + return get_tx_hash(self.h_prevouts) + + def get_sequence_hash(self) -> bytes: + return get_tx_hash(self.h_sequence) + + def get_outputs_hash(self) -> bytes: + return get_tx_hash(self.h_outputs) + + def hash143_preimage_hash(self, txi: TxInputType, pubkeyhash: bytes) -> bytes: + h_preimage = HashWriter( + blake2b( + outlen=32, + personal=b"ZcashSigHash" + struct.pack(" bytearray: + + if txi.multisig: + return output_script_multisig( + multisig_get_pubkeys(txi.multisig), txi.multisig.m + ) + + p2pkh = txi.script_type == InputScriptType.SPENDADDRESS + if p2pkh: + return output_script_p2pkh(pubkeyhash) + + else: + raise SigningError( + FailureType.DataError, "Unknown input script type for zip143 script code" + ) diff --git a/core/tests/test_apps.wallet.segwit.bip143.native_p2wpkh.py b/core/tests/test_apps.wallet.segwit.bip143.native_p2wpkh.py index 5ebc36f9d..e08469ccd 100644 --- a/core/tests/test_apps.wallet.segwit.bip143.native_p2wpkh.py +++ b/core/tests/test_apps.wallet.segwit.bip143.native_p2wpkh.py @@ -1,14 +1,15 @@ from common import * from apps.wallet.sign_tx.scripts import output_derive_script -from apps.wallet.sign_tx.segwit_bip143 import * +from apps.wallet.sign_tx.bitcoin import Bitcoin from apps.common import coins from trezor.messages.SignTx import SignTx from trezor.messages.TxInputType import TxInputType from trezor.messages.TxOutputType import TxOutputType +from trezor.messages.TxOutputBinType import TxOutputBinType from trezor.messages import InputScriptType from trezor.messages import OutputScriptType -from trezor.crypto import bip32, bip39 +from trezor.crypto import bip39 class TestSegwitBip143NativeP2WPKH(unittest.TestCase): @@ -43,55 +44,51 @@ class TestSegwitBip143NativeP2WPKH(unittest.TestCase): address_n=[]) def test_prevouts(self): - - bip143 = Bip143() - bip143.add_input(self.inp1) - bip143.add_input(self.inp2) coin = coins.by_name(self.tx.coin_name) - self.assertEqual(hexlify(bip143.get_prevouts_hash(coin)), b'96b827c8483d4e9b96712b6713a7b68d6e8003a781feba36c31143470b4efd37') + bip143 = Bitcoin(self.tx, None, coin) + bip143.hash143_add_input(self.inp1) + bip143.hash143_add_input(self.inp2) + self.assertEqual(hexlify(bip143.get_prevouts_hash()), b'96b827c8483d4e9b96712b6713a7b68d6e8003a781feba36c31143470b4efd37') def test_sequence(self): - - bip143 = Bip143() - bip143.add_input(self.inp1) - bip143.add_input(self.inp2) coin = coins.by_name(self.tx.coin_name) - self.assertEqual(hexlify(bip143.get_sequence_hash(coin)), b'52b0a642eea2fb7ae638c36f6252b6750293dbe574a806984b8e4d8548339a3b') + bip143 = Bitcoin(self.tx, None, coin) + bip143.hash143_add_input(self.inp1) + bip143.hash143_add_input(self.inp2) + self.assertEqual(hexlify(bip143.get_sequence_hash()), b'52b0a642eea2fb7ae638c36f6252b6750293dbe574a806984b8e4d8548339a3b') def test_outputs(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 = Bip143() + bip143 = Bitcoin(self.tx, None, coin) for txo in [self.out1, self.out2]: txo_bin = TxOutputBinType() txo_bin.amount = txo.amount txo_bin.script_pubkey = output_derive_script(txo, coin) - bip143.add_output(txo_bin) + bip143.hash143_add_output(txo_bin) - self.assertEqual(hexlify(bip143.get_outputs_hash(coin)), + self.assertEqual(hexlify(bip143.get_outputs_hash()), b'863ef3e1a92afbfdb97f31ad0fc7683ee943e9abcf2501590ff8f6551f47e5e5') 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 = Bip143() - bip143.add_input(self.inp1) - bip143.add_input(self.inp2) + bip143 = Bitcoin(self.tx, None, 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 txo_bin.script_pubkey = output_derive_script(txo, coin) - bip143.add_output(txo_bin) + bip143.hash143_add_output(txo_bin) # test data public key hash # only for input 2 - input 1 is not segwit - result = bip143.preimage_hash(coin, self.tx, self.inp2, unhexlify('1d0f172a0ecb48aee1be1f2687d2963ae33f71a1'), 0x01) + result = bip143.hash143_preimage_hash(self.inp2, unhexlify('1d0f172a0ecb48aee1be1f2687d2963ae33f71a1')) self.assertEqual(hexlify(result), b'c37af31116d1b27caf68aae9e3ac82f1477929014d5b917657d0eb49478cb670') diff --git a/core/tests/test_apps.wallet.segwit.bip143.p2wpkh_in_p2sh.py b/core/tests/test_apps.wallet.segwit.bip143.p2wpkh_in_p2sh.py index 06236bfd2..ddb9fbaea 100644 --- a/core/tests/test_apps.wallet.segwit.bip143.p2wpkh_in_p2sh.py +++ b/core/tests/test_apps.wallet.segwit.bip143.p2wpkh_in_p2sh.py @@ -1,14 +1,15 @@ from common import * from apps.wallet.sign_tx.scripts import output_derive_script -from apps.wallet.sign_tx.segwit_bip143 import * +from apps.wallet.sign_tx.bitcoin import Bitcoin from apps.common import coins from trezor.messages.SignTx import SignTx from trezor.messages.TxInputType import TxInputType from trezor.messages.TxOutputType import TxOutputType +from trezor.messages.TxOutputBinType import TxOutputBinType from trezor.messages import InputScriptType from trezor.messages import OutputScriptType -from trezor.crypto import bip32, bip39 +from trezor.crypto import bip39 class TestSegwitBip143(unittest.TestCase): @@ -35,50 +36,44 @@ class TestSegwitBip143(unittest.TestCase): address_n=[]) def test_bip143_prevouts(self): - - bip143 = Bip143() - bip143.add_input(self.inp1) coin = coins.by_name(self.tx.coin_name) - self.assertEqual(hexlify(bip143.get_prevouts_hash(coin)), b'b0287b4a252ac05af83d2dcef00ba313af78a3e9c329afa216eb3aa2a7b4613a') + bip143 = Bitcoin(self.tx, None, coin) + bip143.hash143_add_input(self.inp1) + self.assertEqual(hexlify(bip143.get_prevouts_hash()), b'b0287b4a252ac05af83d2dcef00ba313af78a3e9c329afa216eb3aa2a7b4613a') def test_bip143_sequence(self): - - bip143 = Bip143() - bip143.add_input(self.inp1) coin = coins.by_name(self.tx.coin_name) - self.assertEqual(hexlify(bip143.get_sequence_hash(coin)), b'18606b350cd8bf565266bc352f0caddcf01e8fa789dd8a15386327cf8cabe198') + bip143 = Bitcoin(self.tx, None, coin) + bip143.hash143_add_input(self.inp1) + self.assertEqual(hexlify(bip143.get_sequence_hash()), b'18606b350cd8bf565266bc352f0caddcf01e8fa789dd8a15386327cf8cabe198') def test_bip143_outputs(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 = Bip143() + bip143 = Bitcoin(self.tx, None, coin) for txo in [self.out1, self.out2]: txo_bin = TxOutputBinType() txo_bin.amount = txo.amount txo_bin.script_pubkey = output_derive_script(txo, coin) - bip143.add_output(txo_bin) + bip143.hash143_add_output(txo_bin) - self.assertEqual(hexlify(bip143.get_outputs_hash(coin)), + self.assertEqual(hexlify(bip143.get_outputs_hash()), b'de984f44532e2173ca0d64314fcefe6d30da6f8cf27bafa706da61df8a226c83') 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 = Bip143() - bip143.add_input(self.inp1) + bip143 = Bitcoin(self.tx, None, coin) + bip143.hash143_add_input(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) - bip143.add_output(txo_bin) + bip143.hash143_add_output(txo_bin) # test data public key hash - result = bip143.preimage_hash(coin, self.tx, self.inp1, unhexlify('79091972186c449eb1ded22b78e40d009bdf0089'), 0x01) + result = bip143.hash143_preimage_hash(self.inp1, unhexlify('79091972186c449eb1ded22b78e40d009bdf0089')) self.assertEqual(hexlify(result), b'64f3b0f4dd2bb3aa1ce8566d220cc74dda9df97d8490cc81d89d735c92e59fb6') diff --git a/core/tests/test_apps.wallet.zcash.zip143.py b/core/tests/test_apps.wallet.zcash.zip143.py index 04767353c..7d39250d9 100644 --- a/core/tests/test_apps.wallet.zcash.zip143.py +++ b/core/tests/test_apps.wallet.zcash.zip143.py @@ -7,7 +7,7 @@ from trezor.messages.TxOutputBinType import TxOutputBinType from apps.common import coins if not utils.BITCOIN_ONLY: - from apps.wallet.sign_tx.zcash import Zip143 + from apps.wallet.sign_tx.zcash import Overwintered # test vectors inspired from https://github.com/zcash-hackworks/zcash-test-vectors/blob/master/zip_0143.py @@ -153,7 +153,9 @@ class TestZcashZip143(unittest.TestCase): expiry=v["expiry"], version_group_id=v["version_group_id"], ) - zip143 = Zip143(0x5ba81b19) # Overwinter + + zip143 = Overwintered(tx, None, coin) + for i in v["inputs"]: txi = TxInputType() txi.amount = i["amount"] @@ -161,22 +163,18 @@ class TestZcashZip143(unittest.TestCase): txi.prev_index = i["prevout"][1] txi.script_type = i["script_type"] txi.sequence = i["sequence"] - zip143.add_input(txi) + zip143.hash143_add_input(txi) for o in v["outputs"]: txo = TxOutputBinType() txo.amount = o["amount"] txo.script_pubkey = unhexlify(o["script_pubkey"]) - zip143.add_output(txo) + zip143.hash143_add_output(txo) - self.assertEqual(hexlify(zip143.get_prevouts_hash(coin)), v["prevouts_hash"]) - self.assertEqual(hexlify(zip143.get_sequence_hash(coin)), v["sequence_hash"]) - self.assertEqual(hexlify(zip143.get_outputs_hash(coin)), v["outputs_hash"]) + self.assertEqual(hexlify(zip143.get_prevouts_hash()), v["prevouts_hash"]) + self.assertEqual(hexlify(zip143.get_sequence_hash()), v["sequence_hash"]) + self.assertEqual(hexlify(zip143.get_outputs_hash()), v["outputs_hash"]) self.assertEqual( - hexlify( - zip143.preimage_hash( - coin, tx, txi, unhexlify(i["pubkeyhash"]), v["hash_type"] - ) - ), + hexlify(zip143.hash143_preimage_hash(txi, unhexlify(i["pubkeyhash"]))), v["preimage_hash"], ) diff --git a/core/tests/test_apps.wallet.zcash.zip243.py b/core/tests/test_apps.wallet.zcash.zip243.py index 0ac1a3dd8..ff1c68f2e 100644 --- a/core/tests/test_apps.wallet.zcash.zip243.py +++ b/core/tests/test_apps.wallet.zcash.zip243.py @@ -6,8 +6,7 @@ from trezor.messages.TxOutputBinType import TxOutputBinType from apps.common import coins -if not utils.BITCOIN_ONLY: - from apps.wallet.sign_tx.zcash import Zip243 +from apps.wallet.sign_tx.zcash import Overwintered # test vectors inspired from https://github.com/zcash-hackworks/zcash-test-vectors/blob/master/zip_0243.py @@ -187,7 +186,9 @@ class TestZcashZip243(unittest.TestCase): expiry=v["expiry"], version_group_id=v["version_group_id"], ) - zip243 = Zip243(0x76b809bb) # Sapling + + zip243 = Overwintered(tx, None, coin) + for i in v["inputs"]: txi = TxInputType() txi.amount = i["amount"] @@ -195,24 +196,17 @@ class TestZcashZip243(unittest.TestCase): txi.prev_index = i["prevout"][1] txi.script_type = i["script_type"] txi.sequence = i["sequence"] - zip243.add_input(txi) + zip243.hash143_add_input(txi) for o in v["outputs"]: txo = TxOutputBinType() txo.amount = o["amount"] txo.script_pubkey = unhexlify(o["script_pubkey"]) - zip243.add_output(txo) + zip243.hash143_add_output(txo) - self.assertEqual(hexlify(zip243.get_prevouts_hash(coin)), v["prevouts_hash"]) - self.assertEqual(hexlify(zip243.get_sequence_hash(coin)), v["sequence_hash"]) - self.assertEqual(hexlify(zip243.get_outputs_hash(coin)), v["outputs_hash"]) - self.assertEqual( - hexlify( - zip243.preimage_hash( - coin, tx, txi, unhexlify(i["pubkeyhash"]), v["hash_type"] - ) - ), - v["preimage_hash"], - ) + self.assertEqual(hexlify(zip243.get_prevouts_hash()), v["prevouts_hash"]) + self.assertEqual(hexlify(zip243.get_sequence_hash()), v["sequence_hash"]) + self.assertEqual(hexlify(zip243.get_outputs_hash()), v["outputs_hash"]) + self.assertEqual(hexlify(zip243.hash143_preimage_hash(txi, unhexlify(i["pubkeyhash"]))), v["preimage_hash"]) if __name__ == "__main__":