1
0
mirror of https://github.com/trezor/trezor-firmware.git synced 2024-12-24 15:28:10 +00:00

apps: reflect the wire api changes

This commit is contained in:
Jan Pochyla 2016-12-08 16:18:12 +01:00
parent d56dc88861
commit e0dfc2ef03
28 changed files with 198 additions and 325 deletions

View File

@ -19,7 +19,7 @@ async def confirm(session_id, content=None, code=None, *args, **kwargs):
if code is None:
code = Other
await wire.reply_message(session_id, ButtonRequest(code=code), ButtonAck)
await wire.call(session_id, ButtonRequest(code=code), ButtonAck)
return await loop.Wait((signal, dialog)) == CONFIRMED
@ -39,7 +39,7 @@ async def hold_to_confirm(session_id, content=None, code=None, *args, **kwargs):
if code is None:
code = Other
await wire.reply_message(session_id, ButtonRequest(code=code), ButtonAck)
await wire.call(session_id, ButtonRequest(code=code), ButtonAck)
return await loop.Wait((signal, dialog)) == CONFIRMED

View File

@ -11,5 +11,5 @@ async def request_passphrase(session_id):
'Please enter passphrase', 'on your computer.')
text.render()
ack = await wire.reply_message(session_id, PassphraseRequest(), PassphraseAck)
ack = await wire.call(session_id, PassphraseRequest(), PassphraseAck)
return ack.passphrase

View File

