1
0
mirror of https://github.com/trezor/trezor-firmware.git synced 2024-11-13 19:18:56 +00:00

lisk: restore Lisk sign and verify message functionality

This commit is contained in:
Aleksey Popov 2018-06-06 23:50:27 +03:00 committed by matejcik
parent 435ab2f973
commit 922748e348
9 changed files with 202 additions and 0 deletions

View File

@ -911,6 +911,33 @@ def lisk_sign_tx(connect, address, file):
return payload
@cli.command(help='Sign message with Lisk address.')
@click.option('-n', '--address', required=True, help="BIP-32 path, e.g. m/44'/134'/0'/0'")
@click.argument('message')
@click.pass_obj
def lisk_sign_message(connect, address, message):
client = connect()
address_n = client.expand_path(address)
res = client.lisk_sign_message(address_n, message)
output = {
"message": message,
"public_key": binascii.hexlify(res.public_key).decode(),
"signature": binascii.hexlify(res.signature).decode()
}
return output
@cli.command(help='Verify message signed with Lisk address.')
@click.argument('pubkey')
@click.argument('signature')
@click.argument('message')
@click.pass_obj
def lisk_verify_message(connect, pubkey, signature, message):
signature = bytes.fromhex(signature)
pubkey = bytes.fromhex(pubkey)
return connect().lisk_verify_message(pubkey, signature, message)
#
# CoSi functions
#

View File

@ -559,6 +559,20 @@ class ProtocolMixin(object):
n = self._convert_prime(n)
return self.call(proto.LiskGetPublicKey(address_n=n, show_display=show_display))
@expect(proto.LiskMessageSignature)
def lisk_sign_message(self, n, message):
n = self._convert_prime(n)
message = normalize_nfc(message)
return self.call(proto.LiskSignMessage(address_n=n, message=message))
def lisk_verify_message(self, pubkey, signature, message):
message = normalize_nfc(message)
try:
resp = self.call(proto.LiskVerifyMessage(signature=signature, public_key=pubkey, message=message))
except CallException as e:
resp = e
return isinstance(resp, proto.Success)
@expect(proto.LiskSignedTx)
def lisk_sign_tx(self, n, transaction):
n = self._convert_prime(n)

View File

@ -0,0 +1,18 @@
# Automatically generated by pb2py
from .. import protobuf as p
class LiskMessageSignature(p.MessageType):
MESSAGE_WIRE_TYPE = 119
FIELDS = {
1: ('public_key', p.BytesType, 0),
2: ('signature', p.BytesType, 0),
}
def __init__(
self,
public_key: bytes = None,
signature: bytes = None
) -> None:
self.public_key = public_key
self.signature = signature

View File

@ -0,0 +1,23 @@
# Automatically generated by pb2py
from .. import protobuf as p
if __debug__:
try:
from typing import List
except ImportError:
List = None
class LiskSignMessage(p.MessageType):
MESSAGE_WIRE_TYPE = 118
FIELDS = {
1: ('address_n', p.UVarintType, p.FLAG_REPEATED),
2: ('message', p.BytesType, 0),
}
def __init__(
self,
address_n: List[int] = None,
message: bytes = None
) -> None:
self.address_n = address_n if address_n is not None else []
self.message = message

View File

@ -0,0 +1,21 @@
# Automatically generated by pb2py
from .. import protobuf as p
class LiskVerifyMessage(p.MessageType):
MESSAGE_WIRE_TYPE = 120
FIELDS = {
1: ('signature', p.BytesType, 0),
2: ('public_key', p.BytesType, 0),
3: ('message', p.BytesType, 0),
}
def __init__(
self,
signature: bytes = None,
public_key: bytes = None,
message: bytes = None
) -> None:
self.signature = signature
self.public_key = public_key
self.message = message

View File

@ -88,6 +88,9 @@ LiskGetAddress = 114
LiskAddress = 115
LiskSignTx = 116
LiskSignedTx = 117
LiskSignMessage = 118
LiskMessageSignature = 119
LiskVerifyMessage = 120
LiskGetPublicKey = 121
LiskPublicKey = 122
StellarGetPublicKey = 200

View File

