Dash Core  0.12.2.1
P2P Digital Currency
bip39.cpp
Go to the documentation of this file.
1 
24 // Source:
25 // https://github.com/trezor/trezor-crypto
26 
27 #include "bip39.h"
28 #include "bip39_english.h"
29 #include "crypto/sha256.h"
30 #include "random.h"
31 
32 #include <openssl/evp.h>
33 
35 {
36  if (strength % 32 || strength < 128 || strength > 256) {
37  return SecureString();
38  }
39  SecureVector data(32);
40  GetRandBytes(&data[0], 32);
41  SecureString mnemonic = FromData(data, strength / 8);
42  return mnemonic;
43 }
44 
45 // SecureString CMnemonic::FromData(const uint8_t *data, int len)
47 {
48  if (len % 4 || len < 16 || len > 32) {
49  return SecureString();
50  }
51 
53  CSHA256().Write(&data[0], len).Finalize(&checksum[0]);
54 
55  // data
56  SecureVector bits(len);
57  memcpy(&bits[0], &data[0], len);
58  // checksum
59  bits.push_back(checksum[0]);
60 
61  int mlen = len * 3 / 4;
62  SecureString mnemonic;
63 
64  int i, j, idx;
65  for (i = 0; i < mlen; i++) {
66  idx = 0;
67  for (j = 0; j < 11; j++) {
68  idx <<= 1;
69  idx += (bits[(i * 11 + j) / 8] & (1 << (7 - ((i * 11 + j) % 8)))) > 0;
70  }
71  mnemonic.append(wordlist[idx]);
72  if (i < mlen - 1) {
73  mnemonic += ' ';
74  }
75  }
76 
77  return mnemonic;
78 }
79 
81 {
82  if (mnemonic.empty()) {
83  return false;
84  }
85 
86  uint32_t nWordCount{};
87 
88  for (size_t i = 0; i < mnemonic.size(); ++i) {
89  if (mnemonic[i] == ' ') {
90  nWordCount++;
91  }
92  }
93  nWordCount++;
94  // check number of words
95  if (nWordCount != 12 && nWordCount != 18 && nWordCount != 24) {
96  return false;
97  }
98 
99  SecureString ssCurrentWord;
100  SecureVector bits(32 + 1);
101 
102  uint32_t nWordIndex, ki, nBitsCount{};
103 
104  for (size_t i = 0; i < mnemonic.size(); ++i)
105  {
106  ssCurrentWord = "";
107  while (i + ssCurrentWord.size() < mnemonic.size() && mnemonic[i + ssCurrentWord.size()] != ' ') {
108  if (ssCurrentWord.size() >= 9) {
109  return false;
110  }
111  ssCurrentWord += mnemonic[i + ssCurrentWord.size()];
112  }
113  i += ssCurrentWord.size();
114  nWordIndex = 0;
115  for (;;) {
116  if (!wordlist[nWordIndex]) { // word not found
117  return false;
118  }
119  if (ssCurrentWord == wordlist[nWordIndex]) { // word found on index nWordIndex
120  for (ki = 0; ki < 11; ki++) {
121  if (nWordIndex & (1 << (10 - ki))) {
122  bits[nBitsCount / 8] |= 1 << (7 - (nBitsCount % 8));
123  }
124  nBitsCount++;
125  }
126  break;
127  }
128  nWordIndex++;
129  }
130  }
131  if (nBitsCount != nWordCount * 11) {
132  return false;
133  }
134  bits[32] = bits[nWordCount * 4 / 3];
135  CSHA256().Write(&bits[0], nWordCount * 4 / 3).Finalize(&bits[0]);
136 
137  bool fResult = 0;
138  if (nWordCount == 12) {
139  fResult = (bits[0] & 0xF0) == (bits[32] & 0xF0); // compare first 4 bits
140  } else
141  if (nWordCount == 18) {
142  fResult = (bits[0] & 0xFC) == (bits[32] & 0xFC); // compare first 6 bits
143  } else
144  if (nWordCount == 24) {
145  fResult = bits[0] == bits[32]; // compare 8 bits
146  }
147 
148  return fResult;
149 }
150 
151 // passphrase must be at most 256 characters or code may crash
152 void CMnemonic::ToSeed(SecureString mnemonic, SecureString passphrase, SecureVector& seedRet)
153 {
154  SecureString ssSalt = SecureString("mnemonic") + passphrase;
155  SecureVector vchSalt(ssSalt.begin(), ssSalt.end());
156  seedRet.resize(64);
157  // int PKCS5_PBKDF2_HMAC(const char *pass, int passlen,
158  // const unsigned char *salt, int saltlen, int iter,
159  // const EVP_MD *digest,
160  // int keylen, unsigned char *out);
161  PKCS5_PBKDF2_HMAC(mnemonic.c_str(), mnemonic.size(), &vchSalt[0], vchSalt.size(), 2048, EVP_sha512(), 64, &seedRet[0]);
162 }
std::basic_string< char, std::char_traits< char >, secure_allocator< char > > SecureString
Definition: secure.h:61
void Finalize(unsigned char hash[OUTPUT_SIZE])
Definition: sha256.cpp:167
static SecureString FromData(const SecureVector &data, int len)
Definition: bip39.cpp:46
static bool Check(SecureString mnemonic)
Definition: bip39.cpp:80
std::vector< unsigned char, secure_allocator< unsigned char > > SecureVector
Definition: secure.h:63
def checksum(v)
Definition: base58.py:71
const char *const wordlist[]
Definition: bip39_english.h:24
CSHA256 & Write(const unsigned char *data, size_t len)
Definition: sha256.cpp:141
void * memcpy(void *a, const void *b, size_t c)
static SecureString Generate(int strength)
Definition: bip39.cpp:34
void GetRandBytes(unsigned char *buf, int num)
Definition: random.cpp:86
Definition: sha256.h:12
static void ToSeed(SecureString mnemonic, SecureString passphrase, SecureVector &seedRet)
Definition: bip39.cpp:152