1
0
mirror of https://github.com/trezor/trezor-firmware.git synced 2024-11-27 01:48:17 +00:00

apps/wallet: sign & verify message layouts

This commit is contained in:
Jan Pochyla 2018-02-06 14:07:46 +01:00
parent 8b49e04ade
commit bd44eceeef
3 changed files with 63 additions and 43 deletions

View File

@ -1,15 +1,26 @@
from micropython import const
from trezor.crypto.hashlib import sha256 from trezor.crypto.hashlib import sha256
from trezor.utils import chunks
from apps.wallet.sign_tx.signing import write_varint
from apps.common.hash_writer import HashWriter from apps.common.hash_writer import HashWriter
from apps.wallet.sign_tx.signing import write_varint
def message_digest(coin, message): def message_digest(coin, message):
h = HashWriter(sha256) h = HashWriter(sha256)
write_varint(h, len(coin.signed_message_header)) write_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_varint(h, len(message))
h.extend(message) h.extend(message)
return sha256(h.get_digest()).digest() return sha256(h.get_digest()).digest()
def split_message(message):
chars_per_line = const(18)
message = stringify_message(message)
lines = chunks(message, chars_per_line)
return lines
def stringify_message(message):
# TODO: account for invalid UTF-8 sequences
return str(message, 'utf-8')

View File

@ -1,29 +1,32 @@
from trezor import ui from trezor import ui
async def layout_sign_message(ctx, msg):
from trezor.messages.MessageSignature import MessageSignature
from trezor.crypto.curve import secp256k1 from trezor.crypto.curve import secp256k1
from ..common import coins from trezor.messages.MessageSignature import MessageSignature
from ..common import seed from trezor.ui.text import Text
from ..common.signverify import message_digest from apps.common import coins, seed
from apps.common.confirm import require_confirm
from apps.common.signverify import message_digest, split_message
ui.display.clear()
ui.display.text(10, 30, 'Signing message',
ui.BOLD, ui.LIGHT_GREEN, ui.BG)
ui.display.text(10, 60, msg.message, ui.MONO, ui.FG, ui.BG)
async def sign_message(ctx, msg):
message = msg.message
address_n = msg.address_n
coin_name = msg.coin_name or 'Bitcoin' coin_name = msg.coin_name or 'Bitcoin'
coin = coins.by_name(coin_name) coin = coins.by_name(coin_name)
await confirm_sign_message(ctx, message)
node = await seed.get_root(ctx) node = await seed.get_root(ctx)
node.derive_path(msg.address_n) node.derive_path(address_n)
seckey = node.private_key() seckey = node.private_key()
address = node.address(coin.address_type) address = node.address(coin.address_type)
digest = message_digest(coin, message)
digest = message_digest(coin, msg.message)
signature = secp256k1.sign(seckey, digest) signature = secp256k1.sign(seckey, digest)
return MessageSignature(address=address, signature=signature) return MessageSignature(address=address, signature=signature)
async def confirm_sign_message(ctx, message):
message = split_message(message)
content = Text('Sign message', ui.ICON_CONFIRM, ui.MONO, *message)
await require_confirm(ctx, content)

View File

@ -1,35 +1,41 @@
from trezor import ui from trezor import ui, wire
from trezor.crypto import base58
async def layout_verify_message(ctx, msg):
from trezor.messages.Success import Success
from trezor.crypto.curve import secp256k1 from trezor.crypto.curve import secp256k1
from trezor.crypto.hashlib import ripemd160, sha256 from trezor.crypto.hashlib import ripemd160, sha256
from trezor.crypto import base58 from trezor.messages.FailureType import ProcessError
from ..common import address_type from trezor.messages.Success import Success
from ..common import coins from trezor.ui.text import Text
from ..common.signverify import message_digest from apps.common import address_type, coins
from apps.common.confirm import require_confirm
from apps.common.signverify import message_digest, split_message
async def verify_message(ctx, msg):
message = msg.message
address = msg.address
signature = msg.signature
coin_name = msg.coin_name or 'Bitcoin' coin_name = msg.coin_name or 'Bitcoin'
coin = coins.by_name(coin_name) coin = coins.by_name(coin_name)
digest = message_digest(coin, msg.message) await confirm_verify_message(ctx, message)
pubkey = secp256k1.verify_recover(msg.signature, digest)
digest = message_digest(coin, message)
pubkey = secp256k1.verify_recover(signature, digest)
if not pubkey: if not pubkey:
raise ValueError('Invalid signature') raise wire.FailureError(ProcessError, 'Invalid signature')
raw_address = base58.decode_check(msg.address) raw_address = base58.decode_check(address)
at, pkh = address_type.split(coin, raw_address) _, pkh = address_type.split(coin, raw_address)
pkh2 = ripemd160(sha256(pubkey).digest()).digest() pkh2 = ripemd160(sha256(pubkey).digest()).digest()
if pkh != pkh2: if pkh != pkh2:
raise ValueError('Invalid signature') raise wire.FailureError(ProcessError, 'Invalid signature')
ui.display.clear()
ui.display.text(10, 30, 'Verifying message',
ui.BOLD, ui.LIGHT_GREEN, ui.BG)
ui.display.text(10, 60, msg.message, ui.MONO, ui.FG, ui.BG)
ui.display.text(10, 80, msg.address, ui.MONO, ui.FG, ui.BG)
return Success(message='Message verified') return Success(message='Message verified')
async def confirm_verify_message(ctx, message):
message = split_message(message)
content = Text('Verify message', ui.ICON_CONFIRM, ui.MONO, *message)
await require_confirm(ctx, content)