@ -20,7 +20,7 @@ async def request_pin_on_display(session_id: int, code: int=None) -> str:
_, label = _get_code_and_label(code)
await wire.reply_message(session_id,
await wire.call(session_id,
ButtonRequest(code=ProtectCall),
ButtonAck)
@ -51,7 +51,7 @@ async def request_pin_on_client(session_id: int, code: int=None) -> str:
matrix = PinMatrix(label)
matrix.render()
ack = await wire.reply_message(session_id,
ack = await wire.call(session_id,
PinMatrixRequest(code=code),
PinMatrixAck, Cancel)
digits = matrix.digits

View File

@ -1,16 +1,16 @@
from trezor.wire import register_type, protobuf_handler
from trezor.wire import register, protobuf_workflow
from trezor.messages.wire_types import \
DebugLinkDecision, DebugLinkGetState, DebugLinkStop, \
DebugLinkMemoryRead, DebugLinkMemoryWrite, DebugLinkFlashErase
async def dispatch_DebugLinkDecision(msg, session_id):
async def dispatch_DebugLinkDecision(session_id, msg):
from trezor.ui.confirm import CONFIRMED, CANCELLED
from ..common.confirm import signal
signal.send(CONFIRMED if msg.yes_no else CANCELLED)
async def dispatch_DebugLinkGetState(msg, session_id):
async def dispatch_DebugLinkGetState(session_id, msg):
from trezor.messages.DebugLinkState import DebugLinkState
from ..common import storage, request_pin
@ -35,11 +35,11 @@ async def dispatch_DebugLinkGetState(msg, session_id):
return m
async def dispatch_DebugLinkStop(msg, session_id):
async def dispatch_DebugLinkStop(session_id, msg):
pass
async def dispatch_DebugLinkMemoryRead(msg, session_id):
async def dispatch_DebugLinkMemoryRead(session_id, msg):
from trezor.messages.DebugLinkMemory import DebugLinkMemory
from trezor.debug import memaccess
@ -50,26 +50,20 @@ async def dispatch_DebugLinkMemoryRead(msg, session_id):
return m
async def dispatch_DebugLinkMemoryWrite(msg, session_id):
async def dispatch_DebugLinkMemoryWrite(session_id, msg):
# TODO: memcpy((void *)msg.address, msg.memory, len(msg.memory))
pass
async def dispatch_DebugLinkFlashErase(msg, session_id):
async def dispatch_DebugLinkFlashErase(session_id, msg):
# TODO: erase(msg.sector)
pass
def boot():
register_type(
DebugLinkDecision, protobuf_handler, dispatch_DebugLinkDecision)
register_type(
DebugLinkGetState, protobuf_handler, dispatch_DebugLinkGetState)
register_type(
DebugLinkStop, protobuf_handler, dispatch_DebugLinkStop)
register_type(
DebugLinkMemoryRead, protobuf_handler, dispatch_DebugLinkMemoryRead)
register_type(
DebugLinkMemoryWrite, protobuf_handler, dispatch_DebugLinkMemoryWrite)
register_type(
DebugLinkFlashErase, protobuf_handler, dispatch_DebugLinkFlashErase)
register(DebugLinkDecision, protobuf_workflow, dispatch_DebugLinkDecision)
register(DebugLinkGetState, protobuf_workflow, dispatch_DebugLinkGetState)
register(DebugLinkStop, protobuf_workflow, dispatch_DebugLinkStop)
register(DebugLinkMemoryRead, protobuf_workflow, dispatch_DebugLinkMemoryRead)
register(DebugLinkMemoryWrite, protobuf_workflow, dispatch_DebugLinkMemoryWrite)
register(DebugLinkFlashErase, protobuf_workflow, dispatch_DebugLinkFlashErase)

View File

@ -1,4 +1,4 @@
from trezor.wire import register_type, protobuf_handler
from trezor.wire import register, protobuf_workflow
from trezor.utils import unimport
from trezor.messages.wire_types import \
EthereumGetAddress
@ -6,8 +6,8 @@ from trezor.messages.wire_types import \
@unimport
def dispatch_EthereumGetAddress(*args, **kwargs):
from .layout_ethereum_get_address import layout_ethereum_get_address
from .ethereum_get_address import layout_ethereum_get_address
return layout_ethereum_get_address(*args, **kwargs)
def boot():
register_type(EthereumGetAddress, protobuf_handler, dispatch_EthereumGetAddress)
register(EthereumGetAddress, protobuf_workflow, dispatch_EthereumGetAddress)

View File

@ -3,7 +3,7 @@ from trezor.utils import unimport
@unimport
async def layout_ethereum_get_address(msg, session_id):
async def layout_ethereum_get_address(session_id, msg):
from trezor.messages.EthereumAddress import EthereumAddress
from trezor.crypto.curve import secp256k1
from trezor.crypto.hashlib import sha3_256

View File

@ -1,9 +1,9 @@
from trezor.wire import register_type, protobuf_handler, write_message
from trezor.wire import register, protobuf_workflow
from trezor.utils import unimport
from trezor.messages.wire_types import Initialize, GetFeatures, Ping
async def respond_Features(msg, session_id):
async def respond_Features(session_id, msg):
from ..common import storage, coins
from trezor.messages.Features import Features
@ -25,7 +25,7 @@ async def respond_Features(msg, session_id):
return f
async def respond_Pong(msg, session_id):
async def respond_Pong(session_id, msg):
from trezor.messages.Success import Success
s = Success()
s.message = msg.message
@ -37,6 +37,6 @@ async def respond_Pong(msg, session_id):
def boot():
register_type(Initialize, protobuf_handler, respond_Features)
register_type(GetFeatures, protobuf_handler, respond_Features)
register_type(Ping, protobuf_handler, respond_Pong)
register(Initialize, protobuf_workflow, respond_Features)
register(GetFeatures, protobuf_workflow, respond_Features)
register(Ping, protobuf_workflow, respond_Pong)

View File

@ -1,4 +1,4 @@
from trezor.wire import register_type, protobuf_handler
from trezor.wire import register, protobuf_workflow
from trezor.utils import unimport
from trezor.messages.wire_types import \
LoadDevice, ResetDevice, WipeDevice, RecoveryDevice, ApplySettings
@ -6,37 +6,37 @@ from trezor.messages.wire_types import \
@unimport
def dispatch_LoadDevice(*args, **kwargs):
from .layout_load_device import layout_load_device
from .load_device import layout_load_device
return layout_load_device(*args, **kwargs)
@unimport
def dispatch_ResetDevice(*args, **kwargs):
from .layout_reset_device import layout_reset_device
from .reset_device import layout_reset_device
return layout_reset_device(*args, **kwargs)
@unimport
def dispatch_WipeDevice(*args, **kwargs):
from .layout_wipe_device import layout_wipe_device
from .wipe_device import layout_wipe_device
return layout_wipe_device(*args, **kwargs)
@unimport
def dispatch_RecoveryDevice(*args, **kwargs):
from .layout_recovery_device import layout_recovery_device
from .recovery_device import layout_recovery_device
return layout_recovery_device(*args, **kwargs)
@unimport
def dispatch_ApplySettings(*args, **kwargs):
from .layout_apply_settings import layout_apply_settings
from .apply_settings import layout_apply_settings
return layout_apply_settings(*args, **kwargs)
def boot():
register_type(LoadDevice, protobuf_handler, dispatch_LoadDevice)
register_type(ResetDevice, protobuf_handler, dispatch_ResetDevice)
register_type(WipeDevice, protobuf_handler, dispatch_WipeDevice)
register_type(RecoveryDevice, protobuf_handler, dispatch_RecoveryDevice)
register_type(ApplySettings, protobuf_handler, dispatch_ApplySettings)
register(LoadDevice, protobuf_workflow, dispatch_LoadDevice)
register(ResetDevice, protobuf_workflow, dispatch_ResetDevice)
register(WipeDevice, protobuf_workflow, dispatch_WipeDevice)
register(RecoveryDevice, protobuf_workflow, dispatch_RecoveryDevice)
register(ApplySettings, protobuf_workflow, dispatch_ApplySettings)

View File

@ -3,7 +3,7 @@ from trezor.utils import unimport
@unimport
async def layout_apply_settings(msg, session_id):
async def layout_apply_settings(session_id, msg):
from trezor.messages.Success import Success
from trezor.messages.FailureType import Other
from trezor.ui.text import Text

View File

@ -3,7 +3,7 @@ from trezor.utils import unimport
@unimport
async def layout_load_device(msg, session_id):
async def layout_load_device(session_id, msg):
from trezor.crypto import bip39
from trezor.messages.Success import Success
from trezor.messages.FailureType import UnexpectedMessage, Other

View File

@ -4,7 +4,7 @@ from trezor.utils import unimport, chunks
@unimport
async def layout_reset_device(msg, session_id):
async def layout_reset_device(session_id, msg):
from trezor.messages.Success import Success
from trezor.messages.FailureType import UnexpectedMessage
from ..common.request_pin import request_pin_twice
@ -14,7 +14,7 @@ async def layout_reset_device(msg, session_id):
raise wire.FailureError(UnexpectedMessage, 'Already initialized')
mnemonic = await generate_mnemonic(
msg.strength, msg.display_random, session_id)
session_id, msg.strength, msg.display_random)
await show_mnemonic(mnemonic)
@ -33,7 +33,7 @@ async def layout_reset_device(msg, session_id):
@unimport
async def generate_mnemonic(strength, display_random, session_id):
async def generate_mnemonic(session_id, strength, display_random):
from trezor.crypto import hashlib, random, bip39
from trezor.messages.EntropyRequest import EntropyRequest
from trezor.messages.FailureType import Other
@ -46,7 +46,7 @@ async def generate_mnemonic(strength, display_random, session_id):
# if display_random:
# raise wire.FailureError(Other, 'Entropy display not implemented')
ack = await wire.reply_message(session_id, EntropyRequest(), EntropyAck)
ack = await wire.call(session_id, EntropyRequest(), EntropyAck)
if len(ack.entropy) != 32:
raise wire.FailureError(Other, 'Invalid entropy (has to be 32 bytes)')

View File

@ -3,7 +3,7 @@ from trezor.utils import unimport
@unimport
async def layout_wipe_device(_, session_id):
async def layout_wipe_device(session_id, msg):
from trezor.messages.Success import Success
from trezor.ui.text import Text
from ..common.confirm import hold_to_confirm

View File

@ -1,4 +1,4 @@
from trezor.wire import register_type, protobuf_handler
from trezor.wire import register, protobuf_workflow
from trezor.utils import unimport
from trezor.messages.wire_types import \
GetPublicKey, GetAddress, SignTx, EstimateTxSize, \
@ -9,26 +9,26 @@ from trezor.messages.wire_types import \
@unimport
def dispatch_GetPublicKey(*args, **kwargs):
from .layout_get_public_key import layout_get_public_key
from .get_public_key import layout_get_public_key
return layout_get_public_key(*args, **kwargs)
@unimport
def dispatch_GetAddress(*args, **kwargs):
from .layout_get_address import layout_get_address
from .get_address import layout_get_address
return layout_get_address(*args, **kwargs)
@unimport
def dispatch_SignTx(*args, **kwargs):
from .layout_sign_tx import layout_sign_tx
return layout_sign_tx(*args, **kwargs)
from .sign_tx.workflow import sign_tx
return sign_tx(*args, **kwargs)
@unimport
async def dispatch_EstimateTxSize(msg, session_id):
async def dispatch_EstimateTxSize(session_id, msg):
from trezor.messages.TxSize import TxSize
from ..common.signtx import estimate_tx_size
from .sign_tx.signing import estimate_tx_size
m = TxSize()
m.tx_size = estimate_tx_size(msg.inputs_count, msg.outputs_count)
return m
@ -36,34 +36,34 @@ async def dispatch_EstimateTxSize(msg, session_id):
@unimport
def dispatch_SignMessage(*args, **kwargs):
from .layout_sign_message import layout_sign_message
from .sign_message import layout_sign_message
return layout_sign_message(*args, **kwargs)
@unimport
def dispatch_VerifyMessage(*args, **kwargs):
from .layout_verify_message import layout_verify_message
from .verify_message import layout_verify_message
return layout_verify_message(*args, **kwargs)
@unimport
def dispatch_SignIdentity(*args, **kwargs):
from .layout_sign_identity import layout_sign_identity
from .sign_identity import layout_sign_identity
return layout_sign_identity(*args, **kwargs)
@unimport
def dispatch_CipherKeyValue(*args, **kwargs):
from .layout_cipherkeyvalue import layout_cipherkeyvalue
from .cipherkeyvalue import layout_cipherkeyvalue
return layout_cipherkeyvalue(*args, **kwargs)
def boot():
register_type(GetPublicKey, protobuf_handler, dispatch_GetPublicKey)
register_type(GetAddress, protobuf_handler, dispatch_GetAddress)
register_type(SignTx, protobuf_handler, dispatch_SignTx)
register_type(EstimateTxSize, protobuf_handler, dispatch_EstimateTxSize)
register_type(SignMessage, protobuf_handler, dispatch_SignMessage)
register_type(VerifyMessage, protobuf_handler, dispatch_VerifyMessage)
register_type(SignIdentity, protobuf_handler, dispatch_SignIdentity)
register_type(CipherKeyValue, protobuf_handler, dispatch_CipherKeyValue)
register(GetPublicKey, protobuf_workflow, dispatch_GetPublicKey)
register(GetAddress, protobuf_workflow, dispatch_GetAddress)
register(SignTx, protobuf_workflow, dispatch_SignTx)
register(EstimateTxSize, protobuf_workflow, dispatch_EstimateTxSize)
register(SignMessage, protobuf_workflow, dispatch_SignMessage)
register(VerifyMessage, protobuf_workflow, dispatch_VerifyMessage)
register(SignIdentity, protobuf_workflow, dispatch_SignIdentity)
register(CipherKeyValue, protobuf_workflow, dispatch_CipherKeyValue)

View File

@ -1,11 +1,11 @@
from trezor import wire, ui
from trezor import ui
from trezor.utils import unimport
@unimport
async def layout_cipherkeyvalue(msg, session_id):
async def layout_cipher_key_value(session_id, msg):
from trezor.messages.CipheredKeyValue import CipheredKeyValue
from ..common.seed import get_node
from ..common import seed
from trezor.crypto.hashlib import sha512
from trezor.crypto import hmac
from trezor.crypto.aes import AES_CBC_Encrypt, AES_CBC_Decrypt
@ -18,7 +18,7 @@ async def layout_cipherkeyvalue(msg, session_id):
ui.BOLD, ui.LIGHT_GREEN, ui.BLACK)
ui.display.text(10, 60, msg.key, ui.MONO, ui.WHITE, ui.BLACK)
node = await get_node(session_id, msg.address_n)
node = await seed.get_node(session_id, msg.address_n)
seckey = node.private_key()
data = msg.key

