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