mirror of
https://github.com/shadps4-emu/ext-cryptopp.git
synced 2025-02-13 09:34:56 +00:00
Updated MersenneTwister tests
The tests now include the first 10 elements of the sequence to ensure a properly implemented algorithm and endianess correctness.
This commit is contained in:
parent
c1377b2955
commit
9225ca09cb
58
mersenne.h
58
mersenne.h
@ -26,7 +26,7 @@ NAMESPACE_BEGIN(CryptoPP)
|
||||
//! required quickly. It should not be used for cryptographic purposes.
|
||||
//! \sa MT19937, MT19937ar
|
||||
//! \since Crypto++ 5.6.3
|
||||
template <unsigned int K, unsigned int M, unsigned int N, unsigned int F, unsigned long S>
|
||||
template <unsigned int K, unsigned int M, unsigned int N, unsigned int F, word32 S>
|
||||
class MersenneTwister : public RandomNumberGenerator
|
||||
{
|
||||
public:
|
||||
@ -38,11 +38,26 @@ public:
|
||||
//! \param seed 32-bit seed
|
||||
//! \details Defaults to template parameter S due to changing algorithm
|
||||
//! parameters over time
|
||||
MersenneTwister(unsigned long seed = S) : m_seed(seed), m_idx(N)
|
||||
MersenneTwister(word32 seed = S) : m_seed(seed), m_idx(N)
|
||||
{
|
||||
m_state[0] = seed;
|
||||
for (unsigned int i = 1; i < N+1; i++)
|
||||
m_state[i] = word32(F * (m_state[i-1] ^ (m_state[i-1] >> 30)) + i);
|
||||
Reset(seed);
|
||||
}
|
||||
|
||||
bool CanIncorporateEntropy() const {return true;}
|
||||
|
||||
//! \brief Update RNG state with additional unpredictable values
|
||||
//! \param input the entropy to add to the generator
|
||||
//! \param length the size of the input buffer
|
||||
//! \details MersenneTwister uses the first 32-bits of <tt>input</tt> to reseed the
|
||||
//! generator. If fewer bytes are provided, then the seed is padded with 0's.
|
||||
void IncorporateEntropy(const byte *input, size_t length)
|
||||
{
|
||||
word32 temp = 0;
|
||||
::memcpy(&temp, input, STDMIN(sizeof(temp), length));
|
||||
Reset(temp);
|
||||
|
||||
// Wipe temp
|
||||
SecureWipeArray(&temp, 1);
|
||||
}
|
||||
|
||||
//! \brief Generate random array of bytes
|
||||
@ -58,24 +73,15 @@ public:
|
||||
word32 temp;
|
||||
for (size_t i=0; i < size/4; i++, output += 4)
|
||||
{
|
||||
#if defined(CRYPTOPP_ALLOW_UNALIGNED_DATA_ACCESS) && defined(IS_LITTLE_ENDIAN)
|
||||
*((word32*)output) = ByteReverse(NextMersenneWord());
|
||||
#elif defined(CRYPTOPP_ALLOW_UNALIGNED_DATA_ACCESS)
|
||||
*((word32*)output) = NextMersenneWord();
|
||||
#else
|
||||
temp = NextMersenneWord();
|
||||
output[3] = CRYPTOPP_GET_BYTE_AS_BYTE(temp, 0);
|
||||
output[2] = CRYPTOPP_GET_BYTE_AS_BYTE(temp, 1);
|
||||
output[1] = CRYPTOPP_GET_BYTE_AS_BYTE(temp, 2);
|
||||
output[0] = CRYPTOPP_GET_BYTE_AS_BYTE(temp, 3);
|
||||
#endif
|
||||
PutWord<word32>(false, LITTLE_ENDIAN_ORDER, output, temp);
|
||||
}
|
||||
|
||||
// No tail bytes
|
||||
if (size%4 == 0)
|
||||
{
|
||||
// Wipe temp
|
||||
*((volatile word32*)&temp) = 0;
|
||||
SecureWipeArray(&temp, 1);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -91,7 +97,7 @@ public:
|
||||
}
|
||||
|
||||
// Wipe temp
|
||||
*((volatile word32*)&temp) = 0;
|
||||
SecureWipeArray(&temp, 1);
|
||||
}
|
||||
|
||||
//! \brief Generate a random 32-bit word in the range min to max, inclusive
|
||||
@ -128,6 +134,16 @@ public:
|
||||
|
||||
protected:
|
||||
|
||||
void Reset(word32 seed)
|
||||
{
|
||||
m_seed = seed;
|
||||
m_idx = N;
|
||||
|
||||
m_state[0] = seed;
|
||||
for (unsigned int i = 1; i < N+1; i++)
|
||||
m_state[i] = word32(F * (m_state[i-1] ^ (m_state[i-1] >> 30)) + i);
|
||||
}
|
||||
|
||||
//! \brief Returns the next 32-bit word from the state array
|
||||
//! \returns the next 32-bit word from the state array
|
||||
//! \details fetches the next word frm the state array, performs bit operations on
|
||||
@ -148,7 +164,7 @@ protected:
|
||||
//! \brief Performs the twist operaton on the state array
|
||||
void Twist()
|
||||
{
|
||||
static const unsigned long magic[2]={0x0UL, K};
|
||||
static const word32 magic[2]={0x0UL, K};
|
||||
word32 kk, temp;
|
||||
|
||||
CRYPTOPP_ASSERT(N >= M);
|
||||
@ -171,7 +187,7 @@ protected:
|
||||
m_idx = 0;
|
||||
|
||||
// Wipe temp
|
||||
*((volatile word32*)&temp) = 0;
|
||||
SecureWipeArray(&temp, 1);
|
||||
}
|
||||
|
||||
private:
|
||||
@ -179,9 +195,9 @@ private:
|
||||
//! \brief 32-bit word state array of size N
|
||||
FixedSizeSecBlock<word32, N+1> m_state;
|
||||
//! \brief the value used to seed the generator
|
||||
unsigned int m_seed;
|
||||
word32 m_seed;
|
||||
//! \brief the current index into the state array
|
||||
unsigned int m_idx;
|
||||
word32 m_idx;
|
||||
};
|
||||
|
||||
//! \class MT19937
|
||||
|
@ -98,11 +98,6 @@ bool TestZinflate()
|
||||
return !fail;
|
||||
}
|
||||
|
||||
bool TestMersenne()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
bool TestDefaultEncryptor()
|
||||
{
|
||||
std::cout << "\nTesting DefaultEncryptor...\n\n";
|
||||
|
106
validat1.cpp
106
validat1.cpp
@ -45,6 +45,7 @@
|
||||
#include "osrng.h"
|
||||
#include "drbg.h"
|
||||
#include "rdrand.h"
|
||||
#include "mersenne.h"
|
||||
#include "zdeflate.h"
|
||||
#include "smartptr.h"
|
||||
#include "channels.h"
|
||||
@ -72,7 +73,9 @@ bool ValidateAll(bool thorough)
|
||||
pass=TestAutoSeeded() && pass;
|
||||
pass=TestAutoSeededX917() && pass;
|
||||
// pass=TestSecRandom() && pass;
|
||||
|
||||
#if (defined(CRYPTOPP_DEBUG) || defined(CRYPTOPP_COVERAGE)) && !defined(CRYPTOPP_IMPORTS)
|
||||
pass=TestMersenne() && pass;
|
||||
#endif
|
||||
#if (CRYPTOPP_BOOL_X86 || CRYPTOPP_BOOL_X32 || CRYPTOPP_BOOL_X64)
|
||||
pass=TestRDRAND() && pass;
|
||||
pass=TestRDSEED() && pass;
|
||||
@ -96,7 +99,6 @@ bool ValidateAll(bool thorough)
|
||||
// Additional tests due to no coverage
|
||||
pass=TestGzip() && pass;
|
||||
pass=TestZinflate() && pass;
|
||||
pass=TestMersenne() && pass;
|
||||
pass=TestDefaultEncryptor() && pass;
|
||||
pass=TestDefaultEncryptorWithMAC() && pass;
|
||||
pass=TestLegacyEncryptor() && pass;
|
||||
@ -449,7 +451,7 @@ bool TestOS_RNG()
|
||||
}
|
||||
else
|
||||
std::cout << "passed:";
|
||||
std::cout << " " << total << " generated bytes compressed to " << meter.GetTotalBytes() << " bytes by DEFLATE" << std::endl;
|
||||
std::cout << " " << total << " generated bytes compressed to " << meter.GetTotalBytes() << " bytes by DEFLATE\n";
|
||||
}
|
||||
else
|
||||
std::cout << "\nNo operating system provided blocking random number generator, skipping test." << std::endl;
|
||||
@ -474,7 +476,7 @@ bool TestOS_RNG()
|
||||
}
|
||||
else
|
||||
std::cout << "passed:";
|
||||
std::cout << " 100000 generated bytes compressed to " << meter.GetTotalBytes() << " bytes by DEFLATE" << std::endl;
|
||||
std::cout << " 100000 generated bytes compressed to " << meter.GetTotalBytes() << " bytes by DEFLATE\n";
|
||||
}
|
||||
else
|
||||
std::cout << "\nNo operating system provided nonblocking random number generator, skipping test." << std::endl;
|
||||
@ -511,7 +513,7 @@ bool TestAutoSeeded()
|
||||
}
|
||||
else
|
||||
std::cout << "passed:";
|
||||
std::cout << " 100000 generated bytes compressed to " << meter.GetTotalBytes() << " bytes by DEFLATE" << std::endl;
|
||||
std::cout << " 100000 generated bytes compressed to " << meter.GetTotalBytes() << " bytes by DEFLATE\n";
|
||||
|
||||
try
|
||||
{
|
||||
@ -575,7 +577,7 @@ bool TestAutoSeededX917()
|
||||
}
|
||||
else
|
||||
std::cout << "passed:";
|
||||
std::cout << " 100000 generated bytes compressed to " << meter.GetTotalBytes() << " bytes by DEFLATE" << std::endl;
|
||||
std::cout << " 100000 generated bytes compressed to " << meter.GetTotalBytes() << " bytes by DEFLATE\n";
|
||||
|
||||
try
|
||||
{
|
||||
@ -621,6 +623,90 @@ bool TestAutoSeededX917()
|
||||
}
|
||||
#endif // NO_OS_DEPENDENCE
|
||||
|
||||
#if (defined(CRYPTOPP_DEBUG) || defined(CRYPTOPP_COVERAGE)) && !defined(CRYPTOPP_IMPORTS)
|
||||
bool TestMersenne()
|
||||
{
|
||||
std::cout << "\nTesting Mersenne Twister...\n\n";
|
||||
|
||||
static const unsigned int ENTROPY_SIZE = 32;
|
||||
bool equal = true, generate = true, discard = true, incorporate = false;
|
||||
|
||||
// First 10; http://create.stephan-brumme.com/mersenne-twister/
|
||||
word32 result[10], expected[10] = {0xD091BB5C, 0x22AE9EF6,
|
||||
0xE7E1FAEE, 0xD5C31F79, 0x2082352C, 0xF807B7DF, 0xE9D30005,
|
||||
0x3895AFE1, 0xA1E24BBA, 0x4EE4092B};
|
||||
|
||||
MT19937ar prng;
|
||||
prng.GenerateBlock(reinterpret_cast<byte*>(result), sizeof(result));
|
||||
equal = (0 == ::memcmp(result, expected, sizeof(expected)));
|
||||
|
||||
if (equal)
|
||||
{
|
||||
std::cout << "passed:";
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cout << "FAILED:";
|
||||
equal = false;
|
||||
}
|
||||
std::cout << " Expected sequence from MT19937ar (2002 version)\n";
|
||||
|
||||
MeterFilter meter(new Redirector(TheBitBucket()));
|
||||
RandomNumberSource test(prng, 100000, true, new Deflator(new Redirector(meter)));
|
||||
|
||||
if (meter.GetTotalBytes() < 100000)
|
||||
{
|
||||
std::cout << "FAILED:";
|
||||
generate = false;
|
||||
}
|
||||
else
|
||||
std::cout << "passed:";
|
||||
std::cout << " 100000 generated bytes compressed to " << meter.GetTotalBytes() << " bytes by DEFLATE\n";
|
||||
|
||||
try
|
||||
{
|
||||
prng.DiscardBytes(100000);
|
||||
}
|
||||
catch(const Exception&)
|
||||
{
|
||||
discard = false;
|
||||
}
|
||||
|
||||
if (!discard)
|
||||
std::cout << "FAILED:";
|
||||
else
|
||||
std::cout << "passed:";
|
||||
std::cout << " discarded 10000 bytes\n";
|
||||
|
||||
try
|
||||
{
|
||||
if(prng.CanIncorporateEntropy())
|
||||
{
|
||||
SecByteBlock entropy(ENTROPY_SIZE);
|
||||
OS_GenerateRandomBlock(false, entropy, entropy.SizeInBytes());
|
||||
|
||||
prng.IncorporateEntropy(entropy, entropy.SizeInBytes());
|
||||
prng.IncorporateEntropy(entropy, entropy.SizeInBytes());
|
||||
prng.IncorporateEntropy(entropy, entropy.SizeInBytes());
|
||||
prng.IncorporateEntropy(entropy, entropy.SizeInBytes());
|
||||
|
||||
incorporate = true;
|
||||
}
|
||||
}
|
||||
catch(const Exception& /*ex*/)
|
||||
{
|
||||
}
|
||||
|
||||
if (!incorporate)
|
||||
std::cout << "FAILED:";
|
||||
else
|
||||
std::cout << "passed:";
|
||||
std::cout << " IncorporateEntropy with " << 4*ENTROPY_SIZE << " bytes" << std::endl;
|
||||
|
||||
return equal && generate && discard && incorporate;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if (CRYPTOPP_BOOL_X86 || CRYPTOPP_BOOL_X32 || CRYPTOPP_BOOL_X64)
|
||||
bool TestRDRAND()
|
||||
{
|
||||
@ -657,7 +743,7 @@ bool TestRDRAND()
|
||||
// Coverity finding, also see http://stackoverflow.com/a/34509163/608639.
|
||||
StreamState ss(std::cout);
|
||||
std::cout << std::setiosflags(std::ios::fixed) << std::setprecision(6);
|
||||
std::cout << " Maurer Randomness Test returned value " << mv << std::endl;
|
||||
std::cout << " Maurer Randomness Test returned value " << mv << "\n";
|
||||
|
||||
if (meter.GetTotalBytes() < SIZE)
|
||||
{
|
||||
@ -691,9 +777,6 @@ bool TestRDRAND()
|
||||
(void)rdrand.CanIncorporateEntropy();
|
||||
rdrand.IncorporateEntropy(NULLPTR, 0);
|
||||
|
||||
if (!(entropy && compress && discard))
|
||||
std::cout.flush();
|
||||
|
||||
return entropy && compress && discard;
|
||||
}
|
||||
#endif
|
||||
@ -769,9 +852,6 @@ bool TestRDSEED()
|
||||
(void)rdseed.CanIncorporateEntropy();
|
||||
rdseed.IncorporateEntropy(NULLPTR, 0);
|
||||
|
||||
if (!(entropy && compress && discard))
|
||||
std::cout.flush();
|
||||
|
||||
return entropy && compress && discard;
|
||||
}
|
||||
#endif
|
||||
|
Loading…
x
Reference in New Issue
Block a user