View File

@ -3,18 +3,18 @@ from trezor.utils import unimport
@unimport
async def layout_get_address(msg, session_id):
async def layout_get_address(session_id, msg):
from trezor.messages.Address import Address
from trezor.messages.FailureType import Other
from ..common.seed import get_node
from ..common import coins
from ..common import seed
if msg.multisig:
raise wire.FailureError(Other, 'GetAddress.multisig is unsupported')
address_n = msg.address_n or ()
coin_name = msg.coin_name or 'Bitcoin'
node = await get_node(session_id, address_n)
node = await seed.get_node(session_id, address_n)
coin = coins.by_name(coin_name)
address = node.address(coin.address_type)

View File

@ -1,11 +1,11 @@
from trezor.utils import unimport
from ..common import seed
@unimport
async def layout_get_public_key(msg, session_id):
async def layout_get_public_key(session_id, msg):
from trezor.messages.HDNodeType import HDNodeType
from trezor.messages.PublicKey import PublicKey
from ..common import seed
address_n = msg.address_n or ()
node = await seed.get_node(session_id, address_n)

View File

@ -1,79 +0,0 @@
from trezor.utils import unimport
from trezor import wire
def format_amount(amount, coin):
return '%s %s' % (amount / 1e8, coin.coin_shortcut)
def split_address(address):
from trezor.utils import chunks
return chunks(address, 17)
async def confirm_output(session_id, output, coin):
from trezor import ui
from trezor.ui.text import Text
from trezor.messages.ButtonRequestType import ConfirmOutput
from ..common.confirm import confirm
content = Text('Confirm output', ui.ICON_RESET,
ui.BOLD, format_amount(output.amount, coin),
ui.NORMAL, 'to',
ui.MONO, *split_address(output.address))
return await confirm(session_id, content, ConfirmOutput)
async def confirm_total(session_id, spending, fee, coin):
from trezor import ui
from trezor.ui.text import Text
from trezor.messages.ButtonRequestType import SignTx
from ..common.confirm import hold_to_confirm
content = Text('Confirm transaction', ui.ICON_RESET,
'Sending: %s' % format_amount(spending, coin),
'Fee: %s' % format_amount(fee, coin))
return await hold_to_confirm(session_id, content, SignTx)
async def confirm_feeoverthreshold(session_id, fee, coin):
from trezor import ui
from trezor.ui.text import Text
from trezor.messages.ButtonRequestType import FeeOverThreshold
from ..common.confirm import confirm
content = Text('Confirm high fee:', ui.ICON_RESET,
ui.BOLD, format_amount(fee, coin))
return await confirm(session_id, content, FeeOverThreshold)
@unimport
async def layout_sign_tx(msg, session_id):
from ..common.seed import get_root_node
from ..common import signtx
from trezor.messages.RequestType import TXFINISHED
from trezor.messages.wire_types import TxAck
root = await get_root_node(session_id)
signer = signtx.sign_tx(msg, root)
res = None
while True:
try:
req = signer.send(res)
except signtx.SigningError as e:
raise wire.FailureError(*e.args)
if req.__qualname__ == 'TxRequest':
if req.request_type == TXFINISHED:
break
res = await wire.reply_message(session_id, req, TxAck)
elif req.__qualname__ == 'UiConfirmOutput':
res = await confirm_output(session_id, req.output, req.coin)
elif req.__qualname__ == 'UiConfirmTotal':
res = await confirm_total(session_id, req.spending, req.fee, req.coin)
elif req.__qualname__ == 'UiConfirmFeeOverThreshold':
res = await confirm_feeoverthreshold(session_id, req.fee, req.coin)
else:
raise TypeError('Invalid signing instruction')
return req

