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, const byte *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, deterministicTimeVector ? S : 0)
00065 {
00066 if (!deterministicTimeVector)
00067 {
00068 time_t tstamp1 = time(0);
00069 xorbuf(dtbuf, (byte *)&tstamp1, STDMIN((int)sizeof(tstamp1), S));
00070 cipher->ProcessBlock(dtbuf);
00071 clock_t tstamp2 = clock();
00072 xorbuf(dtbuf, (byte *)&tstamp2, STDMIN((int)sizeof(tstamp2), S));
00073 cipher->ProcessBlock(dtbuf);
00074 }
00075 }
00076
00077 byte X917RNG::GenerateByte()
00078 {
00079 if (randbuf_counter==0)
00080 {
00081
00082 if (m_deterministicTimeVector.size())
00083 {
00084 cipher->ProcessBlock(m_deterministicTimeVector, dtbuf);
00085 IncrementCounterByOne(m_deterministicTimeVector, S);
00086 }
00087 else
00088 {
00089 clock_t tstamp = clock();
00090 xorbuf(dtbuf, (byte *)&tstamp, STDMIN((int)sizeof(tstamp), S));
00091 cipher->ProcessBlock(dtbuf);
00092 }
00093
00094
00095 xorbuf(randseed, dtbuf, S);
00096
00097
00098 cipher->ProcessBlock(randseed, randbuf);
00099
00100
00101 for (int i=0; i<S; i++)
00102 randseed[i] = randbuf[i] ^ dtbuf[i];
00103 cipher->ProcessBlock(randseed);
00104
00105 randbuf_counter=S;
00106 }
00107 return(randbuf[S-randbuf_counter--]);
00108 }
00109
00110 #endif
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 size_t MaurerRandomnessTest::Put2(const byte *inString, size_t length, int messageEnd, bool blocking)
00120 {
00121 while (length--)
00122 {
00123 byte inByte = *inString++;
00124 if (n >= Q)
00125 sum += log(double(n - tab[inByte]));
00126 tab[inByte] = n;
00127 n++;
00128 }
00129 return 0;
00130 }
00131
00132 double MaurerRandomnessTest::GetTestValue() const
00133 {
00134 if (BytesNeeded() > 0)
00135 throw Exception(Exception::OTHER_ERROR, "MaurerRandomnessTest: " + IntToString(BytesNeeded()) + " more bytes of input needed");
00136
00137 double fTu = (sum/(n-Q))/log(2.0);
00138
00139 double value = fTu * 0.1392;
00140 return value > 1.0 ? 1.0 : value;
00141 }
00142
00143 NAMESPACE_END