1
// rng.cpp - written and placed in the public domain by Wei Dai
10
NAMESPACE_BEGIN(CryptoPP)
12
// linear congruential generator
13
// originally by William S. England
15
// do not use for cryptographic purposes
18
** Original_numbers are the original published m and q in the
19
** ACM article above. John Burton has furnished numbers for
20
** a reportedly better generator. The new numbers are now
21
** used in this program by default.
24
#ifndef LCRNG_ORIGINAL_NUMBERS
25
const word32 LC_RNG::m=2147483647L;
26
const word32 LC_RNG::q=44488L;
28
const word16 LC_RNG::a=(unsigned int)48271L;
29
const word16 LC_RNG::r=3399;
31
const word32 LC_RNG::m=2147483647L;
32
const word32 LC_RNG::q=127773L;
34
const word16 LC_RNG::a=16807;
35
const word16 LC_RNG::r=2836;
38
void LC_RNG::GenerateBlock(byte *output, size_t size)
45
long test = a*lo - r*hi;
52
*output++ = (GETBYTE(seed, 0) ^ GETBYTE(seed, 1) ^ GETBYTE(seed, 2) ^ GETBYTE(seed, 3));
56
// ********************************************************
58
#ifndef CRYPTOPP_IMPORTS
60
X917RNG::X917RNG(BlockTransformation *c, const byte *seed, const byte *deterministicTimeVector)
62
S(cipher->BlockSize()),
66
m_deterministicTimeVector(deterministicTimeVector, deterministicTimeVector ? S : 0)
68
assert (deterministicTimeVector);
71
GenerateBlock(m_lastBlock, S);
74
void X917RNG::GenerateIntoBufferedTransformation(BufferedTransformation &target, const std::string &channel, lword size)
78
// calculate new enciphered timestamp
79
if (m_deterministicTimeVector.size())
81
cipher->ProcessBlock(m_deterministicTimeVector, dtbuf);
82
IncrementCounterByOne(m_deterministicTimeVector, S);
89
// combine enciphered timestamp with seed
90
xorbuf(randseed, dtbuf, S);
92
// generate a new block of random bytes
93
cipher->ProcessBlock(randseed);
94
if (memcmp(m_lastBlock, randseed, S) == 0)
95
throw SelfTestFailure("X917RNG: Continuous random number generator test failed.");
97
// output random bytes
98
size_t len = UnsignedMin(S, size);
99
target.ChannelPut(channel, randseed, len);
102
// compute new seed vector
103
memcpy(m_lastBlock, randseed, S);
104
xorbuf(randseed, dtbuf, S);
105
cipher->ProcessBlock(randseed);
111
MaurerRandomnessTest::MaurerRandomnessTest()
114
for (unsigned i=0; i<V; i++)
118
size_t MaurerRandomnessTest::Put2(const byte *inString, size_t length, int messageEnd, bool blocking)
122
byte inByte = *inString++;
124
sum += log(double(n - tab[inByte]));
131
double MaurerRandomnessTest::GetTestValue() const
133
if (BytesNeeded() > 0)
134
throw Exception(Exception::OTHER_ERROR, "MaurerRandomnessTest: " + IntToString(BytesNeeded()) + " more bytes of input needed");
136
double fTu = (sum/(n-Q))/log(2.0); // this is the test value defined by Maurer
138
double value = fTu * 0.1392; // arbitrarily normalize it to
139
return value > 1.0 ? 1.0 : value; // a number between 0 and 1