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