mirror of
https://github.com/shadps4-emu/ext-cryptopp.git
synced 2024-11-30 05:10:40 +00:00
5603661eec
We tweaked ChaCha to arrive at the IETF's implementation specified by RFC 7539. We are not sure how to handle block counter wrap. At the moment the caller is responsible for managing it. We were not able to find a reference implementation so we disable SIMD implementations like SSE, AVX, NEON and Power4. We need the wide block tests for corner cases to ensure our implementation is correct.
1306 lines
46 KiB
C++
1306 lines
46 KiB
C++
// validat3.cpp - originally written and placed in the public domain by Wei Dai
|
|
// CryptoPP::Test namespace added by JW in February 2017.
|
|
// Source files split in July 2018 to expedite compiles.
|
|
|
|
#include "pch.h"
|
|
|
|
#define CRYPTOPP_ENABLE_NAMESPACE_WEAK 1
|
|
|
|
#include "cryptlib.h"
|
|
#include "cpu.h"
|
|
#include "validate.h"
|
|
|
|
#include "rng.h"
|
|
#include "drbg.h"
|
|
#include "darn.h"
|
|
#include "osrng.h"
|
|
#include "rdrand.h"
|
|
#include "mersenne.h"
|
|
#include "padlkrng.h"
|
|
#include "randpool.h"
|
|
|
|
#include "gzip.h"
|
|
#include "channels.h"
|
|
|
|
#include <iostream>
|
|
#include <iomanip>
|
|
#include <sstream>
|
|
|
|
// Aggressive stack checking with VS2005 SP1 and above.
|
|
#if (_MSC_VER >= 1500)
|
|
# pragma strict_gs_check (on)
|
|
#endif
|
|
|
|
#if CRYPTOPP_MSC_VERSION
|
|
# pragma warning(disable: 4505 4355)
|
|
#endif
|
|
|
|
NAMESPACE_BEGIN(CryptoPP)
|
|
NAMESPACE_BEGIN(Test)
|
|
|
|
bool ValidateAll(bool thorough)
|
|
{
|
|
bool pass=TestSettings();
|
|
pass=TestOS_RNG() && pass;
|
|
pass=TestRandomPool() && pass;
|
|
#if !defined(NO_OS_DEPENDENCE) && defined(OS_RNG_AVAILABLE)
|
|
pass=TestAutoSeededX917() && pass;
|
|
#endif
|
|
// pass=TestSecRandom() && pass;
|
|
#if defined(CRYPTOPP_EXTENDED_VALIDATION)
|
|
pass=TestMersenne() && pass;
|
|
#endif
|
|
#if (CRYPTOPP_BOOL_X86 || CRYPTOPP_BOOL_X32 || CRYPTOPP_BOOL_X64)
|
|
pass=TestPadlockRNG() && pass;
|
|
pass=TestRDRAND() && pass;
|
|
pass=TestRDSEED() && pass;
|
|
#endif
|
|
#if (CRYPTOPP_BOOL_PPC32 || CRYPTOPP_BOOL_PPC64)
|
|
pass=TestDARN() && pass;
|
|
#endif
|
|
#if defined(CRYPTOPP_EXTENDED_VALIDATION)
|
|
// http://github.com/weidai11/cryptopp/issues/92
|
|
pass=TestSecBlock() && pass;
|
|
// http://github.com/weidai11/cryptopp/issues/602
|
|
pass=TestIntegerOps() && pass;
|
|
// http://github.com/weidai11/cryptopp/issues/336
|
|
pass=TestIntegerBitops() && pass;
|
|
// http://github.com/weidai11/cryptopp/issues/64
|
|
pass=TestPolynomialMod2() && pass;
|
|
// http://github.com/weidai11/cryptopp/issues/360
|
|
pass=TestRounding() && pass;
|
|
// http://github.com/weidai11/cryptopp/issues/242
|
|
pass=TestHuffmanCodes() && pass;
|
|
// http://github.com/weidai11/cryptopp/issues/346
|
|
pass=TestASN1Parse() && pass;
|
|
// https://github.com/weidai11/cryptopp/pull/334
|
|
pass=TestStringSink() && pass;
|
|
// Always part of the self tests; call in Debug
|
|
# if defined(CRYPTOPP_ALTIVEC_AVAILABLE)
|
|
pass=TestAltivecOps() && pass;
|
|
# endif
|
|
// Always part of the self tests; call in Debug
|
|
pass=ValidateBaseCode() && pass;
|
|
// https://github.com/weidai11/cryptopp/issues/562
|
|
pass=ValidateEncoder() && pass;
|
|
// Additional tests due to no coverage
|
|
pass=TestCompressors() && pass;
|
|
pass=TestSharing() && pass;
|
|
pass=TestEncryptors() && pass;
|
|
pass=TestX25519() && pass;
|
|
pass=TestEd25519() && pass;
|
|
#endif
|
|
|
|
pass=ValidateCRC32() && pass;
|
|
pass=ValidateCRC32C() && pass;
|
|
pass=ValidateAdler32() && pass;
|
|
pass=ValidateMD2() && pass;
|
|
#if defined(CRYPTOPP_EXTENDED_VALIDATION)
|
|
pass=ValidateMD4() && pass;
|
|
#endif
|
|
pass=ValidateMD5() && pass;
|
|
pass=ValidateSHA() && pass;
|
|
|
|
pass=RunTestDataFile("TestVectors/keccak.txt") && pass;
|
|
pass=RunTestDataFile("TestVectors/sha3.txt") && pass;
|
|
|
|
pass=ValidateHashDRBG() && pass;
|
|
pass=ValidateHmacDRBG() && pass;
|
|
|
|
pass=ValidateTiger() && pass;
|
|
pass=ValidateRIPEMD() && pass;
|
|
pass=ValidatePanama() && pass;
|
|
pass=ValidateWhirlpool() && pass;
|
|
|
|
pass=ValidateSM3() && pass;
|
|
pass=ValidateBLAKE2s() && pass;
|
|
pass=ValidateBLAKE2b() && pass;
|
|
pass=ValidatePoly1305() && pass;
|
|
pass=ValidateSipHash() && pass;
|
|
|
|
pass=ValidateHMAC() && pass;
|
|
pass=ValidateTTMAC() && pass;
|
|
|
|
pass=ValidatePBKDF() && pass;
|
|
pass=ValidateHKDF() && pass;
|
|
pass=ValidateScrypt() && pass;
|
|
|
|
pass=ValidateDES() && pass;
|
|
pass=ValidateCipherModes() && pass;
|
|
pass=ValidateIDEA() && pass;
|
|
pass=ValidateSAFER() && pass;
|
|
pass=ValidateRC2() && pass;
|
|
pass=ValidateARC4() && pass;
|
|
pass=ValidateRC5() && pass;
|
|
pass=ValidateBlowfish() && pass;
|
|
pass=ValidateThreeWay() && pass;
|
|
pass=ValidateGOST() && pass;
|
|
pass=ValidateSHARK() && pass;
|
|
pass=ValidateCAST() && pass;
|
|
pass=ValidateSquare() && pass;
|
|
pass=ValidateSKIPJACK() && pass;
|
|
pass=ValidateSEAL() && pass;
|
|
pass=ValidateRC6() && pass;
|
|
pass=ValidateMARS() && pass;
|
|
pass=ValidateRijndael() && pass;
|
|
pass=ValidateTwofish() && pass;
|
|
pass=ValidateSerpent() && pass;
|
|
pass=ValidateSHACAL2() && pass;
|
|
pass=ValidateARIA() && pass;
|
|
pass=ValidateCHAM() && pass;
|
|
pass=ValidateHIGHT() && pass;
|
|
pass=ValidateLEA() && pass;
|
|
pass=ValidateSIMECK() && pass;
|
|
pass=ValidateSIMON() && pass;
|
|
pass=ValidateSPECK() && pass;
|
|
pass=ValidateCamellia() && pass;
|
|
pass=ValidateSalsa() && pass;
|
|
pass=ValidateChaCha() && pass;
|
|
pass=ValidateChaChaTLS() && pass;
|
|
pass=ValidateSosemanuk() && pass;
|
|
pass=ValidateRabbit() && pass;
|
|
pass=ValidateHC128() && pass;
|
|
pass=ValidateHC256() && pass;
|
|
pass=RunTestDataFile("TestVectors/seed.txt") && pass;
|
|
pass=RunTestDataFile("TestVectors/threefish.txt") && pass;
|
|
pass=RunTestDataFile("TestVectors/kalyna.txt") && pass;
|
|
pass=RunTestDataFile("TestVectors/sm4.txt") && pass;
|
|
pass=ValidateVMAC() && pass;
|
|
pass=ValidateCCM() && pass;
|
|
pass=ValidateGCM() && pass;
|
|
pass=ValidateCMAC() && pass;
|
|
pass=RunTestDataFile("TestVectors/eax.txt") && pass;
|
|
|
|
pass=ValidateBBS() && pass;
|
|
pass=ValidateDH() && pass;
|
|
pass=ValidateX25519() && pass;
|
|
pass=ValidateMQV() && pass;
|
|
pass=ValidateHMQV() && pass;
|
|
pass=ValidateFHMQV() && pass;
|
|
pass=ValidateRSA() && pass;
|
|
pass=ValidateElGamal() && pass;
|
|
pass=ValidateDLIES() && pass;
|
|
pass=ValidateNR() && pass;
|
|
pass=ValidateDSA(thorough) && pass;
|
|
pass=ValidateLUC() && pass;
|
|
pass=ValidateLUC_DH() && pass;
|
|
pass=ValidateLUC_DL() && pass;
|
|
pass=ValidateXTR_DH() && pass;
|
|
pass=ValidateRabin() && pass;
|
|
pass=ValidateRW() && pass;
|
|
pass=ValidateECP() && pass;
|
|
pass=ValidateEC2N() && pass;
|
|
pass=ValidateECDSA() && pass;
|
|
pass=ValidateECDSA_RFC6979() && pass;
|
|
pass=ValidateECGDSA(thorough) && pass;
|
|
pass=ValidateESIGN() && pass;
|
|
|
|
pass=ValidateX25519() && pass;
|
|
pass=ValidateEd25519() && pass;
|
|
pass=ValidateNaCl() && pass;
|
|
|
|
if (pass)
|
|
std::cout << "\nAll tests passed!\n";
|
|
else
|
|
std::cout << "\nOops! Not all tests passed.\n";
|
|
|
|
return pass;
|
|
}
|
|
|
|
bool TestSettings()
|
|
{
|
|
bool pass = true;
|
|
|
|
std::cout << "\nTesting Settings...\n\n";
|
|
|
|
word32 w;
|
|
const byte s[] = "\x01\x02\x03\x04";
|
|
|
|
#if (_MSC_VER >= 1500)
|
|
std::copy(s, s+4,
|
|
stdext::make_checked_array_iterator(reinterpret_cast<byte*>(&w), sizeof(w)));
|
|
#else
|
|
std::copy(s, s+4, reinterpret_cast<byte*>(&w));
|
|
#endif
|
|
|
|
if (w == 0x04030201L)
|
|
{
|
|
#if (CRYPTOPP_LITTLE_ENDIAN)
|
|
std::cout << "passed: ";
|
|
#else
|
|
std::cout << "FAILED: ";
|
|
pass = false;
|
|
#endif
|
|
std::cout << "Your machine is little endian.\n";
|
|
}
|
|
else if (w == 0x01020304L)
|
|
{
|
|
#if (CRYPTOPP_BIG_ENDIAN)
|
|
std::cout << "passed: ";
|
|
#else
|
|
std::cout << "FAILED: ";
|
|
pass = false;
|
|
#endif
|
|
std::cout << "Your machine is big endian.\n";
|
|
}
|
|
else
|
|
{
|
|
std::cout << "FAILED: Your machine is neither big endian nor little endian.\n";
|
|
pass = false;
|
|
}
|
|
|
|
#if defined(CRYPTOPP_EXTENDED_VALIDATION)
|
|
// App and library versions, http://github.com/weidai11/cryptopp/issues/371
|
|
const int v1 = LibraryVersion();
|
|
const int v2 = HeaderVersion();
|
|
if(v1/10 == v2/10)
|
|
std::cout << "passed: ";
|
|
else
|
|
{
|
|
std::cout << "FAILED: ";
|
|
pass = false;
|
|
}
|
|
std::cout << "Library version (library): " << v1 << ", header version (app): " << v2 << "\n";
|
|
#endif
|
|
|
|
// CRYPTOPP_ALLOW_UNALIGNED_DATA_ACCESS removed at Issue 682.
|
|
std::cout << "passed: Aligned data access.\n";
|
|
|
|
if (sizeof(byte) == 1)
|
|
std::cout << "passed: ";
|
|
else
|
|
{
|
|
std::cout << "FAILED: ";
|
|
pass = false;
|
|
}
|
|
std::cout << "sizeof(byte) == " << sizeof(byte) << "\n";
|
|
|
|
if (sizeof(word16) == 2)
|
|
std::cout << "passed: ";
|
|
else
|
|
{
|
|
std::cout << "FAILED: ";
|
|
pass = false;
|
|
}
|
|
std::cout << "sizeof(word16) == " << sizeof(word16) << "\n";
|
|
|
|
if (sizeof(word32) == 4)
|
|
std::cout << "passed: ";
|
|
else
|
|
{
|
|
std::cout << "FAILED: ";
|
|
pass = false;
|
|
}
|
|
std::cout << "sizeof(word32) == " << sizeof(word32) << "\n";
|
|
|
|
if (sizeof(word64) == 8)
|
|
std::cout << "passed: ";
|
|
else
|
|
{
|
|
std::cout << "FAILED: ";
|
|
pass = false;
|
|
}
|
|
std::cout << "sizeof(word64) == " << sizeof(word64) << "\n";
|
|
|
|
#ifdef CRYPTOPP_WORD128_AVAILABLE
|
|
if (sizeof(word128) == 16)
|
|
std::cout << "passed: ";
|
|
else
|
|
{
|
|
std::cout << "FAILED: ";
|
|
pass = false;
|
|
}
|
|
std::cout << "sizeof(word128) == " << sizeof(word128) << "\n";
|
|
#endif
|
|
|
|
if (sizeof(word) == 2*sizeof(hword)
|
|
#ifdef CRYPTOPP_NATIVE_DWORD_AVAILABLE
|
|
&& sizeof(dword) == 2*sizeof(word)
|
|
#endif
|
|
)
|
|
std::cout << "passed: ";
|
|
else
|
|
{
|
|
std::cout << "FAILED: ";
|
|
pass = false;
|
|
}
|
|
std::cout << "sizeof(hword) == " << sizeof(hword) << ", sizeof(word) == " << sizeof(word);
|
|
#ifdef CRYPTOPP_NATIVE_DWORD_AVAILABLE
|
|
std::cout << ", sizeof(dword) == " << sizeof(dword);
|
|
#endif
|
|
std::cout << "\n";
|
|
|
|
const int cacheLineSize = GetCacheLineSize();
|
|
if (cacheLineSize < 16 || cacheLineSize > 256 || !IsPowerOf2(cacheLineSize))
|
|
{
|
|
std::cout << "FAILED: ";
|
|
pass = false;
|
|
}
|
|
else
|
|
std::cout << "passed: ";
|
|
std::cout << "cacheLineSize == " << cacheLineSize << "\n";
|
|
|
|
#ifdef CRYPTOPP_CPUID_AVAILABLE
|
|
bool hasSSE2 = HasSSE2();
|
|
bool hasSSSE3 = HasSSSE3();
|
|
bool hasSSE41 = HasSSE41();
|
|
bool hasSSE42 = HasSSE42();
|
|
bool hasAVX = HasAVX();
|
|
bool hasAVX2 = HasAVX2();
|
|
bool hasAESNI = HasAESNI();
|
|
bool hasCLMUL = HasCLMUL();
|
|
bool hasRDRAND = HasRDRAND();
|
|
bool hasRDSEED = HasRDSEED();
|
|
bool hasSHA = HasSHA();
|
|
bool isP4 = IsP4();
|
|
|
|
std::cout << "hasSSE2 == " << hasSSE2 << ", hasSSSE3 == " << hasSSSE3;
|
|
std::cout << ", hasSSE4.1 == " << hasSSE41 << ", hasSSE4.2 == " << hasSSE42;
|
|
std::cout << ", hasAVX == " << hasAVX << ", hasAVX2 == " << hasAVX2;
|
|
std::cout << ", hasAESNI == " << hasAESNI << ", hasCLMUL == " << hasCLMUL;
|
|
std::cout << ", hasRDRAND == " << hasRDRAND << ", hasRDSEED == " << hasRDSEED;
|
|
std::cout << ", hasSHA == " << hasSHA << ", isP4 == " << isP4;
|
|
std::cout << "\n";
|
|
|
|
#elif (CRYPTOPP_BOOL_ARM32 || CRYPTOPP_BOOL_ARMV8)
|
|
|
|
# if defined(__arm__)
|
|
bool hasARMv7 = HasARMv7();
|
|
bool hasNEON = HasNEON();
|
|
|
|
std::cout << "passed: ";
|
|
std::cout << "hasARMv7 == " << hasARMv7 << ", hasNEON == " << hasNEON << "\n";
|
|
# else // __arch32__ and __aarch64__
|
|
bool hasCRC32 = HasCRC32();
|
|
bool hasPMULL = HasPMULL();
|
|
bool hasAES = HasAES();
|
|
bool hasSHA1 = HasSHA1();
|
|
bool hasSHA2 = HasSHA2();
|
|
bool hasSHA512 = HasSHA512();
|
|
bool hasSHA3 = HasSHA3();
|
|
bool hasSM3 = HasSM3();
|
|
bool hasSM4 = HasSM4();
|
|
|
|
std::cout << "passed: ";
|
|
std::cout << ", hasCRC32 == " << hasCRC32 << ", hasAES == " << hasAES;
|
|
std::cout << ", hasPMULL == " << hasPMULL << ", hasSHA1 == " << hasSHA1;
|
|
std::cout << ", hasSHA2 == " << hasSHA2 << ", hasSHA512 == " << hasSHA512;
|
|
std::cout << ", hasSHA3 == " << hasSHA3 << ", hasSM3 == " << hasSM3;
|
|
std::cout << ", hasSM4 == " << hasSM4 << "\n";
|
|
# endif
|
|
|
|
#elif (CRYPTOPP_BOOL_PPC32 || CRYPTOPP_BOOL_PPC64)
|
|
const bool hasAltivec = HasAltivec();
|
|
const bool hasPower7 = HasPower7();
|
|
const bool hasPower8 = HasPower8();
|
|
const bool hasPower9 = HasPower9();
|
|
const bool hasPMULL = HasPMULL();
|
|
const bool hasAES = HasAES();
|
|
const bool hasSHA256 = HasSHA256();
|
|
const bool hasSHA512 = HasSHA512();
|
|
|
|
std::cout << "passed: ";
|
|
std::cout << "hasAltivec == " << hasAltivec << ", hasPower7 == " << hasPower7;
|
|
std::cout << ", hasPower8 == " << hasPower8 << ", hasPower9 == " << hasPower9;
|
|
std::cout << ", hasPMULL == " << hasPMULL << ", hasAES == " << hasAES;
|
|
std::cout << ", hasSHA256 == " << hasSHA256 << ", hasSHA512 == " << hasSHA512 << "\n";
|
|
|
|
#endif
|
|
|
|
if (!pass)
|
|
{
|
|
std::cerr << "Some critical setting in config.h is in error. Please fix it and recompile.\n";
|
|
std::abort();
|
|
}
|
|
return pass;
|
|
}
|
|
|
|
bool Test_RandomNumberGenerator(RandomNumberGenerator& prng, bool drain=false)
|
|
{
|
|
bool pass = true, result = true;
|
|
const size_t GENERATE_SIZE = 1024*10, DISCARD_SIZE = 256, ENTROPY_SIZE = 32;
|
|
|
|
if(drain)
|
|
{
|
|
RandomNumberSource(prng, UINT_MAX, true, new Redirector(TheBitBucket()));
|
|
}
|
|
|
|
MeterFilter meter(new Redirector(TheBitBucket()));
|
|
RandomNumberSource(prng, GENERATE_SIZE, true, new Deflator(new Redirector(meter)));
|
|
|
|
if (meter.GetTotalBytes() < GENERATE_SIZE)
|
|
{
|
|
pass = false;
|
|
result = false;
|
|
}
|
|
|
|
if (!pass)
|
|
std::cout << "FAILED:";
|
|
else
|
|
std::cout << "passed:";
|
|
std::cout << " " << GENERATE_SIZE << " generated bytes compressed to ";
|
|
std::cout << meter.GetTotalBytes() << " bytes by DEFLATE\n";
|
|
|
|
try
|
|
{
|
|
pass = true;
|
|
if(prng.CanIncorporateEntropy())
|
|
{
|
|
SecByteBlock entropy(ENTROPY_SIZE);
|
|
GlobalRNG().GenerateBlock(entropy, entropy.SizeInBytes());
|
|
|
|
prng.IncorporateEntropy(entropy, entropy.SizeInBytes());
|
|
prng.IncorporateEntropy(entropy, entropy.SizeInBytes()-1);
|
|
prng.IncorporateEntropy(entropy, entropy.SizeInBytes()-2);
|
|
prng.IncorporateEntropy(entropy, entropy.SizeInBytes()-3);
|
|
}
|
|
}
|
|
catch (const Exception& /*ex*/)
|
|
{
|
|
pass = false;
|
|
result = false;
|
|
}
|
|
|
|
if (!pass)
|
|
std::cout << "FAILED:";
|
|
else
|
|
std::cout << "passed:";
|
|
std::cout << " IncorporateEntropy with " << 4*ENTROPY_SIZE << " bytes\n";
|
|
|
|
try
|
|
{
|
|
word32 val = prng.GenerateWord32();
|
|
val = prng.GenerateWord32((val & 0xff), 0xffffffff - (val & 0xff));
|
|
|
|
prng.GenerateBlock(reinterpret_cast<byte*>(&val), 4);
|
|
prng.GenerateBlock(reinterpret_cast<byte*>(&val), 3);
|
|
prng.GenerateBlock(reinterpret_cast<byte*>(&val), 2);
|
|
prng.GenerateBlock(reinterpret_cast<byte*>(&val), 1);
|
|
}
|
|
catch (const Exception&)
|
|
{
|
|
pass = false;
|
|
result = false;
|
|
}
|
|
|
|
if (!pass)
|
|
std::cout << "FAILED:";
|
|
else
|
|
std::cout << "passed:";
|
|
std::cout << " GenerateWord32 and Crop\n";
|
|
|
|
try
|
|
{
|
|
pass = true;
|
|
prng.DiscardBytes(DISCARD_SIZE);
|
|
prng.DiscardBytes(DISCARD_SIZE-1);
|
|
prng.DiscardBytes(DISCARD_SIZE-2);
|
|
prng.DiscardBytes(DISCARD_SIZE-3);
|
|
}
|
|
catch (const Exception&)
|
|
{
|
|
pass = false;
|
|
result = false;
|
|
}
|
|
|
|
if (!pass)
|
|
std::cout << "FAILED:";
|
|
else
|
|
std::cout << "passed:";
|
|
std::cout << " DiscardBytes with " << 4*DISCARD_SIZE << " bytes\n";
|
|
|
|
// Miscellaneous for code coverage
|
|
(void)prng.AlgorithmName(); // "unknown"
|
|
|
|
CRYPTOPP_ASSERT(result);
|
|
return result;
|
|
}
|
|
|
|
bool TestOS_RNG()
|
|
{
|
|
bool pass = true;
|
|
|
|
member_ptr<RandomNumberGenerator> rng;
|
|
|
|
#ifdef BLOCKING_RNG_AVAILABLE
|
|
try {rng.reset(new BlockingRng);}
|
|
catch (const OS_RNG_Err &) {}
|
|
|
|
if (rng.get())
|
|
{
|
|
std::cout << "\nTesting operating system provided blocking random number generator...\n\n";
|
|
|
|
MeterFilter meter(new Redirector(TheBitBucket()));
|
|
RandomNumberSource test(*rng, UINT_MAX, false, new Deflator(new Redirector(meter)));
|
|
unsigned long total=0;
|
|
time_t t = time(NULLPTR), t1 = 0;
|
|
|
|
// check that it doesn't take too long to generate a reasonable amount of randomness
|
|
while (total < 16 && (t1 < 10 || total*8 > (unsigned long)t1))
|
|
{
|
|
test.Pump(1);
|
|
total += 1;
|
|
t1 = time(NULLPTR) - t;
|
|
}
|
|
|
|
if (total < 16)
|
|
{
|
|
std::cout << "FAILED:";
|
|
pass = false;
|
|
}
|
|
else
|
|
std::cout << "passed:";
|
|
std::cout << " it took " << long(t1) << " seconds to generate " << total << " bytes" << std::endl;
|
|
|
|
test.AttachedTransformation()->MessageEnd();
|
|
|
|
if (meter.GetTotalBytes() < total)
|
|
{
|
|
std::cout << "FAILED:";
|
|
pass = false;
|
|
}
|
|
else
|
|
std::cout << "passed:";
|
|
std::cout << " " << total << " generated bytes compressed to " << meter.GetTotalBytes() << " bytes by DEFLATE\n";
|
|
|
|
try
|
|
{
|
|
// Miscellaneous for code coverage
|
|
RandomNumberGenerator& prng = *rng.get();
|
|
(void)prng.AlgorithmName();
|
|
word32 result = prng.GenerateWord32();
|
|
result = prng.GenerateWord32((result & 0xff), 0xffffffff - (result & 0xff));
|
|
prng.GenerateBlock(reinterpret_cast<byte*>(&result), 4);
|
|
prng.GenerateBlock(reinterpret_cast<byte*>(&result), 3);
|
|
prng.GenerateBlock(reinterpret_cast<byte*>(&result), 2);
|
|
prng.GenerateBlock(reinterpret_cast<byte*>(&result), 1);
|
|
prng.GenerateBlock(reinterpret_cast<byte*>(&result), 0);
|
|
pass = true;
|
|
}
|
|
catch (const Exception&)
|
|
{
|
|
pass = false;
|
|
}
|
|
|
|
if (!pass)
|
|
std::cout << "FAILED:";
|
|
else
|
|
std::cout << "passed:";
|
|
std::cout << " GenerateWord32 and Crop\n";
|
|
}
|
|
else
|
|
std::cout << "\nNo operating system provided blocking random number generator, skipping test." << std::endl;
|
|
#endif
|
|
|
|
#ifdef NONBLOCKING_RNG_AVAILABLE
|
|
try {rng.reset(new NonblockingRng);}
|
|
catch (OS_RNG_Err &) {}
|
|
|
|
if (rng.get())
|
|
{
|
|
std::cout << "\nTesting operating system provided nonblocking random number generator...\n\n";
|
|
|
|
pass = Test_RandomNumberGenerator(*rng.get()) && pass;
|
|
}
|
|
else
|
|
std::cout << "\nNo operating system provided non-blocking random number generator, skipping test." << std::endl;
|
|
#endif
|
|
|
|
CRYPTOPP_ASSERT(pass);
|
|
return pass;
|
|
}
|
|
|
|
bool TestRandomPool()
|
|
{
|
|
member_ptr<RandomNumberGenerator> prng;
|
|
bool pass=true;
|
|
|
|
try {prng.reset(new RandomPool);}
|
|
catch (Exception &) {}
|
|
|
|
if(prng.get())
|
|
{
|
|
std::cout << "\nTesting RandomPool generator...\n\n";
|
|
pass = Test_RandomNumberGenerator(*prng.get()) && pass;
|
|
}
|
|
|
|
#if !defined(NO_OS_DEPENDENCE) && defined(OS_RNG_AVAILABLE)
|
|
try {prng.reset(new AutoSeededRandomPool);}
|
|
catch (Exception &) {}
|
|
|
|
if(prng.get())
|
|
{
|
|
std::cout << "\nTesting AutoSeeded RandomPool generator...\n\n";
|
|
pass = Test_RandomNumberGenerator(*prng.get()) && pass;
|
|
}
|
|
#endif
|
|
|
|
// Old, PGP 2.6 style RandomPool. Added because users were still having problems
|
|
// with it in 2017. The missing functionality was a barrier to upgrades.
|
|
try {prng.reset(new OldRandomPool);}
|
|
catch (Exception &) {}
|
|
|
|
if(prng.get())
|
|
{
|
|
std::cout << "\nTesting OldRandomPool generator...\n\n";
|
|
pass = Test_RandomNumberGenerator(*prng.get()) && pass;
|
|
|
|
// https://github.com/weidai11/cryptopp/issues/452
|
|
byte actual[32], expected[32] = {
|
|
0x41,0xD1,0xEF,0x8F,0x10,0x3C,0xE2,0x94,
|
|
0x47,0xC0,0xC3,0x86,0x66,0xBC,0x86,0x09,
|
|
0x57,0x77,0x73,0x91,0x57,0x4D,0x93,0x66,
|
|
0xD1,0x13,0xE1,0xBA,0x07,0x49,0x8F,0x75
|
|
};
|
|
|
|
prng.reset(new OldRandomPool);
|
|
RandomNumberGenerator& old = *prng.get();
|
|
|
|
SecByteBlock seed(384);
|
|
for (size_t i=0; i<384; ++i)
|
|
seed[i] = static_cast<byte>(i);
|
|
old.IncorporateEntropy(seed, seed.size());
|
|
|
|
old.GenerateBlock(actual, sizeof(actual));
|
|
pass = (0 == std::memcmp(actual, expected, sizeof(expected))) && pass;
|
|
|
|
if (!pass)
|
|
std::cout << "FAILED:";
|
|
else
|
|
std::cout << "passed:";
|
|
std::cout << " Expected sequence from PGP-style RandomPool (circa 2007)\n";
|
|
}
|
|
|
|
return pass;
|
|
}
|
|
|
|
#if !defined(NO_OS_DEPENDENCE) && defined(OS_RNG_AVAILABLE)
|
|
bool TestAutoSeededX917()
|
|
{
|
|
// This tests Auto-Seeding and GenerateIntoBufferedTransformation.
|
|
std::cout << "\nTesting AutoSeeded X917 generator...\n\n";
|
|
|
|
AutoSeededX917RNG<AES> prng;
|
|
return Test_RandomNumberGenerator(prng);
|
|
}
|
|
#endif
|
|
|
|
#if defined(CRYPTOPP_EXTENDED_VALIDATION)
|
|
bool TestMersenne()
|
|
{
|
|
std::cout << "\nTesting Mersenne Twister...\n\n";
|
|
|
|
member_ptr<RandomNumberGenerator> rng;
|
|
bool pass = true;
|
|
|
|
try {rng.reset(new MT19937ar);}
|
|
catch (const PadlockRNG_Err &) {}
|
|
|
|
if(rng.get())
|
|
{
|
|
pass = Test_RandomNumberGenerator(*rng.get());
|
|
}
|
|
|
|
// Reset state
|
|
try {rng.reset(new MT19937ar);}
|
|
catch (const PadlockRNG_Err &) {}
|
|
|
|
if(rng.get())
|
|
{
|
|
// First 10; http://create.stephan-brumme.com/mersenne-twister/
|
|
word32 result[10], expected[10] = {
|
|
0xD091BB5C, 0x22AE9EF6, 0xE7E1FAEE, 0xD5C31F79,
|
|
0x2082352C, 0xF807B7DF, 0xE9D30005, 0x3895AFE1,
|
|
0xA1E24BBA, 0x4EE4092B
|
|
};
|
|
|
|
rng->GenerateBlock(reinterpret_cast<byte*>(result), sizeof(result));
|
|
pass = (0 == std::memcmp(result, expected, sizeof(expected))) && pass;
|
|
|
|
if (!pass)
|
|
std::cout << "FAILED:";
|
|
else
|
|
std::cout << "passed:";
|
|
std::cout << " Expected sequence from MT19937\n";
|
|
}
|
|
|
|
return pass;
|
|
}
|
|
#endif
|
|
|
|
#if (CRYPTOPP_BOOL_X86 || CRYPTOPP_BOOL_X32 || CRYPTOPP_BOOL_X64)
|
|
bool TestPadlockRNG()
|
|
{
|
|
std::cout << "\nTesting Padlock RNG generator...\n\n";
|
|
|
|
member_ptr<RandomNumberGenerator> rng;
|
|
bool pass = true, fail;
|
|
|
|
try {rng.reset(new PadlockRNG);}
|
|
catch (const PadlockRNG_Err &) {}
|
|
|
|
if (rng.get())
|
|
{
|
|
PadlockRNG& padlock = dynamic_cast<PadlockRNG&>(*rng.get());
|
|
pass = Test_RandomNumberGenerator(padlock);
|
|
|
|
SecByteBlock zero(16), one(16), t(16);
|
|
std::memset(zero, 0x00, zero.size());
|
|
std::memset( one, 0xff, one.size());
|
|
|
|
// Cryptography Research, Inc tests
|
|
word32 oldDivisor = padlock.SetDivisor(0);
|
|
padlock.GenerateBlock(t, t.size());
|
|
word32 msr = padlock.GetMSR();
|
|
padlock.SetDivisor(oldDivisor);
|
|
|
|
// Bit 6 should be set
|
|
fail = !(msr & (1 << 6U));
|
|
pass &= !fail;
|
|
if (fail)
|
|
std::cout << "FAILED:";
|
|
else
|
|
std::cout << "passed:";
|
|
std::cout << " VIA RNG is activated\n";
|
|
|
|
// Bit 13 should be unset
|
|
fail = !!(msr & (1 << 13U));
|
|
pass &= !fail;
|
|
if (fail)
|
|
std::cout << "FAILED:";
|
|
else
|
|
std::cout << "passed:";
|
|
std::cout << " von Neumann corrector is activated\n";
|
|
|
|
// Bit 14 should be unset
|
|
fail = !!(msr & (1 << 14U));
|
|
pass &= !fail;
|
|
if (fail)
|
|
std::cout << "FAILED:";
|
|
else
|
|
std::cout << "passed:";
|
|
std::cout << " String filter is deactivated\n";
|
|
|
|
// Bit 12:10 should be unset
|
|
fail = !!(msr & (0x7 << 10U));
|
|
pass &= !fail;
|
|
if (fail)
|
|
std::cout << "FAILED:";
|
|
else
|
|
std::cout << "passed:";
|
|
std::cout << " Bias voltage is unmodified\n";
|
|
|
|
fail = false;
|
|
if (t == zero || t == one)
|
|
fail = true;
|
|
|
|
pass &= !fail;
|
|
if (fail)
|
|
std::cout << "FAILED:";
|
|
else
|
|
std::cout << "passed:";
|
|
std::cout << " All 0's or all 1's test\n";
|
|
}
|
|
else
|
|
std::cout << "Padlock RNG generator not available, skipping test.\n";
|
|
|
|
return pass;
|
|
}
|
|
|
|
bool TestRDRAND()
|
|
{
|
|
std::cout << "\nTesting RDRAND generator...\n\n";
|
|
|
|
bool pass = true;
|
|
member_ptr<RandomNumberGenerator> rng;
|
|
|
|
try {rng.reset(new RDRAND);}
|
|
catch (const RDRAND_Err &) {}
|
|
|
|
if (rng.get())
|
|
{
|
|
RDRAND& rdrand = dynamic_cast<RDRAND&>(*rng.get());
|
|
pass = Test_RandomNumberGenerator(rdrand) && pass;
|
|
|
|
MaurerRandomnessTest maurer;
|
|
const unsigned int SIZE = 1024*10;
|
|
RandomNumberSource(rdrand, SIZE, true, new Redirector(maurer));
|
|
|
|
CRYPTOPP_ASSERT(0 == maurer.BytesNeeded());
|
|
const double mv = maurer.GetTestValue();
|
|
if (mv < 0.98f)
|
|
pass = false;
|
|
|
|
std::ostringstream oss;
|
|
oss.flags(std::ios::fixed);
|
|
oss.precision(6);
|
|
|
|
if (!pass)
|
|
oss << "FAILED:";
|
|
else
|
|
oss << "passed:";
|
|
oss << " Maurer Randomness Test returned value " << mv << "\n";
|
|
std::cout << oss.str();
|
|
}
|
|
else
|
|
std::cout << "RDRAND generator not available, skipping test.\n";
|
|
|
|
return pass;
|
|
}
|
|
|
|
bool TestRDSEED()
|
|
{
|
|
std::cout << "\nTesting RDSEED generator...\n\n";
|
|
|
|
bool pass = true;
|
|
member_ptr<RandomNumberGenerator> rng;
|
|
|
|
try {rng.reset(new RDSEED);}
|
|
catch (const RDSEED_Err &) {}
|
|
|
|
if (rng.get())
|
|
{
|
|
RDSEED& rdseed = dynamic_cast<RDSEED&>(*rng.get());
|
|
pass = Test_RandomNumberGenerator(rdseed) && pass;
|
|
|
|
MaurerRandomnessTest maurer;
|
|
const unsigned int SIZE = 1024*10;
|
|
RandomNumberSource(rdseed, SIZE, true, new Redirector(maurer));
|
|
|
|
CRYPTOPP_ASSERT(0 == maurer.BytesNeeded());
|
|
const double mv = maurer.GetTestValue();
|
|
if (mv < 0.98f)
|
|
pass = false;
|
|
|
|
std::ostringstream oss;
|
|
oss.flags(std::ios::fixed);
|
|
oss.precision(6);
|
|
|
|
if (!pass)
|
|
oss << "FAILED:";
|
|
else
|
|
oss << "passed:";
|
|
oss << " Maurer Randomness Test returned value " << mv << "\n";
|
|
std::cout << oss.str();
|
|
}
|
|
else
|
|
std::cout << "RDSEED generator not available, skipping test.\n";
|
|
|
|
return pass;
|
|
}
|
|
#endif // x86, x32, or x64
|
|
|
|
#if (CRYPTOPP_BOOL_PPC32 || CRYPTOPP_BOOL_PPC64)
|
|
bool TestDARN()
|
|
{
|
|
std::cout << "\nTesting DARN generator...\n\n";
|
|
|
|
bool pass = true;
|
|
member_ptr<RandomNumberGenerator> rng;
|
|
|
|
try {rng.reset(new DARN);}
|
|
catch (const DARN_Err &) {}
|
|
|
|
if (rng.get())
|
|
{
|
|
DARN& darn = dynamic_cast<DARN&>(*rng.get());
|
|
pass = Test_RandomNumberGenerator(darn) && pass;
|
|
|
|
MaurerRandomnessTest maurer;
|
|
const unsigned int SIZE = 1024*10;
|
|
RandomNumberSource(darn, SIZE, true, new Redirector(maurer));
|
|
|
|
CRYPTOPP_ASSERT(0 == maurer.BytesNeeded());
|
|
const double mv = maurer.GetTestValue();
|
|
if (mv < 0.98f)
|
|
pass = false;
|
|
|
|
std::ostringstream oss;
|
|
oss.flags(std::ios::fixed);
|
|
oss.precision(6);
|
|
|
|
if (!pass)
|
|
oss << "FAILED:";
|
|
else
|
|
oss << "passed:";
|
|
oss << " Maurer Randomness Test returned value " << mv << "\n";
|
|
std::cout << oss.str();
|
|
}
|
|
else
|
|
std::cout << "DARN generator not available, skipping test.\n";
|
|
|
|
return pass;
|
|
}
|
|
#endif // PPC32 or PPC64
|
|
|
|
bool ValidateHashDRBG()
|
|
{
|
|
std::cout << "\nTesting NIST Hash DRBGs...\n\n";
|
|
bool pass=true, fail;
|
|
|
|
// # CAVS 14.3
|
|
// # DRBG800-90A information for "drbg_pr"
|
|
// # Generated on Tue Apr 02 15:32:09 2013
|
|
|
|
{
|
|
// [SHA-1], [PredictionResistance = False], [EntropyInputLen = 128], [NonceLen = 64]
|
|
// [PersonalizationStringLen = 0], [AdditionalInputLen = 0], [ReturnedBitsLen = 640]
|
|
const byte entropy1[] = "\x16\x10\xb8\x28\xcc\xd2\x7d\xe0\x8c\xee\xa0\x32\xa2\x0e\x92\x08";
|
|
const byte entropy2[] = "\x72\xd2\x8c\x90\x8e\xda\xf9\xa4\xd1\xe5\x26\xd8\xf2\xde\xd5\x44";
|
|
const byte nonce[] = "\x49\x2c\xf1\x70\x92\x42\xf6\xb5";
|
|
|
|
Hash_DRBG<SHA1, 128/8, 440/8> drbg(entropy1, 16, nonce, 8);
|
|
drbg.IncorporateEntropy(entropy2, 16);
|
|
|
|
SecByteBlock result(80);
|
|
drbg.GenerateBlock(result, result.size());
|
|
drbg.GenerateBlock(result, result.size());
|
|
|
|
const byte expected[] = "\x56\xF3\x3D\x4F\xDB\xB9\xA5\xB6\x4D\x26\x23\x44\x97\xE9\xDC\xB8\x77\x98\xC6\x8D"
|
|
"\x08\xF7\xC4\x11\x99\xD4\xBD\xDF\x97\xEB\xBF\x6C\xB5\x55\x0E\x5D\x14\x9F\xF4\xD5"
|
|
"\xBD\x0F\x05\xF2\x5A\x69\x88\xC1\x74\x36\x39\x62\x27\x18\x4A\xF8\x4A\x56\x43\x35"
|
|
"\x65\x8E\x2F\x85\x72\xBE\xA3\x33\xEE\xE2\xAB\xFF\x22\xFF\xA6\xDE\x3E\x22\xAC\xA2";
|
|
|
|
fail = !!memcmp(result, expected, 640/8);
|
|
pass = !fail && pass;
|
|
|
|
std::cout << (fail ? "FAILED " : "passed ") << "Hash_DRBG SHA1/128/440 (COUNT=0, E=16, N=8)\n";
|
|
}
|
|
|
|
{
|
|
// [SHA-1], [PredictionResistance = False], [EntropyInputLen = 128], [NonceLen = 64]
|
|
// [PersonalizationStringLen = 0], [AdditionalInputLen = 0], [ReturnedBitsLen = 640]
|
|
const byte entropy1[] = "\x55\x08\x75\xb7\x4e\xc1\x1f\x90\x67\x78\xa3\x1a\x37\xa3\x29\xfd";
|
|
const byte entropy2[] = "\x96\xc6\x39\xec\x14\x9f\x6b\x28\xe2\x79\x3b\xb9\x37\x9e\x60\x67";
|
|
const byte nonce[] = "\x08\xdd\x8c\xd3\x5b\xfa\x00\x94";
|
|
|
|
Hash_DRBG<SHA1, 128/8, 440/8> drbg(entropy1, 16, nonce, 8);
|
|
drbg.IncorporateEntropy(entropy2, 16);
|
|
|
|
SecByteBlock result(80);
|
|
drbg.GenerateBlock(result, result.size());
|
|
drbg.GenerateBlock(result, result.size());
|
|
|
|
const byte expected[] = "\xEE\x44\xC6\xCF\x2C\x0C\x73\xA8\xAC\x4C\xA5\x6C\x0E\x71\x2C\xA5\x50\x9A\x19\x5D"
|
|
"\xE4\x5B\x8D\x2B\xC9\x40\xA7\xDB\x66\xC3\xEB\x2A\xA1\xBD\xB4\xDD\x76\x85\x12\x45"
|
|
"\x80\x2E\x68\x05\x4A\xAB\xA8\x7C\xD6\x3A\xD3\xE5\xC9\x7C\x06\xE7\xA3\x9F\xF6\xF9"
|
|
"\x8E\xB3\xD9\x72\xD4\x11\x35\xE5\xE7\x46\x1B\x49\x9C\x56\x45\x6A\xBE\x7F\x77\xD4";
|
|
|
|
fail = !!memcmp(result, expected, 640/8);
|
|
pass = !fail && pass;
|
|
|
|
std::cout << (fail ? "FAILED " : "passed ") << "Hash_DRBG SHA1/128/440 (COUNT=1, E=16, N=8)\n";
|
|
}
|
|
|
|
{
|
|
// [SHA-1], [PredictionResistance = False], [EntropyInputLen = 128], [NonceLen = 64]
|
|
// [PersonalizationStringLen = 0], [AdditionalInputLen = 128], [ReturnedBitsLen = 640]
|
|
const byte entropy1[] = "\xd9\xba\xb5\xce\xdc\xa9\x6f\x61\x78\xd6\x45\x09\xa0\xdf\xdc\x5e";
|
|
const byte entropy2[] = "\xc6\xba\xd0\x74\xc5\x90\x67\x86\xf5\xe1\xf3\x20\x99\xf5\xb4\x91";
|
|
const byte nonce[] = "\xda\xd8\x98\x94\x14\x45\x0e\x01";
|
|
const byte additional1[] = "\x3e\x6b\xf4\x6f\x4d\xaa\x38\x25\xd7\x19\x4e\x69\x4e\x77\x52\xf7";
|
|
const byte additional2[] = "\x04\xfa\x28\x95\xaa\x5a\x6f\x8c\x57\x43\x34\x3b\x80\x5e\x5e\xa4";
|
|
const byte additional3[] = "\xdf\x5d\xc4\x59\xdf\xf0\x2a\xa2\xf0\x52\xd7\x21\xec\x60\x72\x30";
|
|
|
|
Hash_DRBG<SHA1, 128/8, 440/8> drbg(entropy1, 16, nonce, 8);
|
|
drbg.IncorporateEntropy(entropy2, 16, additional1, 16);
|
|
|
|
SecByteBlock result(80);
|
|
drbg.GenerateBlock(additional2, 16, result, result.size());
|
|
drbg.GenerateBlock(additional3, 16, result, result.size());
|
|
|
|
const byte expected[] = "\xC4\x8B\x89\xF9\xDA\x3F\x74\x82\x45\x55\x5D\x5D\x03\x3B\x69\x3D\xD7\x1A\x4D\xF5"
|
|
"\x69\x02\x05\xCE\xFC\xD7\x20\x11\x3C\xC2\x4E\x09\x89\x36\xFF\x5E\x77\xB5\x41\x53"
|
|
"\x58\x70\xB3\x39\x46\x8C\xDD\x8D\x6F\xAF\x8C\x56\x16\x3A\x70\x0A\x75\xB2\x3E\x59"
|
|
"\x9B\x5A\xEC\xF1\x6F\x3B\xAF\x6D\x5F\x24\x19\x97\x1F\x24\xF4\x46\x72\x0F\xEA\xBE";
|
|
|
|
fail = !!memcmp(result, expected, 640/8);
|
|
pass = !fail && pass;
|
|
|
|
std::cout << (fail ? "FAILED " : "passed ") << "Hash_DRBG SHA1/128/440 (C0UNT=0, E=16, N=8, A=16)\n";
|
|
}
|
|
|
|
{
|
|
// [SHA-1], [PredictionResistance = False], [EntropyInputLen = 128], [NonceLen = 64]
|
|
// [PersonalizationStringLen = 0], [AdditionalInputLen = 128], [ReturnedBitsLen = 640]
|
|
const byte entropy1[] = "\x28\x00\x0f\xbf\xf0\x57\x22\xc8\x89\x93\x06\xc2\x9b\x50\x78\x0a";
|
|
const byte entropy2[] = "\xd9\x95\x8e\x8c\x08\xaf\x5a\x41\x0e\x91\x9b\xdf\x40\x8e\x5a\x0a";
|
|
const byte nonce[] = "\x11\x2f\x6e\x20\xc0\x29\xed\x3f";
|
|
const byte additional1[] = "\x91\x1d\x96\x5b\x6e\x77\xa9\x6c\xfe\x3f\xf2\xd2\xe3\x0e\x2a\x86";
|
|
const byte additional2[] = "\xcd\x44\xd9\x96\xab\x05\xef\xe8\x27\xd3\x65\x83\xf1\x43\x18\x2c";
|
|
const byte additional3[] = "\x9f\x6a\x31\x82\x12\x18\x4e\x70\xaf\x5d\x00\x14\x1f\x42\x82\xf6";
|
|
|
|
Hash_DRBG<SHA1, 128/8, 440/8> drbg(entropy1, 16, nonce, 8);
|
|
drbg.IncorporateEntropy(entropy2, 16, additional1, 16);
|
|
|
|
SecByteBlock result(80);
|
|
drbg.GenerateBlock(additional2, 16, result, result.size());
|
|
drbg.GenerateBlock(additional3, 16, result, result.size());
|
|
|
|
const byte expected[] = "\x54\x61\x65\x92\x1E\x71\x4A\xD1\x39\x02\x2F\x97\xD2\x65\x3F\x0D\x47\x69\xB1\x4A"
|
|
"\x3E\x6E\xEF\xA1\xA0\x16\xD6\x9E\xA9\x7F\x51\xD5\x81\xDC\xAA\xCF\x66\xF9\xB1\xE8"
|
|
"\x06\x94\x41\xD6\xB5\xC5\x44\x60\x54\x07\xE8\xE7\xDC\x1C\xD8\xE4\x70\xAD\x84\x77"
|
|
"\x5A\x65\x31\xBE\xE0\xFC\x81\x36\xE2\x8F\x0B\xFE\xEB\xE1\x98\x62\x7E\x98\xE0\xC1";
|
|
|
|
fail = !!memcmp(result, expected, 640/8);
|
|
pass = !fail && pass;
|
|
|
|
std::cout << (fail ? "FAILED " : "passed ") << "Hash_DRBG SHA1/128/440 (C0UNT=1, E=16, N=8, A=16)\n";
|
|
}
|
|
|
|
{
|
|
// [SHA-1], [PredictionResistance = False], [EntropyInputLen = 128], [NonceLen = 64]
|
|
// [PersonalizationStringLen = 128], [AdditionalInputLen = 0], [ReturnedBitsLen = 640]
|
|
const byte entropy1[] = "\x0e\xd5\x4c\xef\x44\x5c\x61\x7d\x58\x86\xe0\x34\xc0\x97\x36\xd4";
|
|
const byte entropy2[] = "\x0b\x90\x27\xb8\x01\xe7\xf7\x2e\xe6\xec\x50\x2b\x8b\x6b\xd7\x11";
|
|
const byte nonce[] = "\x2c\x8b\x07\x13\x55\x6c\x91\x6f";
|
|
const byte personalization[] = "\xf3\x37\x8e\xa1\x45\x34\x30\x41\x12\xe0\xee\x57\xe9\xb3\x4a\x4b";
|
|
|
|
Hash_DRBG<SHA1, 128/8, 440/8> drbg(entropy1, 16, nonce, 8, personalization, 16);
|
|
drbg.IncorporateEntropy(entropy2, 16);
|
|
|
|
SecByteBlock result(80);
|
|
drbg.GenerateBlock(result, result.size());
|
|
drbg.GenerateBlock(result, result.size());
|
|
|
|
const byte expected[] = "\x55\x37\x0E\xD4\xB7\xCA\xA4\xBB\x67\x3A\x0F\x58\x40\xB3\x9F\x76\x4E\xDA\xD2\x85"
|
|
"\xD5\x6F\x01\x8F\x2D\xA7\x54\x4B\x0E\x66\x39\x62\x35\x96\x1D\xB7\xF6\xDA\xFB\x30"
|
|
"\xB6\xC5\x68\xD8\x40\x6E\x2B\xD4\x3D\x23\xEB\x0F\x10\xBA\x5F\x24\x9C\xC9\xE9\x4A"
|
|
"\xD3\xA5\xF1\xDF\xA4\xF2\xB4\x80\x40\x91\xED\x8C\xD6\x6D\xE7\xB7\x53\xB2\x09\xD5";
|
|
|
|
fail = !!memcmp(result, expected, 640/8);
|
|
pass = !fail && pass;
|
|
|
|
std::cout << (fail ? "FAILED " : "passed ") << "Hash_DRBG SHA1/128/440 (C0UNT=0, E=16, N=8, A=0, P=16)\n";
|
|
}
|
|
|
|
{
|
|
// [SHA-1], [PredictionResistance = False], [EntropyInputLen = 128], [NonceLen = 64]
|
|
// [PersonalizationStringLen = 128], [AdditionalInputLen = 0], [ReturnedBitsLen = 640]
|
|
const byte entropy1[] = "\x8f\x2a\x33\x9f\x5f\x45\x21\x30\xa4\x57\xa9\x6f\xcb\xe2\xe6\x36";
|
|
const byte entropy2[] = "\x1f\xff\x9e\x4f\x4d\x66\x3a\x1f\x9e\x85\x4a\x15\x7d\xad\x97\xe0";
|
|
const byte nonce[] = "\x0e\xd0\xe9\xa5\xa4\x54\x8a\xd0";
|
|
const byte personalization[] = "\x45\xe4\xb3\xe2\x63\x87\x62\x57\x2c\x99\xe4\x03\x45\xd6\x32\x6f";
|
|
|
|
Hash_DRBG<SHA1, 128/8, 440/8> drbg(entropy1, 16, nonce, 8, personalization, 16);
|
|
drbg.IncorporateEntropy(entropy2, 16);
|
|
|
|
SecByteBlock result(80);
|
|
drbg.GenerateBlock(result, result.size());
|
|
drbg.GenerateBlock(result, result.size());
|
|
|
|
const byte expected[] = "\x4F\xE8\x96\x41\xF8\xD3\x95\xC4\x43\x6E\xFB\xF8\x05\x75\xA7\x69\x74\x6E\x0C\x5F"
|
|
"\x54\x14\x35\xB4\xE6\xA6\xB3\x40\x7C\xA2\xC4\x42\xA2\x2F\x66\x28\x28\xCF\x4A\xA8"
|
|
"\xDC\x16\xBC\x5F\x69\xE5\xBB\x05\xD1\x43\x8F\x80\xAB\xC5\x8F\x9C\x3F\x75\x57\xEB"
|
|
"\x44\x0D\xF5\x0C\xF4\x95\x23\x94\x67\x11\x55\x98\x14\x43\xFF\x13\x14\x85\x5A\xBC";
|
|
|
|
fail = !!memcmp(result, expected, 640/8);
|
|
pass = !fail && pass;
|
|
|
|
std::cout << (fail ? "FAILED " : "passed ") << "Hash_DRBG SHA1/128/440 (C0UNT=1, E=16, N=8, A=0, P=16)\n";
|
|
}
|
|
|
|
{
|
|
// [SHA-1], [PredictionResistance = False], [EntropyInputLen = 128], [NonceLen = 64]
|
|
// [PersonalizationStringLen = 128], [AdditionalInputLen = 16], [ReturnedBitsLen = 640]
|
|
const byte entropy1[] = "\x48\xa1\xa9\x7c\xcc\x49\xd7\xcc\xf6\xe3\x78\xa2\xf1\x6b\x0f\xcd";
|
|
const byte entropy2[] = "\xba\x5d\xa6\x79\x12\x37\x24\x3f\xea\x60\x50\xf5\xb9\x9e\xcd\xf5";
|
|
const byte nonce[] = "\xb0\x91\xd2\xec\x12\xa8\x39\xfe";
|
|
const byte personalization[] = "\x3d\xc1\x6c\x1a\xdd\x9c\xac\x4e\xbb\xb0\xb8\x89\xe4\x3b\x9e\x12";
|
|
const byte additional1[] = "\xd1\x23\xe3\x8e\x4c\x97\xe8\x29\x94\xa9\x71\x7a\xc6\xf1\x7c\x08";
|
|
const byte additional2[] = "\x80\x0b\xed\x97\x29\xcf\xad\xe6\x68\x0d\xfe\x53\xba\x0c\x1e\x28";
|
|
const byte additional3[] = "\x25\x1e\x66\xb9\xe3\x85\xac\x1c\x17\xfb\x77\x1b\x5d\xc7\x6c\xf2";
|
|
|
|
Hash_DRBG<SHA1, 128/8, 440/8> drbg(entropy1, 16, nonce, 8, personalization, 16);
|
|
drbg.IncorporateEntropy(entropy2, 16, additional1, 16);
|
|
|
|
SecByteBlock result(80);
|
|
drbg.GenerateBlock(additional2, 16, result, result.size());
|
|
drbg.GenerateBlock(additional3, 16, result, result.size());
|
|
|
|
const byte expected[] = "\xA1\xB2\xEE\x86\xA0\xF1\xDA\xB7\x93\x83\x13\x3A\x62\x27\x99\x08\x95\x3A\x1C\x9A"
|
|
"\x98\x77\x60\x12\x11\x19\xCC\x78\xB8\x51\x2B\xD5\x37\xA1\x9D\xB9\x73\xCA\x39\x7A"
|
|
"\xDD\x92\x33\x78\x6D\x5D\x41\xFF\xFA\xE9\x80\x59\x04\x85\x21\xE2\x52\x84\xBC\x6F"
|
|
"\xDB\x97\xF3\x4E\x6A\x12\x7A\xCD\x41\x0F\x50\x68\x28\x46\xBE\x56\x9E\x9A\x6B\xC8";
|
|
|
|
fail = !!memcmp(result, expected, 640/8);
|
|
pass = !fail && pass;
|
|
|
|
std::cout << (fail ? "FAILED " : "passed ") << "Hash_DRBG SHA1/128/440 (C0UNT=0, E=16, N=8, A=16, P=16)\n";
|
|
}
|
|
|
|
{
|
|
// [SHA-1], [PredictionResistance = False], [EntropyInputLen = 128], [NonceLen = 64]
|
|
// [PersonalizationStringLen = 128], [AdditionalInputLen = 16], [ReturnedBitsLen = 640]
|
|
const byte entropy1[] = "\x3b\xcb\xa8\x3b\x6d\xfb\x06\x79\x80\xef\xc3\x1e\xd2\x9e\x68\x57";
|
|
const byte entropy2[] = "\x2f\xc9\x87\x49\x19\xcb\x52\x4a\x5b\xac\xf0\xcd\x96\x4e\xf8\x6e";
|
|
const byte nonce[] = "\x23\xfe\x20\x9f\xac\x70\x45\xde";
|
|
const byte personalization[] = "\xf2\x25\xf4\xd9\x6b\x9c\xab\x49\x1e\xab\x18\x14\xb2\x5e\x78\xef";
|
|
const byte additional1[] = "\x57\x5b\x9a\x11\x32\x7a\xab\x89\x08\xfe\x46\x11\x9a\xed\x14\x5d";
|
|
const byte additional2[] = "\x5d\x19\xcd\xed\xb7\xe3\x44\x66\x8e\x11\x42\x96\xa0\x38\xb1\x7f";
|
|
const byte additional3[] = "\x2b\xaf\xa0\x15\xed\xdd\x5c\x76\x32\x75\x34\x35\xd1\x37\x72\xfb";
|
|
|
|
Hash_DRBG<SHA1, 128/8, 440/8> drbg(entropy1, 16, nonce, 8, personalization, 16);
|
|
drbg.IncorporateEntropy(entropy2, 16, additional1, 16);
|
|
|
|
SecByteBlock result(80);
|
|
drbg.GenerateBlock(additional2, 16, result, result.size());
|
|
drbg.GenerateBlock(additional3, 16, result, result.size());
|
|
|
|
const byte expected[] = "\x1D\x12\xEB\x6D\x42\x60\xBD\xFB\xA7\x99\xB8\x53\xCC\x6F\x19\xB1\x64\xFE\x2F\x55"
|
|
"\xBA\xA2\x1C\x89\xD4\xD0\xE9\xB4\xBA\xD4\xE5\xF8\xC5\x30\x06\x41\xBA\xC4\x3D\x2B"
|
|
"\x73\x91\x27\xE9\x31\xC0\x55\x55\x11\xE8\xB6\x57\x02\x0D\xCE\x90\xAC\x31\xB9\x00"
|
|
"\x31\xC1\xD4\x4F\xE7\x12\x3B\xCC\x85\x16\x2F\x12\x8F\xB2\xDF\x84\x4E\xF7\x06\xBE";
|
|
|
|
fail = !!memcmp(result, expected, 640/8);
|
|
pass = !fail && pass;
|
|
|
|
std::cout << (fail ? "FAILED " : "passed ") << "Hash_DRBG SHA1/128/440 (C0UNT=1, E=16, N=8, A=16, P=16)\n";
|
|
}
|
|
|
|
{
|
|
// [SHA-256], [PredictionResistance = False], [EntropyInputLen = 256], [NonceLen = 128]
|
|
// [PersonalizationStringLen = 256], [AdditionalInputLen = 256], [ReturnedBitsLen = 1024]
|
|
const byte entropy1[] = "\xf0\x5b\xab\x56\xc7\xac\x6e\xeb\x31\xa0\xcf\x8a\x8a\x06\x2a\x49\x17\x9a\xcf\x3c\x5b\x20\x4d\x60\xdd\x7a\x3e\xb7\x8f\x5d\x8e\x3b";
|
|
const byte entropy2[] = "\x72\xd4\x02\xa2\x59\x7b\x98\xa3\xb8\xf5\x0b\x71\x6c\x63\xc6\xdb\xa7\x3a\x07\xe6\x54\x89\x06\x3f\x02\xc5\x32\xf5\xda\xc4\xd4\x18";
|
|
const byte nonce[] = "\xa1\x45\x08\x53\x41\x68\xb6\x88\xf0\x5f\x1e\x41\x9c\x88\xcc\x30";
|
|
const byte personalization[] = "\xa0\x34\x72\xf4\x04\x59\xe2\x87\xea\xcb\x21\x32\xc0\xb6\x54\x02\x7d\xa3\xe6\x69\x25\xb4\x21\x25\x54\xc4\x48\x18\x8c\x0e\x86\x01";
|
|
const byte additional1[] = "\xb3\x0d\x28\xaf\xa4\x11\x6b\xbc\x13\x6e\x65\x09\xb5\x82\xa6\x93\xbc\x91\x71\x40\x46\xaa\x3c\x66\xb6\x77\xb3\xef\xf9\xad\xfd\x49";
|
|
const byte additional2[] = "\x77\xfd\x1d\x68\xd6\xa4\xdd\xd5\xf3\x27\x25\x2d\x3f\x6b\xdf\xee\x8c\x35\xce\xd3\x83\xbe\xaf\xc9\x32\x77\xef\xf2\x1b\x6f\xf4\x1b";
|
|
const byte additional3[] = "\x59\xa0\x1f\xf8\x6a\x58\x72\x1e\x85\xd2\xf8\x3f\x73\x99\xf1\x96\x4e\x27\xf8\x7f\xcd\x1b\xf5\xc1\xeb\xf3\x37\x10\x9b\x13\xbd\x24";
|
|
|
|
Hash_DRBG<SHA256, 128/8, 440/8> drbg(entropy1, 32, nonce, 16, personalization, 32);
|
|
drbg.IncorporateEntropy(entropy2, 32, additional1, 32);
|
|
|
|
SecByteBlock result(128);
|
|
drbg.GenerateBlock(additional2, 32, result, result.size());
|
|
drbg.GenerateBlock(additional3, 32, result, result.size());
|
|
|
|
const byte expected[] = "\xFF\x27\x96\x38\x5C\x32\xBF\x84\x3D\xFA\xBB\xF0\x3E\x70\x5A\x39\xCB\xA3\x4C\xF1"
|
|
"\x4F\xAE\xC3\x05\x63\xDF\x5A\xDD\xBD\x2D\x35\x83\xF5\x7E\x05\xF9\x40\x30\x56\x18"
|
|
"\xF2\x00\x88\x14\x03\xC2\xD9\x81\x36\x39\xE6\x67\x55\xDC\xFC\x4E\x88\xEA\x71\xDD"
|
|
"\xB2\x25\x2E\x09\x91\x49\x40\xEB\xE2\x3D\x63\x44\xA0\xF4\xDB\x5E\xE8\x39\xE6\x70"
|
|
"\xEC\x47\x24\x3F\xA0\xFC\xF5\x13\x61\xCE\x53\x98\xAA\xBF\xB4\x19\x1B\xFE\xD5\x00"
|
|
"\xE1\x03\x3A\x76\x54\xFF\xD7\x24\x70\x5E\x8C\xB2\x41\x7D\x92\x0A\x2F\x4F\x27\xB8"
|
|
"\x45\x13\x7F\xFB\x87\x90\xA9\x49";
|
|
|
|
fail = !!memcmp(result, expected, 1024/8);
|
|
pass = !fail && pass;
|
|
|
|
std::cout << (fail ? "FAILED " : "passed ") << "Hash_DRBG SHA256/128/440 (C0UNT=0, E=32, N=16, A=32, P=32)\n";
|
|
}
|
|
|
|
{
|
|
// [SHA-256], [PredictionResistance = False], [EntropyInputLen = 256], [NonceLen = 128]
|
|
// [PersonalizationStringLen = 256], [AdditionalInputLen = 256], [ReturnedBitsLen = 1024]
|
|
const byte entropy1[] = "\xfe\x61\x50\x79\xf1\xad\x2a\x71\xea\x7f\x0f\x5a\x14\x34\xee\xc8\x46\x35\x54\x4a\x95\x6a\x4f\xbd\x64\xff\xba\xf6\x1d\x34\x61\x83";
|
|
const byte entropy2[] = "\x18\x89\x7b\xd8\x3e\xff\x38\xab\xb5\x6e\x82\xa8\x1b\x8c\x5e\x59\x3c\x3d\x85\x62\x2a\xe2\x88\xe5\xb2\xc6\xc5\xd2\xad\x7d\xc9\x45";
|
|
const byte nonce[] = "\x9d\xa7\x87\x56\xb7\x49\x17\x02\x4c\xd2\x00\x65\x11\x9b\xe8\x7e";
|
|
const byte personalization[] = "\x77\x5d\xbf\x32\xf3\x5c\xf3\x51\xf4\xb8\x1c\xd3\xfa\x7f\x65\x0b\xcf\x31\x88\xa1\x25\x57\x0c\xdd\xac\xaa\xfe\xa1\x7b\x3b\x29\xbc";
|
|
const byte additional1[] = "\xef\x96\xc7\x9c\xb1\x73\x1d\x82\x85\x0a\x6b\xca\x9b\x5c\x34\x39\xba\xd3\x4e\x4d\x82\x6f\x35\x9f\x61\x5c\xf6\xf2\xa3\x3e\x91\x05";
|
|
const byte additional2[] = "\xaf\x25\xc4\x6e\x21\xfc\xc3\xaf\x1f\xbb\xf8\x76\xb4\x57\xab\x1a\x94\x0a\x85\x16\x47\x81\xa4\xab\xda\xc8\xab\xca\xd0\x84\xda\xae";
|
|
const byte additional3[] = "\x59\x5b\x44\x94\x38\x86\x36\xff\x8e\x45\x1a\x0c\x42\xc8\xcc\x21\x06\x38\x3a\xc5\xa6\x30\x96\xb9\x14\x81\xb3\xa1\x2b\xc8\xcd\xf6";
|
|
|
|
Hash_DRBG<SHA256, 128/8, 440/8> drbg(entropy1, 32, nonce, 16, personalization, 32);
|
|
drbg.IncorporateEntropy(entropy2, 32, additional1, 32);
|
|
|
|
SecByteBlock result(128);
|
|
drbg.GenerateBlock(additional2, 32, result, result.size());
|
|
drbg.GenerateBlock(additional3, 32, result, result.size());
|
|
|
|
const byte expected[] = "\x8B\x1C\x9C\x76\xC4\x9B\x3B\xAE\xFD\x6E\xEB\x6C\xFF\xA3\xA1\x03\x3A\x8C\xAF\x09"
|
|
"\xFE\xBD\x44\x00\xFC\x0F\xD3\xA8\x26\x9C\xEE\x01\xAC\xE3\x73\x0E\xBE\xDA\x9A\xC6"
|
|
"\x23\x44\x6D\xA1\x56\x94\x29\xEC\x4B\xCD\x01\x84\x32\x25\xEF\x00\x91\x0B\xCC\xF3"
|
|
"\x06\x3B\x80\xF5\x46\xAC\xD2\xED\x5F\x70\x2B\x56\x2F\x21\x0A\xE9\x80\x87\x38\xAD"
|
|
"\xB0\x2A\xEB\x27\xF2\xD9\x20\x2A\x66\x0E\xF5\xC9\x20\x4A\xB4\x3C\xCE\xD6\x24\x97"
|
|
"\xDB\xB1\xED\x94\x12\x6A\x2F\x03\x98\x4A\xD4\xD1\x72\xF3\x7A\x66\x74\x7E\x2A\x5B"
|
|
"\xDE\xEF\x43\xBC\xB9\x8C\x49\x01";
|
|
|
|
fail = !!memcmp(result, expected, 1024/8);
|
|
pass = !fail && pass;
|
|
|
|
std::cout << (fail ? "FAILED " : "passed ") << "Hash_DRBG SHA256/128/440 (C0UNT=1, E=32, N=16, A=32, P=32)\n";
|
|
}
|
|
|
|
{
|
|
// [SHA-512], [PredictionResistance = False], [EntropyInputLen = 256], [NonceLen = 128]
|
|
// [PersonalizationStringLen = 256], [AdditionalInputLen = 256], [ReturnedBitsLen = 2048]
|
|
const byte entropy1[] = "\x55\x4e\x8f\xfd\xc4\x9a\xd8\xf9\x9a\xe5\xd5\xf8\x1a\xf5\xda\xfb\x7f\x75\x53\xd7\xcb\x56\x8e\xa7\x3c\xc0\x82\xdd\x80\x76\x25\xc0";
|
|
const byte entropy2[] = "\x78\x07\x3e\x86\x79\x4b\x10\x95\x88\xf4\x22\xf9\xbd\x04\x7e\xc0\xce\xab\xd6\x78\x6b\xdf\xe2\x89\xb3\x16\x43\x9c\x32\x2d\xb2\x59";
|
|
const byte nonce[] = "\xf0\x89\x78\xde\x2d\xc2\xcd\xd9\xc0\xfd\x3d\x84\xd9\x8b\x8e\x8e";
|
|
const byte personalization[] = "\x3e\x52\x7a\xb5\x81\x2b\x0c\x0e\x98\x2a\x95\x78\x93\x98\xd9\xeb\xf1\xb9\xeb\xd6\x1d\x02\x05\xed\x42\x21\x2d\x24\xb8\x37\xf8\x41";
|
|
const byte additional1[] = "\xf2\x6b\xb1\xef\x30\xca\x8f\x97\xc0\x19\xd0\x79\xe5\xc6\x5e\xae\xd1\xa3\x9a\x52\xaf\x12\xe8\x28\xde\x03\x70\x79\x9a\x70\x11\x8b";
|
|
const byte additional2[] = "\xb0\x9d\xb5\xa8\x45\xec\x79\x7a\x4b\x60\x7e\xe4\xd5\x58\x56\x70\x35\x20\x9b\xd8\xe5\x01\x6c\x78\xff\x1f\x6b\x93\xbf\x7c\x34\xca";
|
|
const byte additional3[] = "\x45\x92\x2f\xb3\x5a\xd0\x6a\x84\x5f\xc9\xca\x16\x4a\x42\xbb\x59\x84\xb4\x38\x57\xa9\x16\x23\x48\xf0\x2f\x51\x61\x24\x35\xb8\x62";
|
|
|
|
Hash_DRBG<SHA512, 256/8, 888/8> drbg(entropy1, 32, nonce, 16, personalization, 32);
|
|
drbg.IncorporateEntropy(entropy2, 32, additional1, 32);
|
|
|
|
SecByteBlock result(256);
|
|
drbg.GenerateBlock(additional2, 32, result, result.size());
|
|
drbg.GenerateBlock(additional3, 32, result, result.size());
|
|
|
|
const byte expected[] = "\x1F\x20\x83\x9E\x22\x55\x3B\x1E\x6C\xD4\xF6\x3A\x47\xC3\x99\x54\x0F\x69\xA3\xBB"
|
|
"\x37\x47\xA0\x2A\x12\xAC\xC7\x00\x85\xC5\xCC\xF4\x7B\x12\x5A\x4A\xEA\xED\x2F\xE5"
|
|
"\x31\x51\x0D\xC1\x8E\x50\x29\xE2\xA6\xCB\x8F\x34\xBA\xDA\x8B\x47\x32\x33\x81\xF1"
|
|
"\x2D\xF6\x8B\x73\x8C\xFF\x15\xC8\x8E\x8C\x31\x48\xFA\xC3\xC4\x9F\x52\x81\x23\xC2"
|
|
"\x2A\x83\xBD\xF1\x44\xEF\x15\x49\x93\x44\x83\x6B\x37\x5D\xBB\xFF\x72\xD2\x86\x96"
|
|
"\x62\xF8\x4D\x12\x3B\x16\xCB\xAC\xA1\x00\x12\x1F\x94\xA8\xD5\xAE\x9A\x9E\xDA\xC8"
|
|
"\xD7\x6D\x59\x33\xFD\x55\xC9\xCC\x5B\xAD\x39\x73\xB5\x13\x8B\x96\xDF\xDB\xF5\x90"
|
|
"\x81\xDF\x68\x6A\x30\x72\x42\xF2\x74\xAE\x7F\x1F\x7F\xFE\x8B\x3D\x49\x38\x98\x34"
|
|
"\x7C\x63\x46\x6E\xAF\xFA\xCB\x06\x06\x08\xE6\xC8\x35\x3C\x68\xB8\xCC\x9D\x5C\xDF"
|
|
"\xDB\xC0\x41\x44\x48\xE6\x11\xD4\x78\x50\x81\x91\xED\x1D\x75\xF3\xBD\x79\xFF\x1E"
|
|
"\x37\xAF\xC6\x5D\x49\xD6\x5C\xAC\x5B\xCB\xD6\x91\x37\x51\xFA\x98\x70\xFC\x32\xB3"
|
|
"\xF2\x86\xE4\xED\x74\xF2\x5D\x8B\x6C\x4D\xB8\xDE\xD8\x4A\xD6\x5E\xD6\x6D\xAE\xB1"
|
|
"\x1B\xA2\x94\x52\x54\xAD\x3C\x3D\x25\xBD\x12\x46\x3C\xA0\x45\x9D";
|
|
|
|
fail = !!memcmp(result, expected, 2048/8);
|
|
pass = !fail && pass;
|
|
|
|
std::cout << (fail ? "FAILED " : "passed ") << "Hash_DRBG SHA512/256/888 (C0UNT=0, E=32, N=16, A=32, P=32)\n";
|
|
}
|
|
|
|
{
|
|
// [SHA-512], [PredictionResistance = False], [EntropyInputLen = 256], [NonceLen = 128]
|
|
// [PersonalizationStringLen = 256], [AdditionalInputLen = 256], [ReturnedBitsLen = 2048]
|
|
const byte entropy1[] = "\x0c\x9f\xcd\x06\x21\x3c\xb2\xf6\x3c\xdf\x79\x76\x4b\x46\x74\xfc\xdf\x68\xb0\xff\xae\xc7\x21\x8a\xa2\xaf\x4e\x4c\xb9\xe6\x60\x78";
|
|
const byte entropy2[] = "\x75\xb8\x49\x54\xdf\x30\x10\x16\x2c\x06\x8c\x12\xeb\x6c\x1d\x03\x64\x5c\xad\x10\x5c\xc3\x17\x69\xb2\x5a\xc1\x7c\xb8\x33\x5b\x45";
|
|
const byte nonce[] = "\x43\x1c\x4d\x65\x93\x96\xad\xdc\xc1\x6d\x17\x9f\x7f\x57\x24\x4d";
|
|
const byte personalization[] = "\x7e\x54\xbd\x87\xd2\x0a\x95\xd7\xc4\x0c\x3b\x1b\x32\x15\x26\xd2\x06\x67\xa4\xac\xc1\xaa\xfb\x55\x91\x68\x2c\xb5\xc9\xcd\x66\x05";
|
|
const byte additional1[] = "\xd5\x74\x9e\x56\xfb\x5f\xf3\xf8\x2c\x73\x2b\x7a\x83\xe0\xde\x06\x85\x0b\xf0\x57\x50\xc8\x55\x60\x4a\x41\x4f\x86\xb1\x68\x14\x03";
|
|
const byte additional2[] = "\x9a\x83\xbb\x06\xdf\x4d\x53\x89\xf5\x3f\x24\xff\xf7\xcd\x0c\xcf\x4f\xbe\x46\x79\x8e\xce\x82\xa8\xc4\x6b\x5f\x8e\x58\x32\x62\x23";
|
|
const byte additional3[] = "\x48\x13\xc4\x95\x10\x99\xdd\x7f\xd4\x77\x3c\x9b\x8a\xa4\x1c\x3d\xb0\x93\x92\x50\xba\x23\x98\xef\x4b\x1b\xd2\x53\xc1\x61\xda\xc6";
|
|
|
|
Hash_DRBG<SHA512, 256/8, 888/8> drbg(entropy1, 32, nonce, 16, personalization, 32);
|
|
drbg.IncorporateEntropy(entropy2, 32, additional1, 32);
|
|
|
|
SecByteBlock result(256);
|
|
drbg.GenerateBlock(additional2, 32, result, result.size());
|
|
drbg.GenerateBlock(additional3, 32, result, result.size());
|
|
|
|
const byte expected[] = "\xE1\x7E\x4B\xEE\xD1\x65\x4F\xB2\xFC\xC8\xE8\xD7\xC6\x72\x7D\xD2\xE3\x15\x73\xC0"
|
|
"\x23\xC8\x55\x5D\x2B\xD8\x28\xD8\x31\xE4\xC9\x87\x42\x51\x87\x66\x43\x1F\x2C\xA4"
|
|
"\x73\xED\x4E\x50\x12\xC4\x50\x0E\x4C\xDD\x14\x73\xA2\xFB\xB3\x07\x0C\x66\x97\x4D"
|
|
"\x89\xDE\x35\x1C\x93\xE7\xE6\x8F\x20\x3D\x84\xE6\x73\x46\x0F\x7C\xF4\x3B\x6C\x02"
|
|
"\x23\x7C\x79\x6C\x86\xD9\x48\x80\x9C\x34\xCB\xA1\x23\xE7\xF7\x8A\x2E\x4B\x9D\x39"
|
|
"\xA5\x86\x1A\x73\x58\x28\x5A\x1D\x8D\x4A\xBD\x42\xD5\x49\x2B\xDF\x53\x1D\xE7\x4A"
|
|
"\x5F\x74\x09\x7F\xDC\x29\x7D\x58\x9C\x4B\xC5\x2F\x3B\x8F\xBF\x56\xCA\x48\x0A\x74"
|
|
"\xAE\xFF\xDD\x12\xE4\xF6\xAB\x83\x26\x4F\x52\x8A\x19\xBB\x91\x32\xA4\x42\xEC\x4F"
|
|
"\x3C\x76\xED\x9F\x03\xAA\x5E\x53\x79\x4C\xD0\x06\xD2\x1A\x42\x9D\xB1\xA7\xEC\xF7"
|
|
"\x5B\xD4\x03\x70\x1E\xF2\x47\x26\x48\xAC\x35\xEE\xD0\x58\x40\x94\x8C\x11\xD0\xEB"
|
|
"\x77\x39\x5A\xA3\xD5\xD0\xD3\xC3\x68\xE1\x75\xAA\xC0\x44\xEA\xD8\xDD\x13\x3F\xF9"
|
|
"\x7D\x21\x14\x34\xA5\x87\x43\xA4\x0A\x96\x77\x00\xCC\xCA\xB1\xDA\xC4\x39\xE0\x66"
|
|
"\x37\x05\x6E\xAC\xF2\xE6\xC6\xC5\x4F\x79\xD3\xE5\x6A\x3D\x36\x3F";
|
|
|
|
fail = !!memcmp(result, expected, 2048/8);
|
|
pass = !fail && pass;
|
|
|
|
std::cout << (fail ? "FAILED " : "passed ") << "Hash_DRBG SHA512/256/888 (C0UNT=1, E=32, N=16, A=32, P=32)\n";
|
|
}
|
|
|
|
return pass;
|
|
}
|
|
|
|
NAMESPACE_END // Test
|
|
NAMESPACE_END // CryptoPP
|