Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | File List | Namespace Members | Class Members | File Members

rng.cpp

00001 // rng.cpp - written and placed in the public domain by Wei Dai 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 // linear congruential generator 00013 // originally by William S. England 00014 00015 // do not use for cryptographic purposes 00016 00017 /* 00018 ** Original_numbers are the original published m and q in the 00019 ** ACM article above. John Burton has furnished numbers for 00020 ** a reportedly better generator. The new numbers are now 00021 ** used in this program by default. 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 // calculate new enciphered timestamp 00087 if (m_deterministicTimeVector) 00088 { 00089 xorbuf(dtbuf, (byte *)&m_deterministicTimeVector, STDMIN((int)sizeof(m_deterministicTimeVector), S)); 00090 while (++m_deterministicTimeVector == 0) {} // skip 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 // combine enciphered timestamp with seed 00100 xorbuf(randseed, dtbuf, S); 00101 00102 // generate a new block of random bytes 00103 cipher->ProcessBlock(randseed, randbuf); 00104 00105 // compute new seed vector 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); // this is the test value defined by Maurer 00143 00144 double value = fTu * 0.1392; // arbitrarily normalize it to 00145 return value > 1.0 ? 1.0 : value; // a number between 0 and 1 00146 } 00147 00148 NAMESPACE_END

Generated on Fri Aug 27 19:37:32 2004 for Crypto++ by doxygen 1.3.8