1
0
mirror of https://github.com/trezor/trezor-firmware.git synced 2025-07-19 04:58:11 +00:00

core/sign_tx: Derive Zip143 and DecredPrefixHasher from Bip143.

This commit is contained in:
Andrew Kozlik 2020-04-08 21:59:18 +02:00 committed by Andrew Kozlik
parent e9900df18d
commit 95fad83024
3 changed files with 57 additions and 46 deletions

View File

@ -13,6 +13,7 @@ from trezor.utils import HashWriter, ensure
from apps.common import coininfo, seed from apps.common import coininfo, seed
from apps.wallet.sign_tx import addresses, helpers, multisig, progress, scripts, writers from apps.wallet.sign_tx import addresses, helpers, multisig, progress, scripts, writers
from apps.wallet.sign_tx.segwit_bip143 import Bip143
from apps.wallet.sign_tx.signing import Bitcoin, SigningError, ecdsa_sign from apps.wallet.sign_tx.signing import Bitcoin, SigningError, ecdsa_sign
DECRED_SERIALIZE_FULL = const(0 << 16) DECRED_SERIALIZE_FULL = const(0 << 16)
@ -25,7 +26,7 @@ if False:
from typing import Union from typing import Union
class DecredPrefixHasher: class DecredPrefixHasher(Bip143):
""" """
While Decred does not have the exact same implementation as bip143/zip143, While Decred does not have the exact same implementation as bip143/zip143,
the semantics for using the prefix hash of transactions are close enough the semantics for using the prefix hash of transactions are close enough
@ -53,7 +54,7 @@ class DecredPrefixHasher:
writers.write_uint32(self.h_prefix, tx.lock_time) writers.write_uint32(self.h_prefix, tx.lock_time)
writers.write_uint32(self.h_prefix, tx.expiry) writers.write_uint32(self.h_prefix, tx.expiry)
def prefix_hash(self) -> bytes: def get_prefix_hash(self) -> bytes:
return self.h_prefix.get_digest() return self.h_prefix.get_digest()
@ -110,7 +111,7 @@ class Decred(Bitcoin):
async def phase2(self) -> None: async def phase2(self) -> None:
self.tx_req.serialized = None self.tx_req.serialized = None
prefix_hash = self.hash143.prefix_hash() prefix_hash = self.hash143.get_prefix_hash()
for i_sign in range(self.tx.inputs_count): for i_sign in range(self.tx.inputs_count):
progress.advance() progress.advance()

View File

