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

chore(core): decrease binance size by 460 bytes

This commit is contained in:
grdddj 2022-09-16 14:53:44 +02:00 committed by matejcik
parent f8f3f1bc55
commit 47b924cbec
6 changed files with 113 additions and 111 deletions

View File

@ -1,31 +1,34 @@
from typing import TYPE_CHECKING
from trezor.messages import BinanceAddress
from trezor.ui.layouts import show_address
from apps.common import paths
from apps.common.keychain import Keychain, auto_keychain
from .helpers import address_from_public_key
from apps.common.keychain import auto_keychain
if TYPE_CHECKING:
from trezor.messages import BinanceGetAddress
from trezor.messages import BinanceGetAddress, BinanceAddress
from trezor.wire import Context
from apps.common.keychain import Keychain
@auto_keychain(__name__)
async def get_address(
ctx: Context, msg: BinanceGetAddress, keychain: Keychain
) -> BinanceAddress:
from trezor.messages import BinanceAddress
from trezor.ui.layouts import show_address
from apps.common import paths
from .helpers import address_from_public_key
HRP = "bnb"
address_n = msg.address_n # local_cache_attribute
await paths.validate_path(ctx, keychain, msg.address_n)
await paths.validate_path(ctx, keychain, address_n)
node = keychain.derive(msg.address_n)
node = keychain.derive(address_n)
pubkey = node.public_key()
address = address_from_public_key(pubkey, HRP)
if msg.show_display:
title = paths.address_n_to_str(msg.address_n)
await show_address(ctx, address=address, title=title)
title = paths.address_n_to_str(address_n)
await show_address(ctx, address, title=title)
return BinanceAddress(address=address)

View File

@ -1,21 +1,24 @@
from typing import TYPE_CHECKING
from ubinascii import hexlify
from trezor.messages import BinancePublicKey
from trezor.ui.layouts import show_pubkey
from apps.common import paths
from apps.common.keychain import Keychain, auto_keychain
from apps.common.keychain import auto_keychain
if TYPE_CHECKING:
from trezor.messages import BinanceGetPublicKey
from trezor.messages import BinanceGetPublicKey, BinancePublicKey
from trezor.wire import Context
from apps.common.keychain import Keychain
@auto_keychain(__name__)
async def get_public_key(
ctx: Context, msg: BinanceGetPublicKey, keychain: Keychain
) -> BinancePublicKey:
from ubinascii import hexlify
from trezor.messages import BinancePublicKey
from trezor.ui.layouts import show_pubkey
from apps.common import paths
await paths.validate_path(ctx, keychain, msg.address_n)
node = keychain.derive(msg.address_n)
pubkey = node.public_key()

View File