View File

@ -2,13 +2,13 @@ from trezor import ui
from trezor.utils import unimport
@unimport
async def layout_sign_identity(msg, session_id):
async def layout_sign_identity(session_id, msg):
from trezor.messages.SignedIdentity import SignedIdentity
from trezor.crypto.curve import secp256k1
from trezor.crypto.hashlib import sha256
from ustruct import pack, unpack
from ..common.seed import get_node
from ..common import coins
from ..common import seed
from ..common.signverify import message_digest
identity = ''
@ -38,7 +38,7 @@ async def layout_sign_identity(msg, session_id):
ui.display.text(10, 60, msg.challenge_visual, ui.MONO, ui.WHITE, ui.BLACK)
ui.display.text(10, 80, identity, ui.MONO, ui.WHITE, ui.BLACK)
node = await get_node(session_id, address_n)
node = await seed.get_node(session_id, address_n)
coin = coins.by_name('Bitcoin')
address = node.address(coin.address_type) # hardcoded Bitcoin address type

View File

@ -3,11 +3,11 @@ from trezor.utils import unimport
@unimport
async def layout_sign_message(msg, session_id):
async def layout_sign_message(session_id, msg):
from trezor.messages.MessageSignature import MessageSignature
from trezor.crypto.curve import secp256k1
from ..common.seed import get_node
from ..common import coins
from ..common import seed
from ..common.signverify import message_digest
ui.display.clear()
@ -18,7 +18,7 @@ async def layout_sign_message(msg, session_id):
coin_name = msg.coin_name or 'Bitcoin'
coin = coins.by_name(coin_name)
node = await get_node(session_id, msg.address_n)
node = await seed.get_node(session_id, msg.address_n)
seckey = node.private_key()
address = node.address(coin.address_type)

