1
0
mirror of https://github.com/trezor/trezor-firmware.git synced 2024-12-18 12:28:09 +00:00

feat(core): Add extendable BackupTypes.

This commit is contained in:
Andrew Kozlik 2024-05-17 21:26:21 +02:00 committed by Andrew Kozlik
parent b14b557efc
commit f24c48ef1e
19 changed files with 188 additions and 125 deletions

View File

@ -13,9 +13,12 @@ import "messages.proto";
* Type of the mnemonic backup given/received by the device during reset/recovery. * Type of the mnemonic backup given/received by the device during reset/recovery.
*/ */
enum BackupType { enum BackupType {
Bip39 = 0; // also called "Single Backup", see BIP-0039 Bip39 = 0; // also called "Single Backup", see BIP-0039
Slip39_Basic = 1; // also called "Shamir Backup", see SLIP-0039 Slip39_Basic = 1; // also called "Shamir Backup", see SLIP-0039
Slip39_Advanced = 2; // also called "Super Shamir" or "Shamir with Groups", see SLIP-0039#two-level-scheme Slip39_Advanced = 2; // also called "Super Shamir" or "Shamir with Groups", see SLIP-0039#two-level-scheme
Slip39_Single_Extendable = 3; // extendable single-share Shamir backup
Slip39_Basic_Extendable = 4; // extendable multi-share Shamir backup
Slip39_Advanced_Extendable = 5; // extendable multi-share Shamir backup with groups
} }
/** /**

View File

@ -275,6 +275,8 @@ apps.common.address_type
import apps.common.address_type import apps.common.address_type
apps.common.authorization apps.common.authorization
import apps.common.authorization import apps.common.authorization
apps.common.backup_types
import apps.common.backup_types
apps.common.cbor apps.common.cbor
import apps.common.cbor import apps.common.cbor
apps.common.coininfo apps.common.coininfo
@ -315,8 +317,6 @@ apps.management.authenticate_device
import apps.management.authenticate_device import apps.management.authenticate_device
apps.management.backup_device apps.management.backup_device
import apps.management.backup_device import apps.management.backup_device
apps.management.backup_types
import apps.management.backup_types
apps.management.change_language apps.management.change_language
import apps.management.change_language import apps.management.change_language
apps.management.change_pin apps.management.change_pin

View File

@ -0,0 +1,67 @@
from typing import TYPE_CHECKING
from trezor.enums import BackupType
if TYPE_CHECKING:
from trezor.crypto.slip39 import Share
_BIP39_WORD_COUNTS = (12, 18, 24)
_SLIP39_WORD_COUNTS = (20, 33)
def is_slip39_word_count(word_count: int) -> bool:
"""
Returns True for SLIP-39 and False for BIP-39.
Raise RuntimeError otherwise.
"""
if word_count in _SLIP39_WORD_COUNTS:
return True
elif word_count in _BIP39_WORD_COUNTS:
return False
# Unknown word count.
raise RuntimeError
def is_slip39_backup_type(backup_type: BackupType) -> bool:
return backup_type in (
BackupType.Slip39_Basic,
BackupType.Slip39_Advanced,
BackupType.Slip39_Single_Extendable,
BackupType.Slip39_Basic_Extendable,
BackupType.Slip39_Advanced_Extendable,
)
def is_slip39_advanced_backup_type(backup_type: BackupType) -> bool:
return backup_type in (
BackupType.Slip39_Advanced,
BackupType.Slip39_Advanced_Extendable,
)
def is_extendable_backup_type(backup_type: BackupType) -> bool:
return backup_type in (
BackupType.Slip39_Single_Extendable,
BackupType.Slip39_Basic_Extendable,
BackupType.Slip39_Advanced_Extendable,
)
def infer_backup_type(is_slip39: bool, share: Share | None = None) -> BackupType:
if not is_slip39: # BIP-39
return BackupType.Bip39
elif not share or share.group_count < 1: # invalid parameters
raise RuntimeError
elif share.group_count == 1:
if share.extendable:
if share.threshold == 1:
return BackupType.Slip39_Single_Extendable
else:
return BackupType.Slip39_Basic_Extendable
else:
return BackupType.Slip39_Basic
else:
if share.extendable:
return BackupType.Slip39_Advanced_Extendable
else:
return BackupType.Slip39_Advanced

View File

@ -3,6 +3,8 @@ from typing import TYPE_CHECKING
import storage.device as storage_device import storage.device as storage_device
from trezor import utils from trezor import utils
from . import backup_types
if TYPE_CHECKING: if TYPE_CHECKING:
from trezor.enums import BackupType from trezor.enums import BackupType
from trezor.ui.layouts.common import ProgressLayout from trezor.ui.layouts.common import ProgressLayout
@ -49,7 +51,7 @@ def get_seed(passphrase: str = "", progress_bar: bool = True) -> bytes:
from trezor.crypto import slip39 from trezor.crypto import slip39
identifier = storage_device.get_slip39_identifier() identifier = storage_device.get_slip39_identifier()
extendable = storage_device.get_slip39_extendable() extendable = backup_types.is_extendable_backup_type(get_type())
iteration_exponent = storage_device.get_slip39_iteration_exponent() iteration_exponent = storage_device.get_slip39_iteration_exponent()
if identifier is None or iteration_exponent is None: if identifier is None or iteration_exponent is None:
# Identifier or exponent expected but not found # Identifier or exponent expected but not found

View File

@ -13,7 +13,7 @@ async def load_device(msg: LoadDevice) -> Success:
from trezor.ui.layouts import confirm_action from trezor.ui.layouts import confirm_action
from trezor.wire import ProcessError, UnexpectedMessage from trezor.wire import ProcessError, UnexpectedMessage
from apps.management import backup_types from apps.common import backup_types
mnemonics = msg.mnemonics # local_cache_attribute mnemonics = msg.mnemonics # local_cache_attribute
@ -55,15 +55,8 @@ async def load_device(msg: LoadDevice) -> Success:
# this must succeed if the recover_ems call succeeded # this must succeed if the recover_ems call succeeded
share = slip39.decode_mnemonic(mnemonics[0]) share = slip39.decode_mnemonic(mnemonics[0])
if share.group_count == 1: backup_type = backup_types.infer_backup_type(is_slip39, share)
backup_type = BackupType.Slip39_Basic
elif share.group_count > 1:
backup_type = BackupType.Slip39_Advanced
else:
raise ProcessError("Invalid group count")
storage_device.set_slip39_identifier(identifier) storage_device.set_slip39_identifier(identifier)
storage_device.set_slip39_extendable(extendable)
storage_device.set_slip39_iteration_exponent(iteration_exponent) storage_device.set_slip39_iteration_exponent(iteration_exponent)
storage_device.store_mnemonic_secret( storage_device.store_mnemonic_secret(

View File

@ -14,7 +14,7 @@ async def backup_device(msg: BackupDevice) -> Success:
from trezor import wire from trezor import wire
from trezor.messages import Success from trezor.messages import Success
from apps.common import mnemonic from apps.common import backup_types, mnemonic
from .reset_device import backup_seed, backup_slip39_custom, layout from .reset_device import backup_seed, backup_slip39_custom, layout
@ -44,7 +44,8 @@ async def backup_device(msg: BackupDevice) -> Success:
storage_device.set_backed_up() storage_device.set_backed_up()
if group_threshold is not None: if group_threshold is not None:
await backup_slip39_custom(mnemonic_secret, group_threshold, groups) extendable = backup_types.is_extendable_backup_type(backup_type)
await backup_slip39_custom(mnemonic_secret, group_threshold, groups, extendable)
else: else:
await backup_seed(backup_type, mnemonic_secret) await backup_seed(backup_type, mnemonic_secret)

View File

@ -1,37 +0,0 @@
from typing import TYPE_CHECKING
from trezor.enums import BackupType
if TYPE_CHECKING:
from trezor.crypto.slip39 import Share
_BIP39_WORD_COUNTS = (12, 18, 24)
_SLIP39_WORD_COUNTS = (20, 33)
def is_slip39_word_count(word_count: int) -> bool:
"""
Returns True for SLIP-39 and False for BIP-39.
Raise RuntimeError otherwise.
"""
if word_count in _SLIP39_WORD_COUNTS:
return True
elif word_count in _BIP39_WORD_COUNTS:
return False
# Unknown word count.
raise RuntimeError
def is_slip39_backup_type(backup_type: BackupType) -> bool:
return backup_type in (BackupType.Slip39_Basic, BackupType.Slip39_Advanced)
def infer_backup_type(is_slip39: bool, share: Share | None = None) -> BackupType:
if not is_slip39: # BIP-39
return BackupType.Bip39
elif not share or share.group_count < 1: # invalid parameters
raise RuntimeError
elif share.group_count == 1:
return BackupType.Slip39_Basic
else:
return BackupType.Slip39_Advanced

View File

@ -6,7 +6,8 @@ import storage.recovery_shares as storage_recovery_shares
from trezor import TR, wire from trezor import TR, wire
from trezor.messages import Success from trezor.messages import Success
from .. import backup_types from apps.common import backup_types
from . import layout, recover from . import layout, recover
if TYPE_CHECKING: if TYPE_CHECKING:
@ -116,17 +117,16 @@ async def _finish_recovery_dry_run(secret: bytes, backup_type: BackupType) -> Su
result = utils.consteq(digest_stored, digest_input) result = utils.consteq(digest_stored, digest_input)
is_slip39 = backup_types.is_slip39_backup_type(backup_type) is_slip39 = backup_types.is_slip39_backup_type(backup_type)
# Check that the identifier and iteration exponent match as well # Check that the identifier, extendable backup flag and iteration exponent match as well
if is_slip39: if is_slip39:
if not backup_types.is_extendable_backup_type(backup_type): if not backup_types.is_extendable_backup_type(backup_type):
result &= ( result &= (
storage_device.get_slip39_identifier() storage_device.get_slip39_identifier()
== storage_recovery.get_slip39_identifier() == storage_recovery.get_slip39_identifier()
) )
result &= ( result &= backup_types.is_extendable_backup_type(
storage_device.get_slip39_extendable() storage_device.get_backup_type()
== storage_recovery.get_slip39_extendable() ) == backup_types.is_extendable_backup_type(backup_type)
)
result &= ( result &= (
storage_device.get_slip39_iteration_exponent() storage_device.get_slip39_iteration_exponent()
== storage_recovery.get_slip39_iteration_exponent() == storage_recovery.get_slip39_iteration_exponent()
@ -143,7 +143,6 @@ async def _finish_recovery_dry_run(secret: bytes, backup_type: BackupType) -> Su
async def _finish_recovery(secret: bytes, backup_type: BackupType) -> Success: async def _finish_recovery(secret: bytes, backup_type: BackupType) -> Success:
from trezor.enums import BackupType
from trezor.ui.layouts import show_success from trezor.ui.layouts import show_success
if backup_type is None: if backup_type is None:
@ -154,13 +153,11 @@ async def _finish_recovery(secret: bytes, backup_type: BackupType) -> Success:
) )
if backup_types.is_slip39_backup_type(backup_type): if backup_types.is_slip39_backup_type(backup_type):
identifier = storage_recovery.get_slip39_identifier() identifier = storage_recovery.get_slip39_identifier()
extendable = storage_recovery.get_slip39_extendable()
exponent = storage_recovery.get_slip39_iteration_exponent() exponent = storage_recovery.get_slip39_iteration_exponent()
if identifier is None or extendable is None or exponent is None: if identifier is None or exponent is None:
# Identifier and exponent need to be stored in storage at this point # Identifier and exponent need to be stored in storage at this point
raise RuntimeError raise RuntimeError
storage_device.set_slip39_identifier(identifier) storage_device.set_slip39_identifier(identifier)
storage_device.set_slip39_extendable(extendable)
storage_device.set_slip39_iteration_exponent(exponent) storage_device.set_slip39_iteration_exponent(exponent)
storage_recovery.end_progress() storage_recovery.end_progress()

View File

@ -10,7 +10,7 @@ from trezor.ui.layouts.recovery import ( # noqa: F401
show_remaining_shares, show_remaining_shares,
) )
from .. import backup_types from apps.common import backup_types
if TYPE_CHECKING: if TYPE_CHECKING:
from typing import Callable from typing import Callable

View File

@ -41,7 +41,6 @@ def process_slip39(words: str) -> tuple[bytes | None, slip39.Share]:
storage_recovery.set_slip39_group_count(share.group_count) storage_recovery.set_slip39_group_count(share.group_count)
storage_recovery.set_slip39_iteration_exponent(share.iteration_exponent) storage_recovery.set_slip39_iteration_exponent(share.iteration_exponent)
storage_recovery.set_slip39_identifier(share.identifier) storage_recovery.set_slip39_identifier(share.identifier)
storage_recovery.set_slip39_extendable(share.extendable)
storage_recovery.set_slip39_remaining_shares(share.threshold - 1, group_index) storage_recovery.set_slip39_remaining_shares(share.threshold - 1, group_index)
storage_recovery_shares.set(share.index, group_index, words) storage_recovery_shares.set(share.index, group_index, words)
@ -95,7 +94,7 @@ if TYPE_CHECKING:
def load_slip39_state() -> Slip39State: def load_slip39_state() -> Slip39State:
from .. import backup_types from apps.common import backup_types
previous_mnemonics = fetch_previous_mnemonics() previous_mnemonics = fetch_previous_mnemonics()
if not previous_mnemonics: if not previous_mnemonics:

View File

@ -23,6 +23,8 @@ class ThresholdReached(WordValidityResult):
def check(backup_type: BackupType | None, partial_mnemonic: list[str]) -> None: def check(backup_type: BackupType | None, partial_mnemonic: list[str]) -> None:
from trezor.enums import BackupType from trezor.enums import BackupType
from apps.common import backup_types
from . import recover from . import recover
# we can't perform any checks if the backup type was not yet decided # we can't perform any checks if the backup type was not yet decided
@ -37,10 +39,11 @@ def check(backup_type: BackupType | None, partial_mnemonic: list[str]) -> None:
# this should not happen if backup_type is set # this should not happen if backup_type is set
raise RuntimeError raise RuntimeError
if backup_type == BackupType.Slip39_Basic: if backup_types.is_slip39_backup_type(backup_type):
_check_slip39_basic(partial_mnemonic, previous_mnemonics) if backup_types.is_slip39_advanced_backup_type(backup_type):
elif backup_type == BackupType.Slip39_Advanced: _check_slip39_advanced(partial_mnemonic, previous_mnemonics)
_check_slip39_advanced(partial_mnemonic, previous_mnemonics) else:
_check_slip39_basic(partial_mnemonic, previous_mnemonics)
else: else:
# there are no other backup types # there are no other backup types
raise RuntimeError raise RuntimeError

View File

@ -8,7 +8,8 @@ from trezor.enums import BackupType
from trezor.ui.layouts import confirm_action from trezor.ui.layouts import confirm_action
from trezor.wire import ProcessError from trezor.wire import ProcessError
from .. import backup_types from apps.common import backup_types
from . import layout from . import layout
if __debug__: if __debug__:
@ -21,6 +22,9 @@ if TYPE_CHECKING:
BAK_T_BIP39 = BackupType.Bip39 # global_import_cache BAK_T_BIP39 = BackupType.Bip39 # global_import_cache
BAK_T_SLIP39_BASIC = BackupType.Slip39_Basic # global_import_cache BAK_T_SLIP39_BASIC = BackupType.Slip39_Basic # global_import_cache
BAK_T_SLIP39_ADVANCED = BackupType.Slip39_Advanced # global_import_cache BAK_T_SLIP39_ADVANCED = BackupType.Slip39_Advanced # global_import_cache
BAK_T_SLIP39_SINGLE_EXT = BackupType.Slip39_Single_Extendable # global_import_cache
BAK_T_SLIP39_BASIC_EXT = BackupType.Slip39_Basic_Extendable # global_import_cache
BAK_T_SLIP39_ADVANCED_EXT = BackupType.Slip39_Advanced_Extendable # global_import_cache
_DEFAULT_BACKUP_TYPE = BAK_T_BIP39 _DEFAULT_BACKUP_TYPE = BAK_T_BIP39
@ -36,6 +40,13 @@ async def reset_device(msg: ResetDevice) -> Success:
backup_type = msg.backup_type # local_cache_attribute backup_type = msg.backup_type # local_cache_attribute
# Force extendable backup.
if backup_type == BAK_T_SLIP39_BASIC:
backup_type = BAK_T_SLIP39_BASIC_EXT
if backup_type == BAK_T_SLIP39_ADVANCED:
backup_type = BAK_T_SLIP39_ADVANCED_EXT
# validate parameters and device state # validate parameters and device state
_validate_reset_device(msg) _validate_reset_device(msg)
@ -74,7 +85,6 @@ async def reset_device(msg: ResetDevice) -> Success:
elif backup_types.is_slip39_backup_type(backup_type): elif backup_types.is_slip39_backup_type(backup_type):
# generate and set SLIP39 parameters # generate and set SLIP39 parameters
storage_device.set_slip39_identifier(slip39.generate_random_identifier()) storage_device.set_slip39_identifier(slip39.generate_random_identifier())
storage_device.set_slip39_extendable(slip39.DEFAULT_EXTENDABLE_FLAG)
storage_device.set_slip39_iteration_exponent(slip39.DEFAULT_ITERATION_EXPONENT) storage_device.set_slip39_iteration_exponent(slip39.DEFAULT_ITERATION_EXPONENT)
else: else:
# Unknown backup type. # Unknown backup type.
@ -110,7 +120,18 @@ async def reset_device(msg: ResetDevice) -> Success:
return Success(message="Initialized") return Success(message="Initialized")
async def _backup_slip39_basic(encrypted_master_secret: bytes) -> None: async def _backup_slip39_single(
encrypted_master_secret: bytes, extendable: bool
) -> None:
mnemonics = _get_slip39_mnemonics(encrypted_master_secret, 1, ((1, 1),), extendable)
# for a single 1-of-1 group, we use the same layouts as for BIP39
await layout.show_and_confirm_mnemonic(mnemonics[0][0])
async def _backup_slip39_basic(
encrypted_master_secret: bytes, extendable: bool
) -> None:
group_threshold = 1 group_threshold = 1
# get number of shares # get number of shares
@ -122,7 +143,10 @@ async def _backup_slip39_basic(encrypted_master_secret: bytes) -> None:
share_threshold = await layout.slip39_prompt_threshold(share_count) share_threshold = await layout.slip39_prompt_threshold(share_count)
mnemonics = _get_slip39_mnemonics( mnemonics = _get_slip39_mnemonics(
encrypted_master_secret, group_threshold, ((share_threshold, share_count),) encrypted_master_secret,
group_threshold,
((share_threshold, share_count),),
extendable,
) )
# show and confirm individual shares # show and confirm individual shares
@ -130,7 +154,9 @@ async def _backup_slip39_basic(encrypted_master_secret: bytes) -> None:
await layout.slip39_basic_show_and_confirm_shares(mnemonics[0]) await layout.slip39_basic_show_and_confirm_shares(mnemonics[0])
async def _backup_slip39_advanced(encrypted_master_secret: bytes) -> None: async def _backup_slip39_advanced(
encrypted_master_secret: bytes, extendable: bool
) -> None:
# get number of groups # get number of groups
await layout.slip39_show_checklist(0, advanced=True) await layout.slip39_show_checklist(0, advanced=True)
groups_count = await layout.slip39_advanced_prompt_number_of_groups() groups_count = await layout.slip39_advanced_prompt_number_of_groups()
@ -147,7 +173,9 @@ async def _backup_slip39_advanced(encrypted_master_secret: bytes) -> None:
share_threshold = await layout.slip39_prompt_threshold(share_count, i) share_threshold = await layout.slip39_prompt_threshold(share_count, i)
groups.append((share_threshold, share_count)) groups.append((share_threshold, share_count))
mnemonics = _get_slip39_mnemonics(encrypted_master_secret, group_threshold, groups) mnemonics = _get_slip39_mnemonics(
encrypted_master_secret, group_threshold, groups, extendable
)
# show and confirm individual shares # show and confirm individual shares
await layout.slip39_advanced_show_and_confirm_shares(mnemonics) await layout.slip39_advanced_show_and_confirm_shares(mnemonics)
@ -157,14 +185,15 @@ async def backup_slip39_custom(
encrypted_master_secret: bytes, encrypted_master_secret: bytes,
group_threshold: int, group_threshold: int,
groups: Sequence[tuple[int, int]], groups: Sequence[tuple[int, int]],
extendable: bool,
) -> None: ) -> None:
mnemonics = _get_slip39_mnemonics(encrypted_master_secret, group_threshold, groups)
# show and confirm individual shares # show and confirm individual shares
if len(groups) == 1 and groups[0][0] == 1 and groups[0][1] == 1: if len(groups) == 1 and groups[0][0] == 1 and groups[0][1] == 1:
# for a single 1-of-1 group, we use the same layouts as for BIP39 await _backup_slip39_single(encrypted_master_secret, extendable)
await layout.show_and_confirm_mnemonic(mnemonics[0][0])
else: else:
mnemonics = _get_slip39_mnemonics(
encrypted_master_secret, group_threshold, groups, extendable
)
await confirm_action( await confirm_action(
"warning_shamir_backup", "warning_shamir_backup",
TR.reset__title_shamir_backup, TR.reset__title_shamir_backup,
@ -183,9 +212,9 @@ def _get_slip39_mnemonics(
encrypted_master_secret: bytes, encrypted_master_secret: bytes,
group_threshold: int, group_threshold: int,
groups: Sequence[tuple[int, int]], groups: Sequence[tuple[int, int]],
extendable: bool,
): ):
identifier = storage_device.get_slip39_identifier() identifier = storage_device.get_slip39_identifier()
extendable = storage_device.get_slip39_extendable()
iteration_exponent = storage_device.get_slip39_iteration_exponent() iteration_exponent = storage_device.get_slip39_iteration_exponent()
if identifier is None or iteration_exponent is None: if identifier is None or iteration_exponent is None:
raise ValueError raise ValueError
@ -204,8 +233,6 @@ def _get_slip39_mnemonics(
def _validate_reset_device(msg: ResetDevice) -> None: def _validate_reset_device(msg: ResetDevice) -> None:
from trezor.wire import UnexpectedMessage from trezor.wire import UnexpectedMessage
from .. import backup_types
backup_type = msg.backup_type or _DEFAULT_BACKUP_TYPE backup_type = msg.backup_type or _DEFAULT_BACKUP_TYPE
if backup_types.is_slip39_backup_type(backup_type): if backup_types.is_slip39_backup_type(backup_type):
if msg.strength not in (128, 256): if msg.strength not in (128, 256):
@ -239,9 +266,13 @@ def _compute_secret_from_entropy(
async def backup_seed(backup_type: BackupType, mnemonic_secret: bytes) -> None: async def backup_seed(backup_type: BackupType, mnemonic_secret: bytes) -> None:
if backup_type == BAK_T_SLIP39_BASIC: if backup_types.is_slip39_backup_type(backup_type):
await _backup_slip39_basic(mnemonic_secret) extendable = backup_types.is_extendable_backup_type(backup_type)
elif backup_type == BAK_T_SLIP39_ADVANCED: if backup_types.is_slip39_advanced_backup_type(backup_type):
await _backup_slip39_advanced(mnemonic_secret) await _backup_slip39_advanced(mnemonic_secret, extendable)
elif backup_type == BAK_T_SLIP39_SINGLE_EXT:
await _backup_slip39_single(mnemonic_secret, extendable)
else:
await _backup_slip39_basic(mnemonic_secret, extendable)
else: else:
await layout.show_and_confirm_mnemonic(mnemonic_secret.decode()) await layout.show_and_confirm_mnemonic(mnemonic_secret.decode())

View File

@ -35,7 +35,6 @@ INITIALIZED = const(0x13) # bool (0x01 or empty)
_SAFETY_CHECK_LEVEL = const(0x14) # int _SAFETY_CHECK_LEVEL = const(0x14) # int
_EXPERIMENTAL_FEATURES = const(0x15) # bool (0x01 or empty) _EXPERIMENTAL_FEATURES = const(0x15) # bool (0x01 or empty)
_HIDE_PASSPHRASE_FROM_HOST = const(0x16) # bool (0x01 or empty) _HIDE_PASSPHRASE_FROM_HOST = const(0x16) # bool (0x01 or empty)
_SLIP39_EXTENDABLE = const(0x17) # bool (0x01 or empty)
SAFETY_CHECK_LEVEL_STRICT : Literal[0] = const(0) SAFETY_CHECK_LEVEL_STRICT : Literal[0] = const(0)
SAFETY_CHECK_LEVEL_PROMPT : Literal[1] = const(1) SAFETY_CHECK_LEVEL_PROMPT : Literal[1] = const(1)
@ -130,6 +129,9 @@ def get_backup_type() -> BackupType:
BackupType.Bip39, BackupType.Bip39,
BackupType.Slip39_Basic, BackupType.Slip39_Basic,
BackupType.Slip39_Advanced, BackupType.Slip39_Advanced,
BackupType.Slip39_Single_Extendable,
BackupType.Slip39_Basic_Extendable,
BackupType.Slip39_Advanced_Extendable,
): ):
# Invalid backup type # Invalid backup type
raise RuntimeError raise RuntimeError
@ -261,20 +263,6 @@ def get_slip39_identifier() -> int | None:
return common.get_uint16(_NAMESPACE, _SLIP39_IDENTIFIER) return common.get_uint16(_NAMESPACE, _SLIP39_IDENTIFIER)
def set_slip39_extendable(extendable: bool) -> None:
"""
The device's actual SLIP-39 extendable backup flag.
Not to be confused with recovery.extendable, which is stored only during
the recovery process and it is copied here upon success.
"""
common.set_bool(_NAMESPACE, _SLIP39_EXTENDABLE, extendable)
def get_slip39_extendable() -> bool:
"""The device's actual SLIP-39 extendable backup flag."""
return common.get_bool(_NAMESPACE, _SLIP39_EXTENDABLE)
def set_slip39_iteration_exponent(exponent: int) -> None: def set_slip39_iteration_exponent(exponent: int) -> None:
""" """
The device's actual SLIP-39 iteration exponent used in passphrase derivation. The device's actual SLIP-39 iteration exponent used in passphrase derivation.

View File

@ -57,16 +57,6 @@ def get_slip39_identifier() -> int | None:
return common.get_uint16(_NAMESPACE, _SLIP39_IDENTIFIER) return common.get_uint16(_NAMESPACE, _SLIP39_IDENTIFIER)
def set_slip39_extendable(extendable: bool) -> None:
_require_progress()
common.set_bool(_NAMESPACE, _SLIP39_EXTENDABLE, extendable)
def get_slip39_extendable() -> bool:
_require_progress()
return common.get_bool(_NAMESPACE, _SLIP39_EXTENDABLE)
def set_slip39_iteration_exponent(exponent: int) -> None: def set_slip39_iteration_exponent(exponent: int) -> None:
_require_progress() _require_progress()
common.set_uint8(_NAMESPACE, _SLIP39_ITERATION_EXPONENT, exponent) common.set_uint8(_NAMESPACE, _SLIP39_ITERATION_EXPONENT, exponent)

View File

@ -5,3 +5,6 @@
Bip39 = 0 Bip39 = 0
Slip39_Basic = 1 Slip39_Basic = 1
Slip39_Advanced = 2 Slip39_Advanced = 2
Slip39_Single_Extendable = 3
Slip39_Basic_Extendable = 4
Slip39_Advanced_Extendable = 5

View File

@ -425,6 +425,9 @@ if TYPE_CHECKING:
Bip39 = 0 Bip39 = 0
Slip39_Basic = 1 Slip39_Basic = 1
Slip39_Advanced = 2 Slip39_Advanced = 2
Slip39_Single_Extendable = 3
Slip39_Basic_Extendable = 4
Slip39_Advanced_Extendable = 5
class SafetyCheckLevel(IntEnum): class SafetyCheckLevel(IntEnum):
Strict = 0 Strict = 0

View File

@ -41,7 +41,7 @@ class TestSlip39(unittest.TestCase):
share.iteration_exponent, storage.recovery.get_slip39_iteration_exponent() share.iteration_exponent, storage.recovery.get_slip39_iteration_exponent()
) )
self.assertEqual(share.identifier, storage.recovery.get_slip39_identifier()) self.assertEqual(share.identifier, storage.recovery.get_slip39_identifier())
self.assertEqual(share.extendable, storage.recovery.get_slip39_extendable()) self.assertEqual(share.extendable, False)
self.assertEqual(storage.recovery.get_slip39_remaining_shares(0), 2) self.assertEqual(storage.recovery.get_slip39_remaining_shares(0), 2)
self.assertEqual( self.assertEqual(
storage.recovery_shares.get(share.index, share.group_index), first storage.recovery_shares.get(share.index, share.group_index), first
@ -85,7 +85,7 @@ class TestSlip39(unittest.TestCase):
share.iteration_exponent, storage.recovery.get_slip39_iteration_exponent() share.iteration_exponent, storage.recovery.get_slip39_iteration_exponent()
) )
self.assertEqual(share.identifier, storage.recovery.get_slip39_identifier()) self.assertEqual(share.identifier, storage.recovery.get_slip39_identifier())
self.assertEqual(share.extendable, storage.recovery.get_slip39_extendable()) self.assertEqual(share.extendable, False)
self.assertEqual( self.assertEqual(
storage.recovery.fetch_slip39_remaining_shares(), [16, 0, 16, 16] storage.recovery.fetch_slip39_remaining_shares(), [16, 0, 16, 16]
) )
@ -102,7 +102,7 @@ class TestSlip39(unittest.TestCase):
share.iteration_exponent, storage.recovery.get_slip39_iteration_exponent() share.iteration_exponent, storage.recovery.get_slip39_iteration_exponent()
) )
self.assertEqual(share.identifier, storage.recovery.get_slip39_identifier()) self.assertEqual(share.identifier, storage.recovery.get_slip39_identifier())
self.assertEqual(share.extendable, storage.recovery.get_slip39_extendable()) self.assertEqual(share.extendable, False)
self.assertEqual( self.assertEqual(
storage.recovery_shares.get(share.index, share.group_index), words storage.recovery_shares.get(share.index, share.group_index), words
) )
@ -125,7 +125,7 @@ class TestSlip39(unittest.TestCase):
share.iteration_exponent, storage.recovery.get_slip39_iteration_exponent() share.iteration_exponent, storage.recovery.get_slip39_iteration_exponent()
) )
self.assertEqual(share.identifier, storage.recovery.get_slip39_identifier()) self.assertEqual(share.identifier, storage.recovery.get_slip39_identifier())
self.assertEqual(share.extendable, storage.recovery.get_slip39_extendable()) self.assertEqual(share.extendable, False)
self.assertEqual( self.assertEqual(
storage.recovery_shares.get(share.index, share.group_index), words storage.recovery_shares.get(share.index, share.group_index), words
) )
@ -150,7 +150,7 @@ class TestSlip39(unittest.TestCase):
share.iteration_exponent, storage.recovery.get_slip39_iteration_exponent() share.iteration_exponent, storage.recovery.get_slip39_iteration_exponent()
) )
self.assertEqual(share.identifier, storage.recovery.get_slip39_identifier()) self.assertEqual(share.identifier, storage.recovery.get_slip39_identifier())
self.assertEqual(share.extendable, storage.recovery.get_slip39_extendable()) self.assertEqual(share.extendable, False)
self.assertEqual( self.assertEqual(
storage.recovery_shares.get(share.index, share.group_index), words storage.recovery_shares.get(share.index, share.group_index), words
) )

View File

@ -454,6 +454,9 @@ class BackupType(IntEnum):
Bip39 = 0 Bip39 = 0
Slip39_Basic = 1 Slip39_Basic = 1
Slip39_Advanced = 2 Slip39_Advanced = 2
Slip39_Single_Extendable = 3
Slip39_Basic_Extendable = 4
Slip39_Advanced_Extendable = 5
class SafetyCheckLevel(IntEnum): class SafetyCheckLevel(IntEnum):

View File

@ -10395,6 +10395,12 @@ pub enum BackupType {
Slip39_Basic = 1, Slip39_Basic = 1,
// @@protoc_insertion_point(enum_value:hw.trezor.messages.management.BackupType.Slip39_Advanced) // @@protoc_insertion_point(enum_value:hw.trezor.messages.management.BackupType.Slip39_Advanced)
Slip39_Advanced = 2, Slip39_Advanced = 2,
// @@protoc_insertion_point(enum_value:hw.trezor.messages.management.BackupType.Slip39_Single_Extendable)
Slip39_Single_Extendable = 3,
// @@protoc_insertion_point(enum_value:hw.trezor.messages.management.BackupType.Slip39_Basic_Extendable)
Slip39_Basic_Extendable = 4,
// @@protoc_insertion_point(enum_value:hw.trezor.messages.management.BackupType.Slip39_Advanced_Extendable)
Slip39_Advanced_Extendable = 5,
} }
impl ::protobuf::Enum for BackupType { impl ::protobuf::Enum for BackupType {
@ -10409,6 +10415,9 @@ impl ::protobuf::Enum for BackupType {
0 => ::std::option::Option::Some(BackupType::Bip39), 0 => ::std::option::Option::Some(BackupType::Bip39),
1 => ::std::option::Option::Some(BackupType::Slip39_Basic), 1 => ::std::option::Option::Some(BackupType::Slip39_Basic),
2 => ::std::option::Option::Some(BackupType::Slip39_Advanced), 2 => ::std::option::Option::Some(BackupType::Slip39_Advanced),
3 => ::std::option::Option::Some(BackupType::Slip39_Single_Extendable),
4 => ::std::option::Option::Some(BackupType::Slip39_Basic_Extendable),
5 => ::std::option::Option::Some(BackupType::Slip39_Advanced_Extendable),
_ => ::std::option::Option::None _ => ::std::option::Option::None
} }
} }
@ -10418,6 +10427,9 @@ impl ::protobuf::Enum for BackupType {
"Bip39" => ::std::option::Option::Some(BackupType::Bip39), "Bip39" => ::std::option::Option::Some(BackupType::Bip39),
"Slip39_Basic" => ::std::option::Option::Some(BackupType::Slip39_Basic), "Slip39_Basic" => ::std::option::Option::Some(BackupType::Slip39_Basic),
"Slip39_Advanced" => ::std::option::Option::Some(BackupType::Slip39_Advanced), "Slip39_Advanced" => ::std::option::Option::Some(BackupType::Slip39_Advanced),
"Slip39_Single_Extendable" => ::std::option::Option::Some(BackupType::Slip39_Single_Extendable),
"Slip39_Basic_Extendable" => ::std::option::Option::Some(BackupType::Slip39_Basic_Extendable),
"Slip39_Advanced_Extendable" => ::std::option::Option::Some(BackupType::Slip39_Advanced_Extendable),
_ => ::std::option::Option::None _ => ::std::option::Option::None
} }
} }
@ -10426,6 +10438,9 @@ impl ::protobuf::Enum for BackupType {
BackupType::Bip39, BackupType::Bip39,
BackupType::Slip39_Basic, BackupType::Slip39_Basic,
BackupType::Slip39_Advanced, BackupType::Slip39_Advanced,
BackupType::Slip39_Single_Extendable,
BackupType::Slip39_Basic_Extendable,
BackupType::Slip39_Advanced_Extendable,
]; ];
} }
@ -10744,13 +10759,15 @@ static file_descriptor_proto_data: &'static [u8] = b"\
\x1b\n\taddress_n\x18\x01\x20\x03(\rR\x08addressN\x12\x10\n\x03mac\x18\ \x1b\n\taddress_n\x18\x01\x20\x03(\rR\x08addressN\x12\x10\n\x03mac\x18\
\x02\x20\x01(\x0cR\x03mac\"'\n\x13UnlockedPathRequest\x12\x10\n\x03mac\ \x02\x20\x01(\x0cR\x03mac\"'\n\x13UnlockedPathRequest\x12\x10\n\x03mac\
\x18\x01\x20\x01(\x0cR\x03mac\"\x14\n\x12ShowDeviceTutorial\"\x12\n\x10U\ \x18\x01\x20\x01(\x0cR\x03mac\"\x14\n\x12ShowDeviceTutorial\"\x12\n\x10U\
nlockBootloader*>\n\nBackupType\x12\t\n\x05Bip39\x10\0\x12\x10\n\x0cSlip\ nlockBootloader*\x99\x01\n\nBackupType\x12\t\n\x05Bip39\x10\0\x12\x10\n\
39_Basic\x10\x01\x12\x13\n\x0fSlip39_Advanced\x10\x02*G\n\x10SafetyCheck\ \x0cSlip39_Basic\x10\x01\x12\x13\n\x0fSlip39_Advanced\x10\x02\x12\x1c\n\
Level\x12\n\n\x06Strict\x10\0\x12\x10\n\x0cPromptAlways\x10\x01\x12\x15\ \x18Slip39_Single_Extendable\x10\x03\x12\x1b\n\x17Slip39_Basic_Extendabl\
\n\x11PromptTemporarily\x10\x02*0\n\x10HomescreenFormat\x12\x08\n\x04Toi\ e\x10\x04\x12\x1e\n\x1aSlip39_Advanced_Extendable\x10\x05*G\n\x10SafetyC\
f\x10\x01\x12\x08\n\x04Jpeg\x10\x02\x12\x08\n\x04ToiG\x10\x03BB\n#com.sa\ heckLevel\x12\n\n\x06Strict\x10\0\x12\x10\n\x0cPromptAlways\x10\x01\x12\
toshilabs.trezor.lib.protobufB\x17TrezorMessageManagement\x80\xa6\x1d\ \x15\n\x11PromptTemporarily\x10\x02*0\n\x10HomescreenFormat\x12\x08\n\
\x01\ \x04Toif\x10\x01\x12\x08\n\x04Jpeg\x10\x02\x12\x08\n\x04ToiG\x10\x03BB\n\
#com.satoshilabs.trezor.lib.protobufB\x17TrezorMessageManagement\x80\xa6\
\x1d\x01\
"; ";
/// `FileDescriptorProto` object which was a source for this generated file /// `FileDescriptorProto` object which was a source for this generated file