parent
abc347d4ca
commit
d33d61d84e
@ -0,0 +1 @@
|
|||||||
|
Removed support for Lisk
|
@ -1,5 +0,0 @@
|
|||||||
from apps.common.paths import PATTERN_SEP5
|
|
||||||
|
|
||||||
CURVE = "ed25519"
|
|
||||||
SLIP44_ID = 134
|
|
||||||
PATTERN = PATTERN_SEP5
|
|
@ -1,23 +0,0 @@
|
|||||||
from trezor.messages import LiskAddress
|
|
||||||
from trezor.ui.layouts import show_address
|
|
||||||
|
|
||||||
from apps.common import paths
|
|
||||||
from apps.common.keychain import auto_keychain
|
|
||||||
|
|
||||||
from .helpers import get_address_from_public_key
|
|
||||||
|
|
||||||
|
|
||||||
@auto_keychain(__name__)
|
|
||||||
async def get_address(ctx, msg, keychain):
|
|
||||||
await paths.validate_path(ctx, keychain, msg.address_n)
|
|
||||||
|
|
||||||
node = keychain.derive(msg.address_n)
|
|
||||||
pubkey = node.public_key()
|
|
||||||
pubkey = pubkey[1:] # skip ed25519 pubkey marker
|
|
||||||
address = get_address_from_public_key(pubkey)
|
|
||||||
|
|
||||||
if msg.show_display:
|
|
||||||
title = paths.address_n_to_str(msg.address_n)
|
|
||||||
await show_address(ctx, address=address, address_qr=address, title=title)
|
|
||||||
|
|
||||||
return LiskAddress(address=address)
|
|
@ -1,21 +0,0 @@
|
|||||||
from ubinascii import hexlify
|
|
||||||
|
|
||||||
from trezor.messages import LiskPublicKey
|
|
||||||
from trezor.ui.layouts import show_pubkey
|
|
||||||
|
|
||||||
from apps.common import paths
|
|
||||||
from apps.common.keychain import auto_keychain
|
|
||||||
|
|
||||||
|
|
||||||
@auto_keychain(__name__)
|
|
||||||
async def get_public_key(ctx, msg, keychain):
|
|
||||||
await paths.validate_path(ctx, keychain, msg.address_n)
|
|
||||||
|
|
||||||
node = keychain.derive(msg.address_n)
|
|
||||||
pubkey = node.public_key()
|
|
||||||
pubkey = pubkey[1:] # skip ed25519 pubkey marker
|
|
||||||
|
|
||||||
if msg.show_display:
|
|
||||||
await show_pubkey(ctx, hexlify(pubkey).decode())
|
|
||||||
|
|
||||||
return LiskPublicKey(public_key=pubkey)
|
|
@ -1,31 +0,0 @@
|
|||||||
from trezor.crypto.hashlib import sha256
|
|
||||||
|
|
||||||
|
|
||||||
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
|
|
||||||
for vote in votes:
|
|
||||||
if vote.startswith("+"):
|
|
||||||
plus += 1
|
|
||||||
else:
|
|
||||||
minus += 1
|
|
||||||
return plus, 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"))
|
|
@ -1,84 +0,0 @@
|
|||||||
from ubinascii import hexlify
|
|
||||||
|
|
||||||
from trezor import ui
|
|
||||||
from trezor.enums import ButtonRequestType
|
|
||||||
from trezor.strings import format_amount
|
|
||||||
from trezor.ui.layouts import (
|
|
||||||
confirm_metadata,
|
|
||||||
confirm_output,
|
|
||||||
confirm_total,
|
|
||||||
show_pubkey,
|
|
||||||
)
|
|
||||||
from trezor.utils import chunks
|
|
||||||
|
|
||||||
from .helpers import get_vote_tx_text
|
|
||||||
|
|
||||||
|
|
||||||
async def require_confirm_tx(ctx, to, value):
|
|
||||||
await confirm_output(
|
|
||||||
ctx,
|
|
||||||
to,
|
|
||||||
format_coin_amount(value),
|
|
||||||
font_amount=ui.BOLD,
|
|
||||||
to_str="\nto\n",
|
|
||||||
br_code=ButtonRequestType.SignTx,
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
async def require_confirm_delegate_registration(ctx, delegate_name):
|
|
||||||
await confirm_metadata(
|
|
||||||
ctx,
|
|
||||||
"confirm_delegate",
|
|
||||||
title="Confirm transaction",
|
|
||||||
content="Do you really want to register a delegate?\n{}",
|
|
||||||
param="\n".join(chunks(delegate_name, 20)),
|
|
||||||
param_font=ui.BOLD,
|
|
||||||
hide_continue=True,
|
|
||||||
br_code=ButtonRequestType.SignTx,
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
async def require_confirm_vote_tx(ctx, votes):
|
|
||||||
await confirm_metadata(
|
|
||||||
ctx,
|
|
||||||
"confirm_vote",
|
|
||||||
title="Confirm transaction",
|
|
||||||
content="\n".join(get_vote_tx_text(votes)),
|
|
||||||
hide_continue=True,
|
|
||||||
br_code=ButtonRequestType.SignTx,
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
async def require_confirm_public_key(ctx, public_key):
|
|
||||||
return await show_pubkey(ctx, hexlify(public_key).decode())
|
|
||||||
|
|
||||||
|
|
||||||
async def require_confirm_multisig(ctx, multisignature):
|
|
||||||
content = "Keys group length: %s\nLife time: %s\nMin: %s" % (
|
|
||||||
len(multisignature.keys_group),
|
|
||||||
multisignature.life_time,
|
|
||||||
multisignature.min,
|
|
||||||
)
|
|
||||||
await confirm_metadata(
|
|
||||||
ctx,
|
|
||||||
"confirm_multisig",
|
|
||||||
title="Confirm transaction",
|
|
||||||
content=content,
|
|
||||||
hide_continue=True,
|
|
||||||
br_code=ButtonRequestType.SignTx,
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
async def require_confirm_fee(ctx, value, fee):
|
|
||||||
await confirm_total(
|
|
||||||
ctx,
|
|
||||||
total_amount=format_coin_amount(value),
|
|
||||||
total_label="",
|
|
||||||
fee_amount=format_coin_amount(fee),
|
|
||||||
fee_label="\nfee:\n",
|
|
||||||
br_code=ButtonRequestType.ConfirmOutput,
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
def format_coin_amount(value):
|
|
||||||
return "%s LSK" % format_amount(value, 8)
|
|
@ -1,35 +0,0 @@
|
|||||||
from trezor.crypto.curve import ed25519
|
|
||||||
from trezor.crypto.hashlib import sha256
|
|
||||||
from trezor.messages import LiskMessageSignature
|
|
||||||
from trezor.ui.layouts import confirm_signverify
|
|
||||||
from trezor.utils import HashWriter
|
|
||||||
|
|
||||||
from apps.common import paths
|
|
||||||
from apps.common.keychain import auto_keychain
|
|
||||||
from apps.common.signverify import decode_message
|
|
||||||
from apps.common.writers import write_bitcoin_varint
|
|
||||||
|
|
||||||
|
|
||||||
def message_digest(message):
|
|
||||||
h = HashWriter(sha256())
|
|
||||||
signed_message_header = "Lisk Signed Message:\n"
|
|
||||||
write_bitcoin_varint(h, len(signed_message_header))
|
|
||||||
h.extend(signed_message_header)
|
|
||||||
write_bitcoin_varint(h, len(message))
|
|
||||||
h.extend(message)
|
|
||||||
return sha256(h.get_digest()).digest()
|
|
||||||
|
|
||||||
|
|
||||||
@auto_keychain(__name__)
|
|
||||||
async def sign_message(ctx, msg, keychain):
|
|
||||||
await paths.validate_path(ctx, keychain, msg.address_n)
|
|
||||||
await confirm_signverify(ctx, "Lisk", decode_message(msg.message))
|
|
||||||
|
|
||||||
node = keychain.derive(msg.address_n)
|
|
||||||
seckey = node.private_key()
|
|
||||||
pubkey = node.public_key()
|
|
||||||
pubkey = pubkey[1:] # skip ed25519 pubkey marker
|
|
||||||
|
|
||||||
signature = ed25519.sign(seckey, message_digest(msg.message))
|
|
||||||
|
|
||||||
return LiskMessageSignature(public_key=pubkey, signature=signature)
|
|
@ -1,150 +0,0 @@
|
|||||||
import ustruct
|
|
||||||
|
|
||||||
from trezor import wire
|
|
||||||
from trezor.crypto.curve import ed25519
|
|
||||||
from trezor.crypto.hashlib import sha256
|
|
||||||
from trezor.enums import LiskTransactionType
|
|
||||||
from trezor.messages import LiskSignedTx
|
|
||||||
from trezor.utils import HashWriter
|
|
||||||
|
|
||||||
from apps.common import paths
|
|
||||||
from apps.common.keychain import auto_keychain
|
|
||||||
|
|
||||||
from . import layout
|
|
||||||
from .helpers import get_address_from_public_key
|
|
||||||
|
|
||||||
|
|
||||||
@auto_keychain(__name__)
|
|
||||||
async def sign_tx(ctx, msg, keychain):
|
|
||||||
await paths.validate_path(ctx, keychain, msg.address_n)
|
|
||||||
|
|
||||||
pubkey, seckey = _get_keys(keychain, msg)
|
|
||||||
transaction = _update_raw_tx(msg.transaction, pubkey)
|
|
||||||
|
|
||||||
try:
|
|
||||||
await _require_confirm_by_type(ctx, transaction)
|
|
||||||
except AttributeError:
|
|
||||||
raise wire.DataError("The transaction has invalid asset data field")
|
|
||||||
|
|
||||||
await layout.require_confirm_fee(ctx, transaction.amount, transaction.fee)
|
|
||||||
|
|
||||||
txbytes = _get_transaction_bytes(transaction)
|
|
||||||
txhash = HashWriter(sha256())
|
|
||||||
for field in txbytes:
|
|
||||||
txhash.extend(field)
|
|
||||||
digest = txhash.get_digest()
|
|
||||||
|
|
||||||
signature = ed25519.sign(seckey, digest)
|
|
||||||
|
|
||||||
return LiskSignedTx(signature=signature)
|
|
||||||
|
|
||||||
|
|
||||||
def _get_keys(keychain, msg):
|
|
||||||
node = keychain.derive(msg.address_n)
|
|
||||||
|
|
||||||
seckey = node.private_key()
|
|
||||||
pubkey = node.public_key()
|
|
||||||
pubkey = pubkey[1:] # skip ed25519 pubkey marker
|
|
||||||
|
|
||||||
return pubkey, seckey
|
|
||||||
|
|
||||||
|
|
||||||
def _update_raw_tx(transaction, pubkey):
|
|
||||||
# If device is using for second signature sender_public_key must be exist in transaction
|
|
||||||
if not transaction.sender_public_key:
|
|
||||||
transaction.sender_public_key = pubkey
|
|
||||||
|
|
||||||
# For CastVotes transactions, recipientId should be equal to transaction
|
|
||||||
# creator address.
|
|
||||||
if transaction.type == LiskTransactionType.CastVotes:
|
|
||||||
if not transaction.recipient_id:
|
|
||||||
transaction.recipient_id = get_address_from_public_key(pubkey)
|
|
||||||
|
|
||||||
return transaction
|
|
||||||
|
|
||||||
|
|
||||||
async def _require_confirm_by_type(ctx, transaction):
|
|
||||||
|
|
||||||
if transaction.type == LiskTransactionType.Transfer:
|
|
||||||
return await layout.require_confirm_tx(
|
|
||||||
ctx, transaction.recipient_id, transaction.amount
|
|
||||||
)
|
|
||||||
|
|
||||||
if transaction.type == LiskTransactionType.RegisterDelegate:
|
|
||||||
return await layout.require_confirm_delegate_registration(
|
|
||||||
ctx, transaction.asset.delegate.username
|
|
||||||
)
|
|
||||||
|
|
||||||
if transaction.type == LiskTransactionType.CastVotes:
|
|
||||||
return await layout.require_confirm_vote_tx(ctx, transaction.asset.votes)
|
|
||||||
|
|
||||||
if transaction.type == LiskTransactionType.RegisterSecondPassphrase:
|
|
||||||
return await layout.require_confirm_public_key(
|
|
||||||
ctx, transaction.asset.signature.public_key
|
|
||||||
)
|
|
||||||
|
|
||||||
if transaction.type == LiskTransactionType.RegisterMultisignatureAccount:
|
|
||||||
return await layout.require_confirm_multisig(
|
|
||||||
ctx, transaction.asset.multisignature
|
|
||||||
)
|
|
||||||
|
|
||||||
raise wire.DataError("Invalid transaction type")
|
|
||||||
|
|
||||||
|
|
||||||
def _get_transaction_bytes(tx):
|
|
||||||
|
|
||||||
# Required transaction parameters
|
|
||||||
t_type = ustruct.pack("<b", tx.type)
|
|
||||||
t_timestamp = ustruct.pack("<i", tx.timestamp)
|
|
||||||
t_sender_public_key = tx.sender_public_key
|
|
||||||
t_requester_public_key = tx.requester_public_key or b""
|
|
||||||
|
|
||||||
if not tx.recipient_id:
|
|
||||||
# Value can be empty string
|
|
||||||
t_recipient_id = ustruct.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("<Q", tx.amount)
|
|
||||||
t_asset = _get_asset_data_bytes(tx)
|
|
||||||
t_signature = tx.signature or b""
|
|
||||||
|
|
||||||
return (
|
|
||||||
t_type,
|
|
||||||
t_timestamp,
|
|
||||||
t_sender_public_key,
|
|
||||||
t_requester_public_key,
|
|
||||||
t_recipient_id,
|
|
||||||
t_amount,
|
|
||||||
t_asset,
|
|
||||||
t_signature,
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
def _get_asset_data_bytes(msg):
|
|
||||||
|
|
||||||
if msg.type == LiskTransactionType.Transfer:
|
|
||||||
# Transfer transaction have optional data field
|
|
||||||
if msg.asset.data is not None:
|
|
||||||
return msg.asset.data.encode()
|
|
||||||
else:
|
|
||||||
return b""
|
|
||||||
|
|
||||||
if msg.type == LiskTransactionType.RegisterDelegate:
|
|
||||||
return msg.asset.delegate.username.encode()
|
|
||||||
|
|
||||||
if msg.type == LiskTransactionType.CastVotes:
|
|
||||||
return ("".join(msg.asset.votes)).encode()
|
|
||||||
|
|
||||||
if msg.type == LiskTransactionType.RegisterSecondPassphrase:
|
|
||||||
return msg.asset.signature.public_key
|
|
||||||
|
|
||||||
if msg.type == LiskTransactionType.RegisterMultisignatureAccount:
|
|
||||||
data = b""
|
|
||||||
data += ustruct.pack("<b", msg.asset.multisignature.min)
|
|
||||||
data += ustruct.pack("<b", msg.asset.multisignature.life_time)
|
|
||||||
data += ("".join(msg.asset.multisignature.keys_group)).encode()
|
|
||||||
return data
|
|
||||||
|
|
||||||
raise wire.DataError("Invalid transaction type")
|
|
@ -1,21 +0,0 @@
|
|||||||
from trezor import wire
|
|
||||||
from trezor.crypto.curve import ed25519
|
|
||||||
from trezor.messages import Success
|
|
||||||
from trezor.ui.layouts import confirm_signverify
|
|
||||||
|
|
||||||
from apps.common.signverify import decode_message
|
|
||||||
|
|
||||||
from .helpers import get_address_from_public_key
|
|
||||||
from .sign_message import message_digest
|
|
||||||
|
|
||||||
|
|
||||||
async def verify_message(ctx, msg):
|
|
||||||
digest = message_digest(msg.message)
|
|
||||||
verified = ed25519.verify(msg.public_key, msg.signature, digest)
|
|
||||||
if not verified:
|
|
||||||
raise wire.ProcessError("Invalid signature")
|
|
||||||
|
|
||||||
address = get_address_from_public_key(msg.public_key)
|
|
||||||
await confirm_signverify(ctx, "Lisk", decode_message(msg.message), address=address)
|
|
||||||
|
|
||||||
return Success(message="Message verified")
|
|
@ -1,12 +0,0 @@
|
|||||||
# Automatically generated by pb2py
|
|
||||||
# fmt: off
|
|
||||||
# isort:skip_file
|
|
||||||
|
|
||||||
Transfer = 0
|
|
||||||
RegisterSecondPassphrase = 1
|
|
||||||
RegisterDelegate = 2
|
|
||||||
CastVotes = 3
|
|
||||||
RegisterMultisignatureAccount = 4
|
|
||||||
CreateDapp = 5
|
|
||||||
TransferIntoDapp = 6
|
|
||||||
TransferOutOfDapp = 7
|
|
Loading…
Reference in new issue