View File

View File

@ -0,0 +1,35 @@
from trezor import ui
from trezor.utils import chunks
from trezor.ui.text import Text
from trezor.messages import ButtonRequestType
from apps.common.confirm import confirm
from apps.common.confirm import hold_to_confirm
def format_amount(amount, coin):
return '%s %s' % (amount / 1e8, coin.coin_shortcut)
def split_address(address):
return chunks(address, 17)
async def confirm_output(session_id, output, coin):
content = Text('Confirm output', ui.ICON_RESET,
ui.BOLD, format_amount(output.amount, coin),
ui.NORMAL, 'to',
ui.MONO, *split_address(output.address))
return await confirm(session_id, content, ButtonRequestType.ConfirmOutput)
async def confirm_total(session_id, spending, fee, coin):
content = Text('Confirm transaction', ui.ICON_RESET,
'Sending: %s' % format_amount(spending, coin),
'Fee: %s' % format_amount(fee, coin))
return await hold_to_confirm(session_id, content, ButtonRequestType.SignTx)
async def confirm_feeoverthreshold(session_id, fee, coin):
content = Text('Confirm high fee:', ui.ICON_RESET,
ui.BOLD, format_amount(fee, coin))
return await confirm(session_id, content, ButtonRequestType.FeeOverThreshold)

View File

