diff options
author | weidai <weidai11@users.noreply.github.com> | 2002-10-04 17:31:41 +0000 |
---|---|---|
committer | weidai <weidai11@users.noreply.github.com> | 2002-10-04 17:31:41 +0000 |
commit | a3b6ece7ab341b5b14135baeccea7d5e4c086771 (patch) | |
tree | 8b045309c238226c32a563b1df6b9c30a2f0e0b3 /rng.cpp | |
download | cryptopp-git-a3b6ece7ab341b5b14135baeccea7d5e4c086771.tar.gz |
Initial revision
Diffstat (limited to 'rng.cpp')
-rw-r--r-- | rng.cpp | 124 |
1 files changed, 124 insertions, 0 deletions
diff --git a/rng.cpp b/rng.cpp new file mode 100644 index 00000000..b16e6bd3 --- /dev/null +++ b/rng.cpp @@ -0,0 +1,124 @@ +// rng.cpp - written and placed in the public domain by Wei Dai + +#include "pch.h" +#include "rng.h" + +#include <time.h> +#include <math.h> + +NAMESPACE_BEGIN(CryptoPP) + +// linear congruential generator +// originally by William S. England + +// do not use for cryptographic purposes + +/* +** Original_numbers are the original published m and q in the +** ACM article above. John Burton has furnished numbers for +** a reportedly better generator. The new numbers are now +** used in this program by default. +*/ + +#ifndef LCRNG_ORIGINAL_NUMBERS +const word32 LC_RNG::m=2147483647L; +const word32 LC_RNG::q=44488L; + +const word16 LC_RNG::a=(unsigned int)48271L; +const word16 LC_RNG::r=3399; +#else +const word32 LC_RNG::m=2147483647L; +const word32 LC_RNG::q=127773L; + +const word16 LC_RNG::a=16807; +const word16 LC_RNG::r=2836; +#endif + +byte LC_RNG::GenerateByte() +{ + word32 hi = seed/q; + word32 lo = seed%q; + + long test = a*lo - r*hi; + + if (test > 0) + seed = test; + else + seed = test+ m; + + return (GETBYTE(seed, 0) ^ GETBYTE(seed, 1) ^ GETBYTE(seed, 2) ^ GETBYTE(seed, 3)); +} + +// ******************************************************** + +X917RNG::X917RNG(BlockTransformation *c, const byte *seed) + : cipher(c), + S(cipher->BlockSize()), + dtbuf(S), + randseed(seed, S), + randbuf(S), + randbuf_counter(0) +{ + time_t tstamp1 = time(0); + xorbuf(dtbuf, (byte *)&tstamp1, STDMIN((int)sizeof(tstamp1), S)); + cipher->ProcessBlock(dtbuf); + clock_t tstamp2 = clock(); + xorbuf(dtbuf, (byte *)&tstamp2, STDMIN((int)sizeof(tstamp2), S)); + cipher->ProcessBlock(dtbuf); +} + +byte X917RNG::GenerateByte() +{ + if (randbuf_counter==0) + { + // calculate new enciphered timestamp + clock_t tstamp = clock(); + xorbuf(dtbuf, (byte *)&tstamp, STDMIN((int)sizeof(tstamp), S)); + cipher->ProcessBlock(dtbuf); + + // combine enciphered timestamp with seed + xorbuf(randseed, dtbuf, S); + + // generate a new block of random bytes + cipher->ProcessBlock(randseed, randbuf); + + // compute new seed vector + for (int i=0; i<S; i++) + randseed[i] = randbuf[i] ^ dtbuf[i]; + cipher->ProcessBlock(randseed); + + randbuf_counter=S; + } + return(randbuf[--randbuf_counter]); +} + +MaurerRandomnessTest::MaurerRandomnessTest() + : sum(0.0), n(0) +{ + for (unsigned i=0; i<V; i++) + tab[i] = 0; +} + +inline void MaurerRandomnessTest::Put(byte inByte) +{ + if (n >= Q) + sum += log(double(n - tab[inByte])); + tab[inByte] = n; + n++; +} + +void MaurerRandomnessTest::Put(const byte *inString, unsigned int length) +{ + while (length--) + Put(*inString++); +} + +double MaurerRandomnessTest::GetTestValue() const +{ + double fTu = (sum/(n-Q))/log(2.0); // this is the test value defined by Maurer + + double value = fTu * 0.1392; // arbitrarily normalize it to + return value > 1.0 ? 1.0 : value; // a number between 0 and 1 +} + +NAMESPACE_END |