Added AESCTR_DRBG implementation (beta).
[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, 192, big)
522 SPEED_EAX(AES, aes, 192, small)
523 SPEED_EAX(AES, aes, 192, ct)
524 SPEED_EAX(AES, aes, 192, ct64)
525 SPEED_EAX(AES, aes, 192, x86ni)
526 SPEED_EAX(AES, aes, 256, big)
527 SPEED_EAX(AES, aes, 256, small)
528 SPEED_EAX(AES, aes, 256, ct)
529 SPEED_EAX(AES, aes, 256, ct64)
530 SPEED_EAX(AES, aes, 256, x86ni)
531
532 static const unsigned char RSA_N[] = {
533 0xE9, 0xF2, 0x4A, 0x2F, 0x96, 0xDF, 0x0A, 0x23,
534 0x01, 0x85, 0xF1, 0x2C, 0xB2, 0xA8, 0xEF, 0x23,
535 0xCE, 0x2E, 0xB0, 0x4E, 0x18, 0x31, 0x95, 0x5B,
536 0x98, 0x2D, 0x9B, 0x8C, 0xE3, 0x1A, 0x2B, 0x96,
537 0xB5, 0xC7, 0xEE, 0xED, 0x72, 0x43, 0x2D, 0xFE,
538 0x7F, 0x61, 0x33, 0xEA, 0x14, 0xFC, 0xDE, 0x80,
539 0x17, 0x42, 0xF0, 0xF3, 0xC3, 0xC7, 0x89, 0x47,
540 0x76, 0x5B, 0xFA, 0x33, 0xC4, 0x8C, 0x94, 0xDE,
541 0x6A, 0x75, 0xD8, 0x1A, 0xF4, 0x49, 0xBC, 0xF3,
542 0xB7, 0x9E, 0x2C, 0x8D, 0xEC, 0x5A, 0xEE, 0xBF,
543 0x4B, 0x5A, 0x7F, 0xEF, 0x21, 0x39, 0xDB, 0x1D,
544 0x83, 0x5E, 0x7E, 0x2F, 0xAA, 0x5E, 0xBA, 0x28,
545 0xC3, 0xA2, 0x53, 0x19, 0xFB, 0x2F, 0x78, 0x6B,
546 0x14, 0x60, 0x49, 0x3C, 0xCC, 0x1B, 0xE9, 0x1E,
547 0x3D, 0x10, 0xA4, 0xEB, 0x7F, 0x66, 0x98, 0xF6,
548 0xC3, 0xAC, 0x35, 0xF5, 0x01, 0x84, 0xFF, 0x7D,
549 0x1F, 0x72, 0xBE, 0xB4, 0xD1, 0x89, 0xC8, 0xDD,
550 0x44, 0xE7, 0xB5, 0x2E, 0x2C, 0xE1, 0x85, 0xF5,
551 0x15, 0x50, 0xA9, 0x08, 0xC7, 0x67, 0xD9, 0x2B,
552 0x6C, 0x11, 0xB3, 0xEB, 0x28, 0x8D, 0xF4, 0xCC,
553 0xE3, 0xC3, 0xC5, 0x04, 0x0E, 0x7C, 0x8D, 0xDB,
554 0x39, 0x06, 0x6A, 0x74, 0x75, 0xDF, 0xA8, 0x0F,
555 0xDA, 0x67, 0x5A, 0x73, 0x1E, 0xFD, 0x8E, 0x4C,
556 0xEE, 0x17, 0xEE, 0x1E, 0x67, 0xDB, 0x98, 0x70,
557 0x60, 0xF7, 0xB9, 0xB5, 0x1F, 0x19, 0x93, 0xD6,
558 0x3F, 0x2F, 0x1F, 0xB6, 0x5B, 0x59, 0xAA, 0x85,
559 0xBB, 0x25, 0xE4, 0x13, 0xEF, 0xE7, 0xB9, 0x87,
560 0x9C, 0x3F, 0x5E, 0xE4, 0x08, 0xA3, 0x51, 0xCF,
561 0x8B, 0xAD, 0xF4, 0xE6, 0x1A, 0x5F, 0x51, 0xDD,
562 0xA8, 0xBE, 0xE8, 0xD1, 0x20, 0x19, 0x61, 0x6C,
563 0x18, 0xAB, 0xCA, 0x0A, 0xD9, 0x82, 0xA6, 0x94,
564 0xD5, 0x69, 0x2A, 0xF6, 0x43, 0x66, 0x31, 0x09
565 };
566
567 static const unsigned char RSA_E[] = {
568 0x01, 0x00, 0x01
569 };
570
571 static const unsigned char RSA_P[] = {
572 0xFD, 0x39, 0x40, 0x56, 0x20, 0x80, 0xC5, 0x81,
573 0x4C, 0x5F, 0x0C, 0x1A, 0x52, 0x84, 0x03, 0x2F,
574 0xCE, 0x82, 0xB0, 0xD8, 0x30, 0x23, 0x7F, 0x77,
575 0x45, 0xC2, 0x01, 0xC4, 0x68, 0x96, 0x0D, 0xA7,
576 0x22, 0xA9, 0x6C, 0xA9, 0x1A, 0x33, 0xE5, 0x2F,
577 0xB5, 0x07, 0x9A, 0xF9, 0xEA, 0x33, 0xA5, 0xC8,
578 0x96, 0x60, 0x6A, 0xCA, 0xEB, 0xE5, 0x6E, 0x09,
579 0x46, 0x7E, 0x2D, 0xEF, 0x93, 0x7D, 0x56, 0xED,
580 0x75, 0x70, 0x3B, 0x96, 0xC4, 0xD5, 0xDB, 0x0B,
581 0x3F, 0x69, 0xDF, 0x06, 0x18, 0x76, 0xF4, 0xCF,
582 0xF8, 0x84, 0x22, 0xDF, 0xBD, 0x71, 0x62, 0x7B,
583 0x67, 0x99, 0xBC, 0x09, 0x95, 0x54, 0xA4, 0x98,
584 0x83, 0xF5, 0xA9, 0xCF, 0x09, 0xA5, 0x1F, 0x61,
585 0x25, 0xB4, 0x70, 0x6C, 0x91, 0xB8, 0xB3, 0xD0,
586 0xCE, 0x9C, 0x45, 0x65, 0x9B, 0xEF, 0xD4, 0x70,
587 0xBE, 0x86, 0xD2, 0x98, 0x5D, 0xEB, 0xE3, 0xFF
588 };
589
590 static const unsigned char RSA_Q[] = {
591 0xEC, 0x82, 0xEE, 0x63, 0x5F, 0x40, 0x52, 0xDB,
592 0x38, 0x7A, 0x37, 0x6A, 0x54, 0x5B, 0xD9, 0xA0,
593 0x73, 0xB4, 0xBB, 0x52, 0xB2, 0x84, 0x07, 0xD0,
594 0xCC, 0x82, 0x0D, 0x20, 0xB3, 0xFA, 0xD5, 0xB6,
595 0x25, 0x92, 0x35, 0x4D, 0xB4, 0xC7, 0x36, 0x48,
596 0xCE, 0x5E, 0x21, 0x4A, 0xA6, 0x74, 0x65, 0xF4,
597 0x7D, 0x1D, 0xBC, 0x3B, 0xE2, 0xF4, 0x3E, 0x11,
598 0x58, 0x10, 0x6C, 0x04, 0x46, 0x9E, 0x8D, 0x57,
599 0xE0, 0x04, 0xE2, 0xEC, 0x47, 0xCF, 0xB3, 0x2A,
600 0xFD, 0x4C, 0x55, 0x18, 0xDB, 0xDE, 0x3B, 0xDC,
601 0xF4, 0x5B, 0xDA, 0xF3, 0x1A, 0xC8, 0x41, 0x6F,
602 0x73, 0x3B, 0xFE, 0x3C, 0xA0, 0xDB, 0xBA, 0x6E,
603 0x65, 0xA5, 0xE8, 0x02, 0xA5, 0x6C, 0xEA, 0x03,
604 0xF6, 0x99, 0xF7, 0xCB, 0x4B, 0xB7, 0x11, 0x51,
605 0x93, 0x88, 0x3F, 0xF9, 0x06, 0x85, 0xA9, 0x1E,
606 0xCA, 0x64, 0xF8, 0x11, 0xA5, 0x1A, 0xCA, 0xF7
607 };
608
609 static const unsigned char RSA_DP[] = {
610 0x77, 0x95, 0xE0, 0x02, 0x4C, 0x9B, 0x43, 0xAA,
611 0xCA, 0x4C, 0x60, 0xC4, 0xD5, 0x8F, 0x2E, 0x8A,
612 0x17, 0x36, 0xB5, 0x19, 0x83, 0xB2, 0x5F, 0xF2,
613 0x0D, 0xE9, 0x8F, 0x38, 0x18, 0x44, 0x34, 0xF2,
614 0x67, 0x76, 0x27, 0xB0, 0xBC, 0x85, 0x21, 0x89,
615 0x24, 0x2F, 0x11, 0x4B, 0x51, 0x05, 0x4F, 0x17,
616 0xA9, 0x9C, 0xA3, 0x12, 0x6D, 0xD1, 0x0D, 0xE4,
617 0x27, 0x7C, 0x53, 0x69, 0x3E, 0xF8, 0x04, 0x63,
618 0x64, 0x00, 0xBA, 0xC3, 0x7A, 0xF5, 0x9B, 0xDA,
619 0x75, 0xFA, 0x23, 0xAF, 0x17, 0x42, 0xA6, 0x5E,
620 0xC8, 0xF8, 0x6E, 0x17, 0xC7, 0xB9, 0x92, 0x4E,
621 0xC1, 0x20, 0x63, 0x23, 0x0B, 0x78, 0xCB, 0xBA,
622 0x93, 0x27, 0x23, 0x28, 0x79, 0x5F, 0x97, 0xB0,
623 0x23, 0x44, 0x51, 0x8B, 0x94, 0x4D, 0xEB, 0xED,
624 0x82, 0x85, 0x5E, 0x68, 0x9B, 0xF9, 0xE9, 0x13,
625 0xCD, 0x86, 0x92, 0x52, 0x0E, 0x98, 0xE6, 0x35
626 };
627
628 static const unsigned char RSA_DQ[] = {
629 0xD8, 0xDD, 0x71, 0xB3, 0x62, 0xBA, 0xBB, 0x7E,
630 0xD1, 0xF9, 0x96, 0xE8, 0x83, 0xB3, 0xB9, 0x08,
631 0x9C, 0x30, 0x03, 0x77, 0xDF, 0xC2, 0x9A, 0xDC,
632 0x05, 0x39, 0xD6, 0xC9, 0xBE, 0xDE, 0x68, 0xA9,
633 0xDD, 0x27, 0x84, 0x82, 0xDD, 0x19, 0xB1, 0x97,
634 0xEE, 0xCA, 0x77, 0x22, 0x59, 0x20, 0xEF, 0xFF,
635 0xCF, 0xDD, 0xBD, 0x24, 0xF8, 0x84, 0xD6, 0x88,
636 0xD6, 0xC4, 0x30, 0x17, 0x77, 0x9D, 0x98, 0xA3,
637 0x14, 0x01, 0xC7, 0x05, 0xBB, 0x0F, 0x23, 0x0D,
638 0x6F, 0x37, 0x57, 0xEC, 0x34, 0x67, 0x41, 0x62,
639 0xE8, 0x19, 0x75, 0xD9, 0x66, 0x1C, 0x6B, 0x8B,
640 0xC3, 0x11, 0x26, 0x9C, 0xF7, 0x2E, 0xA3, 0x72,
641 0xE8, 0xF7, 0xC8, 0x96, 0xEC, 0x92, 0xC2, 0xBD,
642 0xA1, 0x98, 0x2A, 0x93, 0x99, 0xB8, 0xA2, 0x43,
643 0xB7, 0xD0, 0xBE, 0x40, 0x1C, 0x8F, 0xE0, 0xB4,
644 0x20, 0x07, 0x97, 0x43, 0xAE, 0xAD, 0xB3, 0x9F
645 };
646
647 static const unsigned char RSA_IQ[] = {
648 0xB7, 0xE2, 0x60, 0xA9, 0x62, 0xEC, 0xEC, 0x0B,
649 0x57, 0x02, 0x96, 0xF9, 0x36, 0x35, 0x2C, 0x37,
650 0xAF, 0xC2, 0xEE, 0x71, 0x49, 0x26, 0x8E, 0x0F,
651 0x27, 0xB1, 0xFA, 0x0F, 0xEA, 0xDC, 0xF0, 0x8B,
652 0x53, 0x6C, 0xB2, 0x46, 0x27, 0xCD, 0x29, 0xA2,
653 0x35, 0x0F, 0x5D, 0x8A, 0x3F, 0x20, 0x8C, 0x13,
654 0x3D, 0xA1, 0xFF, 0x85, 0x91, 0x99, 0xE8, 0x50,
655 0xED, 0xF1, 0x29, 0x00, 0xEE, 0x24, 0x90, 0xB5,
656 0x5F, 0x3A, 0x74, 0x26, 0xD7, 0xA2, 0x24, 0x8D,
657 0x89, 0x88, 0xD8, 0x35, 0x22, 0x22, 0x8A, 0x66,
658 0x5D, 0x5C, 0xDE, 0x83, 0x8C, 0xFA, 0x27, 0xE6,
659 0xB9, 0xEB, 0x72, 0x08, 0xCD, 0x53, 0x4B, 0x93,
660 0x0F, 0xAD, 0xC3, 0xF8, 0x7C, 0xFE, 0x84, 0xD7,
661 0x08, 0xF3, 0xBE, 0x3D, 0x60, 0x1E, 0x95, 0x8D,
662 0x44, 0x5B, 0x65, 0x7E, 0xC1, 0x30, 0xC3, 0x84,
663 0xC0, 0xB0, 0xFE, 0xBF, 0x28, 0x54, 0x1E, 0xC4
664 };
665
666 static const br_rsa_public_key RSA_PK = {
667 (void *)RSA_N, sizeof RSA_N,
668 (void *)RSA_E, sizeof RSA_E
669 };
670
671 static const br_rsa_private_key RSA_SK = {
672 2048,
673 (void *)RSA_P, sizeof RSA_P,
674 (void *)RSA_Q, sizeof RSA_Q,
675 (void *)RSA_DP, sizeof RSA_DP,
676 (void *)RSA_DQ, sizeof RSA_DQ,
677 (void *)RSA_IQ, sizeof RSA_IQ
678 };
679
680 static void
681 test_speed_rsa_inner(char *name,
682 br_rsa_public fpub, br_rsa_private fpriv, br_rsa_keygen kgen)
683 {
684 unsigned char tmp[sizeof RSA_N];
685 int i;
686 long num;
687 /*
688 br_hmac_drbg_context rng;
689 */
690 br_aesctr_drbg_context rng;
691 const br_block_ctr_class *ictr;
692
693 memset(tmp, 'R', sizeof tmp);
694 tmp[0] = 0;
695 for (i = 0; i < 10; i ++) {
696 if (!fpriv(tmp, &RSA_SK)) {
697 abort();
698 }
699 }
700 num = 10;
701 for (;;) {
702 clock_t begin, end;
703 double tt;
704 long k;
705
706 begin = clock();
707 for (k = num; k > 0; k --) {
708 fpriv(tmp, &RSA_SK);
709 }
710 end = clock();
711 tt = (double)(end - begin) / CLOCKS_PER_SEC;
712 if (tt >= 2.0) {
713 printf("%-30s %8.2f priv/s\n", name,
714 (double)num / tt);
715 fflush(stdout);
716 break;
717 }
718 num <<= 1;
719 }
720 for (i = 0; i < 10; i ++) {
721 if (!fpub(tmp, sizeof tmp, &RSA_PK)) {
722 abort();
723 }
724 }
725 num = 10;
726 for (;;) {
727 clock_t begin, end;
728 double tt;
729 long k;
730
731 begin = clock();
732 for (k = num; k > 0; k --) {
733 fpub(tmp, sizeof tmp, &RSA_PK);
734 }
735 end = clock();
736 tt = (double)(end - begin) / CLOCKS_PER_SEC;
737 if (tt >= 2.0) {
738 printf("%-30s %8.2f pub/s\n", name,
739 (double)num / tt);
740 fflush(stdout);
741 break;
742 }
743 num <<= 1;
744 }
745
746 if (kgen == 0) {
747 printf("%-30s KEYGEN UNAVAILABLE\n", name);
748 fflush(stdout);
749 return;
750 }
751 /*
752 br_hmac_drbg_init(&rng, &br_sha256_vtable, "RSA keygen seed", 15);
753 */
754 ictr = br_aes_x86ni_ctr_get_vtable();
755 if (ictr == NULL) {
756 ictr = br_aes_pwr8_ctr_get_vtable();
757 if (ictr == NULL) {
758 #if BR_64
759 ictr = &br_aes_ct64_ctr_vtable;
760 #else
761 ictr = &br_aes_ct_ctr_vtable;
762 #endif
763 }
764 }
765 br_aesctr_drbg_init(&rng, ictr, "RSA keygen seed", 15);
766
767 num = 10;
768 for (;;) {
769 clock_t begin, end;
770 double tt;
771 long k;
772
773 begin = clock();
774 for (k = num; k > 0; k --) {
775 br_rsa_private_key sk;
776 unsigned char kbuf[BR_RSA_KBUF_PRIV_SIZE(1024)];
777
778 kgen(&rng.vtable, &sk, kbuf, NULL, NULL, 1024, 0);
779 }
780 end = clock();
781 tt = (double)(end - begin) / CLOCKS_PER_SEC;
782 if (tt >= 10.0) {
783 printf("%-30s %8.2f kgen[1024]/s\n", name,
784 (double)num / tt);
785 fflush(stdout);
786 break;
787 }
788 num <<= 1;
789 }
790
791 num = 10;
792 for (;;) {
793 clock_t begin, end;
794 double tt;
795 long k;
796
797 begin = clock();
798 for (k = num; k > 0; k --) {
799 br_rsa_private_key sk;
800 unsigned char kbuf[BR_RSA_KBUF_PRIV_SIZE(2048)];
801
802 kgen(&rng.vtable, &sk, kbuf, NULL, NULL, 2048, 0);
803 }
804 end = clock();
805 tt = (double)(end - begin) / CLOCKS_PER_SEC;
806 if (tt >= 10.0) {
807 printf("%-30s %8.2f kgen[2048]/s\n", name,
808 (double)num / tt);
809 fflush(stdout);
810 break;
811 }
812 num <<= 1;
813 }
814 }
815
816 static void
817 test_speed_rsa_i15(void)
818 {
819 test_speed_rsa_inner("RSA i15",
820 &br_rsa_i15_public, &br_rsa_i15_private, &br_rsa_i15_keygen);
821 }
822
823 static void
824 test_speed_rsa_i31(void)
825 {
826 test_speed_rsa_inner("RSA i31",
827 &br_rsa_i31_public, &br_rsa_i31_private, &br_rsa_i31_keygen);
828 }
829
830 static void
831 test_speed_rsa_i32(void)
832 {
833 test_speed_rsa_inner("RSA i32",
834 &br_rsa_i32_public, &br_rsa_i32_private, 0);
835 }
836
837 static void
838 test_speed_rsa_i62(void)
839 {
840 br_rsa_public pub;
841 br_rsa_private priv;
842 br_rsa_keygen kgen;
843
844 pub = br_rsa_i62_public_get();
845 priv = br_rsa_i62_private_get();
846 kgen = br_rsa_i62_keygen_get();
847 if (pub) {
848 test_speed_rsa_inner("RSA i62", pub, priv, kgen);
849 } else {
850 printf("%-30s UNAVAILABLE\n", "RSA i62");
851 }
852 }
853
854 static void
855 test_speed_ec_inner_1(const char *name,
856 const br_ec_impl *impl, const br_ec_curve_def *cd)
857 {
858 unsigned char bx[80], U[160];
859 uint32_t x[22], n[22];
860 size_t nlen, ulen;
861 int i;
862 long num;
863
864 nlen = cd->order_len;
865 br_i31_decode(n, cd->order, nlen);
866 memset(bx, 'T', sizeof bx);
867 br_i31_decode_reduce(x, bx, sizeof bx, n);
868 br_i31_encode(bx, nlen, x);
869 ulen = cd->generator_len;
870 memcpy(U, cd->generator, ulen);
871 for (i = 0; i < 10; i ++) {
872 impl->mul(U, ulen, bx, nlen, cd->curve);
873 }
874 num = 10;
875 for (;;) {
876 clock_t begin, end;
877 double tt;
878 long k;
879
880 begin = clock();
881 for (k = num; k > 0; k --) {
882 impl->mul(U, ulen, bx, nlen, cd->curve);
883 }
884 end = clock();
885 tt = (double)(end - begin) / CLOCKS_PER_SEC;
886 if (tt >= 2.0) {
887 printf("%-30s %8.2f mul/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_ec_inner_2(const char *name,
898 const br_ec_impl *impl, const br_ec_curve_def *cd)
899 {
900 unsigned char bx[80], U[160];
901 uint32_t x[22], n[22];
902 size_t nlen;
903 int i;
904 long num;
905
906 nlen = cd->order_len;
907 br_i31_decode(n, cd->order, nlen);
908 memset(bx, 'T', sizeof bx);
909 br_i31_decode_reduce(x, bx, sizeof bx, n);
910 br_i31_encode(bx, nlen, x);
911 for (i = 0; i < 10; i ++) {
912 impl->mulgen(U, bx, nlen, cd->curve);
913 }
914 num = 10;
915 for (;;) {
916 clock_t begin, end;
917 double tt;
918 long k;
919
920 begin = clock();
921 for (k = num; k > 0; k --) {
922 impl->mulgen(U, bx, nlen, cd->curve);
923 }
924 end = clock();
925 tt = (double)(end - begin) / CLOCKS_PER_SEC;
926 if (tt >= 2.0) {
927 printf("%-30s %8.2f mul/s\n", name,
928 (double)num / tt);
929 fflush(stdout);
930 break;
931 }
932 num <<= 1;
933 }
934 }
935
936 static void
937 test_speed_ec_inner(const char *name,
938 const br_ec_impl *impl, const br_ec_curve_def *cd)
939 {
940 char tmp[50];
941
942 test_speed_ec_inner_1(name, impl, cd);
943 sprintf(tmp, "%s (FP)", name);
944 test_speed_ec_inner_2(tmp, impl, cd);
945 }
946
947 static void
948 test_speed_ec_p256_m15(void)
949 {
950 test_speed_ec_inner("EC p256_m15",
951 &br_ec_p256_m15, &br_secp256r1);
952 }
953
954 static void
955 test_speed_ec_p256_m31(void)
956 {
957 test_speed_ec_inner("EC p256_m31",
958 &br_ec_p256_m31, &br_secp256r1);
959 }
960
961 static void
962 test_speed_ec_prime_i15(void)
963 {
964 test_speed_ec_inner("EC prime_i15 P-256",
965 &br_ec_prime_i15, &br_secp256r1);
966 test_speed_ec_inner("EC prime_i15 P-384",
967 &br_ec_prime_i15, &br_secp384r1);
968 test_speed_ec_inner("EC prime_i15 P-521",
969 &br_ec_prime_i15, &br_secp521r1);
970 }
971
972 static void
973 test_speed_ec_prime_i31(void)
974 {
975 test_speed_ec_inner("EC prime_i31 P-256",
976 &br_ec_prime_i31, &br_secp256r1);
977 test_speed_ec_inner("EC prime_i31 P-384",
978 &br_ec_prime_i31, &br_secp384r1);
979 test_speed_ec_inner("EC prime_i31 P-521",
980 &br_ec_prime_i31, &br_secp521r1);
981 }
982
983 static void
984 test_speed_ec_c25519_i15(void)
985 {
986 test_speed_ec_inner("EC c25519_i15",
987 &br_ec_c25519_i15, &br_curve25519);
988 }
989
990 static void
991 test_speed_ec_c25519_i31(void)
992 {
993 test_speed_ec_inner("EC c25519_i31",
994 &br_ec_c25519_i31, &br_curve25519);
995 }
996
997 static void
998 test_speed_ec_c25519_m15(void)
999 {
1000 test_speed_ec_inner("EC c25519_m15",
1001 &br_ec_c25519_m15, &br_curve25519);
1002 }
1003
1004 static void
1005 test_speed_ec_c25519_m31(void)
1006 {
1007 test_speed_ec_inner("EC c25519_m31",
1008 &br_ec_c25519_m31, &br_curve25519);
1009 }
1010
1011 static void
1012 test_speed_ecdsa_inner(const char *name,
1013 const br_ec_impl *impl, const br_ec_curve_def *cd,
1014 br_ecdsa_sign sign, br_ecdsa_vrfy vrfy)
1015 {
1016 unsigned char bx[80], U[160], hv[32], sig[160];
1017 uint32_t x[22], n[22];
1018 size_t nlen, ulen, sig_len;
1019 int i;
1020 long num;
1021 br_ec_private_key sk;
1022 br_ec_public_key pk;
1023
1024 nlen = cd->order_len;
1025 br_i31_decode(n, cd->order, nlen);
1026 memset(bx, 'T', sizeof bx);
1027 br_i31_decode_reduce(x, bx, sizeof bx, n);
1028 br_i31_encode(bx, nlen, x);
1029 ulen = cd->generator_len;
1030 memcpy(U, cd->generator, ulen);
1031 impl->mul(U, ulen, bx, nlen, cd->curve);
1032 sk.curve = cd->curve;
1033 sk.x = bx;
1034 sk.xlen = nlen;
1035 pk.curve = cd->curve;
1036 pk.q = U;
1037 pk.qlen = ulen;
1038
1039 memset(hv, 'H', sizeof hv);
1040 sig_len = sign(impl, &br_sha256_vtable, hv, &sk, sig);
1041 if (vrfy(impl, hv, sizeof hv, &pk, sig, sig_len) != 1) {
1042 fprintf(stderr, "self-test sign/verify failed\n");
1043 exit(EXIT_FAILURE);
1044 }
1045
1046 for (i = 0; i < 10; i ++) {
1047 hv[1] ++;
1048 sign(impl, &br_sha256_vtable, hv, &sk, sig);
1049 vrfy(impl, hv, sizeof hv, &pk, sig, sig_len);
1050 }
1051
1052 num = 10;
1053 for (;;) {
1054 clock_t begin, end;
1055 double tt;
1056 long k;
1057
1058 begin = clock();
1059 for (k = num; k > 0; k --) {
1060 hv[1] ++;
1061 sig_len = sign(impl, &br_sha256_vtable, hv, &sk, sig);
1062 }
1063 end = clock();
1064 tt = (double)(end - begin) / CLOCKS_PER_SEC;
1065 if (tt >= 2.0) {
1066 printf("%-30s %8.2f sign/s\n", name,
1067 (double)num / tt);
1068 fflush(stdout);
1069 break;
1070 }
1071 num <<= 1;
1072 }
1073
1074 num = 10;
1075 for (;;) {
1076 clock_t begin, end;
1077 double tt;
1078 long k;
1079
1080 begin = clock();
1081 for (k = num; k > 0; k --) {
1082 vrfy(impl, hv, sizeof hv, &pk, sig, sig_len);
1083 }
1084 end = clock();
1085 tt = (double)(end - begin) / CLOCKS_PER_SEC;
1086 if (tt >= 2.0) {
1087 printf("%-30s %8.2f verify/s\n", name,
1088 (double)num / tt);
1089 fflush(stdout);
1090 break;
1091 }
1092 num <<= 1;
1093 }
1094 }
1095
1096 static void
1097 test_speed_ecdsa_p256_m15(void)
1098 {
1099 test_speed_ecdsa_inner("ECDSA m15 P-256",
1100 &br_ec_p256_m15, &br_secp256r1,
1101 &br_ecdsa_i15_sign_asn1,
1102 &br_ecdsa_i15_vrfy_asn1);
1103 }
1104
1105 static void
1106 test_speed_ecdsa_p256_m31(void)
1107 {
1108 test_speed_ecdsa_inner("ECDSA m31 P-256",
1109 &br_ec_p256_m31, &br_secp256r1,
1110 &br_ecdsa_i31_sign_asn1,
1111 &br_ecdsa_i31_vrfy_asn1);
1112 }
1113
1114 static void
1115 test_speed_ecdsa_i15(void)
1116 {
1117 test_speed_ecdsa_inner("ECDSA i15 P-256",
1118 &br_ec_prime_i15, &br_secp256r1,
1119 &br_ecdsa_i15_sign_asn1,
1120 &br_ecdsa_i15_vrfy_asn1);
1121 test_speed_ecdsa_inner("ECDSA i15 P-384",
1122 &br_ec_prime_i15, &br_secp384r1,
1123 &br_ecdsa_i15_sign_asn1,
1124 &br_ecdsa_i15_vrfy_asn1);
1125 test_speed_ecdsa_inner("ECDSA i15 P-521",
1126 &br_ec_prime_i15, &br_secp521r1,
1127 &br_ecdsa_i15_sign_asn1,
1128 &br_ecdsa_i15_vrfy_asn1);
1129 }
1130
1131 static void
1132 test_speed_ecdsa_i31(void)
1133 {
1134 test_speed_ecdsa_inner("ECDSA i31 P-256",
1135 &br_ec_prime_i31, &br_secp256r1,
1136 &br_ecdsa_i31_sign_asn1,
1137 &br_ecdsa_i31_vrfy_asn1);
1138 test_speed_ecdsa_inner("ECDSA i31 P-384",
1139 &br_ec_prime_i31, &br_secp384r1,
1140 &br_ecdsa_i31_sign_asn1,
1141 &br_ecdsa_i31_vrfy_asn1);
1142 test_speed_ecdsa_inner("ECDSA i31 P-521",
1143 &br_ec_prime_i31, &br_secp521r1,
1144 &br_ecdsa_i31_sign_asn1,
1145 &br_ecdsa_i31_vrfy_asn1);
1146 }
1147
1148 static void
1149 test_speed_i31(void)
1150 {
1151 static const unsigned char bp[] = {
1152 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00,
1153 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
1154 0xBC, 0xE6, 0xFA, 0xAD, 0xA7, 0x17, 0x9E, 0x84,
1155 0xF3, 0xB9, 0xCA, 0xC2, 0xFC, 0x63, 0x25, 0x51
1156 };
1157
1158 unsigned char tmp[60 + sizeof bp];
1159 uint32_t p[10], x[10], y[10], z[10], p0i;
1160 int i;
1161 long num;
1162
1163 br_i31_decode(p, bp, sizeof bp);
1164 p0i = br_i31_ninv31(p[1]);
1165 memset(tmp, 'T', sizeof tmp);
1166 br_i31_decode_reduce(x, tmp, sizeof tmp, p);
1167 memset(tmp, 'U', sizeof tmp);
1168 br_i31_decode_reduce(y, tmp, sizeof tmp, p);
1169
1170 for (i = 0; i < 10; i ++) {
1171 br_i31_to_monty(x, p);
1172 }
1173 num = 10;
1174 for (;;) {
1175 clock_t begin, end;
1176 double tt;
1177 long k;
1178
1179 begin = clock();
1180 for (k = num; k > 0; k --) {
1181 br_i31_to_monty(x, p);
1182 }
1183 end = clock();
1184 tt = (double)(end - begin) / CLOCKS_PER_SEC;
1185 if (tt >= 2.0) {
1186 printf("%-30s %8.2f ops/s\n", "i31 to_monty",
1187 (double)num / tt);
1188 fflush(stdout);
1189 break;
1190 }
1191 num <<= 1;
1192 }
1193
1194 for (i = 0; i < 10; i ++) {
1195 br_i31_from_monty(x, p, p0i);
1196 }
1197 num = 10;
1198 for (;;) {
1199 clock_t begin, end;
1200 double tt;
1201 long k;
1202
1203 begin = clock();
1204 for (k = num; k > 0; k --) {
1205 br_i31_from_monty(x, p, p0i);
1206 }
1207 end = clock();
1208 tt = (double)(end - begin) / CLOCKS_PER_SEC;
1209 if (tt >= 2.0) {
1210 printf("%-30s %8.2f ops/s\n", "i31 from_monty",
1211 (double)num / tt);
1212 fflush(stdout);
1213 break;
1214 }
1215 num <<= 1;
1216 }
1217
1218 for (i = 0; i < 10; i ++) {
1219 br_i31_montymul(z, x, y, p, p0i);
1220 }
1221 num = 10;
1222 for (;;) {
1223 clock_t begin, end;
1224 double tt;
1225 long k;
1226
1227 begin = clock();
1228 for (k = num; k > 0; k --) {
1229 br_i31_montymul(z, x, y, p, p0i);
1230 }
1231 end = clock();
1232 tt = (double)(end - begin) / CLOCKS_PER_SEC;
1233 if (tt >= 2.0) {
1234 printf("%-30s %8.2f ops/s\n", "i31 montymul",
1235 (double)num / tt);
1236 fflush(stdout);
1237 break;
1238 }
1239 num <<= 1;
1240 }
1241 }
1242
1243 #if 0
1244
1245 static unsigned char P2048[] = {
1246 0xFD, 0xB6, 0xE0, 0x3E, 0x00, 0x49, 0x4C, 0xF0, 0x69, 0x3A, 0xDD, 0x7D,
1247 0xF8, 0xA2, 0x41, 0xB0, 0x6C, 0x67, 0xC5, 0xBA, 0xB8, 0x46, 0x80, 0xF5,
1248 0xBF, 0xAB, 0x98, 0xFC, 0x84, 0x73, 0xA5, 0x63, 0xC9, 0x52, 0x12, 0xDA,
1249 0x4C, 0xC1, 0x5B, 0x9D, 0x8D, 0xDF, 0xCD, 0xFE, 0xC5, 0xAD, 0x5A, 0x6F,
1250 0xDD, 0x02, 0xD9, 0xEC, 0x71, 0xEF, 0xEB, 0xB6, 0x95, 0xED, 0x94, 0x25,
1251 0x0E, 0x63, 0xDD, 0x6A, 0x52, 0xC7, 0x93, 0xAF, 0x85, 0x9D, 0x2C, 0xBE,
1252 0x5C, 0xBE, 0x35, 0xD8, 0xDD, 0x39, 0xEF, 0x1B, 0xB1, 0x49, 0x67, 0xB2,
1253 0x33, 0xC9, 0x7C, 0xE1, 0x51, 0x79, 0x51, 0x59, 0xCA, 0x6E, 0x2A, 0xDF,
1254 0x0D, 0x76, 0x1C, 0xE7, 0xA5, 0xC0, 0x1E, 0x6C, 0x56, 0x3A, 0x32, 0xE5,
1255 0xB5, 0xC5, 0xD4, 0xDB, 0xFE, 0xFF, 0xF8, 0xF2, 0x96, 0xA9, 0xC9, 0x65,
1256 0x59, 0x9E, 0x01, 0x79, 0x9D, 0x38, 0x68, 0x0F, 0xAD, 0x43, 0x3A, 0xD6,
1257 0x84, 0x0A, 0xE2, 0xEF, 0x96, 0xC1, 0x6D, 0x89, 0x74, 0x19, 0x63, 0x82,
1258 0x3B, 0xA0, 0x9C, 0xBA, 0x78, 0xDE, 0xDC, 0xC2, 0xE7, 0xD4, 0xFA, 0xD6,
1259 0x19, 0x21, 0x29, 0xAE, 0x5E, 0xF4, 0x38, 0x81, 0xC6, 0x9E, 0x0E, 0x3C,
1260 0xCD, 0xC0, 0xDC, 0x93, 0x5D, 0xFD, 0x9A, 0x5C, 0xAB, 0x54, 0x1F, 0xFF,
1261 0x9C, 0x12, 0x1B, 0x4C, 0xDF, 0x2D, 0x9C, 0x85, 0xF9, 0x68, 0x15, 0x89,
1262 0x42, 0x9B, 0x6C, 0x45, 0x89, 0x3A, 0xBC, 0xE9, 0x19, 0x91, 0xBE, 0x0C,
1263 0xEF, 0x90, 0xCC, 0xF6, 0xD6, 0xF0, 0x3D, 0x5C, 0xF5, 0xE5, 0x0F, 0x2F,
1264 0x02, 0x8A, 0x83, 0x4B, 0x93, 0x2F, 0x14, 0x12, 0x1F, 0x56, 0x9A, 0x12,
1265 0x58, 0x88, 0xAE, 0x60, 0xB8, 0x5A, 0xE4, 0xA1, 0xBF, 0x4A, 0x81, 0x84,
1266 0xAB, 0xBB, 0xE4, 0xD0, 0x1D, 0x41, 0xD9, 0x0A, 0xAB, 0x1E, 0x47, 0x5B,
1267 0x31, 0xAC, 0x2B, 0x73
1268 };
1269
1270 static unsigned char G2048[] = {
1271 0x02
1272 };
1273
1274 static void
1275 test_speed_modpow(void)
1276 {
1277 uint32_t mx[65], mp[65], me[65], t1[65], t2[65], len;
1278 unsigned char e[64];
1279 int i;
1280 long num;
1281
1282 len = br_int_decode(mp, sizeof mp / sizeof mp[0],
1283 P2048, sizeof P2048);
1284 if (len != 65) {
1285 abort();
1286 }
1287 memset(e, 'P', sizeof e);
1288 if (!br_int_decode(me, sizeof me / sizeof me[0], e, sizeof e)) {
1289 abort();
1290 }
1291 if (!br_modint_decode(mx, mp, G2048, sizeof G2048)) {
1292 abort();
1293 }
1294 for (i = 0; i < 10; i ++) {
1295 br_modint_to_monty(mx, mp);
1296 br_modint_montypow(mx, me, mp, t1, t2);
1297 br_modint_from_monty(mx, mp);
1298 }
1299 num = 10;
1300 for (;;) {
1301 clock_t begin, end;
1302 double tt;
1303 long k;
1304
1305 begin = clock();
1306 for (k = num; k > 0; k --) {
1307 br_modint_to_monty(mx, mp);
1308 br_modint_montypow(mx, me, mp, t1, t2);
1309 br_modint_from_monty(mx, mp);
1310 }
1311 end = clock();
1312 tt = (double)(end - begin) / CLOCKS_PER_SEC;
1313 if (tt >= 2.0) {
1314 printf("%-30s %8.2f exp/s\n", "pow[2048:256]",
1315 (double)num / tt);
1316 fflush(stdout);
1317 return;
1318 }
1319 num <<= 1;
1320 }
1321 }
1322
1323 static void
1324 test_speed_moddiv(void)
1325 {
1326 uint32_t mx[65], my[65], mp[65], t1[65], t2[65], t3[65], len;
1327 unsigned char x[255], y[255];
1328 int i;
1329 long num;
1330
1331 len = br_int_decode(mp, sizeof mp / sizeof mp[0],
1332 P2048, sizeof P2048);
1333 if (len != 65) {
1334 abort();
1335 }
1336 memset(x, 'T', sizeof x);
1337 memset(y, 'P', sizeof y);
1338 if (!br_modint_decode(mx, mp, x, sizeof x)) {
1339 abort();
1340 }
1341 if (!br_modint_decode(my, mp, y, sizeof y)) {
1342 abort();
1343 }
1344 for (i = 0; i < 10; i ++) {
1345 br_modint_div(mx, my, mp, t1, t2, t3);
1346 }
1347 num = 10;
1348 for (;;) {
1349 clock_t begin, end;
1350 double tt;
1351 long k;
1352
1353 begin = clock();
1354 for (k = num; k > 0; k --) {
1355 br_modint_div(mx, my, mp, t1, t2, t3);
1356 }
1357 end = clock();
1358 tt = (double)(end - begin) / CLOCKS_PER_SEC;
1359 if (tt >= 2.0) {
1360 printf("%-30s %8.2f div/s\n", "div[2048]",
1361 (double)num / tt);
1362 fflush(stdout);
1363 return;
1364 }
1365 num <<= 1;
1366 }
1367 }
1368 #endif
1369
1370 #define STU(x) { test_speed_ ## x, #x }
1371
1372 static const struct {
1373 void (*fn)(void);
1374 char *name;
1375 } tfns[] = {
1376 STU(md5),
1377 STU(sha1),
1378 STU(sha256),
1379 STU(sha512),
1380
1381 STU(aes128_big_cbcenc),
1382 STU(aes128_big_cbcdec),
1383 STU(aes192_big_cbcenc),
1384 STU(aes192_big_cbcdec),
1385 STU(aes256_big_cbcenc),
1386 STU(aes256_big_cbcdec),
1387 STU(aes128_big_ctr),
1388 STU(aes192_big_ctr),
1389 STU(aes256_big_ctr),
1390
1391 STU(aes128_small_cbcenc),
1392 STU(aes128_small_cbcdec),
1393 STU(aes192_small_cbcenc),
1394 STU(aes192_small_cbcdec),
1395 STU(aes256_small_cbcenc),
1396 STU(aes256_small_cbcdec),
1397 STU(aes128_small_ctr),
1398 STU(aes192_small_ctr),
1399 STU(aes256_small_ctr),
1400
1401 STU(aes128_ct_cbcenc),
1402 STU(aes128_ct_cbcdec),
1403 STU(aes192_ct_cbcenc),
1404 STU(aes192_ct_cbcdec),
1405 STU(aes256_ct_cbcenc),
1406 STU(aes256_ct_cbcdec),
1407 STU(aes128_ct_ctr),
1408 STU(aes192_ct_ctr),
1409 STU(aes256_ct_ctr),
1410
1411 STU(aes128_ct64_cbcenc),
1412 STU(aes128_ct64_cbcdec),
1413 STU(aes192_ct64_cbcenc),
1414 STU(aes192_ct64_cbcdec),
1415 STU(aes256_ct64_cbcenc),
1416 STU(aes256_ct64_cbcdec),
1417 STU(aes128_ct64_ctr),
1418 STU(aes192_ct64_ctr),
1419 STU(aes256_ct64_ctr),
1420
1421 STU(aes128_x86ni_cbcenc),
1422 STU(aes128_x86ni_cbcdec),
1423 STU(aes192_x86ni_cbcenc),
1424 STU(aes192_x86ni_cbcdec),
1425 STU(aes256_x86ni_cbcenc),
1426 STU(aes256_x86ni_cbcdec),
1427 STU(aes128_x86ni_ctr),
1428 STU(aes192_x86ni_ctr),
1429 STU(aes256_x86ni_ctr),
1430
1431 STU(aes128_pwr8_cbcenc),
1432 STU(aes128_pwr8_cbcdec),
1433 STU(aes192_pwr8_cbcenc),
1434 STU(aes192_pwr8_cbcdec),
1435 STU(aes256_pwr8_cbcenc),
1436 STU(aes256_pwr8_cbcdec),
1437 STU(aes128_pwr8_ctr),
1438 STU(aes192_pwr8_ctr),
1439 STU(aes256_pwr8_ctr),
1440
1441 STU(des_tab_cbcenc),
1442 STU(des_tab_cbcdec),
1443 STU(3des_tab_cbcenc),
1444 STU(3des_tab_cbcdec),
1445
1446 STU(des_ct_cbcenc),
1447 STU(des_ct_cbcdec),
1448 STU(3des_ct_cbcenc),
1449 STU(3des_ct_cbcdec),
1450
1451 STU(chacha20_ct),
1452 STU(chacha20_sse2),
1453
1454 STU(ghash_ctmul),
1455 STU(ghash_ctmul32),
1456 STU(ghash_ctmul64),
1457 STU(ghash_pclmul),
1458 STU(ghash_pwr8),
1459
1460 STU(poly1305_ctmul),
1461 STU(poly1305_ctmul32),
1462 STU(poly1305_ctmulq),
1463 STU(poly1305_i15),
1464
1465 STU(eax_aes128_big),
1466 STU(eax_aes192_big),
1467 STU(eax_aes256_big),
1468 STU(eax_aes128_small),
1469 STU(eax_aes192_small),
1470 STU(eax_aes256_small),
1471 STU(eax_aes128_ct),
1472 STU(eax_aes192_ct),
1473 STU(eax_aes256_ct),
1474 STU(eax_aes128_ct64),
1475 STU(eax_aes192_ct64),
1476 STU(eax_aes256_ct64),
1477 STU(eax_aes128_x86ni),
1478 STU(eax_aes192_x86ni),
1479 STU(eax_aes256_x86ni),
1480
1481 STU(rsa_i15),
1482 STU(rsa_i31),
1483 STU(rsa_i32),
1484 STU(rsa_i62),
1485 STU(ec_prime_i15),
1486 STU(ec_prime_i31),
1487 STU(ec_p256_m15),
1488 STU(ec_p256_m31),
1489 STU(ec_c25519_i15),
1490 STU(ec_c25519_i31),
1491 STU(ec_c25519_m15),
1492 STU(ec_c25519_m31),
1493 STU(ecdsa_p256_m15),
1494 STU(ecdsa_p256_m31),
1495 STU(ecdsa_i15),
1496 STU(ecdsa_i31),
1497
1498 STU(i31)
1499 };
1500
1501 static int
1502 eq_name(const char *s1, const char *s2)
1503 {
1504 for (;;) {
1505 int c1, c2;
1506
1507 for (;;) {
1508 c1 = *s1 ++;
1509 if (c1 >= 'A' && c1 <= 'Z') {
1510 c1 += 'a' - 'A';
1511 } else {
1512 switch (c1) {
1513 case '-': case '_': case '.': case ' ':
1514 continue;
1515 }
1516 }
1517 break;
1518 }
1519 for (;;) {
1520 c2 = *s2 ++;
1521 if (c2 >= 'A' && c2 <= 'Z') {
1522 c2 += 'a' - 'A';
1523 } else {
1524 switch (c2) {
1525 case '-': case '_': case '.': case ' ':
1526 continue;
1527 }
1528 }
1529 break;
1530 }
1531 if (c1 != c2) {
1532 return 0;
1533 }
1534 if (c1 == 0) {
1535 return 1;
1536 }
1537 }
1538 }
1539
1540 int
1541 main(int argc, char *argv[])
1542 {
1543 size_t u;
1544
1545 if (argc <= 1) {
1546 printf("usage: testspeed all | name...\n");
1547 printf("individual test names:\n");
1548 for (u = 0; u < (sizeof tfns) / (sizeof tfns[0]); u ++) {
1549 printf(" %s\n", tfns[u].name);
1550 }
1551 } else {
1552 for (u = 0; u < (sizeof tfns) / (sizeof tfns[0]); u ++) {
1553 int i;
1554
1555 for (i = 1; i < argc; i ++) {
1556 if (eq_name(argv[i], tfns[u].name)
1557 || eq_name(argv[i], "all"))
1558 {
1559 tfns[u].fn();
1560 break;
1561 }
1562 }
1563 }
1564 }
1565 return 0;
1566 }