add IncorporateEntropy and GenerateIntoBufferedTransformation to RNG interface

pull/2/head
weidai 2007-05-04 15:38:32 +00:00
parent 4186dc1478
commit 5834ecc870
10 changed files with 120 additions and 59 deletions

View File

@ -32,6 +32,18 @@ byte PublicBlumBlumShub::GenerateByte()
return b;
}
void PublicBlumBlumShub::GenerateBlock(byte *output, size_t size)
{
while (size--)
*output++ = PublicBlumBlumShub::GenerateByte();
}
void PublicBlumBlumShub::ProcessData(byte *outString, const byte *inString, size_t length)
{
while (length--)
*outString++ = *inString++ ^ PublicBlumBlumShub::GenerateByte();
}
BlumBlumShub::BlumBlumShub(const Integer &p, const Integer &q, const Integer &seed)
: PublicBlumBlumShub(p*q, seed),
p(p), q(q),

View File

@ -17,12 +17,8 @@ public:
unsigned int GenerateBit();
byte GenerateByte();
void ProcessData(byte *outString, const byte *inString, size_t length)
{
while (length--)
*outString++ = *inString ^ GenerateByte();
}
void GenerateBlock(byte *output, size_t size);
void ProcessData(byte *outString, const byte *inString, size_t length);
bool IsSelfInverting() const {return true;}
bool IsForwardTransformation() const {return true;}

View File

