]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/bearssl/test/test_speed.c
bhnd(9): Fix a few mandoc related issues
[FreeBSD/FreeBSD.git] / contrib / bearssl / test / test_speed.c
1 /*
2  * Copyright (c) 2016 Thomas Pornin <pornin@bolet.org>
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining 
5  * a copy of this software and associated documentation files (the
6  * "Software"), to deal in the Software without restriction, including
7  * without limitation the rights to use, copy, modify, merge, publish,
8  * distribute, sublicense, and/or sell copies of the Software, and to
9  * permit persons to whom the Software is furnished to do so, subject to
10  * the following conditions:
11  *
12  * The above copyright notice and this permission notice shall be 
13  * included in all copies or substantial portions of the Software.
14  *
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 
16  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 
18  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
19  * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
20  * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
21  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22  * SOFTWARE.
23  */
24
25 #include <stdio.h>
26 #include <stdlib.h>
27 #include <string.h>
28 #include <time.h>
29 #include "inner.h"
30
31 #define HASH_SIZE(cname)   br_ ## cname ## _SIZE
32
33 #define SPEED_HASH(Name, cname) \
34 static void \
35 test_speed_ ## cname(void) \
36 { \
37         unsigned char buf[8192]; \
38         unsigned char tmp[HASH_SIZE(cname)]; \
39         br_ ## cname ## _context mc; \
40         int i; \
41         long num; \
42  \
43         memset(buf, 'T', sizeof buf); \
44         for (i = 0; i < 10; i ++) { \
45                 br_ ## cname ## _init(&mc); \
46                 br_ ## cname ## _update(&mc, buf, sizeof buf); \
47                 br_ ## cname ## _out(&mc, tmp); \
48         } \
49         num = 10; \
50         for (;;) { \
51                 clock_t begin, end; \
52                 double tt; \
53                 long k; \
54  \
55                 br_ ## cname ## _init(&mc); \
56                 begin = clock(); \
57                 for (k = num; k > 0; k --) { \
58                         br_ ## cname ## _update(&mc, buf, sizeof buf); \
59                 } \
60                 end = clock(); \
61                 br_ ## cname ## _out(&mc, tmp); \
62                 tt = (double)(end - begin) / CLOCKS_PER_SEC; \
63                 if (tt >= 2.0) { \
64                         printf("%-30s %8.2f MB/s\n", #Name, \
65                                 ((double)sizeof buf) * (double)num \
66                                 / (tt * 1000000.0)); \
67                         fflush(stdout); \
68                         return; \
69                 } \
70                 num <<= 1; \
71         } \
72 }
73
74 #define BLOCK_SIZE(cname)   br_ ## cname ## _BLOCK_SIZE
75
76 #define SPEED_BLOCKCIPHER_CBC(Name, fname, cname, klen, dir) \
77 static void \
78 test_speed_ ## fname(void) \
79 { \
80         unsigned char key[klen]; \
81         unsigned char buf[8192 - (8192 % BLOCK_SIZE(cname))]; \
82         unsigned char iv[BLOCK_SIZE(cname)]; \
83         const br_block_cbc ## dir ## _class *vt; \
84         br_ ## cname ## _cbc ## dir ## _keys ec; \
85         int i; \
86         long num; \
87  \
88         memset(key, 'T', sizeof key); \
89         memset(buf, 'P', sizeof buf); \
90         memset(iv, 'X', sizeof iv); \
91         vt = br_ ## cname ## _cbc ## dir ## _get_vtable(); \
92         if (vt == NULL) { \
93                 printf("%-30s UNAVAILABLE\n", #Name); \
94                 fflush(stdout); \
95                 return; \
96         } \
97         for (i = 0; i < 10; i ++) { \
98                 vt->init(&ec.vtable, key, sizeof key); \
99                 vt->run(&ec.vtable, iv, buf, sizeof buf); \
100         } \
101         num = 10; \
102         for (;;) { \
103                 clock_t begin, end; \
104                 double tt; \
105                 long k; \
106  \
107                 vt->init(&ec.vtable, key, sizeof key); \
108                 begin = clock(); \
109                 for (k = num; k > 0; k --) { \
110                         vt->run(&ec.vtable, iv, buf, sizeof buf); \
111                 } \
112                 end = clock(); \
113                 tt = (double)(end - begin) / CLOCKS_PER_SEC; \
114                 if (tt >= 2.0) { \
115                         printf("%-30s %8.2f MB/s\n", #Name, \
116                                 ((double)sizeof buf) * (double)num \
117                                 / (tt * 1000000.0)); \
118                         fflush(stdout); \
119                         return; \
120                 } \
121                 num <<= 1; \
122         } \
123 }
124
125 #define SPEED_BLOCKCIPHER_CTR(Name, fname, cname, klen) \
126 static void \
127 test_speed_ ## fname(void) \
128 { \
129         unsigned char key[klen]; \
130         unsigned char buf[8192 - (8192 % BLOCK_SIZE(cname))]; \
131         unsigned char iv[BLOCK_SIZE(cname) - 4]; \
132         const br_block_ctr_class *vt; \
133         br_ ## cname ## _ctr_keys ec; \
134         int i; \
135         long num; \
136  \
137         memset(key, 'T', sizeof key); \
138         memset(buf, 'P', sizeof buf); \
139         memset(iv, 'X', sizeof iv); \
140         vt = br_ ## cname ## _ctr_get_vtable(); \
141         if (vt == NULL) { \
142                 printf("%-30s UNAVAILABLE\n", #Name); \
143                 fflush(stdout); \
144                 return; \
145         } \
146         for (i = 0; i < 10; i ++) { \
147                 vt->init(&ec.vtable, key, sizeof key); \
148                 vt->run(&ec.vtable, iv, 1, buf, sizeof buf); \
149         } \
150         num = 10; \
151         for (;;) { \
152                 clock_t begin, end; \
153                 double tt; \
154                 long k; \
155  \
156                 vt->init(&ec.vtable, key, sizeof key); \
157                 begin = clock(); \
158                 for (k = num; k > 0; k --) { \
159                         vt->run(&ec.vtable, iv, 1, buf, sizeof buf); \
160                 } \
161                 end = clock(); \
162                 tt = (double)(end - begin) / CLOCKS_PER_SEC; \
163                 if (tt >= 2.0) { \
164                         printf("%-30s %8.2f MB/s\n", #Name, \
165                                 ((double)sizeof buf) * (double)num \
166                                 / (tt * 1000000.0)); \
167                         fflush(stdout); \
168                         return; \
169                 } \
170                 num <<= 1; \
171         } \
172 }
173
174 #define SPEED_CHACHA20(Name, fname) \
175 static void \
176 test_speed_ ## fname(void) \
177 { \
178         br_chacha20_run bc; \
179         unsigned char key[32]; \
180         unsigned char buf[8192]; \
181         unsigned char iv[12]; \
182         int i; \
183         long num; \
184  \
185         bc = br_ ## fname ## _get(); \
186         if (bc == 0) { \
187                 printf("%-30s UNAVAILABLE\n", #Name); \
188                 fflush(stdout); \
189                 return; \
190         } \
191         memset(key, 'T', sizeof key); \
192         memset(buf, 'P', sizeof buf); \
193         memset(iv, 'X', sizeof iv); \
194         for (i = 0; i < 10; i ++) { \
195                 bc(key, iv, i, buf, sizeof buf); \
196         } \
197         num = 10; \
198         for (;;) { \
199                 clock_t begin, end; \
200                 double tt; \
201                 long k; \
202  \
203                 begin = clock(); \
204                 for (k = num; k > 0; k --) { \
205                         bc(key, iv, (uint32_t)k, buf, sizeof buf); \
206                 } \
207                 end = clock(); \
208                 tt = (double)(end - begin) / CLOCKS_PER_SEC; \
209                 if (tt >= 2.0) { \
210                         printf("%-30s %8.2f MB/s\n", #Name, \
211                                 ((double)sizeof buf) * (double)num \
212                                 / (tt * 1000000.0)); \
213                         fflush(stdout); \
214                         return; \
215                 } \
216                 num <<= 1; \
217         } \
218 }
219
220 SPEED_HASH(MD5, md5)
221 SPEED_HASH(SHA-1, sha1)
222 SPEED_HASH(SHA-256, sha256)
223 SPEED_HASH(SHA-512, sha512)
224
225 /*
226  * There are no vtable selection functions for the portable implementations,
227  * so we define some custom macros.
228  */
229 #define br_aes_big_cbcenc_get_vtable()     (&br_aes_big_cbcenc_vtable)
230 #define br_aes_big_cbcdec_get_vtable()     (&br_aes_big_cbcdec_vtable)
231 #define br_aes_big_ctr_get_vtable()        (&br_aes_big_ctr_vtable)
232 #define br_aes_big_ctrcbc_get_vtable()     (&br_aes_big_ctrcbc_vtable)
233 #define br_aes_small_cbcenc_get_vtable()   (&br_aes_small_cbcenc_vtable)
234 #define br_aes_small_cbcdec_get_vtable()   (&br_aes_small_cbcdec_vtable)
235 #define br_aes_small_ctr_get_vtable()      (&br_aes_small_ctr_vtable)
236 #define br_aes_small_ctrcbc_get_vtable()   (&br_aes_small_ctrcbc_vtable)
237 #define br_aes_ct_cbcenc_get_vtable()      (&br_aes_ct_cbcenc_vtable)
238 #define br_aes_ct_cbcdec_get_vtable()      (&br_aes_ct_cbcdec_vtable)
239 #define br_aes_ct_ctr_get_vtable()         (&br_aes_ct_ctr_vtable)
240 #define br_aes_ct_ctrcbc_get_vtable()      (&br_aes_ct_ctrcbc_vtable)
241 #define br_aes_ct64_cbcenc_get_vtable()    (&br_aes_ct64_cbcenc_vtable)
242 #define br_aes_ct64_cbcdec_get_vtable()    (&br_aes_ct64_cbcdec_vtable)
243 #define br_aes_ct64_ctr_get_vtable()       (&br_aes_ct64_ctr_vtable)
244 #define br_aes_ct64_ctrcbc_get_vtable()    (&br_aes_ct64_ctrcbc_vtable)
245 #define br_chacha20_ct_get()               (&br_chacha20_ct_run)
246
247 #define SPEED_AES(iname) \
248 SPEED_BLOCKCIPHER_CBC(AES-128 CBC encrypt (iname), aes128_ ## iname ## _cbcenc, aes_ ## iname, 16, enc) \
249 SPEED_BLOCKCIPHER_CBC(AES-128 CBC decrypt (iname), aes128_ ## iname ## _cbcdec, aes_ ## iname, 16, dec) \
250 SPEED_BLOCKCIPHER_CBC(AES-192 CBC encrypt (iname), aes192_ ## iname ## _cbcenc, aes_ ## iname, 24, enc) \
251 SPEED_BLOCKCIPHER_CBC(AES-192 CBC decrypt (iname), aes192_ ## iname ## _cbcdec, aes_ ## iname, 24, dec) \
252 SPEED_BLOCKCIPHER_CBC(AES-256 CBC encrypt (iname), aes256_ ## iname ## _cbcenc, aes_ ## iname, 32, enc) \
253 SPEED_BLOCKCIPHER_CBC(AES-256 CBC decrypt (iname), aes256_ ## iname ## _cbcdec, aes_ ## iname, 32, dec) \
254 SPEED_BLOCKCIPHER_CTR(AES-128 CTR (iname), aes128_ ## iname ## _ctr, aes_ ## iname, 16) \
255 SPEED_BLOCKCIPHER_CTR(AES-192 CTR (iname), aes192_ ## iname ## _ctr, aes_ ## iname, 24) \
256 SPEED_BLOCKCIPHER_CTR(AES-256 CTR (iname), aes256_ ## iname ## _ctr, aes_ ## iname, 32)
257
258 SPEED_AES(big)
259 SPEED_AES(small)
260 SPEED_AES(ct)
261 SPEED_AES(ct64)
262 SPEED_AES(x86ni)
263 SPEED_AES(pwr8)
264
265 #define br_des_tab_cbcenc_get_vtable()     (&br_des_tab_cbcenc_vtable)
266 #define br_des_tab_cbcdec_get_vtable()     (&br_des_tab_cbcdec_vtable)
267 #define br_des_ct_cbcenc_get_vtable()      (&br_des_ct_cbcenc_vtable)
268 #define br_des_ct_cbcdec_get_vtable()      (&br_des_ct_cbcdec_vtable)
269
270 #define SPEED_DES(iname) \
271 SPEED_BLOCKCIPHER_CBC(DES CBC encrypt (iname), des_ ## iname ## _cbcenc, des_ ## iname, 8, enc) \
272 SPEED_BLOCKCIPHER_CBC(DES CBC decrypt (iname), des_ ## iname ## _cbcdec, des_ ## iname, 8, dec) \
273 SPEED_BLOCKCIPHER_CBC(3DES CBC encrypt (iname), 3des_ ## iname ## _cbcenc, des_ ## iname, 24, enc) \
274 SPEED_BLOCKCIPHER_CBC(3DES CBC decrypt (iname), 3des_ ## iname ## _cbcdec, des_ ## iname, 24, dec)
275
276 SPEED_DES(tab)
277 SPEED_DES(ct)
278
279 SPEED_CHACHA20(ChaCha20 (ct), chacha20_ct)
280 SPEED_CHACHA20(ChaCha20 (sse2), chacha20_sse2)
281
282 static void
283 test_speed_ghash_inner(char *name, br_ghash gh)
284 {
285         unsigned char buf[8192], h[16], y[16];
286         int i;
287         long num;
288
289         memset(buf, 'T', sizeof buf);
290         memset(h, 'P', sizeof h);
291         memset(y, 0, sizeof y);
292         for (i = 0; i < 10; i ++) {
293                 gh(y, h, buf, sizeof buf);
294         }
295         num = 10;
296         for (;;) {
297                 clock_t begin, end;
298                 double tt;
299                 long k;
300
301                 begin = clock();
302                 for (k = num; k > 0; k --) {
303                         gh(y, h, buf, sizeof buf);
304                 }
305                 end = clock();
306                 tt = (double)(end - begin) / CLOCKS_PER_SEC;
307                 if (tt >= 2.0) {
308                         printf("%-30s %8.2f MB/s\n", name,
309                                 ((double)sizeof buf) * (double)num
310                                 / (tt * 1000000.0));
311                         fflush(stdout);
312                         return;
313                 }
314                 num <<= 1;
315         }
316 }
317
318 static void
319 test_speed_ghash_ctmul(void)
320 {
321         test_speed_ghash_inner("GHASH (ctmul)", &br_ghash_ctmul);
322 }
323
324 static void
325 test_speed_ghash_ctmul32(void)
326 {
327         test_speed_ghash_inner("GHASH (ctmul32)", &br_ghash_ctmul32);
328 }
329
330 static void
331 test_speed_ghash_ctmul64(void)
332 {
333         test_speed_ghash_inner("GHASH (ctmul64)", &br_ghash_ctmul64);
334 }
335
336 static void
337 test_speed_ghash_pclmul(void)
338 {
339         br_ghash gh;
340
341         gh = br_ghash_pclmul_get();
342         if (gh == 0) {
343                 printf("%-30s UNAVAILABLE\n", "GHASH (pclmul)");
344                 fflush(stdout);
345         } else {
346                 test_speed_ghash_inner("GHASH (pclmul)", gh);
347         }
348 }
349
350 static void
351 test_speed_ghash_pwr8(void)
352 {
353         br_ghash gh;
354
355         gh = br_ghash_pwr8_get();
356         if (gh == 0) {
357                 printf("%-30s UNAVAILABLE\n", "GHASH (pwr8)");
358                 fflush(stdout);
359         } else {
360                 test_speed_ghash_inner("GHASH (pwr8)", gh);
361         }
362 }
363
364 static uint32_t
365 fake_chacha20(const void *key, const void *iv,
366         uint32_t cc, void *data, size_t len)
367 {
368         (void)key;
369         (void)iv;
370         (void)data;
371         (void)len;
372         return cc + (uint32_t)((len + 63) >> 6);
373 }
374
375 /*
376  * To speed-test Poly1305, we run it with a do-nothing stub instead of
377  * ChaCha20.
378  */
379 static void
380 test_speed_poly1305_inner(char *name, br_poly1305_run pl)
381 {
382         unsigned char buf[8192], key[32], iv[12], aad[13], tag[16];
383         int i;
384         long num;
385
386         memset(key, 'K', sizeof key);
387         memset(iv, 'I', sizeof iv);
388         memset(aad, 'A', sizeof aad);
389         memset(buf, 'T', sizeof buf);
390         for (i = 0; i < 10; i ++) {
391                 pl(key, iv, buf, sizeof buf,
392                         aad, sizeof aad, tag, &fake_chacha20, 0);
393         }
394         num = 10;
395         for (;;) {
396                 clock_t begin, end;
397                 double tt;
398                 long k;
399
400                 begin = clock();
401                 for (k = num; k > 0; k --) {
402                         pl(key, iv, buf, sizeof buf,
403                                 aad, sizeof aad, tag, &fake_chacha20, 0);
404                 }
405                 end = clock();
406                 tt = (double)(end - begin) / CLOCKS_PER_SEC;
407                 if (tt >= 2.0) {
408                         printf("%-30s %8.2f MB/s\n", name,
409                                 ((double)sizeof buf) * (double)num
410                                 / (tt * 1000000.0));
411                         fflush(stdout);
412                         return;
413                 }
414                 num <<= 1;
415         }
416 }
417
418 static void
419 test_speed_poly1305_ctmul(void)
420 {
421         test_speed_poly1305_inner("Poly1305 (ctmul)", &br_poly1305_ctmul_run);
422 }
423
424 static void
425 test_speed_poly1305_ctmul32(void)
426 {
427         test_speed_poly1305_inner("Poly1305 (ctmul32)",
428                 &br_poly1305_ctmul32_run);
429 }
430
431 static void
432 test_speed_poly1305_ctmulq(void)
433 {
434         br_poly1305_run bp;
435
436         bp = br_poly1305_ctmulq_get();
437         if (bp == 0) {
438                 printf("%-30s UNAVAILABLE\n", "Poly1305 (ctmulq)");
439         } else {
440                 test_speed_poly1305_inner("Poly1305 (ctmulq)", bp);
441         }
442 }
443
444 static void
445 test_speed_poly1305_i15(void)
446 {
447         test_speed_poly1305_inner("Poly1305 (i15)", &br_poly1305_i15_run);
448 }
449
450 static void
451 test_speed_eax_inner(char *name,
452         const br_block_ctrcbc_class *vt, size_t key_len)
453 {
454         unsigned char buf[8192], key[32], nonce[16], aad[16], tag[16];
455         int i;
456         long num;
457         br_aes_gen_ctrcbc_keys ac;
458         br_eax_context ec;
459
460         if (vt == NULL) {
461                 printf("%-30s UNAVAILABLE\n", name);
462                 fflush(stdout);
463                 return;
464         }
465         memset(key, 'K', key_len);
466         memset(nonce, 'N', sizeof nonce);
467         memset(aad, 'A', sizeof aad);
468         memset(buf, 'T', sizeof buf);
469         for (i = 0; i < 10; i ++) {
470                 vt->init(&ac.vtable, key, key_len);
471                 br_eax_init(&ec, &ac.vtable);
472                 br_eax_reset(&ec, nonce, sizeof nonce);
473                 br_eax_aad_inject(&ec, aad, sizeof aad);
474                 br_eax_flip(&ec);
475                 br_eax_run(&ec, 1, buf, sizeof buf);
476                 br_eax_get_tag(&ec, tag);
477         }
478         num = 10;
479         for (;;) {
480                 clock_t begin, end;
481                 double tt;
482                 long k;
483
484                 begin = clock();
485                 for (k = num; k > 0; k --) {
486                         vt->init(&ac.vtable, key, key_len);
487                         br_eax_init(&ec, &ac.vtable);
488                         br_eax_reset(&ec, nonce, sizeof nonce);
489                         br_eax_aad_inject(&ec, aad, sizeof aad);
490                         br_eax_flip(&ec);
491                         br_eax_run(&ec, 1, buf, sizeof buf);
492                         br_eax_get_tag(&ec, tag);
493                 }
494                 end = clock();
495                 tt = (double)(end - begin) / CLOCKS_PER_SEC;
496                 if (tt >= 2.0) {
497                         printf("%-30s %8.2f MB/s\n", name,
498                                 ((double)sizeof buf) * (double)num
499                                 / (tt * 1000000.0));
500                         fflush(stdout);
501                         return;
502                 }
503                 num <<= 1;
504         }
505 }
506
507 #define SPEED_EAX(Algo, algo, keysize, impl) \
508 static void \
509 test_speed_eax_ ## algo ## keysize ## _ ## impl(void) \
510 { \
511         test_speed_eax_inner("EAX " #Algo "-" #keysize "(" #impl ")", \
512                 br_ ## algo ## _ ## impl ##  _ctrcbc_get_vtable() \
513                 , (keysize) >> 3); \
514 }
515
516 SPEED_EAX(AES, aes, 128, big)
517 SPEED_EAX(AES, aes, 128, small)
518 SPEED_EAX(AES, aes, 128, ct)
519 SPEED_EAX(AES, aes, 128, ct64)
520 SPEED_EAX(AES, aes, 128, x86ni)
521 SPEED_EAX(AES, aes, 128, pwr8)
522 SPEED_EAX(AES, aes, 192, big)
523 SPEED_EAX(AES, aes, 192, small)
524 SPEED_EAX(AES, aes, 192, ct)
525 SPEED_EAX(AES, aes, 192, ct64)
526 SPEED_EAX(AES, aes, 192, x86ni)
527 SPEED_EAX(AES, aes, 192, pwr8)
528 SPEED_EAX(AES, aes, 256, big)
529 SPEED_EAX(AES, aes, 256, small)
530 SPEED_EAX(AES, aes, 256, ct)
531 SPEED_EAX(AES, aes, 256, ct64)
532 SPEED_EAX(AES, aes, 256, x86ni)
533 SPEED_EAX(AES, aes, 256, pwr8)
534
535 static void
536 test_speed_shake_inner(int security_level)
537 {
538         unsigned char buf[8192];
539         br_shake_context sc;
540         int i;
541         long num;
542
543         memset(buf, 'D', sizeof buf);
544         br_shake_init(&sc, security_level);
545         for (i = 0; i < 10; i ++) {
546                 br_shake_inject(&sc, buf, sizeof buf);
547         }
548         num = 10;
549         for (;;) {
550                 clock_t begin, end;
551                 double tt;
552                 long k;
553
554                 begin = clock();
555                 for (k = num; k > 0; k --) {
556                         br_shake_inject(&sc, buf, sizeof buf);
557                 }
558                 end = clock();
559                 tt = (double)(end - begin) / CLOCKS_PER_SEC;
560                 if (tt >= 2.0) {
561                         printf("SHAKE%-3d (inject)              %8.2f MB/s\n",
562                                 security_level,
563                                 ((double)sizeof buf) * (double)num
564                                 / (tt * 1000000.0));
565                         fflush(stdout);
566                         break;
567                 }
568                 num <<= 1;
569         }
570
571         br_shake_flip(&sc);
572         for (i = 0; i < 10; i ++) {
573                 br_shake_produce(&sc, buf, sizeof buf);
574         }
575
576         num = 10;
577         for (;;) {
578                 clock_t begin, end;
579                 double tt;
580                 long k;
581
582                 begin = clock();
583                 for (k = num; k > 0; k --) {
584                         br_shake_produce(&sc, buf, sizeof buf);
585                 }
586                 end = clock();
587                 tt = (double)(end - begin) / CLOCKS_PER_SEC;
588                 if (tt >= 2.0) {
589                         printf("SHAKE%-3d (produce)             %8.2f MB/s\n",
590                                 security_level,
591                                 ((double)sizeof buf) * (double)num
592                                 / (tt * 1000000.0));
593                         fflush(stdout);
594                         break;
595                 }
596                 num <<= 1;
597         }
598 }
599
600 static void
601 test_speed_shake128(void)
602 {
603         test_speed_shake_inner(128);
604 }
605
606 static void
607 test_speed_shake256(void)
608 {
609         test_speed_shake_inner(256);
610 }
611
612 static const unsigned char RSA_N[] = {
613         0xE9, 0xF2, 0x4A, 0x2F, 0x96, 0xDF, 0x0A, 0x23,
614         0x01, 0x85, 0xF1, 0x2C, 0xB2, 0xA8, 0xEF, 0x23,
615         0xCE, 0x2E, 0xB0, 0x4E, 0x18, 0x31, 0x95, 0x5B,
616         0x98, 0x2D, 0x9B, 0x8C, 0xE3, 0x1A, 0x2B, 0x96,
617         0xB5, 0xC7, 0xEE, 0xED, 0x72, 0x43, 0x2D, 0xFE,
618         0x7F, 0x61, 0x33, 0xEA, 0x14, 0xFC, 0xDE, 0x80,
619         0x17, 0x42, 0xF0, 0xF3, 0xC3, 0xC7, 0x89, 0x47,
620         0x76, 0x5B, 0xFA, 0x33, 0xC4, 0x8C, 0x94, 0xDE,
621         0x6A, 0x75, 0xD8, 0x1A, 0xF4, 0x49, 0xBC, 0xF3,
622         0xB7, 0x9E, 0x2C, 0x8D, 0xEC, 0x5A, 0xEE, 0xBF,
623         0x4B, 0x5A, 0x7F, 0xEF, 0x21, 0x39, 0xDB, 0x1D,
624         0x83, 0x5E, 0x7E, 0x2F, 0xAA, 0x5E, 0xBA, 0x28,
625         0xC3, 0xA2, 0x53, 0x19, 0xFB, 0x2F, 0x78, 0x6B,
626         0x14, 0x60, 0x49, 0x3C, 0xCC, 0x1B, 0xE9, 0x1E,
627         0x3D, 0x10, 0xA4, 0xEB, 0x7F, 0x66, 0x98, 0xF6,
628         0xC3, 0xAC, 0x35, 0xF5, 0x01, 0x84, 0xFF, 0x7D,
629         0x1F, 0x72, 0xBE, 0xB4, 0xD1, 0x89, 0xC8, 0xDD,
630         0x44, 0xE7, 0xB5, 0x2E, 0x2C, 0xE1, 0x85, 0xF5,
631         0x15, 0x50, 0xA9, 0x08, 0xC7, 0x67, 0xD9, 0x2B,
632         0x6C, 0x11, 0xB3, 0xEB, 0x28, 0x8D, 0xF4, 0xCC,
633         0xE3, 0xC3, 0xC5, 0x04, 0x0E, 0x7C, 0x8D, 0xDB,
634         0x39, 0x06, 0x6A, 0x74, 0x75, 0xDF, 0xA8, 0x0F,
635         0xDA, 0x67, 0x5A, 0x73, 0x1E, 0xFD, 0x8E, 0x4C,
636         0xEE, 0x17, 0xEE, 0x1E, 0x67, 0xDB, 0x98, 0x70,
637         0x60, 0xF7, 0xB9, 0xB5, 0x1F, 0x19, 0x93, 0xD6,
638         0x3F, 0x2F, 0x1F, 0xB6, 0x5B, 0x59, 0xAA, 0x85,
639         0xBB, 0x25, 0xE4, 0x13, 0xEF, 0xE7, 0xB9, 0x87,
640         0x9C, 0x3F, 0x5E, 0xE4, 0x08, 0xA3, 0x51, 0xCF,
641         0x8B, 0xAD, 0xF4, 0xE6, 0x1A, 0x5F, 0x51, 0xDD,
642         0xA8, 0xBE, 0xE8, 0xD1, 0x20, 0x19, 0x61, 0x6C,
643         0x18, 0xAB, 0xCA, 0x0A, 0xD9, 0x82, 0xA6, 0x94,
644         0xD5, 0x69, 0x2A, 0xF6, 0x43, 0x66, 0x31, 0x09
645 };
646
647 static const unsigned char RSA_E[] = {
648         0x01, 0x00, 0x01
649 };
650
651 static const unsigned char RSA_P[] = {
652         0xFD, 0x39, 0x40, 0x56, 0x20, 0x80, 0xC5, 0x81,
653         0x4C, 0x5F, 0x0C, 0x1A, 0x52, 0x84, 0x03, 0x2F,
654         0xCE, 0x82, 0xB0, 0xD8, 0x30, 0x23, 0x7F, 0x77,
655         0x45, 0xC2, 0x01, 0xC4, 0x68, 0x96, 0x0D, 0xA7,
656         0x22, 0xA9, 0x6C, 0xA9, 0x1A, 0x33, 0xE5, 0x2F,
657         0xB5, 0x07, 0x9A, 0xF9, 0xEA, 0x33, 0xA5, 0xC8,
658         0x96, 0x60, 0x6A, 0xCA, 0xEB, 0xE5, 0x6E, 0x09,
659         0x46, 0x7E, 0x2D, 0xEF, 0x93, 0x7D, 0x56, 0xED,
660         0x75, 0x70, 0x3B, 0x96, 0xC4, 0xD5, 0xDB, 0x0B,
661         0x3F, 0x69, 0xDF, 0x06, 0x18, 0x76, 0xF4, 0xCF,
662         0xF8, 0x84, 0x22, 0xDF, 0xBD, 0x71, 0x62, 0x7B,
663         0x67, 0x99, 0xBC, 0x09, 0x95, 0x54, 0xA4, 0x98,
664         0x83, 0xF5, 0xA9, 0xCF, 0x09, 0xA5, 0x1F, 0x61,
665         0x25, 0xB4, 0x70, 0x6C, 0x91, 0xB8, 0xB3, 0xD0,
666         0xCE, 0x9C, 0x45, 0x65, 0x9B, 0xEF, 0xD4, 0x70,
667         0xBE, 0x86, 0xD2, 0x98, 0x5D, 0xEB, 0xE3, 0xFF
668 };
669
670 static const unsigned char RSA_Q[] = {
671         0xEC, 0x82, 0xEE, 0x63, 0x5F, 0x40, 0x52, 0xDB,
672         0x38, 0x7A, 0x37, 0x6A, 0x54, 0x5B, 0xD9, 0xA0,
673         0x73, 0xB4, 0xBB, 0x52, 0xB2, 0x84, 0x07, 0xD0,
674         0xCC, 0x82, 0x0D, 0x20, 0xB3, 0xFA, 0xD5, 0xB6,
675         0x25, 0x92, 0x35, 0x4D, 0xB4, 0xC7, 0x36, 0x48,
676         0xCE, 0x5E, 0x21, 0x4A, 0xA6, 0x74, 0x65, 0xF4,
677         0x7D, 0x1D, 0xBC, 0x3B, 0xE2, 0xF4, 0x3E, 0x11,
678         0x58, 0x10, 0x6C, 0x04, 0x46, 0x9E, 0x8D, 0x57,
679         0xE0, 0x04, 0xE2, 0xEC, 0x47, 0xCF, 0xB3, 0x2A,
680         0xFD, 0x4C, 0x55, 0x18, 0xDB, 0xDE, 0x3B, 0xDC,
681         0xF4, 0x5B, 0xDA, 0xF3, 0x1A, 0xC8, 0x41, 0x6F,
682         0x73, 0x3B, 0xFE, 0x3C, 0xA0, 0xDB, 0xBA, 0x6E,
683         0x65, 0xA5, 0xE8, 0x02, 0xA5, 0x6C, 0xEA, 0x03,
684         0xF6, 0x99, 0xF7, 0xCB, 0x4B, 0xB7, 0x11, 0x51,
685         0x93, 0x88, 0x3F, 0xF9, 0x06, 0x85, 0xA9, 0x1E,
686         0xCA, 0x64, 0xF8, 0x11, 0xA5, 0x1A, 0xCA, 0xF7
687 };
688
689 static const unsigned char RSA_DP[] = {
690         0x77, 0x95, 0xE0, 0x02, 0x4C, 0x9B, 0x43, 0xAA,
691         0xCA, 0x4C, 0x60, 0xC4, 0xD5, 0x8F, 0x2E, 0x8A,
692         0x17, 0x36, 0xB5, 0x19, 0x83, 0xB2, 0x5F, 0xF2,
693         0x0D, 0xE9, 0x8F, 0x38, 0x18, 0x44, 0x34, 0xF2,
694         0x67, 0x76, 0x27, 0xB0, 0xBC, 0x85, 0x21, 0x89,
695         0x24, 0x2F, 0x11, 0x4B, 0x51, 0x05, 0x4F, 0x17,
696         0xA9, 0x9C, 0xA3, 0x12, 0x6D, 0xD1, 0x0D, 0xE4,
697         0x27, 0x7C, 0x53, 0x69, 0x3E, 0xF8, 0x04, 0x63,
698         0x64, 0x00, 0xBA, 0xC3, 0x7A, 0xF5, 0x9B, 0xDA,
699         0x75, 0xFA, 0x23, 0xAF, 0x17, 0x42, 0xA6, 0x5E,
700         0xC8, 0xF8, 0x6E, 0x17, 0xC7, 0xB9, 0x92, 0x4E,
701         0xC1, 0x20, 0x63, 0x23, 0x0B, 0x78, 0xCB, 0xBA,
702         0x93, 0x27, 0x23, 0x28, 0x79, 0x5F, 0x97, 0xB0,
703         0x23, 0x44, 0x51, 0x8B, 0x94, 0x4D, 0xEB, 0xED,
704         0x82, 0x85, 0x5E, 0x68, 0x9B, 0xF9, 0xE9, 0x13,
705         0xCD, 0x86, 0x92, 0x52, 0x0E, 0x98, 0xE6, 0x35
706 };
707
708 static const unsigned char RSA_DQ[] = {
709         0xD8, 0xDD, 0x71, 0xB3, 0x62, 0xBA, 0xBB, 0x7E,
710         0xD1, 0xF9, 0x96, 0xE8, 0x83, 0xB3, 0xB9, 0x08,
711         0x9C, 0x30, 0x03, 0x77, 0xDF, 0xC2, 0x9A, 0xDC,
712         0x05, 0x39, 0xD6, 0xC9, 0xBE, 0xDE, 0x68, 0xA9,
713         0xDD, 0x27, 0x84, 0x82, 0xDD, 0x19, 0xB1, 0x97,
714         0xEE, 0xCA, 0x77, 0x22, 0x59, 0x20, 0xEF, 0xFF,
715         0xCF, 0xDD, 0xBD, 0x24, 0xF8, 0x84, 0xD6, 0x88,
716         0xD6, 0xC4, 0x30, 0x17, 0x77, 0x9D, 0x98, 0xA3,
717         0x14, 0x01, 0xC7, 0x05, 0xBB, 0x0F, 0x23, 0x0D,
718         0x6F, 0x37, 0x57, 0xEC, 0x34, 0x67, 0x41, 0x62,
719         0xE8, 0x19, 0x75, 0xD9, 0x66, 0x1C, 0x6B, 0x8B,
720         0xC3, 0x11, 0x26, 0x9C, 0xF7, 0x2E, 0xA3, 0x72,
721         0xE8, 0xF7, 0xC8, 0x96, 0xEC, 0x92, 0xC2, 0xBD,
722         0xA1, 0x98, 0x2A, 0x93, 0x99, 0xB8, 0xA2, 0x43,
723         0xB7, 0xD0, 0xBE, 0x40, 0x1C, 0x8F, 0xE0, 0xB4,
724         0x20, 0x07, 0x97, 0x43, 0xAE, 0xAD, 0xB3, 0x9F
725 };
726
727 static const unsigned char RSA_IQ[] = {
728         0xB7, 0xE2, 0x60, 0xA9, 0x62, 0xEC, 0xEC, 0x0B,
729         0x57, 0x02, 0x96, 0xF9, 0x36, 0x35, 0x2C, 0x37,
730         0xAF, 0xC2, 0xEE, 0x71, 0x49, 0x26, 0x8E, 0x0F,
731         0x27, 0xB1, 0xFA, 0x0F, 0xEA, 0xDC, 0xF0, 0x8B,
732         0x53, 0x6C, 0xB2, 0x46, 0x27, 0xCD, 0x29, 0xA2,
733         0x35, 0x0F, 0x5D, 0x8A, 0x3F, 0x20, 0x8C, 0x13,
734         0x3D, 0xA1, 0xFF, 0x85, 0x91, 0x99, 0xE8, 0x50,
735         0xED, 0xF1, 0x29, 0x00, 0xEE, 0x24, 0x90, 0xB5,
736         0x5F, 0x3A, 0x74, 0x26, 0xD7, 0xA2, 0x24, 0x8D,
737         0x89, 0x88, 0xD8, 0x35, 0x22, 0x22, 0x8A, 0x66,
738         0x5D, 0x5C, 0xDE, 0x83, 0x8C, 0xFA, 0x27, 0xE6,
739         0xB9, 0xEB, 0x72, 0x08, 0xCD, 0x53, 0x4B, 0x93,
740         0x0F, 0xAD, 0xC3, 0xF8, 0x7C, 0xFE, 0x84, 0xD7,
741         0x08, 0xF3, 0xBE, 0x3D, 0x60, 0x1E, 0x95, 0x8D,
742         0x44, 0x5B, 0x65, 0x7E, 0xC1, 0x30, 0xC3, 0x84,
743         0xC0, 0xB0, 0xFE, 0xBF, 0x28, 0x54, 0x1E, 0xC4
744 };
745
746 static const br_rsa_public_key RSA_PK = {
747         (void *)RSA_N, sizeof RSA_N,
748         (void *)RSA_E, sizeof RSA_E
749 };
750
751 static const br_rsa_private_key RSA_SK = {
752         2048,
753         (void *)RSA_P, sizeof RSA_P,
754         (void *)RSA_Q, sizeof RSA_Q,
755         (void *)RSA_DP, sizeof RSA_DP,
756         (void *)RSA_DQ, sizeof RSA_DQ,
757         (void *)RSA_IQ, sizeof RSA_IQ
758 };
759
760 static void
761 test_speed_rsa_inner(char *name,
762         br_rsa_public fpub, br_rsa_private fpriv, br_rsa_keygen kgen)
763 {
764         unsigned char tmp[sizeof RSA_N];
765         int i;
766         long num;
767         /*
768         br_hmac_drbg_context rng;
769         */
770         br_aesctr_drbg_context rng;
771         const br_block_ctr_class *ictr;
772
773         memset(tmp, 'R', sizeof tmp);
774         tmp[0] = 0;
775         for (i = 0; i < 10; i ++) {
776                 if (!fpriv(tmp, &RSA_SK)) {
777                         abort();
778                 }
779         }
780         num = 10;
781         for (;;) {
782                 clock_t begin, end;
783                 double tt;
784                 long k;
785
786                 begin = clock();
787                 for (k = num; k > 0; k --) {
788                         fpriv(tmp, &RSA_SK);
789                 }
790                 end = clock();
791                 tt = (double)(end - begin) / CLOCKS_PER_SEC;
792                 if (tt >= 2.0) {
793                         printf("%-30s %8.2f priv/s\n", name,
794                                 (double)num / tt);
795                         fflush(stdout);
796                         break;
797                 }
798                 num <<= 1;
799         }
800         for (i = 0; i < 10; i ++) {
801                 if (!fpub(tmp, sizeof tmp, &RSA_PK)) {
802                         abort();
803                 }
804         }
805         num = 10;
806         for (;;) {
807                 clock_t begin, end;
808                 double tt;
809                 long k;
810
811                 begin = clock();
812                 for (k = num; k > 0; k --) {
813                         fpub(tmp, sizeof tmp, &RSA_PK);
814                 }
815                 end = clock();
816                 tt = (double)(end - begin) / CLOCKS_PER_SEC;
817                 if (tt >= 2.0) {
818                         printf("%-30s %8.2f pub/s\n", name,
819                                 (double)num / tt);
820                         fflush(stdout);
821                         break;
822                 }
823                 num <<= 1;
824         }
825
826         if (kgen == 0) {
827                 printf("%-30s KEYGEN UNAVAILABLE\n", name);
828                 fflush(stdout);
829                 return;
830         }
831         /*
832         br_hmac_drbg_init(&rng, &br_sha256_vtable, "RSA keygen seed", 15);
833         */
834         ictr = br_aes_x86ni_ctr_get_vtable();
835         if (ictr == NULL) {
836                 ictr = br_aes_pwr8_ctr_get_vtable();
837                 if (ictr == NULL) {
838 #if BR_64
839                         ictr = &br_aes_ct64_ctr_vtable;
840 #else
841                         ictr = &br_aes_ct_ctr_vtable;
842 #endif
843                 }
844         }
845         br_aesctr_drbg_init(&rng, ictr, "RSA keygen seed", 15);
846
847         num = 10;
848         for (;;) {
849                 clock_t begin, end;
850                 double tt;
851                 long k;
852
853                 begin = clock();
854                 for (k = num; k > 0; k --) {
855                         br_rsa_private_key sk;
856                         unsigned char kbuf[BR_RSA_KBUF_PRIV_SIZE(1024)];
857
858                         kgen(&rng.vtable, &sk, kbuf, NULL, NULL, 1024, 0);
859                 }
860                 end = clock();
861                 tt = (double)(end - begin) / CLOCKS_PER_SEC;
862                 if (tt >= 10.0) {
863                         printf("%-30s %8.2f kgen[1024]/s\n", name,
864                                 (double)num / tt);
865                         fflush(stdout);
866                         break;
867                 }
868                 num <<= 1;
869         }
870
871         num = 10;
872         for (;;) {
873                 clock_t begin, end;
874                 double tt;
875                 long k;
876
877                 begin = clock();
878                 for (k = num; k > 0; k --) {
879                         br_rsa_private_key sk;
880                         unsigned char kbuf[BR_RSA_KBUF_PRIV_SIZE(2048)];
881
882                         kgen(&rng.vtable, &sk, kbuf, NULL, NULL, 2048, 0);
883                 }
884                 end = clock();
885                 tt = (double)(end - begin) / CLOCKS_PER_SEC;
886                 if (tt >= 10.0) {
887                         printf("%-30s %8.2f kgen[2048]/s\n", name,
888                                 (double)num / tt);
889                         fflush(stdout);
890                         break;
891                 }
892                 num <<= 1;
893         }
894 }
895
896 static void
897 test_speed_rsa_i15(void)
898 {
899         test_speed_rsa_inner("RSA i15",
900                 &br_rsa_i15_public, &br_rsa_i15_private, &br_rsa_i15_keygen);
901 }
902
903 static void
904 test_speed_rsa_i31(void)
905 {
906         test_speed_rsa_inner("RSA i31",
907                 &br_rsa_i31_public, &br_rsa_i31_private, &br_rsa_i31_keygen);
908 }
909
910 static void
911 test_speed_rsa_i32(void)
912 {
913         test_speed_rsa_inner("RSA i32",
914                 &br_rsa_i32_public, &br_rsa_i32_private, 0);
915 }
916
917 static void
918 test_speed_rsa_i62(void)
919 {
920         br_rsa_public pub;
921         br_rsa_private priv;
922         br_rsa_keygen kgen;
923
924         pub = br_rsa_i62_public_get();
925         priv = br_rsa_i62_private_get();
926         kgen = br_rsa_i62_keygen_get();
927         if (pub) {
928                 test_speed_rsa_inner("RSA i62", pub, priv, kgen);
929         } else {
930                 printf("%-30s UNAVAILABLE\n", "RSA i62");
931         }
932 }
933
934 static void
935 test_speed_ec_inner_1(const char *name,
936         const br_ec_impl *impl, const br_ec_curve_def *cd)
937 {
938         unsigned char bx[80], U[160];
939         uint32_t x[22], n[22];
940         size_t nlen, ulen;
941         int i;
942         long num;
943
944         nlen = cd->order_len;
945         br_i31_decode(n, cd->order, nlen);
946         memset(bx, 'T', sizeof bx);
947         br_i31_decode_reduce(x, bx, sizeof bx, n);
948         br_i31_encode(bx, nlen, x);
949         ulen = cd->generator_len;
950         memcpy(U, cd->generator, ulen);
951         for (i = 0; i < 10; i ++) {
952                 impl->mul(U, ulen, bx, nlen, cd->curve);
953         }
954         num = 10;
955         for (;;) {
956                 clock_t begin, end;
957                 double tt;
958                 long k;
959
960                 begin = clock();
961                 for (k = num; k > 0; k --) {
962                         impl->mul(U, ulen, bx, nlen, cd->curve);
963                 }
964                 end = clock();
965                 tt = (double)(end - begin) / CLOCKS_PER_SEC;
966                 if (tt >= 2.0) {
967                         printf("%-30s %8.2f mul/s\n", name,
968                                 (double)num / tt);
969                         fflush(stdout);
970                         break;
971                 }
972                 num <<= 1;
973         }
974 }
975
976 static void
977 test_speed_ec_inner_2(const char *name,
978         const br_ec_impl *impl, const br_ec_curve_def *cd)
979 {
980         unsigned char bx[80], U[160];
981         uint32_t x[22], n[22];
982         size_t nlen;
983         int i;
984         long num;
985
986         nlen = cd->order_len;
987         br_i31_decode(n, cd->order, nlen);
988         memset(bx, 'T', sizeof bx);
989         br_i31_decode_reduce(x, bx, sizeof bx, n);
990         br_i31_encode(bx, nlen, x);
991         for (i = 0; i < 10; i ++) {
992                 impl->mulgen(U, bx, nlen, cd->curve);
993         }
994         num = 10;
995         for (;;) {
996                 clock_t begin, end;
997                 double tt;
998                 long k;
999
1000                 begin = clock();
1001                 for (k = num; k > 0; k --) {
1002                         impl->mulgen(U, bx, nlen, cd->curve);
1003                 }
1004                 end = clock();
1005                 tt = (double)(end - begin) / CLOCKS_PER_SEC;
1006                 if (tt >= 2.0) {
1007                         printf("%-30s %8.2f mul/s\n", name,
1008                                 (double)num / tt);
1009                         fflush(stdout);
1010                         break;
1011                 }
1012                 num <<= 1;
1013         }
1014 }
1015
1016 static void
1017 test_speed_ec_inner(const char *name,
1018         const br_ec_impl *impl, const br_ec_curve_def *cd)
1019 {
1020         char tmp[50];
1021
1022         test_speed_ec_inner_1(name, impl, cd);
1023         sprintf(tmp, "%s (FP)", name);
1024         test_speed_ec_inner_2(tmp, impl, cd);
1025 }
1026
1027 static void
1028 test_speed_ec_p256_m15(void)
1029 {
1030         test_speed_ec_inner("EC p256_m15",
1031                 &br_ec_p256_m15, &br_secp256r1);
1032 }
1033
1034 static void
1035 test_speed_ec_p256_m31(void)
1036 {
1037         test_speed_ec_inner("EC p256_m31",
1038                 &br_ec_p256_m31, &br_secp256r1);
1039 }
1040
1041 static void
1042 test_speed_ec_p256_m62(void)
1043 {
1044         const br_ec_impl *ec;
1045
1046         ec = br_ec_p256_m62_get();
1047         if (ec != NULL) {
1048                 test_speed_ec_inner("EC p256_m62", ec, &br_secp256r1);
1049         } else {
1050                 printf("%-30s UNAVAILABLE\n", "EC p256_m62");
1051         }
1052 }
1053
1054 static void
1055 test_speed_ec_p256_m64(void)
1056 {
1057         const br_ec_impl *ec;
1058
1059         ec = br_ec_p256_m64_get();
1060         if (ec != NULL) {
1061                 test_speed_ec_inner("EC p256_m64", ec, &br_secp256r1);
1062         } else {
1063                 printf("%-30s UNAVAILABLE\n", "EC p256_m64");
1064         }
1065 }
1066
1067 static void
1068 test_speed_ec_prime_i15(void)
1069 {
1070         test_speed_ec_inner("EC prime_i15 P-256",
1071                 &br_ec_prime_i15, &br_secp256r1);
1072         test_speed_ec_inner("EC prime_i15 P-384",
1073                 &br_ec_prime_i15, &br_secp384r1);
1074         test_speed_ec_inner("EC prime_i15 P-521",
1075                 &br_ec_prime_i15, &br_secp521r1);
1076 }
1077
1078 static void
1079 test_speed_ec_prime_i31(void)
1080 {
1081         test_speed_ec_inner("EC prime_i31 P-256",
1082                 &br_ec_prime_i31, &br_secp256r1);
1083         test_speed_ec_inner("EC prime_i31 P-384",
1084                 &br_ec_prime_i31, &br_secp384r1);
1085         test_speed_ec_inner("EC prime_i31 P-521",
1086                 &br_ec_prime_i31, &br_secp521r1);
1087 }
1088
1089 static void
1090 test_speed_ec_c25519_i15(void)
1091 {
1092         test_speed_ec_inner("EC c25519_i15",
1093                 &br_ec_c25519_i15, &br_curve25519);
1094 }
1095
1096 static void
1097 test_speed_ec_c25519_i31(void)
1098 {
1099         test_speed_ec_inner("EC c25519_i31",
1100                 &br_ec_c25519_i31, &br_curve25519);
1101 }
1102
1103 static void
1104 test_speed_ec_c25519_m15(void)
1105 {
1106         test_speed_ec_inner("EC c25519_m15",
1107                 &br_ec_c25519_m15, &br_curve25519);
1108 }
1109
1110 static void
1111 test_speed_ec_c25519_m31(void)
1112 {
1113         test_speed_ec_inner("EC c25519_m31",
1114                 &br_ec_c25519_m31, &br_curve25519);
1115 }
1116
1117 static void
1118 test_speed_ec_c25519_m62(void)
1119 {
1120         const br_ec_impl *ec;
1121
1122         ec = br_ec_c25519_m62_get();
1123         if (ec != NULL) {
1124                 test_speed_ec_inner("EC c25519_m62", ec, &br_curve25519);
1125         } else {
1126                 printf("%-30s UNAVAILABLE\n", "EC c25519_m62");
1127         }
1128 }
1129
1130 static void
1131 test_speed_ec_c25519_m64(void)
1132 {
1133         const br_ec_impl *ec;
1134
1135         ec = br_ec_c25519_m64_get();
1136         if (ec != NULL) {
1137                 test_speed_ec_inner("EC c25519_m64", ec, &br_curve25519);
1138         } else {
1139                 printf("%-30s UNAVAILABLE\n", "EC c25519_m64");
1140         }
1141 }
1142
1143 static void
1144 test_speed_ecdsa_inner(const char *name,
1145         const br_ec_impl *impl, const br_ec_curve_def *cd,
1146         br_ecdsa_sign sign, br_ecdsa_vrfy vrfy)
1147 {
1148         unsigned char bx[80], U[160], hv[32], sig[160];
1149         uint32_t x[22], n[22];
1150         size_t nlen, ulen, sig_len;
1151         int i;
1152         long num;
1153         br_ec_private_key sk;
1154         br_ec_public_key pk;
1155
1156         nlen = cd->order_len;
1157         br_i31_decode(n, cd->order, nlen);
1158         memset(bx, 'T', sizeof bx);
1159         br_i31_decode_reduce(x, bx, sizeof bx, n);
1160         br_i31_encode(bx, nlen, x);
1161         ulen = cd->generator_len;
1162         memcpy(U, cd->generator, ulen);
1163         impl->mul(U, ulen, bx, nlen, cd->curve);
1164         sk.curve = cd->curve;
1165         sk.x = bx;
1166         sk.xlen = nlen;
1167         pk.curve = cd->curve;
1168         pk.q = U;
1169         pk.qlen = ulen;
1170
1171         memset(hv, 'H', sizeof hv);
1172         sig_len = sign(impl, &br_sha256_vtable, hv, &sk, sig);
1173         if (vrfy(impl, hv, sizeof hv, &pk, sig, sig_len) != 1) {
1174                 fprintf(stderr, "self-test sign/verify failed\n");
1175                 exit(EXIT_FAILURE);
1176         }
1177
1178         for (i = 0; i < 10; i ++) {
1179                 hv[1] ++;
1180                 sign(impl, &br_sha256_vtable, hv, &sk, sig);
1181                 vrfy(impl, hv, sizeof hv, &pk, sig, sig_len);
1182         }
1183
1184         num = 10;
1185         for (;;) {
1186                 clock_t begin, end;
1187                 double tt;
1188                 long k;
1189
1190                 begin = clock();
1191                 for (k = num; k > 0; k --) {
1192                         hv[1] ++;
1193                         sig_len = sign(impl, &br_sha256_vtable, hv, &sk, sig);
1194                 }
1195                 end = clock();
1196                 tt = (double)(end - begin) / CLOCKS_PER_SEC;
1197                 if (tt >= 2.0) {
1198                         printf("%-30s %8.2f sign/s\n", name,
1199                                 (double)num / tt);
1200                         fflush(stdout);
1201                         break;
1202                 }
1203                 num <<= 1;
1204         }
1205
1206         num = 10;
1207         for (;;) {
1208                 clock_t begin, end;
1209                 double tt;
1210                 long k;
1211
1212                 begin = clock();
1213                 for (k = num; k > 0; k --) {
1214                         vrfy(impl, hv, sizeof hv, &pk, sig, sig_len);
1215                 }
1216                 end = clock();
1217                 tt = (double)(end - begin) / CLOCKS_PER_SEC;
1218                 if (tt >= 2.0) {
1219                         printf("%-30s %8.2f verify/s\n", name,
1220                                 (double)num / tt);
1221                         fflush(stdout);
1222                         break;
1223                 }
1224                 num <<= 1;
1225         }
1226 }
1227
1228 static void
1229 test_speed_ecdsa_p256_m15(void)
1230 {
1231         test_speed_ecdsa_inner("ECDSA m15 P-256",
1232                 &br_ec_p256_m15, &br_secp256r1,
1233                 &br_ecdsa_i15_sign_asn1,
1234                 &br_ecdsa_i15_vrfy_asn1);
1235 }
1236
1237 static void
1238 test_speed_ecdsa_p256_m31(void)
1239 {
1240         test_speed_ecdsa_inner("ECDSA m31 P-256",
1241                 &br_ec_p256_m31, &br_secp256r1,
1242                 &br_ecdsa_i31_sign_asn1,
1243                 &br_ecdsa_i31_vrfy_asn1);
1244 }
1245
1246 static void
1247 test_speed_ecdsa_p256_m62(void)
1248 {
1249         const br_ec_impl *ec;
1250
1251         ec = br_ec_p256_m62_get();
1252         if (ec != NULL) {
1253                 test_speed_ecdsa_inner("ECDSA m62 P-256",
1254                         ec, &br_secp256r1,
1255                         &br_ecdsa_i31_sign_asn1,
1256                         &br_ecdsa_i31_vrfy_asn1);
1257         } else {
1258                 printf("%-30s UNAVAILABLE\n", "ECDSA m62 P-256");
1259         }
1260 }
1261
1262 static void
1263 test_speed_ecdsa_p256_m64(void)
1264 {
1265         const br_ec_impl *ec;
1266
1267         ec = br_ec_p256_m64_get();
1268         if (ec != NULL) {
1269                 test_speed_ecdsa_inner("ECDSA m64 P-256",
1270                         ec, &br_secp256r1,
1271                         &br_ecdsa_i31_sign_asn1,
1272                         &br_ecdsa_i31_vrfy_asn1);
1273         } else {
1274                 printf("%-30s UNAVAILABLE\n", "ECDSA m64 P-256");
1275         }
1276 }
1277
1278 static void
1279 test_speed_ecdsa_i15(void)
1280 {
1281         test_speed_ecdsa_inner("ECDSA i15 P-256",
1282                 &br_ec_prime_i15, &br_secp256r1,
1283                 &br_ecdsa_i15_sign_asn1,
1284                 &br_ecdsa_i15_vrfy_asn1);
1285         test_speed_ecdsa_inner("ECDSA i15 P-384",
1286                 &br_ec_prime_i15, &br_secp384r1,
1287                 &br_ecdsa_i15_sign_asn1,
1288                 &br_ecdsa_i15_vrfy_asn1);
1289         test_speed_ecdsa_inner("ECDSA i15 P-521",
1290                 &br_ec_prime_i15, &br_secp521r1,
1291                 &br_ecdsa_i15_sign_asn1,
1292                 &br_ecdsa_i15_vrfy_asn1);
1293 }
1294
1295 static void
1296 test_speed_ecdsa_i31(void)
1297 {
1298         test_speed_ecdsa_inner("ECDSA i31 P-256",
1299                 &br_ec_prime_i31, &br_secp256r1,
1300                 &br_ecdsa_i31_sign_asn1,
1301                 &br_ecdsa_i31_vrfy_asn1);
1302         test_speed_ecdsa_inner("ECDSA i31 P-384",
1303                 &br_ec_prime_i31, &br_secp384r1,
1304                 &br_ecdsa_i31_sign_asn1,
1305                 &br_ecdsa_i31_vrfy_asn1);
1306         test_speed_ecdsa_inner("ECDSA i31 P-521",
1307                 &br_ec_prime_i31, &br_secp521r1,
1308                 &br_ecdsa_i31_sign_asn1,
1309                 &br_ecdsa_i31_vrfy_asn1);
1310 }
1311
1312 static void
1313 test_speed_i31(void)
1314 {
1315         static const unsigned char bp[] = {
1316                 /* A 521-bit prime integer (order of the P-521 curve). */
1317                 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
1318                 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
1319                 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
1320                 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
1321                 0xFF, 0xFA, 0x51, 0x86, 0x87, 0x83, 0xBF, 0x2F,
1322                 0x96, 0x6B, 0x7F, 0xCC, 0x01, 0x48, 0xF7, 0x09,
1323                 0xA5, 0xD0, 0x3B, 0xB5, 0xC9, 0xB8, 0x89, 0x9C,
1324                 0x47, 0xAE, 0xBB, 0x6F, 0xB7, 0x1E, 0x91, 0x38,
1325                 0x64, 0x09
1326         };
1327
1328         unsigned char tmp[60 + sizeof bp];
1329         uint32_t p[20], x[20], y[20], z[20], uu[60], p0i;
1330         int i;
1331         long num;
1332
1333         br_i31_decode(p, bp, sizeof bp);
1334         p0i = br_i31_ninv31(p[1]);
1335         memset(tmp, 'T', sizeof tmp);
1336         br_i31_decode_reduce(x, tmp, sizeof tmp, p);
1337         memset(tmp, 'U', sizeof tmp);
1338         br_i31_decode_reduce(y, tmp, sizeof tmp, p);
1339
1340         for (i = 0; i < 10; i ++) {
1341                 br_i31_to_monty(x, p);
1342         }
1343         num = 10;
1344         for (;;) {
1345                 clock_t begin, end;
1346                 double tt;
1347                 long k;
1348
1349                 begin = clock();
1350                 for (k = num; k > 0; k --) {
1351                         br_i31_to_monty(x, p);
1352                 }
1353                 end = clock();
1354                 tt = (double)(end - begin) / CLOCKS_PER_SEC;
1355                 if (tt >= 2.0) {
1356                         printf("%-30s %8.2f ops/s\n", "i31 to_monty",
1357                                 (double)num / tt);
1358                         fflush(stdout);
1359                         break;
1360                 }
1361                 num <<= 1;
1362         }
1363
1364         for (i = 0; i < 10; i ++) {
1365                 br_i31_from_monty(x, p, p0i);
1366         }
1367         num = 10;
1368         for (;;) {
1369                 clock_t begin, end;
1370                 double tt;
1371                 long k;
1372
1373                 begin = clock();
1374                 for (k = num; k > 0; k --) {
1375                         br_i31_from_monty(x, p, p0i);
1376                 }
1377                 end = clock();
1378                 tt = (double)(end - begin) / CLOCKS_PER_SEC;
1379                 if (tt >= 2.0) {
1380                         printf("%-30s %8.2f ops/s\n", "i31 from_monty",
1381                                 (double)num / tt);
1382                         fflush(stdout);
1383                         break;
1384                 }
1385                 num <<= 1;
1386         }
1387
1388         for (i = 0; i < 10; i ++) {
1389                 br_i31_montymul(z, x, y, p, p0i);
1390         }
1391         num = 10;
1392         for (;;) {
1393                 clock_t begin, end;
1394                 double tt;
1395                 long k;
1396
1397                 begin = clock();
1398                 for (k = num; k > 0; k --) {
1399                         br_i31_montymul(z, x, y, p, p0i);
1400                 }
1401                 end = clock();
1402                 tt = (double)(end - begin) / CLOCKS_PER_SEC;
1403                 if (tt >= 2.0) {
1404                         printf("%-30s %8.2f ops/s\n", "i31 montymul",
1405                                 (double)num / tt);
1406                         fflush(stdout);
1407                         break;
1408                 }
1409                 num <<= 1;
1410         }
1411
1412         for (i = 0; i < 10; i ++) {
1413                 br_i31_moddiv(x, y, p, p0i, uu);
1414         }
1415         num = 10;
1416         for (;;) {
1417                 clock_t begin, end;
1418                 double tt;
1419                 long k;
1420
1421                 begin = clock();
1422                 for (k = num; k > 0; k --) {
1423                         br_i31_moddiv(x, y, p, p0i, uu);
1424                 }
1425                 end = clock();
1426                 tt = (double)(end - begin) / CLOCKS_PER_SEC;
1427                 if (tt >= 2.0) {
1428                         printf("%-30s %8.2f ops/s\n", "i31 moddiv",
1429                                 (double)num / tt);
1430                         fflush(stdout);
1431                         break;
1432                 }
1433                 num <<= 1;
1434         }
1435 }
1436
1437 #if 0
1438
1439 static unsigned char P2048[] = {
1440         0xFD, 0xB6, 0xE0, 0x3E, 0x00, 0x49, 0x4C, 0xF0, 0x69, 0x3A, 0xDD, 0x7D,
1441         0xF8, 0xA2, 0x41, 0xB0, 0x6C, 0x67, 0xC5, 0xBA, 0xB8, 0x46, 0x80, 0xF5,
1442         0xBF, 0xAB, 0x98, 0xFC, 0x84, 0x73, 0xA5, 0x63, 0xC9, 0x52, 0x12, 0xDA,
1443         0x4C, 0xC1, 0x5B, 0x9D, 0x8D, 0xDF, 0xCD, 0xFE, 0xC5, 0xAD, 0x5A, 0x6F,
1444         0xDD, 0x02, 0xD9, 0xEC, 0x71, 0xEF, 0xEB, 0xB6, 0x95, 0xED, 0x94, 0x25,
1445         0x0E, 0x63, 0xDD, 0x6A, 0x52, 0xC7, 0x93, 0xAF, 0x85, 0x9D, 0x2C, 0xBE,
1446         0x5C, 0xBE, 0x35, 0xD8, 0xDD, 0x39, 0xEF, 0x1B, 0xB1, 0x49, 0x67, 0xB2,
1447         0x33, 0xC9, 0x7C, 0xE1, 0x51, 0x79, 0x51, 0x59, 0xCA, 0x6E, 0x2A, 0xDF,
1448         0x0D, 0x76, 0x1C, 0xE7, 0xA5, 0xC0, 0x1E, 0x6C, 0x56, 0x3A, 0x32, 0xE5,
1449         0xB5, 0xC5, 0xD4, 0xDB, 0xFE, 0xFF, 0xF8, 0xF2, 0x96, 0xA9, 0xC9, 0x65,
1450         0x59, 0x9E, 0x01, 0x79, 0x9D, 0x38, 0x68, 0x0F, 0xAD, 0x43, 0x3A, 0xD6,
1451         0x84, 0x0A, 0xE2, 0xEF, 0x96, 0xC1, 0x6D, 0x89, 0x74, 0x19, 0x63, 0x82,
1452         0x3B, 0xA0, 0x9C, 0xBA, 0x78, 0xDE, 0xDC, 0xC2, 0xE7, 0xD4, 0xFA, 0xD6,
1453         0x19, 0x21, 0x29, 0xAE, 0x5E, 0xF4, 0x38, 0x81, 0xC6, 0x9E, 0x0E, 0x3C,
1454         0xCD, 0xC0, 0xDC, 0x93, 0x5D, 0xFD, 0x9A, 0x5C, 0xAB, 0x54, 0x1F, 0xFF,
1455         0x9C, 0x12, 0x1B, 0x4C, 0xDF, 0x2D, 0x9C, 0x85, 0xF9, 0x68, 0x15, 0x89,
1456         0x42, 0x9B, 0x6C, 0x45, 0x89, 0x3A, 0xBC, 0xE9, 0x19, 0x91, 0xBE, 0x0C,
1457         0xEF, 0x90, 0xCC, 0xF6, 0xD6, 0xF0, 0x3D, 0x5C, 0xF5, 0xE5, 0x0F, 0x2F,
1458         0x02, 0x8A, 0x83, 0x4B, 0x93, 0x2F, 0x14, 0x12, 0x1F, 0x56, 0x9A, 0x12,
1459         0x58, 0x88, 0xAE, 0x60, 0xB8, 0x5A, 0xE4, 0xA1, 0xBF, 0x4A, 0x81, 0x84,
1460         0xAB, 0xBB, 0xE4, 0xD0, 0x1D, 0x41, 0xD9, 0x0A, 0xAB, 0x1E, 0x47, 0x5B,
1461         0x31, 0xAC, 0x2B, 0x73
1462 };
1463
1464 static unsigned char G2048[] = {
1465         0x02
1466 };
1467
1468 static void
1469 test_speed_modpow(void)
1470 {
1471         uint32_t mx[65], mp[65], me[65], t1[65], t2[65], len;
1472         unsigned char e[64];
1473         int i;
1474         long num;
1475
1476         len = br_int_decode(mp, sizeof mp / sizeof mp[0],
1477                 P2048, sizeof P2048);
1478         if (len != 65) {
1479                 abort();
1480         }
1481         memset(e, 'P', sizeof e);
1482         if (!br_int_decode(me, sizeof me / sizeof me[0], e, sizeof e)) {
1483                 abort();
1484         }
1485         if (!br_modint_decode(mx, mp, G2048, sizeof G2048)) {
1486                 abort();
1487         }
1488         for (i = 0; i < 10; i ++) {
1489                 br_modint_to_monty(mx, mp);
1490                 br_modint_montypow(mx, me, mp, t1, t2);
1491                 br_modint_from_monty(mx, mp);
1492         }
1493         num = 10;
1494         for (;;) {
1495                 clock_t begin, end;
1496                 double tt;
1497                 long k;
1498
1499                 begin = clock();
1500                 for (k = num; k > 0; k --) {
1501                         br_modint_to_monty(mx, mp);
1502                         br_modint_montypow(mx, me, mp, t1, t2);
1503                         br_modint_from_monty(mx, mp);
1504                 }
1505                 end = clock();
1506                 tt = (double)(end - begin) / CLOCKS_PER_SEC;
1507                 if (tt >= 2.0) {
1508                         printf("%-30s %8.2f exp/s\n", "pow[2048:256]",
1509                                 (double)num / tt);
1510                         fflush(stdout);
1511                         return;
1512                 }
1513                 num <<= 1;
1514         }
1515 }
1516
1517 static void
1518 test_speed_moddiv(void)
1519 {
1520         uint32_t mx[65], my[65], mp[65], t1[65], t2[65], t3[65], len;
1521         unsigned char x[255], y[255];
1522         int i;
1523         long num;
1524
1525         len = br_int_decode(mp, sizeof mp / sizeof mp[0],
1526                 P2048, sizeof P2048);
1527         if (len != 65) {
1528                 abort();
1529         }
1530         memset(x, 'T', sizeof x);
1531         memset(y, 'P', sizeof y);
1532         if (!br_modint_decode(mx, mp, x, sizeof x)) {
1533                 abort();
1534         }
1535         if (!br_modint_decode(my, mp, y, sizeof y)) {
1536                 abort();
1537         }
1538         for (i = 0; i < 10; i ++) {
1539                 br_modint_div(mx, my, mp, t1, t2, t3);
1540         }
1541         num = 10;
1542         for (;;) {
1543                 clock_t begin, end;
1544                 double tt;
1545                 long k;
1546
1547                 begin = clock();
1548                 for (k = num; k > 0; k --) {
1549                         br_modint_div(mx, my, mp, t1, t2, t3);
1550                 }
1551                 end = clock();
1552                 tt = (double)(end - begin) / CLOCKS_PER_SEC;
1553                 if (tt >= 2.0) {
1554                         printf("%-30s %8.2f div/s\n", "div[2048]",
1555                                 (double)num / tt);
1556                         fflush(stdout);
1557                         return;
1558                 }
1559                 num <<= 1;
1560         }
1561 }
1562 #endif
1563
1564 #define STU(x)   { test_speed_ ## x, #x }
1565
1566 static const struct {
1567         void (*fn)(void);
1568         char *name;
1569 } tfns[] = {
1570         STU(md5),
1571         STU(sha1),
1572         STU(sha256),
1573         STU(sha512),
1574
1575         STU(aes128_big_cbcenc),
1576         STU(aes128_big_cbcdec),
1577         STU(aes192_big_cbcenc),
1578         STU(aes192_big_cbcdec),
1579         STU(aes256_big_cbcenc),
1580         STU(aes256_big_cbcdec),
1581         STU(aes128_big_ctr),
1582         STU(aes192_big_ctr),
1583         STU(aes256_big_ctr),
1584
1585         STU(aes128_small_cbcenc),
1586         STU(aes128_small_cbcdec),
1587         STU(aes192_small_cbcenc),
1588         STU(aes192_small_cbcdec),
1589         STU(aes256_small_cbcenc),
1590         STU(aes256_small_cbcdec),
1591         STU(aes128_small_ctr),
1592         STU(aes192_small_ctr),
1593         STU(aes256_small_ctr),
1594
1595         STU(aes128_ct_cbcenc),
1596         STU(aes128_ct_cbcdec),
1597         STU(aes192_ct_cbcenc),
1598         STU(aes192_ct_cbcdec),
1599         STU(aes256_ct_cbcenc),
1600         STU(aes256_ct_cbcdec),
1601         STU(aes128_ct_ctr),
1602         STU(aes192_ct_ctr),
1603         STU(aes256_ct_ctr),
1604
1605         STU(aes128_ct64_cbcenc),
1606         STU(aes128_ct64_cbcdec),
1607         STU(aes192_ct64_cbcenc),
1608         STU(aes192_ct64_cbcdec),
1609         STU(aes256_ct64_cbcenc),
1610         STU(aes256_ct64_cbcdec),
1611         STU(aes128_ct64_ctr),
1612         STU(aes192_ct64_ctr),
1613         STU(aes256_ct64_ctr),
1614
1615         STU(aes128_x86ni_cbcenc),
1616         STU(aes128_x86ni_cbcdec),
1617         STU(aes192_x86ni_cbcenc),
1618         STU(aes192_x86ni_cbcdec),
1619         STU(aes256_x86ni_cbcenc),
1620         STU(aes256_x86ni_cbcdec),
1621         STU(aes128_x86ni_ctr),
1622         STU(aes192_x86ni_ctr),
1623         STU(aes256_x86ni_ctr),
1624
1625         STU(aes128_pwr8_cbcenc),
1626         STU(aes128_pwr8_cbcdec),
1627         STU(aes192_pwr8_cbcenc),
1628         STU(aes192_pwr8_cbcdec),
1629         STU(aes256_pwr8_cbcenc),
1630         STU(aes256_pwr8_cbcdec),
1631         STU(aes128_pwr8_ctr),
1632         STU(aes192_pwr8_ctr),
1633         STU(aes256_pwr8_ctr),
1634
1635         STU(des_tab_cbcenc),
1636         STU(des_tab_cbcdec),
1637         STU(3des_tab_cbcenc),
1638         STU(3des_tab_cbcdec),
1639
1640         STU(des_ct_cbcenc),
1641         STU(des_ct_cbcdec),
1642         STU(3des_ct_cbcenc),
1643         STU(3des_ct_cbcdec),
1644
1645         STU(chacha20_ct),
1646         STU(chacha20_sse2),
1647
1648         STU(ghash_ctmul),
1649         STU(ghash_ctmul32),
1650         STU(ghash_ctmul64),
1651         STU(ghash_pclmul),
1652         STU(ghash_pwr8),
1653
1654         STU(poly1305_ctmul),
1655         STU(poly1305_ctmul32),
1656         STU(poly1305_ctmulq),
1657         STU(poly1305_i15),
1658
1659         STU(eax_aes128_big),
1660         STU(eax_aes192_big),
1661         STU(eax_aes256_big),
1662         STU(eax_aes128_small),
1663         STU(eax_aes192_small),
1664         STU(eax_aes256_small),
1665         STU(eax_aes128_ct),
1666         STU(eax_aes192_ct),
1667         STU(eax_aes256_ct),
1668         STU(eax_aes128_ct64),
1669         STU(eax_aes192_ct64),
1670         STU(eax_aes256_ct64),
1671         STU(eax_aes128_x86ni),
1672         STU(eax_aes192_x86ni),
1673         STU(eax_aes256_x86ni),
1674         STU(eax_aes128_pwr8),
1675         STU(eax_aes192_pwr8),
1676         STU(eax_aes256_pwr8),
1677
1678         STU(shake128),
1679         STU(shake256),
1680
1681         STU(rsa_i15),
1682         STU(rsa_i31),
1683         STU(rsa_i32),
1684         STU(rsa_i62),
1685         STU(ec_prime_i15),
1686         STU(ec_prime_i31),
1687         STU(ec_p256_m15),
1688         STU(ec_p256_m31),
1689         STU(ec_p256_m62),
1690         STU(ec_p256_m64),
1691         STU(ec_c25519_i15),
1692         STU(ec_c25519_i31),
1693         STU(ec_c25519_m15),
1694         STU(ec_c25519_m31),
1695         STU(ec_c25519_m62),
1696         STU(ec_c25519_m64),
1697         STU(ecdsa_p256_m15),
1698         STU(ecdsa_p256_m31),
1699         STU(ecdsa_p256_m62),
1700         STU(ecdsa_p256_m64),
1701         STU(ecdsa_i15),
1702         STU(ecdsa_i31),
1703
1704         STU(i31)
1705 };
1706
1707 static int
1708 eq_name(const char *s1, const char *s2)
1709 {
1710         for (;;) {
1711                 int c1, c2;
1712
1713                 for (;;) {
1714                         c1 = *s1 ++;
1715                         if (c1 >= 'A' && c1 <= 'Z') {
1716                                 c1 += 'a' - 'A';
1717                         } else {
1718                                 switch (c1) {
1719                                 case '-': case '_': case '.': case ' ':
1720                                         continue;
1721                                 }
1722                         }
1723                         break;
1724                 }
1725                 for (;;) {
1726                         c2 = *s2 ++;
1727                         if (c2 >= 'A' && c2 <= 'Z') {
1728                                 c2 += 'a' - 'A';
1729                         } else {
1730                                 switch (c2) {
1731                                 case '-': case '_': case '.': case ' ':
1732                                         continue;
1733                                 }
1734                         }
1735                         break;
1736                 }
1737                 if (c1 != c2) {
1738                         return 0;
1739                 }
1740                 if (c1 == 0) {
1741                         return 1;
1742                 }
1743         }
1744 }
1745
1746 int
1747 main(int argc, char *argv[])
1748 {
1749         size_t u;
1750
1751         if (argc <= 1) {
1752                 printf("usage: testspeed all | name...\n");
1753                 printf("individual test names:\n");
1754                 for (u = 0; u < (sizeof tfns) / (sizeof tfns[0]); u ++) {
1755                         printf("   %s\n", tfns[u].name);
1756                 }
1757         } else {
1758                 for (u = 0; u < (sizeof tfns) / (sizeof tfns[0]); u ++) {
1759                         int i;
1760
1761                         for (i = 1; i < argc; i ++) {
1762                                 if (eq_name(argv[i], tfns[u].name)
1763                                         || eq_name(argv[i], "all"))
1764                                 {
1765                                         tfns[u].fn();
1766                                         break;
1767                                 }
1768                         }
1769                 }
1770         }
1771         return 0;
1772 }