@ -1,9 +1,7 @@
from trezor.crypto.hashlib import sha256, ripemd160
from trezor.crypto.curve import secp256k1
from trezor.crypto import base58, der
from . import address_type
from . import coins
from trezor.utils import ensure
from trezor.messages.CoinType import CoinType
from trezor.messages.SignTx import SignTx
@ -17,6 +15,9 @@ from trezor.messages.TxRequestSerializedType import TxRequestSerializedType
from trezor.messages.TxRequestDetailsType import TxRequestDetailsType
from trezor.messages import OutputScriptType, InputScriptType, FailureType
from apps.common import address_type
from apps.common import coins
# Machine instructions
# ===
@ -412,11 +413,11 @@ def node_derive(root, address_n: list):
def ecdsa_hash_pubkey(pubkey: bytes) -> bytes:
if pubkey[0] == 0x04:
assert len(pubkey) == 65 # uncompressed format
ensure(len(pubkey) == 65) # uncompressed format
elif pubkey[0] == 0x00:
assert len(pubkey) == 1 # point at infinity
ensure(len(pubkey) == 1) # point at infinity
else:
assert len(pubkey) == 33 # compresssed format
ensure(len(pubkey) == 33) # compresssed format
h = sha256(pubkey).digest()
h = ripemd160(h).digest()
return h
@ -473,9 +474,11 @@ def script_spendaddress_new(pubkey: bytes, signature: bytes) -> bytearray:
# TX Serialization
# ===
_DEFAULT_SEQUENCE = 4294967295
def write_tx_input(w, i: TxInputType):
i_sequence = i.sequence if i.sequence is not None else 4294967295
i_sequence = i.sequence if i.sequence is not None else _DEFAULT_SEQUENCE
write_bytes_rev(w, i.prev_hash)
write_uint32(w, i.prev_index)
write_varint(w, len(i.script_sig))
@ -484,7 +487,7 @@ def write_tx_input(w, i: TxInputType):
def write_tx_input_check(w, i: TxInputType):
i_sequence = i.sequence if i.sequence is not None else 4294967295
i_sequence = i.sequence if i.sequence is not None else _DEFAULT_SEQUENCE
write_bytes(w, i.prev_hash)
write_uint32(w, i.prev_index)
write_uint32(w, len(i.address_n))
@ -500,22 +503,21 @@ def write_tx_output(w, o: TxOutputBinType):
def write_op_push(w, n: int):
wb = w.append
if n < 0x4C:
wb(n & 0xFF)
w.append(n & 0xFF)
elif n < 0xFF:
wb(0x4C)
wb(n & 0xFF)
w.append(0x4C)
w.append(n & 0xFF)
elif n < 0xFFFF:
wb(0x4D)
wb(n & 0xFF)
wb((n >> 8) & 0xFF)
w.append(0x4D)
w.append(n & 0xFF)
w.append((n >> 8) & 0xFF)
else:
wb(0x4E)
wb(n & 0xFF)
wb((n >> 8) & 0xFF)
wb((n >> 16) & 0xFF)
wb((n >> 24) & 0xFF)
w.append(0x4E)
w.append(n & 0xFF)
w.append((n >> 8) & 0xFF)
w.append((n >> 16) & 0xFF)
w.append((n >> 24) & 0xFF)
# Buffer IO & Serialization
@ -523,39 +525,36 @@ def write_op_push(w, n: int):
def write_varint(w, n: int):
wb = w.append
if n < 253:
wb(n & 0xFF)
w.append(n & 0xFF)
elif n < 65536:
wb(253)
wb(n & 0xFF)
wb((n >> 8) & 0xFF)
w.append(253)
w.append(n & 0xFF)
w.append((n >> 8) & 0xFF)
else:
wb(254)
wb(n & 0xFF)
wb((n >> 8) & 0xFF)
wb((n >> 16) & 0xFF)
wb((n >> 24) & 0xFF)
w.append(254)
w.append(n & 0xFF)
w.append((n >> 8) & 0xFF)
w.append((n >> 16) & 0xFF)
w.append((n >> 24) & 0xFF)
def write_uint32(w, n: int):
wb = w.append
wb(n & 0xFF)
wb((n >> 8) & 0xFF)
wb((n >> 16) & 0xFF)
wb((n >> 24) & 0xFF)
w.append(n & 0xFF)
w.append((n >> 8) & 0xFF)
w.append((n >> 16) & 0xFF)
w.append((n >> 24) & 0xFF)
def write_uint64(w, n: int):
wb = w.append
wb(n & 0xFF)
wb((n >> 8) & 0xFF)
wb((n >> 16) & 0xFF)
wb((n >> 24) & 0xFF)
wb((n >> 32) & 0xFF)
wb((n >> 40) & 0xFF)
wb((n >> 48) & 0xFF)
wb((n >> 56) & 0xFF)
w.append(n & 0xFF)
w.append((n >> 8) & 0xFF)
w.append((n >> 16) & 0xFF)
w.append((n >> 24) & 0xFF)
w.append((n >> 32) & 0xFF)
w.append((n >> 40) & 0xFF)
w.append((n >> 48) & 0xFF)
w.append((n >> 56) & 0xFF)
def write_bytes(w, buf: bytearray):

