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