Fabcoin Core  0.16.2
P2P Digital Currency
rng.cpp
Go to the documentation of this file.
1 // rng.cpp - written and placed in the public domain by Wei Dai
2 
3 #include "pch.h"
4 
5 #include "rng.h"
6 #include "fips140.h"
7 
8 #include <time.h>
9 #include <math.h>
10 
12 
13 // linear congruential generator
14 // originally by William S. England
15 
16 // do not use for cryptographic purposes
17 
18 /*
19 ** Original_numbers are the original published m and q in the
20 ** ACM article above. John Burton has furnished numbers for
21 ** a reportedly better generator. The new numbers are now
22 ** used in this program by default.
23 */
24 
25 #ifndef LCRNG_ORIGINAL_NUMBERS
26 const word32 LC_RNG::m=2147483647L;
27 const word32 LC_RNG::q=44488L;
28 
29 const word16 LC_RNG::a=(unsigned int)48271L;
30 const word16 LC_RNG::r=3399;
31 #else
32 const word32 LC_RNG::m=2147483647L;
33 const word32 LC_RNG::q=127773L;
34 
35 const word16 LC_RNG::a=16807;
36 const word16 LC_RNG::r=2836;
37 #endif
38 
39 void LC_RNG::GenerateBlock(byte *output, size_t size)
40 {
41  while (size--)
42  {
43  word32 hi = seed/q;
44  word32 lo = seed%q;
45 
46  long test = a*lo - r*hi;
47 
48  if (test > 0)
49  seed = test;
50  else
51  seed = test+ m;
52 
53  *output++ = byte((GETBYTE(seed, 0) ^ GETBYTE(seed, 1) ^ GETBYTE(seed, 2) ^ GETBYTE(seed, 3)));
54  }
55 }
56 
57 // ********************************************************
58 
59 #ifndef CRYPTOPP_IMPORTS
60 
61 X917RNG::X917RNG(BlockTransformation *c, const byte *seed, const byte *deterministicTimeVector)
62  : m_cipher(c),
63  m_size(m_cipher->BlockSize()),
64  m_datetime(m_size),
65  m_randseed(seed, m_size),
66  m_lastBlock(m_size),
67  m_deterministicTimeVector(deterministicTimeVector, deterministicTimeVector ? m_size : 0)
68 {
69  // Valgrind finding, http://github.com/weidai11/cryptopp/issues/105
70  // Garbage in the tail creates a non-conforming X9.17 or X9.31 generator.
71  if (m_size > 8)
72  {
73  memset(m_datetime, 0x00, m_size);
74  memset(m_lastBlock, 0x00, m_size);
75  }
76 
77  if (!deterministicTimeVector)
78  {
79  time_t tstamp1 = time(0);
80  xorbuf(m_datetime, (byte *)&tstamp1, UnsignedMin(sizeof(tstamp1), m_size));
82  clock_t tstamp2 = clock();
83  xorbuf(m_datetime, (byte *)&tstamp2, UnsignedMin(sizeof(tstamp2), m_size));
85  }
86 
87  // for FIPS 140-2
89 }
90 
92 {
93  while (size > 0)
94  {
95  // calculate new enciphered timestamp
97  {
100  }
101  else
102  {
103  clock_t c = clock();
104  xorbuf(m_datetime, (byte *)&c, UnsignedMin(sizeof(c), m_size));
105  time_t t = time(NULL);
106  xorbuf(m_datetime+m_size-UnsignedMin(sizeof(t), m_size), (byte *)&t, UnsignedMin(sizeof(t), m_size));
108  }
109 
110  // combine enciphered timestamp with seed
112 
113  // generate a new block of random bytes
115  if (memcmp(m_lastBlock, m_randseed, m_size) == 0)
116  throw SelfTestFailure("X917RNG: Continuous random number generator test failed.");
117 
118  // output random bytes
119  size_t len = UnsignedMin(m_size, size);
120  target.ChannelPut(channel, m_randseed, len);
121  size -= len;
122 
123  // compute new seed vector
127  }
128 }
129 
130 #endif
131 
133  : sum(0.0), n(0)
134 {
135  for (unsigned i=0; i<V; i++)
136  tab[i] = 0;
137 }
138 
139 size_t MaurerRandomnessTest::Put2(const byte *inString, size_t length, int /*messageEnd*/, bool /*blocking*/)
140 {
141  while (length--)
142  {
143  byte inByte = *inString++;
144  if (n >= Q)
145  sum += log(double(n - tab[inByte]));
146  tab[inByte] = n;
147  n++;
148  }
149  return 0;
150 }
151 
153 {
154  if (BytesNeeded() > 0)
155  throw Exception(Exception::OTHER_ERROR, "MaurerRandomnessTest: " + IntToString(BytesNeeded()) + " more bytes of input needed");
156 
157  double fTu = (sum/(n-Q))/log(2.0); // this is the test value defined by Maurer
158 
159  double value = fTu * 0.1392; // arbitrarily normalize it to
160  return value > 1.0 ? 1.0 : value; // a number between 0 and 1
161 }
162 
Base class for all exceptions thrown by the library.
Definition: cryptlib.h:140
SecByteBlock m_datetime
Definition: rng.h:74
uint8_t byte
Definition: Common.h:57
unsigned int BytesNeeded() const
Provides the number of bytes of input is needed by the test.
Definition: rng.h:96
void IncrementCounterByOne(byte *inout, unsigned int size)
Performs an addition with carry on a block of bytes.
Definition: misc.h:1029
unsigned short word16
Definition: config.h:230
virtual void GenerateBlock(byte *output, size_t size)
Generate random array of bytes.
Definition: cryptlib.cpp:326
size_t ChannelPut(const std::string &channel, byte inByte, bool blocking=true)
Input a byte for processing on a channel.
Definition: cryptlib.h:1864
#define NAMESPACE_BEGIN(x)
Definition: config.h:200
word32 seed
Definition: rng.h:35
unsigned int n
Definition: rng.h:105
size_type size() const
Provides the count of elements in the SecBlock.
Definition: secblock.h:524
Some other error occurred not belonging to other categories.
Definition: cryptlib.h:159
#define c(i)
SecByteBlock m_lastBlock
Definition: rng.h:75
unsigned int tab[V]
Definition: rng.h:106
Interface for buffered transformations.
Definition: cryptlib.h:1352
SecByteBlock m_randseed
Definition: rng.h:75
static const word16 a
Definition: rng.h:39
best_clock::type clock
Definition: bench.h:48
const unsigned int m_size
Definition: rng.h:73
size_t Put2(const byte *inString, size_t length, int messageEnd, bool blocking)
Input multiple bytes for processing.
Definition: rng.cpp:139
Exception thrown when a crypto algorithm is used after a self test fails.
Definition: fips140.h:23
void ProcessBlock(const byte *inBlock, byte *outBlock) const
Encrypt or decrypt a block.
Definition: cryptlib.h:758
#define GETBYTE(x, y)
Definition: misc.h:610
const T1 UnsignedMin(const T1 &a, const T2 &b)
Safe comparison of values that could be neagtive and incorrectly promoted.
Definition: misc.h:512
void GenerateBlock(byte *output, size_t size)
Generate random array of bytes.
Definition: rng.cpp:39
Miscellaneous classes for RNGs.
void GenerateIntoBufferedTransformation(BufferedTransformation &target, const std::string &channel, lword size)
Generate random bytes into a BufferedTransformation.
Definition: rng.cpp:91
volatile double sum
Definition: Examples.cpp:23
void xorbuf(byte *buf, const byte *mask, size_t count)
Performs an XOR of a buffer with a mask.
Definition: misc.cpp:28
X917RNG(BlockTransformation *cipher, const byte *seed, const byte *deterministicTimeVector=0)
Construct a X917RNG.
Definition: rng.cpp:61
SecByteBlock m_deterministicTimeVector
Definition: rng.h:75
member_ptr< BlockTransformation > m_cipher
Definition: rng.h:72
Classes and functions for the FIPS 140-2 validated library.
uint8_t const size_t const size
Definition: sha3.h:20
void * memcpy(void *a, const void *b, size_t c)
uint8_t byte
Definition: Common.h:10
std::string IntToString(T value, unsigned int base=10)
Converts a value to a string.
Definition: misc.h:539
#define NAMESPACE_END
Definition: config.h:201
static const word32 q
Definition: rng.h:38
word64 lword
Definition: config.h:245
Interface for the data processing part of block ciphers.
Definition: cryptlib.h:734
static const word32 m
Definition: rng.h:37
double GetTestValue() const
Definition: rng.cpp:152
unsigned int word32
Definition: config.h:231
static const word16 r
Definition: rng.h:40
MaurerRandomnessTest()
Construct a MaurerRandomnessTest.
Definition: rng.cpp:132