Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | File List | 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