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