View File

@ -0,0 +1,35 @@
from trezor.utils import unimport
from trezor import wire
@unimport
async def sign_tx(session_id, msg):
from trezor.messages.RequestType import TXFINISHED
from trezor.messages.wire_types import TxAck
from apps.common import seed
from . import signing
from . import layout
root = await seed.get_root_node(session_id)
signer = signing.sign_tx(msg, root)
res = None
while True:
try:
req = signer.send(res)
except signing.SigningError as e:
raise wire.FailureError(*e.args)
if req.__qualname__ == 'TxRequest':
if req.request_type == TXFINISHED:
break
res = await wire.call(session_id, req, TxAck)
elif req.__qualname__ == 'UiConfirmOutput':
res = await layout.confirm_output(session_id, req.output, req.coin)
elif req.__qualname__ == 'UiConfirmTotal':
res = await layout.confirm_total(session_id, req.spending, req.fee, req.coin)
elif req.__qualname__ == 'UiConfirmFeeOverThreshold':
res = await layout.confirm_feeoverthreshold(session_id, req.fee, req.coin)
else:
raise TypeError('Invalid signing instruction')
return req

View File

@ -3,7 +3,7 @@ from trezor.utils import unimport
@unimport
async def layout_verify_message(msg, session_id):
async def layout_verify_message(session_id, msg):
from trezor.messages.Success import Success
from trezor.crypto.curve import secp256k1
from trezor.crypto.hashlib import ripemd160, sha256

View File

