26 #if CRYPTOPP_MSC_VERSION 27 # pragma warning(disable: 4355) 30 #if CRYPTOPP_MSC_VERSION 31 # pragma warning(disable: 4505 4355) 38 const double CLOCK_TICKS_PER_SECOND = (double)CLOCKS_PER_SEC;
39 #elif defined(CLK_TCK) 40 const double CLOCK_TICKS_PER_SECOND = (double)CLK_TCK;
42 const double CLOCK_TICKS_PER_SECOND = 1000000.0;
45 extern const byte defaultKey[] =
"0123456789" 46 "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ" 47 "00000000000000000000000000000000000000000000000000000" 48 "00000000000000000000000000000000000000000000000000000";
50 double g_allocatedTime = 0.0, g_hertz = 0.0, g_logTotal = 0.0;
51 unsigned int g_logCount = 0;
52 time_t g_testBegin, g_testEnd;
54 inline 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";
71 void 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();
97 void 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();
114 void 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);
273 void 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++</A> " << CRYPTOPP_VERSION / 100;
326 oss <<
'.' << (CRYPTOPP_VERSION % 100) / 10 <<
'.' << CRYPTOPP_VERSION % 10 <<
" Benchmarks</H1>";
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();
345 void 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 Benchmark(Test::All, runningTime, cpuFreq);
354 else if (command ==
"b3")
355 Test::Benchmark(Test::PublicKey, runningTime, cpuFreq);
356 else if (command ==
"b2")
357 Test::Benchmark(Test::SharedKey, runningTime, cpuFreq);
358 else if (command ==
"b1")
359 Test::Benchmark(Test::Unkeyed, runningTime, cpuFreq);
362 void Benchmark(Test::TestClass suites,
double t,
double hertz)
369 g_testBegin = ::time(NULLPTR);
371 if (static_cast<int>(suites) == 0 || static_cast<int>(suites) > TestLast)
375 if (suites & Test::Unkeyed)
377 std::cout <<
"\n<BR>";
378 Benchmark1(t, hertz);
382 if (suites & Test::SharedKey)
384 std::cout <<
"\n<BR>";
385 Benchmark2(t, hertz);
389 if (suites & Test::PublicKey)
391 std::cout <<
"\n<BR>";
392 Benchmark3(t, hertz);
395 g_testEnd = ::time(NULLPTR);
397 std::ostringstream oss;
398 oss <<
"\n<P>Throughput Geometric Average: " << std::setiosflags(std::ios::fixed);
399 oss << std::exp(g_logTotal/(g_logCount > 0.0f ? g_logCount : 1.0f)) << std::endl;
401 oss <<
"\n<P>Test started at " << TimeToString(g_testBegin);
402 oss <<
"\n<BR>Test ended at " << TimeToString(g_testEnd);
404 std::cout << oss.str();
409 void Benchmark1(
double t,
double hertz)
416 cpb =
"<TH>Cycles/Byte";
420 std::cout <<
"\n<TABLE>";
422 std::cout <<
"\n<COLGROUP><COL style=\"text-align: left;\"><COL style=\"text-align: right;\">";
423 std::cout <<
"<COL style=\"text-align: right;\">";
424 std::cout <<
"\n<THEAD style=\"background: #F0F0F0\">";
425 std::cout <<
"\n<TR><TH>Algorithm<TH>Provider<TH>MiB/Second" << cpb;
427 std::cout <<
"\n<TBODY style=\"background: white;\">";
429 #ifdef NONBLOCKING_RNG_AVAILABLE 430 BenchMarkByNameKeyLess<RandomNumberGenerator>(
"NonblockingRng");
432 #ifdef OS_RNG_AVAILABLE 433 BenchMarkByNameKeyLess<RandomNumberGenerator>(
"AutoSeededRandomPool");
434 BenchMarkByNameKeyLess<RandomNumberGenerator>(
"AutoSeededX917RNG(AES)");
436 BenchMarkByNameKeyLess<RandomNumberGenerator>(
"MT19937");
437 #if (CRYPTOPP_BOOL_X86) && !defined(CRYPTOPP_DISABLE_ASM) 439 BenchMarkByNameKeyLess<RandomNumberGenerator>(
"PadlockRNG");
441 #if (CRYPTOPP_BOOL_X86 || CRYPTOPP_BOOL_X32 || CRYPTOPP_BOOL_X64) && !defined(CRYPTOPP_DISABLE_ASM) 443 BenchMarkByNameKeyLess<RandomNumberGenerator>(
"RDRAND");
445 BenchMarkByNameKeyLess<RandomNumberGenerator>(
"RDSEED");
447 #if (CRYPTOPP_BOOL_PPC32 || CRYPTOPP_BOOL_PPC64) && !defined(CRYPTOPP_DISABLE_ASM) 449 BenchMarkByNameKeyLess<RandomNumberGenerator>(
"DARN");
451 BenchMarkByNameKeyLess<RandomNumberGenerator>(
"AES/OFB RNG");
452 BenchMarkByNameKeyLess<NIST_DRBG>(
"Hash_DRBG(SHA1)");
453 BenchMarkByNameKeyLess<NIST_DRBG>(
"Hash_DRBG(SHA256)");
454 BenchMarkByNameKeyLess<NIST_DRBG>(
"HMAC_DRBG(SHA1)");
455 BenchMarkByNameKeyLess<NIST_DRBG>(
"HMAC_DRBG(SHA256)");
458 std::cout <<
"\n<TBODY style=\"background: yellow;\">";
460 BenchMarkByNameKeyLess<HashTransformation>(
"CRC32");
461 BenchMarkByNameKeyLess<HashTransformation>(
"CRC32C");
462 BenchMarkByNameKeyLess<HashTransformation>(
"Adler32");
463 BenchMarkByNameKeyLess<HashTransformation>(
"MD5");
464 BenchMarkByNameKeyLess<HashTransformation>(
"SHA-1");
465 BenchMarkByNameKeyLess<HashTransformation>(
"SHA-256");
466 BenchMarkByNameKeyLess<HashTransformation>(
"SHA-512");
467 BenchMarkByNameKeyLess<HashTransformation>(
"SHA3-224");
468 BenchMarkByNameKeyLess<HashTransformation>(
"SHA3-256");
469 BenchMarkByNameKeyLess<HashTransformation>(
"SHA3-384");
470 BenchMarkByNameKeyLess<HashTransformation>(
"SHA3-512");
471 BenchMarkByNameKeyLess<HashTransformation>(
"Keccak-224");
472 BenchMarkByNameKeyLess<HashTransformation>(
"Keccak-256");
473 BenchMarkByNameKeyLess<HashTransformation>(
"Keccak-384");
474 BenchMarkByNameKeyLess<HashTransformation>(
"Keccak-512");
475 BenchMarkByNameKeyLess<HashTransformation>(
"Tiger");
476 BenchMarkByNameKeyLess<HashTransformation>(
"Whirlpool");
477 BenchMarkByNameKeyLess<HashTransformation>(
"RIPEMD-160");
478 BenchMarkByNameKeyLess<HashTransformation>(
"RIPEMD-320");
479 BenchMarkByNameKeyLess<HashTransformation>(
"RIPEMD-128");
480 BenchMarkByNameKeyLess<HashTransformation>(
"RIPEMD-256");
481 BenchMarkByNameKeyLess<HashTransformation>(
"SM3");
482 BenchMarkByNameKeyLess<HashTransformation>(
"BLAKE2s");
483 BenchMarkByNameKeyLess<HashTransformation>(
"BLAKE2b");
486 std::cout <<
"\n</TABLE>" << std::endl;
Standard names for retrieving values by name when working with NameValuePairs.
bool HasDARN()
Determine if a PowerPC processor has DARN available.
Classes for working with NameValuePairs.
virtual void SetKey(const byte *key, size_t length, const NameValuePairs ¶ms=g_nullNameValuePairs)
Sets or reset the key of this object.
Classes for NIST DRBGs from SP 800-90A.
virtual void GenerateBlock(byte *output, size_t size)=0
Generate random array of bytes.
virtual void GenerateBlock(byte *output, size_t size)
Generate random array of bytes.
Classes for VIA Padlock RNG.
bool HasPadlockRNG()
Determines Padlock RNG availability.
Abstract base classes that provide a uniform interface to this library.
virtual unsigned int MinEntropyLength() const =0
Provides the minimum entropy size.
Classes for automatic resource management.
Interface for random number generators.
Classes for RDRAND and RDSEED.
virtual size_t DefaultKeyLength() const =0
Returns default key length.
bool HasRDRAND()
Determines RDRAND availability.
virtual std::string AlgorithmProvider() const
Retrieve the provider of this algorithm.
Pointer that overloads operator ->
bool HasRDSEED()
Determines RDSEED availability.
Interface for one direction (encryption or decryption) of a stream cipher or cipher mode...
const NameValuePairs & g_nullNameValuePairs
An empty set of name-value pairs.
Namespace containing testing and benchmark classes.
SecBlock using AllocatorWithCleanup<byte, true> typedef.
Classes and functions for registering and locating library objects.
Class file for Mersenne Twister.
Functions for CPU features and intrinsics.
virtual void IncorporateEntropy(const byte *input, size_t length)=0
Update RNG state with additional unpredictable values.
void SetKeyWithIV(const byte *key, size_t length, const byte *iv, size_t ivLength)
Sets or reset the key of this object.
Interface for NIST DRBGs from SP 800-90A.
T1 RoundUpToMultipleOf(const T1 &n, const T2 &m)
Rounds a value up to a multiple of a second value.
Crypto++ library namespace.
bool IsResynchronizable() const
Determines if the object can be resynchronized.
Classes for access to the operating system's random number generators.
Interface for retrieving values given their names.