mirror of
https://github.com/trezor/trezor-firmware.git
synced 2024-11-21 23:18:13 +00:00
apps.ethereum: implement SignMessage/VerifyMessage
This commit is contained in:
parent
e47aa9f0c4
commit
d6593e710b
1
.gitignore
vendored
1
.gitignore
vendored
@ -1,3 +1,4 @@
|
||||
.cache/
|
||||
*.pyc
|
||||
.sconsign.dblite
|
||||
.vscode/
|
||||
|
@ -24,7 +24,8 @@ CPPPATH_MOD += [
|
||||
CPPDEFINES_MOD += [
|
||||
'AES_128',
|
||||
'AES_192',
|
||||
'USE_KECCAK',
|
||||
('USE_KECCAK', '1'),
|
||||
('USE_ETHEREUM', '1'),
|
||||
]
|
||||
SOURCE_MOD += [
|
||||
'embed/extmod/modtrezorcrypto/modtrezorcrypto.c',
|
||||
|
@ -25,7 +25,8 @@ CPPPATH_MOD += [
|
||||
CPPDEFINES_MOD += [
|
||||
'AES_128',
|
||||
'AES_192',
|
||||
'USE_KECCAK',
|
||||
('USE_KECCAK', '1'),
|
||||
('USE_ETHEREUM', '1'),
|
||||
]
|
||||
SOURCE_MOD += [
|
||||
'embed/extmod/modtrezorcrypto/modtrezorcrypto.c',
|
||||
|
@ -298,6 +298,21 @@ STATIC mp_obj_t mod_trezorcrypto_HDNode_address(mp_obj_t self, mp_obj_t version)
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_2(mod_trezorcrypto_HDNode_address_obj, mod_trezorcrypto_HDNode_address);
|
||||
|
||||
/// def ethereum_pubkeyhash(self) -> bytes:
|
||||
/// '''
|
||||
/// Compute an Ethereum pubkeyhash (aka address) from the HD node.
|
||||
/// '''
|
||||
STATIC mp_obj_t mod_trezorcrypto_HDNode_ethereum_pubkeyhash(mp_obj_t self) {
|
||||
mp_obj_HDNode_t *o = MP_OBJ_TO_PTR(self);
|
||||
|
||||
vstr_t vstr;
|
||||
vstr_init_len(&vstr, 20);
|
||||
|
||||
hdnode_get_ethereum_pubkeyhash(&o->hdnode, (uint8_t *)vstr.buf);
|
||||
return mp_obj_new_str_from_vstr(&mp_type_bytes, &vstr);
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(mod_trezorcrypto_HDNode_ethereum_pubkeyhash_obj, mod_trezorcrypto_HDNode_ethereum_pubkeyhash);
|
||||
|
||||
STATIC const mp_rom_map_elem_t mod_trezorcrypto_HDNode_locals_dict_table[] = {
|
||||
{ MP_ROM_QSTR(MP_QSTR_derive), MP_ROM_PTR(&mod_trezorcrypto_HDNode_derive_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_derive_path), MP_ROM_PTR(&mod_trezorcrypto_HDNode_derive_path_obj) },
|
||||
@ -312,6 +327,7 @@ STATIC const mp_rom_map_elem_t mod_trezorcrypto_HDNode_locals_dict_table[] = {
|
||||
{ MP_ROM_QSTR(MP_QSTR_private_key), MP_ROM_PTR(&mod_trezorcrypto_HDNode_private_key_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_public_key), MP_ROM_PTR(&mod_trezorcrypto_HDNode_public_key_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_address), MP_ROM_PTR(&mod_trezorcrypto_HDNode_address_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_ethereum_pubkeyhash), MP_ROM_PTR(&mod_trezorcrypto_HDNode_ethereum_pubkeyhash_obj) },
|
||||
};
|
||||
STATIC MP_DEFINE_CONST_DICT(mod_trezorcrypto_HDNode_locals_dict, mod_trezorcrypto_HDNode_locals_dict_table);
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
from trezor.wire import register, protobuf_workflow
|
||||
from trezor.utils import unimport
|
||||
from trezor.messages.wire_types import \
|
||||
EthereumGetAddress, EthereumSignTx
|
||||
EthereumGetAddress, EthereumSignTx, EthereumSignMessage, EthereumVerifyMessage
|
||||
|
||||
|
||||
@unimport
|
||||
@ -16,6 +16,20 @@ def dispatch_EthereumSignTx(*args, **kwargs):
|
||||
return ethereum_sign_tx(*args, **kwargs)
|
||||
|
||||
|
||||
@unimport
|
||||
def dispatch_EthereumSignMessage(*args, **kwargs):
|
||||
from .sign_message import ethereum_sign_message
|
||||
return ethereum_sign_message(*args, **kwargs)
|
||||
|
||||
|
||||
@unimport
|
||||
def dispatch_EthereumVerifyMessage(*args, **kwargs):
|
||||
from .verify_message import ethereum_verify_message
|
||||
return ethereum_verify_message(*args, **kwargs)
|
||||
|
||||
|
||||
def boot():
|
||||
register(EthereumGetAddress, protobuf_workflow, dispatch_EthereumGetAddress)
|
||||
register(EthereumSignTx, protobuf_workflow, dispatch_EthereumSignTx)
|
||||
register(EthereumSignMessage, protobuf_workflow, dispatch_EthereumSignMessage)
|
||||
register(EthereumVerifyMessage, protobuf_workflow, dispatch_EthereumVerifyMessage)
|
||||
|
34
src/apps/ethereum/sign_message.py
Normal file
34
src/apps/ethereum/sign_message.py
Normal file
@ -0,0 +1,34 @@
|
||||
from trezor.utils import unimport
|
||||
|
||||
|
||||
def message_digest(message):
|
||||
from apps.wallet.sign_tx.signing import write_varint
|
||||
from trezor.crypto.hashlib import sha3_256
|
||||
from apps.common.hash_writer import HashWriter
|
||||
|
||||
h = HashWriter(sha3_256)
|
||||
signed_message_header = 'Ethereum Signed Message:\n'
|
||||
write_varint(h, len(signed_message_header))
|
||||
h.extend(signed_message_header)
|
||||
write_varint(h, len(message))
|
||||
h.extend(message)
|
||||
|
||||
return h.get_digest(True)
|
||||
|
||||
|
||||
@unimport
|
||||
async def ethereum_sign_message(ctx, msg):
|
||||
from trezor.messages.EthereumMessageSignature import EthereumMessageSignature
|
||||
from trezor.crypto.curve import secp256k1
|
||||
from ..common import seed
|
||||
|
||||
address_n = msg.address_n or ()
|
||||
node = await seed.get_root(ctx)
|
||||
node.derive_path(address_n)
|
||||
|
||||
signature = secp256k1.sign(node.private_key(), message_digest(msg.message), False)
|
||||
|
||||
sig = EthereumMessageSignature()
|
||||
sig.address = node.ethereum_pubkeyhash()
|
||||
sig.signature = signature[1:] + bytearray([signature[0]])
|
||||
return sig
|
30
src/apps/ethereum/verify_message.py
Normal file
30
src/apps/ethereum/verify_message.py
Normal file
@ -0,0 +1,30 @@
|
||||
from trezor.utils import unimport
|
||||
|
||||
|
||||
@unimport
|
||||
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]
|
||||
pubkey = secp256k1.verify_recover(sig, digest)
|
||||
|
||||
if not pubkey:
|
||||
raise ValueError('Invalid signature')
|
||||
|
||||
pkh = sha3_256(pubkey[1:]).digest(True)[-20:]
|
||||
|
||||
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)
|
||||
|
||||
return Success(message='Message verified')
|
1
tests/.gitignore
vendored
1
tests/.gitignore
vendored
@ -1 +0,0 @@
|
||||
.cache/
|
Loading…
Reference in New Issue
Block a user