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 
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 unsigned int RandomPool::Put2(const byte *inString, unsigned int length, int messageEnd, bool blocking)
00044 {
00045         unsigned 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 unsigned int RandomPool::TransferTo2(BufferedTransformation &target, unsigned long &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         unsigned int t;
00071         unsigned long size = transferBytes;
00072 
00073         while (size > (t = pool.size() - getPos))
00074         {
00075                 target.ChannelPut(channel, pool+getPos, t);
00076                 size -= t;
00077                 Stir();
00078         }
00079 
00080         if (size)
00081         {
00082                 target.ChannelPut(channel, pool+getPos, size);
00083                 getPos += size;
00084         }
00085 
00086         return 0;
00087 }
00088 
00089 byte RandomPool::GenerateByte()
00090 {
00091         if (getPos == pool.size())
00092                 Stir();
00093 
00094         return pool[getPos++];
00095 }
00096 
00097 void RandomPool::GenerateBlock(byte *outString, unsigned int size)
00098 {
00099         ArraySink sink(outString, size);
00100         TransferTo(sink, size);
00101 }
00102 
00103 NAMESPACE_END
00104 
00105 #endif

Generated on Sun Jul 3 00:20:21 2005 for Crypto++ by  doxygen 1.4.3-20050530