Crypto++  7.0
Free C++ class library of cryptographic schemes
bench1.cpp
1 // bench1.cpp - originally written and placed in the public domain by Wei Dai
2 // CryptoPP::Test namespace added by JW in February 2017
3 
4 #include "cryptlib.h"
5 #include "bench.h"
6 #include "validate.h"
7 
8 #include "aes.h"
9 #include "kalyna.h"
10 #include "threefish.h"
11 #include "blumshub.h"
12 #include "files.h"
13 #include "filters.h"
14 #include "hex.h"
15 #include "modes.h"
16 #include "factory.h"
17 #include "smartptr.h"
18 #include "cpu.h"
19 #include "drbg.h"
20 #include "rdrand.h"
21 #include "padlkrng.h"
22 #include "stdcpp.h"
23 
24 #if CRYPTOPP_MSC_VERSION
25 # pragma warning(disable: 4355)
26 #endif
27 
28 #if CRYPTOPP_MSC_VERSION
29 # pragma warning(disable: 4505 4355)
30 #endif
31 
32 NAMESPACE_BEGIN(CryptoPP)
33 NAMESPACE_BEGIN(Test)
34 
35 #ifdef CLOCKS_PER_SEC
36 const double CLOCK_TICKS_PER_SECOND = (double)CLOCKS_PER_SEC;
37 #elif defined(CLK_TCK)
38 const double CLOCK_TICKS_PER_SECOND = (double)CLK_TCK;
39 #else
40 const double CLOCK_TICKS_PER_SECOND = 1000000.0;
41 #endif
42 
43 const byte defaultKey[] = "0123456789" // 168 + NULL
44  "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
45  "00000000000000000000000000000000000000000000000000000"
46  "00000000000000000000000000000000000000000000000000000";
47 
48 double g_allocatedTime = 0.0, g_hertz = 0.0, g_logTotal = 0.0;
49 unsigned int g_logCount = 0;
50 time_t g_testBegin, g_testEnd;
51 
52 void OutputResultBytes(const char *name, double length, double timeTaken)
53 {
54  // Coverity finding, also see http://stackoverflow.com/a/34509163/608639.
55  StreamState ss(std::cout);
56 
57  // Coverity finding
58  if (length < 0.000001f) length = 0.000001f;
59  if (timeTaken < 0.000001f) timeTaken = 0.000001f;
60 
61  double mbs = length / timeTaken / (1024*1024);
62  std::cout << "\n<TR><TD>" << name;
63  std::cout << std::setiosflags(std::ios::fixed);
64  std::cout << "<TD>" << std::setprecision(0) << std::setiosflags(std::ios::fixed) << mbs;
65  if (g_hertz > 1.0f)
66  {
67  const double cpb = timeTaken * g_hertz / length;
68  if (cpb < 24.0f)
69  std::cout << "<TD>" << std::setprecision(2) << std::setiosflags(std::ios::fixed) << cpb;
70  else
71  std::cout << "<TD>" << std::setprecision(1) << std::setiosflags(std::ios::fixed) << cpb;
72  }
73  g_logTotal += log(mbs);
74  g_logCount++;
75 }
76 
77 void OutputResultKeying(double iterations, double timeTaken)
78 {
79  // Coverity finding, also see http://stackoverflow.com/a/34509163/608639.
80  StreamState ss(std::cout);
81 
82  // Coverity finding
83  if (iterations < 0.000001f) iterations = 0.000001f;
84  if (timeTaken < 0.000001f) timeTaken = 0.000001f;
85 
86  std::cout << "<TD>" << std::setprecision(3) << std::setiosflags(std::ios::fixed) << (1000*1000*timeTaken/iterations);
87 
88  // Coverity finding
89  if (g_hertz > 1.0f)
90  std::cout << "<TD>" << std::setprecision(0) << std::setiosflags(std::ios::fixed) << timeTaken * g_hertz / iterations;
91 }
92 
93 void OutputResultOperations(const char *name, const char *operation, bool pc, unsigned long iterations, double timeTaken)
94 {
95  // Coverity finding, also see http://stackoverflow.com/a/34509163/608639.
96  StreamState ss(std::cout);
97 
98  // Coverity finding
99  if (!iterations) iterations++;
100  if (timeTaken < 0.000001f) timeTaken = 0.000001f;
101 
102  std::cout << "\n<TR><TD>" << name << " " << operation << (pc ? " with precomputation" : "");
103  std::cout << "<TD>" << std::setprecision(2) << std::setiosflags(std::ios::fixed) << (1000*timeTaken/iterations);
104 
105  // Coverity finding
106  if (g_hertz > 1.0f)
107  {
108  const double t = timeTaken * g_hertz / iterations / 1000000;
109  std::cout << "<TD>" << std::setprecision(2) << std::setiosflags(std::ios::fixed) << t;
110  }
111 
112  g_logTotal += log(iterations/timeTaken);
113  g_logCount++;
114 }
115 
116 /*
117 void BenchMark(const char *name, BlockTransformation &cipher, double timeTotal)
118 {
119  const int BUF_SIZE = RoundUpToMultipleOf(2048U, cipher.OptimalNumberOfParallelBlocks() * cipher.BlockSize());
120  AlignedSecByteBlock buf(BUF_SIZE);
121  buf.SetMark(16);
122 
123  const int nBlocks = BUF_SIZE / cipher.BlockSize();
124  unsigned long i=0, blocks=1;
125  double timeTaken;
126 
127  clock_t start = ::clock();
128  do
129  {
130  blocks *= 2;
131  for (; i<blocks; i++)
132  cipher.ProcessAndXorMultipleBlocks(buf, NULLPTR, buf, nBlocks);
133  timeTaken = double(::clock() - start) / CLOCK_TICKS_PER_SECOND;
134  }
135  while (timeTaken < 2.0/3*timeTotal);
136 
137  OutputResultBytes(name, double(blocks) * BUF_SIZE, timeTaken);
138 }
139 */
140 
141 void BenchMark(const char *name, StreamTransformation &cipher, double timeTotal)
142 {
143  const int BUF_SIZE=RoundUpToMultipleOf(2048U, cipher.OptimalBlockSize());
144  AlignedSecByteBlock buf(BUF_SIZE);
145  Test::GlobalRNG().GenerateBlock(buf, BUF_SIZE);
146  buf.SetMark(16);
147 
148  unsigned long i=0, blocks=1;
149  double timeTaken;
150 
151  clock_t start = ::clock();
152  do
153  {
154  blocks *= 2;
155  for (; i<blocks; i++)
156  cipher.ProcessString(buf, BUF_SIZE);
157  timeTaken = double(::clock() - start) / CLOCK_TICKS_PER_SECOND;
158  }
159  while (timeTaken < 2.0/3*timeTotal);
160 
161  OutputResultBytes(name, double(blocks) * BUF_SIZE, timeTaken);
162 }
163 
164 void BenchMark(const char *name, AuthenticatedSymmetricCipher &cipher, double timeTotal)
165 {
166  if (cipher.NeedsPrespecifiedDataLengths())
167  cipher.SpecifyDataLengths(0, cipher.MaxMessageLength(), 0);
168 
169  BenchMark(name, static_cast<StreamTransformation &>(cipher), timeTotal);
170 }
171 
172 void BenchMark(const char *name, HashTransformation &ht, double timeTotal)
173 {
174  const int BUF_SIZE=2048U;
175  AlignedSecByteBlock buf(BUF_SIZE);
176  Test::GlobalRNG().GenerateBlock(buf, BUF_SIZE);
177  buf.SetMark(16);
178 
179  unsigned long i=0, blocks=1;
180  double timeTaken;
181 
182  clock_t start = ::clock();
183  do
184  {
185  blocks *= 2;
186  for (; i<blocks; i++)
187  ht.Update(buf, BUF_SIZE);
188  timeTaken = double(::clock() - start) / CLOCK_TICKS_PER_SECOND;
189  }
190  while (timeTaken < 2.0/3*timeTotal);
191 
192  OutputResultBytes(name, double(blocks) * BUF_SIZE, timeTaken);
193 }
194 
195 void BenchMark(const char *name, BufferedTransformation &bt, double timeTotal)
196 {
197  const int BUF_SIZE=2048U;
198  AlignedSecByteBlock buf(BUF_SIZE);
199  Test::GlobalRNG().GenerateBlock(buf, BUF_SIZE);
200  buf.SetMark(16);
201 
202  unsigned long i=0, blocks=1;
203  double timeTaken;
204 
205  clock_t start = ::clock();
206  do
207  {
208  blocks *= 2;
209  for (; i<blocks; i++)
210  bt.Put(buf, BUF_SIZE);
211  timeTaken = double(::clock() - start) / CLOCK_TICKS_PER_SECOND;
212  }
213  while (timeTaken < 2.0/3*timeTotal);
214 
215  OutputResultBytes(name, double(blocks) * BUF_SIZE, timeTaken);
216 }
217 
218 void BenchMark(const char *name, RandomNumberGenerator &rng, double timeTotal)
219 {
220  const int BUF_SIZE = 2048U;
221  AlignedSecByteBlock buf(BUF_SIZE);
222  Test::GlobalRNG().GenerateBlock(buf, BUF_SIZE);
223  buf.SetMark(16);
224 
225  SymmetricCipher * cipher = dynamic_cast<SymmetricCipher*>(&rng);
226  if (cipher != NULLPTR)
227  {
228  const size_t size = cipher->DefaultKeyLength();
229  if (cipher->IsResynchronizable())
230  cipher->SetKeyWithIV(buf, size, buf+size);
231  else
232  cipher->SetKey(buf, size);
233  }
234 
235  unsigned long long blocks = 1;
236  double timeTaken;
237 
238  clock_t start = ::clock();
239  do
240  {
241  rng.GenerateBlock(buf, buf.size());
242  blocks++;
243  timeTaken = double(::clock() - start) / CLOCK_TICKS_PER_SECOND;
244  } while (timeTaken < timeTotal);
245 
246  OutputResultBytes(name, double(blocks) * BUF_SIZE, timeTaken);
247 }
248 
249 // Hack, but we probably need a KeyedRandomNumberGenerator interface
250 // and a few methods to generalize keying a RNG. X917RNG, Hash_DRBG,
251 // HMAC_DRBG, AES/CFB RNG and a few others could use it. "A few others"
252 // includes BLAKE2, ChaCha and Poly1305 when used as a RNG.
253 void BenchMark(const char *name, NIST_DRBG &rng, double timeTotal)
254 {
255  const int BUF_SIZE = 2048U;
256  AlignedSecByteBlock buf(BUF_SIZE);
257  Test::GlobalRNG().GenerateBlock(buf, BUF_SIZE);
258  buf.SetMark(16);
259 
260  rng.IncorporateEntropy(buf, rng.MinEntropyLength());
261  unsigned long long blocks = 1;
262  double timeTaken;
263 
264  clock_t start = ::clock();
265  do
266  {
267  rng.GenerateBlock(buf, buf.size());
268  blocks++;
269  timeTaken = double(::clock() - start) / CLOCK_TICKS_PER_SECOND;
270  } while (timeTaken < timeTotal);
271 
272  OutputResultBytes(name, double(blocks) * BUF_SIZE, timeTaken);
273 }
274 
275 void BenchMarkKeying(SimpleKeyingInterface &c, size_t keyLength, const NameValuePairs &params)
276 {
277  unsigned long iterations = 0;
278  double timeTaken;
279 
280  clock_t start = ::clock();
281  do
282  {
283  for (unsigned int i=0; i<1024; i++)
284  c.SetKey(defaultKey, keyLength, params);
285  timeTaken = double(::clock() - start) / CLOCK_TICKS_PER_SECOND;
286  iterations += 1024;
287  }
288  while (timeTaken < g_allocatedTime);
289 
290  OutputResultKeying(iterations, timeTaken);
291 }
292 
293 template <class T_FactoryOutput, class T_Interface>
294 void BenchMarkByName2(const char *factoryName, size_t keyLength = 0, const char *displayName=NULLPTR, const NameValuePairs &params = g_nullNameValuePairs)
295 {
296  std::string name(factoryName ? factoryName : "");
298 
299  if (!keyLength)
300  keyLength = obj->DefaultKeyLength();
301 
302  if (displayName)
303  name = displayName;
304  else if (keyLength)
305  name += " (" + IntToString(keyLength * 8) + "-bit key)";
306 
307  const int blockSize = params.GetIntValueWithDefault(Name::BlockSize(), 0);
308  obj->SetKey(defaultKey, keyLength, CombinedNameValuePairs(params, MakeParameters(Name::IV(), ConstByteArrayParameter(defaultKey, blockSize ? blockSize : obj->IVSize()), false)));
309  BenchMark(name.c_str(), *static_cast<T_Interface *>(obj.get()), g_allocatedTime);
310  BenchMarkKeying(*obj, keyLength, CombinedNameValuePairs(params, MakeParameters(Name::IV(), ConstByteArrayParameter(defaultKey, blockSize ? blockSize : obj->IVSize()), false)));
311 }
312 
313 template <class T_FactoryOutput>
314 void BenchMarkByName(const char *factoryName, size_t keyLength = 0, const char *displayName=NULLPTR, const NameValuePairs &params = g_nullNameValuePairs)
315 {
316  CRYPTOPP_UNUSED(params);
317  BenchMarkByName2<T_FactoryOutput, T_FactoryOutput>(factoryName, keyLength, displayName, params);
318 }
319 
320 template <class T>
321 void BenchMarkByNameKeyLess(const char *factoryName, const char *displayName=NULLPTR, const NameValuePairs &params = g_nullNameValuePairs)
322 {
323  CRYPTOPP_UNUSED(params);
324  std::string name = factoryName;
325  if (displayName)
326  name = displayName;
327 
328  member_ptr<T> obj(ObjectFactoryRegistry<T>::Registry().CreateObject(factoryName));
329  BenchMark(name.c_str(), *obj, g_allocatedTime);
330 }
331 
332 void AddHtmlHeader()
333 {
334  // HTML5
335  std::cout << "<!DOCTYPE HTML>";
336  std::cout << "\n<HTML lang=\"en\">";
337 
338  std::cout << "\n<HEAD>";
339  std::cout << "\n<META charset=\"UTF-8\">";
340  std::cout << "\n<TITLE>Speed Comparison of Popular Crypto Algorithms</TITLE>";
341  std::cout << "\n<STYLE>\n table {border-collapse: collapse;}";
342  std::cout << "\n table, th, td, tr {border: 1px solid black;}\n</STYLE>";
343  std::cout << "\n</HEAD>";
344 
345  std::cout << "\n<BODY>";
346 
347  std::cout << "\n<H1><A href=\"http://www.cryptopp.com\">Crypto++</A> " << CRYPTOPP_VERSION / 100;
348  std::cout << '.' << (CRYPTOPP_VERSION % 100) / 10 << '.' << CRYPTOPP_VERSION % 10 << " Benchmarks</H1>";
349 
350  std::cout << "\n<P>Here are speed benchmarks for some commonly used cryptographic algorithms.</P>";
351 
352  if (g_hertz > 1.0f)
353  std::cout << "\n<P>CPU frequency of the test platform is " << g_hertz << " Hz.</P>";
354  else
355  std::cout << "\n<P>CPU frequency of the test platform was not provided.</P>" << std::endl;
356 }
357 
358 void AddHtmlFooter()
359 {
360  std::cout << "\n</BODY>";
361  std::cout << "\n</HTML>" << std::endl;
362 }
363 
364 void BenchmarkWithCommand(int argc, const char* const argv[])
365 {
366  std::string command(argv[1]);
367  float runningTime(argc >= 3 ? Test::StringToValue<float, true>(argv[2]) : 1.0f);
368  float cpuFreq(argc >= 4 ? Test::StringToValue<float, true>(argv[3])*float(1e9) : 0.0f);
369  std::string algoName(argc >= 5 ? argv[4] : "");
370 
371  if (command == "b") // All benchmarks
372  Benchmark(Test::All, runningTime, cpuFreq);
373  else if (command == "b3") // Public key algorithms
374  Test::Benchmark(Test::PublicKey, runningTime, cpuFreq);
375  else if (command == "b2") // Shared key algorithms
376  Test::Benchmark(Test::SharedKey, runningTime, cpuFreq);
377  else if (command == "b1") // Unkeyed algorithms
378  Test::Benchmark(Test::Unkeyed, runningTime, cpuFreq);
379 }
380 
381 void Benchmark(Test::TestClass suites, double t, double hertz)
382 {
383  g_allocatedTime = t;
384  g_hertz = hertz;
385 
386  AddHtmlHeader();
387 
388  g_testBegin = ::time(NULLPTR);
389 
390  if (static_cast<int>(suites) == 0 || static_cast<int>(suites) > TestLast)
391  suites = Test::All;
392 
393  // Unkeyed algorithms
394  if (suites & Test::Unkeyed)
395  {
396  std::cout << "\n<BR>";
397  Benchmark1(t, hertz);
398  }
399 
400  // Shared key algorithms
401  if (suites & Test::SharedKey)
402  {
403  std::cout << "\n<BR>";
404  Benchmark2(t, hertz);
405  }
406 
407  // Public key algorithms
408  if (suites & Test::PublicKey)
409  {
410  std::cout << "\n<BR>";
411  Benchmark3(t, hertz);
412  }
413 
414  g_testEnd = ::time(NULLPTR);
415 
416  {
417  StreamState state(std::cout);
418  std::cout << "\n<P>Throughput Geometric Average: " << std::setiosflags(std::ios::fixed);
419  std::cout << std::exp(g_logTotal/(g_logCount > 0.0f ? g_logCount : 1.0f)) << std::endl;
420  }
421 
422  std::cout << "\n<P>Test started at " << TimeToString(g_testBegin);
423  std::cout << "\n<BR>Test ended at " << TimeToString(g_testEnd);
424  std::cout << std::endl;
425 
426  AddHtmlFooter();
427 }
428 
429 void Benchmark1(double t, double hertz)
430 {
431  g_allocatedTime = t;
432  g_hertz = hertz;
433 
434  const char *cpb;
435  if (g_hertz > 1.0f)
436  cpb = "<TH>Cycles Per Byte";
437  else
438  cpb = "";
439 
440  std::cout << "\n<TABLE>";
441 
442  std::cout << "\n<COLGROUP><COL style=\"text-align: left;\"><COL style=\"text-align: right;\">";
443  std::cout << "<COL style=\"text-align: right;\">";
444  std::cout << "\n<THEAD style=\"background: #F0F0F0\">";
445  std::cout << "\n<TR><TH>Algorithm<TH>MiB/Second" << cpb;
446 
447  std::cout << "\n<TBODY style=\"background: white;\">";
448  {
449 #ifdef NONBLOCKING_RNG_AVAILABLE
450  BenchMarkByNameKeyLess<RandomNumberGenerator>("NonblockingRng");
451 #endif
452 #ifdef OS_RNG_AVAILABLE
453  BenchMarkByNameKeyLess<RandomNumberGenerator>("AutoSeededRandomPool");
454  BenchMarkByNameKeyLess<RandomNumberGenerator>("AutoSeededX917RNG(AES)");
455 #endif
456  BenchMarkByNameKeyLess<RandomNumberGenerator>("MT19937");
457 #if (CRYPTOPP_BOOL_X86)
458  if (HasPadlockRNG())
459  BenchMarkByNameKeyLess<RandomNumberGenerator>("PadlockRNG");
460 #endif
461 #if (CRYPTOPP_BOOL_X86 || CRYPTOPP_BOOL_X32 || CRYPTOPP_BOOL_X64)
462  if (HasRDRAND())
463  BenchMarkByNameKeyLess<RandomNumberGenerator>("RDRAND");
464  if (HasRDSEED())
465  BenchMarkByNameKeyLess<RandomNumberGenerator>("RDSEED");
466 #endif
467  BenchMarkByNameKeyLess<RandomNumberGenerator>("AES/OFB RNG");
468  BenchMarkByNameKeyLess<NIST_DRBG>("Hash_DRBG(SHA1)");
469  BenchMarkByNameKeyLess<NIST_DRBG>("Hash_DRBG(SHA256)");
470  BenchMarkByNameKeyLess<NIST_DRBG>("HMAC_DRBG(SHA1)");
471  BenchMarkByNameKeyLess<NIST_DRBG>("HMAC_DRBG(SHA256)");
472  }
473 
474  std::cout << "\n<TBODY style=\"background: yellow;\">";
475  {
476  BenchMarkByNameKeyLess<HashTransformation>("CRC32");
477  BenchMarkByNameKeyLess<HashTransformation>("CRC32C");
478  BenchMarkByNameKeyLess<HashTransformation>("Adler32");
479  BenchMarkByNameKeyLess<HashTransformation>("MD5");
480  BenchMarkByNameKeyLess<HashTransformation>("SHA-1");
481  BenchMarkByNameKeyLess<HashTransformation>("SHA-256");
482  BenchMarkByNameKeyLess<HashTransformation>("SHA-512");
483  BenchMarkByNameKeyLess<HashTransformation>("SHA3-224");
484  BenchMarkByNameKeyLess<HashTransformation>("SHA3-256");
485  BenchMarkByNameKeyLess<HashTransformation>("SHA3-384");
486  BenchMarkByNameKeyLess<HashTransformation>("SHA3-512");
487  BenchMarkByNameKeyLess<HashTransformation>("Keccak-224");
488  BenchMarkByNameKeyLess<HashTransformation>("Keccak-256");
489  BenchMarkByNameKeyLess<HashTransformation>("Keccak-384");
490  BenchMarkByNameKeyLess<HashTransformation>("Keccak-512");
491  BenchMarkByNameKeyLess<HashTransformation>("Tiger");
492  BenchMarkByNameKeyLess<HashTransformation>("Whirlpool");
493  BenchMarkByNameKeyLess<HashTransformation>("RIPEMD-160");
494  BenchMarkByNameKeyLess<HashTransformation>("RIPEMD-320");
495  BenchMarkByNameKeyLess<HashTransformation>("RIPEMD-128");
496  BenchMarkByNameKeyLess<HashTransformation>("RIPEMD-256");
497  BenchMarkByNameKeyLess<HashTransformation>("SM3");
498  BenchMarkByNameKeyLess<HashTransformation>("BLAKE2s");
499  BenchMarkByNameKeyLess<HashTransformation>("BLAKE2b");
500  }
501 
502  std::cout << "\n</TABLE>" << std::endl;
503 }
504 
505 void Benchmark2(double t, double hertz)
506 {
507  g_allocatedTime = t;
508  g_hertz = hertz;
509 
510  const char *cpb, *cpk;
511  if (g_hertz > 1.0f)
512  {
513  cpb = "<TH>Cycles Per Byte";
514  cpk = "<TH>Cycles to<BR>Setup Key and IV";
515  }
516  else
517  {
518  cpb = cpk = "";
519  }
520 
521  std::cout << "\n<TABLE>";
522  std::cout << "\n<COLGROUP><COL style=\"text-align: left;\"><COL style=\"text-align: right;\"><COL style=";
523  std::cout << "\"text-align: right;\"><COL style=\"text-align: right;\"><COL style=\"text-align: right;\">";
524  std::cout << "\n<THEAD style=\"background: #F0F0F0\">";
525  std::cout << "\n<TR><TH>Algorithm<TH>MiB/Second" << cpb;
526  std::cout << "<TH>Microseconds to<BR>Setup Key and IV" << cpk;
527 
528  std::cout << "\n<TBODY style=\"background: white;\">";
529  {
530 #if CRYPTOPP_AESNI_AVAILABLE
531  if (HasCLMUL())
532  BenchMarkByName2<AuthenticatedSymmetricCipher, MessageAuthenticationCode>("AES/GCM", 0, "GMAC(AES)");
533  else
534 #elif CRYPTOPP_ARM_PMULL_AVAILABLE
535  if (HasPMULL())
536  BenchMarkByName2<AuthenticatedSymmetricCipher, MessageAuthenticationCode>("AES/GCM", 0, "GMAC(AES)");
537  else
538 #endif
539  {
540  BenchMarkByName2<AuthenticatedSymmetricCipher, MessageAuthenticationCode>("AES/GCM", 0, "GMAC(AES) (2K tables)", MakeParameters(Name::TableSize(), 2048));
541  BenchMarkByName2<AuthenticatedSymmetricCipher, MessageAuthenticationCode>("AES/GCM", 0, "GMAC(AES) (64K tables)", MakeParameters(Name::TableSize(), 64 * 1024));
542  }
543 
544  BenchMarkByName<MessageAuthenticationCode>("VMAC(AES)-64");
545  BenchMarkByName<MessageAuthenticationCode>("VMAC(AES)-128");
546  BenchMarkByName<MessageAuthenticationCode>("HMAC(SHA-1)");
547  BenchMarkByName<MessageAuthenticationCode>("HMAC(SHA-256)");
548  BenchMarkByName<MessageAuthenticationCode>("Two-Track-MAC");
549  BenchMarkByName<MessageAuthenticationCode>("CMAC(AES)");
550  BenchMarkByName<MessageAuthenticationCode>("DMAC(AES)");
551  BenchMarkByName<MessageAuthenticationCode>("Poly1305(AES)");
552  BenchMarkByName<MessageAuthenticationCode>("BLAKE2s");
553  BenchMarkByName<MessageAuthenticationCode>("BLAKE2b");
554  BenchMarkByName<MessageAuthenticationCode>("SipHash-2-4");
555  BenchMarkByName<MessageAuthenticationCode>("SipHash-4-8");
556  }
557 
558  std::cout << "\n<TBODY style=\"background: yellow;\">";
559  {
560  BenchMarkByName<SymmetricCipher>("Panama-LE");
561  BenchMarkByName<SymmetricCipher>("Panama-BE");
562  BenchMarkByName<SymmetricCipher>("Salsa20");
563  BenchMarkByName<SymmetricCipher>("Salsa20", 0, "Salsa20/12", MakeParameters(Name::Rounds(), 12));
564  BenchMarkByName<SymmetricCipher>("Salsa20", 0, "Salsa20/8", MakeParameters(Name::Rounds(), 8));
565  BenchMarkByName<SymmetricCipher>("ChaCha20");
566  BenchMarkByName<SymmetricCipher>("ChaCha12");
567  BenchMarkByName<SymmetricCipher>("ChaCha8");
568  BenchMarkByName<SymmetricCipher>("Sosemanuk");
569  BenchMarkByName<SymmetricCipher>("MARC4");
570  BenchMarkByName<SymmetricCipher>("SEAL-3.0-LE");
571  BenchMarkByName<SymmetricCipher>("WAKE-OFB-LE");
572  }
573 
574  std::cout << "\n<TBODY style=\"background: white;\">";
575  {
576  BenchMarkByName<SymmetricCipher>("AES/CTR", 16);
577  BenchMarkByName<SymmetricCipher>("AES/CTR", 24);
578  BenchMarkByName<SymmetricCipher>("AES/CTR", 32);
579  BenchMarkByName<SymmetricCipher>("AES/CBC", 16);
580  BenchMarkByName<SymmetricCipher>("AES/CBC", 24);
581  BenchMarkByName<SymmetricCipher>("AES/CBC", 32);
582  BenchMarkByName<SymmetricCipher>("AES/OFB", 16);
583  BenchMarkByName<SymmetricCipher>("AES/CFB", 16);
584  BenchMarkByName<SymmetricCipher>("AES/ECB", 16);
585  BenchMarkByName<SymmetricCipher>("ARIA/CTR", 16);
586  BenchMarkByName<SymmetricCipher>("ARIA/CTR", 32);
587  BenchMarkByName<SymmetricCipher>("Camellia/CTR", 16);
588  BenchMarkByName<SymmetricCipher>("Camellia/CTR", 32);
589  BenchMarkByName<SymmetricCipher>("Twofish/CTR");
590  BenchMarkByName<SymmetricCipher>("Threefish-256(256)/CTR", 32);
591  BenchMarkByName<SymmetricCipher>("Threefish-512(512)/CTR", 64);
592  BenchMarkByName<SymmetricCipher>("Threefish-1024(1024)/CTR", 128);
593  BenchMarkByName<SymmetricCipher>("Serpent/CTR");
594  BenchMarkByName<SymmetricCipher>("CAST-128/CTR");
595  BenchMarkByName<SymmetricCipher>("CAST-256/CTR");
596  BenchMarkByName<SymmetricCipher>("RC6/CTR");
597  BenchMarkByName<SymmetricCipher>("MARS/CTR");
598  BenchMarkByName<SymmetricCipher>("SHACAL-2/CTR", 16);
599  BenchMarkByName<SymmetricCipher>("SHACAL-2/CTR", 64);
600  BenchMarkByName<SymmetricCipher>("DES/CTR");
601  BenchMarkByName<SymmetricCipher>("DES-XEX3/CTR");
602  BenchMarkByName<SymmetricCipher>("DES-EDE3/CTR");
603  BenchMarkByName<SymmetricCipher>("IDEA/CTR");
604  BenchMarkByName<SymmetricCipher>("RC5/CTR", 0, "RC5 (r=16)");
605  BenchMarkByName<SymmetricCipher>("Blowfish/CTR");
606  BenchMarkByName<SymmetricCipher>("TEA/CTR");
607  BenchMarkByName<SymmetricCipher>("XTEA/CTR");
608  BenchMarkByName<SymmetricCipher>("SKIPJACK/CTR");
609  BenchMarkByName<SymmetricCipher>("SEED/CTR", 0, "SEED/CTR (1/2 K table)");
610  BenchMarkByName<SymmetricCipher>("SM4/CTR");
611 
612  BenchMarkByName<SymmetricCipher>("Kalyna-128/CTR", 16, "Kalyna-128(128)/CTR (128-bit key)");
613  BenchMarkByName<SymmetricCipher>("Kalyna-128/CTR", 32, "Kalyna-128(256)/CTR (256-bit key)");
614  BenchMarkByName<SymmetricCipher>("Kalyna-256/CTR", 32, "Kalyna-256(256)/CTR (256-bit key)");
615  BenchMarkByName<SymmetricCipher>("Kalyna-256/CTR", 64, "Kalyna-256(512)/CTR (512-bit key)");
616  BenchMarkByName<SymmetricCipher>("Kalyna-512/CTR", 64, "Kalyna-512(512)/CTR (512-bit key)");
617 
618  BenchMarkByName<SymmetricCipher>("SIMON-64/CTR", 12, "SIMON-64(96)/CTR (96-bit key)");
619  BenchMarkByName<SymmetricCipher>("SIMON-64/CTR", 16, "SIMON-64(128)/CTR (128-bit key)");
620  BenchMarkByName<SymmetricCipher>("SIMON-128/CTR", 16, "SIMON-128(128)/CTR (128-bit key)");
621  BenchMarkByName<SymmetricCipher>("SIMON-128/CTR", 24, "SIMON-128(192)/CTR (192-bit key)");
622  BenchMarkByName<SymmetricCipher>("SIMON-128/CTR", 32, "SIMON-128(256)/CTR (256-bit key)");
623 
624  BenchMarkByName<SymmetricCipher>("SPECK-64/CTR", 12, "SPECK-64(96)/CTR (96-bit key)");
625  BenchMarkByName<SymmetricCipher>("SPECK-64/CTR", 16, "SPECK-64(128)/CTR (128-bit key)");
626  BenchMarkByName<SymmetricCipher>("SPECK-128/CTR", 16, "SPECK-128(128)/CTR (128-bit key)");
627  BenchMarkByName<SymmetricCipher>("SPECK-128/CTR", 24, "SPECK-128(192)/CTR (192-bit key)");
628  BenchMarkByName<SymmetricCipher>("SPECK-128/CTR", 32, "SPECK-128(256)/CTR (256-bit key)");
629  }
630 
631  std::cout << "\n<TBODY style=\"background: yellow;\">";
632  {
633 #if CRYPTOPP_AESNI_AVAILABLE
634  if (HasCLMUL())
635  BenchMarkByName2<AuthenticatedSymmetricCipher, AuthenticatedSymmetricCipher>("AES/GCM", 0, "AES/GCM");
636  else
637 #elif CRYPTOPP_ARM_PMULL_AVAILABLE
638  if (HasPMULL())
639  BenchMarkByName2<AuthenticatedSymmetricCipher, AuthenticatedSymmetricCipher>("AES/GCM", 0, "AES/GCM");
640  else
641 #endif
642  {
643  BenchMarkByName2<AuthenticatedSymmetricCipher, AuthenticatedSymmetricCipher>("AES/GCM", 0, "AES/GCM (2K tables)", MakeParameters(Name::TableSize(), 2048));
644  BenchMarkByName2<AuthenticatedSymmetricCipher, AuthenticatedSymmetricCipher>("AES/GCM", 0, "AES/GCM (64K tables)", MakeParameters(Name::TableSize(), 64 * 1024));
645  }
646  BenchMarkByName2<AuthenticatedSymmetricCipher, AuthenticatedSymmetricCipher>("AES/CCM");
647  BenchMarkByName2<AuthenticatedSymmetricCipher, AuthenticatedSymmetricCipher>("AES/EAX");
648  }
649 
650  std::cout << "\n</TABLE>" << std::endl;
651 }
652 
653 NAMESPACE_END // Test
654 NAMESPACE_END // CryptoPP
Used to pass byte array input as part of a NameValuePairs object.
Definition: algparam.h:20
int GetIntValueWithDefault(const char *name, int defaultValue) const
Get a named value with type int, with default.
Definition: cryptlib.h:392
virtual bool NeedsPrespecifiedDataLengths() const
Determines if data lengths must be specified prior to inputting data.
Definition: cryptlib.h:1296
virtual void SetKey(const byte *key, size_t length, const NameValuePairs &params=g_nullNameValuePairs)
Sets or reset the key of this object.
Definition: cryptlib.cpp:64
Classes for NIST DRBGs from SP 800-90A.
const char * Rounds()
int
Definition: argnames.h:24
virtual void GenerateBlock(byte *output, size_t size)=0
Generate random array of bytes.
Interface for authenticated encryption modes of operation.
Definition: cryptlib.h:1267
Classes for block cipher modes of operation.
virtual void GenerateBlock(byte *output, size_t size)
Generate random array of bytes.
Definition: cryptlib.cpp:317
Classes for VIA Padlock RNG.
bool HasPadlockRNG()
Determines Padlock RNG availability.
Definition: cpu.h:239
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.
Definition: cryptlib.h:1330
Common C++ header files.
void ProcessString(byte *inoutString, size_t length)
Encrypt or decrypt a string of bytes.
Definition: cryptlib.h:1013
Classes for RDRAND and RDSEED.
Combines two sets of NameValuePairs.
Definition: algparam.h:124
virtual size_t DefaultKeyLength() const =0
Returns default key length.
Interface for buffered transformations.
Definition: cryptlib.h:1545
bool HasRDRAND()
Determines RDRAND availability.
Definition: cpu.h:217
Pointer that overloads operator ->
Definition: smartptr.h:36
const char * TableSize()
int, in bytes
Definition: argnames.h:81
size_t Put(byte inByte, bool blocking=true)
Input a byte for processing.
Definition: cryptlib.h:1567
AlgorithmParameters MakeParameters(const char *name, const T &value, bool throwIfNotUsed=true)
Create an object that implements NameValuePairs.
Definition: algparam.h:502
Classes for HexEncoder and HexDecoder.
bool HasRDSEED()
Determines RDSEED availability.
Definition: cpu.h:228
bool HasCLMUL()
Determines Carryless Multiply availability.
Definition: cpu.h:173
Class file for the AES cipher (Rijndael)
Interface for one direction (encryption or decryption) of a stream cipher or cipher mode.
Definition: cryptlib.h:1237
Interface for algorithms that take byte strings as keys.
Definition: cryptlib.h:599
Namespace containing testing and benchmark classes.
Definition: cryptlib.h:550
Classes for the Threefish block cipher.
SecBlock using AllocatorWithCleanup<byte, true> typedef.
Definition: secblock.h:826
Classes and functions for registering and locating library objects.
Classes for the Kalyna block cipher.
Interface for the data processing portion of stream ciphers.
Definition: cryptlib.h:898
const char * BlockSize()
int, in bytes
Definition: argnames.h:27
Functions for CPU features and intrinsics.
virtual void IncorporateEntropy(const byte *input, size_t length)=0
Update RNG state with additional unpredictable values.
Implementation of BufferedTransformation's attachment interface.
const char * IV()
ConstByteArrayParameter, also accepts const byte * for backwards compatibility.
Definition: argnames.h:21
virtual lword MaxMessageLength() const =0
Provides the maximum length of encrypted data.
void SetKeyWithIV(const byte *key, size_t length, const byte *iv, size_t ivLength)
Sets or reset the key of this object.
Definition: cryptlib.cpp:75
const NameValuePairs g_nullNameValuePairs
An empty set of name-value pairs.
Definition: cryptlib.h:494
Interface for NIST DRBGs from SP 800-90A.
Definition: drbg.h:24
Classes for Blum Blum Shub generator.
Interface for hash functions and data processing part of MACs.
Definition: cryptlib.h:1065
std::string IntToString(T value, unsigned int base=10)
Converts a value to a string.
Definition: misc.h:576
T1 RoundUpToMultipleOf(const T1 &n, const T2 &m)
Rounds a value up to a multiple of a second value.
Definition: misc.h:971
Classes providing file-based library services.
void SpecifyDataLengths(lword headerLength, lword messageLength, lword footerLength=0)
Prespecifies the data lengths.
Definition: cryptlib.cpp:239
Crypto++ library namespace.
bool IsResynchronizable() const
Determines if the object can be resynchronized.
Definition: cryptlib.h:693
Object factory registry.
Definition: factory.h:42
virtual unsigned int OptimalBlockSize() const
Provides the input block size most efficient for this cipher.
Definition: cryptlib.h:925
virtual void Update(const byte *input, size_t length)=0
Updates a hash with additional input.
bool HasPMULL()
Determine if an ARM processor provides Polynomial Multiplication.
Definition: cpu.h:348
Interface for retrieving values given their names.
Definition: cryptlib.h:290