1
0
mirror of https://github.com/trezor/trezor-firmware.git synced 2024-11-12 18:49:07 +00:00
trezor-firmware/bip39.c

81 lines
1.6 KiB
C
Raw Normal View History

2013-11-08 00:24:47 +00:00
#include <string.h>
#include "bip39.h"
2013-11-25 21:46:54 +00:00
#include "hmac.h"
#include "rand.h"
2013-11-08 00:24:47 +00:00
#include "sha2.h"
#include "bip39_english.h"
2013-11-25 21:46:54 +00:00
#define HMAC_ROUNDS 10000
2013-11-08 00:24:47 +00:00
2013-11-25 21:46:54 +00:00
const char *mnemonic_generate(int strength)
2013-11-08 00:24:47 +00:00
{
int i;
2013-11-25 21:46:54 +00:00
static uint32_t data[16];
if (strength % 32 || strength < 128 || strength > 256) {
return 0;
2013-11-08 00:24:47 +00:00
}
2013-11-25 21:46:54 +00:00
for (i = 0; i < 16; i++) {
data[i] = random32();
2013-11-08 00:24:47 +00:00
}
2013-11-25 21:46:54 +00:00
return mnemonic_from_data((const uint8_t *)data, strength / 8);
2013-11-08 00:24:47 +00:00
}
2013-11-25 21:46:54 +00:00
const char *mnemonic_from_data(const uint8_t *data, int len)
2013-11-08 00:24:47 +00:00
{
2013-11-25 21:46:54 +00:00
int i, j;
static uint8_t hash[32];
static char bits[256 + 8];
static char mnemo[24 * 10];
2013-11-08 00:24:47 +00:00
if (len % 4 || len < 16 || len > 32) {
return 0;
}
2013-11-25 21:46:54 +00:00
SHA256_Raw((const uint8_t *)data, len, hash);
2013-11-08 00:24:47 +00:00
for (i = 0; i < len; i++) {
for (j = 0; j < 8; j++) {
bits[8 * i + j] = (data[i] & (1 << (7 - j))) > 0;
}
}
2013-11-25 21:46:54 +00:00
char hlen = len / 4;
for (i = 0; i < hlen; i++) {
char c = (hash[0] & (1 << (7 - i))) > 0;
bits[8 * len + i] = c;
2013-11-08 00:24:47 +00:00
}
2013-11-25 21:46:54 +00:00
int mlen = len * 3 / 4;
2013-11-08 00:24:47 +00:00
char *p = mnemo;
2013-11-25 21:46:54 +00:00
for (i = 0; i < mlen; i++) {
2013-11-08 00:24:47 +00:00
int idx = 0;
for (j = 0; j < 11; j++) {
idx += bits[i * 11 + j] << (10 - j);
}
strcpy(p, wordlist[idx]);
p += strlen(wordlist[idx]);
2013-11-25 21:46:54 +00:00
*p = (i < mlen - 1) ? ' ' : 0;
2013-11-08 00:24:47 +00:00
p++;
}
return mnemo;
}
void mnemonic_to_seed(const char *mnemonic, const char *passphrase, uint8_t seed[512 / 8])
2013-11-08 00:24:47 +00:00
{
2013-11-25 21:46:54 +00:00
static uint8_t k[8 + 256];
int i, kl;
kl = strlen(passphrase);
memcpy(k, "mnemonic", 8);
memcpy(k + 8, passphrase, kl);
kl += 8;
hmac_sha512(k, kl, (const uint8_t *)mnemonic, strlen(mnemonic), seed);
2013-11-25 21:46:54 +00:00
for (i = 1; i < HMAC_ROUNDS; i++) {
hmac_sha512(k, kl, seed, 512 / 8, seed);
2013-11-08 00:24:47 +00:00
}
}