From 4de376acd68decf9dfe3d247bec15f7a6c65e6c4 Mon Sep 17 00:00:00 2001 From: Pavol Rusnak Date: Fri, 25 May 2018 14:35:42 +0200 Subject: [PATCH] src/apps/ethereum: implement SignMessage/VerifyMessage --- src/apps/ethereum/__init__.py | 7 +++--- src/apps/ethereum/sign_message.py | 29 +++++++++++++++--------- src/apps/ethereum/verify_message.py | 34 +++++++++++++++++++---------- 3 files changed, 45 insertions(+), 25 deletions(-) diff --git a/src/apps/ethereum/__init__.py b/src/apps/ethereum/__init__.py index 575d647b51..5d0cba75de 100644 --- a/src/apps/ethereum/__init__.py +++ b/src/apps/ethereum/__init__.py @@ -1,6 +1,6 @@ from trezor.wire import register, protobuf_workflow from trezor.messages.wire_types import EthereumGetAddress, EthereumSignTx -# from trezor.messages.wire_types import EthereumSignMessage, EthereumVerifyMessage +from trezor.messages.wire_types import EthereumSignMessage, EthereumVerifyMessage def dispatch_EthereumGetAddress(*args, **kwargs): @@ -26,6 +26,5 @@ def dispatch_EthereumVerifyMessage(*args, **kwargs): def boot(): register(EthereumGetAddress, protobuf_workflow, dispatch_EthereumGetAddress) register(EthereumSignTx, protobuf_workflow, dispatch_EthereumSignTx) - # TODO: re-enable once https://github.com/ethereum/EIPs/pull/712 is accepted/implemented - # register(EthereumSignMessage, protobuf_workflow, dispatch_EthereumSignMessage) - # register(EthereumVerifyMessage, protobuf_workflow, dispatch_EthereumVerifyMessage) + register(EthereumSignMessage, protobuf_workflow, dispatch_EthereumSignMessage) + register(EthereumVerifyMessage, protobuf_workflow, dispatch_EthereumVerifyMessage) diff --git a/src/apps/ethereum/sign_message.py b/src/apps/ethereum/sign_message.py index 647caa6dc4..45076c0289 100644 --- a/src/apps/ethereum/sign_message.py +++ b/src/apps/ethereum/sign_message.py @@ -1,25 +1,28 @@ -# TODO: not currently enabled, waits for https://github.com/ethereum/EIPs/pull/712 +from trezor import ui +from trezor.crypto.hashlib import sha3_256 +from trezor.utils import HashWriter +from trezor.messages.EthereumMessageSignature import EthereumMessageSignature +from trezor.ui.text import Text +from trezor.crypto.curve import secp256k1 +from apps.common import seed +from apps.common.confirm import require_confirm +from apps.common.signverify import split_message def message_digest(message): - from apps.wallet.sign_tx.signing import write_varint - from trezor.crypto.hashlib import sha3_256 - from trezor.utils import HashWriter h = HashWriter(sha3_256) - signed_message_header = 'Ethereum Signed Message:\n' - write_varint(h, len(signed_message_header)) + signed_message_header = '\x19Ethereum Signed Message:\n' h.extend(signed_message_header) - write_varint(h, len(message)) + h.extend(str(len(message))) h.extend(message) return h.get_digest(True) async def ethereum_sign_message(ctx, msg): - from trezor.messages.EthereumMessageSignature import EthereumMessageSignature - from trezor.crypto.curve import secp256k1 - from ..common import seed + + await require_confirm_sign_message(ctx, msg.message) address_n = msg.address_n or () node = await seed.derive_node(ctx, address_n) @@ -30,3 +33,9 @@ async def ethereum_sign_message(ctx, msg): sig.address = node.ethereum_pubkeyhash() sig.signature = signature[1:] + bytearray([signature[0]]) return sig + + +async def require_confirm_sign_message(ctx, message): + message = split_message(message) + content = Text('Sign ETH message', ui.ICON_DEFAULT, max_lines=5, *message) + await require_confirm(ctx, content) diff --git a/src/apps/ethereum/verify_message.py b/src/apps/ethereum/verify_message.py index 452faa032e..92d4e067e5 100644 --- a/src/apps/ethereum/verify_message.py +++ b/src/apps/ethereum/verify_message.py @@ -1,12 +1,16 @@ -# TODO: not currently enabled, waits for https://github.com/ethereum/EIPs/pull/712 +from ubinascii import hexlify +from trezor.crypto.curve import secp256k1 +from trezor.crypto.hashlib import sha3_256 +from trezor import ui +from trezor.ui.text import Text +from trezor.messages.Success import Success +from apps.common.confirm import require_confirm +from apps.common.signverify import split_message +from apps.ethereum.sign_message import message_digest +from apps.wallet.get_address import _split_address async def ethereum_verify_message(ctx, msg): - from .sign_message import message_digest - from trezor.crypto.curve import secp256k1 - from trezor.crypto.hashlib import sha3_256 - from trezor import ui - from trezor.messages.Success import Success digest = message_digest(msg.message) sig = bytearray([msg.signature[64]]) + msg.signature[:64] @@ -20,10 +24,18 @@ async def ethereum_verify_message(ctx, msg): if msg.address != pkh: raise ValueError('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) + address = '0x' + hexlify(msg.address).decode() + + await require_confirm_verify_message(ctx, address, msg.message) return Success(message='Message verified') + + +async def require_confirm_verify_message(ctx, address, message): + lines = _split_address(address) + content = Text('Confirm address', ui.ICON_DEFAULT, ui.MONO, *lines) + await require_confirm(ctx, content) + + message = split_message(message) + content = Text('Verify message', ui.ICON_DEFAULT, max_lines=5, *message) + await require_confirm(ctx, content)