Fixed test code (removed static reference to aes_x86ni code).
[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)
683 {
684 unsigned char tmp[sizeof RSA_N];
685 int i;
686 long num;
687
688 memset(tmp, 'R', sizeof tmp);
689 tmp[0] = 0;
690 for (i = 0; i < 10; i ++) {
691 if (!fpriv(tmp, &RSA_SK)) {
692 abort();
693 }
694 }
695 num = 10;
696 for (;;) {
697 clock_t begin, end;
698 double tt;
699 long k;
700
701 begin = clock();
702 for (k = num; k > 0; k --) {
703 fpriv(tmp, &RSA_SK);
704 }
705 end = clock();
706 tt = (double)(end - begin) / CLOCKS_PER_SEC;
707 if (tt >= 2.0) {
708 printf("%-30s %8.2f priv/s\n", name,
709 (double)num / tt);
710 fflush(stdout);
711 break;
712 }
713 num <<= 1;
714 }
715 for (i = 0; i < 10; i ++) {
716 if (!fpub(tmp, sizeof tmp, &RSA_PK)) {
717 abort();
718 }
719 }
720 num = 10;
721 for (;;) {
722 clock_t begin, end;
723 double tt;
724 long k;
725
726 begin = clock();
727 for (k = num; k > 0; k --) {
728 fpub(tmp, sizeof tmp, &RSA_PK);
729 }
730 end = clock();
731 tt = (double)(end - begin) / CLOCKS_PER_SEC;
732 if (tt >= 2.0) {
733 printf("%-30s %8.2f pub/s\n", name,
734 (double)num / tt);
735 fflush(stdout);
736 break;
737 }
738 num <<= 1;
739 }
740 }
741
742 static void
743 test_speed_rsa_i15(void)
744 {
745 test_speed_rsa_inner("RSA i15",
746 &br_rsa_i15_public, &br_rsa_i15_private);
747 }
748
749 static void
750 test_speed_rsa_i31(void)
751 {
752 test_speed_rsa_inner("RSA i31",
753 &br_rsa_i31_public, &br_rsa_i31_private);
754 }
755
756 static void
757 test_speed_rsa_i32(void)
758 {
759 test_speed_rsa_inner("RSA i32",
760 &br_rsa_i32_public, &br_rsa_i32_private);
761 }
762
763 static void
764 test_speed_rsa_i62(void)
765 {
766 br_rsa_public pub;
767 br_rsa_private priv;
768
769 pub = br_rsa_i62_public_get();
770 priv = br_rsa_i62_private_get();
771 if (pub) {
772 test_speed_rsa_inner("RSA i62", pub, priv);
773 } else {
774 printf("%-30s UNAVAILABLE\n", "RSA i62");
775 }
776 }
777
778 static void
779 test_speed_ec_inner_1(const char *name,
780 const br_ec_impl *impl, const br_ec_curve_def *cd)
781 {
782 unsigned char bx[80], U[160];
783 uint32_t x[22], n[22];
784 size_t nlen, ulen;
785 int i;
786 long num;
787
788 nlen = cd->order_len;
789 br_i31_decode(n, cd->order, nlen);
790 memset(bx, 'T', sizeof bx);
791 br_i31_decode_reduce(x, bx, sizeof bx, n);
792 br_i31_encode(bx, nlen, x);
793 ulen = cd->generator_len;
794 memcpy(U, cd->generator, ulen);
795 for (i = 0; i < 10; i ++) {
796 impl->mul(U, ulen, bx, nlen, cd->curve);
797 }
798 num = 10;
799 for (;;) {
800 clock_t begin, end;
801 double tt;
802 long k;
803
804 begin = clock();
805 for (k = num; k > 0; k --) {
806 impl->mul(U, ulen, bx, nlen, cd->curve);
807 }
808 end = clock();
809 tt = (double)(end - begin) / CLOCKS_PER_SEC;
810 if (tt >= 2.0) {
811 printf("%-30s %8.2f mul/s\n", name,
812 (double)num / tt);
813 fflush(stdout);
814 break;
815 }
816 num <<= 1;
817 }
818 }
819
820 static void
821 test_speed_ec_inner_2(const char *name,
822 const br_ec_impl *impl, const br_ec_curve_def *cd)
823 {
824 unsigned char bx[80], U[160];
825 uint32_t x[22], n[22];
826 size_t nlen;
827 int i;
828 long num;
829
830 nlen = cd->order_len;
831 br_i31_decode(n, cd->order, nlen);
832 memset(bx, 'T', sizeof bx);
833 br_i31_decode_reduce(x, bx, sizeof bx, n);
834 br_i31_encode(bx, nlen, x);
835 for (i = 0; i < 10; i ++) {
836 impl->mulgen(U, bx, nlen, cd->curve);
837 }
838 num = 10;
839 for (;;) {
840 clock_t begin, end;
841 double tt;
842 long k;
843
844 begin = clock();
845 for (k = num; k > 0; k --) {
846 impl->mulgen(U, bx, nlen, cd->curve);
847 }
848 end = clock();
849 tt = (double)(end - begin) / CLOCKS_PER_SEC;
850 if (tt >= 2.0) {
851 printf("%-30s %8.2f mul/s\n", name,
852 (double)num / tt);
853 fflush(stdout);
854 break;
855 }
856 num <<= 1;
857 }
858 }
859
860 static void
861 test_speed_ec_inner(const char *name,
862 const br_ec_impl *impl, const br_ec_curve_def *cd)
863 {
864 char tmp[50];
865
866 test_speed_ec_inner_1(name, impl, cd);
867 sprintf(tmp, "%s (FP)", name);
868 test_speed_ec_inner_2(tmp, impl, cd);
869 }
870
871 static void
872 test_speed_ec_p256_m15(void)
873 {
874 test_speed_ec_inner("EC p256_m15",
875 &br_ec_p256_m15, &br_secp256r1);
876 }
877
878 static void
879 test_speed_ec_p256_m31(void)
880 {
881 test_speed_ec_inner("EC p256_m31",
882 &br_ec_p256_m31, &br_secp256r1);
883 }
884
885 static void
886 test_speed_ec_prime_i15(void)
887 {
888 test_speed_ec_inner("EC prime_i15 P-256",
889 &br_ec_prime_i15, &br_secp256r1);
890 test_speed_ec_inner("EC prime_i15 P-384",
891 &br_ec_prime_i15, &br_secp384r1);
892 test_speed_ec_inner("EC prime_i15 P-521",
893 &br_ec_prime_i15, &br_secp521r1);
894 }
895
896 static void
897 test_speed_ec_prime_i31(void)
898 {
899 test_speed_ec_inner("EC prime_i31 P-256",
900 &br_ec_prime_i31, &br_secp256r1);
901 test_speed_ec_inner("EC prime_i31 P-384",
902 &br_ec_prime_i31, &br_secp384r1);
903 test_speed_ec_inner("EC prime_i31 P-521",
904 &br_ec_prime_i31, &br_secp521r1);
905 }
906
907 static void
908 test_speed_ec_c25519_i15(void)
909 {
910 test_speed_ec_inner("EC c25519_i15",
911 &br_ec_c25519_i15, &br_curve25519);
912 }
913
914 static void
915 test_speed_ec_c25519_i31(void)
916 {
917 test_speed_ec_inner("EC c25519_i31",
918 &br_ec_c25519_i31, &br_curve25519);
919 }
920
921 static void
922 test_speed_ec_c25519_m15(void)
923 {
924 test_speed_ec_inner("EC c25519_m15",
925 &br_ec_c25519_m15, &br_curve25519);
926 }
927
928 static void
929 test_speed_ec_c25519_m31(void)
930 {
931 test_speed_ec_inner("EC c25519_m31",
932 &br_ec_c25519_m31, &br_curve25519);
933 }
934
935 static void
936 test_speed_ecdsa_inner(const char *name,
937 const br_ec_impl *impl, const br_ec_curve_def *cd,
938 br_ecdsa_sign sign, br_ecdsa_vrfy vrfy)
939 {
940 unsigned char bx[80], U[160], hv[32], sig[160];
941 uint32_t x[22], n[22];
942 size_t nlen, ulen, sig_len;
943 int i;
944 long num;
945 br_ec_private_key sk;
946 br_ec_public_key pk;
947
948 nlen = cd->order_len;
949 br_i31_decode(n, cd->order, nlen);
950 memset(bx, 'T', sizeof bx);
951 br_i31_decode_reduce(x, bx, sizeof bx, n);
952 br_i31_encode(bx, nlen, x);
953 ulen = cd->generator_len;
954 memcpy(U, cd->generator, ulen);
955 impl->mul(U, ulen, bx, nlen, cd->curve);
956 sk.curve = cd->curve;
957 sk.x = bx;
958 sk.xlen = nlen;
959 pk.curve = cd->curve;
960 pk.q = U;
961 pk.qlen = ulen;
962
963 memset(hv, 'H', sizeof hv);
964 sig_len = sign(impl, &br_sha256_vtable, hv, &sk, sig);
965 if (vrfy(impl, hv, sizeof hv, &pk, sig, sig_len) != 1) {
966 fprintf(stderr, "self-test sign/verify failed\n");
967 exit(EXIT_FAILURE);
968 }
969
970 for (i = 0; i < 10; i ++) {
971 hv[1] ++;
972 sign(impl, &br_sha256_vtable, hv, &sk, sig);
973 vrfy(impl, hv, sizeof hv, &pk, sig, sig_len);
974 }
975
976 num = 10;
977 for (;;) {
978 clock_t begin, end;
979 double tt;
980 long k;
981
982 begin = clock();
983 for (k = num; k > 0; k --) {
984 hv[1] ++;
985 sig_len = sign(impl, &br_sha256_vtable, hv, &sk, sig);
986 }
987 end = clock();
988 tt = (double)(end - begin) / CLOCKS_PER_SEC;
989 if (tt >= 2.0) {
990 printf("%-30s %8.2f sign/s\n", name,
991 (double)num / tt);
992 fflush(stdout);
993 break;
994 }
995 num <<= 1;
996 }
997
998 num = 10;
999 for (;;) {
1000 clock_t begin, end;
1001 double tt;
1002 long k;
1003
1004 begin = clock();
1005 for (k = num; k > 0; k --) {
1006 vrfy(impl, hv, sizeof hv, &pk, sig, sig_len);
1007 }
1008 end = clock();
1009 tt = (double)(end - begin) / CLOCKS_PER_SEC;
1010 if (tt >= 2.0) {
1011 printf("%-30s %8.2f verify/s\n", name,
1012 (double)num / tt);
1013 fflush(stdout);
1014 break;
1015 }
1016 num <<= 1;
1017 }
1018 }
1019
1020 static void
1021 test_speed_ecdsa_p256_m15(void)
1022 {
1023 test_speed_ecdsa_inner("ECDSA m15 P-256",
1024 &br_ec_p256_m15, &br_secp256r1,
1025 &br_ecdsa_i15_sign_asn1,
1026 &br_ecdsa_i15_vrfy_asn1);
1027 }
1028
1029 static void
1030 test_speed_ecdsa_p256_m31(void)
1031 {
1032 test_speed_ecdsa_inner("ECDSA m31 P-256",
1033 &br_ec_p256_m31, &br_secp256r1,
1034 &br_ecdsa_i31_sign_asn1,
1035 &br_ecdsa_i31_vrfy_asn1);
1036 }
1037
1038 static void
1039 test_speed_ecdsa_i15(void)
1040 {
1041 test_speed_ecdsa_inner("ECDSA i15 P-256",
1042 &br_ec_prime_i15, &br_secp256r1,
1043 &br_ecdsa_i15_sign_asn1,
1044 &br_ecdsa_i15_vrfy_asn1);
1045 test_speed_ecdsa_inner("ECDSA i15 P-384",
1046 &br_ec_prime_i15, &br_secp384r1,
1047 &br_ecdsa_i15_sign_asn1,
1048 &br_ecdsa_i15_vrfy_asn1);
1049 test_speed_ecdsa_inner("ECDSA i15 P-521",
1050 &br_ec_prime_i15, &br_secp521r1,
1051 &br_ecdsa_i15_sign_asn1,
1052 &br_ecdsa_i15_vrfy_asn1);
1053 }
1054
1055 static void
1056 test_speed_ecdsa_i31(void)
1057 {
1058 test_speed_ecdsa_inner("ECDSA i31 P-256",
1059 &br_ec_prime_i31, &br_secp256r1,
1060 &br_ecdsa_i31_sign_asn1,
1061 &br_ecdsa_i31_vrfy_asn1);
1062 test_speed_ecdsa_inner("ECDSA i31 P-384",
1063 &br_ec_prime_i31, &br_secp384r1,
1064 &br_ecdsa_i31_sign_asn1,
1065 &br_ecdsa_i31_vrfy_asn1);
1066 test_speed_ecdsa_inner("ECDSA i31 P-521",
1067 &br_ec_prime_i31, &br_secp521r1,
1068 &br_ecdsa_i31_sign_asn1,
1069 &br_ecdsa_i31_vrfy_asn1);
1070 }
1071
1072 static void
1073 test_speed_i31(void)
1074 {
1075 static const unsigned char bp[] = {
1076 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00,
1077 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
1078 0xBC, 0xE6, 0xFA, 0xAD, 0xA7, 0x17, 0x9E, 0x84,
1079 0xF3, 0xB9, 0xCA, 0xC2, 0xFC, 0x63, 0x25, 0x51
1080 };
1081
1082 unsigned char tmp[60 + sizeof bp];
1083 uint32_t p[10], x[10], y[10], z[10], p0i;
1084 int i;
1085 long num;
1086
1087 br_i31_decode(p, bp, sizeof bp);
1088 p0i = br_i31_ninv31(p[1]);
1089 memset(tmp, 'T', sizeof tmp);
1090 br_i31_decode_reduce(x, tmp, sizeof tmp, p);
1091 memset(tmp, 'U', sizeof tmp);
1092 br_i31_decode_reduce(y, tmp, sizeof tmp, p);
1093
1094 for (i = 0; i < 10; i ++) {
1095 br_i31_to_monty(x, p);
1096 }
1097 num = 10;
1098 for (;;) {
1099 clock_t begin, end;
1100 double tt;
1101 long k;
1102
1103 begin = clock();
1104 for (k = num; k > 0; k --) {
1105 br_i31_to_monty(x, p);
1106 }
1107 end = clock();
1108 tt = (double)(end - begin) / CLOCKS_PER_SEC;
1109 if (tt >= 2.0) {
1110 printf("%-30s %8.2f ops/s\n", "i31 to_monty",
1111 (double)num / tt);
1112 fflush(stdout);
1113 break;
1114 }
1115 num <<= 1;
1116 }
1117
1118 for (i = 0; i < 10; i ++) {
1119 br_i31_from_monty(x, p, p0i);
1120 }
1121 num = 10;
1122 for (;;) {
1123 clock_t begin, end;
1124 double tt;
1125 long k;
1126
1127 begin = clock();
1128 for (k = num; k > 0; k --) {
1129 br_i31_from_monty(x, p, p0i);
1130 }
1131 end = clock();
1132 tt = (double)(end - begin) / CLOCKS_PER_SEC;
1133 if (tt >= 2.0) {
1134 printf("%-30s %8.2f ops/s\n", "i31 from_monty",
1135 (double)num / tt);
1136 fflush(stdout);
1137 break;
1138 }
1139 num <<= 1;
1140 }
1141
1142 for (i = 0; i < 10; i ++) {
1143 br_i31_montymul(z, x, y, p, p0i);
1144 }
1145 num = 10;
1146 for (;;) {
1147 clock_t begin, end;
1148 double tt;
1149 long k;
1150
1151 begin = clock();
1152 for (k = num; k > 0; k --) {
1153 br_i31_montymul(z, x, y, p, p0i);
1154 }
1155 end = clock();
1156 tt = (double)(end - begin) / CLOCKS_PER_SEC;
1157 if (tt >= 2.0) {
1158 printf("%-30s %8.2f ops/s\n", "i31 montymul",
1159 (double)num / tt);
1160 fflush(stdout);
1161 break;
1162 }
1163 num <<= 1;
1164 }
1165 }
1166
1167 #if 0
1168
1169 static unsigned char P2048[] = {
1170 0xFD, 0xB6, 0xE0, 0x3E, 0x00, 0x49, 0x4C, 0xF0, 0x69, 0x3A, 0xDD, 0x7D,
1171 0xF8, 0xA2, 0x41, 0xB0, 0x6C, 0x67, 0xC5, 0xBA, 0xB8, 0x46, 0x80, 0xF5,
1172 0xBF, 0xAB, 0x98, 0xFC, 0x84, 0x73, 0xA5, 0x63, 0xC9, 0x52, 0x12, 0xDA,
1173 0x4C, 0xC1, 0x5B, 0x9D, 0x8D, 0xDF, 0xCD, 0xFE, 0xC5, 0xAD, 0x5A, 0x6F,
1174 0xDD, 0x02, 0xD9, 0xEC, 0x71, 0xEF, 0xEB, 0xB6, 0x95, 0xED, 0x94, 0x25,
1175 0x0E, 0x63, 0xDD, 0x6A, 0x52, 0xC7, 0x93, 0xAF, 0x85, 0x9D, 0x2C, 0xBE,
1176 0x5C, 0xBE, 0x35, 0xD8, 0xDD, 0x39, 0xEF, 0x1B, 0xB1, 0x49, 0x67, 0xB2,
1177 0x33, 0xC9, 0x7C, 0xE1, 0x51, 0x79, 0x51, 0x59, 0xCA, 0x6E, 0x2A, 0xDF,
1178 0x0D, 0x76, 0x1C, 0xE7, 0xA5, 0xC0, 0x1E, 0x6C, 0x56, 0x3A, 0x32, 0xE5,
1179 0xB5, 0xC5, 0xD4, 0xDB, 0xFE, 0xFF, 0xF8, 0xF2, 0x96, 0xA9, 0xC9, 0x65,
1180 0x59, 0x9E, 0x01, 0x79, 0x9D, 0x38, 0x68, 0x0F, 0xAD, 0x43, 0x3A, 0xD6,
1181 0x84, 0x0A, 0xE2, 0xEF, 0x96, 0xC1, 0x6D, 0x89, 0x74, 0x19, 0x63, 0x82,
1182 0x3B, 0xA0, 0x9C, 0xBA, 0x78, 0xDE, 0xDC, 0xC2, 0xE7, 0xD4, 0xFA, 0xD6,
1183 0x19, 0x21, 0x29, 0xAE, 0x5E, 0xF4, 0x38, 0x81, 0xC6, 0x9E, 0x0E, 0x3C,
1184 0xCD, 0xC0, 0xDC, 0x93, 0x5D, 0xFD, 0x9A, 0x5C, 0xAB, 0x54, 0x1F, 0xFF,
1185 0x9C, 0x12, 0x1B, 0x4C, 0xDF, 0x2D, 0x9C, 0x85, 0xF9, 0x68, 0x15, 0x89,
1186 0x42, 0x9B, 0x6C, 0x45, 0x89, 0x3A, 0xBC, 0xE9, 0x19, 0x91, 0xBE, 0x0C,
1187 0xEF, 0x90, 0xCC, 0xF6, 0xD6, 0xF0, 0x3D, 0x5C, 0xF5, 0xE5, 0x0F, 0x2F,
1188 0x02, 0x8A, 0x83, 0x4B, 0x93, 0x2F, 0x14, 0x12, 0x1F, 0x56, 0x9A, 0x12,
1189 0x58, 0x88, 0xAE, 0x60, 0xB8, 0x5A, 0xE4, 0xA1, 0xBF, 0x4A, 0x81, 0x84,
1190 0xAB, 0xBB, 0xE4, 0xD0, 0x1D, 0x41, 0xD9, 0x0A, 0xAB, 0x1E, 0x47, 0x5B,
1191 0x31, 0xAC, 0x2B, 0x73
1192 };
1193
1194 static unsigned char G2048[] = {
1195 0x02
1196 };
1197
1198 static void
1199 test_speed_modpow(void)
1200 {
1201 uint32_t mx[65], mp[65], me[65], t1[65], t2[65], len;
1202 unsigned char e[64];
1203 int i;
1204 long num;
1205
1206 len = br_int_decode(mp, sizeof mp / sizeof mp[0],
1207 P2048, sizeof P2048);
1208 if (len != 65) {
1209 abort();
1210 }
1211 memset(e, 'P', sizeof e);
1212 if (!br_int_decode(me, sizeof me / sizeof me[0], e, sizeof e)) {
1213 abort();
1214 }
1215 if (!br_modint_decode(mx, mp, G2048, sizeof G2048)) {
1216 abort();
1217 }
1218 for (i = 0; i < 10; i ++) {
1219 br_modint_to_monty(mx, mp);
1220 br_modint_montypow(mx, me, mp, t1, t2);
1221 br_modint_from_monty(mx, mp);
1222 }
1223 num = 10;
1224 for (;;) {
1225 clock_t begin, end;
1226 double tt;
1227 long k;
1228
1229 begin = clock();
1230 for (k = num; k > 0; k --) {
1231 br_modint_to_monty(mx, mp);
1232 br_modint_montypow(mx, me, mp, t1, t2);
1233 br_modint_from_monty(mx, mp);
1234 }
1235 end = clock();
1236 tt = (double)(end - begin) / CLOCKS_PER_SEC;
1237 if (tt >= 2.0) {
1238 printf("%-30s %8.2f exp/s\n", "pow[2048:256]",
1239 (double)num / tt);
1240 fflush(stdout);
1241 return;
1242 }
1243 num <<= 1;
1244 }
1245 }
1246
1247 static void
1248 test_speed_moddiv(void)
1249 {
1250 uint32_t mx[65], my[65], mp[65], t1[65], t2[65], t3[65], len;
1251 unsigned char x[255], y[255];
1252 int i;
1253 long num;
1254
1255 len = br_int_decode(mp, sizeof mp / sizeof mp[0],
1256 P2048, sizeof P2048);
1257 if (len != 65) {
1258 abort();
1259 }
1260 memset(x, 'T', sizeof x);
1261 memset(y, 'P', sizeof y);
1262 if (!br_modint_decode(mx, mp, x, sizeof x)) {
1263 abort();
1264 }
1265 if (!br_modint_decode(my, mp, y, sizeof y)) {
1266 abort();
1267 }
1268 for (i = 0; i < 10; i ++) {
1269 br_modint_div(mx, my, mp, t1, t2, t3);
1270 }
1271 num = 10;
1272 for (;;) {
1273 clock_t begin, end;
1274 double tt;
1275 long k;
1276
1277 begin = clock();
1278 for (k = num; k > 0; k --) {
1279 br_modint_div(mx, my, mp, t1, t2, t3);
1280 }
1281 end = clock();
1282 tt = (double)(end - begin) / CLOCKS_PER_SEC;
1283 if (tt >= 2.0) {
1284 printf("%-30s %8.2f div/s\n", "div[2048]",
1285 (double)num / tt);
1286 fflush(stdout);
1287 return;
1288 }
1289 num <<= 1;
1290 }
1291 }
1292 #endif
1293
1294 #define STU(x) { test_speed_ ## x, #x }
1295
1296 static const struct {
1297 void (*fn)(void);
1298 char *name;
1299 } tfns[] = {
1300 STU(md5),
1301 STU(sha1),
1302 STU(sha256),
1303 STU(sha512),
1304
1305 STU(aes128_big_cbcenc),
1306 STU(aes128_big_cbcdec),
1307 STU(aes192_big_cbcenc),
1308 STU(aes192_big_cbcdec),
1309 STU(aes256_big_cbcenc),
1310 STU(aes256_big_cbcdec),
1311 STU(aes128_big_ctr),
1312 STU(aes192_big_ctr),
1313 STU(aes256_big_ctr),
1314
1315 STU(aes128_small_cbcenc),
1316 STU(aes128_small_cbcdec),
1317 STU(aes192_small_cbcenc),
1318 STU(aes192_small_cbcdec),
1319 STU(aes256_small_cbcenc),
1320 STU(aes256_small_cbcdec),
1321 STU(aes128_small_ctr),
1322 STU(aes192_small_ctr),
1323 STU(aes256_small_ctr),
1324
1325 STU(aes128_ct_cbcenc),
1326 STU(aes128_ct_cbcdec),
1327 STU(aes192_ct_cbcenc),
1328 STU(aes192_ct_cbcdec),
1329 STU(aes256_ct_cbcenc),
1330 STU(aes256_ct_cbcdec),
1331 STU(aes128_ct_ctr),
1332 STU(aes192_ct_ctr),
1333 STU(aes256_ct_ctr),
1334
1335 STU(aes128_ct64_cbcenc),
1336 STU(aes128_ct64_cbcdec),
1337 STU(aes192_ct64_cbcenc),
1338 STU(aes192_ct64_cbcdec),
1339 STU(aes256_ct64_cbcenc),
1340 STU(aes256_ct64_cbcdec),
1341 STU(aes128_ct64_ctr),
1342 STU(aes192_ct64_ctr),
1343 STU(aes256_ct64_ctr),
1344
1345 STU(aes128_x86ni_cbcenc),
1346 STU(aes128_x86ni_cbcdec),
1347 STU(aes192_x86ni_cbcenc),
1348 STU(aes192_x86ni_cbcdec),
1349 STU(aes256_x86ni_cbcenc),
1350 STU(aes256_x86ni_cbcdec),
1351 STU(aes128_x86ni_ctr),
1352 STU(aes192_x86ni_ctr),
1353 STU(aes256_x86ni_ctr),
1354
1355 STU(aes128_pwr8_cbcenc),
1356 STU(aes128_pwr8_cbcdec),
1357 STU(aes192_pwr8_cbcenc),
1358 STU(aes192_pwr8_cbcdec),
1359 STU(aes256_pwr8_cbcenc),
1360 STU(aes256_pwr8_cbcdec),
1361 STU(aes128_pwr8_ctr),
1362 STU(aes192_pwr8_ctr),
1363 STU(aes256_pwr8_ctr),
1364
1365 STU(des_tab_cbcenc),
1366 STU(des_tab_cbcdec),
1367 STU(3des_tab_cbcenc),
1368 STU(3des_tab_cbcdec),
1369
1370 STU(des_ct_cbcenc),
1371 STU(des_ct_cbcdec),
1372 STU(3des_ct_cbcenc),
1373 STU(3des_ct_cbcdec),
1374
1375 STU(chacha20_ct),
1376 STU(chacha20_sse2),
1377
1378 STU(ghash_ctmul),
1379 STU(ghash_ctmul32),
1380 STU(ghash_ctmul64),
1381 STU(ghash_pclmul),
1382 STU(ghash_pwr8),
1383
1384 STU(poly1305_ctmul),
1385 STU(poly1305_ctmul32),
1386 STU(poly1305_ctmulq),
1387 STU(poly1305_i15),
1388
1389 STU(eax_aes128_big),
1390 STU(eax_aes192_big),
1391 STU(eax_aes256_big),
1392 STU(eax_aes128_small),
1393 STU(eax_aes192_small),
1394 STU(eax_aes256_small),
1395 STU(eax_aes128_ct),
1396 STU(eax_aes192_ct),
1397 STU(eax_aes256_ct),
1398 STU(eax_aes128_ct64),
1399 STU(eax_aes192_ct64),
1400 STU(eax_aes256_ct64),
1401 STU(eax_aes128_x86ni),
1402 STU(eax_aes192_x86ni),
1403 STU(eax_aes256_x86ni),
1404
1405 STU(rsa_i15),
1406 STU(rsa_i31),
1407 STU(rsa_i32),
1408 STU(rsa_i62),
1409 STU(ec_prime_i15),
1410 STU(ec_prime_i31),
1411 STU(ec_p256_m15),
1412 STU(ec_p256_m31),
1413 STU(ec_c25519_i15),
1414 STU(ec_c25519_i31),
1415 STU(ec_c25519_m15),
1416 STU(ec_c25519_m31),
1417 STU(ecdsa_p256_m15),
1418 STU(ecdsa_p256_m31),
1419 STU(ecdsa_i15),
1420 STU(ecdsa_i31),
1421
1422 STU(i31)
1423 };
1424
1425 static int
1426 eq_name(const char *s1, const char *s2)
1427 {
1428 for (;;) {
1429 int c1, c2;
1430
1431 for (;;) {
1432 c1 = *s1 ++;
1433 if (c1 >= 'A' && c1 <= 'Z') {
1434 c1 += 'a' - 'A';
1435 } else {
1436 switch (c1) {
1437 case '-': case '_': case '.': case ' ':
1438 continue;
1439 }
1440 }
1441 break;
1442 }
1443 for (;;) {
1444 c2 = *s2 ++;
1445 if (c2 >= 'A' && c2 <= 'Z') {
1446 c2 += 'a' - 'A';
1447 } else {
1448 switch (c2) {
1449 case '-': case '_': case '.': case ' ':
1450 continue;
1451 }
1452 }
1453 break;
1454 }
1455 if (c1 != c2) {
1456 return 0;
1457 }
1458 if (c1 == 0) {
1459 return 1;
1460 }
1461 }
1462 }
1463
1464 int
1465 main(int argc, char *argv[])
1466 {
1467 size_t u;
1468
1469 if (argc <= 1) {
1470 printf("usage: testspeed all | name...\n");
1471 printf("individual test names:\n");
1472 for (u = 0; u < (sizeof tfns) / (sizeof tfns[0]); u ++) {
1473 printf(" %s\n", tfns[u].name);
1474 }
1475 } else {
1476 for (u = 0; u < (sizeof tfns) / (sizeof tfns[0]); u ++) {
1477 int i;
1478
1479 for (i = 1; i < argc; i ++) {
1480 if (eq_name(argv[i], tfns[u].name)
1481 || eq_name(argv[i], "all"))
1482 {
1483 tfns[u].fn();
1484 break;
1485 }
1486 }
1487 }
1488 }
1489 return 0;
1490 }