]> git.sur5r.net Git - freertos/blob - FreeRTOS-Plus/CyaSSL/ctaocrypt/benchmark/benchmark.c
Prepare for V7.2.0 release.
[freertos] / FreeRTOS-Plus / CyaSSL / ctaocrypt / benchmark / benchmark.c
1 /* benchmark.c
2  *
3  * Copyright (C) 2006-2012 Sawtooth Consulting Ltd.
4  *
5  * This file is part of CyaSSL.
6  *
7  * CyaSSL is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 2 of the License, or
10  * (at your option) any later version.
11  *
12  * CyaSSL is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
20  */
21
22 /* CTaoCrypt benchmark */
23
24 #ifdef HAVE_CONFIG_H
25     #include <config.h>
26 #endif
27
28 #include <string.h>
29 #include <stdio.h>
30
31 #include <cyassl/ctaocrypt/des3.h>
32 #include <cyassl/ctaocrypt/arc4.h>
33 #include <cyassl/ctaocrypt/hc128.h>
34 #include <cyassl/ctaocrypt/rabbit.h>
35 #include <cyassl/ctaocrypt/aes.h>
36 #include <cyassl/ctaocrypt/md5.h>
37 #include <cyassl/ctaocrypt/sha.h>
38 #include <cyassl/ctaocrypt/sha256.h>
39 #include <cyassl/ctaocrypt/sha512.h>
40 #include <cyassl/ctaocrypt/rsa.h>
41 #include <cyassl/ctaocrypt/asn.h>
42 #include <cyassl/ctaocrypt/ripemd.h>
43 #include <cyassl/ctaocrypt/ecc.h>
44
45 #include <cyassl/ctaocrypt/dh.h>
46
47 #ifdef _MSC_VER
48     /* 4996 warning to use MS extensions e.g., strcpy_s instead of strncpy */
49     #pragma warning(disable: 4996)
50 #endif
51
52 void bench_des();
53 void bench_arc4();
54 void bench_hc128();
55 void bench_rabbit();
56 void bench_aes(int);
57 void bench_aesgcm();
58
59 void bench_md5();
60 void bench_sha();
61 void bench_sha256();
62 void bench_sha512();
63 void bench_ripemd();
64
65 void bench_rsa();
66 void bench_rsaKeyGen();
67 void bench_dh();
68 #ifdef HAVE_ECC
69 void bench_eccKeyGen();
70 void bench_eccKeyAgree();
71 #endif
72
73 double current_time();
74
75
76
77 int main(int argc, char** argv)
78 {
79 #ifndef NO_AES
80     bench_aes(0);
81     bench_aes(1);
82 #endif
83 #ifdef HAVE_AESGCM
84     bench_aesgcm();
85 #endif
86     bench_arc4();
87 #ifdef HAVE_HC128
88     bench_hc128();
89 #endif
90 #ifndef NO_RABBIT
91     bench_rabbit();
92 #endif
93 #ifndef NO_DES3
94     bench_des();
95 #endif
96     
97     printf("\n");
98
99     bench_md5();
100     bench_sha();
101 #ifndef NO_SHA256
102     bench_sha256();
103 #endif
104 #ifdef CYASSL_SHA512
105     bench_sha512();
106 #endif
107 #ifdef CYASSL_RIPEMD
108     bench_ripemd();
109 #endif
110
111     printf("\n");
112     
113     bench_rsa();
114
115 #ifndef NO_DH
116     bench_dh();
117 #endif
118
119 #ifdef CYASSL_KEY_GEN
120     bench_rsaKeyGen();
121 #endif
122
123 #ifdef HAVE_ECC 
124     bench_eccKeyGen();
125     bench_eccKeyAgree();
126 #endif
127
128     return 0;
129 }
130
131 const int megs  = 5;     /* how many megs to test (en/de)cryption */
132 const int times = 100;   /* public key iterations */
133
134 const byte key[] = 
135 {
136     0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef,
137     0xfe,0xde,0xba,0x98,0x76,0x54,0x32,0x10,
138     0x89,0xab,0xcd,0xef,0x01,0x23,0x45,0x67
139 };
140
141 const byte iv[] = 
142 {
143     0x12,0x34,0x56,0x78,0x90,0xab,0xcd,0xef,
144     0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
145     0x11,0x21,0x31,0x41,0x51,0x61,0x71,0x81
146     
147 };
148
149
150 byte plain [1024*1024];
151 byte cipher[1024*1024];
152
153
154 #ifndef NO_AES
155 void bench_aes(int show)
156 {
157     Aes    enc;
158     double start, total, persec;
159     int    i;
160
161     AesSetKey(&enc, key, 16, iv, AES_ENCRYPTION);
162     start = current_time();
163
164     for(i = 0; i < megs; i++)
165         AesCbcEncrypt(&enc, plain, cipher, sizeof(plain));
166
167     total = current_time() - start;
168
169     persec = 1 / total * megs;
170
171     if (show)
172         printf("AES      %d megs took %5.3f seconds, %6.2f MB/s\n", megs, total,
173                                                                     persec);
174 }
175 #endif
176
177
178 byte additional[13];
179 byte tag[16];
180
181
182 #ifdef HAVE_AESGCM
183 void bench_aesgcm()
184 {
185     Aes    enc;
186     double start, total, persec;
187     int    i;
188
189     AesGcmSetKey(&enc, key, 16, iv);
190     AesGcmSetExpIV(&enc, iv+4);
191     start = current_time();
192
193     for(i = 0; i < megs; i++)
194         AesGcmEncrypt(&enc, cipher, plain, sizeof(plain),
195                         tag, 16, additional, 13);
196
197     total = current_time() - start;
198
199     persec = 1 / total * megs;
200     printf("AES-GCM  %d megs took %5.3f seconds, %6.2f MB/s\n", megs, total,
201                                                                     persec);
202 }
203 #endif
204
205
206 #ifndef NO_DES3
207 void bench_des()
208 {
209     Des3   enc;
210     double start, total, persec;
211     int    i;
212
213     Des3_SetKey(&enc, key, iv, DES_ENCRYPTION);
214     start = current_time();
215
216     for(i = 0; i < megs; i++)
217         Des3_CbcEncrypt(&enc, plain, cipher, sizeof(plain));
218
219     total = current_time() - start;
220
221     persec = 1 / total * megs;
222
223     printf("3DES     %d megs took %5.3f seconds, %6.2f MB/s\n", megs, total,
224                                                              persec);
225 }
226 #endif
227
228
229 void bench_arc4()
230 {
231     Arc4   enc;
232     double start, total, persec;
233     int    i;
234     
235     Arc4SetKey(&enc, key, 16);
236     start = current_time();
237
238     for(i = 0; i < megs; i++)
239         Arc4Process(&enc, cipher, plain, sizeof(plain));
240
241     total = current_time() - start;
242     persec = 1 / total * megs;
243
244     printf("ARC4     %d megs took %5.3f seconds, %6.2f MB/s\n", megs, total,
245                                                              persec);
246 }
247
248
249 #ifdef HAVE_HC128
250 void bench_hc128()
251 {
252     HC128  enc;
253     double start, total, persec;
254     int    i;
255     
256     Hc128_SetKey(&enc, key, iv);
257     start = current_time();
258
259     for(i = 0; i < megs; i++)
260         Hc128_Process(&enc, cipher, plain, sizeof(plain));
261
262     total = current_time() - start;
263     persec = 1 / total * megs;
264
265     printf("HC128    %d megs took %5.3f seconds, %6.2f MB/s\n", megs, total,
266                                                              persec);
267 }
268 #endif /* HAVE_HC128 */
269
270
271 #ifndef NO_RABBIT
272 void bench_rabbit()
273 {
274     Rabbit  enc;
275     double start, total, persec;
276     int    i;
277     
278     RabbitSetKey(&enc, key, iv);
279     start = current_time();
280
281     for(i = 0; i < megs; i++)
282         RabbitProcess(&enc, cipher, plain, sizeof(plain));
283
284     total = current_time() - start;
285     persec = 1 / total * megs;
286
287     printf("RABBIT   %d megs took %5.3f seconds, %6.2f MB/s\n", megs, total,
288                                                              persec);
289 }
290 #endif /* NO_RABBIT */
291
292
293 void bench_md5()
294 {
295     Md5    hash;
296     byte   digest[MD5_DIGEST_SIZE];
297     double start, total, persec;
298     int    i;
299
300     InitMd5(&hash);
301     start = current_time();
302
303     for(i = 0; i < megs; i++)
304         Md5Update(&hash, plain, sizeof(plain));
305    
306     Md5Final(&hash, digest);
307
308     total = current_time() - start;
309     persec = 1 / total * megs;
310
311     printf("MD5      %d megs took %5.3f seconds, %6.2f MB/s\n", megs, total,
312                                                              persec);
313 }
314
315
316 void bench_sha()
317 {
318     Sha    hash;
319     byte   digest[SHA_DIGEST_SIZE];
320     double start, total, persec;
321     int    i;
322         
323     InitSha(&hash);
324     start = current_time();
325     
326     for(i = 0; i < megs; i++)
327         ShaUpdate(&hash, plain, sizeof(plain));
328    
329     ShaFinal(&hash, digest);
330
331     total = current_time() - start;
332     persec = 1 / total * megs;
333
334     printf("SHA      %d megs took %5.3f seconds, %6.2f MB/s\n", megs, total,
335                                                              persec);
336 }
337
338
339 #ifndef NO_SHA256
340 void bench_sha256()
341 {
342     Sha256 hash;
343     byte   digest[SHA256_DIGEST_SIZE];
344     double start, total, persec;
345     int    i;
346         
347     InitSha256(&hash);
348     start = current_time();
349     
350     for(i = 0; i < megs; i++)
351         Sha256Update(&hash, plain, sizeof(plain));
352    
353     Sha256Final(&hash, digest);
354
355     total = current_time() - start;
356     persec = 1 / total * megs;
357
358     printf("SHA-256  %d megs took %5.3f seconds, %6.2f MB/s\n", megs, total,
359                                                              persec);
360 }
361 #endif
362
363 #ifdef CYASSL_SHA512
364 void bench_sha512()
365 {
366     Sha512 hash;
367     byte   digest[SHA512_DIGEST_SIZE];
368     double start, total, persec;
369     int    i;
370         
371     InitSha512(&hash);
372     start = current_time();
373     
374     for(i = 0; i < megs; i++)
375         Sha512Update(&hash, plain, sizeof(plain));
376    
377     Sha512Final(&hash, digest);
378
379     total = current_time() - start;
380     persec = 1 / total * megs;
381
382     printf("SHA-512  %d megs took %5.3f seconds, %6.2f MB/s\n", megs, total,
383                                                              persec);
384 }
385 #endif
386
387 #ifdef CYASSL_RIPEMD
388 void bench_ripemd()
389 {
390     RipeMd hash;
391     byte   digest[RIPEMD_DIGEST_SIZE];
392     double start, total, persec;
393     int    i;
394         
395     InitRipeMd(&hash);
396     start = current_time();
397     
398     for(i = 0; i < megs; i++)
399         RipeMdUpdate(&hash, plain, sizeof(plain));
400    
401     RipeMdFinal(&hash, digest);
402
403     total = current_time() - start;
404     persec = 1 / total * megs;
405
406     printf("RIPEMD   %d megs took %5.3f seconds, %6.2f MB/s\n", megs, total,
407                                                              persec);
408 }
409 #endif
410
411
412 RNG rng;
413
414 void bench_rsa()
415 {
416     int    i;
417     byte   tmp[4096];
418     size_t bytes;
419     word32 idx = 0;
420
421     byte      message[] = "Everyone gets Friday off.";
422     byte      cipher[512];  /* for up to 4096 bit */
423     byte*     output;
424     const int len = (int)strlen((char*)message);
425     double    start, total, each, milliEach;
426     
427     RsaKey key;
428     FILE*  file = fopen("./certs/rsa2048.der", "rb");
429
430     if (!file) {
431         printf("can't find ./certs/rsa2048.der, "
432                "Please run from CyaSSL home dir\n");
433         return;
434     }
435
436     InitRng(&rng);
437     bytes = fread(tmp, 1, sizeof(tmp), file);
438     InitRsaKey(&key, 0);
439     bytes = RsaPrivateKeyDecode(tmp, &idx, &key, (word32)bytes);
440     
441     start = current_time();
442
443     for (i = 0; i < times; i++)
444         bytes = RsaPublicEncrypt(message,len,cipher,sizeof(cipher), &key, &rng);
445
446     total = current_time() - start;
447     each  = total / times;   /* per second   */
448     milliEach = each * 1000; /* milliseconds */
449
450     printf("RSA 2048 encryption took %6.2f milliseconds, avg over %d" 
451            " iterations\n", milliEach, times);
452
453     start = current_time();
454
455     for (i = 0; i < times; i++)
456         RsaPrivateDecryptInline(cipher, (word32)bytes, &output, &key);
457
458     total = current_time() - start;
459     each  = total / times;   /* per second   */
460     milliEach = each * 1000; /* milliseconds */
461
462     printf("RSA 2048 decryption took %6.2f milliseconds, avg over %d" 
463            " iterations\n", milliEach, times);
464
465     fclose(file);
466     FreeRsaKey(&key);
467 }
468
469
470 #ifndef NO_DH
471 void bench_dh()
472 {
473     int    i;
474     byte   tmp[1024];
475     size_t bytes;
476     word32 idx = 0, pubSz, privSz, pubSz2, privSz2, agreeSz;
477
478     byte   pub[256];    /* for 2048 bit */
479     byte   priv[256];   /* for 2048 bit */
480     byte   pub2[256];   /* for 2048 bit */
481     byte   priv2[256];  /* for 2048 bit */
482     byte   agree[256];  /* for 2048 bit */
483     
484     double start, total, each, milliEach;
485     DhKey  key;
486     FILE*  file = fopen("./certs/dh2048.der", "rb");
487
488     if (!file) {
489         printf("can't find ./certs/dh2048.der, "
490                "Please run from CyaSSL home dir\n");
491         return;
492     }
493
494     bytes = fread(tmp, 1, sizeof(tmp), file);
495     InitDhKey(&key);
496     bytes = DhKeyDecode(tmp, &idx, &key, (word32)bytes);
497
498     start = current_time();
499
500     for (i = 0; i < times; i++)
501         DhGenerateKeyPair(&key, &rng, priv, &privSz, pub, &pubSz);
502
503     total = current_time() - start;
504     each  = total / times;   /* per second   */
505     milliEach = each * 1000; /* milliseconds */
506
507     printf("DH  2048 key generation  %6.2f milliseconds, avg over %d" 
508            " iterations\n", milliEach, times);
509
510     DhGenerateKeyPair(&key, &rng, priv2, &privSz2, pub2, &pubSz2);
511     start = current_time();
512
513     for (i = 0; i < times; i++)
514         DhAgree(&key, agree, &agreeSz, priv, privSz, pub2, pubSz2);
515
516     total = current_time() - start;
517     each  = total / times;   /* per second   */
518     milliEach = each * 1000; /* milliseconds */
519
520     printf("DH  2048 key agreement   %6.2f milliseconds, avg over %d" 
521            " iterations\n", milliEach, times);
522
523     fclose(file);
524     FreeDhKey(&key);
525 }
526 #endif
527
528 #ifdef CYASSL_KEY_GEN
529 void bench_rsaKeyGen()
530 {
531     RsaKey genKey;
532     double start, total, each, milliEach;
533     int    i;
534     const int genTimes = 5;
535   
536     /* 1024 bit */ 
537     start = current_time();
538
539     for(i = 0; i < genTimes; i++) {
540         InitRsaKey(&genKey, 0); 
541         MakeRsaKey(&genKey, 1024, 65537, &rng);
542         FreeRsaKey(&genKey);
543     }
544
545     total = current_time() - start;
546     each  = total / genTimes;  /* per second  */
547     milliEach = each * 1000;   /* millisconds */
548     printf("\n");
549     printf("RSA 1024 key generation  %6.2f milliseconds, avg over %d" 
550            " iterations\n", milliEach, genTimes);
551
552     /* 2048 bit */
553     start = current_time();
554
555     for(i = 0; i < genTimes; i++) {
556         InitRsaKey(&genKey, 0); 
557         MakeRsaKey(&genKey, 2048, 65537, &rng);
558         FreeRsaKey(&genKey);
559     }
560
561     total = current_time() - start;
562     each  = total / genTimes;  /* per second  */
563     milliEach = each * 1000;   /* millisconds */
564     printf("RSA 2048 key generation  %6.2f milliseconds, avg over %d" 
565            " iterations\n", milliEach, genTimes);
566 }
567 #endif /* CYASSL_KEY_GEN */
568
569 #ifdef HAVE_ECC 
570 void bench_eccKeyGen()
571 {
572     ecc_key genKey;
573     double start, total, each, milliEach;
574     int    i;
575     const int genTimes = 5;
576   
577     /* 256 bit */ 
578     start = current_time();
579
580     for(i = 0; i < genTimes; i++) {
581         int ret = ecc_make_key(&rng, 32, &genKey);
582         ecc_free(&genKey);
583     }
584
585     total = current_time() - start;
586     each  = total / genTimes;  /* per second  */
587     milliEach = each * 1000;   /* millisconds */
588     printf("\n");
589     printf("ECC  256 key generation  %6.2f milliseconds, avg over %d" 
590            " iterations\n", milliEach, genTimes);
591 }
592
593
594 void bench_eccKeyAgree()
595 {
596     ecc_key genKey, genKey2;
597     double start, total, each, milliEach;
598     int    i;
599     const int agreeTimes = 5;
600     byte   shared[1024];
601     byte   sig[1024];
602     byte   digest[32];
603     word32 x;
604   
605     ecc_make_key(&rng, 32, &genKey);
606     ecc_make_key(&rng, 32, &genKey2);
607
608     /* 256 bit */ 
609     start = current_time();
610
611     for(i = 0; i < agreeTimes; i++) {
612         x = sizeof(shared);
613         ecc_shared_secret(&genKey, &genKey2, shared, &x);
614     }
615
616     total = current_time() - start;
617     each  = total / agreeTimes;  /* per second  */
618     milliEach = each * 1000;   /* millisconds */
619     printf("EC-DHE   key agreement   %6.2f milliseconds, avg over %d" 
620            " iterations\n", milliEach, agreeTimes);
621
622     /* make dummy digest */
623     for (i = 0; i < sizeof(digest); i++)
624         digest[i] = i;
625
626
627     start = current_time();
628
629     for(i = 0; i < agreeTimes; i++) {
630         x = sizeof(sig);
631         ecc_sign_hash(digest, sizeof(digest), sig, &x, &rng, &genKey);
632     }
633
634     total = current_time() - start;
635     each  = total / agreeTimes;  /* per second  */
636     milliEach = each * 1000;   /* millisconds */
637     printf("EC-DSA   sign time       %6.2f milliseconds, avg over %d" 
638            " iterations\n", milliEach, agreeTimes);
639
640     ecc_free(&genKey2);
641     ecc_free(&genKey);
642 }
643 #endif /* HAVE_ECC */
644
645
646 #ifdef _WIN32
647
648     #define WIN32_LEAN_AND_MEAN
649     #include <windows.h>
650
651     double current_time()
652     {
653         static int init = 0;
654         static LARGE_INTEGER freq;
655     
656         LARGE_INTEGER count;
657
658         if (!init) {
659             QueryPerformanceFrequency(&freq);
660             init = 1;
661         }
662
663         QueryPerformanceCounter(&count);
664
665         return (double)count.QuadPart / freq.QuadPart;
666     }
667
668 #else
669
670     #include <sys/time.h>
671
672     double current_time()
673     {
674         struct timeval tv;
675         gettimeofday(&tv, 0);
676
677         return (double)tv.tv_sec + (double)tv.tv_usec / 1000000;
678     }
679
680 #endif /* _WIN32 */
681