00001 // rng.h - written and placed in the public domain by Wei Dai 00002 00003 //! \file rng.h 00004 //! \brief Miscellaneous classes for RNGs 00005 //! \details This file contains miscellaneous classes for RNGs, including LC_RNG(), 00006 //! X917RNG() and MaurerRandomnessTest() 00007 //! \sa osrng.h, randpool.h 00008 00009 #ifndef CRYPTOPP_RNG_H 00010 #define CRYPTOPP_RNG_H 00011 00012 #include "cryptlib.h" 00013 #include "filters.h" 00014 #include "smartptr.h" 00015 00016 NAMESPACE_BEGIN(CryptoPP) 00017 00018 //! \brief Linear Congruential Generator (LCG) 00019 //! \details Originally propsed by William S. England. 00020 //! \warning LC_RNG is suitable for simulations, where uniformaly distrubuted numbers are 00021 //! required quickly. It should not be used for cryptographic purposes. 00022 class LC_RNG : public RandomNumberGenerator 00023 { 00024 public: 00025 //! \brief Construct a Linear Congruential Generator (LCG) 00026 //! \param init_seed the initial value for the generator 00027 LC_RNG(word32 init_seed) 00028 : seed(init_seed) {} 00029 00030 void GenerateBlock(byte *output, size_t size); 00031 00032 word32 GetSeed() {return seed;} 00033 00034 private: 00035 word32 seed; 00036 00037 static const word32 m; 00038 static const word32 q; 00039 static const word16 a; 00040 static const word16 r; 00041 }; 00042 00043 //! \class X917RNG 00044 //! \brief ANSI X9.17 RNG 00045 //! \details X917RNG is from ANSI X9.17 Appendix C. 00046 //! \sa AutoSeededX917RNG, DefaultAutoSeededRNG 00047 class CRYPTOPP_DLL X917RNG : public RandomNumberGenerator, public NotCopyable 00048 { 00049 public: 00050 //! \brief Construct a X917RNG 00051 //! \param cipher the block cipher to use for the generator 00052 //! \param seed a byte buffer to use as a seed 00053 //! \param deterministicTimeVector additional entropy 00054 //! \details <tt>cipher</tt> will be deleted by the destructor. <tt>seed</tt> must be at least 00055 //! BlockSize() in length. <tt>deterministicTimeVector = 0</tt> means obtain time vector 00056 //! from the system. 00057 //! \details When constructing an AutoSeededX917RNG, the generator must be keyed or an 00058 //! access violation will occur because the time vector is encrypted using the block cipher. 00059 //! To key the generator during constructions, perform the following: 00060 //! <pre> 00061 //! SecByteBlock key(AES::DEFAULT_KEYLENGTH), seed(AES::BLOCKSIZE); 00062 //! OS_GenerateRandomBlock(false, key, key.size()); 00063 //! OS_GenerateRandomBlock(false, seed, seed.size()); 00064 //! X917RNG prng(new AES::Encryption(key, AES::DEFAULT_KEYLENGTH), seed, NULL); 00065 //! </pre> 00066 //! \sa AutoSeededX917RNG 00067 X917RNG(BlockTransformation *cipher, const byte *seed, const byte *deterministicTimeVector = 0); 00068 00069 void GenerateIntoBufferedTransformation(BufferedTransformation &target, const std::string &channel, lword size); 00070 00071 private: 00072 member_ptr<BlockTransformation> cipher; 00073 const unsigned int S; // blocksize of cipher 00074 SecByteBlock dtbuf; // buffer for enciphered timestamp 00075 SecByteBlock randseed, m_lastBlock, m_deterministicTimeVector; 00076 }; 00077 00078 //! \class MaurerRandomnessTest 00079 //! \brief Maurer's Universal Statistical Test for Random Bit Generators 00080 //! \details This class implements Maurer's Universal Statistical Test for 00081 //! Random Bit Generators. It is intended for measuring the randomness of 00082 //! *PHYSICAL* RNGs. 00083 //! \details For more details see Maurer's paper in Journal of Cryptology, 1992. 00084 class MaurerRandomnessTest : public Bufferless<Sink> 00085 { 00086 public: 00087 MaurerRandomnessTest(); 00088 00089 size_t Put2(const byte *inString, size_t length, int messageEnd, bool blocking); 00090 00091 //! \brief Provides the number of bytes of input is needed by the test 00092 //! \returns how many more bytes of input is needed by the test 00093 // BytesNeeded() returns how many more bytes of input is needed by the test 00094 // GetTestValue() should not be called before BytesNeeded()==0 00095 unsigned int BytesNeeded() const {return n >= (Q+K) ? 0 : Q+K-n;} 00096 00097 // returns a number between 0.0 and 1.0, describing the quality of the 00098 // random numbers entered 00099 double GetTestValue() const; 00100 00101 private: 00102 enum {L=8, V=256, Q=2000, K=2000}; 00103 double sum; 00104 unsigned int n; 00105 unsigned int tab[V]; 00106 }; 00107 00108 NAMESPACE_END 00109 00110 #endif