@ -95,9 +95,12 @@ from .Initialize import Initialize
from .LiskAddress import LiskAddress
from .LiskGetAddress import LiskGetAddress
from .LiskGetPublicKey import LiskGetPublicKey
from .LiskMessageSignature import LiskMessageSignature
from .LiskPublicKey import LiskPublicKey
from .LiskSignMessage import LiskSignMessage
from .LiskSignTx import LiskSignTx
from .LiskSignedTx import LiskSignedTx
from .LiskVerifyMessage import LiskVerifyMessage
from .LoadDevice import LoadDevice
from .MessageSignature import MessageSignature
from .NEMAddress import NEMAddress

View File

@ -0,0 +1,38 @@
# This file is part of the TREZOR project.
#
# Copyright (C) 2016-2017 Pavol Rusnak <stick@satoshilabs.com>
#
# This library is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with this library. If not, see <http://www.gnu.org/licenses/>.
from binascii import hexlify
import pytest
from .common import TrezorTest
@pytest.mark.lisk
@pytest.mark.skip_t1
class TestMsgLiskSignmessage(TrezorTest):
def test_sign(self):
self.setup_mnemonic_nopin_nopassphrase()
sig = self.client.lisk_sign_message([2147483692, 2147483782, 2147483648, 2147483648], 'This is an example of a signed message.')
assert hexlify(sig.public_key) == b'eb56d7bbb5e8ea9269405f7a8527fe126023d1db2c973cfac6f760b60ae27294'
assert hexlify(sig.signature) == b'7858ae7cd52ea6d4b17e800ca60144423db5560bfd618b663ffbf26ab66758563df45cbffae8463db22dc285dd94309083b8c807776085b97d05374d79867d05'
def test_sign_long(self):
self.setup_mnemonic_nopin_nopassphrase()
sig = self.client.lisk_sign_message([2147483692, 2147483782, 2147483648], 'VeryLongMessage!' * 64)
assert hexlify(sig.public_key) == b'8bca6b65a1a877767b746ea0b3c4310d404aa113df99c1b554e1802d70185ab5'
assert hexlify(sig.signature) == b'458ca5896d0934866992268f7509b5e954d568b1251e20c19bd3149ee3c86ffb5a44d1c2a0abbb99a3ab4767272dbb0e419b4579e890a24919ebbbe6cc0f970f'

View File

@ -0,0 +1,55 @@
# This file is part of the TREZOR project.
#
# Copyright (C) 2016-2017 Pavol Rusnak <stick@satoshilabs.com>
#
# This library is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with this library. If not, see <http://www.gnu.org/licenses/>.
from binascii import unhexlify
import pytest
from .common import TrezorTest
from trezorlib import messages as proto
@pytest.mark.lisk
@pytest.mark.skip_t1
class TestMsgLiskVerifymessage(TrezorTest):
def test_verify(self):
self.setup_mnemonic_nopin_nopassphrase()
with self.client:
self.client.set_expected_responses([
proto.ButtonRequest(code=proto.ButtonRequestType.Other),
proto.ButtonRequest(code=proto.ButtonRequestType.Other),
proto.Success(message='Message verified')
])
self.client.lisk_verify_message(
unhexlify('eb56d7bbb5e8ea9269405f7a8527fe126023d1db2c973cfac6f760b60ae27294'),
unhexlify('7858ae7cd52ea6d4b17e800ca60144423db5560bfd618b663ffbf26ab66758563df45cbffae8463db22dc285dd94309083b8c807776085b97d05374d79867d05'),
'This is an example of a signed message.'
)
def test_verify_long(self):
self.setup_mnemonic_nopin_nopassphrase()
with self.client:
self.client.set_expected_responses([
proto.ButtonRequest(code=proto.ButtonRequestType.Other),
proto.ButtonRequest(code=proto.ButtonRequestType.Other),
proto.Success(message='Message verified')
])
self.client.lisk_verify_message(
unhexlify('8bca6b65a1a877767b746ea0b3c4310d404aa113df99c1b554e1802d70185ab5'),
unhexlify('458ca5896d0934866992268f7509b5e954d568b1251e20c19bd3149ee3c86ffb5a44d1c2a0abbb99a3ab4767272dbb0e419b4579e890a24919ebbbe6cc0f970f'),
'VeryLongMessage!' * 64
)