00001
00002
00003
00004
00005
00006
00007
00008 #ifndef CRYPTOPP_MERSENNE_TWISTER_H
00009 #define CRYPTOPP_MERSENNE_TWISTER_H
00010
00011 #include "cryptlib.h"
00012 #include "secblock.h"
00013 #include "misc.h"
00014
00015 NAMESPACE_BEGIN(CryptoPP)
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027 template <unsigned int K, unsigned int M, unsigned int N, unsigned int F, unsigned long S>
00028 class MersenneTwister : public RandomNumberGenerator
00029 {
00030 public:
00031
00032
00033
00034
00035 MersenneTwister(unsigned long seed = S) : m_seed(seed), m_idx(N)
00036 {
00037 m_state[0] = seed;
00038 for (unsigned int i = 1; i < N+1; i++)
00039 m_state[i] = word32(F * (m_state[i-1] ^ (m_state[i-1] >> 30)) + i);
00040 }
00041
00042
00043
00044
00045
00046
00047
00048
00049 void GenerateBlock(byte *output, size_t size)
00050 {
00051
00052 word32 temp;
00053 for (size_t i=0; i < size/4; i++, output += 4)
00054 {
00055 #if defined(CRYPTOPP_ALLOW_UNALIGNED_DATA_ACCESS) && defined(IS_LITTLE_ENDIAN)
00056 *((word32*)output) = ByteReverse(NextMersenneWord());
00057 #elif defined(CRYPTOPP_ALLOW_UNALIGNED_DATA_ACCESS)
00058 *((word32*)output) = NextMersenneWord();
00059 #else
00060 temp = NextMersenneWord();
00061 output[3] = CRYPTOPP_GET_BYTE_AS_BYTE(temp, 0);
00062 output[2] = CRYPTOPP_GET_BYTE_AS_BYTE(temp, 1);
00063 output[1] = CRYPTOPP_GET_BYTE_AS_BYTE(temp, 2);
00064 output[0] = CRYPTOPP_GET_BYTE_AS_BYTE(temp, 3);
00065 #endif
00066 }
00067
00068
00069 if (size%4 == 0)
00070 {
00071
00072 *((volatile word32*)&temp) = 0;
00073 return;
00074 }
00075
00076
00077 temp = NextMersenneWord();
00078 switch (size%4)
00079 {
00080 case 3: output[2] = CRYPTOPP_GET_BYTE_AS_BYTE(temp, 1);
00081 case 2: output[1] = CRYPTOPP_GET_BYTE_AS_BYTE(temp, 2);
00082 case 1: output[0] = CRYPTOPP_GET_BYTE_AS_BYTE(temp, 3); break;
00083
00084 default: assert(0); ;;
00085 }
00086
00087
00088 *((volatile word32*)&temp) = 0;
00089 }
00090
00091
00092
00093
00094
00095 word32 GenerateWord32(word32 min=0, word32 max=0xffffffffL)
00096 {
00097 const word32 range = max-min;
00098 if (range == 0xffffffffL)
00099 return NextMersenneWord();
00100
00101 const int maxBits = BitPrecision(range);
00102 word32 value;
00103
00104 do{
00105 value = Crop(NextMersenneWord(), maxBits);
00106 } while (value > range);
00107
00108 return value+min;
00109 }
00110
00111
00112
00113
00114
00115
00116
00117 void DiscardBytes(size_t n)
00118 {
00119 for(size_t i=0; i < RoundUpToMultipleOf(n, 4U); i++)
00120 NextMersenneWord();
00121 }
00122
00123 protected:
00124
00125
00126
00127
00128
00129 word32 NextMersenneWord()
00130 {
00131 if (m_idx >= N) { Twist(); }
00132
00133 word32 temp = m_state[m_idx++];
00134
00135 temp ^= (temp >> 11);
00136 temp ^= (temp << 7) & 0x9D2C5680;
00137 temp ^= (temp << 15) & 0xEFC60000;
00138
00139 return temp ^ (temp >> 18);
00140 }
00141
00142
00143 void Twist()
00144 {
00145 static const unsigned long magic[2]={0x0UL, K};
00146 word32 kk, temp;
00147
00148 assert(N >= M);
00149 for (kk=0;kk<N-M;kk++)
00150 {
00151 temp = (m_state[kk] & 0x80000000)|(m_state[kk+1] & 0x7FFFFFFF);
00152 m_state[kk] = m_state[kk+M] ^ (temp >> 1) ^ magic[temp & 0x1UL];
00153 }
00154
00155 for (;kk<N-1;kk++)
00156 {
00157 temp = (m_state[kk] & 0x80000000)|(m_state[kk+1] & 0x7FFFFFFF);
00158 m_state[kk] = m_state[kk+(M-N)] ^ (temp >> 1) ^ magic[temp & 0x1UL];
00159 }
00160
00161 temp = (m_state[N-1] & 0x80000000)|(m_state[0] & 0x7FFFFFFF);
00162 m_state[N-1] = m_state[M-1] ^ (temp >> 1) ^ magic[temp & 0x1UL];
00163
00164
00165 m_idx = 0;
00166
00167
00168 *((volatile word32*)&temp) = 0;
00169 }
00170
00171 private:
00172
00173
00174 FixedSizeSecBlock<word32, N+1> m_state;
00175
00176 unsigned int m_seed;
00177
00178 unsigned int m_idx;
00179 };
00180
00181
00182
00183 typedef MersenneTwister<0x9908B0DF , 397, 624, 0x10DCD , 4537> MT19937;
00184
00185
00186
00187
00188 typedef MersenneTwister<0x9908B0DF , 397, 624, 0x6C078965 , 5489> MT19937ar;
00189
00190 NAMESPACE_END
00191
00192 #endif // CRYPTOPP_MERSENNE_TWISTER_H
00193