You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
trezor-firmware/core/src/apps/bitcoin/writers.py

126 lines
3.4 KiB

from micropython import const
from trezor.crypto.hashlib import sha256
from trezor.messages.TxInputType import TxInputType
from trezor.messages.TxOutputBinType import TxOutputBinType
from trezor.messages.TxOutputType import TxOutputType
from trezor.utils import ensure
from apps.common.writers import ( # noqa: F401
empty_bytearray,
write_bytes_fixed,
write_bytes_reversed,
write_bytes_unchecked,
write_uint8,
write_uint16_le,
write_uint32_le,
write_uint64_le,
)
if False:
from typing import Union
from apps.common.writers import Writer
from trezor.utils import HashWriter
write_uint16 = write_uint16_le
write_uint32 = write_uint32_le
write_uint64 = write_uint64_le
TX_HASH_SIZE = const(32)
def write_bytes_prefixed(w: Writer, b: bytes) -> None:
write_varint(w, len(b))
write_bytes_unchecked(w, b)
def write_tx_input(w: Writer, i: TxInputType, script: bytes) -> None:
write_bytes_reversed(w, i.prev_hash, TX_HASH_SIZE)
write_uint32(w, i.prev_index)
write_bytes_prefixed(w, script)
write_uint32(w, i.sequence)
def write_tx_input_check(w: Writer, i: TxInputType) -> None:
write_bytes_fixed(w, i.prev_hash, TX_HASH_SIZE)
write_uint32(w, i.prev_index)
write_uint32(w, i.script_type)
write_uint32(w, len(i.address_n))
for n in i.address_n:
write_uint32(w, n)
write_uint32(w, i.sequence)
write_uint64(w, i.amount or 0)
def write_tx_input_decred(w: Writer, i: TxInputType) -> None:
write_bytes_reversed(w, i.prev_hash, TX_HASH_SIZE)
write_uint32(w, i.prev_index or 0)
write_uint8(w, i.decred_tree or 0)
write_uint32(w, i.sequence)
def write_tx_input_decred_witness(w: Writer, i: TxInputType, script_sig: bytes) -> None:
write_uint64(w, i.amount or 0)
write_uint32(w, 0) # block height fraud proof
write_uint32(w, 0xFFFFFFFF) # block index fraud proof
write_bytes_prefixed(w, script_sig)
def write_tx_output(
w: Writer, o: Union[TxOutputType, TxOutputBinType], script_pubkey: bytes
) -> None:
write_uint64(w, o.amount)
write_bytes_prefixed(w, script_pubkey)
def write_tx_output_decred(
w: Writer, o: Union[TxOutputType, TxOutputBinType], script_pubkey: bytes
) -> None:
write_uint64(w, o.amount)
write_uint16(w, o.decred_script_version)
write_bytes_prefixed(w, script_pubkey)
def write_op_push(w: Writer, n: int) -> None:
ensure(n >= 0 and n <= 0xFFFFFFFF)
if n < 0x4C:
w.append(n & 0xFF)
elif n < 0xFF:
w.append(0x4C)
w.append(n & 0xFF)
elif n < 0xFFFF:
w.append(0x4D)
w.append(n & 0xFF)
w.append((n >> 8) & 0xFF)
else:
w.append(0x4E)
w.append(n & 0xFF)
w.append((n >> 8) & 0xFF)
w.append((n >> 16) & 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:
d = w.get_digest()
if double:
d = sha256(d).digest()
if reverse:
d = bytes(reversed(d))
return d