00001
00002
00003 #include "pch.h"
00004 #include "rng.h"
00005
00006 #include <time.h>
00007 #include <math.h>
00008
00009 NAMESPACE_BEGIN(CryptoPP)
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #ifndef LCRNG_ORIGINAL_NUMBERS
00024 const word32 LC_RNG::m=2147483647L;
00025 const word32 LC_RNG::q=44488L;
00026
00027 const word16 LC_RNG::a=(unsigned int)48271L;
00028 const word16 LC_RNG::r=3399;
00029 #else
00030 const word32 LC_RNG::m=2147483647L;
00031 const word32 LC_RNG::q=127773L;
00032
00033 const word16 LC_RNG::a=16807;
00034 const word16 LC_RNG::r=2836;
00035 #endif
00036
00037 byte LC_RNG::GenerateByte()
00038 {
00039 word32 hi = seed/q;
00040 word32 lo = seed%q;
00041
00042 long test = a*lo - r*hi;
00043
00044 if (test > 0)
00045 seed = test;
00046 else
00047 seed = test+ m;
00048
00049 return (GETBYTE(seed, 0) ^ GETBYTE(seed, 1) ^ GETBYTE(seed, 2) ^ GETBYTE(seed, 3));
00050 }
00051
00052
00053
00054 X917RNG::X917RNG(BlockTransformation *c, const byte *seed, unsigned long deterministicTimeVector)
00055 : cipher(c),
00056 S(cipher->BlockSize()),
00057 dtbuf(S),
00058 randseed(seed, S),
00059 randbuf(S),
00060 randbuf_counter(0),
00061 m_deterministicTimeVector(deterministicTimeVector)
00062 {
00063 if (m_deterministicTimeVector)
00064 {
00065 memset(dtbuf, 0, S);
00066 memcpy(dtbuf, (byte *)&m_deterministicTimeVector, STDMIN((int)sizeof(m_deterministicTimeVector), S));
00067 }
00068 else
00069 {
00070 time_t tstamp1 = time(0);
00071 xorbuf(dtbuf, (byte *)&tstamp1, STDMIN((int)sizeof(tstamp1), S));
00072 cipher->ProcessBlock(dtbuf);
00073 clock_t tstamp2 = clock();
00074 xorbuf(dtbuf, (byte *)&tstamp2, STDMIN((int)sizeof(tstamp2), S));
00075 cipher->ProcessBlock(dtbuf);
00076 }
00077 }
00078
00079 byte X917RNG::GenerateByte()
00080 {
00081 if (randbuf_counter==0)
00082 {
00083
00084 if (m_deterministicTimeVector)
00085 {
00086 xorbuf(dtbuf, (byte *)&m_deterministicTimeVector, STDMIN((int)sizeof(m_deterministicTimeVector), S));
00087 while (++m_deterministicTimeVector == 0) {}
00088 }
00089 else
00090 {
00091 clock_t tstamp = clock();
00092 xorbuf(dtbuf, (byte *)&tstamp, STDMIN((int)sizeof(tstamp), S));
00093 }
00094 cipher->ProcessBlock(dtbuf);
00095
00096
00097 xorbuf(randseed, dtbuf, S);
00098
00099
00100 cipher->ProcessBlock(randseed, randbuf);
00101
00102
00103 for (int i=0; i<S; i++)
00104 randseed[i] = randbuf[i] ^ dtbuf[i];
00105 cipher->ProcessBlock(randseed);
00106
00107 randbuf_counter=S;
00108 }
00109 return(randbuf[--randbuf_counter]);
00110 }
00111
00112 MaurerRandomnessTest::MaurerRandomnessTest()
00113 : sum(0.0), n(0)
00114 {
00115 for (unsigned i=0; i<V; i++)
00116 tab[i] = 0;
00117 }
00118
00119 inline void MaurerRandomnessTest::Put(byte inByte)
00120 {
00121 if (n >= Q)
00122 sum += log(double(n - tab[inByte]));
00123 tab[inByte] = n;
00124 n++;
00125 }
00126
00127 void MaurerRandomnessTest::Put(const byte *inString, unsigned int length)
00128 {
00129 while (length--)
00130 Put(*inString++);
00131 }
00132
00133 double MaurerRandomnessTest::GetTestValue() const
00134 {
00135 double fTu = (sum/(n-Q))/log(2.0);
00136
00137 double value = fTu * 0.1392;
00138 return value > 1.0 ? 1.0 : value;
00139 }
00140
00141 NAMESPACE_END