def test_iteration_exponent(self):
        identifier = slip39.generate_random_identifier()
        mnemonics = slip39.split_ems(1, [(3, 5)], identifier, 1, self.EMS)
        mnemonics = mnemonics[0]
        identifier, exponent, ems = slip39.recover_ems(mnemonics[1:4])
        self.assertEqual(ems, self.EMS)

        identifier = slip39.generate_random_identifier()
        mnemonics = slip39.split_ems(1, [(3, 5)], identifier, 2, self.EMS)
        mnemonics = mnemonics[0]
        identifier, exponent, ems = slip39.recover_ems(mnemonics[1:4])
        self.assertEqual(ems, self.EMS)
예제 #2
0
async def backup_slip39_advanced(
    ctx: wire.Context, encrypted_master_secret: bytes
) -> None:
    # get number of groups
    await layout.slip39_show_checklist(ctx, 0, BackupType.Slip39_Advanced)
    groups_count = await layout.slip39_advanced_prompt_number_of_groups(ctx)

    # get group threshold
    await layout.slip39_show_checklist(ctx, 1, BackupType.Slip39_Advanced)
    group_threshold = await layout.slip39_advanced_prompt_group_threshold(
        ctx, groups_count
    )

    # get shares and thresholds
    await layout.slip39_show_checklist(ctx, 2, BackupType.Slip39_Advanced)
    groups = []
    for i in range(groups_count):
        share_count = await layout.slip39_prompt_number_of_shares(ctx, i)
        share_threshold = await layout.slip39_prompt_threshold(ctx, share_count, i)
        groups.append((share_threshold, share_count))

    # generate the mnemonics
    mnemonics = slip39.split_ems(
        group_threshold=group_threshold,
        groups=groups,
        identifier=storage.device.get_slip39_identifier(),
        iteration_exponent=storage.device.get_slip39_iteration_exponent(),
        encrypted_master_secret=encrypted_master_secret,
    )

    # show and confirm individual shares
    await layout.slip39_advanced_show_and_confirm_shares(ctx, mnemonics)
