From 452ad41575120500f06f4ab312dd59a13ace8740 Mon Sep 17 00:00:00 2001 From: Aleksey Popov Date: Mon, 16 Apr 2018 22:43:28 +0300 Subject: [PATCH 01/16] common: update trezor-common submodule --- vendor/trezor-common | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vendor/trezor-common b/vendor/trezor-common index 66a85673ed..9abe3a7c69 160000 --- a/vendor/trezor-common +++ b/vendor/trezor-common @@ -1 +1 @@ -Subproject commit 66a85673ed303f2cf48bdb3d027adbc7e8464364 +Subproject commit 9abe3a7c69000cc7ee3cda2ec940193fa9d62e6c From 59e6e491110d320c081ab3a9675122168881c371 Mon Sep 17 00:00:00 2001 From: Aleksey Popov Date: Mon, 16 Apr 2018 22:45:19 +0300 Subject: [PATCH 02/16] protob: Generate new messages --- src/trezor/messages/ApplySettings.py | 3 ++ src/trezor/messages/LiskAddress.py | 17 ++++++ src/trezor/messages/LiskDelegateType.py | 16 ++++++ src/trezor/messages/LiskGetAddress.py | 20 +++++++ src/trezor/messages/LiskGetPublicKey.py | 20 +++++++ src/trezor/messages/LiskMessageSignature.py | 20 +++++++ src/trezor/messages/LiskMultisignatureType.py | 22 ++++++++ src/trezor/messages/LiskPublicKey.py | 17 ++++++ src/trezor/messages/LiskSignMessage.py | 20 +++++++ src/trezor/messages/LiskSignTx.py | 21 ++++++++ src/trezor/messages/LiskSignatureType.py | 16 ++++++ src/trezor/messages/LiskSignedTx.py | 17 ++++++ src/trezor/messages/LiskTransactionAsset.py | 31 +++++++++++ src/trezor/messages/LiskTransactionCommon.py | 41 ++++++++++++++ src/trezor/messages/LiskTransactionType.py | 11 ++++ src/trezor/messages/LiskVerifyMessage.py | 23 ++++++++ src/trezor/messages/MessageType.py | 28 ++++++++++ src/trezor/messages/StellarAccountMergeOp.py | 20 +++++++ src/trezor/messages/StellarAllowTrustOp.py | 29 ++++++++++ src/trezor/messages/StellarAssetType.py | 22 ++++++++ src/trezor/messages/StellarBumpSequenceOp.py | 20 +++++++ src/trezor/messages/StellarChangeTrustOp.py | 24 +++++++++ src/trezor/messages/StellarCreateAccountOp.py | 23 ++++++++ .../messages/StellarCreatePassiveOfferOp.py | 33 ++++++++++++ src/trezor/messages/StellarGetPublicKey.py | 17 ++++++ src/trezor/messages/StellarManageDataOp.py | 23 ++++++++ src/trezor/messages/StellarManageOfferOp.py | 36 +++++++++++++ .../messages/StellarMessageSignature.py | 20 +++++++ src/trezor/messages/StellarPathPaymentOp.py | 36 +++++++++++++ src/trezor/messages/StellarPaymentOp.py | 27 ++++++++++ src/trezor/messages/StellarPublicKey.py | 17 ++++++ src/trezor/messages/StellarSetOptionsOp.py | 50 +++++++++++++++++ src/trezor/messages/StellarSignMessage.py | 20 +++++++ src/trezor/messages/StellarSignTx.py | 53 +++++++++++++++++++ src/trezor/messages/StellarSignedTx.py | 20 +++++++ src/trezor/messages/StellarTxOpRequest.py | 12 +++++ src/trezor/messages/StellarVerifyMessage.py | 23 ++++++++ src/trezor/messages/wire_types.py | 28 ++++++++++ 38 files changed, 896 insertions(+) create mode 100644 src/trezor/messages/LiskAddress.py create mode 100644 src/trezor/messages/LiskDelegateType.py create mode 100644 src/trezor/messages/LiskGetAddress.py create mode 100644 src/trezor/messages/LiskGetPublicKey.py create mode 100644 src/trezor/messages/LiskMessageSignature.py create mode 100644 src/trezor/messages/LiskMultisignatureType.py create mode 100644 src/trezor/messages/LiskPublicKey.py create mode 100644 src/trezor/messages/LiskSignMessage.py create mode 100644 src/trezor/messages/LiskSignTx.py create mode 100644 src/trezor/messages/LiskSignatureType.py create mode 100644 src/trezor/messages/LiskSignedTx.py create mode 100644 src/trezor/messages/LiskTransactionAsset.py create mode 100644 src/trezor/messages/LiskTransactionCommon.py create mode 100644 src/trezor/messages/LiskTransactionType.py create mode 100644 src/trezor/messages/LiskVerifyMessage.py create mode 100644 src/trezor/messages/StellarAccountMergeOp.py create mode 100644 src/trezor/messages/StellarAllowTrustOp.py create mode 100644 src/trezor/messages/StellarAssetType.py create mode 100644 src/trezor/messages/StellarBumpSequenceOp.py create mode 100644 src/trezor/messages/StellarChangeTrustOp.py create mode 100644 src/trezor/messages/StellarCreateAccountOp.py create mode 100644 src/trezor/messages/StellarCreatePassiveOfferOp.py create mode 100644 src/trezor/messages/StellarGetPublicKey.py create mode 100644 src/trezor/messages/StellarManageDataOp.py create mode 100644 src/trezor/messages/StellarManageOfferOp.py create mode 100644 src/trezor/messages/StellarMessageSignature.py create mode 100644 src/trezor/messages/StellarPathPaymentOp.py create mode 100644 src/trezor/messages/StellarPaymentOp.py create mode 100644 src/trezor/messages/StellarPublicKey.py create mode 100644 src/trezor/messages/StellarSetOptionsOp.py create mode 100644 src/trezor/messages/StellarSignMessage.py create mode 100644 src/trezor/messages/StellarSignTx.py create mode 100644 src/trezor/messages/StellarSignedTx.py create mode 100644 src/trezor/messages/StellarTxOpRequest.py create mode 100644 src/trezor/messages/StellarVerifyMessage.py diff --git a/src/trezor/messages/ApplySettings.py b/src/trezor/messages/ApplySettings.py index c71136ca89..6f7d34c1b9 100644 --- a/src/trezor/messages/ApplySettings.py +++ b/src/trezor/messages/ApplySettings.py @@ -9,6 +9,7 @@ class ApplySettings(p.MessageType): 3: ('use_passphrase', p.BoolType, 0), 4: ('homescreen', p.BytesType, 0), 5: ('passphrase_source', p.UVarintType, 0), + 6: ('auto_lock_delay_ms', p.UVarintType, 0), } MESSAGE_WIRE_TYPE = 25 @@ -19,6 +20,7 @@ class ApplySettings(p.MessageType): use_passphrase: bool = None, homescreen: bytes = None, passphrase_source: int = None, + auto_lock_delay_ms: int = None, **kwargs, ): self.language = language @@ -26,4 +28,5 @@ class ApplySettings(p.MessageType): self.use_passphrase = use_passphrase self.homescreen = homescreen self.passphrase_source = passphrase_source + self.auto_lock_delay_ms = auto_lock_delay_ms p.MessageType.__init__(self, **kwargs) diff --git a/src/trezor/messages/LiskAddress.py b/src/trezor/messages/LiskAddress.py new file mode 100644 index 0000000000..22f694e3f9 --- /dev/null +++ b/src/trezor/messages/LiskAddress.py @@ -0,0 +1,17 @@ +# Automatically generated by pb2py +import protobuf as p + + +class LiskAddress(p.MessageType): + FIELDS = { + 1: ('address', p.UnicodeType, 0), + } + MESSAGE_WIRE_TYPE = 115 + + def __init__( + self, + address: str = None, + **kwargs, + ): + self.address = address + p.MessageType.__init__(self, **kwargs) diff --git a/src/trezor/messages/LiskDelegateType.py b/src/trezor/messages/LiskDelegateType.py new file mode 100644 index 0000000000..92351f93b5 --- /dev/null +++ b/src/trezor/messages/LiskDelegateType.py @@ -0,0 +1,16 @@ +# Automatically generated by pb2py +import protobuf as p + + +class LiskDelegateType(p.MessageType): + FIELDS = { + 1: ('username', p.UnicodeType, 0), + } + + def __init__( + self, + username: str = None, + **kwargs, + ): + self.username = username + p.MessageType.__init__(self, **kwargs) diff --git a/src/trezor/messages/LiskGetAddress.py b/src/trezor/messages/LiskGetAddress.py new file mode 100644 index 0000000000..99af409c01 --- /dev/null +++ b/src/trezor/messages/LiskGetAddress.py @@ -0,0 +1,20 @@ +# Automatically generated by pb2py +import protobuf as p + + +class LiskGetAddress(p.MessageType): + FIELDS = { + 1: ('address_n', p.UVarintType, p.FLAG_REPEATED), + 2: ('show_display', p.BoolType, 0), + } + MESSAGE_WIRE_TYPE = 114 + + def __init__( + self, + address_n: list = None, + show_display: bool = None, + **kwargs, + ): + self.address_n = [] if address_n is None else address_n + self.show_display = show_display + p.MessageType.__init__(self, **kwargs) diff --git a/src/trezor/messages/LiskGetPublicKey.py b/src/trezor/messages/LiskGetPublicKey.py new file mode 100644 index 0000000000..8b22b87697 --- /dev/null +++ b/src/trezor/messages/LiskGetPublicKey.py @@ -0,0 +1,20 @@ +# Automatically generated by pb2py +import protobuf as p + + +class LiskGetPublicKey(p.MessageType): + FIELDS = { + 1: ('address_n', p.UVarintType, p.FLAG_REPEATED), + 2: ('show_display', p.BoolType, 0), + } + MESSAGE_WIRE_TYPE = 121 + + def __init__( + self, + address_n: list = None, + show_display: bool = None, + **kwargs, + ): + self.address_n = [] if address_n is None else address_n + self.show_display = show_display + p.MessageType.__init__(self, **kwargs) diff --git a/src/trezor/messages/LiskMessageSignature.py b/src/trezor/messages/LiskMessageSignature.py new file mode 100644 index 0000000000..c74fa232b7 --- /dev/null +++ b/src/trezor/messages/LiskMessageSignature.py @@ -0,0 +1,20 @@ +# Automatically generated by pb2py +import protobuf as p + + +class LiskMessageSignature(p.MessageType): + FIELDS = { + 1: ('address', p.UnicodeType, 0), + 2: ('signature', p.BytesType, 0), + } + MESSAGE_WIRE_TYPE = 119 + + def __init__( + self, + address: str = None, + signature: bytes = None, + **kwargs, + ): + self.address = address + self.signature = signature + p.MessageType.__init__(self, **kwargs) diff --git a/src/trezor/messages/LiskMultisignatureType.py b/src/trezor/messages/LiskMultisignatureType.py new file mode 100644 index 0000000000..f863e62812 --- /dev/null +++ b/src/trezor/messages/LiskMultisignatureType.py @@ -0,0 +1,22 @@ +# Automatically generated by pb2py +import protobuf as p + + +class LiskMultisignatureType(p.MessageType): + FIELDS = { + 1: ('min', p.UVarintType, 0), + 2: ('life_time', p.UVarintType, 0), + 3: ('keys_group', p.UnicodeType, p.FLAG_REPEATED), + } + + def __init__( + self, + min: int = None, + life_time: int = None, + keys_group: list = None, + **kwargs, + ): + self.min = min + self.life_time = life_time + self.keys_group = [] if keys_group is None else keys_group + p.MessageType.__init__(self, **kwargs) diff --git a/src/trezor/messages/LiskPublicKey.py b/src/trezor/messages/LiskPublicKey.py new file mode 100644 index 0000000000..f33968ac31 --- /dev/null +++ b/src/trezor/messages/LiskPublicKey.py @@ -0,0 +1,17 @@ +# Automatically generated by pb2py +import protobuf as p + + +class LiskPublicKey(p.MessageType): + FIELDS = { + 1: ('public_key', p.BytesType, 0), + } + MESSAGE_WIRE_TYPE = 122 + + def __init__( + self, + public_key: bytes = None, + **kwargs, + ): + self.public_key = public_key + p.MessageType.__init__(self, **kwargs) diff --git a/src/trezor/messages/LiskSignMessage.py b/src/trezor/messages/LiskSignMessage.py new file mode 100644 index 0000000000..d473aec6cd --- /dev/null +++ b/src/trezor/messages/LiskSignMessage.py @@ -0,0 +1,20 @@ +# Automatically generated by pb2py +import protobuf as p + + +class LiskSignMessage(p.MessageType): + FIELDS = { + 1: ('address_n', p.UVarintType, p.FLAG_REPEATED), + 2: ('message', p.BytesType, 0), + } + MESSAGE_WIRE_TYPE = 118 + + def __init__( + self, + address_n: list = None, + message: bytes = None, + **kwargs, + ): + self.address_n = [] if address_n is None else address_n + self.message = message + p.MessageType.__init__(self, **kwargs) diff --git a/src/trezor/messages/LiskSignTx.py b/src/trezor/messages/LiskSignTx.py new file mode 100644 index 0000000000..5370d2e926 --- /dev/null +++ b/src/trezor/messages/LiskSignTx.py @@ -0,0 +1,21 @@ +# Automatically generated by pb2py +import protobuf as p +from .LiskTransactionCommon import LiskTransactionCommon + + +class LiskSignTx(p.MessageType): + FIELDS = { + 1: ('address_n', p.UVarintType, p.FLAG_REPEATED), + 2: ('transaction', LiskTransactionCommon, 0), + } + MESSAGE_WIRE_TYPE = 116 + + def __init__( + self, + address_n: list = None, + transaction: LiskTransactionCommon = None, + **kwargs, + ): + self.address_n = [] if address_n is None else address_n + self.transaction = transaction + p.MessageType.__init__(self, **kwargs) diff --git a/src/trezor/messages/LiskSignatureType.py b/src/trezor/messages/LiskSignatureType.py new file mode 100644 index 0000000000..8811b55808 --- /dev/null +++ b/src/trezor/messages/LiskSignatureType.py @@ -0,0 +1,16 @@ +# Automatically generated by pb2py +import protobuf as p + + +class LiskSignatureType(p.MessageType): + FIELDS = { + 1: ('public_key', p.BytesType, 0), + } + + def __init__( + self, + public_key: bytes = None, + **kwargs, + ): + self.public_key = public_key + p.MessageType.__init__(self, **kwargs) diff --git a/src/trezor/messages/LiskSignedTx.py b/src/trezor/messages/LiskSignedTx.py new file mode 100644 index 0000000000..ffb4c98806 --- /dev/null +++ b/src/trezor/messages/LiskSignedTx.py @@ -0,0 +1,17 @@ +# Automatically generated by pb2py +import protobuf as p + + +class LiskSignedTx(p.MessageType): + FIELDS = { + 1: ('signature', p.BytesType, 0), + } + MESSAGE_WIRE_TYPE = 117 + + def __init__( + self, + signature: bytes = None, + **kwargs, + ): + self.signature = signature + p.MessageType.__init__(self, **kwargs) diff --git a/src/trezor/messages/LiskTransactionAsset.py b/src/trezor/messages/LiskTransactionAsset.py new file mode 100644 index 0000000000..3c485a2216 --- /dev/null +++ b/src/trezor/messages/LiskTransactionAsset.py @@ -0,0 +1,31 @@ +# Automatically generated by pb2py +import protobuf as p +from .LiskDelegateType import LiskDelegateType +from .LiskMultisignatureType import LiskMultisignatureType +from .LiskSignatureType import LiskSignatureType + + +class LiskTransactionAsset(p.MessageType): + FIELDS = { + 1: ('signature', LiskSignatureType, 0), + 2: ('delegate', LiskDelegateType, 0), + 3: ('votes', p.UnicodeType, p.FLAG_REPEATED), + 4: ('multisignature', LiskMultisignatureType, 0), + 5: ('data', p.UnicodeType, 0), + } + + def __init__( + self, + signature: LiskSignatureType = None, + delegate: LiskDelegateType = None, + votes: list = None, + multisignature: LiskMultisignatureType = None, + data: str = None, + **kwargs, + ): + self.signature = signature + self.delegate = delegate + self.votes = [] if votes is None else votes + self.multisignature = multisignature + self.data = data + p.MessageType.__init__(self, **kwargs) diff --git a/src/trezor/messages/LiskTransactionCommon.py b/src/trezor/messages/LiskTransactionCommon.py new file mode 100644 index 0000000000..935266a89b --- /dev/null +++ b/src/trezor/messages/LiskTransactionCommon.py @@ -0,0 +1,41 @@ +# Automatically generated by pb2py +import protobuf as p +from .LiskTransactionAsset import LiskTransactionAsset + + +class LiskTransactionCommon(p.MessageType): + FIELDS = { + 1: ('type', p.UVarintType, 0), + 2: ('amount', p.UVarintType, 0), # default=0 + 3: ('fee', p.UVarintType, 0), + 4: ('recipient_id', p.UnicodeType, 0), + 5: ('sender_public_key', p.BytesType, 0), + 6: ('requester_public_key', p.BytesType, 0), + 7: ('signature', p.BytesType, 0), + 8: ('timestamp', p.UVarintType, 0), + 9: ('asset', LiskTransactionAsset, 0), + } + + def __init__( + self, + type: int = None, + amount: int = None, + fee: int = None, + recipient_id: str = None, + sender_public_key: bytes = None, + requester_public_key: bytes = None, + signature: bytes = None, + timestamp: int = None, + asset: LiskTransactionAsset = None, + **kwargs, + ): + self.type = type + self.amount = amount + self.fee = fee + self.recipient_id = recipient_id + self.sender_public_key = sender_public_key + self.requester_public_key = requester_public_key + self.signature = signature + self.timestamp = timestamp + self.asset = asset + p.MessageType.__init__(self, **kwargs) diff --git a/src/trezor/messages/LiskTransactionType.py b/src/trezor/messages/LiskTransactionType.py new file mode 100644 index 0000000000..9de0b22f81 --- /dev/null +++ b/src/trezor/messages/LiskTransactionType.py @@ -0,0 +1,11 @@ +# Automatically generated by pb2py +from micropython import const + +Transfer = const(0) +RegisterSecondPassphrase = const(1) +RegisterDelegate = const(2) +CastVotes = const(3) +RegisterMultisignatureAccount = const(4) +CreateDapp = const(5) +TransferIntoDapp = const(6) +TransferOutOfDapp = const(7) diff --git a/src/trezor/messages/LiskVerifyMessage.py b/src/trezor/messages/LiskVerifyMessage.py new file mode 100644 index 0000000000..a0808c859b --- /dev/null +++ b/src/trezor/messages/LiskVerifyMessage.py @@ -0,0 +1,23 @@ +# Automatically generated by pb2py +import protobuf as p + + +class LiskVerifyMessage(p.MessageType): + FIELDS = { + 1: ('signature', p.BytesType, 0), + 2: ('public_key', p.BytesType, 0), + 3: ('message', p.BytesType, 0), + } + MESSAGE_WIRE_TYPE = 120 + + def __init__( + self, + signature: bytes = None, + public_key: bytes = None, + message: bytes = None, + **kwargs, + ): + self.signature = signature + self.public_key = public_key + self.message = message + p.MessageType.__init__(self, **kwargs) diff --git a/src/trezor/messages/MessageType.py b/src/trezor/messages/MessageType.py index 1dff26cf72..d5503b733f 100644 --- a/src/trezor/messages/MessageType.py +++ b/src/trezor/messages/MessageType.py @@ -86,3 +86,31 @@ DebugLinkMemoryRead = const(110) DebugLinkMemory = const(111) DebugLinkMemoryWrite = const(112) DebugLinkFlashErase = const(113) +LiskGetAddress = const(114) +LiskAddress = const(115) +LiskSignTx = const(116) +LiskSignedTx = const(117) +LiskSignMessage = const(118) +LiskMessageSignature = const(119) +LiskVerifyMessage = const(120) +LiskGetPublicKey = const(121) +LiskPublicKey = const(122) +StellarGetPublicKey = const(200) +StellarPublicKey = const(201) +StellarSignTx = const(202) +StellarTxOpRequest = const(203) +StellarSignMessage = const(204) +StellarMessageSignature = const(205) +StellarVerifyMessage = const(206) +StellarCreateAccountOp = const(210) +StellarPaymentOp = const(211) +StellarPathPaymentOp = const(212) +StellarManageOfferOp = const(213) +StellarCreatePassiveOfferOp = const(214) +StellarSetOptionsOp = const(215) +StellarChangeTrustOp = const(216) +StellarAllowTrustOp = const(217) +StellarAccountMergeOp = const(218) +StellarManageDataOp = const(220) +StellarBumpSequenceOp = const(221) +StellarSignedTx = const(230) diff --git a/src/trezor/messages/StellarAccountMergeOp.py b/src/trezor/messages/StellarAccountMergeOp.py new file mode 100644 index 0000000000..e1b16820a4 --- /dev/null +++ b/src/trezor/messages/StellarAccountMergeOp.py @@ -0,0 +1,20 @@ +# Automatically generated by pb2py +import protobuf as p + + +class StellarAccountMergeOp(p.MessageType): + FIELDS = { + 1: ('source_account', p.BytesType, 0), + 2: ('destination_account', p.BytesType, 0), + } + MESSAGE_WIRE_TYPE = 218 + + def __init__( + self, + source_account: bytes = None, + destination_account: bytes = None, + **kwargs, + ): + self.source_account = source_account + self.destination_account = destination_account + p.MessageType.__init__(self, **kwargs) diff --git a/src/trezor/messages/StellarAllowTrustOp.py b/src/trezor/messages/StellarAllowTrustOp.py new file mode 100644 index 0000000000..0dcba61981 --- /dev/null +++ b/src/trezor/messages/StellarAllowTrustOp.py @@ -0,0 +1,29 @@ +# Automatically generated by pb2py +import protobuf as p + + +class StellarAllowTrustOp(p.MessageType): + FIELDS = { + 1: ('source_account', p.BytesType, 0), + 2: ('trusted_account', p.BytesType, 0), + 3: ('asset_type', p.UVarintType, 0), + 4: ('asset_code', p.UnicodeType, 0), + 5: ('is_authorized', p.UVarintType, 0), + } + MESSAGE_WIRE_TYPE = 217 + + def __init__( + self, + source_account: bytes = None, + trusted_account: bytes = None, + asset_type: int = None, + asset_code: str = None, + is_authorized: int = None, + **kwargs, + ): + self.source_account = source_account + self.trusted_account = trusted_account + self.asset_type = asset_type + self.asset_code = asset_code + self.is_authorized = is_authorized + p.MessageType.__init__(self, **kwargs) diff --git a/src/trezor/messages/StellarAssetType.py b/src/trezor/messages/StellarAssetType.py new file mode 100644 index 0000000000..a52c7e3069 --- /dev/null +++ b/src/trezor/messages/StellarAssetType.py @@ -0,0 +1,22 @@ +# Automatically generated by pb2py +import protobuf as p + + +class StellarAssetType(p.MessageType): + FIELDS = { + 1: ('type', p.UVarintType, 0), + 2: ('code', p.UnicodeType, 0), + 3: ('issuer', p.BytesType, 0), + } + + def __init__( + self, + type: int = None, + code: str = None, + issuer: bytes = None, + **kwargs, + ): + self.type = type + self.code = code + self.issuer = issuer + p.MessageType.__init__(self, **kwargs) diff --git a/src/trezor/messages/StellarBumpSequenceOp.py b/src/trezor/messages/StellarBumpSequenceOp.py new file mode 100644 index 0000000000..ab6f6e18c5 --- /dev/null +++ b/src/trezor/messages/StellarBumpSequenceOp.py @@ -0,0 +1,20 @@ +# Automatically generated by pb2py +import protobuf as p + + +class StellarBumpSequenceOp(p.MessageType): + FIELDS = { + 1: ('source_account', p.BytesType, 0), + 2: ('bump_to', p.UVarintType, 0), + } + MESSAGE_WIRE_TYPE = 221 + + def __init__( + self, + source_account: bytes = None, + bump_to: int = None, + **kwargs, + ): + self.source_account = source_account + self.bump_to = bump_to + p.MessageType.__init__(self, **kwargs) diff --git a/src/trezor/messages/StellarChangeTrustOp.py b/src/trezor/messages/StellarChangeTrustOp.py new file mode 100644 index 0000000000..dbb38cff82 --- /dev/null +++ b/src/trezor/messages/StellarChangeTrustOp.py @@ -0,0 +1,24 @@ +# Automatically generated by pb2py +import protobuf as p +from .StellarAssetType import StellarAssetType + + +class StellarChangeTrustOp(p.MessageType): + FIELDS = { + 1: ('source_account', p.BytesType, 0), + 2: ('asset', StellarAssetType, 0), + 3: ('limit', p.UVarintType, 0), + } + MESSAGE_WIRE_TYPE = 216 + + def __init__( + self, + source_account: bytes = None, + asset: StellarAssetType = None, + limit: int = None, + **kwargs, + ): + self.source_account = source_account + self.asset = asset + self.limit = limit + p.MessageType.__init__(self, **kwargs) diff --git a/src/trezor/messages/StellarCreateAccountOp.py b/src/trezor/messages/StellarCreateAccountOp.py new file mode 100644 index 0000000000..0ff7dd72cf --- /dev/null +++ b/src/trezor/messages/StellarCreateAccountOp.py @@ -0,0 +1,23 @@ +# Automatically generated by pb2py +import protobuf as p + + +class StellarCreateAccountOp(p.MessageType): + FIELDS = { + 1: ('source_account', p.BytesType, 0), + 2: ('new_account', p.BytesType, 0), + 3: ('starting_balance', p.Sint64Type, 0), + } + MESSAGE_WIRE_TYPE = 210 + + def __init__( + self, + source_account: bytes = None, + new_account: bytes = None, + starting_balance: int = None, + **kwargs, + ): + self.source_account = source_account + self.new_account = new_account + self.starting_balance = starting_balance + p.MessageType.__init__(self, **kwargs) diff --git a/src/trezor/messages/StellarCreatePassiveOfferOp.py b/src/trezor/messages/StellarCreatePassiveOfferOp.py new file mode 100644 index 0000000000..38cfeec497 --- /dev/null +++ b/src/trezor/messages/StellarCreatePassiveOfferOp.py @@ -0,0 +1,33 @@ +# Automatically generated by pb2py +import protobuf as p +from .StellarAssetType import StellarAssetType + + +class StellarCreatePassiveOfferOp(p.MessageType): + FIELDS = { + 1: ('source_account', p.BytesType, 0), + 2: ('selling_asset', StellarAssetType, 0), + 3: ('buying_asset', StellarAssetType, 0), + 4: ('amount', p.Sint64Type, 0), + 5: ('price_n', p.UVarintType, 0), + 6: ('price_d', p.UVarintType, 0), + } + MESSAGE_WIRE_TYPE = 214 + + def __init__( + self, + source_account: bytes = None, + selling_asset: StellarAssetType = None, + buying_asset: StellarAssetType = None, + amount: int = None, + price_n: int = None, + price_d: int = None, + **kwargs, + ): + self.source_account = source_account + self.selling_asset = selling_asset + self.buying_asset = buying_asset + self.amount = amount + self.price_n = price_n + self.price_d = price_d + p.MessageType.__init__(self, **kwargs) diff --git a/src/trezor/messages/StellarGetPublicKey.py b/src/trezor/messages/StellarGetPublicKey.py new file mode 100644 index 0000000000..ddce95e539 --- /dev/null +++ b/src/trezor/messages/StellarGetPublicKey.py @@ -0,0 +1,17 @@ +# Automatically generated by pb2py +import protobuf as p + + +class StellarGetPublicKey(p.MessageType): + FIELDS = { + 1: ('address_n', p.UVarintType, p.FLAG_REPEATED), + } + MESSAGE_WIRE_TYPE = 200 + + def __init__( + self, + address_n: list = None, + **kwargs, + ): + self.address_n = [] if address_n is None else address_n + p.MessageType.__init__(self, **kwargs) diff --git a/src/trezor/messages/StellarManageDataOp.py b/src/trezor/messages/StellarManageDataOp.py new file mode 100644 index 0000000000..1871c84fac --- /dev/null +++ b/src/trezor/messages/StellarManageDataOp.py @@ -0,0 +1,23 @@ +# Automatically generated by pb2py +import protobuf as p + + +class StellarManageDataOp(p.MessageType): + FIELDS = { + 1: ('source_account', p.BytesType, 0), + 2: ('key', p.UnicodeType, 0), + 3: ('value', p.BytesType, 0), + } + MESSAGE_WIRE_TYPE = 220 + + def __init__( + self, + source_account: bytes = None, + key: str = None, + value: bytes = None, + **kwargs, + ): + self.source_account = source_account + self.key = key + self.value = value + p.MessageType.__init__(self, **kwargs) diff --git a/src/trezor/messages/StellarManageOfferOp.py b/src/trezor/messages/StellarManageOfferOp.py new file mode 100644 index 0000000000..9daac495e4 --- /dev/null +++ b/src/trezor/messages/StellarManageOfferOp.py @@ -0,0 +1,36 @@ +# Automatically generated by pb2py +import protobuf as p +from .StellarAssetType import StellarAssetType + + +class StellarManageOfferOp(p.MessageType): + FIELDS = { + 1: ('source_account', p.BytesType, 0), + 2: ('selling_asset', StellarAssetType, 0), + 3: ('buying_asset', StellarAssetType, 0), + 4: ('amount', p.Sint64Type, 0), + 5: ('price_n', p.UVarintType, 0), + 6: ('price_d', p.UVarintType, 0), + 7: ('offer_id', p.UVarintType, 0), + } + MESSAGE_WIRE_TYPE = 213 + + def __init__( + self, + source_account: bytes = None, + selling_asset: StellarAssetType = None, + buying_asset: StellarAssetType = None, + amount: int = None, + price_n: int = None, + price_d: int = None, + offer_id: int = None, + **kwargs, + ): + self.source_account = source_account + self.selling_asset = selling_asset + self.buying_asset = buying_asset + self.amount = amount + self.price_n = price_n + self.price_d = price_d + self.offer_id = offer_id + p.MessageType.__init__(self, **kwargs) diff --git a/src/trezor/messages/StellarMessageSignature.py b/src/trezor/messages/StellarMessageSignature.py new file mode 100644 index 0000000000..23e2a1d118 --- /dev/null +++ b/src/trezor/messages/StellarMessageSignature.py @@ -0,0 +1,20 @@ +# Automatically generated by pb2py +import protobuf as p + + +class StellarMessageSignature(p.MessageType): + FIELDS = { + 1: ('public_key', p.BytesType, 0), + 2: ('signature', p.BytesType, 0), + } + MESSAGE_WIRE_TYPE = 205 + + def __init__( + self, + public_key: bytes = None, + signature: bytes = None, + **kwargs, + ): + self.public_key = public_key + self.signature = signature + p.MessageType.__init__(self, **kwargs) diff --git a/src/trezor/messages/StellarPathPaymentOp.py b/src/trezor/messages/StellarPathPaymentOp.py new file mode 100644 index 0000000000..4e09f0dd00 --- /dev/null +++ b/src/trezor/messages/StellarPathPaymentOp.py @@ -0,0 +1,36 @@ +# Automatically generated by pb2py +import protobuf as p +from .StellarAssetType import StellarAssetType + + +class StellarPathPaymentOp(p.MessageType): + FIELDS = { + 1: ('source_account', p.BytesType, 0), + 2: ('send_asset', StellarAssetType, 0), + 3: ('send_max', p.Sint64Type, 0), + 4: ('destination_account', p.BytesType, 0), + 5: ('destination_asset', StellarAssetType, 0), + 6: ('destination_amount', p.Sint64Type, 0), + 7: ('paths', StellarAssetType, p.FLAG_REPEATED), + } + MESSAGE_WIRE_TYPE = 212 + + def __init__( + self, + source_account: bytes = None, + send_asset: StellarAssetType = None, + send_max: int = None, + destination_account: bytes = None, + destination_asset: StellarAssetType = None, + destination_amount: int = None, + paths: list = None, + **kwargs, + ): + self.source_account = source_account + self.send_asset = send_asset + self.send_max = send_max + self.destination_account = destination_account + self.destination_asset = destination_asset + self.destination_amount = destination_amount + self.paths = [] if paths is None else paths + p.MessageType.__init__(self, **kwargs) diff --git a/src/trezor/messages/StellarPaymentOp.py b/src/trezor/messages/StellarPaymentOp.py new file mode 100644 index 0000000000..ee621aeac1 --- /dev/null +++ b/src/trezor/messages/StellarPaymentOp.py @@ -0,0 +1,27 @@ +# Automatically generated by pb2py +import protobuf as p +from .StellarAssetType import StellarAssetType + + +class StellarPaymentOp(p.MessageType): + FIELDS = { + 1: ('source_account', p.BytesType, 0), + 2: ('destination_account', p.BytesType, 0), + 3: ('asset', StellarAssetType, 0), + 4: ('amount', p.Sint64Type, 0), + } + MESSAGE_WIRE_TYPE = 211 + + def __init__( + self, + source_account: bytes = None, + destination_account: bytes = None, + asset: StellarAssetType = None, + amount: int = None, + **kwargs, + ): + self.source_account = source_account + self.destination_account = destination_account + self.asset = asset + self.amount = amount + p.MessageType.__init__(self, **kwargs) diff --git a/src/trezor/messages/StellarPublicKey.py b/src/trezor/messages/StellarPublicKey.py new file mode 100644 index 0000000000..c09c55fb7c --- /dev/null +++ b/src/trezor/messages/StellarPublicKey.py @@ -0,0 +1,17 @@ +# Automatically generated by pb2py +import protobuf as p + + +class StellarPublicKey(p.MessageType): + FIELDS = { + 1: ('public_key', p.BytesType, 0), + } + MESSAGE_WIRE_TYPE = 201 + + def __init__( + self, + public_key: bytes = None, + **kwargs, + ): + self.public_key = public_key + p.MessageType.__init__(self, **kwargs) diff --git a/src/trezor/messages/StellarSetOptionsOp.py b/src/trezor/messages/StellarSetOptionsOp.py new file mode 100644 index 0000000000..9e7bd11cb5 --- /dev/null +++ b/src/trezor/messages/StellarSetOptionsOp.py @@ -0,0 +1,50 @@ +# Automatically generated by pb2py +import protobuf as p + + +class StellarSetOptionsOp(p.MessageType): + FIELDS = { + 1: ('source_account', p.BytesType, 0), + 2: ('inflation_destination_account', p.BytesType, 0), + 3: ('clear_flags', p.UVarintType, 0), + 4: ('set_flags', p.UVarintType, 0), + 5: ('master_weight', p.UVarintType, 0), + 6: ('low_threshold', p.UVarintType, 0), + 7: ('medium_threshold', p.UVarintType, 0), + 8: ('high_threshold', p.UVarintType, 0), + 9: ('home_domain', p.UnicodeType, 0), + 10: ('signer_type', p.UVarintType, 0), + 11: ('signer_key', p.BytesType, 0), + 12: ('signer_weight', p.UVarintType, 0), + } + MESSAGE_WIRE_TYPE = 215 + + def __init__( + self, + source_account: bytes = None, + inflation_destination_account: bytes = None, + clear_flags: int = None, + set_flags: int = None, + master_weight: int = None, + low_threshold: int = None, + medium_threshold: int = None, + high_threshold: int = None, + home_domain: str = None, + signer_type: int = None, + signer_key: bytes = None, + signer_weight: int = None, + **kwargs, + ): + self.source_account = source_account + self.inflation_destination_account = inflation_destination_account + self.clear_flags = clear_flags + self.set_flags = set_flags + self.master_weight = master_weight + self.low_threshold = low_threshold + self.medium_threshold = medium_threshold + self.high_threshold = high_threshold + self.home_domain = home_domain + self.signer_type = signer_type + self.signer_key = signer_key + self.signer_weight = signer_weight + p.MessageType.__init__(self, **kwargs) diff --git a/src/trezor/messages/StellarSignMessage.py b/src/trezor/messages/StellarSignMessage.py new file mode 100644 index 0000000000..d71890bee3 --- /dev/null +++ b/src/trezor/messages/StellarSignMessage.py @@ -0,0 +1,20 @@ +# Automatically generated by pb2py +import protobuf as p + + +class StellarSignMessage(p.MessageType): + FIELDS = { + 1: ('address_n', p.UVarintType, p.FLAG_REPEATED), + 2: ('message', p.UnicodeType, 0), + } + MESSAGE_WIRE_TYPE = 204 + + def __init__( + self, + address_n: list = None, + message: str = None, + **kwargs, + ): + self.address_n = [] if address_n is None else address_n + self.message = message + p.MessageType.__init__(self, **kwargs) diff --git a/src/trezor/messages/StellarSignTx.py b/src/trezor/messages/StellarSignTx.py new file mode 100644 index 0000000000..5e99f1fae2 --- /dev/null +++ b/src/trezor/messages/StellarSignTx.py @@ -0,0 +1,53 @@ +# Automatically generated by pb2py +import protobuf as p + + +class StellarSignTx(p.MessageType): + FIELDS = { + 1: ('protocol_version', p.UVarintType, 0), + 2: ('address_n', p.UVarintType, p.FLAG_REPEATED), + 3: ('network_passphrase', p.UnicodeType, 0), + 4: ('source_account', p.BytesType, 0), + 5: ('fee', p.UVarintType, 0), + 6: ('sequence_number', p.UVarintType, 0), + 8: ('timebounds_start', p.UVarintType, 0), + 9: ('timebounds_end', p.UVarintType, 0), + 10: ('memo_type', p.UVarintType, 0), + 11: ('memo_text', p.UnicodeType, 0), + 12: ('memo_id', p.UVarintType, 0), + 13: ('memo_hash', p.BytesType, 0), + 14: ('num_operations', p.UVarintType, 0), + } + MESSAGE_WIRE_TYPE = 202 + + def __init__( + self, + protocol_version: int = None, + address_n: list = None, + network_passphrase: str = None, + source_account: bytes = None, + fee: int = None, + sequence_number: int = None, + timebounds_start: int = None, + timebounds_end: int = None, + memo_type: int = None, + memo_text: str = None, + memo_id: int = None, + memo_hash: bytes = None, + num_operations: int = None, + **kwargs, + ): + self.protocol_version = protocol_version + self.address_n = [] if address_n is None else address_n + self.network_passphrase = network_passphrase + self.source_account = source_account + self.fee = fee + self.sequence_number = sequence_number + self.timebounds_start = timebounds_start + self.timebounds_end = timebounds_end + self.memo_type = memo_type + self.memo_text = memo_text + self.memo_id = memo_id + self.memo_hash = memo_hash + self.num_operations = num_operations + p.MessageType.__init__(self, **kwargs) diff --git a/src/trezor/messages/StellarSignedTx.py b/src/trezor/messages/StellarSignedTx.py new file mode 100644 index 0000000000..8815c969f4 --- /dev/null +++ b/src/trezor/messages/StellarSignedTx.py @@ -0,0 +1,20 @@ +# Automatically generated by pb2py +import protobuf as p + + +class StellarSignedTx(p.MessageType): + FIELDS = { + 1: ('public_key', p.BytesType, 0), + 2: ('signature', p.BytesType, 0), + } + MESSAGE_WIRE_TYPE = 230 + + def __init__( + self, + public_key: bytes = None, + signature: bytes = None, + **kwargs, + ): + self.public_key = public_key + self.signature = signature + p.MessageType.__init__(self, **kwargs) diff --git a/src/trezor/messages/StellarTxOpRequest.py b/src/trezor/messages/StellarTxOpRequest.py new file mode 100644 index 0000000000..01aed2959d --- /dev/null +++ b/src/trezor/messages/StellarTxOpRequest.py @@ -0,0 +1,12 @@ +# Automatically generated by pb2py +import protobuf as p + + +class StellarTxOpRequest(p.MessageType): + MESSAGE_WIRE_TYPE = 203 + + def __init__( + self, + **kwargs, + ): + p.MessageType.__init__(self, **kwargs) diff --git a/src/trezor/messages/StellarVerifyMessage.py b/src/trezor/messages/StellarVerifyMessage.py new file mode 100644 index 0000000000..d3d67b220b --- /dev/null +++ b/src/trezor/messages/StellarVerifyMessage.py @@ -0,0 +1,23 @@ +# Automatically generated by pb2py +import protobuf as p + + +class StellarVerifyMessage(p.MessageType): + FIELDS = { + 1: ('public_key', p.BytesType, 0), + 2: ('message', p.BytesType, 0), + 3: ('signature', p.BytesType, 0), + } + MESSAGE_WIRE_TYPE = 206 + + def __init__( + self, + public_key: bytes = None, + message: bytes = None, + signature: bytes = None, + **kwargs, + ): + self.public_key = public_key + self.message = message + self.signature = signature + p.MessageType.__init__(self, **kwargs) diff --git a/src/trezor/messages/wire_types.py b/src/trezor/messages/wire_types.py index eadc919a77..3b28115b55 100644 --- a/src/trezor/messages/wire_types.py +++ b/src/trezor/messages/wire_types.py @@ -53,6 +53,15 @@ GetEntropy = const(9) GetFeatures = const(55) GetPublicKey = const(11) Initialize = const(0) +LiskAddress = const(115) +LiskGetAddress = const(114) +LiskGetPublicKey = const(121) +LiskMessageSignature = const(119) +LiskPublicKey = const(122) +LiskSignMessage = const(118) +LiskSignTx = const(116) +LiskSignedTx = const(117) +LiskVerifyMessage = const(120) LoadDevice = const(13) MessageSignature = const(40) NEMAddress = const(68) @@ -78,6 +87,25 @@ SignMessage = const(38) SignTx = const(15) SignedIdentity = const(54) SimpleSignTx = const(16) +StellarAccountMergeOp = const(218) +StellarAllowTrustOp = const(217) +StellarBumpSequenceOp = const(221) +StellarChangeTrustOp = const(216) +StellarCreateAccountOp = const(210) +StellarCreatePassiveOfferOp = const(214) +StellarGetPublicKey = const(200) +StellarManageDataOp = const(220) +StellarManageOfferOp = const(213) +StellarMessageSignature = const(205) +StellarPathPaymentOp = const(212) +StellarPaymentOp = const(211) +StellarPublicKey = const(201) +StellarSetOptionsOp = const(215) +StellarSignMessage = const(204) +StellarSignTx = const(202) +StellarSignedTx = const(230) +StellarTxOpRequest = const(203) +StellarVerifyMessage = const(206) Success = const(2) TxAck = const(22) TxRequest = const(21) From a2a861a688000a17f249d047e0c7a738548ed76f Mon Sep 17 00:00:00 2001 From: Aleksey Popov Date: Mon, 16 Apr 2018 23:03:04 +0300 Subject: [PATCH 03/16] app.lisk: Add lisk_get_address and helpers --- src/apps/lisk/__init__.py | 11 +++++++++++ src/apps/lisk/get_address.py | 25 +++++++++++++++++++++++++ src/apps/lisk/helpers.py | 33 +++++++++++++++++++++++++++++++++ src/main.py | 2 ++ 4 files changed, 71 insertions(+) create mode 100644 src/apps/lisk/__init__.py create mode 100644 src/apps/lisk/get_address.py create mode 100644 src/apps/lisk/helpers.py diff --git a/src/apps/lisk/__init__.py b/src/apps/lisk/__init__.py new file mode 100644 index 0000000000..e9630e57e9 --- /dev/null +++ b/src/apps/lisk/__init__.py @@ -0,0 +1,11 @@ +from trezor.wire import register, protobuf_workflow +from trezor.messages.wire_types import \ + LiskGetAddress + + +def dispatch_LiskGetAddress(*args, **kwargs): + from .get_address import layout_lisk_get_address + return layout_lisk_get_address(*args, **kwargs) + +def boot(): + register(LiskGetAddress, protobuf_workflow, dispatch_LiskGetAddress) diff --git a/src/apps/lisk/get_address.py b/src/apps/lisk/get_address.py new file mode 100644 index 0000000000..ae3da52c7b --- /dev/null +++ b/src/apps/lisk/get_address.py @@ -0,0 +1,25 @@ +from apps.wallet.get_address import _show_address, _show_qr +from .helpers import LISK_CURVE, get_address_from_public_key + + +async def layout_lisk_get_address(ctx, msg): + from trezor.messages.LiskAddress import LiskAddress + from trezor.crypto.curve import ed25519 + from ..common import seed + + address_n = msg.address_n or () + + node = await seed.derive_node(ctx, address_n, LISK_CURVE) + + seckey = node.private_key() + public_key = ed25519.publickey(seckey) + address = get_address_from_public_key(public_key) + + if msg.show_display: + while True: + if await _show_address(ctx, address): + break + if await _show_qr(ctx, address): + break + + return LiskAddress(address=address) diff --git a/src/apps/lisk/helpers.py b/src/apps/lisk/helpers.py new file mode 100644 index 0000000000..8ba96587ee --- /dev/null +++ b/src/apps/lisk/helpers.py @@ -0,0 +1,33 @@ + +LISK_CURVE = 'ed25519' + +def get_address_from_public_key(public_key): + from trezor.crypto.hashlib import sha256 + + # logic from lisk-js library + # https://github.com/LiskHQ/lisk-js/blob/115e0e771e8456dc6c1d4acaabba93d975655cfe/lib/transactions/crypto/convert.js#L30 + publicKeyHash = list(sha256(public_key).digest()) + addressData = [] + for i in range(8): + addressData.append(publicKeyHash[7 - i]) + + address = int.from_bytes(bytes(addressData), 'big') + return str(address) + "L" + +def get_votes_count(votes): + plus, minus = [], [] + for vote in votes: + plus.append(vote) if vote.startswith('+') else minus.append(vote) + return len(plus), len(minus) + +def get_vote_tx_text(votes): + plus, minus = get_votes_count(votes) + text = [] + if plus > 0: + text.append(_text_with_plural('Add', plus)) + if minus > 0: + text.append(_text_with_plural('Remove', minus)) + return text + +def _text_with_plural(txt, value): + return '%s %s %s' % (txt, value, ('votes' if value != 1 else 'vote')) diff --git a/src/main.py b/src/main.py index d41b0ecc56..5b1fe06c24 100644 --- a/src/main.py +++ b/src/main.py @@ -11,6 +11,7 @@ import apps.homescreen import apps.management import apps.wallet import apps.ethereum +import apps.lisk if __debug__: import apps.debug else: @@ -21,6 +22,7 @@ apps.homescreen.boot() apps.management.boot() apps.wallet.boot() apps.ethereum.boot() +apps.lisk.boot() if __debug__: apps.debug.boot() else: From a37493a8611e58aeedad217f566be60de8095d7f Mon Sep 17 00:00:00 2001 From: Aleksey Popov Date: Mon, 16 Apr 2018 23:07:25 +0300 Subject: [PATCH 04/16] app.lisk: Add lisk_get_public_key --- src/apps/lisk/__init__.py | 9 ++++++++- src/apps/lisk/get_public_key.py | 20 ++++++++++++++++++++ 2 files changed, 28 insertions(+), 1 deletion(-) create mode 100644 src/apps/lisk/get_public_key.py diff --git a/src/apps/lisk/__init__.py b/src/apps/lisk/__init__.py index e9630e57e9..854cd38a2a 100644 --- a/src/apps/lisk/__init__.py +++ b/src/apps/lisk/__init__.py @@ -1,11 +1,18 @@ from trezor.wire import register, protobuf_workflow from trezor.messages.wire_types import \ - LiskGetAddress + LiskGetAddress, LiskGetPublicKey def dispatch_LiskGetAddress(*args, **kwargs): from .get_address import layout_lisk_get_address return layout_lisk_get_address(*args, **kwargs) + +def dispatch_LiskGetPublicKey(*args, **kwargs): + from .get_public_key import lisk_get_public_key + return lisk_get_public_key(*args, **kwargs) + + def boot(): + register(LiskGetPublicKey, protobuf_workflow, dispatch_LiskGetPublicKey) register(LiskGetAddress, protobuf_workflow, dispatch_LiskGetAddress) diff --git a/src/apps/lisk/get_public_key.py b/src/apps/lisk/get_public_key.py new file mode 100644 index 0000000000..7880999046 --- /dev/null +++ b/src/apps/lisk/get_public_key.py @@ -0,0 +1,20 @@ +from apps.wallet.get_public_key import _show_pubkey +from .helpers import LISK_CURVE + + +async def lisk_get_public_key(ctx, msg): + from trezor.messages.LiskPublicKey import LiskPublicKey + from trezor.crypto.curve import ed25519 + from ..common import seed + + address_n = msg.address_n or () + + node = await seed.derive_node(ctx, address_n, LISK_CURVE) + + seckey = node.private_key() + public_key = ed25519.publickey(seckey) + + if msg.show_display: + await _show_pubkey(ctx, public_key) + + return LiskPublicKey(public_key=public_key) From dc5115055f84ef7e83cf7bf0e57619fc6b1213c4 Mon Sep 17 00:00:00 2001 From: Aleksey Popov Date: Mon, 16 Apr 2018 23:09:32 +0300 Subject: [PATCH 05/16] app.lisk: Add lisk_sign_message --- src/apps/lisk/__init__.py | 8 +++++++- src/apps/lisk/sign_message.py | 17 +++++++++++++++++ 2 files changed, 24 insertions(+), 1 deletion(-) create mode 100644 src/apps/lisk/sign_message.py diff --git a/src/apps/lisk/__init__.py b/src/apps/lisk/__init__.py index 854cd38a2a..0bbd41b356 100644 --- a/src/apps/lisk/__init__.py +++ b/src/apps/lisk/__init__.py @@ -1,6 +1,6 @@ from trezor.wire import register, protobuf_workflow from trezor.messages.wire_types import \ - LiskGetAddress, LiskGetPublicKey + LiskGetAddress, LiskSignMessage, LiskGetPublicKey def dispatch_LiskGetAddress(*args, **kwargs): @@ -13,6 +13,12 @@ def dispatch_LiskGetPublicKey(*args, **kwargs): return lisk_get_public_key(*args, **kwargs) +def dispatch_LiskSignMessage(*args, **kwargs): + from .sign_message import lisk_sign_message + return lisk_sign_message(*args, **kwargs) + + def boot(): register(LiskGetPublicKey, protobuf_workflow, dispatch_LiskGetPublicKey) register(LiskGetAddress, protobuf_workflow, dispatch_LiskGetAddress) + register(LiskSignMessage, protobuf_workflow, dispatch_LiskSignMessage) diff --git a/src/apps/lisk/sign_message.py b/src/apps/lisk/sign_message.py new file mode 100644 index 0000000000..632761efb0 --- /dev/null +++ b/src/apps/lisk/sign_message.py @@ -0,0 +1,17 @@ +from .helpers import LISK_CURVE, get_address_from_public_key + +async def lisk_sign_message(ctx, msg): + from trezor.messages.LiskMessageSignature import LiskMessageSignature + from trezor.crypto.curve import ed25519 + from ..common import seed + + address_n = msg.address_n or () + node = await seed.derive_node(ctx, address_n, LISK_CURVE) + + seckey = node.private_key() + public_key = ed25519.publickey(seckey) + address = get_address_from_public_key(public_key) + + signature = ed25519.sign(seckey, msg.message) + + return LiskMessageSignature(address=address, signature=signature) From 3334163e854d9913a890c1fb0e7178fc0f2bc717 Mon Sep 17 00:00:00 2001 From: Aleksey Popov Date: Mon, 16 Apr 2018 23:13:38 +0300 Subject: [PATCH 06/16] app.lisk: Add lisk_verify_message --- src/apps/lisk/__init__.py | 8 +++++++- src/apps/lisk/verify_message.py | 21 +++++++++++++++++++++ 2 files changed, 28 insertions(+), 1 deletion(-) create mode 100644 src/apps/lisk/verify_message.py diff --git a/src/apps/lisk/__init__.py b/src/apps/lisk/__init__.py index 0bbd41b356..e2fcbdb389 100644 --- a/src/apps/lisk/__init__.py +++ b/src/apps/lisk/__init__.py @@ -1,6 +1,6 @@ from trezor.wire import register, protobuf_workflow from trezor.messages.wire_types import \ - LiskGetAddress, LiskSignMessage, LiskGetPublicKey + LiskGetAddress, LiskSignMessage, LiskVerifyMessage, LiskGetPublicKey def dispatch_LiskGetAddress(*args, **kwargs): @@ -18,7 +18,13 @@ def dispatch_LiskSignMessage(*args, **kwargs): return lisk_sign_message(*args, **kwargs) +def dispatch_LiskVerifyMessage(*args, **kwargs): + from .verify_message import lisk_verify_message + return lisk_verify_message(*args, **kwargs) + + def boot(): register(LiskGetPublicKey, protobuf_workflow, dispatch_LiskGetPublicKey) register(LiskGetAddress, protobuf_workflow, dispatch_LiskGetAddress) register(LiskSignMessage, protobuf_workflow, dispatch_LiskSignMessage) + register(LiskVerifyMessage, protobuf_workflow, dispatch_LiskVerifyMessage) diff --git a/src/apps/lisk/verify_message.py b/src/apps/lisk/verify_message.py new file mode 100644 index 0000000000..0b9eda748f --- /dev/null +++ b/src/apps/lisk/verify_message.py @@ -0,0 +1,21 @@ + +async def lisk_verify_message(ctx, msg): + from trezor.crypto.curve import ed25519 + from .helpers import get_address_from_public_key + from trezor import wire + from trezor.messages.Success import Success + from trezor.messages.FailureType import ProcessError + from apps.wallet.verify_message import require_confirm_verify_message + + # Lisk signature can be more than 64 bytes + sig = msg.signature[:64] + verify = ed25519.verify(msg.public_key, sig, msg.message) + + if not verify: + raise wire.FailureError(ProcessError, 'Invalid signature') + + address = get_address_from_public_key(msg.public_key) + + await require_confirm_verify_message(ctx, address, msg.message) + + return Success(message='Message verified') From b6949f61537dc599ea641ef0af570a947c32cd08 Mon Sep 17 00:00:00 2001 From: Aleksey Popov Date: Mon, 16 Apr 2018 23:14:31 +0300 Subject: [PATCH 07/16] app.lisk: Add lisk_sign_tx and layouts --- src/apps/lisk/__init__.py | 8 +- src/apps/lisk/layout.py | 57 +++++++++++++++ src/apps/lisk/sign_tx.py | 126 ++++++++++++++++++++++++++++++++ src/apps/lisk/verify_message.py | 2 +- 4 files changed, 191 insertions(+), 2 deletions(-) create mode 100644 src/apps/lisk/layout.py create mode 100644 src/apps/lisk/sign_tx.py diff --git a/src/apps/lisk/__init__.py b/src/apps/lisk/__init__.py index e2fcbdb389..7c2835e48e 100644 --- a/src/apps/lisk/__init__.py +++ b/src/apps/lisk/__init__.py @@ -1,6 +1,6 @@ from trezor.wire import register, protobuf_workflow from trezor.messages.wire_types import \ - LiskGetAddress, LiskSignMessage, LiskVerifyMessage, LiskGetPublicKey + LiskGetAddress, LiskSignMessage, LiskVerifyMessage, LiskSignTx, LiskGetPublicKey def dispatch_LiskGetAddress(*args, **kwargs): @@ -23,8 +23,14 @@ def dispatch_LiskVerifyMessage(*args, **kwargs): return lisk_verify_message(*args, **kwargs) +def dispatch_LiskSignTx(*args, **kwargs): + from .sign_tx import lisk_sign_tx + return lisk_sign_tx(*args, **kwargs) + + def boot(): register(LiskGetPublicKey, protobuf_workflow, dispatch_LiskGetPublicKey) register(LiskGetAddress, protobuf_workflow, dispatch_LiskGetAddress) register(LiskSignMessage, protobuf_workflow, dispatch_LiskSignMessage) register(LiskVerifyMessage, protobuf_workflow, dispatch_LiskVerifyMessage) + register(LiskSignTx, protobuf_workflow, dispatch_LiskSignTx) diff --git a/src/apps/lisk/layout.py b/src/apps/lisk/layout.py new file mode 100644 index 0000000000..002622e92d --- /dev/null +++ b/src/apps/lisk/layout.py @@ -0,0 +1,57 @@ +from apps.common.confirm import * +from trezor import ui +from trezor.utils import chunks +from trezor.messages import ButtonRequestType +from trezor.ui.text import Text +from .helpers import get_vote_tx_text + + +async def require_confirm_tx(ctx, to, value): + content = Text('Confirm sending', ui.ICON_SEND, + ui.BOLD, format_amount(value), + ui.NORMAL, 'to', + ui.MONO, *split_address(to), + icon_color=ui.GREEN) + return await require_confirm(ctx, content, ButtonRequestType.SignTx) + +async def require_confirm_delegate_registration(ctx, delegate_name): + content = Text('Confirm transaction', ui.ICON_SEND, + 'Do you really want to', + 'register a delegate?', + ui.BOLD, *chunks(delegate_name, 20), + icon_color=ui.GREEN) + return await require_confirm(ctx, content, ButtonRequestType.SignTx) + +async def require_confirm_vote_tx(ctx, votes): + content = Text('Confirm transaction', ui.ICON_SEND, + *get_vote_tx_text(votes), + icon_color=ui.GREEN) + + return await require_confirm(ctx, content, ButtonRequestType.SignTx) + +async def require_confirm_public_key(ctx, public_key): + from apps.wallet.get_public_key import _show_pubkey + return await _show_pubkey(ctx, public_key) + +async def require_confirm_multisig(ctx, multisignature): + content = Text('Confirm transaction', ui.ICON_SEND, + ('Keys group length: %s' % len(multisignature.keys_group)), + ('Life time: %s' % multisignature.life_time), + ('Min: %s' % multisignature.min), + icon_color=ui.GREEN) + + return await require_confirm(ctx, content, ButtonRequestType.SignTx) + +async def require_confirm_fee(ctx, value, fee): + content = Text('Confirm transaction', ui.ICON_SEND, + ui.BOLD, format_amount(value), + ui.NORMAL, 'fee:', + ui.BOLD, format_amount(fee), + icon_color=ui.GREEN) + await require_hold_to_confirm(ctx, content, ButtonRequestType.ConfirmOutput) + +def format_amount(value): + return '%s LSK' % (int(value) / 100000000) + +def split_address(address): + return chunks(address, 16) diff --git a/src/apps/lisk/sign_tx.py b/src/apps/lisk/sign_tx.py new file mode 100644 index 0000000000..8ef130639d --- /dev/null +++ b/src/apps/lisk/sign_tx.py @@ -0,0 +1,126 @@ +from trezor import wire, ui +from trezor.messages.LiskSignedTx import LiskSignedTx +from trezor.messages.LiskTransactionType import * +from trezor.messages import FailureType +from trezor.utils import HashWriter +from apps.lisk.layout import * +from ubinascii import unhexlify, hexlify + + +async def lisk_sign_tx(ctx, msg): + from trezor.crypto.hashlib import sha256 + + public_key, seckey = await _get_keys(ctx, msg) + transaction = update_raw_tx(msg.transaction, public_key) + + # throw ValueError if transaction has not valid structure + try: + await require_confirm_by_type(ctx, transaction) + except AttributeError: + raise ValueError(FailureType.DataError, 'The transaction has invalid asset data field') + + await require_confirm_fee(ctx, transaction.amount, transaction.fee) + + sha = HashWriter(sha256) + transactionBytes = _get_transaction_bytes(transaction) + + for field in transactionBytes: + sha.extend(field) + + digest = sha.get_digest() + + signature = await get_signature(seckey, digest) + + return LiskSignedTx(signature=signature) + +async def require_confirm_by_type(ctx, transaction): + if transaction.type is Transfer: + return await require_confirm_tx(ctx, transaction.recipient_id, transaction.amount) + if transaction.type is RegisterDelegate: + return await require_confirm_delegate_registration(ctx, transaction.asset.delegate.username) + if transaction.type is CastVotes: + return await require_confirm_vote_tx(ctx, transaction.asset.votes) + if transaction.type is RegisterSecondPassphrase: + return await require_confirm_public_key(ctx, transaction.asset.signature.public_key) + if transaction.type is RegisterMultisignatureAccount: + return await require_confirm_multisig(ctx, transaction.asset.multisignature) + +async def get_signature(seckey, digest): + from trezor.crypto.curve import ed25519 + signature = ed25519.sign(seckey, digest) + + return signature + +def _get_transaction_bytes(msg): + from ustruct import pack + + # Required transaction parameters + t_type = pack('Q', 0) + else: + t_recipient_id = pack('>Q', int(msg.recipient_id[:-1])) + + if msg.signature is None: + t_signature = b'' + else: + t_signature = msg.signature + + t_asset = _get_asset_data_byttes(msg) + + return [t_type, t_timestamp, t_pubkey, t_requester_public_key, t_recipient_id, t_amount, t_asset, t_signature] + +def _get_asset_data_byttes(msg): + from ustruct import pack + data = b'' + + if msg.type is Transfer and getattr(msg.asset, "data"): + data = bytes(msg.asset.data, "utf8") + + if msg.type is RegisterDelegate: + data = bytes(msg.asset.delegate.username, "utf8") + + if msg.type is CastVotes: + data = bytes("".join(msg.asset.votes), "utf8") + + if msg.type is RegisterSecondPassphrase: + data = msg.asset.signature.public_key + + if msg.type is RegisterMultisignatureAccount: + data += pack(' Date: Sat, 21 Apr 2018 21:46:59 +0300 Subject: [PATCH 08/16] app.lisk: refactor helpers code --- src/apps/lisk/helpers.py | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/src/apps/lisk/helpers.py b/src/apps/lisk/helpers.py index 8ba96587ee..4371ca2c3c 100644 --- a/src/apps/lisk/helpers.py +++ b/src/apps/lisk/helpers.py @@ -4,21 +4,18 @@ LISK_CURVE = 'ed25519' def get_address_from_public_key(public_key): from trezor.crypto.hashlib import sha256 - # logic from lisk-js library - # https://github.com/LiskHQ/lisk-js/blob/115e0e771e8456dc6c1d4acaabba93d975655cfe/lib/transactions/crypto/convert.js#L30 - publicKeyHash = list(sha256(public_key).digest()) - addressData = [] - for i in range(8): - addressData.append(publicKeyHash[7 - i]) - - address = int.from_bytes(bytes(addressData), 'big') + public_key_hash = sha256(public_key).digest() + address = int.from_bytes(public_key_hash[:8], 'little') return str(address) + "L" def get_votes_count(votes): - plus, minus = [], [] + plus, minus = 0, 0 for vote in votes: - plus.append(vote) if vote.startswith('+') else minus.append(vote) - return len(plus), len(minus) + if vote.startswith('+'): + plus += 1 + else: + minus += 1 + return plus, minus def get_vote_tx_text(votes): plus, minus = get_votes_count(votes) From a0f5bbb734145f5be39c0385c55384192bca85c3 Mon Sep 17 00:00:00 2001 From: Aleksey Popov Date: Sat, 21 Apr 2018 21:48:25 +0300 Subject: [PATCH 09/16] app.lisk: review improvments --- src/apps/lisk/sign_tx.py | 48 +++++++++++++++++++++------------------- 1 file changed, 25 insertions(+), 23 deletions(-) diff --git a/src/apps/lisk/sign_tx.py b/src/apps/lisk/sign_tx.py index 8ef130639d..fcb69c988f 100644 --- a/src/apps/lisk/sign_tx.py +++ b/src/apps/lisk/sign_tx.py @@ -22,9 +22,9 @@ async def lisk_sign_tx(ctx, msg): await require_confirm_fee(ctx, transaction.amount, transaction.fee) sha = HashWriter(sha256) - transactionBytes = _get_transaction_bytes(transaction) + transaction_bytes = _get_transaction_bytes(transaction) - for field in transactionBytes: + for field in transaction_bytes: sha.extend(field) digest = sha.get_digest() @@ -44,6 +44,7 @@ async def require_confirm_by_type(ctx, transaction): return await require_confirm_public_key(ctx, transaction.asset.signature.public_key) if transaction.type is RegisterMultisignatureAccount: return await require_confirm_multisig(ctx, transaction.asset.multisignature) + raise ValueError(FailureType.DataError, 'Invalid transaction type') async def get_signature(seckey, digest): from trezor.crypto.curve import ed25519 @@ -60,47 +61,47 @@ def _get_transaction_bytes(msg): t_amount = pack('Q', 0) else: + # Lisk use big-endian for recipient_id + # string -> int -> bytes t_recipient_id = pack('>Q', int(msg.recipient_id[:-1])) - if msg.signature is None: - t_signature = b'' - else: - t_signature = msg.signature + t_signature = msg.signature or b'' - t_asset = _get_asset_data_byttes(msg) + t_asset = _get_asset_data_bytes(msg) - return [t_type, t_timestamp, t_pubkey, t_requester_public_key, t_recipient_id, t_amount, t_asset, t_signature] + return t_type, t_timestamp, t_pubkey, t_requester_public_key, t_recipient_id, t_amount, t_asset, t_signature -def _get_asset_data_byttes(msg): +def _get_asset_data_bytes(msg): from ustruct import pack - data = b'' - if msg.type is Transfer and getattr(msg.asset, "data"): - data = bytes(msg.asset.data, "utf8") + if msg.type is Transfer: + # Transfer transaction have optional data field + if msg.asset.data is not None: + return bytes(msg.asset.data, "utf8") + else: + return b'' if msg.type is RegisterDelegate: - data = bytes(msg.asset.delegate.username, "utf8") + return bytes(msg.asset.delegate.username, "utf8") if msg.type is CastVotes: - data = bytes("".join(msg.asset.votes), "utf8") + return bytes("".join(msg.asset.votes), "utf8") if msg.type is RegisterSecondPassphrase: - data = msg.asset.signature.public_key + return msg.asset.signature.public_key if msg.type is RegisterMultisignatureAccount: + data = b'' data += pack(' Date: Tue, 1 May 2018 18:03:05 +0300 Subject: [PATCH 10/16] app.lisk: fix lisk_verify_message --- src/apps/lisk/verify_message.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/apps/lisk/verify_message.py b/src/apps/lisk/verify_message.py index 39e7adabd5..cf3af668c0 100644 --- a/src/apps/lisk/verify_message.py +++ b/src/apps/lisk/verify_message.py @@ -7,9 +7,7 @@ async def lisk_verify_message(ctx, msg): from trezor.messages.FailureType import ProcessError from apps.wallet.verify_message import require_confirm_verify_message - # Lisk signature can be more than 64 bytes - sig = msg.signature[:64] - verify = ed25519.verify(msg.public_key, sig, msg.message) + verify = ed25519.verify(msg.public_key, msg.signature, msg.message) if not verify: raise wire.FailureError(ProcessError, 'Invalid signature') From 83a1df99f46deac52b60e56e51274d34f54890f6 Mon Sep 17 00:00:00 2001 From: Aleksey Popov Date: Thu, 17 May 2018 19:24:36 +0300 Subject: [PATCH 11/16] app.lisk: add require confirm layout for message signing --- src/apps/lisk/sign_message.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/apps/lisk/sign_message.py b/src/apps/lisk/sign_message.py index 632761efb0..22aa255c49 100644 --- a/src/apps/lisk/sign_message.py +++ b/src/apps/lisk/sign_message.py @@ -1,10 +1,15 @@ from .helpers import LISK_CURVE, get_address_from_public_key +from apps.wallet.sign_message import require_confirm_sign_message async def lisk_sign_message(ctx, msg): from trezor.messages.LiskMessageSignature import LiskMessageSignature from trezor.crypto.curve import ed25519 from ..common import seed + message = msg.message + + await require_confirm_sign_message(ctx, message) + address_n = msg.address_n or () node = await seed.derive_node(ctx, address_n, LISK_CURVE) @@ -12,6 +17,6 @@ async def lisk_sign_message(ctx, msg): public_key = ed25519.publickey(seckey) address = get_address_from_public_key(public_key) - signature = ed25519.sign(seckey, msg.message) + signature = ed25519.sign(seckey, message) return LiskMessageSignature(address=address, signature=signature) From c78c6616f65f81451264b8b6866f0d1bffc48942 Mon Sep 17 00:00:00 2001 From: Jan Pochyla Date: Thu, 17 May 2018 16:12:02 +0200 Subject: [PATCH 12/16] app.lisk: simplify pubkey computation --- src/apps/lisk/get_address.py | 8 +++----- src/apps/lisk/get_public_key.py | 10 ++++------ src/apps/lisk/sign_message.py | 7 ++++--- src/apps/lisk/sign_tx.py | 6 +++--- 4 files changed, 14 insertions(+), 17 deletions(-) diff --git a/src/apps/lisk/get_address.py b/src/apps/lisk/get_address.py index ae3da52c7b..b5228ec2ad 100644 --- a/src/apps/lisk/get_address.py +++ b/src/apps/lisk/get_address.py @@ -4,16 +4,14 @@ from .helpers import LISK_CURVE, get_address_from_public_key async def layout_lisk_get_address(ctx, msg): from trezor.messages.LiskAddress import LiskAddress - from trezor.crypto.curve import ed25519 from ..common import seed address_n = msg.address_n or () node = await seed.derive_node(ctx, address_n, LISK_CURVE) - - seckey = node.private_key() - public_key = ed25519.publickey(seckey) - address = get_address_from_public_key(public_key) + pubkey = node.public_key() + pubkey = pubkey[1:] # skip ed25519 pubkey marker + address = get_address_from_public_key(pubkey) if msg.show_display: while True: diff --git a/src/apps/lisk/get_public_key.py b/src/apps/lisk/get_public_key.py index 7880999046..6973ac1246 100644 --- a/src/apps/lisk/get_public_key.py +++ b/src/apps/lisk/get_public_key.py @@ -4,17 +4,15 @@ from .helpers import LISK_CURVE async def lisk_get_public_key(ctx, msg): from trezor.messages.LiskPublicKey import LiskPublicKey - from trezor.crypto.curve import ed25519 from ..common import seed address_n = msg.address_n or () node = await seed.derive_node(ctx, address_n, LISK_CURVE) - - seckey = node.private_key() - public_key = ed25519.publickey(seckey) + pubkey = node.public_key() + pubkey = pubkey[1:] # skip ed25519 pubkey marker if msg.show_display: - await _show_pubkey(ctx, public_key) + await _show_pubkey(ctx, pubkey) - return LiskPublicKey(public_key=public_key) + return LiskPublicKey(public_key=pubkey) diff --git a/src/apps/lisk/sign_message.py b/src/apps/lisk/sign_message.py index 22aa255c49..2acfd3e573 100644 --- a/src/apps/lisk/sign_message.py +++ b/src/apps/lisk/sign_message.py @@ -11,11 +11,12 @@ async def lisk_sign_message(ctx, msg): await require_confirm_sign_message(ctx, message) address_n = msg.address_n or () - node = await seed.derive_node(ctx, address_n, LISK_CURVE) + node = await seed.derive_node(ctx, address_n, LISK_CURVE) seckey = node.private_key() - public_key = ed25519.publickey(seckey) - address = get_address_from_public_key(public_key) + pubkey = node.public_key() + pubkey = pubkey[1:] # skip ed25519 pubkey marker + address = get_address_from_public_key(pubkey) signature = ed25519.sign(seckey, message) diff --git a/src/apps/lisk/sign_tx.py b/src/apps/lisk/sign_tx.py index fcb69c988f..523b5f2639 100644 --- a/src/apps/lisk/sign_tx.py +++ b/src/apps/lisk/sign_tx.py @@ -104,7 +104,6 @@ def _get_asset_data_bytes(msg): return data async def _get_keys(ctx, msg): - from trezor.crypto.curve import ed25519 from ..common import seed from .helpers import LISK_CURVE @@ -112,9 +111,10 @@ async def _get_keys(ctx, msg): node = await seed.derive_node(ctx, address_n, LISK_CURVE) seckey = node.private_key() - public_key = ed25519.publickey(seckey) + pubkey = node.public_key() + pubkey = pubkey[1:] # skip ed25519 pubkey marker - return public_key, seckey + return pubkey, seckey def update_raw_tx(transaction, public_key): from .helpers import get_address_from_public_key From 04c652c12062693a5767f78c474abd062ccd76e5 Mon Sep 17 00:00:00 2001 From: Jan Pochyla Date: Mon, 21 May 2018 12:18:09 +0200 Subject: [PATCH 13/16] app.lisk: use == for comparing ints, code style --- src/apps/lisk/sign_tx.py | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/src/apps/lisk/sign_tx.py b/src/apps/lisk/sign_tx.py index 523b5f2639..9da973cc29 100644 --- a/src/apps/lisk/sign_tx.py +++ b/src/apps/lisk/sign_tx.py @@ -10,8 +10,8 @@ from ubinascii import unhexlify, hexlify async def lisk_sign_tx(ctx, msg): from trezor.crypto.hashlib import sha256 - public_key, seckey = await _get_keys(ctx, msg) - transaction = update_raw_tx(msg.transaction, public_key) + pubkey, seckey = await _get_keys(ctx, msg) + transaction = update_raw_tx(msg.transaction, pubkey) # throw ValueError if transaction has not valid structure try: @@ -34,15 +34,15 @@ async def lisk_sign_tx(ctx, msg): return LiskSignedTx(signature=signature) async def require_confirm_by_type(ctx, transaction): - if transaction.type is Transfer: + if transaction.type == Transfer: return await require_confirm_tx(ctx, transaction.recipient_id, transaction.amount) - if transaction.type is RegisterDelegate: + if transaction.type == RegisterDelegate: return await require_confirm_delegate_registration(ctx, transaction.asset.delegate.username) - if transaction.type is CastVotes: + if transaction.type == CastVotes: return await require_confirm_vote_tx(ctx, transaction.asset.votes) - if transaction.type is RegisterSecondPassphrase: + if transaction.type == RegisterSecondPassphrase: return await require_confirm_public_key(ctx, transaction.asset.signature.public_key) - if transaction.type is RegisterMultisignatureAccount: + if transaction.type == RegisterMultisignatureAccount: return await require_confirm_multisig(ctx, transaction.asset.multisignature) raise ValueError(FailureType.DataError, 'Invalid transaction type') @@ -80,23 +80,23 @@ def _get_transaction_bytes(msg): def _get_asset_data_bytes(msg): from ustruct import pack - if msg.type is Transfer: + if msg.type == Transfer: # Transfer transaction have optional data field if msg.asset.data is not None: return bytes(msg.asset.data, "utf8") else: return b'' - if msg.type is RegisterDelegate: + if msg.type == RegisterDelegate: return bytes(msg.asset.delegate.username, "utf8") - if msg.type is CastVotes: + if msg.type == CastVotes: return bytes("".join(msg.asset.votes), "utf8") - if msg.type is RegisterSecondPassphrase: + if msg.type == RegisterSecondPassphrase: return msg.asset.signature.public_key - if msg.type is RegisterMultisignatureAccount: + if msg.type == RegisterMultisignatureAccount: data = b'' data += pack(' Date: Mon, 21 May 2018 15:09:06 +0200 Subject: [PATCH 14/16] app.lisk: code style --- src/apps/lisk/get_address.py | 6 +- src/apps/lisk/get_public_key.py | 6 +- src/apps/lisk/helpers.py | 13 ++- src/apps/lisk/layout.py | 16 ++- src/apps/lisk/sign_tx.py | 195 ++++++++++++++++---------------- 5 files changed, 124 insertions(+), 112 deletions(-) diff --git a/src/apps/lisk/get_address.py b/src/apps/lisk/get_address.py index b5228ec2ad..a273289d8b 100644 --- a/src/apps/lisk/get_address.py +++ b/src/apps/lisk/get_address.py @@ -1,11 +1,11 @@ +from apps.common import seed from apps.wallet.get_address import _show_address, _show_qr +from trezor.messages.LiskAddress import LiskAddress + from .helpers import LISK_CURVE, get_address_from_public_key async def layout_lisk_get_address(ctx, msg): - from trezor.messages.LiskAddress import LiskAddress - from ..common import seed - address_n = msg.address_n or () node = await seed.derive_node(ctx, address_n, LISK_CURVE) diff --git a/src/apps/lisk/get_public_key.py b/src/apps/lisk/get_public_key.py index 6973ac1246..d79ec6fb1e 100644 --- a/src/apps/lisk/get_public_key.py +++ b/src/apps/lisk/get_public_key.py @@ -1,11 +1,11 @@ +from apps.common import seed from apps.wallet.get_public_key import _show_pubkey +from trezor.messages.LiskPublicKey import LiskPublicKey + from .helpers import LISK_CURVE async def lisk_get_public_key(ctx, msg): - from trezor.messages.LiskPublicKey import LiskPublicKey - from ..common import seed - address_n = msg.address_n or () node = await seed.derive_node(ctx, address_n, LISK_CURVE) diff --git a/src/apps/lisk/helpers.py b/src/apps/lisk/helpers.py index 4371ca2c3c..87aa46aaa5 100644 --- a/src/apps/lisk/helpers.py +++ b/src/apps/lisk/helpers.py @@ -1,12 +1,13 @@ +from trezor.crypto.hashlib import sha256 LISK_CURVE = 'ed25519' -def get_address_from_public_key(public_key): - from trezor.crypto.hashlib import sha256 - public_key_hash = sha256(public_key).digest() - address = int.from_bytes(public_key_hash[:8], 'little') - return str(address) + "L" +def get_address_from_public_key(pubkey): + pubkeyhash = sha256(pubkey).digest() + address = int.from_bytes(pubkeyhash[:8], 'little') + return str(address) + 'L' + def get_votes_count(votes): plus, minus = 0, 0 @@ -17,6 +18,7 @@ def get_votes_count(votes): minus += 1 return plus, minus + def get_vote_tx_text(votes): plus, minus = get_votes_count(votes) text = [] @@ -26,5 +28,6 @@ def get_vote_tx_text(votes): text.append(_text_with_plural('Remove', minus)) return text + def _text_with_plural(txt, value): return '%s %s %s' % (txt, value, ('votes' if value != 1 else 'vote')) diff --git a/src/apps/lisk/layout.py b/src/apps/lisk/layout.py index 002622e92d..2847a4afd1 100644 --- a/src/apps/lisk/layout.py +++ b/src/apps/lisk/layout.py @@ -1,8 +1,10 @@ -from apps.common.confirm import * +from apps.common.confirm import require_confirm, require_hold_to_confirm +from apps.wallet.get_public_key import _show_pubkey from trezor import ui -from trezor.utils import chunks from trezor.messages import ButtonRequestType from trezor.ui.text import Text +from trezor.utils import chunks + from .helpers import get_vote_tx_text @@ -14,6 +16,7 @@ async def require_confirm_tx(ctx, to, value): icon_color=ui.GREEN) return await require_confirm(ctx, content, ButtonRequestType.SignTx) + async def require_confirm_delegate_registration(ctx, delegate_name): content = Text('Confirm transaction', ui.ICON_SEND, 'Do you really want to', @@ -22,26 +25,27 @@ async def require_confirm_delegate_registration(ctx, delegate_name): icon_color=ui.GREEN) return await require_confirm(ctx, content, ButtonRequestType.SignTx) + async def require_confirm_vote_tx(ctx, votes): content = Text('Confirm transaction', ui.ICON_SEND, *get_vote_tx_text(votes), icon_color=ui.GREEN) - return await require_confirm(ctx, content, ButtonRequestType.SignTx) + async def require_confirm_public_key(ctx, public_key): - from apps.wallet.get_public_key import _show_pubkey return await _show_pubkey(ctx, public_key) + async def require_confirm_multisig(ctx, multisignature): content = Text('Confirm transaction', ui.ICON_SEND, ('Keys group length: %s' % len(multisignature.keys_group)), ('Life time: %s' % multisignature.life_time), ('Min: %s' % multisignature.min), icon_color=ui.GREEN) - return await require_confirm(ctx, content, ButtonRequestType.SignTx) + async def require_confirm_fee(ctx, value, fee): content = Text('Confirm transaction', ui.ICON_SEND, ui.BOLD, format_amount(value), @@ -50,8 +54,10 @@ async def require_confirm_fee(ctx, value, fee): icon_color=ui.GREEN) await require_hold_to_confirm(ctx, content, ButtonRequestType.ConfirmOutput) + def format_amount(value): return '%s LSK' % (int(value) / 100000000) + def split_address(address): return chunks(address, 16) diff --git a/src/apps/lisk/sign_tx.py b/src/apps/lisk/sign_tx.py index 9da973cc29..28a0167c72 100644 --- a/src/apps/lisk/sign_tx.py +++ b/src/apps/lisk/sign_tx.py @@ -1,112 +1,39 @@ -from trezor import wire, ui +import ustruct +from apps.common import seed +from trezor import wire +from trezor.crypto.curve import ed25519 +from trezor.crypto.hashlib import sha256 +from trezor.messages import LiskTransactionType from trezor.messages.LiskSignedTx import LiskSignedTx -from trezor.messages.LiskTransactionType import * -from trezor.messages import FailureType from trezor.utils import HashWriter -from apps.lisk.layout import * -from ubinascii import unhexlify, hexlify + +from . import layout +from .helpers import LISK_CURVE, get_address_from_public_key async def lisk_sign_tx(ctx, msg): - from trezor.crypto.hashlib import sha256 - pubkey, seckey = await _get_keys(ctx, msg) - transaction = update_raw_tx(msg.transaction, pubkey) + transaction = _update_raw_tx(msg.transaction, pubkey) - # throw ValueError if transaction has not valid structure try: - await require_confirm_by_type(ctx, transaction) + await _require_confirm_by_type(ctx, transaction) except AttributeError: - raise ValueError(FailureType.DataError, 'The transaction has invalid asset data field') + raise wire.DataError('The transaction has invalid asset data field') - await require_confirm_fee(ctx, transaction.amount, transaction.fee) + await layout.require_confirm_fee(ctx, transaction.amount, transaction.fee) - sha = HashWriter(sha256) - transaction_bytes = _get_transaction_bytes(transaction) + txbytes = _get_transaction_bytes(transaction) + txhash = HashWriter(sha256) + for field in txbytes: + txhash.extend(field) + digest = txhash.get_digest() - for field in transaction_bytes: - sha.extend(field) - - digest = sha.get_digest() - - signature = await get_signature(seckey, digest) + signature = ed25519.sign(seckey, digest) return LiskSignedTx(signature=signature) -async def require_confirm_by_type(ctx, transaction): - if transaction.type == Transfer: - return await require_confirm_tx(ctx, transaction.recipient_id, transaction.amount) - if transaction.type == RegisterDelegate: - return await require_confirm_delegate_registration(ctx, transaction.asset.delegate.username) - if transaction.type == CastVotes: - return await require_confirm_vote_tx(ctx, transaction.asset.votes) - if transaction.type == RegisterSecondPassphrase: - return await require_confirm_public_key(ctx, transaction.asset.signature.public_key) - if transaction.type == RegisterMultisignatureAccount: - return await require_confirm_multisig(ctx, transaction.asset.multisignature) - raise ValueError(FailureType.DataError, 'Invalid transaction type') - -async def get_signature(seckey, digest): - from trezor.crypto.curve import ed25519 - signature = ed25519.sign(seckey, digest) - - return signature - -def _get_transaction_bytes(msg): - from ustruct import pack - - # Required transaction parameters - t_type = pack('Q', 0) - else: - # Lisk use big-endian for recipient_id - # string -> int -> bytes - t_recipient_id = pack('>Q', int(msg.recipient_id[:-1])) - - t_signature = msg.signature or b'' - - t_asset = _get_asset_data_bytes(msg) - - return t_type, t_timestamp, t_pubkey, t_requester_public_key, t_recipient_id, t_amount, t_asset, t_signature - -def _get_asset_data_bytes(msg): - from ustruct import pack - - if msg.type == Transfer: - # Transfer transaction have optional data field - if msg.asset.data is not None: - return bytes(msg.asset.data, "utf8") - else: - return b'' - - if msg.type == RegisterDelegate: - return bytes(msg.asset.delegate.username, "utf8") - - if msg.type == CastVotes: - return bytes("".join(msg.asset.votes), "utf8") - - if msg.type == RegisterSecondPassphrase: - return msg.asset.signature.public_key - - if msg.type == RegisterMultisignatureAccount: - data = b'' - data += pack('Q', 0) + else: + # Lisk uses big-endian for recipient_id, string -> int -> bytes + t_recipient_id = ustruct.pack('>Q', int(tx.recipient_id[:-1])) + + t_amount = ustruct.pack(' Date: Tue, 22 May 2018 15:26:43 +0200 Subject: [PATCH 15/16] app.lisk: remove sign/verify code --- src/apps/lisk/__init__.py | 14 +------------- src/apps/lisk/sign_message.py | 23 ----------------------- src/apps/lisk/verify_message.py | 19 ------------------- 3 files changed, 1 insertion(+), 55 deletions(-) delete mode 100644 src/apps/lisk/sign_message.py delete mode 100644 src/apps/lisk/verify_message.py diff --git a/src/apps/lisk/__init__.py b/src/apps/lisk/__init__.py index 7c2835e48e..c82515e268 100644 --- a/src/apps/lisk/__init__.py +++ b/src/apps/lisk/__init__.py @@ -1,6 +1,6 @@ from trezor.wire import register, protobuf_workflow from trezor.messages.wire_types import \ - LiskGetAddress, LiskSignMessage, LiskVerifyMessage, LiskSignTx, LiskGetPublicKey + LiskGetAddress, LiskSignTx, LiskGetPublicKey def dispatch_LiskGetAddress(*args, **kwargs): @@ -13,16 +13,6 @@ def dispatch_LiskGetPublicKey(*args, **kwargs): return lisk_get_public_key(*args, **kwargs) -def dispatch_LiskSignMessage(*args, **kwargs): - from .sign_message import lisk_sign_message - return lisk_sign_message(*args, **kwargs) - - -def dispatch_LiskVerifyMessage(*args, **kwargs): - from .verify_message import lisk_verify_message - return lisk_verify_message(*args, **kwargs) - - def dispatch_LiskSignTx(*args, **kwargs): from .sign_tx import lisk_sign_tx return lisk_sign_tx(*args, **kwargs) @@ -31,6 +21,4 @@ def dispatch_LiskSignTx(*args, **kwargs): def boot(): register(LiskGetPublicKey, protobuf_workflow, dispatch_LiskGetPublicKey) register(LiskGetAddress, protobuf_workflow, dispatch_LiskGetAddress) - register(LiskSignMessage, protobuf_workflow, dispatch_LiskSignMessage) - register(LiskVerifyMessage, protobuf_workflow, dispatch_LiskVerifyMessage) register(LiskSignTx, protobuf_workflow, dispatch_LiskSignTx) diff --git a/src/apps/lisk/sign_message.py b/src/apps/lisk/sign_message.py deleted file mode 100644 index 2acfd3e573..0000000000 --- a/src/apps/lisk/sign_message.py +++ /dev/null @@ -1,23 +0,0 @@ -from .helpers import LISK_CURVE, get_address_from_public_key -from apps.wallet.sign_message import require_confirm_sign_message - -async def lisk_sign_message(ctx, msg): - from trezor.messages.LiskMessageSignature import LiskMessageSignature - from trezor.crypto.curve import ed25519 - from ..common import seed - - message = msg.message - - await require_confirm_sign_message(ctx, message) - - address_n = msg.address_n or () - - node = await seed.derive_node(ctx, address_n, LISK_CURVE) - seckey = node.private_key() - pubkey = node.public_key() - pubkey = pubkey[1:] # skip ed25519 pubkey marker - address = get_address_from_public_key(pubkey) - - signature = ed25519.sign(seckey, message) - - return LiskMessageSignature(address=address, signature=signature) diff --git a/src/apps/lisk/verify_message.py b/src/apps/lisk/verify_message.py deleted file mode 100644 index cf3af668c0..0000000000 --- a/src/apps/lisk/verify_message.py +++ /dev/null @@ -1,19 +0,0 @@ - -async def lisk_verify_message(ctx, msg): - from trezor.crypto.curve import ed25519 - from .helpers import get_address_from_public_key - from trezor import wire - from trezor.messages.Success import Success - from trezor.messages.FailureType import ProcessError - from apps.wallet.verify_message import require_confirm_verify_message - - verify = ed25519.verify(msg.public_key, msg.signature, msg.message) - - if not verify: - raise wire.FailureError(ProcessError, 'Invalid signature') - - address = get_address_from_public_key(msg.public_key) - - await require_confirm_verify_message(ctx, address, msg.message) - - return Success(message='Message verified') From e6dc6eb6d7d016dfa3a3f0b59e13eea0ac2c6f9d Mon Sep 17 00:00:00 2001 From: Jan Pochyla Date: Wed, 23 May 2018 13:29:12 +0200 Subject: [PATCH 16/16] app.lisk: enable lisk tests --- pytest.ini | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/pytest.ini b/pytest.ini index cce4ddc98f..0f83d26ca7 100644 --- a/pytest.ini +++ b/pytest.ini @@ -1,6 +1,4 @@ [pytest] addopts = --pyargs trezorlib.tests.device_tests xfail_strict = true - -# List of markers that run as if not xfailed. See docs/testing.md for details -# run_xfail = stellar lisk nem +run_xfail = lisk