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 #include "rng.h" 00005 00006 #include <time.h> 00007 #include <math.h> 00008 00009 NAMESPACE_BEGIN(CryptoPP) 00010 00011 // linear congruential generator 00012 // originally by William S. England 00013 00014 // do not use for cryptographic purposes 00015 00016 /* 00017 ** Original_numbers are the original published m and q in the 00018 ** ACM article above. John Burton has furnished numbers for 00019 ** a reportedly better generator. The new numbers are now 00020 ** used in this program by default. 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 // calculate new enciphered timestamp 00084 if (m_deterministicTimeVector) 00085 { 00086 xorbuf(dtbuf, (byte *)&m_deterministicTimeVector, STDMIN((int)sizeof(m_deterministicTimeVector), S)); 00087 while (++m_deterministicTimeVector == 0) {} // skip 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 // combine enciphered timestamp with seed 00097 xorbuf(randseed, dtbuf, S); 00098 00099 // generate a new block of random bytes 00100 cipher->ProcessBlock(randseed, randbuf); 00101 00102 // compute new seed vector 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); // this is the test value defined by Maurer 00136 00137 double value = fTu * 0.1392; // arbitrarily normalize it to 00138 return value > 1.0 ? 1.0 : value; // a number between 0 and 1 00139 } 00140 00141 NAMESPACE_END

Generated on Fri Aug 13 09:56:54 2004 for Crypto++ by doxygen 1.3.7