@ -37,9 +37,15 @@ class Bip143:
def add_sequence(self, txi: TxInputType) -> None: def add_sequence(self, txi: TxInputType) -> None:
write_uint32(self.h_sequence, txi.sequence) write_uint32(self.h_sequence, txi.sequence)
def add_output_count(self, tx: SignTx) -> None:
pass
def add_output(self, txo_bin: TxOutputBinType) -> None: def add_output(self, txo_bin: TxOutputBinType) -> None:
write_tx_output(self.h_outputs, txo_bin) 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: def get_prevouts_hash(self, coin: CoinInfo) -> bytes:
return get_tx_hash(self.h_prevouts, double=coin.sign_hash_double) return get_tx_hash(self.h_prevouts, double=coin.sign_hash_double)
@ -49,6 +55,9 @@ class Bip143:
def get_outputs_hash(self, coin: CoinInfo) -> bytes: def get_outputs_hash(self, coin: CoinInfo) -> bytes:
return get_tx_hash(self.h_outputs, double=coin.sign_hash_double) return get_tx_hash(self.h_outputs, double=coin.sign_hash_double)
def get_prefix_hash(self) -> bytes:
pass
def preimage_hash( def preimage_hash(
self, self,
coin: CoinInfo, coin: CoinInfo,
@ -70,7 +79,7 @@ class Bip143:
write_bytes_reversed(h_preimage, txi.prev_hash, TX_HASH_SIZE) # outpoint write_bytes_reversed(h_preimage, txi.prev_hash, TX_HASH_SIZE) # outpoint
write_uint32(h_preimage, txi.prev_index) # outpoint write_uint32(h_preimage, txi.prev_index) # outpoint
script_code = self.derive_script_code(txi, pubkeyhash) # scriptCode script_code = derive_script_code(txi, pubkeyhash) # scriptCode
write_bytes_prefixed(h_preimage, script_code) write_bytes_prefixed(h_preimage, script_code)
write_uint64(h_preimage, txi.amount) # amount write_uint64(h_preimage, txi.amount) # amount
@ -82,9 +91,10 @@ class Bip143:
return get_tx_hash(h_preimage, double=coin.sign_hash_double) 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 # see https://github.com/bitcoin/bips/blob/master/bip-0143.mediawiki#specification
def derive_script_code(self, txi: TxInputType, pubkeyhash: bytes) -> bytearray: # item 5 for details
def derive_script_code(txi: TxInputType, pubkeyhash: bytes) -> bytearray:
if txi.multisig: if txi.multisig:
return output_script_multisig( return output_script_multisig(
@ -103,6 +113,5 @@ class Bip143:
else: else:
raise Bip143Error( raise Bip143Error(
FailureType.DataError, FailureType.DataError, "Unknown input script type for bip143 script code",
"Unknown input script type for bip143 script code",
) )

View File

@ -6,7 +6,6 @@ from trezor.messages import FailureType, InputScriptType
from trezor.messages.SignTx import SignTx from trezor.messages.SignTx import SignTx
from trezor.messages.TransactionType import TransactionType from trezor.messages.TransactionType import TransactionType
from trezor.messages.TxInputType import TxInputType from trezor.messages.TxInputType import TxInputType
from trezor.messages.TxOutputBinType import TxOutputBinType
from trezor.utils import HashWriter, ensure from trezor.utils import HashWriter, ensure
from apps.common.coininfo import CoinInfo from apps.common.coininfo import CoinInfo
@ -14,6 +13,7 @@ from apps.common.seed import Keychain
from apps.wallet.sign_tx.bitcoinlike import Bitcoinlike from apps.wallet.sign_tx.bitcoinlike import Bitcoinlike
from apps.wallet.sign_tx.multisig import multisig_get_pubkeys 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.scripts import output_script_multisig, output_script_p2pkh
from apps.wallet.sign_tx.segwit_bip143 import Bip143
from apps.wallet.sign_tx.signing import SigningError from apps.wallet.sign_tx.signing import SigningError
from apps.wallet.sign_tx.writers import ( from apps.wallet.sign_tx.writers import (
TX_HASH_SIZE, TX_HASH_SIZE,
@ -21,7 +21,6 @@ from apps.wallet.sign_tx.writers import (
write_bytes_fixed, write_bytes_fixed,
write_bytes_prefixed, write_bytes_prefixed,
write_bytes_reversed, write_bytes_reversed,
write_tx_output,
write_uint32, write_uint32,
write_uint64, write_uint64,
write_varint, write_varint,
@ -55,30 +54,20 @@ def derive_script_code(txi: TxInputType, pubkeyhash: bytes) -> bytearray:
) )
class Zip143: class Zip143(Bip143):
def __init__(self, branch_id: int) -> None: def __init__(self, branch_id: int) -> None:
self.branch_id = branch_id self.branch_id = branch_id
self.h_prevouts = HashWriter(blake2b(outlen=32, personal=b"ZcashPrevoutHash")) self.h_prevouts = HashWriter(blake2b(outlen=32, personal=b"ZcashPrevoutHash"))
self.h_sequence = HashWriter(blake2b(outlen=32, personal=b"ZcashSequencHash")) self.h_sequence = HashWriter(blake2b(outlen=32, personal=b"ZcashSequencHash"))
self.h_outputs = HashWriter(blake2b(outlen=32, personal=b"ZcashOutputsHash")) self.h_outputs = HashWriter(blake2b(outlen=32, personal=b"ZcashOutputsHash"))
def add_prevouts(self, txi: TxInputType) -> None: def get_prevouts_hash(self, coin: CoinInfo) -> bytes:
write_bytes_reversed(self.h_prevouts, txi.prev_hash, TX_HASH_SIZE)
write_uint32(self.h_prevouts, txi.prev_index)
def add_sequence(self, txi: TxInputType) -> None:
write_uint32(self.h_sequence, txi.sequence)
def add_output(self, txo_bin: TxOutputBinType) -> None:
write_tx_output(self.h_outputs, txo_bin)
def get_prevouts_hash(self) -> bytes:
return get_tx_hash(self.h_prevouts) return get_tx_hash(self.h_prevouts)
def get_sequence_hash(self) -> bytes: def get_sequence_hash(self, coin: CoinInfo) -> bytes:
return get_tx_hash(self.h_sequence) return get_tx_hash(self.h_sequence)
def get_outputs_hash(self) -> bytes: def get_outputs_hash(self, coin: CoinInfo) -> bytes:
return get_tx_hash(self.h_outputs) return get_tx_hash(self.h_outputs)
def preimage_hash( def preimage_hash(
@ -103,11 +92,17 @@ class Zip143:
) # 1. nVersion | fOverwintered ) # 1. nVersion | fOverwintered
write_uint32(h_preimage, tx.version_group_id) # 2. nVersionGroupId write_uint32(h_preimage, tx.version_group_id) # 2. nVersionGroupId
# 3. hashPrevouts # 3. hashPrevouts
write_bytes_fixed(h_preimage, bytearray(self.get_prevouts_hash()), TX_HASH_SIZE) write_bytes_fixed(
h_preimage, bytearray(self.get_prevouts_hash(coin)), TX_HASH_SIZE
)
# 4. hashSequence # 4. hashSequence
write_bytes_fixed(h_preimage, bytearray(self.get_sequence_hash()), TX_HASH_SIZE) write_bytes_fixed(
h_preimage, bytearray(self.get_sequence_hash(coin)), TX_HASH_SIZE
)
# 5. hashOutputs # 5. hashOutputs
write_bytes_fixed(h_preimage, bytearray(self.get_outputs_hash()), TX_HASH_SIZE) write_bytes_fixed(
h_preimage, bytearray(self.get_outputs_hash(coin)), TX_HASH_SIZE
)
# 6. hashJoinSplits # 6. hashJoinSplits
write_bytes_fixed(h_preimage, b"\x00" * TX_HASH_SIZE, TX_HASH_SIZE) write_bytes_fixed(h_preimage, b"\x00" * TX_HASH_SIZE, TX_HASH_SIZE)
write_uint32(h_preimage, tx.lock_time) # 7. nLockTime write_uint32(h_preimage, tx.lock_time) # 7. nLockTime
@ -153,11 +148,17 @@ class Zip243(Zip143):
) # 1. nVersion | fOverwintered ) # 1. nVersion | fOverwintered
write_uint32(h_preimage, tx.version_group_id) # 2. nVersionGroupId write_uint32(h_preimage, tx.version_group_id) # 2. nVersionGroupId
# 3. hashPrevouts # 3. hashPrevouts
write_bytes_fixed(h_preimage, bytearray(self.get_prevouts_hash()), TX_HASH_SIZE) write_bytes_fixed(
h_preimage, bytearray(self.get_prevouts_hash(coin)), TX_HASH_SIZE
)
# 4. hashSequence # 4. hashSequence
write_bytes_fixed(h_preimage, bytearray(self.get_sequence_hash()), TX_HASH_SIZE) write_bytes_fixed(
h_preimage, bytearray(self.get_sequence_hash(coin)), TX_HASH_SIZE
)
# 5. hashOutputs # 5. hashOutputs
write_bytes_fixed(h_preimage, bytearray(self.get_outputs_hash()), TX_HASH_SIZE) write_bytes_fixed(
h_preimage, bytearray(self.get_outputs_hash(coin)), TX_HASH_SIZE
)
zero_hash = b"\x00" * TX_HASH_SIZE zero_hash = b"\x00" * TX_HASH_SIZE
write_bytes_fixed(h_preimage, zero_hash, TX_HASH_SIZE) # 6. hashJoinSplits write_bytes_fixed(h_preimage, zero_hash, TX_HASH_SIZE) # 6. hashJoinSplits