1
0
mirror of https://github.com/trezor/trezor-firmware.git synced 2024-12-22 14:28:07 +00:00

core/bitcoin: move write_bitcoin_varint to common writers

This commit is contained in:
Tomas Susanka 2020-05-15 18:59:06 +00:00
parent 445f56d387
commit 3084ee1eed
9 changed files with 54 additions and 54 deletions

View File

@ -16,11 +16,7 @@ from .multisig import (
multisig_get_pubkeys, multisig_get_pubkeys,
multisig_pubkey_index, multisig_pubkey_index,
) )
from .writers import ( from .writers import write_bytes_fixed, write_bytes_unchecked, write_op_push
write_bytes_fixed,
write_bytes_unchecked,
write_op_push,
)
if False: if False:
from typing import List, Optional from typing import List, Optional
@ -248,7 +244,7 @@ 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, sighash: int) -> bytearray:
w = empty_bytearray(1 + 5 + len(signature) + 1 + 5 + len(pubkey)) w = empty_bytearray(1 + 5 + len(signature) + 1 + 5 + len(pubkey))
write_varint(w, 0x02) # num of segwit items, in P2WPKH it's always 2 write_bitcoin_varint(w, 0x02) # num of segwit items, in P2WPKH it's always 2
append_signature(w, signature, sighash) append_signature(w, signature, sighash)
append_pubkey(w, pubkey) append_pubkey(w, pubkey)
return w return w
@ -287,17 +283,17 @@ def witness_p2wsh(
w = empty_bytearray(total_length) w = empty_bytearray(total_length)
write_varint(w, num_of_witness_items) write_bitcoin_varint(w, num_of_witness_items)
# Starts with OP_FALSE because of an old OP_CHECKMULTISIG bug, which # Starts with OP_FALSE because of an old OP_CHECKMULTISIG bug, which
# consumes one additional item on the stack: # consumes one additional item on the stack:
# https://bitcoin.org/en/developer-guide#standard-transactions # https://bitcoin.org/en/developer-guide#standard-transactions
write_varint(w, 0) write_bitcoin_varint(w, 0)
for s in signatures: for s in signatures:
append_signature(w, s, sighash) # size of the witness included append_signature(w, s, sighash) # size of the witness included
# redeem script # redeem script
write_varint(w, redeem_script_length) write_bitcoin_varint(w, redeem_script_length)
write_output_script_multisig(w, pubkeys, multisig.m) write_output_script_multisig(w, pubkeys, multisig.m)
return w return w

View File

@ -139,7 +139,7 @@ class Bitcoin:
async def step4_serialize_inputs(self) -> None: async def step4_serialize_inputs(self) -> None:
self.write_tx_header(self.serialized_tx, self.tx, bool(self.segwit)) self.write_tx_header(self.serialized_tx, self.tx, bool(self.segwit))
writers.write_varint(self.serialized_tx, self.tx.inputs_count) write_bitcoin_varint(self.serialized_tx, self.tx.inputs_count)
for i in range(self.tx.inputs_count): for i in range(self.tx.inputs_count):
progress.advance() progress.advance()
@ -149,7 +149,7 @@ class Bitcoin:
await self.sign_nonsegwit_input(i) await self.sign_nonsegwit_input(i)
async def step5_serialize_outputs(self) -> None: async def step5_serialize_outputs(self) -> None:
writers.write_varint(self.serialized_tx, self.tx.outputs_count) write_bitcoin_varint(self.serialized_tx, self.tx.outputs_count)
for i in range(self.tx.outputs_count): for i in range(self.tx.outputs_count):
progress.advance() progress.advance()
await self.serialize_output(i) await self.serialize_output(i)
@ -275,7 +275,7 @@ class Bitcoin:
h_check = self.create_hash_writer() h_check = self.create_hash_writer()
self.write_tx_header(h_sign, self.tx, witness_marker=False) self.write_tx_header(h_sign, self.tx, witness_marker=False)
writers.write_varint(h_sign, self.tx.inputs_count) write_bitcoin_varint(h_sign, self.tx.inputs_count)
for i in range(self.tx.inputs_count): for i in range(self.tx.inputs_count):
# STAGE_REQUEST_4_INPUT in legacy # STAGE_REQUEST_4_INPUT in legacy
@ -307,7 +307,7 @@ class Bitcoin:
script_pubkey = bytes() script_pubkey = bytes()
self.write_tx_input(h_sign, txi, script_pubkey) self.write_tx_input(h_sign, txi, script_pubkey)
writers.write_varint(h_sign, self.tx.outputs_count) write_bitcoin_varint(h_sign, self.tx.outputs_count)
for i in range(self.tx.outputs_count): for i in range(self.tx.outputs_count):
# STAGE_REQUEST_4_OUTPUT in legacy # STAGE_REQUEST_4_OUTPUT in legacy
@ -353,14 +353,14 @@ class Bitcoin:
# witnesses are not included in txid hash # witnesses are not included in txid hash
self.write_tx_header(txh, tx, witness_marker=False) self.write_tx_header(txh, tx, witness_marker=False)
writers.write_varint(txh, tx.inputs_cnt) write_bitcoin_varint(txh, tx.inputs_cnt)
for i in range(tx.inputs_cnt): for i in range(tx.inputs_cnt):
# STAGE_REQUEST_2_PREV_INPUT in legacy # STAGE_REQUEST_2_PREV_INPUT in legacy
txi = await helpers.request_tx_input(self.tx_req, i, self.coin, prev_hash) txi = await helpers.request_tx_input(self.tx_req, i, self.coin, prev_hash)
self.write_tx_input(txh, txi, txi.script_sig) self.write_tx_input(txh, txi, txi.script_sig)
writers.write_varint(txh, tx.outputs_cnt) write_bitcoin_varint(txh, tx.outputs_cnt)
for i in range(tx.outputs_cnt): for i in range(tx.outputs_cnt):
# STAGE_REQUEST_2_PREV_OUTPUT in legacy # STAGE_REQUEST_2_PREV_OUTPUT in legacy
@ -413,8 +413,8 @@ class Bitcoin:
) -> None: ) -> None:
writers.write_uint32(w, tx.version) # nVersion writers.write_uint32(w, tx.version) # nVersion
if witness_marker: if witness_marker:
writers.write_varint(w, 0x00) # segwit witness marker write_bitcoin_varint(w, 0x00) # segwit witness marker
writers.write_varint(w, 0x01) # segwit witness flag write_bitcoin_varint(w, 0x01) # segwit witness flag
def write_tx_footer( def write_tx_footer(
self, w: writers.Writer, tx: Union[SignTx, TransactionType] self, w: writers.Writer, tx: Union[SignTx, TransactionType]

View File

@ -6,6 +6,8 @@ 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 apps.common.writers import write_bitcoin_varint
from .. import multisig, writers from .. import multisig, writers
from . import helpers from . import helpers
from .bitcoin import Bitcoin, input_is_nonsegwit from .bitcoin import Bitcoin, input_is_nonsegwit
@ -74,8 +76,8 @@ class Bitcoinlike(Bitcoin):
if self.coin.timestamp: if self.coin.timestamp:
writers.write_uint32(w, tx.timestamp) writers.write_uint32(w, tx.timestamp)
if witness_marker: if witness_marker:
writers.write_varint(w, 0x00) # segwit witness marker write_bitcoin_varint(w, 0x00) # segwit witness marker
writers.write_varint(w, 0x01) # segwit witness flag write_bitcoin_varint(w, 0x01) # segwit witness flag
async def write_prev_tx_footer( async def write_prev_tx_footer(
self, w: writers.Writer, tx: TransactionType, prev_hash: bytes self, w: writers.Writer, tx: TransactionType, prev_hash: bytes

View File

@ -12,6 +12,7 @@ from trezor.messages.TxOutputType import TxOutputType
from trezor.utils import HashWriter, ensure from trezor.utils import HashWriter, ensure
from apps.common import coininfo, seed from apps.common import coininfo, seed
from apps.common.writers import write_bitcoin_varint
from .. import multisig, scripts, writers from .. import multisig, scripts, writers
from ..common import ecdsa_hash_pubkey, ecdsa_sign from ..common import ecdsa_hash_pubkey, ecdsa_sign
@ -36,21 +37,21 @@ class Decred(Bitcoin):
super().__init__(tx, keychain, coin) super().__init__(tx, keychain, coin)
self.write_tx_header(self.serialized_tx, self.tx, witness_marker=True) self.write_tx_header(self.serialized_tx, self.tx, witness_marker=True)
writers.write_varint(self.serialized_tx, self.tx.inputs_count) write_bitcoin_varint(self.serialized_tx, self.tx.inputs_count)
def init_hash143(self) -> None: def init_hash143(self) -> None:
self.h_prefix = self.create_hash_writer() self.h_prefix = self.create_hash_writer()
writers.write_uint32( writers.write_uint32(
self.h_prefix, self.tx.version | DECRED_SERIALIZE_NO_WITNESS self.h_prefix, self.tx.version | DECRED_SERIALIZE_NO_WITNESS
) )
writers.write_varint(self.h_prefix, self.tx.inputs_count) write_bitcoin_varint(self.h_prefix, self.tx.inputs_count)
def create_hash_writer(self) -> HashWriter: def create_hash_writer(self) -> HashWriter:
return HashWriter(blake256()) return HashWriter(blake256())
async def step2_confirm_outputs(self) -> None: async def step2_confirm_outputs(self) -> None:
writers.write_varint(self.serialized_tx, self.tx.outputs_count) write_bitcoin_varint(self.serialized_tx, self.tx.outputs_count)
writers.write_varint(self.h_prefix, self.tx.outputs_count) write_bitcoin_varint(self.h_prefix, self.tx.outputs_count)
await super().step2_confirm_outputs() await super().step2_confirm_outputs()
self.write_tx_footer(self.serialized_tx, self.tx) self.write_tx_footer(self.serialized_tx, self.tx)
self.write_tx_footer(self.h_prefix, self.tx) self.write_tx_footer(self.h_prefix, self.tx)
@ -68,7 +69,7 @@ class Decred(Bitcoin):
self.write_tx_output(self.serialized_tx, txo, script_pubkey) self.write_tx_output(self.serialized_tx, txo, script_pubkey)
async def step4_serialize_inputs(self) -> None: async def step4_serialize_inputs(self) -> None:
writers.write_varint(self.serialized_tx, self.tx.inputs_count) write_bitcoin_varint(self.serialized_tx, self.tx.inputs_count)
prefix_hash = self.h_prefix.get_digest() prefix_hash = self.h_prefix.get_digest()
@ -99,13 +100,13 @@ class Decred(Bitcoin):
writers.write_uint32( writers.write_uint32(
h_witness, self.tx.version | DECRED_SERIALIZE_WITNESS_SIGNING h_witness, self.tx.version | DECRED_SERIALIZE_WITNESS_SIGNING
) )
writers.write_varint(h_witness, self.tx.inputs_count) write_bitcoin_varint(h_witness, self.tx.inputs_count)
for ii in range(self.tx.inputs_count): for ii in range(self.tx.inputs_count):
if ii == i_sign: if ii == i_sign:
writers.write_bytes_prefixed(h_witness, prev_pkscript) writers.write_bytes_prefixed(h_witness, prev_pkscript)
else: else:
writers.write_varint(h_witness, 0) write_bitcoin_varint(h_witness, 0)
witness_hash = writers.get_tx_hash( witness_hash = writers.get_tx_hash(
h_witness, double=self.coin.sign_hash_double, reverse=False h_witness, double=self.coin.sign_hash_double, reverse=False

View File

@ -11,6 +11,7 @@ from trezor.utils import HashWriter, ensure
from apps.common.coininfo import CoinInfo from apps.common.coininfo import CoinInfo
from apps.common.seed import Keychain from apps.common.seed import Keychain
from apps.common.writers import write_bitcoin_varint
from ..multisig import multisig_get_pubkeys from ..multisig import multisig_get_pubkeys
from ..scripts import output_script_multisig, output_script_p2pkh from ..scripts import output_script_multisig, output_script_p2pkh
@ -22,7 +23,6 @@ from ..writers import (
write_bytes_reversed, write_bytes_reversed,
write_uint32, write_uint32,
write_uint64, write_uint64,
write_varint,
) )
from . import helpers from . import helpers
from .bitcoinlike import Bitcoinlike from .bitcoinlike import Bitcoinlike
@ -53,13 +53,13 @@ class Overwintered(Bitcoinlike):
if self.tx.version == 3: if self.tx.version == 3:
write_uint32(self.serialized_tx, self.tx.expiry) # expiryHeight write_uint32(self.serialized_tx, self.tx.expiry) # expiryHeight
write_varint(self.serialized_tx, 0) # nJoinSplit write_bitcoin_varint(self.serialized_tx, 0) # nJoinSplit
elif self.tx.version == 4: elif self.tx.version == 4:
write_uint32(self.serialized_tx, self.tx.expiry) # expiryHeight write_uint32(self.serialized_tx, self.tx.expiry) # expiryHeight
write_uint64(self.serialized_tx, 0) # valueBalance write_uint64(self.serialized_tx, 0) # valueBalance
write_varint(self.serialized_tx, 0) # nShieldedSpend write_bitcoin_varint(self.serialized_tx, 0) # nShieldedSpend
write_varint(self.serialized_tx, 0) # nShieldedOutput write_bitcoin_varint(self.serialized_tx, 0) # nShieldedOutput
write_varint(self.serialized_tx, 0) # nJoinSplit write_bitcoin_varint(self.serialized_tx, 0) # nJoinSplit
else: else:
raise wire.DataError("Unsupported version for overwintered transaction") raise wire.DataError("Unsupported version for overwintered transaction")

View File

@ -8,6 +8,7 @@ from trezor.utils import ensure
from apps.common.writers import ( # noqa: F401 from apps.common.writers import ( # noqa: F401
empty_bytearray, empty_bytearray,
write_bitcoin_varint,
write_bytes_fixed, write_bytes_fixed,
write_bytes_reversed, write_bytes_reversed,
write_bytes_unchecked, write_bytes_unchecked,
@ -30,7 +31,7 @@ TX_HASH_SIZE = const(32)
def write_bytes_prefixed(w: Writer, b: bytes) -> None: def write_bytes_prefixed(w: Writer, b: bytes) -> None:
write_varint(w, len(b)) write_bitcoin_varint(w, len(b))
write_bytes_unchecked(w, b) write_bytes_unchecked(w, b)
@ -100,22 +101,6 @@ def write_op_push(w: Writer, n: int) -> None:
w.append((n >> 24) & 0xFF) w.append((n >> 24) & 0xFF)
def write_varint(w: Writer, n: int) -> None:
ensure(n >= 0 and n <= 0xFFFFFFFF)
if n < 253:
w.append(n & 0xFF)
elif n < 0x10000:
w.append(253)
w.append(n & 0xFF)
w.append((n >> 8) & 0xFF)
else:
w.append(254)
w.append(n & 0xFF)
w.append((n >> 8) & 0xFF)
w.append((n >> 16) & 0xFF)
w.append((n >> 24) & 0xFF)
def get_tx_hash(w: HashWriter, double: bool = False, reverse: bool = False) -> bytes: def get_tx_hash(w: HashWriter, double: bool = False, reverse: bool = False) -> bytes:
d = w.get_digest() d = w.get_digest()
if double: if double:

View File

@ -4,9 +4,9 @@ from trezor import utils, wire
from trezor.crypto.hashlib import blake256, sha256 from trezor.crypto.hashlib import blake256, sha256
from trezor.ui.text import Text from trezor.ui.text import Text
from apps.bitcoin.writers import write_varint
from apps.common.confirm import require_confirm from apps.common.confirm import require_confirm
from apps.common.layout import split_address from apps.common.layout import split_address
from apps.common.writers import write_bitcoin_varint
if False: if False:
from typing import List from typing import List
@ -18,9 +18,9 @@ def message_digest(coin: CoinType, message: bytes) -> bytes:
h = utils.HashWriter(blake256()) h = utils.HashWriter(blake256())
else: else:
h = utils.HashWriter(sha256()) h = utils.HashWriter(sha256())
write_varint(h, len(coin.signed_message_header)) write_bitcoin_varint(h, len(coin.signed_message_header))
h.extend(coin.signed_message_header) h.extend(coin.signed_message_header)
write_varint(h, len(message)) write_bitcoin_varint(h, len(message))
h.extend(message) h.extend(message)
ret = h.get_digest() ret = h.get_digest()
if coin.sign_hash_double: if coin.sign_hash_double:

View File

@ -93,3 +93,19 @@ def write_bytes_reversed(w: Writer, b: bytes, length: int) -> int:
ensure(len(b) == length) ensure(len(b) == length)
w.extend(bytes(reversed(b))) w.extend(bytes(reversed(b)))
return length return length
def write_bitcoin_varint(w: Writer, n: int) -> None:
ensure(n >= 0 and n <= 0xFFFFFFFF)
if n < 253:
w.append(n & 0xFF)
elif n < 0x10000:
w.append(253)
w.append(n & 0xFF)
w.append((n >> 8) & 0xFF)
else:
w.append(254)
w.append(n & 0xFF)
w.append((n >> 8) & 0xFF)
w.append((n >> 16) & 0xFF)
w.append((n >> 24) & 0xFF)

View File

@ -3,10 +3,10 @@ from trezor.crypto.hashlib import sha256
from trezor.messages.LiskMessageSignature import LiskMessageSignature from trezor.messages.LiskMessageSignature import LiskMessageSignature
from trezor.utils import HashWriter from trezor.utils import HashWriter
from apps.bitcoin.sign_tx.writers import write_varint
from apps.common import paths from apps.common import paths
from apps.common.seed import with_slip44_keychain from apps.common.seed import with_slip44_keychain
from apps.common.signverify import require_confirm_sign_message from apps.common.signverify import require_confirm_sign_message
from apps.common.writers import write_bitcoin_varint
from apps.lisk import CURVE, SLIP44_ID from apps.lisk import CURVE, SLIP44_ID
from apps.lisk.helpers import validate_full_path from apps.lisk.helpers import validate_full_path
@ -14,9 +14,9 @@ from apps.lisk.helpers import validate_full_path
def message_digest(message): def message_digest(message):
h = HashWriter(sha256()) h = HashWriter(sha256())
signed_message_header = "Lisk Signed Message:\n" signed_message_header = "Lisk Signed Message:\n"
write_varint(h, len(signed_message_header)) write_bitcoin_varint(h, len(signed_message_header))
h.extend(signed_message_header) h.extend(signed_message_header)
write_varint(h, len(message)) write_bitcoin_varint(h, len(message))
h.extend(message) h.extend(message)
return sha256(h.get_digest()).digest() return sha256(h.get_digest()).digest()