mirror of
https://github.com/trezor/trezor-firmware.git
synced 2025-05-28 03:38:46 +00:00
feat(core): update most apps to use path schemas
This commit is contained in:
parent
4ca8f7b0d6
commit
f5c8138df6
@ -1,8 +1,11 @@
|
||||
from trezor import wire
|
||||
from trezor.messages import MessageType
|
||||
|
||||
from apps.common.paths import PATTERN_BIP44
|
||||
|
||||
CURVE = "secp256k1"
|
||||
SLIP44_ID = 714
|
||||
PATTERN = PATTERN_BIP44
|
||||
|
||||
|
||||
def boot() -> None:
|
||||
|
@ -2,23 +2,21 @@ from trezor.messages.BinanceAddress import BinanceAddress
|
||||
from trezor.messages.BinanceGetAddress import BinanceGetAddress
|
||||
|
||||
from apps.common import paths
|
||||
from apps.common.keychain import Keychain, with_slip44_keychain
|
||||
from apps.common.keychain import Keychain, auto_keychain
|
||||
from apps.common.layout import address_n_to_str, show_address, show_qr
|
||||
|
||||
from . import CURVE, SLIP44_ID, helpers
|
||||
from .helpers import address_from_public_key
|
||||
|
||||
|
||||
@with_slip44_keychain(SLIP44_ID, CURVE, allow_testnet=True)
|
||||
@auto_keychain(__name__)
|
||||
async def get_address(ctx, msg: BinanceGetAddress, keychain: Keychain):
|
||||
HRP = "bnb"
|
||||
|
||||
await paths.validate_path(
|
||||
ctx, helpers.validate_full_path, keychain, msg.address_n, CURVE
|
||||
)
|
||||
await paths.validate_path(ctx, keychain, msg.address_n)
|
||||
|
||||
node = keychain.derive(msg.address_n)
|
||||
pubkey = node.public_key()
|
||||
address = helpers.address_from_public_key(pubkey, HRP)
|
||||
address = address_from_public_key(pubkey, HRP)
|
||||
if msg.show_display:
|
||||
desc = address_n_to_str(msg.address_n)
|
||||
while True:
|
||||
|
@ -2,16 +2,12 @@ from trezor.messages.BinanceGetPublicKey import BinanceGetPublicKey
|
||||
from trezor.messages.BinancePublicKey import BinancePublicKey
|
||||
|
||||
from apps.common import layout, paths
|
||||
from apps.common.keychain import Keychain, with_slip44_keychain
|
||||
|
||||
from . import CURVE, SLIP44_ID, helpers
|
||||
from apps.common.keychain import Keychain, auto_keychain
|
||||
|
||||
|
||||
@with_slip44_keychain(SLIP44_ID, CURVE, allow_testnet=True)
|
||||
@auto_keychain(__name__)
|
||||
async def get_public_key(ctx, msg: BinanceGetPublicKey, keychain: Keychain):
|
||||
await paths.validate_path(
|
||||
ctx, helpers.validate_full_path, keychain, msg.address_n, CURVE
|
||||
)
|
||||
await paths.validate_path(ctx, keychain, msg.address_n)
|
||||
node = keychain.derive(msg.address_n)
|
||||
pubkey = node.public_key()
|
||||
|
||||
|
@ -8,8 +8,6 @@ from trezor.messages.BinanceOrderMsg import BinanceOrderMsg
|
||||
from trezor.messages.BinanceSignTx import BinanceSignTx
|
||||
from trezor.messages.BinanceTransferMsg import BinanceTransferMsg
|
||||
|
||||
from apps.common import HARDENED
|
||||
|
||||
ENVELOPE_BLUEPRINT = '{{"account_number":"{account_number}","chain_id":"{chain_id}","data":null,"memo":"{memo}","msgs":[{msgs}],"sequence":"{sequence}","source":"{source}"}}'
|
||||
MSG_TRANSFER_BLUEPRINT = '{{"inputs":[{inputs}],"outputs":[{outputs}]}}'
|
||||
MSG_NEWORDER_BLUEPRINT = '{{"id":"{id}","ordertype":{ordertype},"price":{price},"quantity":{quantity},"sender":"{sender}","side":{side},"symbol":"{symbol}","timeinforce":{timeinforce}}}'
|
||||
@ -91,25 +89,3 @@ def address_from_public_key(pubkey: bytes, hrp: str) -> str:
|
||||
convertedbits = bech32.convertbits(h, 8, 5, False)
|
||||
|
||||
return bech32.bech32_encode(hrp, convertedbits)
|
||||
|
||||
|
||||
def validate_full_path(path: list) -> bool:
|
||||
"""
|
||||
Validates derivation path to equal 44'/714'/a'/0/0,
|
||||
where `a` is an account index from 0 to 1 000 000.
|
||||
Similar to Ethereum this should be 44'/714'/a', but for
|
||||
compatibility with other HW vendors we use 44'/714'/a'/0/0.
|
||||
"""
|
||||
if len(path) != 5:
|
||||
return False
|
||||
if path[0] != 44 | HARDENED:
|
||||
return False
|
||||
if path[1] != 714 | HARDENED:
|
||||
return False
|
||||
if path[2] < HARDENED or path[2] > 1000000 | HARDENED:
|
||||
return False
|
||||
if path[3] != 0:
|
||||
return False
|
||||
if path[4] != 0:
|
||||
return False
|
||||
return True
|
||||
|
@ -9,20 +9,18 @@ from trezor.messages.BinanceTransferMsg import BinanceTransferMsg
|
||||
from trezor.messages.BinanceTxRequest import BinanceTxRequest
|
||||
|
||||
from apps.common import paths
|
||||
from apps.common.keychain import Keychain, with_slip44_keychain
|
||||
from apps.common.keychain import Keychain, auto_keychain
|
||||
|
||||
from . import CURVE, SLIP44_ID, helpers, layout
|
||||
from . import helpers, layout
|
||||
|
||||
|
||||
@with_slip44_keychain(SLIP44_ID, CURVE, allow_testnet=True)
|
||||
@auto_keychain(__name__)
|
||||
async def sign_tx(ctx, envelope, keychain: Keychain):
|
||||
# create transaction message -> sign it -> create signature/pubkey message -> serialize all
|
||||
if envelope.msg_count > 1:
|
||||
raise wire.DataError("Multiple messages not supported.")
|
||||
await paths.validate_path(
|
||||
ctx, helpers.validate_full_path, keychain, envelope.address_n, CURVE
|
||||
)
|
||||
|
||||
await paths.validate_path(ctx, keychain, envelope.address_n)
|
||||
node = keychain.derive(envelope.address_n)
|
||||
|
||||
tx_req = BinanceTxRequest()
|
||||
|
@ -1,8 +1,11 @@
|
||||
from trezor import wire
|
||||
from trezor.messages import MessageType
|
||||
|
||||
from apps.common.paths import PATTERN_BIP44
|
||||
|
||||
CURVE = "secp256k1"
|
||||
SLIP44_ID = 194
|
||||
PATTERN = PATTERN_BIP44
|
||||
|
||||
|
||||
def boot() -> None:
|
||||
|
@ -4,10 +4,9 @@ from trezor.messages.EosGetPublicKey import EosGetPublicKey
|
||||
from trezor.messages.EosPublicKey import EosPublicKey
|
||||
|
||||
from apps.common import paths
|
||||
from apps.common.keychain import Keychain, with_slip44_keychain
|
||||
from apps.common.keychain import Keychain, auto_keychain
|
||||
|
||||
from . import CURVE, SLIP44_ID
|
||||
from .helpers import public_key_to_wif, validate_full_path
|
||||
from .helpers import public_key_to_wif
|
||||
from .layout import require_get_public_key
|
||||
|
||||
if False:
|
||||
@ -22,11 +21,11 @@ def _get_public_key(node: bip32.HDNode) -> Tuple[str, bytes]:
|
||||
return wif, public_key
|
||||
|
||||
|
||||
@with_slip44_keychain(SLIP44_ID, CURVE)
|
||||
@auto_keychain(__name__)
|
||||
async def get_public_key(
|
||||
ctx: wire.Context, msg: EosGetPublicKey, keychain: Keychain
|
||||
) -> EosPublicKey:
|
||||
await paths.validate_path(ctx, validate_full_path, keychain, msg.address_n, CURVE)
|
||||
await paths.validate_path(ctx, keychain, msg.address_n)
|
||||
|
||||
node = keychain.derive(msg.address_n)
|
||||
wif, public_key = _get_public_key(node)
|
||||
|
@ -2,8 +2,6 @@ from trezor import wire
|
||||
from trezor.crypto import base58
|
||||
from trezor.messages.EosAsset import EosAsset
|
||||
|
||||
from apps.common import HARDENED
|
||||
|
||||
|
||||
def base58_encode(prefix: str, sig_prefix: str, data: bytes) -> str:
|
||||
b58 = base58.encode(data + base58.ripemd160_32(data + sig_prefix.encode()))
|
||||
@ -42,28 +40,6 @@ def eos_asset_to_string(asset: EosAsset) -> str:
|
||||
return "{} {}".format(amount_digits, symbol)
|
||||
|
||||
|
||||
def validate_full_path(path: list) -> bool:
|
||||
"""
|
||||
Validates derivation path to equal 44'/194'/a'/0/0,
|
||||
where `a` is an account index from 0 to 1 000 000.
|
||||
Similar to Ethereum this should be 44'/194'/a', but for
|
||||
compatibility with other HW vendors we use 44'/194'/a'/0/0.
|
||||
"""
|
||||
if len(path) != 5:
|
||||
return False
|
||||
if path[0] != 44 | HARDENED:
|
||||
return False
|
||||
if path[1] != 194 | HARDENED:
|
||||
return False
|
||||
if path[2] < HARDENED or path[2] > 1000000 | HARDENED:
|
||||
return False
|
||||
if path[3] != 0:
|
||||
return False
|
||||
if path[4] != 0:
|
||||
return False
|
||||
return True
|
||||
|
||||
|
||||
def public_key_to_wif(pub_key: bytes) -> str:
|
||||
if pub_key[0] == 0x04 and len(pub_key) == 65:
|
||||
head = b"\x03" if pub_key[64] & 0x01 else b"\x02"
|
||||
|
@ -8,15 +8,15 @@ from trezor.messages.EosTxActionRequest import EosTxActionRequest
|
||||
from trezor.utils import HashWriter
|
||||
|
||||
from apps.common import paths
|
||||
from apps.common.keychain import Keychain, with_slip44_keychain
|
||||
from apps.common.keychain import Keychain, auto_keychain
|
||||
|
||||
from . import CURVE, SLIP44_ID, writers
|
||||
from . import writers
|
||||
from .actions import process_action
|
||||
from .helpers import base58_encode, validate_full_path
|
||||
from .helpers import base58_encode
|
||||
from .layout import require_sign_tx
|
||||
|
||||
|
||||
@with_slip44_keychain(SLIP44_ID, CURVE)
|
||||
@auto_keychain(__name__)
|
||||
async def sign_tx(ctx: wire.Context, msg: EosSignTx, keychain: Keychain) -> EosSignedTx:
|
||||
if msg.chain_id is None:
|
||||
raise wire.DataError("No chain id")
|
||||
@ -25,7 +25,7 @@ async def sign_tx(ctx: wire.Context, msg: EosSignTx, keychain: Keychain) -> EosS
|
||||
if msg.num_actions is None or msg.num_actions == 0:
|
||||
raise wire.DataError("No actions")
|
||||
|
||||
await paths.validate_path(ctx, validate_full_path, keychain, msg.address_n, CURVE)
|
||||
await paths.validate_path(ctx, keychain, msg.address_n)
|
||||
|
||||
node = keychain.derive(msg.address_n)
|
||||
sha = HashWriter(sha256())
|
||||
|
@ -2,59 +2,6 @@ from ubinascii import unhexlify
|
||||
|
||||
from trezor import wire
|
||||
|
||||
from apps.common import HARDENED, paths
|
||||
|
||||
from . import networks
|
||||
|
||||
|
||||
"""
|
||||
We believe Ethereum should use 44'/60'/a' for everything, because it is
|
||||
account-based, rather than UTXO-based. Unfortunately, lot of Ethereum
|
||||
tools (MEW, Metamask) do not use such scheme and set a = 0 and then
|
||||
iterate the address index i. Therefore for compatibility reasons we use
|
||||
the same scheme: 44'/60'/0'/0/i and only the i is being iterated.
|
||||
"""
|
||||
|
||||
|
||||
def validate_path_for_get_public_key(path: list) -> bool:
|
||||
"""
|
||||
This should be 44'/60'/0', but other non-hardened items are allowed.
|
||||
"""
|
||||
length = len(path)
|
||||
if length < 3 or length > 5:
|
||||
return False
|
||||
if path[0] != 44 | HARDENED:
|
||||
return False
|
||||
if path[1] not in networks.all_slip44_ids_hardened():
|
||||
return False
|
||||
if path[2] != 0 | HARDENED:
|
||||
return False
|
||||
if length > 3 and paths.is_hardened(path[3]):
|
||||
return False
|
||||
if length > 4 and paths.is_hardened(path[4]):
|
||||
return False
|
||||
return True
|
||||
|
||||
|
||||
def validate_full_path(path: list) -> bool:
|
||||
"""
|
||||
Validates derivation path to equal 44'/60'/0'/0/i,
|
||||
where `i` is an address index from 0 to 1 000 000.
|
||||
"""
|
||||
if len(path) != 5:
|
||||
return False
|
||||
if path[0] != 44 | HARDENED:
|
||||
return False
|
||||
if path[1] not in networks.all_slip44_ids_hardened():
|
||||
return False
|
||||
if path[2] != 0 | HARDENED:
|
||||
return False
|
||||
if path[3] != 0:
|
||||
return False
|
||||
if path[4] > 1000000:
|
||||
return False
|
||||
return True
|
||||
|
||||
|
||||
def address_from_bytes(address_bytes: bytes, network=None) -> str:
|
||||
"""
|
||||
|
@ -5,14 +5,14 @@ from trezor.messages.EthereumAddress import EthereumAddress
|
||||
from apps.common import paths
|
||||
from apps.common.layout import address_n_to_str, show_address, show_qr
|
||||
|
||||
from . import CURVE, networks
|
||||
from .address import address_from_bytes, validate_full_path
|
||||
from .keychain import with_keychain_from_path
|
||||
from . import networks
|
||||
from .address import address_from_bytes
|
||||
from .keychain import PATTERN_ADDRESS, with_keychain_from_path
|
||||
|
||||
|
||||
@with_keychain_from_path
|
||||
@with_keychain_from_path(PATTERN_ADDRESS)
|
||||
async def get_address(ctx, msg, keychain):
|
||||
await paths.validate_path(ctx, validate_full_path, keychain, msg.address_n, CURVE)
|
||||
await paths.validate_path(ctx, keychain, msg.address_n)
|
||||
|
||||
node = keychain.derive(msg.address_n)
|
||||
seckey = node.private_key()
|
||||
|
@ -3,15 +3,12 @@ from trezor.messages.HDNodeType import HDNodeType
|
||||
|
||||
from apps.common import coins, layout, paths
|
||||
|
||||
from . import CURVE, address
|
||||
from .keychain import with_keychain_from_path
|
||||
from .keychain import PATTERN_PUBKEY, with_keychain_from_path
|
||||
|
||||
|
||||
@with_keychain_from_path
|
||||
@with_keychain_from_path(PATTERN_PUBKEY)
|
||||
async def get_public_key(ctx, msg, keychain):
|
||||
await paths.validate_path(
|
||||
ctx, address.validate_path_for_get_public_key, keychain, msg.address_n, CURVE
|
||||
)
|
||||
await paths.validate_path(ctx, keychain, msg.address_n)
|
||||
node = keychain.derive(msg.address_n)
|
||||
|
||||
# we use the Bitcoin format for Ethereum xpubs
|
||||
|
@ -1,12 +1,12 @@
|
||||
from trezor import wire
|
||||
|
||||
from apps.common import HARDENED, seed
|
||||
from apps.common import HARDENED, paths
|
||||
from apps.common.keychain import get_keychain
|
||||
|
||||
from . import CURVE, networks
|
||||
|
||||
if False:
|
||||
from typing import List
|
||||
from typing import Callable
|
||||
from typing_extensions import Protocol
|
||||
|
||||
from protobuf import MessageType
|
||||
@ -16,48 +16,76 @@ if False:
|
||||
from apps.common.keychain import MsgOut, Handler, HandlerWithKeychain
|
||||
|
||||
class MsgWithAddressN(MessageType, Protocol):
|
||||
address_n = ... # type: List[int]
|
||||
address_n = ... # type: paths.Bip32Path
|
||||
|
||||
|
||||
async def from_address_n(ctx: wire.Context, address_n: List[int]) -> seed.Keychain:
|
||||
# We believe Ethereum should use 44'/60'/a' for everything, because it is
|
||||
# account-based, rather than UTXO-based. Unfortunately, lot of Ethereum
|
||||
# tools (MEW, Metamask) do not use such scheme and set a = 0 and then
|
||||
# iterate the address index i. Therefore for compatibility reasons we use
|
||||
# the same scheme: 44'/60'/0'/0/i and only the i is being iterated.
|
||||
|
||||
PATTERN_ADDRESS = "m/44'/coin_type'/0'/0/address_index"
|
||||
PATTERN_PUBKEY = "m/44'/coin_type'/0'/*"
|
||||
|
||||
|
||||
def _schema_from_address_n(
|
||||
pattern: str, address_n: paths.Bip32Path
|
||||
) -> paths.PathSchema:
|
||||
if len(address_n) < 2:
|
||||
raise wire.DataError("Forbidden key path")
|
||||
return paths.SCHEMA_NO_MATCH
|
||||
|
||||
slip44_hardened = address_n[1]
|
||||
if slip44_hardened not in networks.all_slip44_ids_hardened():
|
||||
raise wire.DataError("Forbidden key path")
|
||||
namespace = [44 | HARDENED, slip44_hardened]
|
||||
return await get_keychain(ctx, CURVE, [namespace])
|
||||
return paths.SCHEMA_NO_MATCH
|
||||
|
||||
if not slip44_hardened & HARDENED:
|
||||
return paths.SCHEMA_ANY_PATH
|
||||
|
||||
slip44_id = slip44_hardened - HARDENED
|
||||
return paths.PathSchema(pattern, slip44_id)
|
||||
|
||||
|
||||
def with_keychain_from_path(
|
||||
func: HandlerWithKeychain[MsgWithAddressN, MsgOut]
|
||||
) -> Handler[MsgWithAddressN, MsgOut]:
|
||||
async def wrapper(ctx: wire.Context, msg: MsgWithAddressN) -> MsgOut:
|
||||
keychain = await from_address_n(ctx, msg.address_n)
|
||||
with keychain:
|
||||
return await func(ctx, msg, keychain)
|
||||
pattern: str,
|
||||
) -> Callable[
|
||||
[HandlerWithKeychain[MsgWithAddressN, MsgOut]], Handler[MsgWithAddressN, MsgOut]
|
||||
]:
|
||||
def decorator(
|
||||
func: HandlerWithKeychain[MsgWithAddressN, MsgOut]
|
||||
) -> Handler[MsgWithAddressN, MsgOut]:
|
||||
async def wrapper(ctx: wire.Context, msg: MsgWithAddressN) -> MsgOut:
|
||||
schema = _schema_from_address_n(pattern, msg.address_n)
|
||||
keychain = await get_keychain(ctx, CURVE, [schema])
|
||||
with keychain:
|
||||
return await func(ctx, msg, keychain)
|
||||
|
||||
return wrapper
|
||||
return wrapper
|
||||
|
||||
return decorator
|
||||
|
||||
|
||||
def _schema_from_chain_id(msg: EthereumSignTx) -> paths.PathSchema:
|
||||
if msg.chain_id is None:
|
||||
return _schema_from_address_n(PATTERN_ADDRESS, msg.address_n)
|
||||
|
||||
info = networks.by_chain_id(msg.chain_id)
|
||||
if info is None:
|
||||
return paths.SCHEMA_NO_MATCH
|
||||
|
||||
slip44_id = info.slip44
|
||||
if networks.is_wanchain(msg.chain_id, msg.tx_type):
|
||||
slip44_id = networks.SLIP44_WANCHAIN
|
||||
return paths.PathSchema(PATTERN_ADDRESS, slip44_id)
|
||||
|
||||
|
||||
def with_keychain_from_chain_id(
|
||||
func: HandlerWithKeychain[EthereumSignTx, MsgOut]
|
||||
) -> Handler[EthereumSignTx, MsgOut]:
|
||||
# this is only for SignTx, and only PATTERN_ADDRESS is allowed
|
||||
async def wrapper(ctx: wire.Context, msg: EthereumSignTx) -> MsgOut:
|
||||
if msg.chain_id is None:
|
||||
keychain = await from_address_n(ctx, msg.address_n)
|
||||
else:
|
||||
info = networks.by_chain_id(msg.chain_id)
|
||||
if info is None:
|
||||
raise wire.DataError("Unsupported chain id")
|
||||
|
||||
slip44 = info.slip44
|
||||
if networks.is_wanchain(msg.chain_id, msg.tx_type):
|
||||
slip44 = networks.SLIP44_WANCHAIN
|
||||
|
||||
namespace = [44 | HARDENED, slip44 | HARDENED]
|
||||
keychain = await get_keychain(ctx, CURVE, [namespace])
|
||||
|
||||
schema = _schema_from_chain_id(msg)
|
||||
keychain = await get_keychain(ctx, CURVE, [schema])
|
||||
with keychain:
|
||||
return await func(ctx, msg, keychain)
|
||||
|
||||
|
@ -6,8 +6,8 @@ from trezor.utils import HashWriter
|
||||
from apps.common import paths
|
||||
from apps.common.signverify import require_confirm_sign_message
|
||||
|
||||
from . import CURVE, address
|
||||
from .keychain import with_keychain_from_path
|
||||
from . import address
|
||||
from .keychain import PATTERN_ADDRESS, with_keychain_from_path
|
||||
|
||||
|
||||
def message_digest(message):
|
||||
@ -19,11 +19,9 @@ def message_digest(message):
|
||||
return h.get_digest()
|
||||
|
||||
|
||||
@with_keychain_from_path
|
||||
@with_keychain_from_path(PATTERN_ADDRESS)
|
||||
async def sign_message(ctx, msg, keychain):
|
||||
await paths.validate_path(
|
||||
ctx, address.validate_full_path, keychain, msg.address_n, CURVE
|
||||
)
|
||||
await paths.validate_path(ctx, keychain, msg.address_n)
|
||||
await require_confirm_sign_message(ctx, "ETH", msg.message)
|
||||
|
||||
node = keychain.derive(msg.address_n)
|
||||
|
@ -9,8 +9,7 @@ from trezor.utils import HashWriter
|
||||
|
||||
from apps.common import paths
|
||||
|
||||
from . import CURVE, address, tokens
|
||||
from .address import validate_full_path
|
||||
from . import address, tokens
|
||||
from .keychain import with_keychain_from_chain_id
|
||||
from .layout import require_confirm_data, require_confirm_fee, require_confirm_tx
|
||||
|
||||
@ -22,7 +21,7 @@ MAX_CHAIN_ID = 2147483629
|
||||
async def sign_tx(ctx, msg, keychain):
|
||||
msg = sanitize(msg)
|
||||
check(msg)
|
||||
await paths.validate_path(ctx, validate_full_path, keychain, msg.address_n, CURVE)
|
||||
await paths.validate_path(ctx, keychain, msg.address_n)
|
||||
|
||||
data_total = msg.data_length
|
||||
|
||||
|
@ -1,8 +1,11 @@
|
||||
from trezor import wire
|
||||
from trezor.messages import MessageType
|
||||
|
||||
from apps.common.paths import PATTERN_SEP5
|
||||
|
||||
CURVE = "ed25519"
|
||||
SLIP44_ID = 134
|
||||
PATTERN = PATTERN_SEP5
|
||||
|
||||
|
||||
def boot() -> None:
|
||||
|
@ -1,16 +1,15 @@
|
||||
from trezor.messages.LiskAddress import LiskAddress
|
||||
|
||||
from apps.common import paths
|
||||
from apps.common.keychain import with_slip44_keychain
|
||||
from apps.common.keychain import auto_keychain
|
||||
from apps.common.layout import address_n_to_str, show_address, show_qr
|
||||
|
||||
from . import CURVE, SLIP44_ID
|
||||
from .helpers import get_address_from_public_key, validate_full_path
|
||||
from .helpers import get_address_from_public_key
|
||||
|
||||
|
||||
@with_slip44_keychain(SLIP44_ID, CURVE, allow_testnet=True)
|
||||
@auto_keychain(__name__)
|
||||
async def get_address(ctx, msg, keychain):
|
||||
await paths.validate_path(ctx, validate_full_path, keychain, msg.address_n, CURVE)
|
||||
await paths.validate_path(ctx, keychain, msg.address_n)
|
||||
|
||||
node = keychain.derive(msg.address_n)
|
||||
pubkey = node.public_key()
|
||||
|
@ -1,15 +1,12 @@
|
||||
from trezor.messages.LiskPublicKey import LiskPublicKey
|
||||
|
||||
from apps.common import layout, paths
|
||||
from apps.common.keychain import with_slip44_keychain
|
||||
|
||||
from . import CURVE, SLIP44_ID
|
||||
from .helpers import validate_full_path
|
||||
from apps.common.keychain import auto_keychain
|
||||
|
||||
|
||||
@with_slip44_keychain(SLIP44_ID, CURVE, allow_testnet=True)
|
||||
@auto_keychain(__name__)
|
||||
async def get_public_key(ctx, msg, keychain):
|
||||
await paths.validate_path(ctx, validate_full_path, keychain, msg.address_n, CURVE)
|
||||
await paths.validate_path(ctx, keychain, msg.address_n)
|
||||
|
||||
node = keychain.derive(msg.address_n)
|
||||
pubkey = node.public_key()
|
||||
|
@ -1,7 +1,5 @@
|
||||
from trezor.crypto.hashlib import sha256
|
||||
|
||||
from apps.common import HARDENED
|
||||
|
||||
|
||||
def get_address_from_public_key(pubkey):
|
||||
pubkeyhash = sha256(pubkey).digest()
|
||||
@ -31,19 +29,3 @@ def get_vote_tx_text(votes):
|
||||
|
||||
def _text_with_plural(txt, value):
|
||||
return "%s %s %s" % (txt, value, ("votes" if value != 1 else "vote"))
|
||||
|
||||
|
||||
def validate_full_path(path: list) -> bool:
|
||||
"""
|
||||
Validates derivation path to equal 44'/134'/a',
|
||||
where `a` is an account index from 0 to 1 000 000.
|
||||
"""
|
||||
if len(path) != 3:
|
||||
return False
|
||||
if path[0] != 44 | HARDENED:
|
||||
return False
|
||||
if path[1] != 134 | HARDENED:
|
||||
return False
|
||||
if path[2] < HARDENED or path[2] > 1000000 | HARDENED:
|
||||
return False
|
||||
return True
|
||||
|
@ -4,13 +4,10 @@ from trezor.messages.LiskMessageSignature import LiskMessageSignature
|
||||
from trezor.utils import HashWriter
|
||||
|
||||
from apps.common import paths
|
||||
from apps.common.keychain import with_slip44_keychain
|
||||
from apps.common.keychain import auto_keychain
|
||||
from apps.common.signverify import require_confirm_sign_message
|
||||
from apps.common.writers import write_bitcoin_varint
|
||||
|
||||
from . import CURVE, SLIP44_ID
|
||||
from .helpers import validate_full_path
|
||||
|
||||
|
||||
def message_digest(message):
|
||||
h = HashWriter(sha256())
|
||||
@ -22,9 +19,9 @@ def message_digest(message):
|
||||
return sha256(h.get_digest()).digest()
|
||||
|
||||
|
||||
@with_slip44_keychain(SLIP44_ID, CURVE, allow_testnet=True)
|
||||
@auto_keychain(__name__)
|
||||
async def sign_message(ctx, msg, keychain):
|
||||
await paths.validate_path(ctx, validate_full_path, keychain, msg.address_n, CURVE)
|
||||
await paths.validate_path(ctx, keychain, msg.address_n)
|
||||
await require_confirm_sign_message(ctx, "Lisk", msg.message)
|
||||
|
||||
node = keychain.derive(msg.address_n)
|
||||
|
@ -8,15 +8,15 @@ from trezor.messages.LiskSignedTx import LiskSignedTx
|
||||
from trezor.utils import HashWriter
|
||||
|
||||
from apps.common import paths
|
||||
from apps.common.keychain import with_slip44_keychain
|
||||
from apps.common.keychain import auto_keychain
|
||||
|
||||
from . import CURVE, SLIP44_ID, layout
|
||||
from .helpers import get_address_from_public_key, validate_full_path
|
||||
from . import layout
|
||||
from .helpers import get_address_from_public_key
|
||||
|
||||
|
||||
@with_slip44_keychain(SLIP44_ID, CURVE, allow_testnet=True)
|
||||
@auto_keychain(__name__)
|
||||
async def sign_tx(ctx, msg, keychain):
|
||||
await paths.validate_path(ctx, validate_full_path, keychain, msg.address_n, CURVE)
|
||||
await paths.validate_path(ctx, keychain, msg.address_n)
|
||||
|
||||
pubkey, seckey = _get_keys(keychain, msg)
|
||||
transaction = _update_raw_tx(msg.transaction, pubkey)
|
||||
|
@ -5,10 +5,11 @@ from trezor.ui.text import Text
|
||||
|
||||
from apps.common.confirm import require_confirm
|
||||
from apps.common.keychain import get_keychain
|
||||
from apps.common.paths import AlwaysMatchingSchema
|
||||
|
||||
|
||||
async def cipher_key_value(ctx, msg):
|
||||
keychain = await get_keychain(ctx, "secp256k1", [[]])
|
||||
keychain = await get_keychain(ctx, "secp256k1", [AlwaysMatchingSchema])
|
||||
|
||||
if len(msg.value) % 16 > 0:
|
||||
raise wire.DataError("Value length must be a multiple of 16")
|
||||
|
@ -9,6 +9,7 @@ from trezor.utils import chunks
|
||||
from apps.common import HARDENED
|
||||
from apps.common.confirm import require_confirm
|
||||
from apps.common.keychain import get_keychain
|
||||
from apps.common.paths import AlwaysMatchingSchema
|
||||
|
||||
from .sign_identity import serialize_identity, serialize_identity_without_proto
|
||||
|
||||
@ -17,7 +18,7 @@ async def get_ecdh_session_key(ctx, msg):
|
||||
if msg.ecdsa_curve_name is None:
|
||||
msg.ecdsa_curve_name = "secp256k1"
|
||||
|
||||
keychain = await get_keychain(ctx, msg.ecdsa_curve_name, [[]])
|
||||
keychain = await get_keychain(ctx, msg.ecdsa_curve_name, [AlwaysMatchingSchema])
|
||||
identity = serialize_identity(msg.identity)
|
||||
|
||||
await require_confirm_ecdh_session_key(ctx, msg.identity)
|
||||
|
@ -9,13 +9,14 @@ from trezor.utils import chunks
|
||||
from apps.common import HARDENED, coins
|
||||
from apps.common.confirm import require_confirm
|
||||
from apps.common.keychain import get_keychain
|
||||
from apps.common.paths import AlwaysMatchingSchema
|
||||
|
||||
|
||||
async def sign_identity(ctx, msg):
|
||||
if msg.ecdsa_curve_name is None:
|
||||
msg.ecdsa_curve_name = "secp256k1"
|
||||
|
||||
keychain = await get_keychain(ctx, msg.ecdsa_curve_name, [[]])
|
||||
keychain = await get_keychain(ctx, msg.ecdsa_curve_name, [AlwaysMatchingSchema])
|
||||
identity = serialize_identity(msg.identity)
|
||||
|
||||
await require_confirm_sign_identity(ctx, msg.identity, msg.challenge_visual)
|
||||
|
@ -1,8 +1,11 @@
|
||||
from trezor import wire
|
||||
from trezor.messages import MessageType
|
||||
|
||||
from apps.common.paths import PATTERN_SEP5
|
||||
|
||||
CURVE = "ed25519"
|
||||
SLIP44_ID = 128
|
||||
PATTERN = PATTERN_SEP5
|
||||
|
||||
|
||||
def boot() -> None:
|
||||
|
@ -1,19 +1,17 @@
|
||||
from trezor.messages.MoneroAddress import MoneroAddress
|
||||
|
||||
from apps.common import paths
|
||||
from apps.common.keychain import with_slip44_keychain
|
||||
from apps.common.keychain import auto_keychain
|
||||
from apps.common.layout import address_n_to_str, show_qr
|
||||
from apps.monero import CURVE, SLIP44_ID, misc
|
||||
from apps.monero import misc
|
||||
from apps.monero.layout import confirms
|
||||
from apps.monero.xmr import addresses, crypto, monero
|
||||
from apps.monero.xmr.networks import net_version
|
||||
|
||||
|
||||
@with_slip44_keychain(SLIP44_ID, CURVE, allow_testnet=True)
|
||||
@auto_keychain(__name__)
|
||||
async def get_address(ctx, msg, keychain):
|
||||
await paths.validate_path(
|
||||
ctx, misc.validate_full_path, keychain, msg.address_n, CURVE
|
||||
)
|
||||
await paths.validate_path(ctx, keychain, msg.address_n)
|
||||
|
||||
creds = misc.get_creds(keychain, msg.address_n, msg.network_type)
|
||||
addr = creds.address
|
||||
|
@ -20,8 +20,8 @@ from trezor.messages.MoneroGetTxKeyAck import MoneroGetTxKeyAck
|
||||
from trezor.messages.MoneroGetTxKeyRequest import MoneroGetTxKeyRequest
|
||||
|
||||
from apps.common import paths
|
||||
from apps.common.keychain import with_slip44_keychain
|
||||
from apps.monero import CURVE, SLIP44_ID, misc
|
||||
from apps.common.keychain import auto_keychain
|
||||
from apps.monero import misc
|
||||
from apps.monero.layout import confirms
|
||||
from apps.monero.xmr import crypto
|
||||
from apps.monero.xmr.crypto import chacha_poly
|
||||
@ -30,11 +30,9 @@ _GET_TX_KEY_REASON_TX_KEY = 0
|
||||
_GET_TX_KEY_REASON_TX_DERIVATION = 1
|
||||
|
||||
|
||||
@with_slip44_keychain(SLIP44_ID, CURVE, allow_testnet=True)
|
||||
@auto_keychain(__name__)
|
||||
async def get_tx_keys(ctx, msg: MoneroGetTxKeyRequest, keychain):
|
||||
await paths.validate_path(
|
||||
ctx, misc.validate_full_path, keychain, msg.address_n, CURVE
|
||||
)
|
||||
await paths.validate_path(ctx, keychain, msg.address_n)
|
||||
|
||||
do_deriv = msg.reason == _GET_TX_KEY_REASON_TX_DERIVATION
|
||||
await confirms.require_confirm_tx_key(ctx, export_key=not do_deriv)
|
||||
|
@ -2,17 +2,15 @@ from trezor.messages.MoneroGetWatchKey import MoneroGetWatchKey
|
||||
from trezor.messages.MoneroWatchKey import MoneroWatchKey
|
||||
|
||||
from apps.common import paths
|
||||
from apps.common.keychain import with_slip44_keychain
|
||||
from apps.monero import CURVE, SLIP44_ID, misc
|
||||
from apps.common.keychain import auto_keychain
|
||||
from apps.monero import misc
|
||||
from apps.monero.layout import confirms
|
||||
from apps.monero.xmr import crypto
|
||||
|
||||
|
||||
@with_slip44_keychain(SLIP44_ID, CURVE, allow_testnet=True)
|
||||
@auto_keychain(__name__)
|
||||
async def get_watch_only(ctx, msg: MoneroGetWatchKey, keychain):
|
||||
await paths.validate_path(
|
||||
ctx, misc.validate_full_path, keychain, msg.address_n, CURVE
|
||||
)
|
||||
await paths.validate_path(ctx, keychain, msg.address_n)
|
||||
|
||||
await confirms.require_confirm_watchkey(ctx)
|
||||
|
||||
|
@ -11,14 +11,14 @@ from trezor.messages.MoneroKeyImageSyncStepAck import MoneroKeyImageSyncStepAck
|
||||
from trezor.messages.MoneroKeyImageSyncStepRequest import MoneroKeyImageSyncStepRequest
|
||||
|
||||
from apps.common import paths
|
||||
from apps.common.keychain import with_slip44_keychain
|
||||
from apps.monero import CURVE, SLIP44_ID, misc
|
||||
from apps.common.keychain import auto_keychain
|
||||
from apps.monero import misc
|
||||
from apps.monero.layout import confirms
|
||||
from apps.monero.xmr import crypto, key_image, monero
|
||||
from apps.monero.xmr.crypto import chacha_poly
|
||||
|
||||
|
||||
@with_slip44_keychain(SLIP44_ID, CURVE, allow_testnet=True)
|
||||
@auto_keychain(__name__)
|
||||
async def key_image_sync(ctx, msg, keychain):
|
||||
state = KeyImageSync()
|
||||
|
||||
@ -45,9 +45,7 @@ class KeyImageSync:
|
||||
|
||||
|
||||
async def _init_step(s, ctx, msg, keychain):
|
||||
await paths.validate_path(
|
||||
ctx, misc.validate_full_path, keychain, msg.address_n, CURVE
|
||||
)
|
||||
await paths.validate_path(ctx, keychain, msg.address_n)
|
||||
|
||||
s.creds = misc.get_creds(keychain, msg.address_n, msg.network_type)
|
||||
|
||||
|
@ -10,14 +10,14 @@ from trezor.messages.MoneroLiveRefreshStepAck import MoneroLiveRefreshStepAck
|
||||
from trezor.messages.MoneroLiveRefreshStepRequest import MoneroLiveRefreshStepRequest
|
||||
|
||||
from apps.common import paths
|
||||
from apps.common.keychain import with_slip44_keychain
|
||||
from apps.monero import CURVE, SLIP44_ID, misc
|
||||
from apps.common.keychain import auto_keychain
|
||||
from apps.monero import misc
|
||||
from apps.monero.layout import confirms
|
||||
from apps.monero.xmr import crypto, key_image, monero
|
||||
from apps.monero.xmr.crypto import chacha_poly
|
||||
|
||||
|
||||
@with_slip44_keychain(SLIP44_ID, CURVE, allow_testnet=True)
|
||||
@auto_keychain(__name__)
|
||||
async def live_refresh(ctx, msg: MoneroLiveRefreshStartRequest, keychain):
|
||||
state = LiveRefreshState()
|
||||
|
||||
@ -47,9 +47,7 @@ class LiveRefreshState:
|
||||
async def _init_step(
|
||||
s: LiveRefreshState, ctx, msg: MoneroLiveRefreshStartRequest, keychain
|
||||
):
|
||||
await paths.validate_path(
|
||||
ctx, misc.validate_full_path, keychain, msg.address_n, CURVE
|
||||
)
|
||||
await paths.validate_path(ctx, keychain, msg.address_n)
|
||||
|
||||
if not storage.cache.get(storage.cache.APP_MONERO_LIVE_REFRESH):
|
||||
await confirms.require_confirm_live_refresh(ctx)
|
||||
|
@ -1,5 +1,3 @@
|
||||
from apps.common import HARDENED
|
||||
|
||||
if False:
|
||||
from typing import Tuple
|
||||
from apps.monero.xmr.types import Sc25519
|
||||
@ -18,22 +16,6 @@ def get_creds(keychain, address_n=None, network_type=None):
|
||||
return creds
|
||||
|
||||
|
||||
def validate_full_path(path: list) -> bool:
|
||||
"""
|
||||
Validates derivation path to equal 44'/128'/a',
|
||||
where `a` is an account index from 0 to 1 000 000.
|
||||
"""
|
||||
if len(path) != 3:
|
||||
return False
|
||||
if path[0] != 44 | HARDENED:
|
||||
return False
|
||||
if path[1] != 128 | HARDENED:
|
||||
return False
|
||||
if path[2] < HARDENED or path[2] > 1000000 | HARDENED:
|
||||
return False
|
||||
return True
|
||||
|
||||
|
||||
def compute_tx_key(
|
||||
spend_key_private: Sc25519,
|
||||
tx_prefix_hash: bytes,
|
||||
|
@ -3,12 +3,11 @@ import gc
|
||||
from trezor import log, utils, wire
|
||||
from trezor.messages import MessageType
|
||||
|
||||
from apps.common.keychain import with_slip44_keychain
|
||||
from apps.monero import CURVE, SLIP44_ID
|
||||
from apps.common.keychain import auto_keychain
|
||||
from apps.monero.signing.state import State
|
||||
|
||||
|
||||
@with_slip44_keychain(SLIP44_ID, CURVE, allow_testnet=True)
|
||||
@auto_keychain(__name__)
|
||||
async def sign_tx(ctx, received_msg, keychain):
|
||||
state = State(ctx)
|
||||
mods = utils.unimport_begin()
|
||||
|
@ -4,7 +4,7 @@ Initializes a new transaction.
|
||||
|
||||
import gc
|
||||
|
||||
from apps.monero import CURVE, misc, signing
|
||||
from apps.monero import misc, signing
|
||||
from apps.monero.layout import confirms
|
||||
from apps.monero.signing.state import State
|
||||
from apps.monero.xmr import crypto, monero
|
||||
@ -31,9 +31,7 @@ async def init_transaction(
|
||||
from apps.monero.signing import offloading_keys
|
||||
from apps.common import paths
|
||||
|
||||
await paths.validate_path(
|
||||
state.ctx, misc.validate_full_path, keychain, address_n, CURVE
|
||||
)
|
||||
await paths.validate_path(state.ctx, keychain, address_n)
|
||||
|
||||
state.creds = misc.get_creds(keychain, address_n, network_type)
|
||||
state.client_version = tsx_data.client_version or 0
|
||||
|
@ -1,9 +1,16 @@
|
||||
from trezor import wire
|
||||
from trezor.messages import MessageType
|
||||
|
||||
from apps.common.paths import PATTERN_SEP5
|
||||
|
||||
CURVE = "ed25519-keccak"
|
||||
SLIP44_ID = 43
|
||||
|
||||
PATTERNS = (
|
||||
PATTERN_SEP5,
|
||||
"m/44'/coin_type'/account'/0'/0'", # NanoWallet compatibility
|
||||
)
|
||||
|
||||
|
||||
def boot() -> None:
|
||||
wire.add(MessageType.NEMGetAddress, __name__, "get_address")
|
||||
|
@ -4,16 +4,16 @@ from apps.common.keychain import with_slip44_keychain
|
||||
from apps.common.layout import address_n_to_str, show_address, show_qr
|
||||
from apps.common.paths import validate_path
|
||||
|
||||
from . import CURVE, SLIP44_ID
|
||||
from . import CURVE, PATTERNS, SLIP44_ID
|
||||
from .helpers import check_path, get_network_str
|
||||
from .validators import validate_network
|
||||
|
||||
|
||||
@with_slip44_keychain(SLIP44_ID, CURVE, allow_testnet=True)
|
||||
@with_slip44_keychain(*PATTERNS, slip44_id=SLIP44_ID, curve=CURVE)
|
||||
async def get_address(ctx, msg, keychain):
|
||||
network = validate_network(msg.network)
|
||||
await validate_path(
|
||||
ctx, check_path, keychain, msg.address_n, CURVE, network=network
|
||||
ctx, keychain, msg.address_n, check_path(msg.address_n, msg.network)
|
||||
)
|
||||
|
||||
node = keychain.derive(msg.address_n)
|
||||
|
@ -1,6 +1,8 @@
|
||||
from micropython import const
|
||||
|
||||
from apps.common import HARDENED
|
||||
from apps.common import HARDENED, paths
|
||||
|
||||
from . import SLIP44_ID
|
||||
|
||||
NEM_NETWORK_MAINNET = const(0x68)
|
||||
NEM_NETWORK_TESTNET = const(0x98)
|
||||
@ -38,26 +40,18 @@ def get_network_str(network: int) -> str:
|
||||
return "Mijin"
|
||||
|
||||
|
||||
def check_path(path: list, network=None) -> bool:
|
||||
"""
|
||||
Validates derivation path to fit 44'/43'/a' or 44'/43'/a'/0'/0',
|
||||
where `a` is an account number. We believe the path should be
|
||||
44'/43'/a', but for compatibility reasons with NEM's NanoWallet
|
||||
we allow 44'/43'/a'/0'/0' as well.
|
||||
Testnet is also allowed: 44'/1'/a'{/0'/0'}
|
||||
"""
|
||||
length = len(path)
|
||||
if length != 3 and length != 5:
|
||||
def check_path(path: paths.Bip32Path, network: int) -> bool:
|
||||
"""Validates that the appropriate coin_type is set for the given network."""
|
||||
if len(path) < 2:
|
||||
return False
|
||||
if path[0] != 44 | HARDENED:
|
||||
return False
|
||||
if not (
|
||||
path[1] == 43 | HARDENED
|
||||
or (network == NEM_NETWORK_TESTNET and path[1] == 1 | HARDENED)
|
||||
):
|
||||
return False
|
||||
if path[2] < HARDENED or path[2] > 1000000 | HARDENED:
|
||||
return False
|
||||
if length == 5 and (path[3] != 0 | HARDENED or path[4] != 0 | HARDENED):
|
||||
return False
|
||||
return True
|
||||
|
||||
coin_type = path[1] - HARDENED
|
||||
|
||||
if network == NEM_NETWORK_TESTNET:
|
||||
return coin_type == 1
|
||||
|
||||
if network in (NEM_NETWORK_MAINNET, NEM_NETWORK_MIJIN):
|
||||
return coin_type == SLIP44_ID
|
||||
|
||||
# unknown network
|
||||
return False
|
||||
|
@ -7,22 +7,20 @@ from apps.common import seed
|
||||
from apps.common.keychain import with_slip44_keychain
|
||||
from apps.common.paths import validate_path
|
||||
|
||||
from . import CURVE, SLIP44_ID, mosaic, multisig, namespace, transfer
|
||||
from . import CURVE, PATTERNS, SLIP44_ID, mosaic, multisig, namespace, transfer
|
||||
from .helpers import NEM_HASH_ALG, check_path
|
||||
from .validators import validate
|
||||
|
||||
|
||||
@with_slip44_keychain(SLIP44_ID, CURVE, allow_testnet=True)
|
||||
@with_slip44_keychain(*PATTERNS, slip44_id=SLIP44_ID, curve=CURVE)
|
||||
async def sign_tx(ctx, msg: NEMSignTx, keychain):
|
||||
validate(msg)
|
||||
|
||||
await validate_path(
|
||||
ctx,
|
||||
check_path,
|
||||
keychain,
|
||||
msg.transaction.address_n,
|
||||
CURVE,
|
||||
network=msg.transaction.network,
|
||||
check_path(msg.transaction.address_n, msg.transaction.network),
|
||||
)
|
||||
|
||||
node = keychain.derive(msg.transaction.address_n)
|
||||
|
@ -1,8 +1,11 @@
|
||||
from trezor import wire
|
||||
from trezor.messages import MessageType
|
||||
|
||||
from apps.common.paths import PATTERN_BIP44
|
||||
|
||||
CURVE = "secp256k1"
|
||||
SLIP44_ID = 144
|
||||
PATTERN = PATTERN_BIP44
|
||||
|
||||
|
||||
def boot() -> None:
|
||||
|
@ -2,21 +2,19 @@ from trezor.messages.RippleAddress import RippleAddress
|
||||
from trezor.messages.RippleGetAddress import RippleGetAddress
|
||||
|
||||
from apps.common import paths
|
||||
from apps.common.keychain import with_slip44_keychain
|
||||
from apps.common.keychain import auto_keychain
|
||||
from apps.common.layout import address_n_to_str, show_address, show_qr
|
||||
|
||||
from . import CURVE, SLIP44_ID, helpers
|
||||
from .helpers import address_from_public_key
|
||||
|
||||
|
||||
@with_slip44_keychain(SLIP44_ID, CURVE, allow_testnet=True)
|
||||
@auto_keychain(__name__)
|
||||
async def get_address(ctx, msg: RippleGetAddress, keychain):
|
||||
await paths.validate_path(
|
||||
ctx, helpers.validate_full_path, keychain, msg.address_n, CURVE
|
||||
)
|
||||
await paths.validate_path(ctx, keychain, msg.address_n)
|
||||
|
||||
node = keychain.derive(msg.address_n)
|
||||
pubkey = node.public_key()
|
||||
address = helpers.address_from_public_key(pubkey)
|
||||
address = address_from_public_key(pubkey)
|
||||
|
||||
if msg.show_display:
|
||||
desc = address_n_to_str(msg.address_n)
|
||||
|
@ -2,8 +2,6 @@ from micropython import const
|
||||
|
||||
from trezor.crypto.hashlib import ripemd160, sha256
|
||||
|
||||
from apps.common import HARDENED
|
||||
|
||||
from . import base58_ripple
|
||||
|
||||
# HASH_TX_ID = const(0x54584E00) # 'TXN'
|
||||
@ -50,25 +48,3 @@ def decode_address(address: str):
|
||||
"""Returns so called Account ID"""
|
||||
adr = base58_ripple.decode_check(address)
|
||||
return adr[1:]
|
||||
|
||||
|
||||
def validate_full_path(path: list) -> bool:
|
||||
"""
|
||||
Validates derivation path to equal 44'/144'/a'/0/0,
|
||||
where `a` is an account index from 0 to 1 000 000.
|
||||
Similar to Ethereum this should be 44'/144'/a', but for
|
||||
compatibility with other HW vendors we use 44'/144'/a'/0/0.
|
||||
"""
|
||||
if len(path) != 5:
|
||||
return False
|
||||
if path[0] != 44 | HARDENED:
|
||||
return False
|
||||
if path[1] != 144 | HARDENED:
|
||||
return False
|
||||
if path[2] < HARDENED or path[2] > 1000000 | HARDENED:
|
||||
return False
|
||||
if path[3] != 0:
|
||||
return False
|
||||
if path[4] != 0:
|
||||
return False
|
||||
return True
|
||||
|
@ -6,19 +6,16 @@ from trezor.messages.RippleSignTx import RippleSignTx
|
||||
from trezor.wire import ProcessError
|
||||
|
||||
from apps.common import paths
|
||||
from apps.common.keychain import with_slip44_keychain
|
||||
from apps.common.keychain import auto_keychain
|
||||
|
||||
from . import CURVE, SLIP44_ID, helpers, layout
|
||||
from . import helpers, layout
|
||||
from .serialize import serialize
|
||||
|
||||
|
||||
@with_slip44_keychain(SLIP44_ID, CURVE, allow_testnet=True)
|
||||
@auto_keychain(__name__)
|
||||
async def sign_tx(ctx, msg: RippleSignTx, keychain):
|
||||
validate(msg)
|
||||
|
||||
await paths.validate_path(
|
||||
ctx, helpers.validate_full_path, keychain, msg.address_n, CURVE
|
||||
)
|
||||
await paths.validate_path(ctx, keychain, msg.address_n)
|
||||
|
||||
node = keychain.derive(msg.address_n)
|
||||
source_address = helpers.address_from_public_key(node.public_key())
|
||||
|
@ -1,8 +1,11 @@
|
||||
from trezor import wire
|
||||
from trezor.messages import MessageType
|
||||
|
||||
from apps.common.paths import PATTERN_SEP5
|
||||
|
||||
CURVE = "ed25519"
|
||||
SLIP44_ID = 148
|
||||
PATTERN = PATTERN_SEP5
|
||||
|
||||
|
||||
def boot() -> None:
|
||||
|
@ -2,17 +2,15 @@ from trezor.messages.StellarAddress import StellarAddress
|
||||
from trezor.messages.StellarGetAddress import StellarGetAddress
|
||||
|
||||
from apps.common import paths, seed
|
||||
from apps.common.keychain import with_slip44_keychain
|
||||
from apps.common.keychain import auto_keychain
|
||||
from apps.common.layout import address_n_to_str, show_address, show_qr
|
||||
|
||||
from . import CURVE, SLIP44_ID, helpers
|
||||
from . import helpers
|
||||
|
||||
|
||||
@with_slip44_keychain(SLIP44_ID, CURVE, allow_testnet=True)
|
||||
@auto_keychain(__name__)
|
||||
async def get_address(ctx, msg: StellarGetAddress, keychain):
|
||||
await paths.validate_path(
|
||||
ctx, helpers.validate_full_path, keychain, msg.address_n, CURVE
|
||||
)
|
||||
await paths.validate_path(ctx, keychain, msg.address_n)
|
||||
|
||||
node = keychain.derive(msg.address_n)
|
||||
pubkey = seed.remove_ed25519_prefix(node.public_key())
|
||||
|
@ -3,8 +3,6 @@ import ustruct
|
||||
from trezor.crypto import base32
|
||||
from trezor.wire import ProcessError
|
||||
|
||||
from apps.common import HARDENED
|
||||
|
||||
|
||||
def public_key_from_address(address: str) -> bytes:
|
||||
"""Extracts public key from an address
|
||||
@ -26,22 +24,6 @@ def address_from_public_key(pubkey: bytes):
|
||||
return base32.encode(address)
|
||||
|
||||
|
||||
def validate_full_path(path: list) -> bool:
|
||||
"""
|
||||
Validates derivation path to equal 44'/148'/a',
|
||||
where `a` is an account index from 0 to 1 000 000.
|
||||
"""
|
||||
if len(path) != 3:
|
||||
return False
|
||||
if path[0] != 44 | HARDENED:
|
||||
return False
|
||||
if path[1] != 148 | HARDENED:
|
||||
return False
|
||||
if path[2] < HARDENED or path[2] > 1000000 | HARDENED:
|
||||
return False
|
||||
return True
|
||||
|
||||
|
||||
def _crc16_checksum_verify(data: bytes, checksum: bytes):
|
||||
if _crc16_checksum(data) != checksum:
|
||||
raise ProcessError("Invalid address checksum")
|
||||
|
@ -8,17 +8,15 @@ from trezor.messages.StellarTxOpRequest import StellarTxOpRequest
|
||||
from trezor.wire import ProcessError
|
||||
|
||||
from apps.common import paths, seed
|
||||
from apps.common.keychain import with_slip44_keychain
|
||||
from apps.common.keychain import auto_keychain
|
||||
|
||||
from . import CURVE, SLIP44_ID, consts, helpers, layout, writers
|
||||
from . import consts, helpers, layout, writers
|
||||
from .operations import process_operation
|
||||
|
||||
|
||||
@with_slip44_keychain(SLIP44_ID, CURVE, allow_testnet=True)
|
||||
@auto_keychain(__name__)
|
||||
async def sign_tx(ctx, msg: StellarSignTx, keychain):
|
||||
await paths.validate_path(
|
||||
ctx, helpers.validate_full_path, keychain, msg.address_n, CURVE
|
||||
)
|
||||
await paths.validate_path(ctx, keychain, msg.address_n)
|
||||
|
||||
node = keychain.derive(msg.address_n)
|
||||
pubkey = seed.remove_ed25519_prefix(node.public_key())
|
||||
|
@ -1,8 +1,14 @@
|
||||
from trezor import wire
|
||||
from trezor.messages import MessageType
|
||||
|
||||
from apps.common.paths import PATTERN_SEP5
|
||||
|
||||
CURVE = "ed25519"
|
||||
SLIP44_ID = 1729
|
||||
PATTERNS = (
|
||||
PATTERN_SEP5,
|
||||
"m/44'/coin_type'/0'/account'", # Ledger compatibility
|
||||
)
|
||||
|
||||
|
||||
def boot() -> None:
|
||||
|
@ -5,14 +5,12 @@ from apps.common import paths, seed
|
||||
from apps.common.keychain import with_slip44_keychain
|
||||
from apps.common.layout import address_n_to_str, show_address, show_qr
|
||||
|
||||
from . import CURVE, SLIP44_ID, helpers
|
||||
from . import CURVE, PATTERNS, SLIP44_ID, helpers
|
||||
|
||||
|
||||
@with_slip44_keychain(SLIP44_ID, CURVE, allow_testnet=True)
|
||||
@with_slip44_keychain(*PATTERNS, slip44_id=SLIP44_ID, curve=CURVE)
|
||||
async def get_address(ctx, msg, keychain):
|
||||
await paths.validate_path(
|
||||
ctx, helpers.validate_full_path, keychain, msg.address_n, CURVE
|
||||
)
|
||||
await paths.validate_path(ctx, keychain, msg.address_n)
|
||||
|
||||
node = keychain.derive(msg.address_n)
|
||||
|
||||
|
@ -8,14 +8,12 @@ from apps.common import paths, seed
|
||||
from apps.common.confirm import require_confirm
|
||||
from apps.common.keychain import with_slip44_keychain
|
||||
|
||||
from . import CURVE, SLIP44_ID, helpers
|
||||
from . import CURVE, PATTERNS, SLIP44_ID, helpers
|
||||
|
||||
|
||||
@with_slip44_keychain(SLIP44_ID, CURVE, allow_testnet=True)
|
||||
@with_slip44_keychain(*PATTERNS, slip44_id=SLIP44_ID, curve=CURVE)
|
||||
async def get_public_key(ctx, msg, keychain):
|
||||
await paths.validate_path(
|
||||
ctx, helpers.validate_full_path, keychain, msg.address_n, CURVE
|
||||
)
|
||||
await paths.validate_path(ctx, keychain, msg.address_n)
|
||||
|
||||
node = keychain.derive(msg.address_n)
|
||||
pk = seed.remove_ed25519_prefix(node.public_key())
|
||||
|
@ -2,7 +2,6 @@ from micropython import const
|
||||
|
||||
from trezor.crypto import base58
|
||||
|
||||
from apps.common import HARDENED
|
||||
from apps.common.writers import write_bytes_unchecked, write_uint8
|
||||
|
||||
TEZOS_AMOUNT_DECIMALS = const(6)
|
||||
@ -66,31 +65,6 @@ def base58_decode_check(enc, prefix=None):
|
||||
return decoded
|
||||
|
||||
|
||||
def validate_full_path(path: list) -> bool:
|
||||
"""
|
||||
Validates derivation path to equal 44'/1729'/a',
|
||||
where `a` is an account index from 0 to 1 000 000.
|
||||
Additional component added to allow ledger migration
|
||||
44'/1729'/0'/b' where `b` is an account index from 0 to 1 000 000
|
||||
"""
|
||||
length = len(path)
|
||||
if length < 3 or length > 4:
|
||||
return False
|
||||
if path[0] != 44 | HARDENED:
|
||||
return False
|
||||
if path[1] != 1729 | HARDENED:
|
||||
return False
|
||||
if length == 3:
|
||||
if path[2] < HARDENED or path[2] > 1000000 | HARDENED:
|
||||
return False
|
||||
if length == 4:
|
||||
if path[2] != 0 | HARDENED:
|
||||
return False
|
||||
if path[3] < HARDENED or path[3] > 1000000 | HARDENED:
|
||||
return False
|
||||
return True
|
||||
|
||||
|
||||
def write_bool(w: bytearray, boolean: bool):
|
||||
if boolean:
|
||||
write_uint8(w, 255)
|
||||
|
@ -10,16 +10,14 @@ from apps.common import paths
|
||||
from apps.common.keychain import with_slip44_keychain
|
||||
from apps.common.writers import write_bytes_unchecked, write_uint8, write_uint32_be
|
||||
|
||||
from . import CURVE, SLIP44_ID, helpers, layout
|
||||
from . import CURVE, PATTERNS, SLIP44_ID, helpers, layout
|
||||
|
||||
PROPOSAL_LENGTH = const(32)
|
||||
|
||||
|
||||
@with_slip44_keychain(SLIP44_ID, CURVE, allow_testnet=True)
|
||||
@with_slip44_keychain(*PATTERNS, slip44_id=SLIP44_ID, curve=CURVE)
|
||||
async def sign_tx(ctx, msg, keychain):
|
||||
await paths.validate_path(
|
||||
ctx, helpers.validate_full_path, keychain, msg.address_n, CURVE
|
||||
)
|
||||
await paths.validate_path(ctx, keychain, msg.address_n)
|
||||
|
||||
node = keychain.derive(msg.address_n)
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user