00001
00002
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();
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