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.generate_mnemonics_from_data( self.MS, identifier, group_threshold, list(zip(member_thresholds, group_sizes)) ) # 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.combine_mnemonics(mnemonic_subset) self.assertEqual(slip39.decrypt(identifier, exponent, ems, b""), self.MS) # Minimal sets of mnemonics. identifier, exponent, ems = slip39.combine_mnemonics([mnemonics[2][0], mnemonics[2][2], mnemonics[3][0]]) self.assertEqual(slip39.decrypt(identifier, exponent, ems, b""), self.MS) self.assertEqual(slip39.combine_mnemonics([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.combine_mnemonics(mnemonics[0][2:] + [mnemonics[1][0]]) # One group of two required. with self.assertRaises(slip39.MnemonicError): slip39.combine_mnemonics(mnemonics[0][1:4])
async def _confirm_word(ctx, share_index, share_words, offset, count, group_index=None): # remove duplicates non_duplicates = list(set(share_words)) # shuffle list random.shuffle(non_duplicates) # take top NUM_OF_CHOICES words choices = non_duplicates[: MnemonicWordSelect.NUM_OF_CHOICES] # select first of them checked_word = choices[0] # find its index checked_index = share_words.index(checked_word) + offset # shuffle again so the confirmed word is not always the first choice random.shuffle(choices) if __debug__: debug.reset_word_index.publish(checked_index) # let the user pick a word select = MnemonicWordSelect(choices, share_index, checked_index, count, group_index) if __debug__: selected_word = await ctx.wait(select, debug.input_signal()) else: selected_word = await ctx.wait(select) # confirm it is the correct one return selected_word == checked_word
async def _confirm_word(ctx, share_index, numbered_share_words): # TODO: duplicated words in the choice list # shuffle the numbered seed half, slice off the choices we need random.shuffle(numbered_share_words) numbered_choices = numbered_share_words[:MnemonicWordSelect.NUM_OF_CHOICES] # we always confirm the first (random) word index checked_index, checked_word = numbered_choices[0] if __debug__: debug.reset_word_index = checked_index # shuffle again so the confirmed word is not always the first choice random.shuffle(numbered_choices) # let the user pick a word choices = [word for _, word in numbered_choices] select = MnemonicWordSelect(choices, share_index, checked_index) if __debug__: selected_word = await ctx.wait(select, debug.input_signal) else: selected_word = await ctx.wait(select) # confirm it is the correct one return selected_word == checked_word
def generate_digits(with_zero): if with_zero: digits = list(range(0, 10)) # 0-9 else: digits = list(range(1, 10)) # 1-9 random.shuffle(digits) return digits
async def confirm_word( ctx: wire.GenericContext, share_index: int | None, share_words: Sequence[str], offset: int, count: int, group_index: int | None = None, ) -> bool: # remove duplicates non_duplicates = list(set(share_words)) # shuffle list random.shuffle(non_duplicates) # take top NUM_OF_CHOICES words choices = non_duplicates[:MnemonicWordSelect.NUM_OF_CHOICES] # select first of them checked_word = choices[0] # find its index checked_index = share_words.index(checked_word) + offset # shuffle again so the confirmed word is not always the first choice random.shuffle(choices) if __debug__: debug.reset_word_index.publish(checked_index) # let the user pick a word select = MnemonicWordSelect(choices, share_index, checked_index, count, group_index) selected_word: str = await ctx.wait(select) # confirm it is the correct one return selected_word == checked_word
def test_group_sharing_threshold_1(self): group_threshold = 1 group_sizes = (5, 3, 5, 1) member_thresholds = (3, 2, 2, 1) mnemonics = slip39.generate_mnemonics( group_threshold, list(zip(member_thresholds, group_sizes)), self.MS ) # 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.combine_mnemonics(mnemonic_subset) self.assertEqual(slip39.decrypt(identifier, exponent, ems, b""), self.MS)
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)
def generate_digits() -> Iterable[int]: digits = list(range(0, 10)) # 0-9 random.shuffle(digits) # We lay out the buttons top-left to bottom-right, but the order # of the digits is defined as bottom-left to top-right (on numpad). return digits[6:] + digits[3:6] + digits[:3]
def generate_digits(): digits = list(range(0, 10)) # 0-9 random.shuffle(digits) return digits
from ubinascii import hexlify from trezor import ui, loop, res from trezor.utils import unimport from trezor.crypto import random from . import knownapps ids = list(knownapps.knownapps.keys()) random.shuffle(ids) appid = ids[0] action = 'Register' @unimport def layout_u2f(): if appid in knownapps.knownapps: appname = knownapps.knownapps[appid] appicon = res.load('apps/fido_u2f/res/u2f_%s.toif' % appname.lower().replace(' ', '_')) else: appname = hexlify(appid[:4]) + '...' + hexlify(appid[-4:]) appicon = res.load('apps/fido_u2f/res/u2f_unknown.toif') # paint background black ui.display.bar(0, 0, 240, 240, ui.BLACK) # top header bar ui.display.text(10, 28, 'U2F Login', ui.BOLD, ui.PM_BLUE, ui.BLACK) # content
def test_shuffle(self): for l in range(256 + 1): lst = list(range(l)) random.shuffle(lst) self.assertEqual(len(lst), l) self.assertEqual(sorted(lst), list(range(l)))