mirror of
https://github.com/trezor/trezor-firmware.git
synced 2024-12-18 04:18:10 +00:00
feat(cardano): add support for 1854 and 1855 path roots
This commit is contained in:
parent
2687fd4ade
commit
54909681a8
@ -57,6 +57,78 @@
|
||||
"public_key": "be81ace1f63f4f0cae74dd274a72d7818f238bc764ab3e0dc0beb1945b756dca",
|
||||
"chain_code": "29034f036a162ac4f9f9f397b2d1f289754bb6633915f26b199e156f81d05c88"
|
||||
}
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"path": "m/1854'/1815'/0'"
|
||||
},
|
||||
"result": {
|
||||
"public_key": "99694f772a1cffa68ad4a8d911e649cfe990aee720d26893211a8818c4566a42",
|
||||
"chain_code": "9c3372fcecd832bfe2418319e473b981cdd641e0e12bd878b5e94d93fa0b1552"
|
||||
}
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"path": "m/1854'/1815'/1'"
|
||||
},
|
||||
"result": {
|
||||
"public_key": "1b66eb903dc15131c0f39c1ac41ca659115ab790c3e2aef129e3095e406abffe",
|
||||
"chain_code": "0fcb6522d3aa8ad78370c48e62c97eb1315f4234ded8d8fdd9b941c4e5fda0c0"
|
||||
}
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"path": "m/1854'/1815'/2'"
|
||||
},
|
||||
"result": {
|
||||
"public_key": "29f3535b40978eda8038de3fe85cf08efecff5e565a3dc745660a43a172aaa0a",
|
||||
"chain_code": "b82dbc91a252a93ec6d3f9e418a4e779c848162777367f729468ec23f409304e"
|
||||
}
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"path": "m/1854'/1815'/3'"
|
||||
},
|
||||
"result": {
|
||||
"public_key": "bdc40afecb357a08538cd98878b11d0afa7a0a36a8c5f71be1b591ae09088149",
|
||||
"chain_code": "c4e0b579c132de4204d19f12260ac6bede8ae67f0fe15b9098d4f32a42314924"
|
||||
}
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"path": "m/1855'/1815'/0'"
|
||||
},
|
||||
"result": {
|
||||
"public_key": "b75258e4f61eb7b313d8554c2fe10673cf214ca2d762bfd53ec3b7846e2ee872",
|
||||
"chain_code": "9ad37dc23fe1cda7b0ac5574c6f16171cdb2bb723496954770a2bf0e08334e8f"
|
||||
}
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"path": "m/1855'/1815'/1'"
|
||||
},
|
||||
"result": {
|
||||
"public_key": "a54627d6d16724032172541d4261e7aa87c06395724f1d18975a21d56650bda9",
|
||||
"chain_code": "bccfd881a3bb7eefbfb885a80909c30892a9a2151f7530c10c68ec6e7a89b28a"
|
||||
}
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"path": "m/1855'/1815'/2'"
|
||||
},
|
||||
"result": {
|
||||
"public_key": "5307953b17d4195e0b87d61731339dba2c7d543f621d87c1bd73466328372345",
|
||||
"chain_code": "0e3314c9499b6efec4fa48cd5068dd549ed5ee524c300e754ebc0a63c3bc06ff"
|
||||
}
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"path": "m/1855'/1815'/3'"
|
||||
},
|
||||
"result": {
|
||||
"public_key": "b404bb5bf674a38ebd6141416df8e1aea9ed04c2ebea659c29145d24db7e67db",
|
||||
"chain_code": "2dc07d8eda29c2a806295ee42dc1f3bf63814d0c9ee978a24827575dcb5a53bb"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
|
@ -7,7 +7,7 @@ from trezor.ui.layouts import show_pubkey
|
||||
from apps.common import paths
|
||||
|
||||
from . import seed
|
||||
from .helpers.paths import SCHEMA_PUBKEY
|
||||
from .helpers.paths import SCHEMA_MINT, SCHEMA_PUBKEY
|
||||
from .helpers.utils import derive_public_key
|
||||
|
||||
if False:
|
||||
@ -23,7 +23,7 @@ async def get_public_key(
|
||||
keychain,
|
||||
msg.address_n,
|
||||
# path must match the PUBKEY schema
|
||||
SCHEMA_PUBKEY.match(msg.address_n),
|
||||
SCHEMA_PUBKEY.match(msg.address_n) or SCHEMA_MINT.match(msg.address_n),
|
||||
)
|
||||
|
||||
try:
|
||||
|
@ -6,13 +6,17 @@ SLIP44_ID = 1815
|
||||
|
||||
BYRON_ROOT = [44 | HARDENED, SLIP44_ID | HARDENED]
|
||||
SHELLEY_ROOT = [1852 | HARDENED, SLIP44_ID | HARDENED]
|
||||
MULTISIG_ROOT = [1854 | HARDENED, SLIP44_ID | HARDENED]
|
||||
MINTING_ROOT = [1855 | HARDENED, SLIP44_ID | HARDENED]
|
||||
|
||||
# fmt: off
|
||||
SCHEMA_PUBKEY = PathSchema.parse("m/[44,1852]'/coin_type'/account'/*", SLIP44_ID)
|
||||
SCHEMA_PUBKEY = PathSchema.parse("m/[44,1852,1854]'/coin_type'/account'/*", SLIP44_ID)
|
||||
# minting has a specific schema for key derivation - see CIP-1855
|
||||
SCHEMA_MINT = PathSchema.parse("m/1855'/coin_type'/[0-%s]'" % (HARDENED - 1), SLIP44_ID)
|
||||
SCHEMA_PAYMENT = PathSchema.parse("m/[44,1852]'/coin_type'/account'/[0,1]/address_index", SLIP44_ID)
|
||||
# staking is only allowed on Shelley paths with suffix /2/0
|
||||
SCHEMA_STAKING = PathSchema.parse("m/1852'/coin_type'/account'/2/0", SLIP44_ID)
|
||||
SCHEMA_STAKING_ANY_ACCOUNT = PathSchema.parse("m/1852'/coin_type'/[0-%s]'/2/0" % (HARDENED - 1), SLIP44_ID)
|
||||
SCHEMA_STAKING = PathSchema.parse("m/[1852]'/coin_type'/account'/2/0", SLIP44_ID)
|
||||
SCHEMA_STAKING_ANY_ACCOUNT = PathSchema.parse("m/[1852]'/coin_type'/[0-%s]'/2/0" % (HARDENED - 1), SLIP44_ID)
|
||||
# fmt: on
|
||||
|
||||
ACCOUNT_PATH_LENGTH = const(3)
|
||||
|
@ -18,15 +18,20 @@ if False:
|
||||
|
||||
|
||||
class Keychain:
|
||||
"""Cardano keychain hard-coded to Byron and Shelley seed namespaces."""
|
||||
"""
|
||||
Cardano keychain hard-coded to 44 (Byron), 1852 (Shelley), 1854 (multi-sig) and 1855 (token minting)
|
||||
seed namespaces.
|
||||
"""
|
||||
|
||||
def __init__(self, root: bip32.HDNode) -> None:
|
||||
self.byron_root = derive_path_cardano(root, paths.BYRON_ROOT)
|
||||
self.shelley_root = derive_path_cardano(root, paths.SHELLEY_ROOT)
|
||||
self.multisig_root = derive_path_cardano(root, paths.MULTISIG_ROOT)
|
||||
self.minting_root = derive_path_cardano(root, paths.MINTING_ROOT)
|
||||
root.__del__()
|
||||
|
||||
def verify_path(self, path: Bip32Path) -> None:
|
||||
if not is_byron_path(path) and not is_shelley_path(path):
|
||||
if not self.is_in_keychain(path):
|
||||
raise wire.DataError("Forbidden key path")
|
||||
|
||||
def _get_path_root(self, path: Bip32Path) -> bip32.HDNode:
|
||||
@ -34,18 +39,31 @@ class Keychain:
|
||||
return self.byron_root
|
||||
elif is_shelley_path(path):
|
||||
return self.shelley_root
|
||||
elif is_multisig_path(path):
|
||||
return self.multisig_root
|
||||
elif is_minting_path(path):
|
||||
return self.minting_root
|
||||
else:
|
||||
raise wire.DataError("Forbidden key path")
|
||||
|
||||
def is_in_keychain(self, path: Bip32Path) -> bool:
|
||||
return is_byron_path(path) or is_shelley_path(path)
|
||||
return (
|
||||
is_byron_path(path)
|
||||
or is_shelley_path(path)
|
||||
or is_multisig_path(path)
|
||||
or is_minting_path(path)
|
||||
)
|
||||
|
||||
def derive(self, node_path: Bip32Path) -> bip32.HDNode:
|
||||
self.verify_path(node_path)
|
||||
path_root = self._get_path_root(node_path)
|
||||
|
||||
# this is true now, so for simplicity we don't branch on path type
|
||||
assert len(paths.BYRON_ROOT) == len(paths.SHELLEY_ROOT)
|
||||
assert (
|
||||
len(paths.BYRON_ROOT) == len(paths.SHELLEY_ROOT)
|
||||
and len(paths.MULTISIG_ROOT) == len(paths.SHELLEY_ROOT)
|
||||
and len(paths.MINTING_ROOT) == len(paths.SHELLEY_ROOT)
|
||||
)
|
||||
suffix = node_path[len(paths.SHELLEY_ROOT) :]
|
||||
|
||||
# derive child node from the root
|
||||
@ -64,6 +82,14 @@ def is_shelley_path(path: Bip32Path) -> bool:
|
||||
return path[: len(paths.SHELLEY_ROOT)] == paths.SHELLEY_ROOT
|
||||
|
||||
|
||||
def is_multisig_path(path: Bip32Path) -> bool:
|
||||
return path[: len(paths.MULTISIG_ROOT)] == paths.MULTISIG_ROOT
|
||||
|
||||
|
||||
def is_minting_path(path: Bip32Path) -> bool:
|
||||
return path[: len(paths.MINTING_ROOT)] == paths.MINTING_ROOT
|
||||
|
||||
|
||||
def derive_path_cardano(root: bip32.HDNode, path: Bip32Path) -> bip32.HDNode:
|
||||
node = root.clone()
|
||||
for i in path:
|
||||
|
Loading…
Reference in New Issue
Block a user