1
0
mirror of https://github.com/trezor/trezor-firmware.git synced 2024-11-17 21:22:10 +00:00

core/bitcoin: Clarify hash_type vs. sighash_type terminology.

This commit is contained in:
Andrew Kozlik 2020-06-26 09:37:30 +02:00 committed by Andrew Kozlik
parent d1e043f417
commit 5378e12ba2
4 changed files with 31 additions and 24 deletions

View File

@ -137,10 +137,10 @@ def bip143_derive_script_code(txi: TxInputType, pubkeyhash: bytes) -> bytearray:
def input_script_p2pkh_or_p2sh(
pubkey: bytes, signature: bytes, sighash: int
pubkey: bytes, signature: bytes, hash_type: int
) -> bytearray:
w = empty_bytearray(5 + len(signature) + 1 + 5 + len(pubkey))
append_signature(w, signature, sighash)
append_signature(w, signature, hash_type)
append_pubkey(w, pubkey)
return w
@ -264,10 +264,10 @@ def input_script_p2wsh_in_p2sh(script_hash: bytes) -> bytearray:
# ===
def witness_p2wpkh(signature: bytes, pubkey: bytes, sighash: int) -> bytearray:
def witness_p2wpkh(signature: bytes, pubkey: bytes, hash_type: int) -> bytearray:
w = empty_bytearray(1 + 5 + len(signature) + 1 + 5 + len(pubkey))
write_bitcoin_varint(w, 0x02) # num of segwit items, in P2WPKH it's always 2
write_signature_prefixed(w, signature, sighash)
write_signature_prefixed(w, signature, hash_type)
write_bytes_prefixed(w, pubkey)
return w
@ -297,7 +297,7 @@ def witness_p2wsh(
multisig: MultisigRedeemScriptType,
signature: bytes,
signature_index: int,
sighash: int,
hash_type: int,
) -> bytearray:
# get other signatures, stretch with None to the number of the pubkeys
signatures = multisig.signatures + [None] * (
@ -321,7 +321,7 @@ def witness_p2wsh(
# length of the result
total_length = 1 + 1 # number of items, OP_FALSE
for s in signatures:
total_length += 1 + len(s) + 1 # length, signature, sighash
total_length += 1 + len(s) + 1 # length, signature, hash_type
total_length += 1 + redeem_script_length # length, script
w = empty_bytearray(total_length)
@ -333,7 +333,7 @@ def witness_p2wsh(
write_bitcoin_varint(w, 0)
for s in signatures:
write_signature_prefixed(w, s, sighash) # size of the witness included
write_signature_prefixed(w, s, hash_type) # size of the witness included
# redeem script
write_bitcoin_varint(w, redeem_script_length)
@ -379,7 +379,7 @@ def input_script_multisig(
multisig: MultisigRedeemScriptType,
signature: bytes,
signature_index: int,
sighash: int,
hash_type: int,
coin: CoinInfo,
) -> bytearray:
signatures = multisig.signatures # other signatures
@ -396,7 +396,7 @@ def input_script_multisig(
if utils.BITCOIN_ONLY or not coin.decred:
total_length += 1 # OP_FALSE
for s in signatures:
total_length += 1 + len(s) + 1 # length, signature, sighash
total_length += 1 + len(s) + 1 # length, signature, hash_type
total_length += 1 + redeem_script_length # length, script
w = empty_bytearray(total_length)
@ -409,7 +409,7 @@ def input_script_multisig(
for s in signatures:
if len(s):
append_signature(w, s, sighash)
append_signature(w, s, hash_type)
# redeem script
write_op_push(w, redeem_script_length)
@ -519,16 +519,16 @@ def output_script_paytoopreturn(data: bytes) -> bytearray:
# ===
def write_signature_prefixed(w: Writer, signature: bytes, sighash: int) -> None:
def write_signature_prefixed(w: Writer, signature: bytes, hash_type: int) -> None:
write_bitcoin_varint(w, len(signature) + 1)
write_bytes_unchecked(w, signature)
w.append(sighash)
w.append(hash_type)
def append_signature(w: Writer, signature: bytes, sighash: int) -> None:
def append_signature(w: Writer, signature: bytes, hash_type: int) -> None:
write_op_push(w, len(signature) + 1)
write_bytes_unchecked(w, signature)
w.append(sighash)
w.append(hash_type)
def append_pubkey(w: Writer, pubkey: bytes) -> None:

View File

@ -250,12 +250,12 @@ class Bitcoin:
signature_index = multisig.multisig_pubkey_index(txi.multisig, public_key)
self.serialized_tx.extend(
scripts.witness_p2wsh(
txi.multisig, signature, signature_index, self.get_hash_type()
txi.multisig, signature, signature_index, self.get_hash_type(txi)
)
)
else:
self.serialized_tx.extend(
scripts.witness_p2wpkh(signature, public_key, self.get_hash_type())
scripts.witness_p2wpkh(signature, public_key, self.get_hash_type(txi))
)
async def sign_nonsegwit_input(self, i_sign: int) -> None:
@ -307,7 +307,7 @@ class Bitcoin:
self.write_tx_output(h_sign, txo, script_pubkey)
writers.write_uint32(h_sign, self.tx.lock_time)
writers.write_uint32(h_sign, self.get_hash_type())
writers.write_uint32(h_sign, self.get_sighash_type(txi_sign))
# check the control digests
if self.h_confirmed.get_digest() != h_check.get_digest():
@ -382,9 +382,16 @@ class Bitcoin:
# Tx Helpers
# ===
def get_hash_type(self) -> int:
def get_sighash_type(self, txi: TxInputType) -> int:
return _SIGHASH_ALL
def get_hash_type(self, txi: TxInputType) -> int:
""" Return the nHashType flags."""
# The nHashType is the 8 least significant bits of the sighash type.
# Some coins set the 24 most significant bits of the sighash type to
# the fork ID value.
return self.get_sighash_type(txi) & 0xFF
def write_tx_input(
self, w: writers.Writer, txi: TxInputType, script: bytes
) -> None:
@ -470,7 +477,7 @@ class Bitcoin:
txi.script_type,
txi.multisig,
self.coin,
self.get_hash_type(),
self.get_hash_type(txi),
pubkey,
signature,
)
@ -535,7 +542,7 @@ class Bitcoin:
writers.write_uint32(h_preimage, self.tx.lock_time)
# nHashType
writers.write_uint32(h_preimage, self.get_hash_type())
writers.write_uint32(h_preimage, self.get_sighash_type(txi))
return writers.get_tx_hash(h_preimage, double=self.coin.sign_hash_double)

View File

@ -46,8 +46,8 @@ class Bitcoinlike(Bitcoin):
if not self.coin.negative_fee:
super().on_negative_fee()
def get_hash_type(self) -> int:
hashtype = super().get_hash_type()
def get_sighash_type(self, txi: TxInputType) -> int:
hashtype = super().get_sighash_type(txi)
if self.coin.fork_id is not None:
hashtype |= (self.coin.fork_id << 8) | _SIGHASH_FORKID
return hashtype

View File

@ -117,7 +117,7 @@ class Overwintered(Bitcoinlike):
# 8. expiryHeight
write_uint32(h_preimage, self.tx.expiry)
# 9. nHashType
write_uint32(h_preimage, self.get_hash_type())
write_uint32(h_preimage, self.get_sighash_type(txi))
elif self.tx.version == 4:
zero_hash = b"\x00" * TX_HASH_SIZE
# 6. hashJoinSplits
@ -133,7 +133,7 @@ class Overwintered(Bitcoinlike):
# 11. valueBalance
write_uint64(h_preimage, 0)
# 12. nHashType
write_uint32(h_preimage, self.get_hash_type())
write_uint32(h_preimage, self.get_sighash_type(txi))
else:
raise wire.DataError("Unsupported version for overwintered transaction")