randpool.cpp

00001 // randpool.cpp - written and placed in the public domain by Wei Dai
00002 // The algorithm in this module comes from PGP's randpool.c
00003 
00004 #include "pch.h"
00005 
00006 #ifndef CRYPTOPP_IMPORTS
00007 
00008 #include "randpool.h"
00009 #include "mdc.h"
00010 #include "sha.h"
00011 #include "modes.h"
00012 
00013 NAMESPACE_BEGIN(CryptoPP)
00014 
00015 typedef MDC<SHA> RandomPoolCipher;
00016 
00017 RandomPool::RandomPool(unsigned int poolSize)
00018         : pool(poolSize), key(RandomPoolCipher::DEFAULT_KEYLENGTH)
00019 {
00020         assert(poolSize > key.size());
00021 
00022         addPos=0;
00023         getPos=poolSize;
00024         memset(pool, 0, poolSize);
00025         memset(key, 0, key.size());
00026 }
00027 
00028 void RandomPool::Stir()
00029 {
00030         CFB_Mode<RandomPoolCipher>::Encryption cipher;
00031 
00032         for (int i=0; i<2; i++)
00033         {
00034                 cipher.SetKeyWithIV(key, key.size(), pool.end()-cipher.IVSize());
00035                 cipher.ProcessString(pool, pool.size());
00036                 memcpy(key, pool, key.size());
00037         }
00038 
00039         addPos = 0;
00040         getPos = key.size();
00041 }
00042 
00043 size_t RandomPool::Put2(const byte *inString, size_t length, int messageEnd, bool blocking)
00044 {
00045         size_t t;
00046 
00047         while (length > (t = pool.size() - addPos))
00048         {
00049                 xorbuf(pool+addPos, inString, t);
00050                 inString += t;
00051                 length -= t;
00052                 Stir();
00053         }
00054 
00055         if (length)
00056         {
00057                 xorbuf(pool+addPos, inString, length);
00058                 addPos += length;
00059                 getPos = pool.size(); // Force stir on get
00060         }
00061 
00062         return 0;
00063 }
00064 
00065 size_t RandomPool::TransferTo2(BufferedTransformation &target, lword &transferBytes, const std::string &channel, bool blocking)
00066 {
00067         if (!blocking)
00068                 throw NotImplemented("RandomPool: nonblocking transfer is not implemented by this object");
00069 
00070         lword size = transferBytes;
00071 
00072         while (size > 0)
00073         {
00074                 if (getPos == pool.size())
00075                         Stir();
00076                 size_t t = UnsignedMin(pool.size() - getPos, size);
00077                 target.ChannelPut(channel, pool+getPos, t);
00078                 size -= t;
00079                 getPos += t;
00080         }
00081 
00082         return 0;
00083 }
00084 
00085 byte RandomPool::GenerateByte()
00086 {
00087         if (getPos == pool.size())
00088                 Stir();
00089 
00090         return pool[getPos++];
00091 }
00092 
00093 void RandomPool::GenerateBlock(byte *outString, size_t size)
00094 {
00095         ArraySink sink(outString, size);
00096         TransferTo(sink, size);
00097 }
00098 
00099 NAMESPACE_END
00100 
00101 #endif

Generated on Sat Dec 23 02:07:09 2006 for Crypto++ by  doxygen 1.5.1-p1