예제 #3
0
async def backup_slip39_basic(ctx: wire.Context,
                              encrypted_master_secret: bytes) -> None:
    # get number of shares
    await layout.slip39_show_checklist(ctx, 0, BackupType.Slip39_Basic)
    shares_count = await layout.slip39_prompt_number_of_shares(ctx)

    # get threshold
    await layout.slip39_show_checklist(ctx, 1, BackupType.Slip39_Basic)
    threshold = await layout.slip39_prompt_threshold(ctx, shares_count)

    identifier = storage.device.get_slip39_identifier()
    iteration_exponent = storage.device.get_slip39_iteration_exponent()
    if identifier is None or iteration_exponent is None:
        raise ValueError

    # generate the mnemonics
    mnemonics = slip39.split_ems(
        1,  # Single Group threshold
        [(threshold, shares_count)],  # Single Group threshold/count
        identifier,
        iteration_exponent,
        encrypted_master_secret,
    )[0]

    # show and confirm individual shares
    await layout.slip39_show_checklist(ctx, 2, BackupType.Slip39_Basic)
    await layout.slip39_basic_show_and_confirm_shares(ctx, mnemonics)
    def test_group_sharing(self):
        group_threshold = 2
        group_sizes = (5, 3, 5, 1)
        member_thresholds = (3, 2, 2, 1)
        identifier = slip39.generate_random_identifier()
        mnemonics = slip39.split_ems(group_threshold,
                                     list(zip(member_thresholds, group_sizes)),
                                     identifier, 1, self.EMS)

        # Test all valid combinations of mnemonics.
        for groups in combinations(zip(mnemonics, member_thresholds),
                                   group_threshold):
            for group1_subset in combinations(groups[0][0], groups[0][1]):
                for group2_subset in combinations(groups[1][0], groups[1][1]):
                    mnemonic_subset = list(group1_subset + group2_subset)
                    random.shuffle(mnemonic_subset)
                    identifier, exponent, ems = slip39.recover_ems(
                        mnemonic_subset)
                    self.assertEqual(ems, self.EMS)

        # Minimal sets of mnemonics.
        identifier, exponent, ems = slip39.recover_ems(
            [mnemonics[2][0], mnemonics[2][2], mnemonics[3][0]])
        self.assertEqual(ems, self.EMS)
        self.assertEqual(
            slip39.recover_ems(
                [mnemonics[2][3], mnemonics[3][0], mnemonics[2][4]])[2], ems)

        # One complete group and one incomplete group out of two groups required.
        with self.assertRaises(slip39.MnemonicError):
            slip39.recover_ems(mnemonics[0][2:] + [mnemonics[1][0]])

        # One group of two required.
        with self.assertRaises(slip39.MnemonicError):
            slip39.recover_ems(mnemonics[0][1:4])
 def test_basic_sharing_random(self):
     ems = random.bytes(32)
     identifier = slip39.generate_random_identifier()
     mnemonics = slip39.split_ems(1, [(3, 5)], identifier, 1, ems)
     mnemonics = mnemonics[0]
     self.assertEqual(slip39.recover_ems(mnemonics[:3]),
                      slip39.recover_ems(mnemonics[2:]))
 def test_all_groups_exist(self):
     for group_threshold in (1, 2, 5):
         identifier = slip39.generate_random_identifier()
         mnemonics = slip39.split_ems(group_threshold, [(3, 5), (1, 1),
                                                        (2, 3), (2, 5),
                                                        (3, 5)], identifier,
                                      1, self.EMS)
         self.assertEqual(len(mnemonics), 5)
         self.assertEqual(len(sum(mnemonics, [])), 19)
 def test_basic_sharing_fixed(self):
     generated_identifier = slip39.generate_random_identifier()
     mnemonics = slip39.split_ems(1, [(3, 5)], generated_identifier, 1,
                                  self.EMS)
     mnemonics = mnemonics[0]
     identifier, exponent, ems = slip39.recover_ems(mnemonics[:3])
     self.assertEqual(ems, self.EMS)
     self.assertEqual(generated_identifier, identifier)
     self.assertEqual(slip39.recover_ems(mnemonics[1:4])[2], ems)
     with self.assertRaises(slip39.MnemonicError):
         slip39.recover_ems(mnemonics[1:3])
    def test_invalid_sharing(self):
        identifier = slip39.generate_random_identifier()

        # Group threshold exceeds number of groups.
        with self.assertRaises(ValueError):
            slip39.split_ems(3, [(3, 5), (2, 5)], identifier, 1, self.EMS)

        # Invalid group threshold.
        with self.assertRaises(ValueError):
            slip39.split_ems(0, [(3, 5), (2, 5)], identifier, 1, self.EMS)

        # Member threshold exceeds number of members.
        with self.assertRaises(ValueError):
            slip39.split_ems(2, [(3, 2), (2, 5)], identifier, 1, self.EMS)

        # Invalid member threshold.
        with self.assertRaises(ValueError):
            slip39.split_ems(2, [(0, 2), (2, 5)], identifier, 1, self.EMS)

        # Group with multiple members and threshold 1.
        with self.assertRaises(ValueError):
            slip39.split_ems(2, [(3, 5), (1, 3), (2, 5)], identifier, 1,
                             self.EMS)
    def test_group_sharing_threshold_1(self):
        group_threshold = 1
        group_sizes = (5, 3, 5, 1)
        member_thresholds = (3, 2, 2, 1)
        identifier = slip39.generate_random_identifier()
        mnemonics = slip39.split_ems(group_threshold,
                                     list(zip(member_thresholds, group_sizes)),
                                     identifier, 1, self.EMS)

        # Test all valid combinations of mnemonics.
        for group, threshold in zip(mnemonics, member_thresholds):
            for group_subset in combinations(group, threshold):
                mnemonic_subset = list(group_subset)
                random.shuffle(mnemonic_subset)
                identifier, exponent, ems = slip39.recover_ems(mnemonic_subset)
                self.assertEqual(ems, self.EMS)