@ -1,111 +0,0 @@
from common import *
from trezor.utils import chunks
from trezor.crypto import bip32, bip39
from trezor.messages.SignTx import SignTx
from trezor.messages.TxInputType import TxInputType
from trezor.messages.TxOutputType import TxOutputType
from trezor.messages.TxOutputBinType import TxOutputBinType
from trezor.messages.TxRequest import TxRequest
from trezor.messages.TxAck import TxAck
from trezor.messages.TransactionType import TransactionType
from trezor.messages.RequestType import TXINPUT, TXOUTPUT, TXMETA, TXFINISHED
from trezor.messages.TxRequestDetailsType import TxRequestDetailsType
from trezor.messages.TxRequestSerializedType import TxRequestSerializedType
from trezor.messages import OutputScriptType
from apps.common import coins
from apps.common import signtx
class TestSignTx(unittest.TestCase):
# pylint: disable=C0301
def test_one_one_fee(self):
# tx: d5f65ee80147b4bcc70b75e4bbf2d7382021b871bd8867ef8fa525ef50864882
# input 0: 0.0039 BTC
coin_bitcoin = coins.by_name('Bitcoin')
ptx1 = TransactionType(version=1, lock_time=0, inputs_cnt=2, outputs_cnt=1)
pinp1 = TxInputType(script_sig=unhexlify('483045022072ba61305fe7cb542d142b8f3299a7b10f9ea61f6ffaab5dca8142601869d53c0221009a8027ed79eb3b9bc13577ac2853269323434558528c6b6a7e542be46e7e9a820141047a2d177c0f3626fc68c53610b0270fa6156181f46586c679ba6a88b34c6f4874686390b4d92e5769fbb89c8050b984f4ec0b257a0e5c4ff8bd3b035a51709503'),
prev_hash=unhexlify('c16a03f1cf8f99f6b5297ab614586cacec784c2d259af245909dedb0e39eddcf'),
prev_index=1,
script_type=None,
sequence=None)
pinp2 = TxInputType(script_sig=unhexlify('48304502200fd63adc8f6cb34359dc6cca9e5458d7ea50376cbd0a74514880735e6d1b8a4c0221008b6ead7fe5fbdab7319d6dfede3a0bc8e2a7c5b5a9301636d1de4aa31a3ee9b101410486ad608470d796236b003635718dfc07c0cac0cfc3bfc3079e4f491b0426f0676e6643a39198e8e7bdaffb94f4b49ea21baa107ec2e237368872836073668214'),
prev_hash=unhexlify('1ae39a2f8d59670c8fc61179148a8e61e039d0d9e8ab08610cb69b4a19453eaf'),
prev_index=1,
script_type=None,
sequence=None)
pout1 = TxOutputBinType(script_pubkey=unhexlify('76a91424a56db43cf6f2b02e838ea493f95d8d6047423188ac'),
amount=390000,
address_n=None)
inp1 = TxInputType(address_n=[0], # 14LmW5k4ssUrtbAB4255zdqv3b4w1TuX9e
# amount=390000,
prev_hash=unhexlify('d5f65ee80147b4bcc70b75e4bbf2d7382021b871bd8867ef8fa525ef50864882'),
prev_index=0,
script_type=None,
sequence=None)
out1 = TxOutputType(address='1MJ2tj2ThBE62zXbBYA5ZaN3fdve5CPAz1',
amount=390000 - 10000,
script_type=OutputScriptType.PAYTOADDRESS,
address_n=None)
tx = SignTx(coin_name=None, version=None, lock_time=None, inputs_count=1, outputs_count=1)
messages = [
None,
TxRequest(request_type=TXINPUT, details=TxRequestDetailsType(request_index=0, tx_hash=None)),
TxAck(tx=TransactionType(inputs=[inp1])),
TxRequest(request_type=TXMETA, details=TxRequestDetailsType(request_index=None, tx_hash=unhexlify('d5f65ee80147b4bcc70b75e4bbf2d7382021b871bd8867ef8fa525ef50864882')), serialized=None),
TxAck(tx=ptx1),
TxRequest(request_type=TXINPUT, details=TxRequestDetailsType(request_index=0, tx_hash=unhexlify('d5f65ee80147b4bcc70b75e4bbf2d7382021b871bd8867ef8fa525ef50864882')), serialized=None),
TxAck(tx=TransactionType(inputs=[pinp1])),
TxRequest(request_type=TXINPUT, details=TxRequestDetailsType(request_index=1, tx_hash=unhexlify('d5f65ee80147b4bcc70b75e4bbf2d7382021b871bd8867ef8fa525ef50864882')), serialized=None),
TxAck(tx=TransactionType(inputs=[pinp2])),
TxRequest(request_type=TXOUTPUT, details=TxRequestDetailsType(request_index=0, tx_hash=unhexlify('d5f65ee80147b4bcc70b75e4bbf2d7382021b871bd8867ef8fa525ef50864882')), serialized=None),
TxAck(tx=TransactionType(bin_outputs=[pout1])),
TxRequest(request_type=TXOUTPUT, details=TxRequestDetailsType(request_index=0, tx_hash=None), serialized=None),
TxAck(tx=TransactionType(outputs=[out1])),
signtx.UiConfirmOutput(out1, coin_bitcoin),
True,
signtx.UiConfirmTotal(380000, 10000, coin_bitcoin),
True,
# ButtonRequest(code=ButtonRequest_ConfirmOutput),
# ButtonRequest(code=ButtonRequest_SignTx),
TxRequest(request_type=TXINPUT, details=TxRequestDetailsType(request_index=0, tx_hash=None), serialized=None),
TxAck(tx=TransactionType(inputs=[inp1])),
TxRequest(request_type=TXOUTPUT, details=TxRequestDetailsType(request_index=0, tx_hash=None), serialized=None),
TxAck(tx=TransactionType(outputs=[out1])),
TxRequest(request_type=TXOUTPUT, details=TxRequestDetailsType(request_index=0, tx_hash=None), serialized=TxRequestSerializedType(
signature_index=0,
signature=unhexlify('30450221009a0b7be0d4ed3146ee262b42202841834698bb3ee39c24e7437df208b8b7077102202b79ab1e7736219387dffe8d615bbdba87e11477104b867ef47afed1a5ede781'),
serialized_tx=unhexlify('010000000182488650ef25a58fef6788bd71b8212038d7f2bbe4750bc7bcb44701e85ef6d5000000006b4830450221009a0b7be0d4ed3146ee262b42202841834698bb3ee39c24e7437df208b8b7077102202b79ab1e7736219387dffe8d615bbdba87e11477104b867ef47afed1a5ede7810121023230848585885f63803a0a8aecdd6538792d5c539215c91698e315bf0253b43dffffffff'))),
TxAck(tx=TransactionType(outputs=[out1])),
TxRequest(request_type=TXFINISHED, details=None, serialized=TxRequestSerializedType(
signature_index=None,
signature=None,
serialized_tx=unhexlify('0160cc0500000000001976a914de9b2a8da088824e8fe51debea566617d851537888ac00000000'),
)),
]
seed = bip39.seed('alcohol woman abuse must during monitor noble actual mixed trade anger aisle', '')
root = bip32.from_seed(seed, 'secp256k1')
signer = signtx.sign_tx(tx, root)
for request, response in chunks(messages, 2):
self.assertEqualEx(signer.send(request), response)
with self.assertRaises(StopIteration):
signer.send(None)
def assertEqualEx(self, a, b):
# hack to avoid adding __eq__ to signtx.Ui* classes
if ((isinstance(a, signtx.UiConfirmOutput) and isinstance(b, signtx.UiConfirmOutput)) or
(isinstance(a, signtx.UiConfirmTotal) and isinstance(b, signtx.UiConfirmTotal))):
return self.assertEqual(a.__dict__, b.__dict__)
else:
return self.assertEqual(a, b)
if __name__ == '__main__':
unittest.main()