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; 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) BlumBlumShub::BlumBlumShub(const Integer &p, const Integer &q, const Integer &seed)
: PublicBlumBlumShub(p*q, seed), : PublicBlumBlumShub(p*q, seed),
p(p), q(q), p(p), q(q),

View File

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

View File

@ -11,6 +11,8 @@
#include "fips140.h" #include "fips140.h"
#include "argnames.h" #include "argnames.h"
#include "fltrimpl.h" #include "fltrimpl.h"
#include "trdlocal.h"
#include "osrng.h"
#include <memory> #include <memory>
@ -91,6 +93,11 @@ const byte * SimpleKeyingInterface::GetIVAndThrowIfInvalid(const NameValuePairs
return iv; 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 void BlockTransformation::ProcessAndXorMultipleBlocks(const byte *inBlocks, const byte *xorBlocks, byte *outBlocks, size_t numberOfBlocks) const
{ {
unsigned int blockSize = BlockSize(); 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) void StreamTransformation::ProcessLastBlock(byte *outString, const byte *inString, size_t length)
{ {
assert(MinLastBlockSize() == 0); // this function should be overriden otherwise 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() unsigned int RandomNumberGenerator::GenerateBit()
{ {
return Parity(GenerateByte()); return GenerateByte() & 1;
} }
void RandomNumberGenerator::GenerateBlock(byte *output, size_t size) byte RandomNumberGenerator::GenerateByte()
{ {
while (size--) byte b;
*output++ = GenerateByte(); GenerateBlock(&b, 1);
return b;
} }
word32 RandomNumberGenerator::GenerateWord32(word32 min, word32 max) word32 RandomNumberGenerator::GenerateWord32(word32 min, word32 max)
{ {
word32 range = max-min; word32 range = max-min;
const int maxBytes = BytePrecision(range);
const int maxBits = BitPrecision(range); const int maxBits = BitPrecision(range);
word32 value; word32 value;
do do
{ {
value = 0; GenerateBlock((byte *)&value, sizeof(value));
for (int i=0; i<maxBytes; i++)
value = (value << 8) | GenerateByte();
value = Crop(value, maxBits); value = Crop(value, maxBits);
} while (value > range); } while (value > range);
return value+min; 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) void RandomNumberGenerator::DiscardBytes(size_t n)
{ {
while (n--) GenerateIntoBufferedTransformation(TheBitBucket(), BufferedTransformation::NULL_CHANNEL, n);
GenerateByte(); }
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() //! see NullRNG()
@ -156,7 +182,7 @@ class ClassNullRNG : public RandomNumberGenerator
{ {
public: public:
std::string AlgorithmName() const {return "NullRNG";} 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() RandomNumberGenerator & NullRNG()

View File

@ -17,7 +17,7 @@
<dt>Message Authentication Codes<dd> <dt>Message Authentication Codes<dd>
#MD5MAC, XMACC, HMAC, CBC_MAC, DMAC, PanamaMAC, TTMAC #MD5MAC, XMACC, HMAC, CBC_MAC, DMAC, PanamaMAC, TTMAC
<dt>Random Number Generators<dd> <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> <dt>Password-based Cryptography<dd>
PasswordBasedKeyDerivationFunction PasswordBasedKeyDerivationFunction
<dt>Public Key Cryptosystems<dd> <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> <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\> HMAC\<H\>, CBC_MAC\<DES_EDE2\>, CBC_MAC\<DES_EDE3\>
<dt>Random Number Generators<dd> <dt>Random Number Generators<dd>
AutoSeededX917RNG\<DES_EDE3\> DefaultAutoSeededRNG (AutoSeededX917RNG\<AES\>)
<dt>Key Agreement<dd> <dt>Key Agreement<dd>
#DH #DH
<dt>Public Key Cryptosystems<dd> <dt>Public Key Cryptosystems<dd>
@ -84,6 +84,8 @@ NAMESPACE_BEGIN(CryptoPP)
// forward declarations // forward declarations
class Integer; class Integer;
class RandomNumberGenerator;
class BufferedTransformation;
//! used to specify a direction for a cipher to operate in (encrypt or decrypt) //! used to specify a direction for a cipher to operate in (encrypt or decrypt)
enum CipherDir {ENCRYPTION, DECRYPTION}; 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. /*! 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. After calling it, you must call SetKey() or Resynchronize() before using this object again.
This method is not implemented on decryption objects. */ 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: protected:
virtual const Algorithm & GetAlgorithm() const =0; virtual const Algorithm & GetAlgorithm() const =0;
@ -438,7 +440,7 @@ public:
virtual unsigned int BlockSize() const =0; virtual unsigned int BlockSize() const =0;
//! block pointers must be divisible by this //! 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) //! returns true if this is a permutation (i.e. there is an inverse transformation)
virtual bool IsPermutation() const {return true;} virtual bool IsPermutation() const {return true;}
@ -624,24 +626,31 @@ typedef SymmetricCipher StreamCipher;
class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE RandomNumberGenerator : public Algorithm class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE RandomNumberGenerator : public Algorithm
{ {
public: 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 //! generate new random byte and return it
virtual byte GenerateByte() =0; virtual byte GenerateByte();
//! generate new random bit and return it //! 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(); virtual unsigned int GenerateBit();
//! generate a random 32 bit word in the range min to max, inclusive //! generate a random 32 bit word in the range min to max, inclusive
virtual word32 GenerateWord32(word32 a=0, word32 b=0xffffffffL); virtual word32 GenerateWord32(word32 a=0, word32 b=0xffffffffL);
//! generate random array of bytes //! generate random array of bytes
/*! Default implementation is to call GenerateByte() size times. */
virtual void GenerateBlock(byte *output, size_t size); virtual void GenerateBlock(byte *output, size_t size);
//! generate and discard n bytes //! generate and discard n bytes
/*! Default implementation is to call GenerateByte() n times. */
virtual void DiscardBytes(size_t n); 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 //! randomly shuffle the specified array, resulting permutation is uniformly distributed
template <class IT> void Shuffle(IT begin, IT end) 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) 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))); 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) if (!blocking)
throw NotImplemented("RandomNumberStore: nonblocking transfer is not implemented by this object"); throw NotImplemented("RandomNumberStore: nonblocking transfer is not implemented by this object");
lword transferMax = transferBytes; transferBytes = UnsignedMin(transferBytes, m_length - m_count);
for (transferBytes = 0; transferBytes<transferMax && m_count < (unsigned int)m_length; ++transferBytes, ++m_count) m_rng->GenerateIntoBufferedTransformation(target, channel, transferBytes);
target.ChannelPut(channel, m_rng->GenerateByte()); m_count += transferBytes;
return 0; return 0;
} }

View File

@ -565,6 +565,23 @@ private:
CRYPTOPP_DLL_TEMPLATE_CLASS StringSinkTemplate<std::string>; CRYPTOPP_DLL_TEMPLATE_CLASS StringSinkTemplate<std::string>;
typedef StringSinkTemplate<std::string> StringSink; 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 //! Copy input to a memory buffer
class CRYPTOPP_DLL ArraySink : public Bufferless<Sink> class CRYPTOPP_DLL ArraySink : public Bufferless<Sink>
{ {
@ -716,14 +733,20 @@ class CRYPTOPP_DLL StringSource : public SourceTemplate<StringStore>
public: public:
StringSource(BufferedTransformation *attachment = NULL) StringSource(BufferedTransformation *attachment = NULL)
: SourceTemplate<StringStore>(attachment) {} : SourceTemplate<StringStore>(attachment) {}
//! zero terminated string as source
StringSource(const char *string, bool pumpAll, BufferedTransformation *attachment = NULL) StringSource(const char *string, bool pumpAll, BufferedTransformation *attachment = NULL)
: SourceTemplate<StringStore>(attachment) {SourceInitialize(pumpAll, MakeParameters("InputBuffer", ConstByteArrayParameter(string)));} : 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) StringSource(const byte *string, size_t length, bool pumpAll, BufferedTransformation *attachment = NULL)
: SourceTemplate<StringStore>(attachment) {SourceInitialize(pumpAll, MakeParameters("InputBuffer", ConstByteArrayParameter(string, length)));} : SourceTemplate<StringStore>(attachment) {SourceInitialize(pumpAll, MakeParameters("InputBuffer", ConstByteArrayParameter(string, length)));}
//! std::string as source
StringSource(const std::string &string, bool pumpAll, BufferedTransformation *attachment = NULL) StringSource(const std::string &string, bool pumpAll, BufferedTransformation *attachment = NULL)
: SourceTemplate<StringStore>(attachment) {SourceInitialize(pumpAll, MakeParameters("InputBuffer", ConstByteArrayParameter(string)));} : 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 //! RNG-based implementation of Source interface
class CRYPTOPP_DLL RandomNumberSource : public SourceTemplate<RandomNumberStore> 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)); 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> template <class S>
void AdditiveCipherTemplate<S>::GenerateBlock(byte *outString, size_t length) 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) if (length >= bytesPerIteration)
{ {
size_t iterations = length / bytesPerIteration; size_t iterations = length / bytesPerIteration;
policy.WriteKeystream(outString, iterations); policy.WriteKeystream(outString, iterations);
outString += iterations * bytesPerIteration; outString += iterations * bytesPerIteration;
length -= iterations * bytesPerIteration; length -= iterations * bytesPerIteration;

View File

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

View File

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

View File

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