Team Fortress 2 Source Code as on 22/4/2020
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

337 lines
12 KiB

  1. // bench2.cpp - written and placed in the public domain by Wei Dai
  2. #include "cryptlib.h"
  3. #include "pubkey.h"
  4. #include "gfpcrypt.h"
  5. #include "eccrypto.h"
  6. #include "bench.h"
  7. #include "validate.h"
  8. #include "files.h"
  9. #include "filters.h"
  10. #include "hex.h"
  11. #include "rsa.h"
  12. #include "nr.h"
  13. #include "dsa.h"
  14. #include "luc.h"
  15. #include "rw.h"
  16. #include "eccrypto.h"
  17. #include "ecp.h"
  18. #include "ec2n.h"
  19. #include "asn.h"
  20. #include "dh.h"
  21. #include "mqv.h"
  22. #include "xtrcrypt.h"
  23. #include "esign.h"
  24. #include "pssr.h"
  25. #include "oids.h"
  26. #include "randpool.h"
  27. #include <time.h>
  28. #include <math.h>
  29. #include <iostream>
  30. #include <iomanip>
  31. // These are noisy enoguh due to test.cpp. Turn them off here.
  32. #if CRYPTOPP_GCC_DIAGNOSTIC_AVAILABLE
  33. # pragma GCC diagnostic ignored "-Wdeprecated-declarations"
  34. #endif
  35. USING_NAMESPACE(CryptoPP)
  36. USING_NAMESPACE(std)
  37. void OutputResultOperations(const char *name, const char *operation, bool pc, unsigned long iterations, double timeTaken);
  38. void BenchMarkEncryption(const char *name, PK_Encryptor &key, double timeTotal, bool pc=false)
  39. {
  40. unsigned int len = 16;
  41. SecByteBlock plaintext(len), ciphertext(key.CiphertextLength(len));
  42. GlobalRNG().GenerateBlock(plaintext, len);
  43. const clock_t start = clock();
  44. unsigned int i;
  45. double timeTaken;
  46. for (timeTaken=(double)0, i=0; timeTaken < timeTotal; timeTaken = double(clock() - start) / CLOCK_TICKS_PER_SECOND, i++)
  47. key.Encrypt(GlobalRNG(), plaintext, len, ciphertext);
  48. OutputResultOperations(name, "Encryption", pc, i, timeTaken);
  49. if (!pc && key.GetMaterial().SupportsPrecomputation())
  50. {
  51. key.AccessMaterial().Precompute(16);
  52. BenchMarkEncryption(name, key, timeTotal, true);
  53. }
  54. }
  55. void BenchMarkDecryption(const char *name, PK_Decryptor &priv, PK_Encryptor &pub, double timeTotal)
  56. {
  57. unsigned int len = 16;
  58. SecByteBlock ciphertext(pub.CiphertextLength(len));
  59. SecByteBlock plaintext(pub.MaxPlaintextLength(ciphertext.size()));
  60. GlobalRNG().GenerateBlock(plaintext, len);
  61. pub.Encrypt(GlobalRNG(), plaintext, len, ciphertext);
  62. const clock_t start = clock();
  63. unsigned int i;
  64. double timeTaken;
  65. for (timeTaken=(double)0, i=0; timeTaken < timeTotal; timeTaken = double(clock() - start) / CLOCK_TICKS_PER_SECOND, i++)
  66. priv.Decrypt(GlobalRNG(), ciphertext, ciphertext.size(), plaintext);
  67. OutputResultOperations(name, "Decryption", false, i, timeTaken);
  68. }
  69. void BenchMarkSigning(const char *name, PK_Signer &key, double timeTotal, bool pc=false)
  70. {
  71. unsigned int len = 16;
  72. AlignedSecByteBlock message(len), signature(key.SignatureLength());
  73. GlobalRNG().GenerateBlock(message, len);
  74. const clock_t start = clock();
  75. unsigned int i;
  76. double timeTaken;
  77. for (timeTaken=(double)0, i=0; timeTaken < timeTotal; timeTaken = double(clock() - start) / CLOCK_TICKS_PER_SECOND, i++)
  78. key.SignMessage(GlobalRNG(), message, len, signature);
  79. OutputResultOperations(name, "Signature", pc, i, timeTaken);
  80. if (!pc && key.GetMaterial().SupportsPrecomputation())
  81. {
  82. key.AccessMaterial().Precompute(16);
  83. BenchMarkSigning(name, key, timeTotal, true);
  84. }
  85. }
  86. void BenchMarkVerification(const char *name, const PK_Signer &priv, PK_Verifier &pub, double timeTotal, bool pc=false)
  87. {
  88. unsigned int len = 16;
  89. AlignedSecByteBlock message(len), signature(pub.SignatureLength());
  90. GlobalRNG().GenerateBlock(message, len);
  91. priv.SignMessage(GlobalRNG(), message, len, signature);
  92. const clock_t start = clock();
  93. unsigned int i;
  94. double timeTaken;
  95. for (timeTaken=(double)0, i=0; timeTaken < timeTotal; timeTaken = double(clock() - start) / CLOCK_TICKS_PER_SECOND, i++)
  96. {
  97. // The return value is ignored because we are interested in throughput
  98. bool unused = pub.VerifyMessage(message, len, signature, signature.size());
  99. CRYPTOPP_UNUSED(unused);
  100. }
  101. OutputResultOperations(name, "Verification", pc, i, timeTaken);
  102. if (!pc && pub.GetMaterial().SupportsPrecomputation())
  103. {
  104. pub.AccessMaterial().Precompute(16);
  105. BenchMarkVerification(name, priv, pub, timeTotal, true);
  106. }
  107. }
  108. void BenchMarkKeyGen(const char *name, SimpleKeyAgreementDomain &d, double timeTotal, bool pc=false)
  109. {
  110. SecByteBlock priv(d.PrivateKeyLength()), pub(d.PublicKeyLength());
  111. const clock_t start = clock();
  112. unsigned int i;
  113. double timeTaken;
  114. for (timeTaken=(double)0, i=0; timeTaken < timeTotal; timeTaken = double(clock() - start) / CLOCK_TICKS_PER_SECOND, i++)
  115. d.GenerateKeyPair(GlobalRNG(), priv, pub);
  116. OutputResultOperations(name, "Key-Pair Generation", pc, i, timeTaken);
  117. if (!pc && d.GetMaterial().SupportsPrecomputation())
  118. {
  119. d.AccessMaterial().Precompute(16);
  120. BenchMarkKeyGen(name, d, timeTotal, true);
  121. }
  122. }
  123. void BenchMarkKeyGen(const char *name, AuthenticatedKeyAgreementDomain &d, double timeTotal, bool pc=false)
  124. {
  125. SecByteBlock priv(d.EphemeralPrivateKeyLength()), pub(d.EphemeralPublicKeyLength());
  126. const clock_t start = clock();
  127. unsigned int i;
  128. double timeTaken;
  129. for (timeTaken=(double)0, i=0; timeTaken < timeTotal; timeTaken = double(clock() - start) / CLOCK_TICKS_PER_SECOND, i++)
  130. d.GenerateEphemeralKeyPair(GlobalRNG(), priv, pub);
  131. OutputResultOperations(name, "Key-Pair Generation", pc, i, timeTaken);
  132. if (!pc && d.GetMaterial().SupportsPrecomputation())
  133. {
  134. d.AccessMaterial().Precompute(16);
  135. BenchMarkKeyGen(name, d, timeTotal, true);
  136. }
  137. }
  138. void BenchMarkAgreement(const char *name, SimpleKeyAgreementDomain &d, double timeTotal, bool pc=false)
  139. {
  140. SecByteBlock priv1(d.PrivateKeyLength()), priv2(d.PrivateKeyLength());
  141. SecByteBlock pub1(d.PublicKeyLength()), pub2(d.PublicKeyLength());
  142. d.GenerateKeyPair(GlobalRNG(), priv1, pub1);
  143. d.GenerateKeyPair(GlobalRNG(), priv2, pub2);
  144. SecByteBlock val(d.AgreedValueLength());
  145. const clock_t start = clock();
  146. unsigned int i;
  147. double timeTaken;
  148. for (timeTaken=(double)0, i=0; timeTaken < timeTotal; timeTaken = double(clock() - start) / CLOCK_TICKS_PER_SECOND, i+=2)
  149. {
  150. d.Agree(val, priv1, pub2);
  151. d.Agree(val, priv2, pub1);
  152. }
  153. OutputResultOperations(name, "Key Agreement", pc, i, timeTaken);
  154. }
  155. void BenchMarkAgreement(const char *name, AuthenticatedKeyAgreementDomain &d, double timeTotal, bool pc=false)
  156. {
  157. SecByteBlock spriv1(d.StaticPrivateKeyLength()), spriv2(d.StaticPrivateKeyLength());
  158. SecByteBlock epriv1(d.EphemeralPrivateKeyLength()), epriv2(d.EphemeralPrivateKeyLength());
  159. SecByteBlock spub1(d.StaticPublicKeyLength()), spub2(d.StaticPublicKeyLength());
  160. SecByteBlock epub1(d.EphemeralPublicKeyLength()), epub2(d.EphemeralPublicKeyLength());
  161. d.GenerateStaticKeyPair(GlobalRNG(), spriv1, spub1);
  162. d.GenerateStaticKeyPair(GlobalRNG(), spriv2, spub2);
  163. d.GenerateEphemeralKeyPair(GlobalRNG(), epriv1, epub1);
  164. d.GenerateEphemeralKeyPair(GlobalRNG(), epriv2, epub2);
  165. SecByteBlock val(d.AgreedValueLength());
  166. const clock_t start = clock();
  167. unsigned int i;
  168. double timeTaken;
  169. for (timeTaken=(double)0, i=0; timeTaken < timeTotal; timeTaken = double(clock() - start) / CLOCK_TICKS_PER_SECOND, i+=2)
  170. {
  171. d.Agree(val, spriv1, epriv1, spub2, epub2);
  172. d.Agree(val, spriv2, epriv2, spub1, epub1);
  173. }
  174. OutputResultOperations(name, "Key Agreement", pc, i, timeTaken);
  175. }
  176. //VC60 workaround: compiler bug triggered without the extra dummy parameters
  177. template <class SCHEME>
  178. void BenchMarkCrypto(const char *filename, const char *name, double timeTotal, SCHEME *x=NULL)
  179. {
  180. CRYPTOPP_UNUSED(x);
  181. FileSource f(filename, true, new HexDecoder());
  182. typename SCHEME::Decryptor priv(f);
  183. typename SCHEME::Encryptor pub(priv);
  184. BenchMarkEncryption(name, pub, timeTotal);
  185. BenchMarkDecryption(name, priv, pub, timeTotal);
  186. }
  187. //VC60 workaround: compiler bug triggered without the extra dummy parameters
  188. template <class SCHEME>
  189. void BenchMarkSignature(const char *filename, const char *name, double timeTotal, SCHEME *x=NULL)
  190. {
  191. CRYPTOPP_UNUSED(x);
  192. FileSource f(filename, true, new HexDecoder());
  193. typename SCHEME::Signer priv(f);
  194. typename SCHEME::Verifier pub(priv);
  195. BenchMarkSigning(name, priv, timeTotal);
  196. BenchMarkVerification(name, priv, pub, timeTotal);
  197. }
  198. //VC60 workaround: compiler bug triggered without the extra dummy parameters
  199. template <class D>
  200. void BenchMarkKeyAgreement(const char *filename, const char *name, double timeTotal, D *x=NULL)
  201. {
  202. CRYPTOPP_UNUSED(x);
  203. FileSource f(filename, true, new HexDecoder());
  204. D d(f);
  205. BenchMarkKeyGen(name, d, timeTotal);
  206. BenchMarkAgreement(name, d, timeTotal);
  207. }
  208. extern double g_hertz;
  209. void BenchmarkAll2(double t, double hertz)
  210. {
  211. g_hertz = hertz;
  212. cout << "<TABLE border=1><COLGROUP><COL align=left><COL align=right><COL align=right>" << endl;
  213. cout << "<THEAD><TR><TH>Operation<TH>Milliseconds/Operation" << (g_hertz ? "<TH>Megacycles/Operation" : "") << endl;
  214. cout << "\n<TBODY style=\"background: yellow\">";
  215. BenchMarkCrypto<RSAES<OAEP<SHA> > >("TestData/rsa1024.dat", "RSA 1024", t);
  216. BenchMarkCrypto<LUCES<OAEP<SHA> > >("TestData/luc1024.dat", "LUC 1024", t);
  217. BenchMarkCrypto<DLIES<> >("TestData/dlie1024.dat", "DLIES 1024", t);
  218. BenchMarkCrypto<LUC_IES<> >("TestData/lucc512.dat", "LUCELG 512", t);
  219. cout << "\n<TBODY style=\"background: white\">";
  220. BenchMarkCrypto<RSAES<OAEP<SHA> > >("TestData/rsa2048.dat", "RSA 2048", t);
  221. BenchMarkCrypto<LUCES<OAEP<SHA> > >("TestData/luc2048.dat", "LUC 2048", t);
  222. BenchMarkCrypto<DLIES<> >("TestData/dlie2048.dat", "DLIES 2048", t);
  223. BenchMarkCrypto<LUC_IES<> >("TestData/lucc1024.dat", "LUCELG 1024", t);
  224. cout << "\n<TBODY style=\"background: yellow\">";
  225. BenchMarkSignature<RSASS<PSSR, SHA> >("TestData/rsa1024.dat", "RSA 1024", t);
  226. BenchMarkSignature<RWSS<PSSR, SHA> >("TestData/rw1024.dat", "RW 1024", t);
  227. BenchMarkSignature<LUCSS<PSSR, SHA> >("TestData/luc1024.dat", "LUC 1024", t);
  228. BenchMarkSignature<NR<SHA> >("TestData/nr1024.dat", "NR 1024", t);
  229. BenchMarkSignature<DSA>("TestData/dsa1024.dat", "DSA 1024", t);
  230. BenchMarkSignature<LUC_HMP<SHA> >("TestData/lucs512.dat", "LUC-HMP 512", t);
  231. BenchMarkSignature<ESIGN<SHA> >("TestData/esig1023.dat", "ESIGN 1023", t);
  232. BenchMarkSignature<ESIGN<SHA> >("TestData/esig1536.dat", "ESIGN 1536", t);
  233. cout << "\n<TBODY style=\"background: white\">";
  234. BenchMarkSignature<RSASS<PSSR, SHA> >("TestData/rsa2048.dat", "RSA 2048", t);
  235. BenchMarkSignature<RWSS<PSSR, SHA> >("TestData/rw2048.dat", "RW 2048", t);
  236. BenchMarkSignature<LUCSS<PSSR, SHA> >("TestData/luc2048.dat", "LUC 2048", t);
  237. BenchMarkSignature<NR<SHA> >("TestData/nr2048.dat", "NR 2048", t);
  238. BenchMarkSignature<LUC_HMP<SHA> >("TestData/lucs1024.dat", "LUC-HMP 1024", t);
  239. BenchMarkSignature<ESIGN<SHA> >("TestData/esig2046.dat", "ESIGN 2046", t);
  240. cout << "\n<TBODY style=\"background: yellow\">";
  241. BenchMarkKeyAgreement<XTR_DH>("TestData/xtrdh171.dat", "XTR-DH 171", t);
  242. BenchMarkKeyAgreement<XTR_DH>("TestData/xtrdh342.dat", "XTR-DH 342", t);
  243. BenchMarkKeyAgreement<DH>("TestData/dh1024.dat", "DH 1024", t);
  244. BenchMarkKeyAgreement<DH>("TestData/dh2048.dat", "DH 2048", t);
  245. BenchMarkKeyAgreement<LUC_DH>("TestData/lucd512.dat", "LUCDIF 512", t);
  246. BenchMarkKeyAgreement<LUC_DH>("TestData/lucd1024.dat", "LUCDIF 1024", t);
  247. BenchMarkKeyAgreement<MQV>("TestData/mqv1024.dat", "MQV 1024", t);
  248. BenchMarkKeyAgreement<MQV>("TestData/mqv2048.dat", "MQV 2048", t);
  249. cout << "\n<TBODY style=\"background: white\">";
  250. {
  251. ECIES<ECP>::Decryptor cpriv(GlobalRNG(), ASN1::secp256k1());
  252. ECIES<ECP>::Encryptor cpub(cpriv);
  253. ECDSA<ECP, SHA>::Signer spriv(cpriv);
  254. ECDSA<ECP, SHA>::Verifier spub(spriv);
  255. ECDH<ECP>::Domain ecdhc(ASN1::secp256k1());
  256. ECMQV<ECP>::Domain ecmqvc(ASN1::secp256k1());
  257. BenchMarkEncryption("ECIES over GF(p) 256", cpub, t);
  258. BenchMarkDecryption("ECIES over GF(p) 256", cpriv, cpub, t);
  259. BenchMarkSigning("ECDSA over GF(p) 256", spriv, t);
  260. BenchMarkVerification("ECDSA over GF(p) 256", spriv, spub, t);
  261. BenchMarkKeyGen("ECDHC over GF(p) 256", ecdhc, t);
  262. BenchMarkAgreement("ECDHC over GF(p) 256", ecdhc, t);
  263. BenchMarkKeyGen("ECMQVC over GF(p) 256", ecmqvc, t);
  264. BenchMarkAgreement("ECMQVC over GF(p) 256", ecmqvc, t);
  265. }
  266. cout << "<TBODY style=\"background: yellow\">" << endl;
  267. {
  268. ECIES<EC2N>::Decryptor cpriv(GlobalRNG(), ASN1::sect233r1());
  269. ECIES<EC2N>::Encryptor cpub(cpriv);
  270. ECDSA<EC2N, SHA>::Signer spriv(cpriv);
  271. ECDSA<EC2N, SHA>::Verifier spub(spriv);
  272. ECDH<EC2N>::Domain ecdhc(ASN1::sect233r1());
  273. ECMQV<EC2N>::Domain ecmqvc(ASN1::sect233r1());
  274. BenchMarkEncryption("ECIES over GF(2^n) 233", cpub, t);
  275. BenchMarkDecryption("ECIES over GF(2^n) 233", cpriv, cpub, t);
  276. BenchMarkSigning("ECDSA over GF(2^n) 233", spriv, t);
  277. BenchMarkVerification("ECDSA over GF(2^n) 233", spriv, spub, t);
  278. BenchMarkKeyGen("ECDHC over GF(2^n) 233", ecdhc, t);
  279. BenchMarkAgreement("ECDHC over GF(2^n) 233", ecdhc, t);
  280. BenchMarkKeyGen("ECMQVC over GF(2^n) 233", ecmqvc, t);
  281. BenchMarkAgreement("ECMQVC over GF(2^n) 233", ecmqvc, t);
  282. }
  283. cout << "</TABLE>" << endl;
  284. }