summaryrefslogtreecommitdiff
path: root/rng.cpp
diff options
context:
space:
mode:
authorweidai <weidai11@users.noreply.github.com>2002-10-04 17:31:41 +0000
committerweidai <weidai11@users.noreply.github.com>2002-10-04 17:31:41 +0000
commita3b6ece7ab341b5b14135baeccea7d5e4c086771 (patch)
tree8b045309c238226c32a563b1df6b9c30a2f0e0b3 /rng.cpp
downloadcryptopp-git-a3b6ece7ab341b5b14135baeccea7d5e4c086771.tar.gz
Initial revision
Diffstat (limited to 'rng.cpp')
-rw-r--r--rng.cpp124
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