@ -1,33 +1,52 @@
from micropython import const
from typing import TYPE_CHECKING
from trezor import wire
from trezor.crypto import bech32
from trezor.crypto.scripts import sha256_ripemd160
from trezor.messages import BinanceCancelMsg, BinanceOrderMsg, BinanceTransferMsg
if TYPE_CHECKING:
from trezor.messages import BinanceInputOutput, BinanceSignTx
from trezor.protobuf import MessageType
ENVELOPE_BLUEPRINT = '{{"account_number":"{account_number}","chain_id":"{chain_id}","data":null,"memo":"{memo}","msgs":[{msgs}],"sequence":"{sequence}","source":"{source}"}}'
MSG_TRANSFER_BLUEPRINT = '{{"inputs":[{inputs}],"outputs":[{outputs}]}}'
MSG_NEWORDER_BLUEPRINT = '{{"id":"{id}","ordertype":{ordertype},"price":{price},"quantity":{quantity},"sender":"{sender}","side":{side},"symbol":"{symbol}","timeinforce":{timeinforce}}}'
MSG_CANCEL_BLUEPRINT = '{{"refid":"{refid}","sender":"{sender}","symbol":"{symbol}"}}'
INPUT_OUTPUT_BLUEPRINT = '{{"address":"{address}","coins":[{coins}]}}'
COIN_BLUEPRINT = '{{"amount":{amount},"denom":"{denom}"}}'
# 1*10^8 Jagers equal 1 BNB https://www.binance.vision/glossary/jager
DECIMALS = const(8)
# NOTE: it is 11 bytes smaller to define it on top level than inside a function
def _make_input_output(input_output: BinanceInputOutput) -> str:
COIN_BLUEPRINT = '{{"amount":{},"denom":"{}"}}'
INPUT_OUTPUT_BLUEPRINT = '{{"address":"{}","coins":[{}]}}'
coins = ",".join(
COIN_BLUEPRINT.format(c.amount, c.denom) for c in input_output.coins
)
return INPUT_OUTPUT_BLUEPRINT.format(input_output.address, coins)
def produce_json_for_signing(envelope: BinanceSignTx, msg: MessageType) -> str:
from trezor.messages import BinanceCancelMsg, BinanceOrderMsg, BinanceTransferMsg
from trezor import wire
# NOTE: not defining kwargs in format string saves 7 bytes per each argument
ENVELOPE_BLUEPRINT = '{{"account_number":"{}","chain_id":"{}","data":null,"memo":"{}","msgs":[{}],"sequence":"{}","source":"{}"}}'
MSG_TRANSFER_BLUEPRINT = '{{"inputs":[{}],"outputs":[{}]}}'
MSG_NEWORDER_BLUEPRINT = '{{"id":"{}","ordertype":{},"price":{},"quantity":{},"sender":"{}","side":{},"symbol":"{}","timeinforce":{}}}'
MSG_CANCEL_BLUEPRINT = '{{"refid":"{}","sender":"{}","symbol":"{}"}}'
if BinanceTransferMsg.is_type_of(msg):
json_msg = produce_transfer_json(msg)
inputs = ",".join(_make_input_output(i) for i in msg.inputs)
outputs = ",".join(_make_input_output(o) for o in msg.outputs)
json_msg = MSG_TRANSFER_BLUEPRINT.format(inputs, outputs)
elif BinanceOrderMsg.is_type_of(msg):
json_msg = produce_neworder_json(msg)
json_msg = MSG_NEWORDER_BLUEPRINT.format(
msg.id,
msg.ordertype,
msg.price,
msg.quantity,
msg.sender,
msg.side,
msg.symbol,
msg.timeinforce,
)
elif BinanceCancelMsg.is_type_of(msg):
json_msg = produce_cancel_json(msg)
json_msg = MSG_CANCEL_BLUEPRINT.format(msg.refid, msg.sender, msg.symbol)
else:
raise wire.ProcessError("input message unrecognized")
@ -35,45 +54,12 @@ def produce_json_for_signing(envelope: BinanceSignTx, msg: MessageType) -> str:
raise wire.DataError("Source is invalid")
return ENVELOPE_BLUEPRINT.format(
account_number=envelope.account_number,
chain_id=envelope.chain_id,
memo=envelope.memo,
msgs=json_msg,
sequence=envelope.sequence,
source=envelope.source,
)
def produce_transfer_json(msg: BinanceTransferMsg) -> str:
def make_input_output(input_output: BinanceInputOutput) -> str:
coins = ",".join(
COIN_BLUEPRINT.format(amount=c.amount, denom=c.denom)
for c in input_output.coins
)
return INPUT_OUTPUT_BLUEPRINT.format(address=input_output.address, coins=coins)
inputs = ",".join(make_input_output(i) for i in msg.inputs)
outputs = ",".join(make_input_output(o) for o in msg.outputs)
return MSG_TRANSFER_BLUEPRINT.format(inputs=inputs, outputs=outputs)
def produce_neworder_json(msg: BinanceOrderMsg) -> str:
return MSG_NEWORDER_BLUEPRINT.format(
id=msg.id,
ordertype=msg.ordertype,
price=msg.price,
quantity=msg.quantity,
sender=msg.sender,
side=msg.side,
symbol=msg.symbol,
timeinforce=msg.timeinforce,
)
def produce_cancel_json(msg: BinanceCancelMsg) -> str:
return MSG_CANCEL_BLUEPRINT.format(
refid=msg.refid, sender=msg.sender, symbol=msg.symbol
envelope.account_number,
envelope.chain_id,
envelope.memo,
json_msg,
envelope.sequence,
envelope.source,
)
@ -83,6 +69,8 @@ def address_from_public_key(pubkey: bytes, hrp: str) -> str:
Address_Bech32 = HRP + '1' + bech32.encode(convert8BitsTo5Bits(RIPEMD160(SHA256(compressed public key))))
HRP - bnb for productions, tbnb for tests
"""
from trezor.crypto import bech32
from trezor.crypto.scripts import sha256_ripemd160
h = sha256_ripemd160(pubkey).digest()

View File

@ -1,11 +1,10 @@
from typing import TYPE_CHECKING
from trezor.enums import BinanceOrderSide, ButtonRequestType
from trezor.enums import ButtonRequestType
from trezor.strings import format_amount
from trezor.ui.layouts import confirm_properties
from trezor.ui.layouts.altcoin import confirm_transfer_binance
from . import helpers
from .helpers import DECIMALS
if TYPE_CHECKING:
from trezor.messages import (
@ -18,14 +17,16 @@ if TYPE_CHECKING:
async def require_confirm_transfer(ctx: Context, msg: BinanceTransferMsg) -> None:
items = []
from trezor.ui.layouts.altcoin import confirm_transfer_binance
items: list[tuple[str, str, str]] = []
def make_input_output_pages(msg: BinanceInputOutput, direction: str) -> None:
for coin in msg.coins:
items.append(
(
direction,
format_amount(coin.amount, helpers.DECIMALS) + " " + coin.denom,
format_amount(coin.amount, DECIMALS) + " " + coin.denom,
msg.address,
)
)
@ -43,18 +44,20 @@ async def require_confirm_cancel(ctx: Context, msg: BinanceCancelMsg) -> None:
await confirm_properties(
ctx,
"confirm_cancel",
title="Confirm cancel",
props=[
"Confirm cancel",
(
("Sender address:", str(msg.sender)),
("Pair:", str(msg.symbol)),
("Order ID:", str(msg.refid)),
],
),
hold=True,
br_code=ButtonRequestType.SignTx,
)
async def require_confirm_order(ctx: Context, msg: BinanceOrderMsg) -> None:
from trezor.enums import BinanceOrderSide
if msg.side == BinanceOrderSide.BUY:
side = "Buy"
elif msg.side == BinanceOrderSide.SELL:
@ -65,14 +68,14 @@ async def require_confirm_order(ctx: Context, msg: BinanceOrderMsg) -> None:
await confirm_properties(
ctx,
"confirm_order",
title="Confirm order",
props=[
"Confirm order",
(
("Sender address:", str(msg.sender)),
("Pair:", str(msg.symbol)),
("Side:", side),
("Quantity:", format_amount(msg.quantity, helpers.DECIMALS)),
("Price:", format_amount(msg.price, helpers.DECIMALS)),
],
("Quantity:", format_amount(msg.quantity, DECIMALS)),
("Price:", format_amount(msg.price, DECIMALS)),
),
hold=True,
br_code=ButtonRequestType.SignTx,
)

View File

@ -1,30 +1,33 @@
from typing import TYPE_CHECKING
from trezor import wire
from trezor.crypto.curve import secp256k1
from trezor.crypto.hashlib import sha256
from trezor.enums import MessageType
from trezor.messages import (
BinanceCancelMsg,
BinanceOrderMsg,
BinanceSignedTx,
BinanceTransferMsg,
BinanceTxRequest,
)
from apps.common import paths
from apps.common.keychain import Keychain, auto_keychain
from . import helpers, layout
from apps.common.keychain import auto_keychain
if TYPE_CHECKING:
from trezor.messages import BinanceSignTx
from trezor.messages import BinanceSignTx, BinanceSignedTx
from apps.common.keychain import Keychain
from trezor.wire import Context
@auto_keychain(__name__)
async def sign_tx(
ctx: wire.Context, envelope: BinanceSignTx, keychain: Keychain
ctx: Context, envelope: BinanceSignTx, keychain: Keychain
) -> BinanceSignedTx:
from trezor import wire
from trezor.crypto.curve import secp256k1
from trezor.crypto.hashlib import sha256
from trezor.enums import MessageType
from trezor.messages import (
BinanceCancelMsg,
BinanceOrderMsg,
BinanceSignedTx,
BinanceTransferMsg,
BinanceTxRequest,
)
from apps.common import paths
from . import helpers, layout
# create transaction message -> sign it -> create signature/pubkey message -> serialize all
if envelope.msg_count > 1:
raise wire.DataError("Multiple messages not supported.")
@ -55,11 +58,8 @@ async def sign_tx(
else:
raise wire.ProcessError("input message unrecognized")
signature_bytes = generate_content_signature(msg_json.encode(), node.private_key())
# generate_content_signature
msghash = sha256(msg_json.encode()).digest()
signature_bytes = secp256k1.sign(node.private_key(), msghash)[1:65]
return BinanceSignedTx(signature=signature_bytes, public_key=node.public_key())
def generate_content_signature(json: bytes, private_key: bytes) -> bytes:
msghash = sha256(json).digest()
return secp256k1.sign(private_key, msghash)[1:65]

View File

@ -5,7 +5,6 @@ from trezor.crypto.hashlib import sha256
if not utils.BITCOIN_ONLY:
from apps.binance.helpers import produce_json_for_signing
from apps.binance.sign_tx import generate_content_signature, sign_tx
from trezor.messages import BinanceCancelMsg
from trezor.messages import BinanceCoin
from trezor.messages import BinanceInputOutput
@ -14,6 +13,12 @@ if not utils.BITCOIN_ONLY:
from trezor.messages import BinanceTransferMsg
# NOTE: copy-pasted from apps.binance.sign_tx
def generate_content_signature(json: bytes, private_key: bytes) -> bytes:
msghash = sha256(json).digest()
return secp256k1.sign(private_key, msghash)[1:65]
@unittest.skipUnless(not utils.BITCOIN_ONLY, "altcoin")
class TestBinanceSign(unittest.TestCase):
def test_order_signature(self):