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 Thu Oct 28 03:02:11 2004 for Crypto++ by  doxygen 1.3.9.1