26#if CRYPTOPP_MSC_VERSION
27# pragma warning(disable: 4355)
30#if CRYPTOPP_MSC_VERSION
31# pragma warning(disable: 4505 4355)
38const double CLOCK_TICKS_PER_SECOND = (double)CLOCKS_PER_SEC;
40const double CLOCK_TICKS_PER_SECOND = (double)CLK_TCK;
42const double CLOCK_TICKS_PER_SECOND = 1000000.0;
45extern const byte defaultKey[] =
"0123456789"
46 "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
47 "00000000000000000000000000000000000000000000000000000"
48 "00000000000000000000000000000000000000000000000000000";
50double g_allocatedTime = 0.0, g_hertz = 0.0, g_logTotal = 0.0;
51unsigned int g_logCount = 0;
52time_t g_testBegin, g_testEnd;
54inline std::string HertzToString(
double hertz)
56 std::ostringstream oss;
59 if (hertz >= 0.999e+9)
60 oss << hertz / 1e+9 <<
" GHz";
61 else if (hertz >= 0.999e+6)
62 oss << hertz / 1e+6 <<
" MHz";
63 else if (hertz >= 0.999e+3)
64 oss << hertz / 1e+3 <<
" KHz";
66 oss << hertz <<
" Hz";
71void OutputResultBytes(
const char *name,
const char *provider,
double length,
double timeTaken)
73 std::ostringstream oss;
76 if (length < 0.000001f) length = 0.000001f;
77 if (timeTaken < 0.000001f) timeTaken = 0.000001f;
79 double mbs = length / timeTaken / (1024*1024);
80 oss <<
"\n<TR><TD>" << name <<
"<TD>" << provider;
81 oss << std::setiosflags(std::ios::fixed);
82 oss <<
"<TD>" << std::setprecision(0) << std::setiosflags(std::ios::fixed) << mbs;
85 const double cpb = timeTaken * g_hertz / length;
87 oss <<
"<TD>" << std::setprecision(2) << std::setiosflags(std::ios::fixed) << cpb;
89 oss <<
"<TD>" << std::setprecision(1) << std::setiosflags(std::ios::fixed) << cpb;
91 g_logTotal += log(mbs);
94 std::cout << oss.str();
97void OutputResultKeying(
double iterations,
double timeTaken)
99 std::ostringstream oss;
102 if (iterations < 0.000001f) iterations = 0.000001f;
103 if (timeTaken < 0.000001f) timeTaken = 0.000001f;
105 oss <<
"<TD>" << std::setprecision(3) << std::setiosflags(std::ios::fixed) << (1000*1000*timeTaken/iterations);
109 oss <<
"<TD>" << std::setprecision(0) << std::setiosflags(std::ios::fixed) << timeTaken * g_hertz / iterations;
111 std::cout << oss.str();
114void OutputResultOperations(
const char *name,
const char *provider,
const char *operation,
bool pc,
unsigned long iterations,
double timeTaken)
116 CRYPTOPP_UNUSED(provider);
117 std::ostringstream oss;
120 if (!iterations) iterations++;
121 if (timeTaken < 0.000001f) timeTaken = 0.000001f;
123 oss <<
"\n<TR><TD>" << name <<
" " << operation << (pc ?
" with precomputation" :
"");
125 oss <<
"<TD>" << std::setprecision(3) << std::setiosflags(std::ios::fixed) << (1000*timeTaken/iterations);
130 const double t = timeTaken * g_hertz / iterations / 1000000;
131 oss <<
"<TD>" << std::setprecision(3) << std::setiosflags(std::ios::fixed) << t;
134 g_logTotal += log(iterations/timeTaken);
137 std::cout << oss.str();
169 Test::GlobalRNG().GenerateBlock(buf, BUF_SIZE);
172 unsigned long i=0, blocks=1;
175 clock_t start = ::clock();
179 for (; i<blocks; i++)
181 timeTaken = double(::clock() - start) / CLOCK_TICKS_PER_SECOND;
183 while (timeTaken < 2.0/3*timeTotal);
186 OutputResultBytes(name, provider.c_str(),
double(blocks) * BUF_SIZE, timeTaken);
191 const int BUF_SIZE=2048U;
193 Test::GlobalRNG().GenerateBlock(buf, BUF_SIZE);
196 unsigned long i=0, blocks=1;
199 clock_t start = ::clock();
203 for (; i<blocks; i++)
205 timeTaken = double(::clock() - start) / CLOCK_TICKS_PER_SECOND;
207 while (timeTaken < 2.0/3*timeTotal);
210 OutputResultBytes(name, provider.c_str(),
double(blocks) * BUF_SIZE, timeTaken);
215 const int BUF_SIZE=2048U;
217 Test::GlobalRNG().GenerateBlock(buf, BUF_SIZE);
220 unsigned long i=0, blocks=1;
223 clock_t start = ::clock();
227 for (; i<blocks; i++)
228 bt.
Put(buf, BUF_SIZE);
229 timeTaken = double(::clock() - start) / CLOCK_TICKS_PER_SECOND;
231 while (timeTaken < 2.0/3*timeTotal);
234 OutputResultBytes(name, provider.c_str(),
double(blocks) * BUF_SIZE, timeTaken);
239 const int BUF_SIZE = 2048U;
241 Test::GlobalRNG().GenerateBlock(buf, BUF_SIZE);
245 if (cipher != NULLPTR)
251 cipher->
SetKey(buf, size);
254 unsigned long long blocks = 1;
257 clock_t start = ::clock();
262 timeTaken = double(::clock() - start) / CLOCK_TICKS_PER_SECOND;
263 }
while (timeTaken < timeTotal);
266 OutputResultBytes(name, provider.c_str(),
double(blocks) * BUF_SIZE, timeTaken);
273void BenchMark(
const char *name,
NIST_DRBG &rng,
double timeTotal)
275 const int BUF_SIZE = 2048U;
277 Test::GlobalRNG().GenerateBlock(buf, BUF_SIZE);
281 unsigned long long blocks = 1;
284 clock_t start = ::clock();
289 timeTaken = double(::clock() - start) / CLOCK_TICKS_PER_SECOND;
290 }
while (timeTaken < timeTotal);
293 OutputResultBytes(name, provider.c_str(),
double(blocks) * BUF_SIZE, timeTaken);
299 CRYPTOPP_UNUSED(params);
300 std::string name = factoryName;
305 BenchMark(name.c_str(), *obj, g_allocatedTime);
310 std::ostringstream oss;
313 oss <<
"<!DOCTYPE HTML>";
314 oss <<
"\n<HTML lang=\"en\">";
317 oss <<
"\n<META charset=\"UTF-8\">";
318 oss <<
"\n<TITLE>Speed Comparison of Popular Crypto Algorithms</TITLE>";
319 oss <<
"\n<STYLE>\n table {border-collapse: collapse;}";
320 oss <<
"\n table, th, td, tr {border: 1px solid black;}\n</STYLE>";
325 oss <<
"\n<H1><A href=\"http://www.cryptopp.com\">Crypto++ " <<
CRYPTOPP_VERSION / 100;
328 oss <<
"\n<P>Here are speed benchmarks for some commonly used cryptographic algorithms.</P>";
331 oss <<
"\n<P>CPU frequency of the test platform is " << HertzToString(g_hertz) <<
".</P>";
333 oss <<
"\n<P>CPU frequency of the test platform was not provided.</P>" << std::endl;
335 std::cout << oss.str();
340 std::ostringstream oss;
341 oss <<
"\n</BODY>\n</HTML>\n";
342 std::cout << oss.str();
345void BenchmarkWithCommand(
int argc,
const char*
const argv[])
347 std::string command(argv[1]);
348 float runningTime(argc >= 3 ? Test::StringToValue<float, true>(argv[2]) : 1.0f);
349 float cpuFreq(argc >= 4 ? Test::StringToValue<float, true>(argv[3])*
float(1e9) : 0.0f);
350 std::string algoName(argc >= 5 ? argv[4] :
"");
353 if (runningTime > 10.0f)
357 Benchmark(Test::All, runningTime, cpuFreq);
358 else if (command ==
"b4")
359 Test::Benchmark(Test::PublicKeyEC, runningTime, cpuFreq);
360 else if (command ==
"b3")
361 Test::Benchmark(Test::PublicKey, runningTime, cpuFreq);
362 else if (command ==
"b2")
363 Test::Benchmark(Test::SharedKey, runningTime, cpuFreq);
364 else if (command ==
"b1")
365 Test::Benchmark(Test::Unkeyed, runningTime, cpuFreq);
368void Benchmark(Test::TestClass suites,
double t,
double hertz)
374 size_t count_breaks = 0;
378 g_testBegin = ::time(NULLPTR);
380 if (
static_cast<int>(suites) == 0 ||
static_cast<int>(suites) > TestLast)
384 if (suites & Test::Unkeyed)
387 std::cout <<
"\n<BR>";
390 BenchmarkUnkeyedAlgorithms(t, hertz);
394 if (suites & Test::SharedKey)
397 std::cout <<
"\n<BR>";
400 BenchmarkSharedKeyedAlgorithms(t, hertz);
404 if (suites & Test::PublicKey)
407 std::cout <<
"\n<BR>";
410 BenchmarkPublicKeyAlgorithms(t, hertz);
414 if (suites & Test::PublicKeyEC)
417 std::cout <<
"\n<BR>";
420 BenchmarkEllipticCurveAlgorithms(t, hertz);
423 g_testEnd = ::time(NULLPTR);
425 std::ostringstream oss;
426 oss <<
"\n<P>Throughput Geometric Average: " << std::setiosflags(std::ios::fixed);
427 oss << std::exp(g_logTotal/(g_logCount > 0.0f ? g_logCount : 1.0f)) << std::endl;
429 oss <<
"\n<P>Test started at " << TimeToString(g_testBegin);
430 oss <<
"\n<BR>Test ended at " << TimeToString(g_testEnd);
432 std::cout << oss.str();
437void BenchmarkUnkeyedAlgorithms(
double t,
double hertz)
444 cpb =
"<TH>Cycles/Byte";
448 std::cout <<
"\n<TABLE>";
450 std::cout <<
"\n<COLGROUP><COL style=\"text-align: left;\"><COL style=\"text-align: right;\">";
451 std::cout <<
"<COL style=\"text-align: right;\">";
452 std::cout <<
"\n<THEAD style=\"background: #F0F0F0\">";
453 std::cout <<
"\n<TR><TH>Algorithm<TH>Provider<TH>MiB/Second" << cpb;
455 std::cout <<
"\n<TBODY style=\"background: white;\">";
457#ifdef NONBLOCKING_RNG_AVAILABLE
458 BenchMarkByNameKeyLess<RandomNumberGenerator>(
"NonblockingRng");
460#ifdef OS_RNG_AVAILABLE
461 BenchMarkByNameKeyLess<RandomNumberGenerator>(
"AutoSeededRandomPool");
462 BenchMarkByNameKeyLess<RandomNumberGenerator>(
"AutoSeededX917RNG(AES)");
464 BenchMarkByNameKeyLess<RandomNumberGenerator>(
"MT19937");
465#if (CRYPTOPP_BOOL_X86) && !defined(CRYPTOPP_DISABLE_ASM)
467 BenchMarkByNameKeyLess<RandomNumberGenerator>(
"PadlockRNG");
469#if (CRYPTOPP_BOOL_X86 || CRYPTOPP_BOOL_X32 || CRYPTOPP_BOOL_X64) && !defined(CRYPTOPP_DISABLE_ASM)
471 BenchMarkByNameKeyLess<RandomNumberGenerator>(
"RDRAND");
473 BenchMarkByNameKeyLess<RandomNumberGenerator>(
"RDSEED");
475#if (CRYPTOPP_BOOL_PPC32 || CRYPTOPP_BOOL_PPC64) && !defined(CRYPTOPP_DISABLE_ASM)
477 BenchMarkByNameKeyLess<RandomNumberGenerator>(
"DARN");
479 BenchMarkByNameKeyLess<RandomNumberGenerator>(
"AES/OFB RNG");
480 BenchMarkByNameKeyLess<NIST_DRBG>(
"Hash_DRBG(SHA1)");
481 BenchMarkByNameKeyLess<NIST_DRBG>(
"Hash_DRBG(SHA256)");
482 BenchMarkByNameKeyLess<NIST_DRBG>(
"HMAC_DRBG(SHA1)");
483 BenchMarkByNameKeyLess<NIST_DRBG>(
"HMAC_DRBG(SHA256)");
486 std::cout <<
"\n<TBODY style=\"background: yellow;\">";
488 BenchMarkByNameKeyLess<HashTransformation>(
"CRC32");
489 BenchMarkByNameKeyLess<HashTransformation>(
"CRC32C");
490 BenchMarkByNameKeyLess<HashTransformation>(
"Adler32");
491 BenchMarkByNameKeyLess<HashTransformation>(
"MD5");
492 BenchMarkByNameKeyLess<HashTransformation>(
"SHA-1");
493 BenchMarkByNameKeyLess<HashTransformation>(
"SHA-256");
494 BenchMarkByNameKeyLess<HashTransformation>(
"SHA-512");
495 BenchMarkByNameKeyLess<HashTransformation>(
"SHA3-224");
496 BenchMarkByNameKeyLess<HashTransformation>(
"SHA3-256");
497 BenchMarkByNameKeyLess<HashTransformation>(
"SHA3-384");
498 BenchMarkByNameKeyLess<HashTransformation>(
"SHA3-512");
499 BenchMarkByNameKeyLess<HashTransformation>(
"Keccak-224");
500 BenchMarkByNameKeyLess<HashTransformation>(
"Keccak-256");
501 BenchMarkByNameKeyLess<HashTransformation>(
"Keccak-384");
502 BenchMarkByNameKeyLess<HashTransformation>(
"Keccak-512");
503 BenchMarkByNameKeyLess<HashTransformation>(
"Tiger");
504 BenchMarkByNameKeyLess<HashTransformation>(
"Whirlpool");
505 BenchMarkByNameKeyLess<HashTransformation>(
"RIPEMD-160");
506 BenchMarkByNameKeyLess<HashTransformation>(
"RIPEMD-320");
507 BenchMarkByNameKeyLess<HashTransformation>(
"RIPEMD-128");
508 BenchMarkByNameKeyLess<HashTransformation>(
"RIPEMD-256");
509 BenchMarkByNameKeyLess<HashTransformation>(
"SM3");
510 BenchMarkByNameKeyLess<HashTransformation>(
"BLAKE2s");
511 BenchMarkByNameKeyLess<HashTransformation>(
"BLAKE2b");
512 BenchMarkByNameKeyLess<HashTransformation>(
"LSH-256");
513 BenchMarkByNameKeyLess<HashTransformation>(
"LSH-512");
516 std::cout <<
"\n</TABLE>" << std::endl;
Classes for working with NameValuePairs.
Standard names for retrieving values by name when working with NameValuePairs.
virtual std::string AlgorithmProvider() const
Retrieve the provider of this algorithm.
SecBlock using AllocatorWithCleanup<byte, true> typedef.
Interface for NIST DRBGs from SP 800-90A.
virtual void IncorporateEntropy(const byte *input, size_t length)=0
Update RNG state with additional unpredictable values.
virtual void GenerateBlock(byte *output, size_t size)=0
Generate random array of bytes.
virtual unsigned int MinEntropyLength() const =0
Provides the minimum entropy size.
Interface for retrieving values given their names.
Interface for random number generators.
virtual void GenerateBlock(byte *output, size_t size)
Generate random array of bytes.
void SetKeyWithIV(const byte *key, size_t length, const byte *iv, size_t ivLength)
Sets or reset the key of this object.
bool IsResynchronizable() const
Determines if the object can be resynchronized.
virtual void SetKey(const byte *key, size_t length, const NameValuePairs ¶ms=g_nullNameValuePairs)
Sets or reset the key of this object.
virtual size_t DefaultKeyLength() const =0
Returns default key length.
Interface for one direction (encryption or decryption) of a stream cipher or cipher mode.
Pointer that overloads operator ->
#define CRYPTOPP_VERSION
Full library version.
Functions for CPU features and intrinsics.
Abstract base classes that provide a uniform interface to this library.
const NameValuePairs & g_nullNameValuePairs
An empty set of name-value pairs.
Classes for NIST DRBGs from SP 800-90A.
Classes and functions for registering and locating library objects.
Class file for Mersenne Twister.
T1 RoundUpToMultipleOf(const T1 &n, const T2 &m)
Rounds a value up to a multiple of a second value.
Crypto++ library namespace.
Namespace containing testing and benchmark classes.
Classes for access to the operating system's random number generators.
Classes for VIA Padlock RNG.
Classes for RDRAND and RDSEED.
Classes for automatic resource management.