chore(core): In apps.bitcoin move BIP143 hashing back to a separate class.

pull/1331/head
Andrew Kozlik 4 years ago committed by Andrew Kozlik
parent 443e0c101e
commit 5fc491c597

@ -15,6 +15,7 @@ from ..common import BIP32_WALLET_DEPTH, SIGHASH_ALL, ecdsa_sign
from ..ownership import verify_nonownership
from ..verification import SignatureVerifier
from . import approvers, helpers, progress
from .hash143 import Hash143
from .matchcheck import MultisigFingerprintChecker, WalletPathChecker
if False:
@ -114,19 +115,22 @@ class Bitcoin:
self.h_inputs = None # type: Optional[bytes]
# BIP-0143 transaction hashing
self.init_hash143()
self.hash143 = self.create_hash143()
progress.init(self.tx.inputs_count, self.tx.outputs_count)
def create_hash_writer(self) -> HashWriter:
return HashWriter(sha256())
def create_hash143(self) -> Hash143:
return Hash143()
async def step1_process_inputs(self) -> None:
for i in range(self.tx.inputs_count):
# STAGE_REQUEST_1_INPUT in legacy
txi = await helpers.request_tx_input(self.tx_req, i, self.coin)
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)
writers.write_tx_input_check(self.h_approved, txi)
if input_is_segwit(txi):
@ -229,7 +233,7 @@ class Bitcoin:
await self.approver.add_external_output(txo, script_pubkey)
self.write_tx_output(self.h_approved, txo, script_pubkey)
self.hash143_add_output(txo, script_pubkey)
self.hash143.add_output(txo, script_pubkey)
async def get_tx_digest(
self,
@ -240,7 +244,14 @@ class Bitcoin:
script_pubkey: bytes,
) -> bytes:
if txi.witness:
return self.hash143_preimage_hash(txi, public_keys, threshold)
return self.hash143.preimage_hash(
txi,
public_keys,
threshold,
self.tx,
self.coin,
self.get_sighash_type(txi),
)
else:
digest, _, _ = await self.get_legacy_tx_digest(i, script_pubkey)
return digest
@ -304,7 +315,9 @@ class Bitcoin:
else:
public_keys = [public_key]
threshold = 1
hash143_hash = self.hash143_preimage_hash(txi, public_keys, threshold)
hash143_hash = self.hash143.preimage_hash(
txi, public_keys, threshold, self.tx, self.coin, self.get_sighash_type(txi)
)
signature = ecdsa_sign(node, hash143_hash)
@ -478,16 +491,16 @@ class Bitcoin:
# the fork ID value.
return self.get_sighash_type(txi) & 0xFF
@staticmethod
def write_tx_input(
self,
w: writers.Writer,
txi: Union[TxInput, PrevInput],
script: bytes,
) -> None:
writers.write_tx_input(w, txi, script)
@staticmethod
def write_tx_output(
self,
w: writers.Writer,
txo: Union[TxOutput, PrevOutput],
script_pubkey: bytes,
@ -574,74 +587,6 @@ class Bitcoin:
signature,
)
# BIP-0143
# ===
def init_hash143(self) -> None:
self.h_prevouts = HashWriter(sha256())
self.h_sequence = HashWriter(sha256())
self.h_outputs = HashWriter(sha256())
def hash143_add_input(self, txi: TxInput) -> 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: TxOutput, script_pubkey: bytes) -> None:
writers.write_tx_output(self.h_outputs, txo, script_pubkey)
def hash143_preimage_hash(
self, txi: TxInput, public_keys: List[bytes], threshold: int
) -> bytes:
h_preimage = HashWriter(sha256())
# nVersion
writers.write_uint32(h_preimage, self.tx.version)
# hashPrevouts
prevouts_hash = writers.get_tx_hash(
self.h_prevouts, double=self.coin.sign_hash_double
)
writers.write_bytes_fixed(h_preimage, prevouts_hash, writers.TX_HASH_SIZE)
# hashSequence
sequence_hash = writers.get_tx_hash(
self.h_sequence, double=self.coin.sign_hash_double
)
writers.write_bytes_fixed(h_preimage, 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, public_keys, threshold, self.coin
)
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
outputs_hash = writers.get_tx_hash(
self.h_outputs, double=self.coin.sign_hash_double
)
writers.write_bytes_fixed(h_preimage, outputs_hash, writers.TX_HASH_SIZE)
# nLockTime
writers.write_uint32(h_preimage, self.tx.lock_time)
# nHashType
writers.write_uint32(h_preimage, self.get_sighash_type(txi))
return writers.get_tx_hash(h_preimage, double=self.coin.sign_hash_double)
def input_is_segwit(txi: TxInput) -> bool:
return txi.script_type in common.SEGWIT_INPUT_SCRIPT_TYPES or (

@ -49,7 +49,14 @@ class Bitcoinlike(Bitcoin):
script_pubkey: bytes,
) -> bytes:
if self.coin.force_bip143:
return self.hash143_preimage_hash(txi, public_keys, threshold)
return self.hash143.preimage_hash(
txi,
public_keys,
threshold,
self.tx,
self.coin,
self.get_sighash_type(txi),
)
else:
return await super().get_tx_digest(
i, txi, public_keys, threshold, script_pubkey

@ -12,6 +12,7 @@ from .. import multisig, scripts, writers
from ..common import ecdsa_hash_pubkey, ecdsa_sign
from . import approvers, helpers, progress
from .bitcoin import Bitcoin
from .hash143 import Hash143
DECRED_SERIALIZE_FULL = const(0 << 16)
DECRED_SERIALIZE_NO_WITNESS = const(1 << 16)
@ -33,6 +34,17 @@ if False:
from apps.common.keychain import Keychain
class DecredHash(Hash143):
def __init__(self, h_prefix: HashWriter) -> None:
self.h_prefix = h_prefix
def add_input(self, txi: TxInput) -> None:
Decred.write_tx_input(self.h_prefix, txi, bytes())
def add_output(self, txo: TxOutput, script_pubkey: bytes) -> None:
Decred.write_tx_output(self.h_prefix, txo, script_pubkey)
class Decred(Bitcoin):
def __init__(
self,
@ -42,21 +54,22 @@ class Decred(Bitcoin):
approver: approvers.Approver,
) -> None:
ensure(coin.decred)
self.h_prefix = HashWriter(blake256())
writers.write_uint32(self.h_prefix, tx.version | DECRED_SERIALIZE_NO_WITNESS)
write_bitcoin_varint(self.h_prefix, tx.inputs_count)
super().__init__(tx, keychain, coin, approver)
self.write_tx_header(self.serialized_tx, self.tx, witness_marker=True)
write_bitcoin_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
)
write_bitcoin_varint(self.h_prefix, self.tx.inputs_count)
def create_hash_writer(self) -> HashWriter:
return HashWriter(blake256())
def create_hash143(self) -> Hash143:
return DecredHash(self.h_prefix)
async def step2_approve_outputs(self) -> None:
write_bitcoin_varint(self.serialized_tx, self.tx.outputs_count)
write_bitcoin_varint(self.h_prefix, self.tx.outputs_count)
@ -148,14 +161,8 @@ class Decred(Bitcoin):
if txo_bin.decred_script_version != 0:
raise wire.ProcessError("Cannot use utxo that has script_version != 0")
def hash143_add_input(self, txi: TxInput) -> None:
self.write_tx_input(self.h_prefix, txi, bytes())
def hash143_add_output(self, txo: TxOutput, script_pubkey: bytes) -> None:
self.write_tx_output(self.h_prefix, txo, script_pubkey)
@staticmethod
def write_tx_input(
self,
w: writers.Writer,
txi: Union[TxInput, PrevInput],
script: bytes,
@ -165,8 +172,8 @@ class Decred(Bitcoin):
writers.write_uint8(w, txi.decred_tree or 0)
writers.write_uint32(w, txi.sequence)
@staticmethod
def write_tx_output(
self,
w: writers.Writer,
txo: Union[TxOutput, PrevOutput],
script_pubkey: bytes,

@ -0,0 +1,85 @@
from trezor.crypto.hashlib import sha256
from trezor.messages.PrevTx import PrevTx
from trezor.messages.SignTx import SignTx
from trezor.messages.TxInput import TxInput
from trezor.messages.TxOutput import TxOutput
from trezor.utils import HashWriter
from apps.common import coininfo
from .. import scripts, writers
if False:
from typing import List, Union
# BIP-0143 hash
class Hash143:
def __init__(self) -> None:
self.h_prevouts = HashWriter(sha256())
self.h_sequence = HashWriter(sha256())
self.h_outputs = HashWriter(sha256())
def add_input(self, txi: TxInput) -> 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 add_output(self, txo: TxOutput, script_pubkey: bytes) -> None:
writers.write_tx_output(self.h_outputs, txo, script_pubkey)
def preimage_hash(
self,
txi: TxInput,
public_keys: List[bytes],
threshold: int,
tx: Union[SignTx, PrevTx],
coin: coininfo.CoinInfo,
sighash_type: int,
) -> bytes:
h_preimage = HashWriter(sha256())
# nVersion
writers.write_uint32(h_preimage, tx.version)
# hashPrevouts
prevouts_hash = writers.get_tx_hash(
self.h_prevouts, double=coin.sign_hash_double
)
writers.write_bytes_fixed(h_preimage, prevouts_hash, writers.TX_HASH_SIZE)
# hashSequence
sequence_hash = writers.get_tx_hash(
self.h_sequence, double=coin.sign_hash_double
)
writers.write_bytes_fixed(h_preimage, 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, public_keys, threshold, coin
)
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
outputs_hash = writers.get_tx_hash(self.h_outputs, double=coin.sign_hash_double)
writers.write_bytes_fixed(h_preimage, outputs_hash, writers.TX_HASH_SIZE)
# nLockTime
writers.write_uint32(h_preimage, tx.lock_time)
# nHashType
writers.write_uint32(h_preimage, sighash_type)
return writers.get_tx_hash(h_preimage, double=coin.sign_hash_double)

@ -26,14 +26,80 @@ from ..writers import (
)
from . import approvers, helpers
from .bitcoinlike import Bitcoinlike
from .hash143 import Hash143
if False:
from apps.common import coininfo
from typing import List, Union
from ..writers import Writer
OVERWINTERED = const(0x80000000)
class Zip243Hash(Hash143):
def __init__(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"))
def preimage_hash(
self,
txi: TxInput,
public_keys: List[bytes],
threshold: int,
tx: Union[SignTx, PrevTx],
coin: coininfo.CoinInfo,
sighash_type: int,
) -> bytes:
h_preimage = HashWriter(
blake2b(
outlen=32,
personal=b"ZcashSigHash" + struct.pack("<I", tx.branch_id),
)
)
assert tx.version_group_id is not None
assert tx.expiry is not None
zero_hash = b"\x00" * TX_HASH_SIZE
# 1. nVersion | fOverwintered
write_uint32(h_preimage, tx.version | OVERWINTERED)
# 2. nVersionGroupId
write_uint32(h_preimage, tx.version_group_id)
# 3. hashPrevouts
write_bytes_fixed(h_preimage, get_tx_hash(self.h_prevouts), TX_HASH_SIZE)
# 4. hashSequence
write_bytes_fixed(h_preimage, get_tx_hash(self.h_sequence), TX_HASH_SIZE)
# 5. hashOutputs
write_bytes_fixed(h_preimage, get_tx_hash(self.h_outputs), TX_HASH_SIZE)
# 6. hashJoinSplits
write_bytes_fixed(h_preimage, zero_hash, TX_HASH_SIZE)
# 7. hashShieldedSpends
write_bytes_fixed(h_preimage, zero_hash, TX_HASH_SIZE)
# 8. hashShieldedOutputs
write_bytes_fixed(h_preimage, zero_hash, TX_HASH_SIZE)
# 9. nLockTime
write_uint32(h_preimage, tx.lock_time)
# 10. expiryHeight
write_uint32(h_preimage, tx.expiry)
# 11. valueBalance
write_uint64(h_preimage, 0)
# 12. nHashType
write_uint32(h_preimage, sighash_type)
# 13a. outpoint
write_bytes_reversed(h_preimage, txi.prev_hash, TX_HASH_SIZE)
write_uint32(h_preimage, txi.prev_index)
# 13b. scriptCode
script_code = derive_script_code(txi, public_keys, threshold, coin)
write_bytes_prefixed(h_preimage, script_code)
# 13c. value
write_uint64(h_preimage, txi.amount)
# 13d. nSequence
write_uint32(h_preimage, txi.sequence)
return get_tx_hash(h_preimage)
class Zcashlike(Bitcoinlike):
def __init__(
self,
@ -48,6 +114,9 @@ class Zcashlike(Bitcoinlike):
if self.tx.version != 4:
raise wire.DataError("Unsupported transaction version.")
def create_hash143(self) -> Hash143:
return Zip243Hash()
async def step7_finish(self) -> None:
self.write_tx_footer(self.serialized_tx, self.tx)
@ -69,7 +138,9 @@ class Zcashlike(Bitcoinlike):
threshold: int,
script_pubkey: bytes,
) -> bytes:
return self.hash143_preimage_hash(txi, public_keys, threshold)
return self.hash143.preimage_hash(
txi, public_keys, threshold, self.tx, self.coin, self.get_sighash_type(txi)
)
def write_tx_header(
self, w: Writer, tx: Union[SignTx, PrevTx], witness_marker: bool
@ -90,70 +161,9 @@ class Zcashlike(Bitcoinlike):
if tx.version >= 3:
write_uint32(w, tx.expiry) # expiryHeight
# ZIP-0143 / ZIP-0243
# ===
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"))
def hash143_preimage_hash(
self, txi: TxInput, public_keys: List[bytes], threshold: int
) -> bytes:
h_preimage = HashWriter(
blake2b(
outlen=32,
personal=b"ZcashSigHash" + struct.pack("<I", self.tx.branch_id),
)
)
assert self.tx.version_group_id is not None
assert self.tx.expiry is not None
# 1. nVersion | fOverwintered
write_uint32(h_preimage, self.tx.version | OVERWINTERED)
# 2. nVersionGroupId
write_uint32(h_preimage, self.tx.version_group_id)
# 3. hashPrevouts
write_bytes_fixed(h_preimage, get_tx_hash(self.h_prevouts), TX_HASH_SIZE)
# 4. hashSequence
write_bytes_fixed(h_preimage, get_tx_hash(self.h_sequence), TX_HASH_SIZE)
# 5. hashOutputs
write_bytes_fixed(h_preimage, get_tx_hash(self.h_outputs), TX_HASH_SIZE)
zero_hash = b"\x00" * TX_HASH_SIZE
# 6. hashJoinSplits
write_bytes_fixed(h_preimage, zero_hash, TX_HASH_SIZE)
# 7. hashShieldedSpends
write_bytes_fixed(h_preimage, zero_hash, TX_HASH_SIZE)
# 8. hashShieldedOutputs
write_bytes_fixed(h_preimage, zero_hash, TX_HASH_SIZE)
# 9. nLockTime
write_uint32(h_preimage, self.tx.lock_time)
# 10. expiryHeight
write_uint32(h_preimage, self.tx.expiry)
# 11. valueBalance
write_uint64(h_preimage, 0)
# 12. nHashType
write_uint32(h_preimage, self.get_sighash_type(txi))
# 10a /13a. outpoint
write_bytes_reversed(h_preimage, txi.prev_hash, TX_HASH_SIZE)
write_uint32(h_preimage, txi.prev_index)
# 10b / 13b. scriptCode
script_code = derive_script_code(txi, public_keys, threshold, self.coin)
write_bytes_prefixed(h_preimage, script_code)
# 10c / 13c. value
write_uint64(h_preimage, txi.amount)
# 10d / 13d. nSequence
write_uint32(h_preimage, txi.sequence)
return get_tx_hash(h_preimage)
def derive_script_code(
txi: TxInput, public_keys: List[bytes], threshold: int, coin: CoinInfo

@ -1,8 +1,8 @@
from common import *
from apps.bitcoin.common import SIGHASH_ALL
from apps.bitcoin.scripts import output_derive_script
from apps.bitcoin.sign_tx.approvers import BasicApprover
from apps.bitcoin.sign_tx.bitcoin import Bitcoin
from apps.bitcoin.sign_tx.bitcoin import Hash143
from apps.bitcoin.writers import get_tx_hash
from apps.common import coins
from apps.common.keychain import Keychain
@ -48,17 +48,17 @@ class TestSegwitBip143NativeP2WPKH(unittest.TestCase):
def test_prevouts(self):
coin = coins.by_name(self.tx.coin_name)
bip143 = Bitcoin(self.tx, None, coin, BasicApprover(self.tx, coin))
bip143.hash143_add_input(self.inp1)
bip143.hash143_add_input(self.inp2)
bip143 = Hash143()
bip143.add_input(self.inp1)
bip143.add_input(self.inp2)
prevouts_hash = get_tx_hash(bip143.h_prevouts, double=coin.sign_hash_double)
self.assertEqual(hexlify(prevouts_hash), b'96b827c8483d4e9b96712b6713a7b68d6e8003a781feba36c31143470b4efd37')
def test_sequence(self):
coin = coins.by_name(self.tx.coin_name)
bip143 = Bitcoin(self.tx, None, coin, BasicApprover(self.tx, coin))
bip143.hash143_add_input(self.inp1)
bip143.hash143_add_input(self.inp2)
bip143 = Hash143()
bip143.add_input(self.inp1)
bip143.add_input(self.inp2)
sequence_hash = get_tx_hash(bip143.h_sequence, double=coin.sign_hash_double)
self.assertEqual(hexlify(sequence_hash), b'52b0a642eea2fb7ae638c36f6252b6750293dbe574a806984b8e4d8548339a3b')
@ -66,12 +66,12 @@ class TestSegwitBip143NativeP2WPKH(unittest.TestCase):
seed = bip39.seed('alcohol woman abuse must during monitor noble actual mixed trade anger aisle', '')
coin = coins.by_name(self.tx.coin_name)
bip143 = Bitcoin(self.tx, None, coin, BasicApprover(self.tx, coin))
bip143 = Hash143()
for txo in [self.out1, self.out2]:
script_pubkey = output_derive_script(txo.address, coin)
txo_bin = PrevOutput(amount=txo.amount, script_pubkey=script_pubkey)
bip143.hash143_add_output(txo_bin, script_pubkey)
bip143.add_output(txo_bin, script_pubkey)
outputs_hash = get_tx_hash(bip143.h_outputs, double=coin.sign_hash_double)
self.assertEqual(hexlify(outputs_hash), b'863ef3e1a92afbfdb97f31ad0fc7683ee943e9abcf2501590ff8f6551f47e5e5')
@ -80,21 +80,21 @@ class TestSegwitBip143NativeP2WPKH(unittest.TestCase):
seed = bip39.seed('alcohol woman abuse must during monitor noble actual mixed trade anger aisle', '')
coin = coins.by_name(self.tx.coin_name)
bip143 = Bitcoin(self.tx, None, coin, BasicApprover(self.tx, coin))
bip143.hash143_add_input(self.inp1)
bip143.hash143_add_input(self.inp2)
bip143 = Hash143()
bip143.add_input(self.inp1)
bip143.add_input(self.inp2)
for txo in [self.out1, self.out2]:
script_pubkey = output_derive_script(txo.address, coin)
txo_bin = PrevOutput(amount=txo.amount, script_pubkey=script_pubkey)
bip143.hash143_add_output(txo_bin, script_pubkey)
bip143.add_output(txo_bin, script_pubkey)
keychain = Keychain(seed, coin.curve_name, [[]])
node = keychain.derive(self.inp2.address_n)
# test data public key hash
# only for input 2 - input 1 is not segwit
result = bip143.hash143_preimage_hash(self.inp2, [node.public_key()], 1)
result = bip143.preimage_hash(self.inp2, [node.public_key()], 1, self.tx, coin, SIGHASH_ALL)
self.assertEqual(hexlify(result), b'2fa3f1351618b2532228d7182d3221d95c21fd3d496e7e22e9ded873cf022a8b')

@ -1,8 +1,8 @@
from common import *
from apps.bitcoin.common import SIGHASH_ALL
from apps.bitcoin.scripts import output_derive_script
from apps.bitcoin.sign_tx.approvers import BasicApprover
from apps.bitcoin.sign_tx.bitcoin import Bitcoin
from apps.bitcoin.sign_tx.bitcoin import Hash143
from apps.bitcoin.writers import get_tx_hash
from apps.common import coins
from apps.common.keychain import Keychain
@ -40,27 +40,27 @@ class TestSegwitBip143(unittest.TestCase):
def test_bip143_prevouts(self):
coin = coins.by_name(self.tx.coin_name)
bip143 = Bitcoin(self.tx, None, coin, BasicApprover(self.tx, coin))
bip143.hash143_add_input(self.inp1)
bip143 = Hash143()
bip143.add_input(self.inp1)
prevouts_hash = get_tx_hash(bip143.h_prevouts, double=coin.sign_hash_double)
self.assertEqual(hexlify(prevouts_hash), b'b0287b4a252ac05af83d2dcef00ba313af78a3e9c329afa216eb3aa2a7b4613a')
def test_bip143_sequence(self):
coin = coins.by_name(self.tx.coin_name)
bip143 = Bitcoin(self.tx, None, coin, BasicApprover(self.tx, coin))
bip143.hash143_add_input(self.inp1)
bip143 = Hash143()
bip143.add_input(self.inp1)
sequence_hash = get_tx_hash(bip143.h_sequence, double=coin.sign_hash_double)
self.assertEqual(hexlify(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 = Bitcoin(self.tx, None, coin, BasicApprover(self.tx, coin))
bip143 = Hash143()
for txo in [self.out1, self.out2]:
script_pubkey = output_derive_script(txo.address, coin)
txo_bin = PrevOutput(amount=txo.amount, script_pubkey=script_pubkey)
bip143.hash143_add_output(txo_bin, script_pubkey)
bip143.add_output(txo_bin, script_pubkey)
outputs_hash = get_tx_hash(bip143.h_outputs, double=coin.sign_hash_double)
self.assertEqual(hexlify(outputs_hash), b'de984f44532e2173ca0d64314fcefe6d30da6f8cf27bafa706da61df8a226c83')
@ -68,18 +68,18 @@ class TestSegwitBip143(unittest.TestCase):
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 = Bitcoin(self.tx, None, coin, BasicApprover(self.tx, coin))
bip143.hash143_add_input(self.inp1)
bip143 = Hash143()
bip143.add_input(self.inp1)
for txo in [self.out1, self.out2]:
script_pubkey = output_derive_script(txo.address, coin)
txo_bin = PrevOutput(amount=txo.amount, script_pubkey=script_pubkey)
bip143.hash143_add_output(txo_bin, script_pubkey)
bip143.add_output(txo_bin, script_pubkey)
keychain = Keychain(seed, coin.curve_name, [[]])
node = keychain.derive(self.inp1.address_n)
# test data public key hash
result = bip143.hash143_preimage_hash(self.inp1, [node.public_key()], 1)
result = bip143.preimage_hash(self.inp1, [node.public_key()], 1, self.tx, coin, SIGHASH_ALL)
self.assertEqual(hexlify(result), b'6e28aca7041720995d4acf59bbda64eef5d6f23723d23f2e994757546674bbd9')

@ -5,11 +5,11 @@ from trezor.messages.TxInput import TxInput
from trezor.messages.PrevOutput import PrevOutput
from apps.common import coins
from apps.bitcoin.common import SIGHASH_ALL
from apps.bitcoin.writers import get_tx_hash
from apps.bitcoin.sign_tx.approvers import BasicApprover
if not utils.BITCOIN_ONLY:
from apps.bitcoin.sign_tx.zcash import Zcashlike
from apps.bitcoin.sign_tx.zcash import Zip243Hash
# test vectors inspired from https://github.com/zcash-hackworks/zcash-test-vectors/blob/master/zip_0243.py
@ -191,7 +191,7 @@ class TestZcashZip243(unittest.TestCase):
branch_id=v["branch_id"],
)
zip243 = Zcashlike(tx, None, coin, BasicApprover(tx, coin))
zip243 = Zip243Hash()
for i in v["inputs"]:
txi = TxInput(
@ -201,18 +201,19 @@ class TestZcashZip243(unittest.TestCase):
script_type = i["script_type"],
sequence = i["sequence"],
)
zip243.hash143_add_input(txi)
zip243.add_input(txi)
for o in v["outputs"]:
txo = PrevOutput(
amount = o["amount"],
script_pubkey = unhexlify(o["script_pubkey"]),
)
zip243.hash143_add_output(txo, txo.script_pubkey)
zip243.add_output(txo, txo.script_pubkey)
self.assertEqual(hexlify(get_tx_hash(zip243.h_prevouts)), v["prevouts_hash"])
self.assertEqual(hexlify(get_tx_hash(zip243.h_sequence)), v["sequence_hash"])
self.assertEqual(hexlify(get_tx_hash(zip243.h_outputs)), v["outputs_hash"])
self.assertEqual(hexlify(zip243.hash143_preimage_hash(txi, [unhexlify(i["pubkey"])], 1)), v["preimage_hash"])
self.assertEqual(hexlify(zip243.preimage_hash(txi, [unhexlify(i["pubkey"])], 1, tx, coin, SIGHASH_ALL)), v["preimage_hash"])
if __name__ == "__main__":

Loading…
Cancel
Save