Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor homescreen and backup types #509

Merged
merged 2 commits into from Sep 10, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
15 changes: 14 additions & 1 deletion core/src/apps/common/storage/recovery.py
Expand Up @@ -4,6 +4,9 @@

from apps.common.storage import common, recovery_shares

if False:
from apps.management.recovery_device.backup_types import BackupTypeUnion

# Namespace:
_NAMESPACE = common._APP_RECOVERY

Expand All @@ -12,12 +15,13 @@
_IN_PROGRESS = const(0x00) # bool
_DRY_RUN = const(0x01) # bool
_WORD_COUNT = const(0x02) # int
_REMAINING = const(0x05) # int
_SLIP39_IDENTIFIER = const(0x03) # bytes
_SLIP39_THRESHOLD = const(0x04) # int
_REMAINING = const(0x05) # int
_SLIP39_ITERATION_EXPONENT = const(0x06) # int
_SLIP39_GROUP_COUNT = const(0x07) # int
_SLIP39_GROUP_THRESHOLD = const(0x08) # int
_BACKUP_TYPE = const(0x09) # int
# fmt: on

if False:
Expand Down Expand Up @@ -48,6 +52,14 @@ def get_word_count() -> Optional[int]:
return common._get_uint8(_NAMESPACE, _WORD_COUNT)


def set_backup_type(backup_type: BackupTypeUnion) -> None:
common._set_uint8(_NAMESPACE, _BACKUP_TYPE, backup_type)


def get_backup_type() -> Optional[BackupTypeUnion]:
return common._get_uint8(_NAMESPACE, _BACKUP_TYPE)


def set_slip39_identifier(identifier: int) -> None:
common._set_uint16(_NAMESPACE, _SLIP39_IDENTIFIER, identifier)

Expand Down Expand Up @@ -135,4 +147,5 @@ def end_progress() -> None:
common._delete(_NAMESPACE, _SLIP39_ITERATION_EXPONENT)
common._delete(_NAMESPACE, _SLIP39_GROUP_COUNT)
common._delete(_NAMESPACE, _SLIP39_GROUP_THRESHOLD)
common._delete(_NAMESPACE, _BACKUP_TYPE)
recovery_shares.delete()
2 changes: 1 addition & 1 deletion core/src/apps/common/storage/recovery_shares.py
Expand Up @@ -23,7 +23,7 @@ def get(index: int) -> Optional[str]:
def fetch() -> List[str]:
mnemonics = []
if not recovery.get_slip39_group_count():
raise RuntimeError
return mnemonics
for index in range(0, slip39.MAX_SHARE_COUNT * recovery.get_slip39_group_count()):
m = get(index)
if m:
Expand Down
24 changes: 8 additions & 16 deletions core/src/apps/management/load_device.py
Expand Up @@ -12,39 +12,31 @@

async def load_device(ctx, msg):
word_count = _validate(msg)
possible_backup_types = backup_types.get(word_count)
is_slip39 = backup_types.is_slip39_word_count(word_count)

if (
BackupType.Bip39 in possible_backup_types
and not msg.skip_checksum
and not bip39.check(msg.mnemonics[0])
):
if not is_slip39 and not msg.skip_checksum and not bip39.check(msg.mnemonics[0]):
raise wire.ProcessError("Mnemonic is not valid")

await _warn(ctx)

if BackupType.Bip39 in possible_backup_types:
if not is_slip39: # BIP-39
secret = msg.mnemonics[0].encode()
elif backup_types.is_slip39(possible_backup_types):
backup_type = BackupType.Bip39
else:
identifier, iteration_exponent, secret, group_count = slip39.combine_mnemonics(
msg.mnemonics
)
if group_count == 1:
possible_backup_types = [BackupType.Slip39_Basic]
backup_type = BackupType.Slip39_Basic
elif group_count > 1:
possible_backup_types = [BackupType.Slip39_Advanced]
backup_type = BackupType.Slip39_Advanced
else:
raise RuntimeError("Invalid group count")
storage.device.set_slip39_identifier(identifier)
storage.device.set_slip39_iteration_exponent(iteration_exponent)
else:
raise RuntimeError("Unknown mnemonic type")

if len(possible_backup_types) != 1:
# Only one possible backup type should be left before storing into the storage.
raise RuntimeError
storage.device.store_mnemonic_secret(
secret, possible_backup_types[0], needs_backup=True, no_backup=False
secret, backup_type, needs_backup=True, no_backup=False
)
storage.device.load_settings(
use_passphrase=msg.passphrase_protection, label=msg.label
Expand Down
28 changes: 11 additions & 17 deletions core/src/apps/management/recovery_device/backup_types.py
Expand Up @@ -7,24 +7,18 @@
BackupType.Bip39, BackupType.Slip39_Basic, BackupType.Slip39_Advanced
]

# possible backup types based on the number of words
TYPES = {
12: [BackupType.Bip39],
18: [BackupType.Bip39],
24: [BackupType.Bip39],
20: [BackupType.Slip39_Basic, BackupType.Slip39_Advanced],
33: [BackupType.Slip39_Basic, BackupType.Slip39_Advanced],
}
_BIP39_WORD_COUNTS = (12, 18, 24)
_SLIP39_WORD_COUNTS = (20, 33)


def get(word_count: int) -> list:
def is_slip39_word_count(word_count: int) -> bool:
"""
Returns possible backup types inferred from the word count.
Returns True for SLIP-39 and False for BIP-39.
Raise RuntimeError otherwise.
"""
if word_count not in TYPES:
raise RuntimeError("Recovery: Unknown words count")
return TYPES[word_count]


def is_slip39(backup: list) -> bool:
return BackupType.Slip39_Basic in backup or BackupType.Slip39_Advanced in backup
if word_count in _SLIP39_WORD_COUNTS:
return True
elif word_count in _BIP39_WORD_COUNTS:
return False
# Unknown word count.
raise RuntimeError