@ -11,6 +11,8 @@
#include "fips140.h"
#include "argnames.h"
#include "fltrimpl.h"
#include "trdlocal.h"
#include "osrng.h"
#include <memory>
@ -91,6 +93,11 @@ const byte * SimpleKeyingInterface::GetIVAndThrowIfInvalid(const NameValuePairs
return iv;
}
void SimpleKeyingInterface::GetNextIV(RandomNumberGenerator &rng, byte *IV)
{
rng.GenerateBlock(IV, IVSize());
}
void BlockTransformation::ProcessAndXorMultipleBlocks(const byte *inBlocks, const byte *xorBlocks, byte *outBlocks, size_t numberOfBlocks) const
{
unsigned int blockSize = BlockSize();
@ -104,6 +111,11 @@ void BlockTransformation::ProcessAndXorMultipleBlocks(const byte *inBlocks, cons
}
}
unsigned int BlockTransformation::BlockAlignment() const
{
return GetAlignmentOf<word32>();
}
void StreamTransformation::ProcessLastBlock(byte *outString, const byte *inString, size_t length)
{
assert(MinLastBlockSize() == 0); // this function should be overriden otherwise
@ -116,39 +128,53 @@ void StreamTransformation::ProcessLastBlock(byte *outString, const byte *inStrin
unsigned int RandomNumberGenerator::GenerateBit()
{
return Parity(GenerateByte());
return GenerateByte() & 1;
}
void RandomNumberGenerator::GenerateBlock(byte *output, size_t size)
byte RandomNumberGenerator::GenerateByte()
{
while (size--)
*output++ = GenerateByte();
byte b;
GenerateBlock(&b, 1);
return b;
}
word32 RandomNumberGenerator::GenerateWord32(word32 min, word32 max)
{
word32 range = max-min;
const int maxBytes = BytePrecision(range);
const int maxBits = BitPrecision(range);
word32 value;
do
{
value = 0;
for (int i=0; i<maxBytes; i++)
value = (value << 8) | GenerateByte();
GenerateBlock((byte *)&value, sizeof(value));
value = Crop(value, maxBits);
} while (value > range);
return value+min;
}
void RandomNumberGenerator::GenerateBlock(byte *output, size_t size)
{
ArraySink s(output, size);
GenerateIntoBufferedTransformation(s, BufferedTransformation::NULL_CHANNEL, size);
}
void RandomNumberGenerator::DiscardBytes(size_t n)
{
while (n--)
GenerateByte();
GenerateIntoBufferedTransformation(TheBitBucket(), BufferedTransformation::NULL_CHANNEL, n);
}
void RandomNumberGenerator::GenerateIntoBufferedTransformation(BufferedTransformation &target, const std::string &channel, lword length)
{
FixedSizeSecBlock<byte, 256> buffer;
while (length)
{
size_t len = UnsignedMin(buffer.size(), length);
GenerateBlock(buffer, len);
target.ChannelPut(channel, buffer, len);
length -= len;
}
}
//! see NullRNG()
@ -156,7 +182,7 @@ class ClassNullRNG : public RandomNumberGenerator
{
public:
std::string AlgorithmName() const {return "NullRNG";}
byte GenerateByte() {throw NotImplemented("NullRNG: NullRNG should only be passed to functions that don't need to generate random bytes");}
void GenerateBlock(byte *output, size_t size) {throw NotImplemented("NullRNG: NullRNG should only be passed to functions that don't need to generate random bytes");}
};
RandomNumberGenerator & NullRNG()

View File

@ -17,7 +17,7 @@
<dt>Message Authentication Codes<dd>
#MD5MAC, XMACC, HMAC, CBC_MAC, DMAC, PanamaMAC, TTMAC
<dt>Random Number Generators<dd>
NullRNG(), LC_RNG, RandomPool, BlockingRng, NonblockingRng, AutoSeededRandomPool, AutoSeededX917RNG
NullRNG(), LC_RNG, RandomPool, BlockingRng, NonblockingRng, AutoSeededRandomPool, AutoSeededX917RNG, DefaultAutoSeededRNG
<dt>Password-based Cryptography<dd>
PasswordBasedKeyDerivationFunction
<dt>Public Key Cryptosystems<dd>
@ -61,7 +61,7 @@ In the FIPS 140-2 validated DLL version of Crypto++, only the following implemen
<dt>Message Authentication Codes (replace template parameter H with one of the hash functions above)<dd>
HMAC\<H\>, CBC_MAC\<DES_EDE2\>, CBC_MAC\<DES_EDE3\>
<dt>Random Number Generators<dd>
AutoSeededX917RNG\<DES_EDE3\>
DefaultAutoSeededRNG (AutoSeededX917RNG\<AES\>)
<dt>Key Agreement<dd>
#DH
<dt>Public Key Cryptosystems<dd>
@ -84,6 +84,8 @@ NAMESPACE_BEGIN(CryptoPP)
// forward declarations
class Integer;
class RandomNumberGenerator;
class BufferedTransformation;
//! used to specify a direction for a cipher to operate in (encrypt or decrypt)
enum CipherDir {ENCRYPTION, DECRYPTION};
@ -397,7 +399,7 @@ public:
/*! This method should be called after you finish encrypting one message and are ready to start the next one.
After calling it, you must call SetKey() or Resynchronize() before using this object again.
This method is not implemented on decryption objects. */
virtual void GetNextIV(byte *IV) {throw NotImplemented("SimpleKeyingInterface: this object doesn't support GetNextIV()");}
virtual void GetNextIV(RandomNumberGenerator &rng, byte *IV);
protected:
virtual const Algorithm & GetAlgorithm() const =0;
@ -438,7 +440,7 @@ public:
virtual unsigned int BlockSize() const =0;
//! block pointers must be divisible by this
virtual unsigned int BlockAlignment() const {return 4;}
virtual unsigned int BlockAlignment() const; // returns alignment of word32 by default
//! returns true if this is a permutation (i.e. there is an inverse transformation)
virtual bool IsPermutation() const {return true;}
@ -624,24 +626,31 @@ typedef SymmetricCipher StreamCipher;
class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE RandomNumberGenerator : public Algorithm
{
public:
//! update RNG state with additional unpredictable values
virtual void IncorporateEntropy(const byte *input, size_t length) {throw NotImplemented("RandomNumberGenerator: IncorporateEntropy not implemented");}
//! returns true if IncorporateEntropy is implemented
virtual bool CanIncorporateEntropy() const {return false;}
//! generate new random byte and return it
virtual byte GenerateByte() =0;
virtual byte GenerateByte();
//! generate new random bit and return it
/*! Default implementation is to call GenerateByte() and return its parity. */
/*! Default implementation is to call GenerateByte() and return its lowest bit. */
virtual unsigned int GenerateBit();
//! generate a random 32 bit word in the range min to max, inclusive
virtual word32 GenerateWord32(word32 a=0, word32 b=0xffffffffL);
//! generate random array of bytes
/*! Default implementation is to call GenerateByte() size times. */
virtual void GenerateBlock(byte *output, size_t size);
//! generate and discard n bytes
/*! Default implementation is to call GenerateByte() n times. */
virtual void DiscardBytes(size_t n);
//! generate random bytes as input to a BufferedTransformation
virtual void GenerateIntoBufferedTransformation(BufferedTransformation &target, const std::string &channel, lword length);
//! randomly shuffle the specified array, resulting permutation is uniformly distributed
template <class IT> void Shuffle(IT begin, IT end)
{

View File

@ -496,6 +496,17 @@ void ProxyFilter::NextPutModifiable(byte *s, size_t len)
// *************************************************************
void RandomNumberSink::IsolatedInitialize(const NameValuePairs &parameters)
{
parameters.GetRequiredParameter("RandomNumberSink", "RandomNumberGeneratorPointer", m_rng);
}
size_t RandomNumberSink::Put2(const byte *begin, size_t length, int messageEnd, bool blocking)
{
m_rng->IncorporateEntropy(begin, length);
return 0;
}
size_t ArraySink::Put2(const byte *begin, size_t length, int messageEnd, bool blocking)
{
memcpy(m_buf+m_total, begin, STDMIN(length, SaturatingSubtract(m_size, m_total)));
@ -952,9 +963,10 @@ size_t RandomNumberStore::TransferTo2(BufferedTransformation &target, lword &tra
if (!blocking)
throw NotImplemented("RandomNumberStore: nonblocking transfer is not implemented by this object");
lword transferMax = transferBytes;
for (transferBytes = 0; transferBytes<transferMax && m_count < (unsigned int)m_length; ++transferBytes, ++m_count)
target.ChannelPut(channel, m_rng->GenerateByte());
transferBytes = UnsignedMin(transferBytes, m_length - m_count);
m_rng->GenerateIntoBufferedTransformation(target, channel, transferBytes);
m_count += transferBytes;
return 0;
}

View File

@ -565,6 +565,23 @@ private:
CRYPTOPP_DLL_TEMPLATE_CLASS StringSinkTemplate<std::string>;
typedef StringSinkTemplate<std::string> StringSink;
//! incorporates input into RNG as additional entropy
class RandomNumberSink : public Bufferless<Sink>
{
public:
RandomNumberSink()
: m_rng(NULL) {}
RandomNumberSink(RandomNumberGenerator &rng)
: m_rng(&rng) {}
void IsolatedInitialize(const NameValuePairs &parameters);
size_t Put2(const byte *begin, size_t length, int messageEnd, bool blocking);
private:
RandomNumberGenerator *m_rng;
};
//! Copy input to a memory buffer
class CRYPTOPP_DLL ArraySink : public Bufferless<Sink>
{
@ -716,14 +733,20 @@ class CRYPTOPP_DLL StringSource : public SourceTemplate<StringStore>
public:
StringSource(BufferedTransformation *attachment = NULL)
: SourceTemplate<StringStore>(attachment) {}
//! zero terminated string as source
StringSource(const char *string, bool pumpAll, BufferedTransformation *attachment = NULL)
: SourceTemplate<StringStore>(attachment) {SourceInitialize(pumpAll, MakeParameters("InputBuffer", ConstByteArrayParameter(string)));}
//! binary byte array as source
StringSource(const byte *string, size_t length, bool pumpAll, BufferedTransformation *attachment = NULL)
: SourceTemplate<StringStore>(attachment) {SourceInitialize(pumpAll, MakeParameters("InputBuffer", ConstByteArrayParameter(string, length)));}
//! std::string as source
StringSource(const std::string &string, bool pumpAll, BufferedTransformation *attachment = NULL)
: SourceTemplate<StringStore>(attachment) {SourceInitialize(pumpAll, MakeParameters("InputBuffer", ConstByteArrayParameter(string)));}
};
//! use the third constructor for an array source
typedef StringSource ArraySource;
//! RNG-based implementation of Source interface
class CRYPTOPP_DLL RandomNumberSource : public SourceTemplate<RandomNumberStore>
{

View File

@ -23,20 +23,6 @@ void AdditiveCipherTemplate<S>::UncheckedSetKey(const byte *key, unsigned int le
policy.CipherResynchronize(m_buffer, this->GetIVAndThrowIfInvalid(params));
}
template <class S>
byte AdditiveCipherTemplate<S>::GenerateByte()
{
PolicyInterface &policy = this->AccessPolicy();
if (m_leftOver == 0)
{
policy.WriteKeystream(m_buffer, policy.GetIterationsToBuffer());
m_leftOver = policy.GetBytesPerIteration();
}
return *(KeystreamBufferEnd()-m_leftOver--);
}
template <class S>
void AdditiveCipherTemplate<S>::GenerateBlock(byte *outString, size_t length)
{
@ -59,9 +45,7 @@ void AdditiveCipherTemplate<S>::GenerateBlock(byte *outString, size_t length)
if (length >= bytesPerIteration)
{
size_t iterations = length / bytesPerIteration;
policy.WriteKeystream(outString, iterations);
outString += iterations * bytesPerIteration;
length -= iterations * bytesPerIteration;

View File

@ -2,7 +2,7 @@
#define _CRT_SECURE_NO_DEPRECATE
#define CRYPTOPP_DEFAULT_NO_DLL
#define CRYPTOPP_ENABLE_NAMESPACE_WEAK
#define CRYPTOPP_ENABLE_NAMESPACE_WEAK 1
#include "dll.h"
#include "md5.h"
@ -355,7 +355,7 @@ int CRYPTOPP_API main(int argc, char *argv[])
void FIPS140_GenerateRandomFiles()
{
#ifdef OS_RNG_AVAILABLE
AutoSeededX917RNG<DES_EDE3> rng;
DefaultAutoSeededRNG rng;
RandomNumberStore store(rng, ULONG_MAX);
for (unsigned int i=0; i<100000; i++)
@ -374,7 +374,7 @@ SecByteBlock HexDecodeString(const char *hex)
return result;
}
RandomPool & GlobalRNG()
RandomNumberGenerator & GlobalRNG()
{
static RandomPool randomPool;
return randomPool;
@ -383,7 +383,7 @@ RandomPool & GlobalRNG()
void GenerateRSAKey(unsigned int keyLength, const char *privFilename, const char *pubFilename, const char *seed)
{
RandomPool randPool;
randPool.Put((byte *)seed, strlen(seed));
randPool.IncorporateEntropy((byte *)seed, strlen(seed));
RSAES_OAEP_SHA_Decryptor priv(randPool, keyLength);
HexEncoder privFile(new FileSink(privFilename));
@ -402,7 +402,7 @@ string RSAEncryptString(const char *pubFilename, const char *seed, const char *m
RSAES_OAEP_SHA_Encryptor pub(pubFile);
RandomPool randPool;
randPool.Put((byte *)seed, strlen(seed));
randPool.IncorporateEntropy((byte *)seed, strlen(seed));
string result;
StringSource(message, true, new PK_EncryptorFilter(randPool, pub, new HexEncoder(new StringSink(result))));
@ -544,7 +544,7 @@ void SecretShareFile(int threshold, int nShares, const char *filename, const cha
assert(nShares<=1000);
RandomPool rng;
rng.Put((byte *)seed, strlen(seed));
rng.IncorporateEntropy((byte *)seed, strlen(seed));
ChannelSwitch *channelSwitch;
FileSource source(filename, false, new SecretSharing(rng, threshold, nShares, channelSwitch = new ChannelSwitch));
@ -774,7 +774,7 @@ bool Validate(int alg, bool thorough, const char *seed)
}
cout << "Using seed: " << seed << endl << endl;
GlobalRNG().Put((const byte *)seed, strlen(seed));
GlobalRNG().IncorporateEntropy((const byte *)seed, strlen(seed));
switch (alg)
{
@ -843,6 +843,7 @@ bool Validate(int alg, bool thorough, const char *seed)
case 63: result = ValidateTTMAC(); break;
case 64: result = ValidateSalsa(); break;
case 65: result = ValidateSosemanuk(); break;
case 66: result = ValidateVMAC(); break;
default: return false;
}

View File

@ -2,7 +2,7 @@
#include "pch.h"
#define CRYPTOPP_ENABLE_NAMESPACE_WEAK
#define CRYPTOPP_ENABLE_NAMESPACE_WEAK 1
#include "blumshub.h"
#include "rsa.h"
#include "md2.h"
@ -39,11 +39,9 @@ class FixedRNG : public RandomNumberGenerator
public:
FixedRNG(BufferedTransformation &source) : m_source(source) {}
byte GenerateByte()
void GenerateBlock(byte *output, size_t size)
{
byte b;
m_source.Get(b);
return b;
m_source.Get(output, size);
}
private:

View File

@ -2,7 +2,6 @@
#define CRYPTOPP_VALIDATE_H
#include "cryptlib.h"
#include "randpool.h"
bool ValidateAll(bool thorough);
bool TestSettings();
@ -51,6 +50,7 @@ bool ValidateSHACAL2();
bool ValidateCamellia();
bool ValidateSalsa();
bool ValidateSosemanuk();
bool ValidateVMAC();
bool ValidateBBS();
bool ValidateDH();
@ -72,7 +72,7 @@ bool ValidateEC2N();
bool ValidateECDSA();
bool ValidateESIGN();
CryptoPP::RandomPool & GlobalRNG();
CryptoPP::RandomNumberGenerator & GlobalRNG();
bool RunTestDataFile(const char *filename);
#endif