diff options
author | weidai <weidai@57ff6487-cd31-0410-9ec3-f628ee90f5f0> | 2002-10-04 17:31:41 +0000 |
---|---|---|
committer | weidai <weidai@57ff6487-cd31-0410-9ec3-f628ee90f5f0> | 2002-10-04 17:31:41 +0000 |
commit | b21162cf8e06f40baa1f58be6a8c17435cebc34d (patch) | |
tree | 8b045309c238226c32a563b1df6b9c30a2f0e0b3 /randpool.cpp | |
download | cryptopp-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.cpp | 100 |
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 |