mirror of
https://github.com/trezor/trezor-firmware.git
synced 2025-07-15 02:58:12 +00:00
83 lines
2.4 KiB
Python
83 lines
2.4 KiB
Python
from ubinascii import hexlify
|
|
|
|
from trezor import log, wire
|
|
from trezor.messages.CardanoPublicKey import CardanoPublicKey
|
|
from trezor.messages.HDNodeType import HDNodeType
|
|
|
|
from apps.common import HARDENED, layout, paths
|
|
from apps.common.seed import remove_ed25519_prefix
|
|
|
|
from . import CURVE, seed
|
|
from .helpers import purposes
|
|
|
|
if False:
|
|
from typing import List
|
|
from trezor.messages import CardanoGetPublicKey
|
|
|
|
|
|
@seed.with_keychain
|
|
async def get_public_key(
|
|
ctx: wire.Context, msg: CardanoGetPublicKey, keychain: seed.Keychain
|
|
):
|
|
await paths.validate_path(
|
|
ctx,
|
|
_validate_path_for_get_public_key,
|
|
keychain,
|
|
msg.address_n,
|
|
CURVE,
|
|
)
|
|
|
|
try:
|
|
key = _get_public_key(keychain, msg.address_n)
|
|
except ValueError as e:
|
|
if __debug__:
|
|
log.exception(__name__, e)
|
|
raise wire.ProcessError("Deriving public key failed")
|
|
|
|
if msg.show_display:
|
|
await layout.show_pubkey(ctx, key.node.public_key)
|
|
return key
|
|
|
|
|
|
def _get_public_key(
|
|
keychain: seed.Keychain, derivation_path: List[int]
|
|
) -> CardanoPublicKey:
|
|
node = keychain.derive(derivation_path)
|
|
|
|
public_key = hexlify(remove_ed25519_prefix(node.public_key())).decode()
|
|
chain_code = hexlify(node.chain_code()).decode()
|
|
xpub_key = public_key + chain_code
|
|
|
|
node_type = HDNodeType(
|
|
depth=node.depth(),
|
|
child_num=node.child_num(),
|
|
fingerprint=node.fingerprint(),
|
|
chain_code=node.chain_code(),
|
|
public_key=remove_ed25519_prefix(node.public_key()),
|
|
)
|
|
|
|
return CardanoPublicKey(node=node_type, xpub=xpub_key)
|
|
|
|
|
|
def _validate_path_for_get_public_key(path: List[int]) -> bool:
|
|
"""
|
|
Modified version of paths.validate_path_for_get_public_key.
|
|
Checks if path has at least three hardened items, Byron or Shelley purpose
|
|
and slip44 id 1815. The path is allowed to have more than three items,
|
|
but all the following items have to be non-hardened.
|
|
"""
|
|
length = len(path)
|
|
if length < 3 or length > 5:
|
|
return False
|
|
if path[0] not in (purposes.BYRON, purposes.SHELLEY):
|
|
return False
|
|
if path[1] != 1815 | HARDENED:
|
|
return False
|
|
if path[2] < HARDENED or path[2] > 20 | 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
|