mirror of
https://github.com/trezor/trezor-firmware.git
synced 2024-11-25 17:09:44 +00:00
add mnemonic_check function
This commit is contained in:
parent
393c298c35
commit
e827517591
105
bip39.c
105
bip39.c
@ -14,12 +14,9 @@ const char *mnemonic_generate(int strength)
|
||||
if (strength % 32 || strength < 128 || strength > 256) {
|
||||
return 0;
|
||||
}
|
||||
int i;
|
||||
static uint32_t data[16];
|
||||
for (i = 0; i < 16; i++) {
|
||||
data[i] = random32();
|
||||
}
|
||||
return mnemonic_from_data((const uint8_t *)data, strength / 8);
|
||||
static uint8_t data[32];
|
||||
random_buffer(data, 32);
|
||||
return mnemonic_from_data(data, strength / 8);
|
||||
}
|
||||
|
||||
const char *mnemonic_from_data(const uint8_t *data, int len)
|
||||
@ -28,31 +25,23 @@ const char *mnemonic_from_data(const uint8_t *data, int len)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int i, j;
|
||||
char bits[256 + 8];
|
||||
for (i = 0; i < len; i++) {
|
||||
for (j = 0; j < 8; j++) {
|
||||
bits[8 * i + j] = (data[i] & (1 << (7 - j))) > 0;
|
||||
}
|
||||
}
|
||||
uint8_t bits[32 + 1];
|
||||
memcpy(bits, data, len);
|
||||
|
||||
uint8_t hash[32];
|
||||
sha256_Raw((const uint8_t *)data, len, hash);
|
||||
|
||||
char hlen = len / 4;
|
||||
for (i = 0; i < hlen; i++) {
|
||||
char c = (hash[0] & (1 << (7 - i))) > 0;
|
||||
bits[8 * len + i] = c;
|
||||
}
|
||||
sha256_Raw(data, len, bits);
|
||||
bits[len] = bits[0];
|
||||
memcpy(bits, data, len);
|
||||
|
||||
int mlen = len * 3 / 4;
|
||||
static char mnemo[24 * 10];
|
||||
|
||||
int i, j, idx;
|
||||
char *p = mnemo;
|
||||
for (i = 0; i < mlen; i++) {
|
||||
int idx = 0;
|
||||
idx = 0;
|
||||
for (j = 0; j < 11; j++) {
|
||||
idx += bits[i * 11 + j] << (10 - j);
|
||||
idx <<= 1;
|
||||
idx += (bits[(i * 11 + j) / 8] & (1 << (7 - ((i * 11 + j) % 8)))) > 0;
|
||||
}
|
||||
strcpy(p, wordlist[idx]);
|
||||
p += strlen(wordlist[idx]);
|
||||
@ -65,9 +54,73 @@ const char *mnemonic_from_data(const uint8_t *data, int len)
|
||||
|
||||
int mnemonic_check(const char *mnemonic)
|
||||
{
|
||||
// TODO: add proper check
|
||||
(void)mnemonic;
|
||||
return 1;
|
||||
if (!mnemonic) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint32_t i, n;
|
||||
|
||||
i = 0; n = 0;
|
||||
while (mnemonic[i]) {
|
||||
if (mnemonic[i] == ' ') {
|
||||
n++;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
n++;
|
||||
// check number of words
|
||||
if (n != 12 && n != 18 && n != 24) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
char current_word[10];
|
||||
uint32_t j, k, ki, bi;
|
||||
uint8_t bits[32 + 1];
|
||||
memset(bits, 0, sizeof(bits));
|
||||
i = 0; bi = 0;
|
||||
while (mnemonic[i]) {
|
||||
j = 0;
|
||||
while (mnemonic[i] != ' ' && mnemonic[i] != 0) {
|
||||
if (j >= sizeof(current_word)) {
|
||||
return 0;
|
||||
}
|
||||
current_word[j] = mnemonic[i];
|
||||
i++; j++;
|
||||
}
|
||||
current_word[j] = 0;
|
||||
if (mnemonic[i] != 0) i++;
|
||||
k = 0;
|
||||
for (;;) {
|
||||
if (!wordlist[k]) { // word not found
|
||||
return 0;
|
||||
}
|
||||
if (strcmp(current_word, wordlist[k]) == 0) { // word found on index k
|
||||
for (ki = 0; ki < 11; ki++) {
|
||||
if (k & (1 << (10 - ki))) {
|
||||
bits[bi / 8] |= 1 << (7 - (bi % 8));
|
||||
}
|
||||
bi++;
|
||||
}
|
||||
break;
|
||||
}
|
||||
k++;
|
||||
}
|
||||
}
|
||||
if (bi != n * 11) {
|
||||
return 0;
|
||||
}
|
||||
bits[32] = bits[n * 4 / 3];
|
||||
sha256_Raw(bits, n * 4 / 3, bits);
|
||||
if (n == 12) {
|
||||
return (bits[0] & 0xF0) == (bits[32] & 0xF0); // compare first 4 bits
|
||||
} else
|
||||
if (n == 18) {
|
||||
return (bits[0] & 0xFC) == (bits[32] & 0xFC); // compare first 6 bits
|
||||
} else
|
||||
if (n == 24) {
|
||||
return bits[0] == bits[32]; // compare 8 bits
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void mnemonic_to_seed(const char *mnemonic, const char *passphrase, uint8_t seed[512 / 8], void (*progress_callback)(uint32_t current, uint32_t total))
|
||||
|
11
rand.c
11
rand.c
@ -27,12 +27,19 @@
|
||||
|
||||
static FILE *f;
|
||||
|
||||
void init_rand(void) {
|
||||
void init_rand(void)
|
||||
{
|
||||
f = fopen("/dev/urandom", "r");
|
||||
}
|
||||
|
||||
uint32_t random32(void) {
|
||||
uint32_t random32(void)
|
||||
{
|
||||
uint32_t r;
|
||||
fread(&r, 1, sizeof(r), f);
|
||||
return r;
|
||||
}
|
||||
|
||||
void random_buffer(uint8_t *buf, uint32_t len)
|
||||
{
|
||||
fread(buf, 1, len, f);
|
||||
}
|
||||
|
1
rand.h
1
rand.h
@ -28,5 +28,6 @@
|
||||
|
||||
void init_rand(void);
|
||||
uint32_t random32(void);
|
||||
void random_buffer(uint8_t *buf, uint32_t len);
|
||||
|
||||
#endif
|
||||
|
99
tests.c
99
tests.c
@ -458,6 +458,104 @@ START_TEST(test_mnemonic)
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(test_mnemonic_check)
|
||||
{
|
||||
static const char *vectors_ok[] = {
|
||||
"abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about",
|
||||
"legal winner thank year wave sausage worth useful legal winner thank yellow",
|
||||
"letter advice cage absurd amount doctor acoustic avoid letter advice cage above",
|
||||
"zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo wrong",
|
||||
"abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon agent",
|
||||
"legal winner thank year wave sausage worth useful legal winner thank year wave sausage worth useful legal will",
|
||||
"letter advice cage absurd amount doctor acoustic avoid letter advice cage absurd amount doctor acoustic avoid letter always",
|
||||
"zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo when",
|
||||
"abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon art",
|
||||
"legal winner thank year wave sausage worth useful legal winner thank year wave sausage worth useful legal winner thank year wave sausage worth title",
|
||||
"letter advice cage absurd amount doctor acoustic avoid letter advice cage absurd amount doctor acoustic avoid letter advice cage absurd amount doctor acoustic bless",
|
||||
"zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo vote",
|
||||
"jelly better achieve collect unaware mountain thought cargo oxygen act hood bridge",
|
||||
"renew stay biology evidence goat welcome casual join adapt armor shuffle fault little machine walk stumble urge swap",
|
||||
"dignity pass list indicate nasty swamp pool script soccer toe leaf photo multiply desk host tomato cradle drill spread actor shine dismiss champion exotic",
|
||||
"afford alter spike radar gate glance object seek swamp infant panel yellow",
|
||||
"indicate race push merry suffer human cruise dwarf pole review arch keep canvas theme poem divorce alter left",
|
||||
"clutch control vehicle tonight unusual clog visa ice plunge glimpse recipe series open hour vintage deposit universe tip job dress radar refuse motion taste",
|
||||
"turtle front uncle idea crush write shrug there lottery flower risk shell",
|
||||
"kiss carry display unusual confirm curtain upgrade antique rotate hello void custom frequent obey nut hole price segment",
|
||||
"exile ask congress lamp submit jacket era scheme attend cousin alcohol catch course end lucky hurt sentence oven short ball bird grab wing top",
|
||||
"board flee heavy tunnel powder denial science ski answer betray cargo cat",
|
||||
"board blade invite damage undo sun mimic interest slam gaze truly inherit resist great inject rocket museum chief",
|
||||
"beyond stage sleep clip because twist token leaf atom beauty genius food business side grid unable middle armed observe pair crouch tonight away coconut",
|
||||
0,
|
||||
};
|
||||
static const char *vectors_fail[] = {
|
||||
"above abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about",
|
||||
"above winner thank year wave sausage worth useful legal winner thank yellow",
|
||||
"above advice cage absurd amount doctor acoustic avoid letter advice cage above",
|
||||
"above zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo wrong",
|
||||
"above abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon agent",
|
||||
"above winner thank year wave sausage worth useful legal winner thank year wave sausage worth useful legal will",
|
||||
"above advice cage absurd amount doctor acoustic avoid letter advice cage absurd amount doctor acoustic avoid letter always",
|
||||
"above zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo when",
|
||||
"above abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon art",
|
||||
"above winner thank year wave sausage worth useful legal winner thank year wave sausage worth useful legal winner thank year wave sausage worth title",
|
||||
"above advice cage absurd amount doctor acoustic avoid letter advice cage absurd amount doctor acoustic avoid letter advice cage absurd amount doctor acoustic bless",
|
||||
"above zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo vote",
|
||||
"above better achieve collect unaware mountain thought cargo oxygen act hood bridge",
|
||||
"above stay biology evidence goat welcome casual join adapt armor shuffle fault little machine walk stumble urge swap",
|
||||
"above pass list indicate nasty swamp pool script soccer toe leaf photo multiply desk host tomato cradle drill spread actor shine dismiss champion exotic",
|
||||
"above alter spike radar gate glance object seek swamp infant panel yellow",
|
||||
"above race push merry suffer human cruise dwarf pole review arch keep canvas theme poem divorce alter left",
|
||||
"above control vehicle tonight unusual clog visa ice plunge glimpse recipe series open hour vintage deposit universe tip job dress radar refuse motion taste",
|
||||
"above front uncle idea crush write shrug there lottery flower risk shell",
|
||||
"above carry display unusual confirm curtain upgrade antique rotate hello void custom frequent obey nut hole price segment",
|
||||
"above ask congress lamp submit jacket era scheme attend cousin alcohol catch course end lucky hurt sentence oven short ball bird grab wing top",
|
||||
"above flee heavy tunnel powder denial science ski answer betray cargo cat",
|
||||
"above blade invite damage undo sun mimic interest slam gaze truly inherit resist great inject rocket museum chief",
|
||||
"above stage sleep clip because twist token leaf atom beauty genius food business side grid unable middle armed observe pair crouch tonight away coconut",
|
||||
"abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about",
|
||||
"winner thank year wave sausage worth useful legal winner thank yellow",
|
||||
"advice cage absurd amount doctor acoustic avoid letter advice cage above",
|
||||
"zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo wrong",
|
||||
"abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon agent",
|
||||
"winner thank year wave sausage worth useful legal winner thank year wave sausage worth useful legal will",
|
||||
"advice cage absurd amount doctor acoustic avoid letter advice cage absurd amount doctor acoustic avoid letter always",
|
||||
"zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo when",
|
||||
"abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon art",
|
||||
"winner thank year wave sausage worth useful legal winner thank year wave sausage worth useful legal winner thank year wave sausage worth title",
|
||||
"advice cage absurd amount doctor acoustic avoid letter advice cage absurd amount doctor acoustic avoid letter advice cage absurd amount doctor acoustic bless",
|
||||
"zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo vote",
|
||||
"better achieve collect unaware mountain thought cargo oxygen act hood bridge",
|
||||
"stay biology evidence goat welcome casual join adapt armor shuffle fault little machine walk stumble urge swap",
|
||||
"pass list indicate nasty swamp pool script soccer toe leaf photo multiply desk host tomato cradle drill spread actor shine dismiss champion exotic",
|
||||
"alter spike radar gate glance object seek swamp infant panel yellow",
|
||||
"race push merry suffer human cruise dwarf pole review arch keep canvas theme poem divorce alter left",
|
||||
"control vehicle tonight unusual clog visa ice plunge glimpse recipe series open hour vintage deposit universe tip job dress radar refuse motion taste",
|
||||
"front uncle idea crush write shrug there lottery flower risk shell",
|
||||
"carry display unusual confirm curtain upgrade antique rotate hello void custom frequent obey nut hole price segment",
|
||||
"ask congress lamp submit jacket era scheme attend cousin alcohol catch course end lucky hurt sentence oven short ball bird grab wing top",
|
||||
"flee heavy tunnel powder denial science ski answer betray cargo cat",
|
||||
"blade invite damage undo sun mimic interest slam gaze truly inherit resist great inject rocket museum chief",
|
||||
"stage sleep clip because twist token leaf atom beauty genius food business side grid unable middle armed observe pair crouch tonight away coconut",
|
||||
0,
|
||||
};
|
||||
|
||||
const char **m;
|
||||
int r;
|
||||
m = vectors_ok;
|
||||
while (*m) {
|
||||
r = mnemonic_check(*m);
|
||||
ck_assert_int_eq(r, 1);
|
||||
m++;
|
||||
}
|
||||
m = vectors_fail;
|
||||
while (*m) {
|
||||
r = mnemonic_check(*m);
|
||||
ck_assert_int_eq(r, 0);
|
||||
m++;
|
||||
}
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(test_address)
|
||||
{
|
||||
char address[35];
|
||||
@ -660,6 +758,7 @@ Suite *test_suite(void)
|
||||
|
||||
tc = tcase_create("bip39");
|
||||
tcase_add_test(tc, test_mnemonic);
|
||||
tcase_add_test(tc, test_mnemonic_check);
|
||||
suite_add_tcase(s, tc);
|
||||
|
||||
return s;
|
||||
|
Loading…
Reference in New Issue
Block a user