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 (seedBytes[0] ^ seedBytes[1] ^ seedBytes[2] ^ seedBytes[3]);
00050 }
00051
00052
00053
00054 X917RNG::X917RNG(BlockTransformation *c, const byte *seed)
00055 : cipher(c),
00056 S(cipher->BlockSize()),
00057 dtbuf(S),
00058 randseed(seed, S),
00059 randbuf(S),
00060 randbuf_counter(0)
00061 {
00062 time_t tstamp1 = time(0);
00063 xorbuf(dtbuf, (byte *)&tstamp1, STDMIN((int)sizeof(tstamp1), S));
00064 cipher->ProcessBlock(dtbuf);
00065 clock_t tstamp2 = clock();
00066 xorbuf(dtbuf, (byte *)&tstamp2, STDMIN((int)sizeof(tstamp2), S));
00067 cipher->ProcessBlock(dtbuf);
00068 }
00069
00070 byte X917RNG::GenerateByte()
00071 {
00072 if (randbuf_counter==0)
00073 {
00074
00075 clock_t tstamp = clock();
00076 xorbuf(dtbuf, (byte *)&tstamp, STDMIN((int)sizeof(tstamp), S));
00077 cipher->ProcessBlock(dtbuf);
00078
00079
00080 xorbuf(randseed, dtbuf, S);
00081
00082
00083 cipher->ProcessBlock(randseed, randbuf);
00084
00085
00086 for (int i=0; i<S; i++)
00087 randseed[i] = randbuf[i] ^ dtbuf[i];
00088 cipher->ProcessBlock(randseed);
00089
00090 randbuf_counter=S;
00091 }
00092 return(randbuf[--randbuf_counter]);
00093 }
00094
00095 MaurerRandomnessTest::MaurerRandomnessTest()
00096 : sum(0.0), n(0)
00097 {
00098 for (unsigned i=0; i<V; i++)
00099 tab[i] = 0;
00100 }
00101
00102 inline void MaurerRandomnessTest::Put(byte inByte)
00103 {
00104 if (n >= Q)
00105 sum += log(double(n - tab[inByte]));
00106 tab[inByte] = n;
00107 n++;
00108 }
00109
00110 void MaurerRandomnessTest::Put(const byte *inString, unsigned int length)
00111 {
00112 while (length--)
00113 Put(*inString++);
00114 }
00115
00116 double MaurerRandomnessTest::GetTestValue() const
00117 {
00118 double fTu = (sum/(n-Q))/log(2.0);
00119
00120 double value = fTu * 0.1392;
00121 return value > 1.0 ? 1.0 : value;
00122 }
00123
00124 NAMESPACE_END