Dash Core Source Documentation (0.16.0.1)

Find detailed information regarding the Dash Core source code.

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  GetStrongRandBytes(data.data(), 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 
52  SecureVector checksum(32);
53  CSHA256().Write(data.data(), len).Finalize(checksum.data());
54 
55  // data
56  SecureVector bits(len);
57  memcpy(bits.data(), data.data(), 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.data(), nWordCount * 4 / 3).Finalize(bits.data());
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.data(), vchSalt.size(), 2048, EVP_sha512(), 64, seedRet.data());
162 }
CSHA256 & Write(const unsigned char *data, size_t len)
Definition: sha256.cpp:648
constexpr auto bits
Definition: position.hpp:23
std::basic_string< char, std::char_traits< char >, secure_allocator< char > > SecureString
Definition: secure.h:57
void GetStrongRandBytes(unsigned char *out, int num)
Function to gather random data from multiple sources, failing whenever any of those source fail to pr...
Definition: random.cpp:317
static SecureString FromData(const SecureVector &data, int len)
Definition: bip39.cpp:46
static void ToSeed(SecureString mnemonic, SecureString passphrase, SecureVector &seedRet)
Definition: bip39.cpp:152
std::vector< unsigned char, secure_allocator< unsigned char > > SecureVector
Definition: secure.h:59
const char *const wordlist[]
Copyright (c) 2013-2014 Tomas Dzetkulic Copyright (c) 2013-2014 Pavol Rusnak.
Definition: bip39_english.h:24
static SecureString Generate(int strength)
Copyright (c) 2013-2014 Tomas Dzetkulic Copyright (c) 2013-2014 Pavol Rusnak.
Definition: bip39.cpp:34
static bool Check(SecureString mnemonic)
Definition: bip39.cpp:80
void * memcpy(void *a, const void *b, size_t c)
A hasher class for SHA-256.
Definition: sha256.h:13
Released under the MIT license