From 387466e0735bdc854acdf380f67ad19497b0582f Mon Sep 17 00:00:00 2001 From: matejcik Date: Fri, 15 Oct 2021 17:26:13 +0200 Subject: [PATCH] refactor(core): separate Cardano cryptography into its own module --- core/SConscript.firmware | 1 + core/SConscript.unix | 1 + core/embed/extmod/modtrezorcrypto/hdnode.h | 35 ++++ .../modtrezorcrypto/modtrezorcrypto-bip32.h | 116 +----------- .../modtrezorcrypto/modtrezorcrypto-bip39.h | 9 - .../modtrezorcrypto/modtrezorcrypto-cardano.h | 168 ++++++++++++++++++ .../extmod/modtrezorcrypto/modtrezorcrypto.c | 14 ++ core/mocks/generated/trezorcrypto/bip32.pyi | 13 -- core/mocks/generated/trezorcrypto/cardano.pyi | 28 +++ core/src/trezor/crypto/__init__.py | 1 + 10 files changed, 251 insertions(+), 135 deletions(-) create mode 100644 core/embed/extmod/modtrezorcrypto/hdnode.h create mode 100644 core/embed/extmod/modtrezorcrypto/modtrezorcrypto-cardano.h create mode 100644 core/mocks/generated/trezorcrypto/cardano.pyi diff --git a/core/SConscript.firmware b/core/SConscript.firmware index 03bec4c57..94f72490e 100644 --- a/core/SConscript.firmware +++ b/core/SConscript.firmware @@ -104,6 +104,7 @@ SOURCE_MOD += [ ] if EVERYTHING: SOURCE_MOD += [ + 'vendor/trezor-crypto/cardano.c', 'vendor/trezor-crypto/monero/base58.c', 'vendor/trezor-crypto/monero/serialize.c', 'vendor/trezor-crypto/monero/xmr.c', diff --git a/core/SConscript.unix b/core/SConscript.unix index 192c20888..df1878945 100644 --- a/core/SConscript.unix +++ b/core/SConscript.unix @@ -102,6 +102,7 @@ SOURCE_MOD += [ ] if EVERYTHING: SOURCE_MOD += [ + 'vendor/trezor-crypto/cardano.c', 'vendor/trezor-crypto/monero/base58.c', 'vendor/trezor-crypto/monero/serialize.c', 'vendor/trezor-crypto/monero/xmr.c', diff --git a/core/embed/extmod/modtrezorcrypto/hdnode.h b/core/embed/extmod/modtrezorcrypto/hdnode.h new file mode 100644 index 000000000..2e06dfff0 --- /dev/null +++ b/core/embed/extmod/modtrezorcrypto/hdnode.h @@ -0,0 +1,35 @@ +/* + * This file is part of the Trezor project, https://trezor.io/ + * + * Copyright (c) SatoshiLabs + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef __HDNODE_H__ +#define __HDNODE_H__ + +#include "py/obj.h" + +#include "bip32.h" + +typedef struct _mp_obj_HDNode_t { + mp_obj_base_t base; + uint32_t fingerprint; + HDNode hdnode; +} mp_obj_HDNode_t; + +extern const mp_obj_type_t mod_trezorcrypto_HDNode_type; + +#endif diff --git a/core/embed/extmod/modtrezorcrypto/modtrezorcrypto-bip32.h b/core/embed/extmod/modtrezorcrypto/modtrezorcrypto-bip32.h index 3b0b49a86..c946ea380 100644 --- a/core/embed/extmod/modtrezorcrypto/modtrezorcrypto-bip32.h +++ b/core/embed/extmod/modtrezorcrypto/modtrezorcrypto-bip32.h @@ -20,6 +20,7 @@ #include "py/objstr.h" #include "embed/extmod/trezorobj.h" +#include "hdnode.h" #include "bip32.h" #include "bip39.h" @@ -35,13 +36,6 @@ /// """ /// BIP0032 HD node structure. /// """ -typedef struct _mp_obj_HDNode_t { - mp_obj_base_t base; - uint32_t fingerprint; - HDNode hdnode; -} mp_obj_HDNode_t; - -STATIC const mp_obj_type_t mod_trezorcrypto_HDNode_type; /// def __init__( /// self, @@ -183,43 +177,6 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mod_trezorcrypto_HDNode_derive_obj, 2, 3, mod_trezorcrypto_HDNode_derive); -#if !BITCOIN_ONLY - -/// def derive_cardano(self, index: int) -> None: -/// """ -/// Derive a BIP0032 child node in place using Cardano algorithm. -/// """ -STATIC mp_obj_t mod_trezorcrypto_HDNode_derive_cardano(mp_obj_t self, - mp_obj_t index) { - mp_obj_HDNode_t *o = MP_OBJ_TO_PTR(self); - uint32_t i = mp_obj_get_int_truncated(index); - uint32_t fp = hdnode_fingerprint(&o->hdnode); - - int res = 0; - // same as in derive - if (0 == - memcmp(o->hdnode.private_key, - "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" - "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", - 32)) { - memzero(&o->hdnode, sizeof(o->hdnode)); - mp_raise_ValueError("Failed to derive, private key not set"); - } - // special for cardano - res = hdnode_private_ckd_cardano(&o->hdnode, i); - if (!res) { - memzero(&o->hdnode, sizeof(o->hdnode)); - mp_raise_ValueError("Failed to derive"); - } - o->fingerprint = fp; - - return mp_const_none; -} -STATIC MP_DEFINE_CONST_FUN_OBJ_2(mod_trezorcrypto_HDNode_derive_cardano_obj, - mod_trezorcrypto_HDNode_derive_cardano); - -#endif - /// def derive_path(self, path: Sequence[int]) -> None: /// """ /// Go through a list of indexes and iteratively derive a child node in @@ -504,10 +461,6 @@ STATIC const mp_rom_map_elem_t mod_trezorcrypto_HDNode_locals_dict_table[] = { MP_ROM_PTR(&mod_trezorcrypto_HDNode___del___obj)}, {MP_ROM_QSTR(MP_QSTR_derive), MP_ROM_PTR(&mod_trezorcrypto_HDNode_derive_obj)}, -#if !BITCOIN_ONLY - {MP_ROM_QSTR(MP_QSTR_derive_cardano), - MP_ROM_PTR(&mod_trezorcrypto_HDNode_derive_cardano_obj)}, -#endif {MP_ROM_QSTR(MP_QSTR_derive_path), MP_ROM_PTR(&mod_trezorcrypto_HDNode_derive_path_obj)}, {MP_ROM_QSTR(MP_QSTR_serialize_public), @@ -542,7 +495,7 @@ STATIC const mp_rom_map_elem_t mod_trezorcrypto_HDNode_locals_dict_table[] = { STATIC MP_DEFINE_CONST_DICT(mod_trezorcrypto_HDNode_locals_dict, mod_trezorcrypto_HDNode_locals_dict_table); -STATIC const mp_obj_type_t mod_trezorcrypto_HDNode_type = { +const mp_obj_type_t mod_trezorcrypto_HDNode_type = { {&mp_type_type}, .name = MP_QSTR_HDNode, .make_new = mod_trezorcrypto_HDNode_make_new, @@ -569,14 +522,7 @@ STATIC mp_obj_t mod_trezorcrypto_bip32_from_seed(mp_obj_t seed, } HDNode hdnode = {0}; - int res = 0; - if (strcmp(curveb.buf, ED25519_CARDANO_NAME) != 0) { - res = hdnode_from_seed(seedb.buf, seedb.len, curveb.buf, &hdnode); -#if !BITCOIN_ONLY - } else { - res = hdnode_from_seed_cardano(seedb.buf, seedb.len, &hdnode); -#endif - } + int res = hdnode_from_seed(seedb.buf, seedb.len, curveb.buf, &hdnode); if (!res) { mp_raise_ValueError("Failed to derive the root node"); @@ -591,67 +537,11 @@ STATIC mp_obj_t mod_trezorcrypto_bip32_from_seed(mp_obj_t seed, STATIC MP_DEFINE_CONST_FUN_OBJ_2(mod_trezorcrypto_bip32_from_seed_obj, mod_trezorcrypto_bip32_from_seed); -#if !BITCOIN_ONLY - -/// def from_mnemonic_cardano(mnemonic: str, passphrase: str) -> HDNode: -/// """ -/// Construct a HD node from a BIP-0039 mnemonic using the Icarus derivation -/// scheme, aka v2 derivation scheme. -/// """ -STATIC mp_obj_t mod_trezorcrypto_bip32_from_mnemonic_cardano( - mp_obj_t mnemonic, mp_obj_t passphrase) { - mp_buffer_info_t mnemo = {0}, phrase = {0}; - mp_get_buffer_raise(mnemonic, &mnemo, MP_BUFFER_READ); - mp_get_buffer_raise(passphrase, &phrase, MP_BUFFER_READ); - HDNode hdnode = {0}; - const char *pmnemonic = mnemo.len > 0 ? mnemo.buf : ""; - const char *ppassphrase = phrase.len > 0 ? phrase.buf : ""; - - uint8_t mnemonic_bits[64] = {0}; - int mnemonic_bits_len = mnemonic_to_bits(pmnemonic, mnemonic_bits); - - if (mnemonic_bits_len == 0) { - mp_raise_ValueError("Invalid mnemonic"); - } - - // BEWARE: passing of mnemonic_bits (i.e. entropy + checksum bits) into - // hdnode_from_entropy_cardano_icarus() is actually not correct and we should - // be passing the entropy alone. However, the bug is there since Cardano - // support has been launched for Trezor and its reversal would result in - // people with a 24-word mnemonic on Trezor losing access to their Cardano - // funds. More info at https://github.com/trezor/trezor-firmware/issues/1387 - const int res = hdnode_from_entropy_cardano_icarus( - (const uint8_t *)ppassphrase, phrase.len, mnemonic_bits, - mnemonic_bits_len / 8, &hdnode); - - if (!res) { - mp_raise_ValueError( - "Secret key generation from mnemonic is looping forever"); - } else if (res == -1) { - mp_raise_ValueError("Invalid mnemonic"); - } - - mp_obj_HDNode_t *o = m_new_obj_with_finaliser(mp_obj_HDNode_t); - o->base.type = &mod_trezorcrypto_HDNode_type; - o->hdnode = hdnode; - o->fingerprint = 0; - return MP_OBJ_FROM_PTR(o); -} -STATIC MP_DEFINE_CONST_FUN_OBJ_2( - mod_trezorcrypto_bip32_from_mnemonic_cardano_obj, - mod_trezorcrypto_bip32_from_mnemonic_cardano); - -#endif - STATIC const mp_rom_map_elem_t mod_trezorcrypto_bip32_globals_table[] = { {MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_bip32)}, {MP_ROM_QSTR(MP_QSTR_HDNode), MP_ROM_PTR(&mod_trezorcrypto_HDNode_type)}, {MP_ROM_QSTR(MP_QSTR_from_seed), MP_ROM_PTR(&mod_trezorcrypto_bip32_from_seed_obj)}, -#if !BITCOIN_ONLY - {MP_ROM_QSTR(MP_QSTR_from_mnemonic_cardano), - MP_ROM_PTR(&mod_trezorcrypto_bip32_from_mnemonic_cardano_obj)}, -#endif }; STATIC MP_DEFINE_CONST_DICT(mod_trezorcrypto_bip32_globals, mod_trezorcrypto_bip32_globals_table); diff --git a/core/embed/extmod/modtrezorcrypto/modtrezorcrypto-bip39.h b/core/embed/extmod/modtrezorcrypto/modtrezorcrypto-bip39.h index 5f9eb701f..cfca37c4f 100644 --- a/core/embed/extmod/modtrezorcrypto/modtrezorcrypto-bip39.h +++ b/core/embed/extmod/modtrezorcrypto/modtrezorcrypto-bip39.h @@ -113,15 +113,6 @@ STATIC mp_obj_t mod_trezorcrypto_bip39_check(mp_obj_t mnemonic) { STATIC MP_DEFINE_CONST_FUN_OBJ_1(mod_trezorcrypto_bip39_check_obj, mod_trezorcrypto_bip39_check); -static mp_obj_t ui_wait_callback = mp_const_none; - -static void wrapped_ui_wait_callback(uint32_t current, uint32_t total) { - if (mp_obj_is_callable(ui_wait_callback)) { - mp_call_function_2_protected(ui_wait_callback, mp_obj_new_int(current), - mp_obj_new_int(total)); - } -} - /// def seed( /// mnemonic: str, /// passphrase: str, diff --git a/core/embed/extmod/modtrezorcrypto/modtrezorcrypto-cardano.h b/core/embed/extmod/modtrezorcrypto/modtrezorcrypto-cardano.h new file mode 100644 index 000000000..da3e6f993 --- /dev/null +++ b/core/embed/extmod/modtrezorcrypto/modtrezorcrypto-cardano.h @@ -0,0 +1,168 @@ +/* + * This file is part of the Trezor project, https://trezor.io/ + * + * Copyright (c) SatoshiLabs + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#if !BITCOIN_ONLY + +#include "py/objstr.h" + +#include "embed/extmod/trezorobj.h" +#include "hdnode.h" + +#include "bip39.h" +#include "cardano.h" +#include "curves.h" +#include "memzero.h" + +/// package: trezorcrypto.cardano + +/// def derive_icarus_trezor( +/// mnemonic: str, +/// passphrase: str, +/// callback: Callable[[int, int], None] | None = None, +/// ) -> bytes: +/// """ +/// Derives a Cardano master secret from a mnemonic and passphrase using the +/// Icarus-Trezor derivation scheme. This differs from the Icarus scheme by +/// including checksum if the mnemonic is 24 words. +/// """ +STATIC mp_obj_t mod_trezorcrypto_cardano_derive_icarus_trezor( + size_t n_args, const mp_obj_t *args) { + mp_buffer_info_t mnemo = {0}, phrase = {0}; + mp_get_buffer_raise(args[0], &mnemo, MP_BUFFER_READ); + mp_get_buffer_raise(args[1], &phrase, MP_BUFFER_READ); + const char *pmnemonic = mnemo.len > 0 ? mnemo.buf : ""; + const char *ppassphrase = phrase.len > 0 ? phrase.buf : ""; + + uint8_t mnemonic_bits[64] = {0}; + int mnemonic_bits_len = mnemonic_to_bits(pmnemonic, mnemonic_bits); + + if (mnemonic_bits_len == 0) { + mp_raise_ValueError("Invalid mnemonic"); + } + + vstr_t vstr = {0}; + vstr_init_len(&vstr, CARDANO_SECRET_LENGTH); + + void (*callback)(uint32_t current, uint32_t total) = NULL; + if (n_args > 2) { + // generate with a progress callback + ui_wait_callback = args[2]; + callback = wrapped_ui_wait_callback; + } + + // BEWARE: unlike `derive_icarus`, we are passing the raw result of + // `mnemonic_bits`, i.e., entropy + checksum bits. More info at + // https://github.com/trezor/trezor-firmware/issues/1387 and CIP-3 + const int res = secret_from_entropy_cardano_icarus( + (const uint8_t *)ppassphrase, phrase.len, mnemonic_bits, + mnemonic_bits_len / 8, (uint8_t *)vstr.buf, callback); + + ui_wait_callback = mp_const_none; + + if (res != 1) { + mp_raise_msg(&mp_type_RuntimeError, + "Unexpected failure in Icarus derivation."); + } + + return mp_obj_new_str_from_vstr(&mp_type_bytes, &vstr); +} + +STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN( + mod_trezorcrypto_cardano_derive_icarus_trezor_obj, 2, 3, + mod_trezorcrypto_cardano_derive_icarus_trezor); + +/// def from_secret(secret: bytes) -> HDNode: +/// """ +/// Creates a Cardano HD node from a master secret. +/// """ +STATIC mp_obj_t mod_trezorcrypto_from_secret(mp_obj_t secret) { + mp_buffer_info_t bufinfo; + mp_get_buffer_raise(secret, &bufinfo, MP_BUFFER_READ); + if (bufinfo.len != CARDANO_SECRET_LENGTH) { + mp_raise_ValueError("Invalid secret length"); + } + + mp_obj_HDNode_t *o = m_new_obj_with_finaliser(mp_obj_HDNode_t); + o->base.type = &mod_trezorcrypto_HDNode_type; + const int res = hdnode_from_secret_cardano(bufinfo.buf, &o->hdnode); + if (res != 1) { + mp_raise_msg(&mp_type_RuntimeError, + "Unexpected failure in constructing Cardano node."); + } + o->fingerprint = hdnode_fingerprint(&o->hdnode); + return MP_OBJ_FROM_PTR(o); +} + +STATIC MP_DEFINE_CONST_FUN_OBJ_1(mod_trezorcrypto_from_secret_obj, + mod_trezorcrypto_from_secret); + +/// def from_seed_slip23(seed: bytes) -> HDNode: +/// """ +/// Creates a Cardano HD node from a seed via SLIP-23 derivation. +/// """ +STATIC mp_obj_t mod_trezorcrypto_from_seed_slip23(mp_obj_t seed) { + mp_buffer_info_t bufinfo; + mp_get_buffer_raise(seed, &bufinfo, MP_BUFFER_READ); + if (bufinfo.len == 0) { + mp_raise_ValueError("Invalid seed"); + } + + uint8_t secret[CARDANO_SECRET_LENGTH] = {0}; + HDNode hdnode = {0}; + int res = 0; + + res = secret_from_seed_cardano_slip23(bufinfo.buf, bufinfo.len, secret); + if (res != 1) { + mp_raise_msg(&mp_type_RuntimeError, + "Unexpected failure in SLIP-23 derivation."); + } + res = hdnode_from_secret_cardano(secret, &hdnode); + if (res != 1) { + mp_raise_msg(&mp_type_RuntimeError, + "Unexpected failure in constructing Cardano node."); + } + + mp_obj_HDNode_t *o = m_new_obj_with_finaliser(mp_obj_HDNode_t); + o->base.type = &mod_trezorcrypto_HDNode_type; + o->hdnode = hdnode; + o->fingerprint = hdnode_fingerprint(&o->hdnode); + return MP_OBJ_FROM_PTR(o); +} + +STATIC MP_DEFINE_CONST_FUN_OBJ_1(mod_trezorcrypto_from_seed_slip23_obj, + mod_trezorcrypto_from_seed_slip23); + +STATIC const mp_rom_map_elem_t mod_trezorcrypto_cardano_globals_table[] = { + {MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_cardano)}, + {MP_ROM_QSTR(MP_QSTR_derive_icarus_trezor), + MP_ROM_PTR(&mod_trezorcrypto_cardano_derive_icarus_trezor_obj)}, + {MP_ROM_QSTR(MP_QSTR_from_secret), + MP_ROM_PTR(&mod_trezorcrypto_from_secret_obj)}, + {MP_ROM_QSTR(MP_QSTR_from_seed_slip23), + MP_ROM_PTR(&mod_trezorcrypto_from_seed_slip23_obj)}, +}; +STATIC MP_DEFINE_CONST_DICT(mod_trezorcrypto_cardano_globals, + mod_trezorcrypto_cardano_globals_table); + +STATIC const mp_obj_module_t mod_trezorcrypto_cardano_module = { + .base = {&mp_type_module}, + .globals = (mp_obj_dict_t *)&mod_trezorcrypto_cardano_globals, +}; + +#endif // !BITCOIN_ONLY diff --git a/core/embed/extmod/modtrezorcrypto/modtrezorcrypto.c b/core/embed/extmod/modtrezorcrypto/modtrezorcrypto.c index aff2a3d12..87c5a0357 100644 --- a/core/embed/extmod/modtrezorcrypto/modtrezorcrypto.c +++ b/core/embed/extmod/modtrezorcrypto/modtrezorcrypto.c @@ -27,6 +27,15 @@ #if MICROPY_PY_TREZORCRYPTO +static mp_obj_t ui_wait_callback = mp_const_none; + +static void wrapped_ui_wait_callback(uint32_t current, uint32_t total) { + if (mp_obj_is_callable(ui_wait_callback)) { + mp_call_function_2_protected(ui_wait_callback, mp_obj_new_int(current), + mp_obj_new_int(total)); + } +} + #include "modtrezorcrypto-aes.h" #include "modtrezorcrypto-bip32.h" #include "modtrezorcrypto-bip39.h" @@ -55,6 +64,7 @@ #include "modtrezorcrypto-shamir.h" #include "modtrezorcrypto-slip39.h" #if !BITCOIN_ONLY +#include "modtrezorcrypto-cardano.h" #include "modtrezorcrypto-monero.h" #include "modtrezorcrypto-nem.h" #endif @@ -68,6 +78,10 @@ STATIC const mp_rom_map_elem_t mp_module_trezorcrypto_globals_table[] = { MP_ROM_PTR(&mod_trezorcrypto_Blake256_type)}, {MP_ROM_QSTR(MP_QSTR_blake2b), MP_ROM_PTR(&mod_trezorcrypto_Blake2b_type)}, {MP_ROM_QSTR(MP_QSTR_blake2s), MP_ROM_PTR(&mod_trezorcrypto_Blake2s_type)}, +#if !BITCOIN_ONLY + {MP_ROM_QSTR(MP_QSTR_cardano), + MP_ROM_PTR(&mod_trezorcrypto_cardano_module)}, +#endif {MP_ROM_QSTR(MP_QSTR_chacha20poly1305), MP_ROM_PTR(&mod_trezorcrypto_ChaCha20Poly1305_type)}, {MP_ROM_QSTR(MP_QSTR_crc), MP_ROM_PTR(&mod_trezorcrypto_crc_module)}, diff --git a/core/mocks/generated/trezorcrypto/bip32.pyi b/core/mocks/generated/trezorcrypto/bip32.pyi index ce406884b..e2a8cbde9 100644 --- a/core/mocks/generated/trezorcrypto/bip32.pyi +++ b/core/mocks/generated/trezorcrypto/bip32.pyi @@ -25,11 +25,6 @@ class HDNode: Derive a BIP0032 child node in place. """ - def derive_cardano(self, index: int) -> None: - """ - Derive a BIP0032 child node in place using Cardano algorithm. - """ - def derive_path(self, path: Sequence[int]) -> None: """ Go through a list of indexes and iteratively derive a child node in @@ -114,11 +109,3 @@ def from_seed(seed: bytes, curve_name: str) -> HDNode: """ Construct a BIP0032 HD node from a BIP0039 seed value. """ - - -# extmod/modtrezorcrypto/modtrezorcrypto-bip32.h -def from_mnemonic_cardano(mnemonic: str, passphrase: str) -> HDNode: - """ - Construct a HD node from a BIP-0039 mnemonic using the Icarus derivation - scheme, aka v2 derivation scheme. - """ diff --git a/core/mocks/generated/trezorcrypto/cardano.pyi b/core/mocks/generated/trezorcrypto/cardano.pyi new file mode 100644 index 000000000..3779fb300 --- /dev/null +++ b/core/mocks/generated/trezorcrypto/cardano.pyi @@ -0,0 +1,28 @@ +from typing import * + + +# extmod/modtrezorcrypto/modtrezorcrypto-cardano.h +def derive_icarus_trezor( + mnemonic: str, + passphrase: str, + callback: Callable[[int, int], None] | None = None, +) -> bytes: + """ + Derives a Cardano master secret from a mnemonic and passphrase using the + Icarus-Trezor derivation scheme. This differs from the Icarus scheme by + including checksum if the mnemonic is 24 words. + """ + + +# extmod/modtrezorcrypto/modtrezorcrypto-cardano.h +def from_secret(secret: bytes) -> HDNode: + """ + Creates a Cardano HD node from a master secret. + """ + + +# extmod/modtrezorcrypto/modtrezorcrypto-cardano.h +def from_seed_slip23(seed: bytes) -> HDNode: + """ + Creates a Cardano HD node from a seed via SLIP-23 derivation. + """ diff --git a/core/src/trezor/crypto/__init__.py b/core/src/trezor/crypto/__init__.py index 957346f24..9637922fc 100644 --- a/core/src/trezor/crypto/__init__.py +++ b/core/src/trezor/crypto/__init__.py @@ -2,6 +2,7 @@ from trezorcrypto import ( # noqa: F401 aes, bip32, bip39, + cardano, chacha20poly1305, crc, hmac,