summaryrefslogtreecommitdiff
path: root/randpool.cpp
diff options
context:
space:
mode:
authorweidai <weidai@57ff6487-cd31-0410-9ec3-f628ee90f5f0>2002-10-04 17:31:41 +0000
committerweidai <weidai@57ff6487-cd31-0410-9ec3-f628ee90f5f0>2002-10-04 17:31:41 +0000
commitb21162cf8e06f40baa1f58be6a8c17435cebc34d (patch)
tree8b045309c238226c32a563b1df6b9c30a2f0e0b3 /randpool.cpp
downloadcryptopp-b21162cf8e06f40baa1f58be6a8c17435cebc34d.tar.gz
Initial revision
git-svn-id: svn://svn.code.sf.net/p/cryptopp/code/trunk/c5@2 57ff6487-cd31-0410-9ec3-f628ee90f5f0
Diffstat (limited to 'randpool.cpp')
-rw-r--r--randpool.cpp100
1 files changed, 100 insertions, 0 deletions
diff --git a/randpool.cpp b/randpool.cpp
new file mode 100644
index 0000000..9fa0b4b
--- /dev/null
+++ b/randpool.cpp
@@ -0,0 +1,100 @@
+// randpool.cpp - written and placed in the public domain by Wei Dai
+// The algorithm in this module comes from PGP's randpool.c
+
+#include "pch.h"
+#include "randpool.h"
+#include "mdc.h"
+#include "sha.h"
+#include "modes.h"
+
+NAMESPACE_BEGIN(CryptoPP)
+
+typedef MDC<SHA> RandomPoolCipher;
+
+RandomPool::RandomPool(unsigned int poolSize)
+ : pool(poolSize), key(RandomPoolCipher::DEFAULT_KEYLENGTH)
+{
+ assert(poolSize > key.size());
+
+ addPos=0;
+ getPos=poolSize;
+ memset(pool, 0, poolSize);
+ memset(key, 0, key.size());
+}
+
+void RandomPool::Stir()
+{
+ CFB_Mode<RandomPoolCipher>::Encryption cipher;
+
+ for (int i=0; i<2; i++)
+ {
+ cipher.SetKeyWithIV(key, key.size(), pool.end()-cipher.IVSize());
+ cipher.ProcessString(pool, pool.size());
+ memcpy(key, pool, key.size());
+ }
+
+ addPos = 0;
+ getPos = key.size();
+}
+
+unsigned int RandomPool::Put2(const byte *inString, unsigned int length, int messageEnd, bool blocking)
+{
+ unsigned t;
+
+ while (length > (t = pool.size() - addPos))
+ {
+ xorbuf(pool+addPos, inString, t);
+ inString += t;
+ length -= t;
+ Stir();
+ }
+
+ if (length)
+ {
+ xorbuf(pool+addPos, inString, length);
+ addPos += length;
+ getPos = pool.size(); // Force stir on get
+ }
+
+ return 0;
+}
+
+unsigned int RandomPool::TransferTo2(BufferedTransformation &target, unsigned long &transferBytes, const std::string &channel, bool blocking)
+{
+ if (!blocking)
+ throw NotImplemented("RandomPool: nonblocking transfer is not implemented by this object");
+
+ unsigned int t;
+ unsigned long size = transferBytes;
+
+ while (size > (t = pool.size() - getPos))
+ {
+ target.ChannelPut(channel, pool+getPos, t);
+ size -= t;
+ Stir();
+ }
+
+ if (size)
+ {
+ target.ChannelPut(channel, pool+getPos, size);
+ getPos += size;
+ }
+
+ return 0;
+}
+
+byte RandomPool::GenerateByte()
+{
+ if (getPos == pool.size())
+ Stir();
+
+ return pool[getPos++];
+}
+
+void RandomPool::GenerateBlock(byte *outString, unsigned int size)
+{
+ ArraySink sink(outString, size);
+ TransferTo(sink, size);
+}
+
+NAMESPACE_END