Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | File List | Namespace Members | Class Members | File Members

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

Generated on Mon Apr 19 18:12:32 2004 for Crypto++ by doxygen 1.3.6-20040222