Fabcoin Core  0.16.2
P2P Digital Currency
drbg.h
Go to the documentation of this file.
1 // drbg.h - written and placed in public domain by Jeffrey Walton.
2 // Copyright assigned to Crypto++ project.
3 
9 
10 #ifndef CRYPTOPP_NIST_DRBG_H
11 #define CRYPTOPP_NIST_DRBG_H
12 
13 #include "cryptlib.h"
14 #include "secblock.h"
15 
17 
18 class NIST_DRBG : public RandomNumberGenerator
25 {
26 public:
28  class Err : public Exception
29  {
30  public:
31  explicit Err(const std::string &c, const std::string &m)
32  : Exception(OTHER_ERROR, c + ": " + m) {}
33  };
34 
35 public:
36  virtual ~NIST_DRBG() {}
37 
41  virtual bool CanIncorporateEntropy() const {return true;}
42 
50  virtual void IncorporateEntropy(const byte *input, size_t length)=0;
51 
62  virtual void IncorporateEntropy(const byte *entropy, size_t entropyLength, const byte* additional, size_t additionaLength)=0;
63 
69  virtual void GenerateBlock(byte *output, size_t size)=0;
70 
80  virtual void GenerateBlock(const byte* additional, size_t additionaLength, byte *output, size_t size)=0;
81 
85  virtual unsigned int GetSecurityStrength() const=0;
86 
91  virtual unsigned int GetSeedLength() const=0;
92 
98  virtual unsigned int GetMinEntropy() const=0;
99 
105  virtual unsigned int GetMaxEntropy() const=0;
106 
112  virtual unsigned int GetMinNonce() const=0;
113 
120  virtual unsigned int GetMaxNonce() const=0;
121 
125  virtual unsigned int GetMaxBytesPerRequest() const=0;
126 
132  virtual unsigned int GetMaxRequestBeforeReseed() const=0;
133 
134 protected:
135  virtual void DRBG_Instantiate(const byte* entropy, size_t entropyLength,
136  const byte* nonce, size_t nonceLength, const byte* personalization, size_t personalizationLength)=0;
137 
138  virtual void DRBG_Reseed(const byte* entropy, size_t entropyLength, const byte* additional, size_t additionaLength)=0;
139 };
140 
155 template <typename HASH=SHA256, unsigned int STRENGTH=128/8, unsigned int SEEDLENGTH=440/8>
156 class Hash_DRBG : public NIST_DRBG
157 {
158 public:
159  CRYPTOPP_CONSTANT(SECURITY_STRENGTH=STRENGTH)
160  CRYPTOPP_CONSTANT(SEED_LENGTH=SEEDLENGTH)
161  CRYPTOPP_CONSTANT(MINIMUM_ENTROPY=STRENGTH)
162  CRYPTOPP_CONSTANT(MINIMUM_NONCE=0)
163  CRYPTOPP_CONSTANT(MINIMUM_ADDITIONAL=0)
164  CRYPTOPP_CONSTANT(MINIMUM_PERSONALIZATION=0)
165  CRYPTOPP_CONSTANT(MAXIMUM_ENTROPY=INT_MAX)
166  CRYPTOPP_CONSTANT(MAXIMUM_NONCE=INT_MAX)
167  CRYPTOPP_CONSTANT(MAXIMUM_ADDITIONAL=INT_MAX)
168  CRYPTOPP_CONSTANT(MAXIMUM_PERSONALIZATION=INT_MAX)
169  CRYPTOPP_CONSTANT(MAXIMUM_BYTES_PER_REQUEST=65536)
170  CRYPTOPP_CONSTANT(MAXIMUM_REQUESTS_BEFORE_RESEED=INT_MAX)
171 
172 
173  Hash_DRBG(const byte* entropy, size_t entropyLength=STRENGTH, const byte* nonce=NULL,
198  size_t nonceLength=0, const byte* personalization=NULL, size_t personalizationLength=0)
199  : NIST_DRBG(), m_c(SEEDLENGTH), m_v(SEEDLENGTH)
200  {
201  DRBG_Instantiate(entropy, entropyLength, nonce, nonceLength, personalization, personalizationLength);
202  }
203 
204  unsigned int GetSecurityStrength() const {return SECURITY_STRENGTH;}
205  unsigned int GetSeedLength() const {return SEED_LENGTH;}
206  unsigned int GetMinEntropy() const {return MINIMUM_ENTROPY;}
207  unsigned int GetMaxEntropy() const {return MAXIMUM_ENTROPY;}
208  unsigned int GetMinNonce() const {return MINIMUM_NONCE;}
209  unsigned int GetMaxNonce() const {return MAXIMUM_NONCE;}
210  unsigned int GetMaxBytesPerRequest() const {return MAXIMUM_BYTES_PER_REQUEST;}
211  unsigned int GetMaxRequestBeforeReseed() const {return MAXIMUM_REQUESTS_BEFORE_RESEED;}
212 
213  void IncorporateEntropy(const byte *input, size_t length)
214  {return DRBG_Reseed(input, length, NULL, 0);}
215 
216  void IncorporateEntropy(const byte *entropy, size_t entropyLength, const byte* additional, size_t additionaLength)
217  {return DRBG_Reseed(entropy, entropyLength, additional, additionaLength);}
218 
219  void GenerateBlock(byte *output, size_t size)
220  {return Hash_Generate(NULL, 0, output, size);}
221 
222  void GenerateBlock(const byte* additional, size_t additionaLength, byte *output, size_t size)
223  {return Hash_Generate(additional, additionaLength, output, size);}
224 
225 protected:
226  // 10.3.1 Derivation Function Using a Hash Function (Hash_df) (p.58)
227  void Hash_df(const byte* input1, size_t inlen1, const byte* input2, size_t inlen2,
228  const byte* input3, size_t inlen3, const byte* input4, size_t inlen4, byte* output, size_t outlen)
229  {
230  HASH hash;
231  byte counter = 1;
232  word32 bits = ConditionalByteReverse(BIG_ENDIAN_ORDER, static_cast<word32>(outlen*8));
233 
234  size_t count;
235  for (count=0; outlen; outlen -= count, output += count, counter++)
236  {
237  hash.Update(&counter, 1);
238  hash.Update(reinterpret_cast<const byte*>(&bits), 4);
239 
240  if (input1 && inlen1)
241  hash.Update(input1, inlen1);
242  if (input2 && inlen2)
243  hash.Update(input2, inlen2);
244  if (input3 && inlen3)
245  hash.Update(input3, inlen3);
246  if (input4 && inlen4)
247  hash.Update(input4, inlen4);
248 
249  count = STDMIN(outlen, (size_t)HASH::DIGESTSIZE);
250  hash.TruncatedFinal(output, count);
251  }
252  }
253 
254  // 10.1.1.2 Instantiation of Hash_DRBG (p.48)
255  void DRBG_Instantiate(const byte* entropy, size_t entropyLength, const byte* nonce, size_t nonceLength,
256  const byte* personalization, size_t personalizationLength)
257  {
258  // SP 800-90A, 8.6.3: The entropy input shall have entropy that is equal to or greater than the security
259  // strength of the instantiation. Additional entropy may be provided in the nonce or the optional
260  // personalization string during instantiation, or in the additional input during reseeding and generation,
261  // but this is not required and does not increase the "official" security strength of the DRBG
262  // instantiation that is recorded in the internal state.
263  CRYPTOPP_ASSERT(entropyLength >= MINIMUM_ENTROPY);
264  if (entropyLength < MINIMUM_ENTROPY)
265  throw NIST_DRBG::Err("Hash_DRBG", "Insufficient entropy during instantiate");
266 
267  // SP 800-90A, Section 9, says we should throw if we have too much entropy, too large a nonce,
268  // or too large a persoanlization string. We warn in Debug builds, but do nothing in Release builds.
269  CRYPTOPP_ASSERT(entropyLength <= MAXIMUM_ENTROPY);
270  CRYPTOPP_ASSERT(nonceLength <= MAXIMUM_NONCE);
271  CRYPTOPP_ASSERT(personalizationLength <= MAXIMUM_PERSONALIZATION);
272 
273  const byte zero = 0;
274  SecByteBlock t1(SEEDLENGTH), t2(SEEDLENGTH);
275  Hash_df(entropy, entropyLength, nonce, nonceLength, personalization, personalizationLength, NULL, 0, t1, t1.size());
276  Hash_df(&zero, 1, t1, t1.size(), NULL, 0, NULL, 0, t2, t2.size());
277 
278  m_v.swap(t1); m_c.swap(t2);
279  m_reseed = 1;
280  }
281 
282  // 10.1.1.3 Reseeding a Hash_DRBG Instantiation (p.49)
283  void DRBG_Reseed(const byte* entropy, size_t entropyLength, const byte* additional, size_t additionaLength)
284  {
285  // SP 800-90A, 8.6.3: The entropy input shall have entropy that is equal to or greater than the security
286  // strength of the instantiation. Additional entropy may be provided in the nonce or the optional
287  // personalization string during instantiation, or in the additional input during reseeding and generation,
288  // but this is not required and does not increase the "official" security strength of the DRBG
289  // instantiation that is recorded in the internal state..
290  CRYPTOPP_ASSERT(entropyLength >= MINIMUM_ENTROPY);
291  if (entropyLength < MINIMUM_ENTROPY)
292  throw NIST_DRBG::Err("Hash_DRBG", "Insufficient entropy during reseed");
293 
294  // SP 800-90A, Section 9, says we should throw if we have too much entropy, too large a nonce,
295  // or too large a persoanlization string. We warn in Debug builds, but do nothing in Release builds.
296  CRYPTOPP_ASSERT(entropyLength <= MAXIMUM_ENTROPY);
297  CRYPTOPP_ASSERT(additionaLength <= MAXIMUM_ADDITIONAL);
298 
299  const byte zero = 0, one = 1;
300  SecByteBlock t1(SEEDLENGTH), t2(SEEDLENGTH);
301  Hash_df(&one, 1, m_v, m_v.size(), entropy, entropyLength, additional, additionaLength, t1, t1.size());
302  Hash_df(&zero, 1, t1, t1.size(), NULL, 0, NULL, 0, t2, t2.size());
303 
304  m_v.swap(t1); m_c.swap(t2);
305  m_reseed = 1;
306  }
307 
308  // 10.1.1.4 Generating Pseudorandom Bits Using Hash_DRBG (p.50)
309  void Hash_Generate(const byte* additional, size_t additionaLength, byte *output, size_t size)
310  {
311  // Step 1
312  if (static_cast<word64>(m_reseed) >= static_cast<word64>(GetMaxRequestBeforeReseed()))
313  throw NIST_DRBG::Err("Hash_DRBG", "Reseed required");
314 
315  if (size > GetMaxBytesPerRequest())
316  throw NIST_DRBG::Err("Hash_DRBG", "Request size exceeds limit");
317 
318  // SP 800-90A, Section 9, says we should throw if we have too much entropy, too large a nonce,
319  // or too large a persoanlization string. We warn in Debug builds, but do nothing in Release builds.
320  CRYPTOPP_ASSERT(additionaLength <= MAXIMUM_ADDITIONAL);
321 
322  // Step 2
323  if (additional && additionaLength)
324  {
325  HASH hash;
326  const byte two = 2;
327  SecByteBlock w(HASH::DIGESTSIZE);
328 
329  hash.Update(&two, 1);
330  hash.Update(m_v, m_v.size());
331  hash.Update(additional, additionaLength);
332  hash.Final(w);
333 
334  CRYPTOPP_ASSERT(SEEDLENGTH >= HASH::DIGESTSIZE);
335  int carry=0, i=SEEDLENGTH-1, j=HASH::DIGESTSIZE-1;
336  while(i>=0 && j>=0)
337  {
338  carry = m_v[i] + w[j] + carry;
339  m_v[i] = static_cast<byte>(carry);
340  carry >>= 8; i--; j--;
341  }
342  while (carry && i>=0)
343  {
344  carry = m_v[i] + carry;
345  m_v[i] = static_cast<byte>(carry);
346  carry >>= 8; i--;
347  }
348  }
349 
350  // Step 3
351  {
352  HASH hash;
353  SecByteBlock data(m_v);
354 
355  size_t count;
356  for (count = 0; size; size -= count, output += count)
357  {
358  hash.Update(data, data.size());
359  count = STDMIN(size, (size_t)HASH::DIGESTSIZE);
360  hash.TruncatedFinal(output, count);
361 
362  IncrementCounterByOne(data, static_cast<unsigned int>(data.size()));
363  }
364  }
365 
366  // Steps 4-7
367  {
368  HASH hash;
369  const byte three = 3;
370  SecByteBlock h(HASH::DIGESTSIZE);
371 
372  hash.Update(&three, 1);
373  hash.Update(m_v, m_v.size());
374  hash.Final(h);
375 
376  CRYPTOPP_ASSERT(SEEDLENGTH >= HASH::DIGESTSIZE);
377  CRYPTOPP_ASSERT(HASH::DIGESTSIZE >= sizeof(m_reseed));
378  int carry=0, i=SEEDLENGTH-1, j=HASH::DIGESTSIZE-1, k=sizeof(m_reseed)-1;
379  while(i>=0 && j>=0 && k>=0)
380  {
381  carry = m_v[i] + m_c[i] + h[j] + GetByte<word64>(BIG_ENDIAN_ORDER, m_reseed, k) + carry;
382  m_v[i] = static_cast<byte>(carry);
383  carry >>= 8; i--; j--; k--;
384  }
385  while(i>=0 && j>=0)
386  {
387  carry = m_v[i] + m_c[i] + h[j] + carry;
388  m_v[i] = static_cast<byte>(carry);
389  carry >>= 8; i--; j--;
390  }
391  while (i>=0)
392  {
393  carry = m_v[i] + m_c[i] + carry;
394  m_v[i] = static_cast<byte>(carry);
395  carry >>= 8; i--;
396  }
397  }
398 
399  m_reseed++;
400  }
401 
402 private:
405 };
406 
408 
409 #endif // CRYPTOPP_NIST_DRBG_H
410 
Base class for all exceptions thrown by the library.
Definition: cryptlib.h:140
SecByteBlock m_v
Definition: drbg.h:403
void Hash_df(const byte *input1, size_t inlen1, const byte *input2, size_t inlen2, const byte *input3, size_t inlen3, const byte *input4, size_t inlen4, byte *output, size_t outlen)
Definition: drbg.h:227
uint8_t byte
Definition: Common.h:57
SHA-256 message digest.
Definition: sha.h:39
void IncrementCounterByOne(byte *inout, unsigned int size)
Performs an addition with carry on a block of bytes.
Definition: misc.h:1029
void IncorporateEntropy(const byte *entropy, size_t entropyLength, const byte *additional, size_t additionaLength)
Update RNG state with additional unpredictable values.
Definition: drbg.h:216
#define NAMESPACE_BEGIN(x)
Definition: config.h:200
#define h(i)
Definition: sha.cpp:736
size_t count
Definition: ExecStats.cpp:37
Abstract base classes that provide a uniform interface to this library.
size_type size() const
Provides the count of elements in the SecBlock.
Definition: secblock.h:524
unsigned int GetMinNonce() const
Provides the minimum nonce size.
Definition: drbg.h:208
#define c(i)
Interface for random number generators.
Definition: cryptlib.h:1188
unsigned int GetMinEntropy() const
Provides the minimum entropy size.
Definition: drbg.h:206
void DRBG_Instantiate(const byte *entropy, size_t entropyLength, const byte *nonce, size_t nonceLength, const byte *personalization, size_t personalizationLength)
Definition: drbg.h:255
Err(const std::string &c, const std::string &m)
Definition: drbg.h:31
Classes and functions for secure memory allocations.
void IncorporateEntropy(const byte *input, size_t length)
Update RNG state with additional unpredictable values.
Definition: drbg.h:213
Exception thrown when a NIST DRBG encounters an error.
Definition: drbg.h:28
void GenerateBlock(const byte *additional, size_t additionaLength, byte *output, size_t size)
Generate random array of bytes.
Definition: drbg.h:222
T ConditionalByteReverse(ByteOrder order, T value)
Reverses bytes in a value depending upon endianness.
Definition: misc.h:1807
unsigned int GetSecurityStrength() const
Provides the security strength.
Definition: drbg.h:204
void GenerateBlock(byte *output, size_t size)
Generate random array of bytes.
Definition: drbg.h:219
#define t1
unsigned long long word64
Definition: config.h:240
unsigned int GetMaxNonce() const
Provides the maximum nonce size.
Definition: drbg.h:209
#define CRYPTOPP_CONSTANT(x)
Definition: config.h:540
unsigned int GetMaxBytesPerRequest() const
Provides the maximum size of a request to GenerateBlock.
Definition: drbg.h:210
byte order is big-endian
Definition: cryptlib.h:128
const T & STDMIN(const T &a, const T &b)
Replacement function for std::min.
Definition: misc.h:477
#define CRYPTOPP_ASSERT(exp)
Definition: trap.h:92
#define t2
word64 m_reseed
Definition: drbg.h:404
void Hash_Generate(const byte *additional, size_t additionaLength, byte *output, size_t size)
Definition: drbg.h:309
Hash_DRBG from SP 800-90A Rev 1 (June 2015)
Definition: drbg.h:156
virtual ~NIST_DRBG()
Definition: drbg.h:36
Interface for NIST DRBGs from SP 800-90A.
Definition: drbg.h:24
uint8_t const size_t const size
Definition: sha3.h:20
#define NAMESPACE_END
Definition: config.h:201
unsigned int GetSeedLength() const
Provides the seed length.
Definition: drbg.h:205
virtual bool CanIncorporateEntropy() const
Determines if a generator can accept additional entropy.
Definition: drbg.h:41
unsigned int word32
Definition: config.h:231
unsigned int GetMaxRequestBeforeReseed() const
Provides the maximum number of requests before a reseed.
Definition: drbg.h:211
uint8_t const * data
Definition: sha3.h:19
unsigned int GetMaxEntropy() const
Provides the maximum entropy size.
Definition: drbg.h:207
void DRBG_Reseed(const byte *entropy, size_t entropyLength, const byte *additional, size_t additionaLength)
Definition: drbg.h:283