Esempio n. 1
0
def fetch_previous_mnemonics() -> Optional[List[List[str]]]:
    mnemonics = []
    if not storage_recovery.get_slip39_group_count():
        return None
    for i in range(storage_recovery.get_slip39_group_count()):
        mnemonics.append(storage_recovery_shares.fetch_group(i))
    if not any(p for p in mnemonics):
        return None
    return mnemonics
def fetch() -> List[str]:
    mnemonics = []
    if not recovery.get_slip39_group_count():
        raise RuntimeError
    for index in range(
            0, slip39.MAX_SHARE_COUNT * recovery.get_slip39_group_count()):
        m = get(index)
        if m:
            mnemonics.append(m)
    return mnemonics
Esempio n. 3
0
async def _request_share_next_screen(ctx: wire.GenericContext) -> None:
    remaining = storage_recovery.fetch_slip39_remaining_shares()
    group_count = storage_recovery.get_slip39_group_count()
    if not remaining:
        # 'remaining' should be stored at this point
        raise RuntimeError

    if group_count > 1:
        content = layout.RecoveryHomescreen("More shares needed")
        await layout.homescreen_dialog(ctx, content, "Enter",
                                       _show_remaining_groups_and_shares)
    else:
        if remaining[0] == 1:
            text = "1 more share"
        else:
            text = "%d more shares" % remaining[0]
        content = layout.RecoveryHomescreen(text, "needed to enter")
        await layout.homescreen_dialog(ctx, content, "Enter share")
Esempio n. 4
0
def process_slip39(words: str) -> Tuple[Optional[bytes], slip39.Share]:
    """
    Processes a single mnemonic share. Returns the encrypted master secret
    (or None if more shares are needed) and the share's group index and member index.
    """
    share = slip39.decode_mnemonic(words)

    remaining = storage_recovery.fetch_slip39_remaining_shares()

    # if this is the first share, parse and store metadata
    if not remaining:
        storage_recovery.set_slip39_group_count(share.group_count)
        storage_recovery.set_slip39_iteration_exponent(share.iteration_exponent)
        storage_recovery.set_slip39_identifier(share.identifier)
        storage_recovery.set_slip39_remaining_shares(
            share.threshold - 1, share.group_index
        )
        storage_recovery_shares.set(share.index, share.group_index, words)

        # if share threshold and group threshold are 1
        # we can calculate the secret right away
        if share.threshold == 1 and share.group_threshold == 1:
            identifier, iteration_exponent, secret, _ = slip39.combine_mnemonics(
                [words]
            )
            return secret, share
        else:
            # we need more shares
            return None, share

    # These should be checked by UI before so it's a Runtime exception otherwise
    if share.identifier != storage_recovery.get_slip39_identifier():
        raise RuntimeError("Slip39: Share identifiers do not match")
    if share.iteration_exponent != storage_recovery.get_slip39_iteration_exponent():
        raise RuntimeError("Slip39: Share exponents do not match")
    if storage_recovery_shares.get(share.index, share.group_index):
        raise RuntimeError("Slip39: This mnemonic was already entered")
    if share.group_count != storage_recovery.get_slip39_group_count():
        raise RuntimeError("Slip39: Group count does not match")

    remaining_for_share = (
        storage_recovery.get_slip39_remaining_shares(share.group_index)
        or share.threshold
    )
    storage_recovery.set_slip39_remaining_shares(
        remaining_for_share - 1, share.group_index
    )
    remaining[share.group_index] = remaining_for_share - 1
    storage_recovery_shares.set(share.index, share.group_index, words)

    if remaining.count(0) < share.group_threshold:
        # we need more shares
        return None, share

    if share.group_count > 1:
        mnemonics = []
        for i, r in enumerate(remaining):
            # if we have multiple groups pass only the ones with threshold reached
            if r == 0:
                group = storage_recovery_shares.fetch_group(i)
                mnemonics.extend(group)
    else:
        # in case of slip39 basic we only need the first and only group
        mnemonics = storage_recovery_shares.fetch_group(0)

    identifier, iteration_exponent, secret, _ = slip39.combine_mnemonics(mnemonics)
    return secret, share