- Main Page
- Namespaces
- Classes
- Files

- File List
- 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 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