Skip to content

Commit

Permalink
mnemonic: more thorough recovery phrase word verification
Browse files Browse the repository at this point in the history
Rather than displaying a number of random words to be confirmed, all
words are displayed in groups of three, with one of them selected for
user verification.  This means that every word will be displayed, and
one in three will be selected/confirmed by the user.
  • Loading branch information
JamieDriver committed Jan 17, 2024
1 parent 42fd57a commit 3eae6c6
Showing 1 changed file with 13 additions and 21 deletions.
34 changes: 13 additions & 21 deletions main/process/mnemonic.c
Original file line number Diff line number Diff line change
Expand Up @@ -298,31 +298,26 @@ static bool display_confirm_mnemonic(const size_t nwords, char* mnemonic, const
}
}

// Large enough for 12 and 24 word mnemonic
bool already_confirmed[MNEMONIC_MAXWORDS] = { false };

// Confirm the mnemonic - the number of words to confirm
// and the number of options presented for each word.
const size_t num_words_confirm = nwords == MNEMONIC_MAXWORDS ? 6 : 4;
// Confirm the mnemonic - show groups of three consecutive words
// and have user confirm one of them at random.
// Ensures all words are at the very least displayed.
mnemonic_confirmed = true; // will be set to false if wrong word selected
const size_t num_words_options = nwords == MNEMONIC_MAXWORDS ? 8 : 6;
for (size_t i = 0; i < num_words_confirm; ++i) {
size_t selected;
do {
selected = 1 + get_uniform_random_byte(nwords - 2); // never select the first or last word
} while (already_confirmed[selected]);
already_confirmed[selected] = true;

// Make the word to confirm the 'middle' word of the three shown
for (size_t i = 0; i < nwords; i += 3) {
const size_t offset_word_to_confirm = get_uniform_random_byte(3);
const size_t selected = i + offset_word_to_confirm;
gui_view_node_t* textbox = NULL;
gui_activity_t* const confirm_act
= make_confirm_mnemonic_word_activity(&textbox, selected - 1, 1, words, nwords);
= make_confirm_mnemonic_word_activity(&textbox, i, offset_word_to_confirm, words, nwords);
JADE_LOGD("selected = %u", selected);

// Pick some other words from the mnemonic as options, but avoid
// the words currently displayed on screen (neighbouring words).
// Large enough for 12 and 24 word mnemonic
bool already_picked[MNEMONIC_MAXWORDS] = { false };
already_picked[selected] = true;
already_picked[selected - 1] = true;
already_picked[selected + 1] = true;
already_picked[i] = true;
already_picked[i + 1] = true;
already_picked[i + 2] = true;

// Large enough for 12 and 24 word mnemonic
// (Only really needs to be as big as 'num_words_options' so MAXWORDS is plenty)
Expand Down Expand Up @@ -375,9 +370,6 @@ static bool display_confirm_mnemonic(const size_t nwords, char* mnemonic, const
await_error_activity("\n Incorrect. Check your\n recovery phrase and\n try again.");
mnemonic_confirmed = false;
break;
} else if (i == num_words_confirm - 1) { // last word, and it's correct
mnemonic_confirmed = true;
break;
}
}
}
Expand Down

0 comments on commit 3eae6c6

Please sign in to comment.