From 60bb2fe2b1605d56672ed2b0e96b5caea4cc9bb9 Mon Sep 17 00:00:00 2001 From: Pavol Rusnak Date: Fri, 13 Feb 2015 20:49:53 +0100 Subject: [PATCH] use Knuth shuffles --- firmware/pinmatrix.c | 12 ++---------- firmware/recovery.c | 13 +++---------- rng.c | 19 +++++++++++++++++++ rng.h | 2 ++ 4 files changed, 26 insertions(+), 20 deletions(-) diff --git a/firmware/pinmatrix.c b/firmware/pinmatrix.c index 821297244..73ae3b405 100644 --- a/firmware/pinmatrix.c +++ b/firmware/pinmatrix.c @@ -49,20 +49,12 @@ void pinmatrix_draw(const char *text) void pinmatrix_start(const char *text) { - int i, j, k; - char t; - + int i; for (i = 0; i < 9; i++) { pinmatrix_perm[i] = '1' + i; } pinmatrix_perm[9] = 0; - for (i = 0; i < 10000; i++) { - j = random32() % 9; - k = random32() % 9; - t = pinmatrix_perm[j]; - pinmatrix_perm[j] = pinmatrix_perm[k]; - pinmatrix_perm[k] = t; - } + random_permute(pinmatrix_perm, 9); pinmatrix_draw(text); } diff --git a/firmware/recovery.c b/firmware/recovery.c index 1aa6d36e8..c53a42b84 100644 --- a/firmware/recovery.c +++ b/firmware/recovery.c @@ -40,7 +40,7 @@ void next_word(void) { word_pos = word_order[word_index]; if (word_pos == 0) { const char **wl = mnemonic_wordlist(); - strlcpy(fake_word, wl[random32() & 0x7FF], sizeof(fake_word)); + strlcpy(fake_word, wl[random_uniform(2048)], sizeof(fake_word)); layoutDialogSwipe(DIALOG_ICON_INFO, NULL, NULL, NULL, "Please enter the word", NULL, fake_word, NULL, "on your computer", NULL); } else { fake_word[0] = 0; @@ -89,21 +89,14 @@ void recovery_init(uint32_t _word_count, bool passphrase_protection, bool pin_pr storage_setLanguage(language); storage_setLabel(label); - uint32_t i, j, k; - char t; + uint32_t i; for (i = 0; i < word_count; i++) { word_order[i] = i + 1; } for (i = word_count; i < 24; i++) { word_order[i] = 0; } - for (i = 0; i < 10000; i++) { - j = random32() % 24; - k = random32() % 24; - t = word_order[j]; - word_order[j] = word_order[k]; - word_order[k] = t; - } + random_permute(word_order, 24); awaiting_word = true; word_index = 0; next_word(); diff --git a/rng.c b/rng.c index 0f7437a74..39aea9771 100644 --- a/rng.c +++ b/rng.c @@ -35,6 +35,13 @@ uint32_t random32(void) return new; } +uint32_t random_uniform(uint32_t n) +{ + uint32_t x, max = 0xFFFFFFFF - (0xFFFFFFFF % n); + while ((x = random32()) >= max); + return x / (max / n); +} + void random_buffer(uint8_t *buf, size_t len) { size_t i; @@ -46,3 +53,15 @@ void random_buffer(uint8_t *buf, size_t len) buf[i] = (r >> ((i % 4) * 8)) & 0xFF; } } + +void random_permute(char *str, size_t len) +{ + int i, j; + char t; + for (i = len - 1; i >= 1; i--) { + j = random_uniform(i + 1); + t = str[j]; + str[j] = str[i]; + str[i] = t; + } +} diff --git a/rng.h b/rng.h index 9fbe2bea2..3e25c0eed 100644 --- a/rng.h +++ b/rng.h @@ -24,6 +24,8 @@ #include uint32_t random32(void); +uint32_t random_uniform(uint32_t n); void random_buffer(uint8_t *buf, size_t len); +void random_permute(char *buf, size_t len); #endif