initial
This commit is contained in:
155
external/crypto++-5.61/rng.cpp
vendored
Normal file
155
external/crypto++-5.61/rng.cpp
vendored
Normal file
@@ -0,0 +1,155 @@
|
||||
// rng.cpp - written and placed in the public domain by Wei Dai
|
||||
|
||||
#include "pch.h"
|
||||
|
||||
#include "rng.h"
|
||||
#include "fips140.h"
|
||||
|
||||
#include <time.h>
|
||||
#include <math.h>
|
||||
|
||||
NAMESPACE_BEGIN(CryptoPP)
|
||||
|
||||
// linear congruential generator
|
||||
// originally by William S. England
|
||||
|
||||
// do not use for cryptographic purposes
|
||||
|
||||
/*
|
||||
** Original_numbers are the original published m and q in the
|
||||
** ACM article above. John Burton has furnished numbers for
|
||||
** a reportedly better generator. The new numbers are now
|
||||
** used in this program by default.
|
||||
*/
|
||||
|
||||
#ifndef LCRNG_ORIGINAL_NUMBERS
|
||||
const word32 LC_RNG::m=2147483647L;
|
||||
const word32 LC_RNG::q=44488L;
|
||||
|
||||
const word16 LC_RNG::a=(unsigned int)48271L;
|
||||
const word16 LC_RNG::r=3399;
|
||||
#else
|
||||
const word32 LC_RNG::m=2147483647L;
|
||||
const word32 LC_RNG::q=127773L;
|
||||
|
||||
const word16 LC_RNG::a=16807;
|
||||
const word16 LC_RNG::r=2836;
|
||||
#endif
|
||||
|
||||
void LC_RNG::GenerateBlock(byte *output, size_t size)
|
||||
{
|
||||
while (size--)
|
||||
{
|
||||
word32 hi = seed/q;
|
||||
word32 lo = seed%q;
|
||||
|
||||
long test = a*lo - r*hi;
|
||||
|
||||
if (test > 0)
|
||||
seed = test;
|
||||
else
|
||||
seed = test+ m;
|
||||
|
||||
*output++ = (GETBYTE(seed, 0) ^ GETBYTE(seed, 1) ^ GETBYTE(seed, 2) ^ GETBYTE(seed, 3));
|
||||
}
|
||||
}
|
||||
|
||||
// ********************************************************
|
||||
|
||||
#ifndef CRYPTOPP_IMPORTS
|
||||
|
||||
X917RNG::X917RNG(BlockTransformation *c, const byte *seed, const byte *deterministicTimeVector)
|
||||
: cipher(c),
|
||||
S(cipher->BlockSize()),
|
||||
dtbuf(S),
|
||||
randseed(seed, S),
|
||||
m_lastBlock(S),
|
||||
m_deterministicTimeVector(deterministicTimeVector, deterministicTimeVector ? S : 0)
|
||||
{
|
||||
if (!deterministicTimeVector)
|
||||
{
|
||||
time_t tstamp1 = time(0);
|
||||
xorbuf(dtbuf, (byte *)&tstamp1, UnsignedMin(sizeof(tstamp1), S));
|
||||
cipher->ProcessBlock(dtbuf);
|
||||
clock_t tstamp2 = clock();
|
||||
xorbuf(dtbuf, (byte *)&tstamp2, UnsignedMin(sizeof(tstamp2), S));
|
||||
cipher->ProcessBlock(dtbuf);
|
||||
}
|
||||
|
||||
// for FIPS 140-2
|
||||
GenerateBlock(m_lastBlock, S);
|
||||
}
|
||||
|
||||
void X917RNG::GenerateIntoBufferedTransformation(BufferedTransformation &target, const std::string &channel, lword size)
|
||||
{
|
||||
while (size > 0)
|
||||
{
|
||||
// calculate new enciphered timestamp
|
||||
if (m_deterministicTimeVector.size())
|
||||
{
|
||||
cipher->ProcessBlock(m_deterministicTimeVector, dtbuf);
|
||||
IncrementCounterByOne(m_deterministicTimeVector, S);
|
||||
}
|
||||
else
|
||||
{
|
||||
clock_t c = clock();
|
||||
xorbuf(dtbuf, (byte *)&c, UnsignedMin(sizeof(c), S));
|
||||
time_t t = time(NULL);
|
||||
xorbuf(dtbuf+S-UnsignedMin(sizeof(t), S), (byte *)&t, UnsignedMin(sizeof(t), S));
|
||||
cipher->ProcessBlock(dtbuf);
|
||||
}
|
||||
|
||||
// combine enciphered timestamp with seed
|
||||
xorbuf(randseed, dtbuf, S);
|
||||
|
||||
// generate a new block of random bytes
|
||||
cipher->ProcessBlock(randseed);
|
||||
if (memcmp(m_lastBlock, randseed, S) == 0)
|
||||
throw SelfTestFailure("X917RNG: Continuous random number generator test failed.");
|
||||
|
||||
// output random bytes
|
||||
size_t len = UnsignedMin(S, size);
|
||||
target.ChannelPut(channel, randseed, len);
|
||||
size -= len;
|
||||
|
||||
// compute new seed vector
|
||||
memcpy(m_lastBlock, randseed, S);
|
||||
xorbuf(randseed, dtbuf, S);
|
||||
cipher->ProcessBlock(randseed);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
MaurerRandomnessTest::MaurerRandomnessTest()
|
||||
: sum(0.0), n(0)
|
||||
{
|
||||
for (unsigned i=0; i<V; i++)
|
||||
tab[i] = 0;
|
||||
}
|
||||
|
||||
size_t MaurerRandomnessTest::Put2(const byte *inString, size_t length, int messageEnd, bool blocking)
|
||||
{
|
||||
while (length--)
|
||||
{
|
||||
byte inByte = *inString++;
|
||||
if (n >= Q)
|
||||
sum += log(double(n - tab[inByte]));
|
||||
tab[inByte] = n;
|
||||
n++;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
double MaurerRandomnessTest::GetTestValue() const
|
||||
{
|
||||
if (BytesNeeded() > 0)
|
||||
throw Exception(Exception::OTHER_ERROR, "MaurerRandomnessTest: " + IntToString(BytesNeeded()) + " more bytes of input needed");
|
||||
|
||||
double fTu = (sum/(n-Q))/log(2.0); // this is the test value defined by Maurer
|
||||
|
||||
double value = fTu * 0.1392; // arbitrarily normalize it to
|
||||
return value > 1.0 ? 1.0 : value; // a number between 0 and 1
|
||||
}
|
||||
|
||||
NAMESPACE_END
|
||||
Reference in New Issue
Block a user