Added generic EAX and CCM implementations.
[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_small_cbcenc_get_vtable() (&br_aes_small_cbcenc_vtable)
233 #define br_aes_small_cbcdec_get_vtable() (&br_aes_small_cbcdec_vtable)
234 #define br_aes_small_ctr_get_vtable() (&br_aes_small_ctr_vtable)
235 #define br_aes_ct_cbcenc_get_vtable() (&br_aes_ct_cbcenc_vtable)
236 #define br_aes_ct_cbcdec_get_vtable() (&br_aes_ct_cbcdec_vtable)
237 #define br_aes_ct_ctr_get_vtable() (&br_aes_ct_ctr_vtable)
238 #define br_aes_ct64_cbcenc_get_vtable() (&br_aes_ct64_cbcenc_vtable)
239 #define br_aes_ct64_cbcdec_get_vtable() (&br_aes_ct64_cbcdec_vtable)
240 #define br_aes_ct64_ctr_get_vtable() (&br_aes_ct64_ctr_vtable)
241 #define br_chacha20_ct_get() (&br_chacha20_ct_run)
242
243 #define SPEED_AES(iname) \
244 SPEED_BLOCKCIPHER_CBC(AES-128 CBC encrypt (iname), aes128_ ## iname ## _cbcenc, aes_ ## iname, 16, enc) \
245 SPEED_BLOCKCIPHER_CBC(AES-128 CBC decrypt (iname), aes128_ ## iname ## _cbcdec, aes_ ## iname, 16, dec) \
246 SPEED_BLOCKCIPHER_CBC(AES-192 CBC encrypt (iname), aes192_ ## iname ## _cbcenc, aes_ ## iname, 24, enc) \
247 SPEED_BLOCKCIPHER_CBC(AES-192 CBC decrypt (iname), aes192_ ## iname ## _cbcdec, aes_ ## iname, 24, dec) \
248 SPEED_BLOCKCIPHER_CBC(AES-256 CBC encrypt (iname), aes256_ ## iname ## _cbcenc, aes_ ## iname, 32, enc) \
249 SPEED_BLOCKCIPHER_CBC(AES-256 CBC decrypt (iname), aes256_ ## iname ## _cbcdec, aes_ ## iname, 32, dec) \
250 SPEED_BLOCKCIPHER_CTR(AES-128 CTR (iname), aes128_ ## iname ## _ctr, aes_ ## iname, 16) \
251 SPEED_BLOCKCIPHER_CTR(AES-192 CTR (iname), aes192_ ## iname ## _ctr, aes_ ## iname, 24) \
252 SPEED_BLOCKCIPHER_CTR(AES-256 CTR (iname), aes256_ ## iname ## _ctr, aes_ ## iname, 32)
253
254 SPEED_AES(big)
255 SPEED_AES(small)
256 SPEED_AES(ct)
257 SPEED_AES(ct64)
258 SPEED_AES(x86ni)
259 SPEED_AES(pwr8)
260
261 #define br_des_tab_cbcenc_get_vtable() (&br_des_tab_cbcenc_vtable)
262 #define br_des_tab_cbcdec_get_vtable() (&br_des_tab_cbcdec_vtable)
263 #define br_des_ct_cbcenc_get_vtable() (&br_des_ct_cbcenc_vtable)
264 #define br_des_ct_cbcdec_get_vtable() (&br_des_ct_cbcdec_vtable)
265
266 #define SPEED_DES(iname) \
267 SPEED_BLOCKCIPHER_CBC(DES CBC encrypt (iname), des_ ## iname ## _cbcenc, des_ ## iname, 8, enc) \
268 SPEED_BLOCKCIPHER_CBC(DES CBC decrypt (iname), des_ ## iname ## _cbcdec, des_ ## iname, 8, dec) \
269 SPEED_BLOCKCIPHER_CBC(3DES CBC encrypt (iname), 3des_ ## iname ## _cbcenc, des_ ## iname, 24, enc) \
270 SPEED_BLOCKCIPHER_CBC(3DES CBC decrypt (iname), 3des_ ## iname ## _cbcdec, des_ ## iname, 24, dec)
271
272 SPEED_DES(tab)
273 SPEED_DES(ct)
274
275 SPEED_CHACHA20(ChaCha20 (ct), chacha20_ct)
276 SPEED_CHACHA20(ChaCha20 (sse2), chacha20_sse2)
277
278 static void
279 test_speed_ghash_inner(char *name, br_ghash gh)
280 {
281 unsigned char buf[8192], h[16], y[16];
282 int i;
283 long num;
284
285 memset(buf, 'T', sizeof buf);
286 memset(h, 'P', sizeof h);
287 memset(y, 0, sizeof y);
288 for (i = 0; i < 10; i ++) {
289 gh(y, h, buf, sizeof buf);
290 }
291 num = 10;
292 for (;;) {
293 clock_t begin, end;
294 double tt;
295 long k;
296
297 begin = clock();
298 for (k = num; k > 0; k --) {
299 gh(y, h, buf, sizeof buf);
300 }
301 end = clock();
302 tt = (double)(end - begin) / CLOCKS_PER_SEC;
303 if (tt >= 2.0) {
304 printf("%-30s %8.2f MB/s\n", name,
305 ((double)sizeof buf) * (double)num
306 / (tt * 1000000.0));
307 fflush(stdout);
308 return;
309 }
310 num <<= 1;
311 }
312 }
313
314 static void
315 test_speed_ghash_ctmul(void)
316 {
317 test_speed_ghash_inner("GHASH (ctmul)", &br_ghash_ctmul);
318 }
319
320 static void
321 test_speed_ghash_ctmul32(void)
322 {
323 test_speed_ghash_inner("GHASH (ctmul32)", &br_ghash_ctmul32);
324 }
325
326 static void
327 test_speed_ghash_ctmul64(void)
328 {
329 test_speed_ghash_inner("GHASH (ctmul64)", &br_ghash_ctmul64);
330 }
331
332 static void
333 test_speed_ghash_pclmul(void)
334 {
335 br_ghash gh;
336
337 gh = br_ghash_pclmul_get();
338 if (gh == 0) {
339 printf("%-30s UNAVAILABLE\n", "GHASH (pclmul)");
340 fflush(stdout);
341 } else {
342 test_speed_ghash_inner("GHASH (pclmul)", gh);
343 }
344 }
345
346 static void
347 test_speed_ghash_pwr8(void)
348 {
349 br_ghash gh;
350
351 gh = br_ghash_pwr8_get();
352 if (gh == 0) {
353 printf("%-30s UNAVAILABLE\n", "GHASH (pwr8)");
354 fflush(stdout);
355 } else {
356 test_speed_ghash_inner("GHASH (pwr8)", gh);
357 }
358 }
359
360 static uint32_t
361 fake_chacha20(const void *key, const void *iv,
362 uint32_t cc, void *data, size_t len)
363 {
364 (void)key;
365 (void)iv;
366 (void)data;
367 (void)len;
368 return cc + (uint32_t)((len + 63) >> 6);
369 }
370
371 /*
372 * To speed-test Poly1305, we run it with a do-nothing stub instead of
373 * ChaCha20.
374 */
375 static void
376 test_speed_poly1305_inner(char *name, br_poly1305_run pl)
377 {
378 unsigned char buf[8192], key[32], iv[12], aad[13], tag[16];
379 int i;
380 long num;
381
382 memset(key, 'K', sizeof key);
383 memset(iv, 'I', sizeof iv);
384 memset(aad, 'A', sizeof aad);
385 memset(buf, 'T', sizeof buf);
386 for (i = 0; i < 10; i ++) {
387 pl(key, iv, buf, sizeof buf,
388 aad, sizeof aad, tag, &fake_chacha20, 0);
389 }
390 num = 10;
391 for (;;) {
392 clock_t begin, end;
393 double tt;
394 long k;
395
396 begin = clock();
397 for (k = num; k > 0; k --) {
398 pl(key, iv, buf, sizeof buf,
399 aad, sizeof aad, tag, &fake_chacha20, 0);
400 }
401 end = clock();
402 tt = (double)(end - begin) / CLOCKS_PER_SEC;
403 if (tt >= 2.0) {
404 printf("%-30s %8.2f MB/s\n", name,
405 ((double)sizeof buf) * (double)num
406 / (tt * 1000000.0));
407 fflush(stdout);
408 return;
409 }
410 num <<= 1;
411 }
412 }
413
414 static void
415 test_speed_poly1305_ctmul(void)
416 {
417 test_speed_poly1305_inner("Poly1305 (ctmul)", &br_poly1305_ctmul_run);
418 }
419
420 static void
421 test_speed_poly1305_ctmul32(void)
422 {
423 test_speed_poly1305_inner("Poly1305 (ctmul32)",
424 &br_poly1305_ctmul32_run);
425 }
426
427 static void
428 test_speed_poly1305_ctmulq(void)
429 {
430 br_poly1305_run bp;
431
432 bp = br_poly1305_ctmulq_get();
433 if (bp == 0) {
434 printf("%-30s UNAVAILABLE\n", "Poly1305 (ctmulq)");
435 } else {
436 test_speed_poly1305_inner("Poly1305 (ctmulq)", bp);
437 }
438 }
439
440 static void
441 test_speed_poly1305_i15(void)
442 {
443 test_speed_poly1305_inner("Poly1305 (i15)", &br_poly1305_i15_run);
444 }
445
446 static void
447 test_speed_eax_inner(char *name,
448 const br_block_ctrcbc_class *vt, size_t key_len)
449 {
450 unsigned char buf[8192], key[32], nonce[16], aad[16], tag[16];
451 int i;
452 long num;
453 br_aes_gen_ctrcbc_keys ac;
454 br_eax_context ec;
455
456 memset(key, 'K', key_len);
457 memset(nonce, 'N', sizeof nonce);
458 memset(aad, 'A', sizeof aad);
459 memset(buf, 'T', sizeof buf);
460 for (i = 0; i < 10; i ++) {
461 vt->init(&ac.vtable, key, key_len);
462 br_eax_init(&ec, &ac.vtable);
463 br_eax_reset(&ec, nonce, sizeof nonce);
464 br_eax_aad_inject(&ec, aad, sizeof aad);
465 br_eax_flip(&ec);
466 br_eax_run(&ec, 1, buf, sizeof buf);
467 br_eax_get_tag(&ec, tag);
468 }
469 num = 10;
470 for (;;) {
471 clock_t begin, end;
472 double tt;
473 long k;
474
475 begin = clock();
476 for (k = num; k > 0; k --) {
477 vt->init(&ac.vtable, key, key_len);
478 br_eax_init(&ec, &ac.vtable);
479 br_eax_reset(&ec, nonce, sizeof nonce);
480 br_eax_aad_inject(&ec, aad, sizeof aad);
481 br_eax_flip(&ec);
482 br_eax_run(&ec, 1, buf, sizeof buf);
483 br_eax_get_tag(&ec, tag);
484 }
485 end = clock();
486 tt = (double)(end - begin) / CLOCKS_PER_SEC;
487 if (tt >= 2.0) {
488 printf("%-30s %8.2f MB/s\n", name,
489 ((double)sizeof buf) * (double)num
490 / (tt * 1000000.0));
491 fflush(stdout);
492 return;
493 }
494 num <<= 1;
495 }
496 }
497
498 #define SPEED_EAX(Algo, algo, keysize, impl) \
499 static void \
500 test_speed_eax_ ## algo ## keysize ## _ ## impl(void) \
501 { \
502 test_speed_eax_inner("EAX " #Algo "-" #keysize "(" #impl ")", \
503 &br_ ## algo ## _ ## impl ## _ctrcbc_vtable, (keysize) >> 3); \
504 }
505
506 SPEED_EAX(AES, aes, 128, big)
507 SPEED_EAX(AES, aes, 128, small)
508 SPEED_EAX(AES, aes, 128, ct)
509 SPEED_EAX(AES, aes, 128, ct64)
510 SPEED_EAX(AES, aes, 128, x86ni)
511 SPEED_EAX(AES, aes, 192, big)
512 SPEED_EAX(AES, aes, 192, small)
513 SPEED_EAX(AES, aes, 192, ct)
514 SPEED_EAX(AES, aes, 192, ct64)
515 SPEED_EAX(AES, aes, 192, x86ni)
516 SPEED_EAX(AES, aes, 256, big)
517 SPEED_EAX(AES, aes, 256, small)
518 SPEED_EAX(AES, aes, 256, ct)
519 SPEED_EAX(AES, aes, 256, ct64)
520 SPEED_EAX(AES, aes, 256, x86ni)
521
522 static const unsigned char RSA_N[] = {
523 0xE9, 0xF2, 0x4A, 0x2F, 0x96, 0xDF, 0x0A, 0x23,
524 0x01, 0x85, 0xF1, 0x2C, 0xB2, 0xA8, 0xEF, 0x23,
525 0xCE, 0x2E, 0xB0, 0x4E, 0x18, 0x31, 0x95, 0x5B,
526 0x98, 0x2D, 0x9B, 0x8C, 0xE3, 0x1A, 0x2B, 0x96,
527 0xB5, 0xC7, 0xEE, 0xED, 0x72, 0x43, 0x2D, 0xFE,
528 0x7F, 0x61, 0x33, 0xEA, 0x14, 0xFC, 0xDE, 0x80,
529 0x17, 0x42, 0xF0, 0xF3, 0xC3, 0xC7, 0x89, 0x47,
530 0x76, 0x5B, 0xFA, 0x33, 0xC4, 0x8C, 0x94, 0xDE,
531 0x6A, 0x75, 0xD8, 0x1A, 0xF4, 0x49, 0xBC, 0xF3,
532 0xB7, 0x9E, 0x2C, 0x8D, 0xEC, 0x5A, 0xEE, 0xBF,
533 0x4B, 0x5A, 0x7F, 0xEF, 0x21, 0x39, 0xDB, 0x1D,
534 0x83, 0x5E, 0x7E, 0x2F, 0xAA, 0x5E, 0xBA, 0x28,
535 0xC3, 0xA2, 0x53, 0x19, 0xFB, 0x2F, 0x78, 0x6B,
536 0x14, 0x60, 0x49, 0x3C, 0xCC, 0x1B, 0xE9, 0x1E,
537 0x3D, 0x10, 0xA4, 0xEB, 0x7F, 0x66, 0x98, 0xF6,
538 0xC3, 0xAC, 0x35, 0xF5, 0x01, 0x84, 0xFF, 0x7D,
539 0x1F, 0x72, 0xBE, 0xB4, 0xD1, 0x89, 0xC8, 0xDD,
540 0x44, 0xE7, 0xB5, 0x2E, 0x2C, 0xE1, 0x85, 0xF5,
541 0x15, 0x50, 0xA9, 0x08, 0xC7, 0x67, 0xD9, 0x2B,
542 0x6C, 0x11, 0xB3, 0xEB, 0x28, 0x8D, 0xF4, 0xCC,
543 0xE3, 0xC3, 0xC5, 0x04, 0x0E, 0x7C, 0x8D, 0xDB,
544 0x39, 0x06, 0x6A, 0x74, 0x75, 0xDF, 0xA8, 0x0F,
545 0xDA, 0x67, 0x5A, 0x73, 0x1E, 0xFD, 0x8E, 0x4C,
546 0xEE, 0x17, 0xEE, 0x1E, 0x67, 0xDB, 0x98, 0x70,
547 0x60, 0xF7, 0xB9, 0xB5, 0x1F, 0x19, 0x93, 0xD6,
548 0x3F, 0x2F, 0x1F, 0xB6, 0x5B, 0x59, 0xAA, 0x85,
549 0xBB, 0x25, 0xE4, 0x13, 0xEF, 0xE7, 0xB9, 0x87,
550 0x9C, 0x3F, 0x5E, 0xE4, 0x08, 0xA3, 0x51, 0xCF,
551 0x8B, 0xAD, 0xF4, 0xE6, 0x1A, 0x5F, 0x51, 0xDD,
552 0xA8, 0xBE, 0xE8, 0xD1, 0x20, 0x19, 0x61, 0x6C,
553 0x18, 0xAB, 0xCA, 0x0A, 0xD9, 0x82, 0xA6, 0x94,
554 0xD5, 0x69, 0x2A, 0xF6, 0x43, 0x66, 0x31, 0x09
555 };
556
557 static const unsigned char RSA_E[] = {
558 0x01, 0x00, 0x01
559 };
560
561 static const unsigned char RSA_P[] = {
562 0xFD, 0x39, 0x40, 0x56, 0x20, 0x80, 0xC5, 0x81,
563 0x4C, 0x5F, 0x0C, 0x1A, 0x52, 0x84, 0x03, 0x2F,
564 0xCE, 0x82, 0xB0, 0xD8, 0x30, 0x23, 0x7F, 0x77,
565 0x45, 0xC2, 0x01, 0xC4, 0x68, 0x96, 0x0D, 0xA7,
566 0x22, 0xA9, 0x6C, 0xA9, 0x1A, 0x33, 0xE5, 0x2F,
567 0xB5, 0x07, 0x9A, 0xF9, 0xEA, 0x33, 0xA5, 0xC8,
568 0x96, 0x60, 0x6A, 0xCA, 0xEB, 0xE5, 0x6E, 0x09,
569 0x46, 0x7E, 0x2D, 0xEF, 0x93, 0x7D, 0x56, 0xED,
570 0x75, 0x70, 0x3B, 0x96, 0xC4, 0xD5, 0xDB, 0x0B,
571 0x3F, 0x69, 0xDF, 0x06, 0x18, 0x76, 0xF4, 0xCF,
572 0xF8, 0x84, 0x22, 0xDF, 0xBD, 0x71, 0x62, 0x7B,
573 0x67, 0x99, 0xBC, 0x09, 0x95, 0x54, 0xA4, 0x98,
574 0x83, 0xF5, 0xA9, 0xCF, 0x09, 0xA5, 0x1F, 0x61,
575 0x25, 0xB4, 0x70, 0x6C, 0x91, 0xB8, 0xB3, 0xD0,
576 0xCE, 0x9C, 0x45, 0x65, 0x9B, 0xEF, 0xD4, 0x70,
577 0xBE, 0x86, 0xD2, 0x98, 0x5D, 0xEB, 0xE3, 0xFF
578 };
579
580 static const unsigned char RSA_Q[] = {
581 0xEC, 0x82, 0xEE, 0x63, 0x5F, 0x40, 0x52, 0xDB,
582 0x38, 0x7A, 0x37, 0x6A, 0x54, 0x5B, 0xD9, 0xA0,
583 0x73, 0xB4, 0xBB, 0x52, 0xB2, 0x84, 0x07, 0xD0,
584 0xCC, 0x82, 0x0D, 0x20, 0xB3, 0xFA, 0xD5, 0xB6,
585 0x25, 0x92, 0x35, 0x4D, 0xB4, 0xC7, 0x36, 0x48,
586 0xCE, 0x5E, 0x21, 0x4A, 0xA6, 0x74, 0x65, 0xF4,
587 0x7D, 0x1D, 0xBC, 0x3B, 0xE2, 0xF4, 0x3E, 0x11,
588 0x58, 0x10, 0x6C, 0x04, 0x46, 0x9E, 0x8D, 0x57,
589 0xE0, 0x04, 0xE2, 0xEC, 0x47, 0xCF, 0xB3, 0x2A,
590 0xFD, 0x4C, 0x55, 0x18, 0xDB, 0xDE, 0x3B, 0xDC,
591 0xF4, 0x5B, 0xDA, 0xF3, 0x1A, 0xC8, 0x41, 0x6F,
592 0x73, 0x3B, 0xFE, 0x3C, 0xA0, 0xDB, 0xBA, 0x6E,
593 0x65, 0xA5, 0xE8, 0x02, 0xA5, 0x6C, 0xEA, 0x03,
594 0xF6, 0x99, 0xF7, 0xCB, 0x4B, 0xB7, 0x11, 0x51,
595 0x93, 0x88, 0x3F, 0xF9, 0x06, 0x85, 0xA9, 0x1E,
596 0xCA, 0x64, 0xF8, 0x11, 0xA5, 0x1A, 0xCA, 0xF7
597 };
598
599 static const unsigned char RSA_DP[] = {
600 0x77, 0x95, 0xE0, 0x02, 0x4C, 0x9B, 0x43, 0xAA,
601 0xCA, 0x4C, 0x60, 0xC4, 0xD5, 0x8F, 0x2E, 0x8A,
602 0x17, 0x36, 0xB5, 0x19, 0x83, 0xB2, 0x5F, 0xF2,
603 0x0D, 0xE9, 0x8F, 0x38, 0x18, 0x44, 0x34, 0xF2,
604 0x67, 0x76, 0x27, 0xB0, 0xBC, 0x85, 0x21, 0x89,
605 0x24, 0x2F, 0x11, 0x4B, 0x51, 0x05, 0x4F, 0x17,
606 0xA9, 0x9C, 0xA3, 0x12, 0x6D, 0xD1, 0x0D, 0xE4,
607 0x27, 0x7C, 0x53, 0x69, 0x3E, 0xF8, 0x04, 0x63,
608 0x64, 0x00, 0xBA, 0xC3, 0x7A, 0xF5, 0x9B, 0xDA,
609 0x75, 0xFA, 0x23, 0xAF, 0x17, 0x42, 0xA6, 0x5E,
610 0xC8, 0xF8, 0x6E, 0x17, 0xC7, 0xB9, 0x92, 0x4E,
611 0xC1, 0x20, 0x63, 0x23, 0x0B, 0x78, 0xCB, 0xBA,
612 0x93, 0x27, 0x23, 0x28, 0x79, 0x5F, 0x97, 0xB0,
613 0x23, 0x44, 0x51, 0x8B, 0x94, 0x4D, 0xEB, 0xED,
614 0x82, 0x85, 0x5E, 0x68, 0x9B, 0xF9, 0xE9, 0x13,
615 0xCD, 0x86, 0x92, 0x52, 0x0E, 0x98, 0xE6, 0x35
616 };
617
618 static const unsigned char RSA_DQ[] = {
619 0xD8, 0xDD, 0x71, 0xB3, 0x62, 0xBA, 0xBB, 0x7E,
620 0xD1, 0xF9, 0x96, 0xE8, 0x83, 0xB3, 0xB9, 0x08,
621 0x9C, 0x30, 0x03, 0x77, 0xDF, 0xC2, 0x9A, 0xDC,
622 0x05, 0x39, 0xD6, 0xC9, 0xBE, 0xDE, 0x68, 0xA9,
623 0xDD, 0x27, 0x84, 0x82, 0xDD, 0x19, 0xB1, 0x97,
624 0xEE, 0xCA, 0x77, 0x22, 0x59, 0x20, 0xEF, 0xFF,
625 0xCF, 0xDD, 0xBD, 0x24, 0xF8, 0x84, 0xD6, 0x88,
626 0xD6, 0xC4, 0x30, 0x17, 0x77, 0x9D, 0x98, 0xA3,
627 0x14, 0x01, 0xC7, 0x05, 0xBB, 0x0F, 0x23, 0x0D,
628 0x6F, 0x37, 0x57, 0xEC, 0x34, 0x67, 0x41, 0x62,
629 0xE8, 0x19, 0x75, 0xD9, 0x66, 0x1C, 0x6B, 0x8B,
630 0xC3, 0x11, 0x26, 0x9C, 0xF7, 0x2E, 0xA3, 0x72,
631 0xE8, 0xF7, 0xC8, 0x96, 0xEC, 0x92, 0xC2, 0xBD,
632 0xA1, 0x98, 0x2A, 0x93, 0x99, 0xB8, 0xA2, 0x43,
633 0xB7, 0xD0, 0xBE, 0x40, 0x1C, 0x8F, 0xE0, 0xB4,
634 0x20, 0x07, 0x97, 0x43, 0xAE, 0xAD, 0xB3, 0x9F
635 };
636
637 static const unsigned char RSA_IQ[] = {
638 0xB7, 0xE2, 0x60, 0xA9, 0x62, 0xEC, 0xEC, 0x0B,
639 0x57, 0x02, 0x96, 0xF9, 0x36, 0x35, 0x2C, 0x37,
640 0xAF, 0xC2, 0xEE, 0x71, 0x49, 0x26, 0x8E, 0x0F,
641 0x27, 0xB1, 0xFA, 0x0F, 0xEA, 0xDC, 0xF0, 0x8B,
642 0x53, 0x6C, 0xB2, 0x46, 0x27, 0xCD, 0x29, 0xA2,
643 0x35, 0x0F, 0x5D, 0x8A, 0x3F, 0x20, 0x8C, 0x13,
644 0x3D, 0xA1, 0xFF, 0x85, 0x91, 0x99, 0xE8, 0x50,
645 0xED, 0xF1, 0x29, 0x00, 0xEE, 0x24, 0x90, 0xB5,
646 0x5F, 0x3A, 0x74, 0x26, 0xD7, 0xA2, 0x24, 0x8D,
647 0x89, 0x88, 0xD8, 0x35, 0x22, 0x22, 0x8A, 0x66,
648 0x5D, 0x5C, 0xDE, 0x83, 0x8C, 0xFA, 0x27, 0xE6,
649 0xB9, 0xEB, 0x72, 0x08, 0xCD, 0x53, 0x4B, 0x93,
650 0x0F, 0xAD, 0xC3, 0xF8, 0x7C, 0xFE, 0x84, 0xD7,
651 0x08, 0xF3, 0xBE, 0x3D, 0x60, 0x1E, 0x95, 0x8D,
652 0x44, 0x5B, 0x65, 0x7E, 0xC1, 0x30, 0xC3, 0x84,
653 0xC0, 0xB0, 0xFE, 0xBF, 0x28, 0x54, 0x1E, 0xC4
654 };
655
656 static const br_rsa_public_key RSA_PK = {
657 (void *)RSA_N, sizeof RSA_N,
658 (void *)RSA_E, sizeof RSA_E
659 };
660
661 static const br_rsa_private_key RSA_SK = {
662 2048,
663 (void *)RSA_P, sizeof RSA_P,
664 (void *)RSA_Q, sizeof RSA_Q,
665 (void *)RSA_DP, sizeof RSA_DP,
666 (void *)RSA_DQ, sizeof RSA_DQ,
667 (void *)RSA_IQ, sizeof RSA_IQ
668 };
669
670 static void
671 test_speed_rsa_inner(char *name,
672 br_rsa_public fpub, br_rsa_private fpriv)
673 {
674 unsigned char tmp[sizeof RSA_N];
675 int i;
676 long num;
677
678 memset(tmp, 'R', sizeof tmp);
679 tmp[0] = 0;
680 for (i = 0; i < 10; i ++) {
681 if (!fpriv(tmp, &RSA_SK)) {
682 abort();
683 }
684 }
685 num = 10;
686 for (;;) {
687 clock_t begin, end;
688 double tt;
689 long k;
690
691 begin = clock();
692 for (k = num; k > 0; k --) {
693 fpriv(tmp, &RSA_SK);
694 }
695 end = clock();
696 tt = (double)(end - begin) / CLOCKS_PER_SEC;
697 if (tt >= 2.0) {
698 printf("%-30s %8.2f priv/s\n", name,
699 (double)num / tt);
700 fflush(stdout);
701 break;
702 }
703 num <<= 1;
704 }
705 for (i = 0; i < 10; i ++) {
706 if (!fpub(tmp, sizeof tmp, &RSA_PK)) {
707 abort();
708 }
709 }
710 num = 10;
711 for (;;) {
712 clock_t begin, end;
713 double tt;
714 long k;
715
716 begin = clock();
717 for (k = num; k > 0; k --) {
718 fpub(tmp, sizeof tmp, &RSA_PK);
719 }
720 end = clock();
721 tt = (double)(end - begin) / CLOCKS_PER_SEC;
722 if (tt >= 2.0) {
723 printf("%-30s %8.2f pub/s\n", name,
724 (double)num / tt);
725 fflush(stdout);
726 break;
727 }
728 num <<= 1;
729 }
730 }
731
732 static void
733 test_speed_rsa_i15(void)
734 {
735 test_speed_rsa_inner("RSA i15",
736 &br_rsa_i15_public, &br_rsa_i15_private);
737 }
738
739 static void
740 test_speed_rsa_i31(void)
741 {
742 test_speed_rsa_inner("RSA i31",
743 &br_rsa_i31_public, &br_rsa_i31_private);
744 }
745
746 static void
747 test_speed_rsa_i32(void)
748 {
749 test_speed_rsa_inner("RSA i32",
750 &br_rsa_i32_public, &br_rsa_i32_private);
751 }
752
753 static void
754 test_speed_rsa_i62(void)
755 {
756 br_rsa_public pub;
757 br_rsa_private priv;
758
759 pub = br_rsa_i62_public_get();
760 priv = br_rsa_i62_private_get();
761 if (pub) {
762 test_speed_rsa_inner("RSA i62", pub, priv);
763 } else {
764 printf("%-30s UNAVAILABLE\n", "RSA i62");
765 }
766 }
767
768 static void
769 test_speed_ec_inner_1(const char *name,
770 const br_ec_impl *impl, const br_ec_curve_def *cd)
771 {
772 unsigned char bx[80], U[160];
773 uint32_t x[22], n[22];
774 size_t nlen, ulen;
775 int i;
776 long num;
777
778 nlen = cd->order_len;
779 br_i31_decode(n, cd->order, nlen);
780 memset(bx, 'T', sizeof bx);
781 br_i31_decode_reduce(x, bx, sizeof bx, n);
782 br_i31_encode(bx, nlen, x);
783 ulen = cd->generator_len;
784 memcpy(U, cd->generator, ulen);
785 for (i = 0; i < 10; i ++) {
786 impl->mul(U, ulen, bx, nlen, cd->curve);
787 }
788 num = 10;
789 for (;;) {
790 clock_t begin, end;
791 double tt;
792 long k;
793
794 begin = clock();
795 for (k = num; k > 0; k --) {
796 impl->mul(U, ulen, bx, nlen, cd->curve);
797 }
798 end = clock();
799 tt = (double)(end - begin) / CLOCKS_PER_SEC;
800 if (tt >= 2.0) {
801 printf("%-30s %8.2f mul/s\n", name,
802 (double)num / tt);
803 fflush(stdout);
804 break;
805 }
806 num <<= 1;
807 }
808 }
809
810 static void
811 test_speed_ec_inner_2(const char *name,
812 const br_ec_impl *impl, const br_ec_curve_def *cd)
813 {
814 unsigned char bx[80], U[160];
815 uint32_t x[22], n[22];
816 size_t nlen;
817 int i;
818 long num;
819
820 nlen = cd->order_len;
821 br_i31_decode(n, cd->order, nlen);
822 memset(bx, 'T', sizeof bx);
823 br_i31_decode_reduce(x, bx, sizeof bx, n);
824 br_i31_encode(bx, nlen, x);
825 for (i = 0; i < 10; i ++) {
826 impl->mulgen(U, bx, nlen, cd->curve);
827 }
828 num = 10;
829 for (;;) {
830 clock_t begin, end;
831 double tt;
832 long k;
833
834 begin = clock();
835 for (k = num; k > 0; k --) {
836 impl->mulgen(U, bx, nlen, cd->curve);
837 }
838 end = clock();
839 tt = (double)(end - begin) / CLOCKS_PER_SEC;
840 if (tt >= 2.0) {
841 printf("%-30s %8.2f mul/s\n", name,
842 (double)num / tt);
843 fflush(stdout);
844 break;
845 }
846 num <<= 1;
847 }
848 }
849
850 static void
851 test_speed_ec_inner(const char *name,
852 const br_ec_impl *impl, const br_ec_curve_def *cd)
853 {
854 char tmp[50];
855
856 test_speed_ec_inner_1(name, impl, cd);
857 sprintf(tmp, "%s (FP)", name);
858 test_speed_ec_inner_2(tmp, impl, cd);
859 }
860
861 static void
862 test_speed_ec_p256_m15(void)
863 {
864 test_speed_ec_inner("EC p256_m15",
865 &br_ec_p256_m15, &br_secp256r1);
866 }
867
868 static void
869 test_speed_ec_p256_m31(void)
870 {
871 test_speed_ec_inner("EC p256_m31",
872 &br_ec_p256_m31, &br_secp256r1);
873 }
874
875 static void
876 test_speed_ec_prime_i15(void)
877 {
878 test_speed_ec_inner("EC prime_i15 P-256",
879 &br_ec_prime_i15, &br_secp256r1);
880 test_speed_ec_inner("EC prime_i15 P-384",
881 &br_ec_prime_i15, &br_secp384r1);
882 test_speed_ec_inner("EC prime_i15 P-521",
883 &br_ec_prime_i15, &br_secp521r1);
884 }
885
886 static void
887 test_speed_ec_prime_i31(void)
888 {
889 test_speed_ec_inner("EC prime_i31 P-256",
890 &br_ec_prime_i31, &br_secp256r1);
891 test_speed_ec_inner("EC prime_i31 P-384",
892 &br_ec_prime_i31, &br_secp384r1);
893 test_speed_ec_inner("EC prime_i31 P-521",
894 &br_ec_prime_i31, &br_secp521r1);
895 }
896
897 static void
898 test_speed_ec_c25519_i15(void)
899 {
900 test_speed_ec_inner("EC c25519_i15",
901 &br_ec_c25519_i15, &br_curve25519);
902 }
903
904 static void
905 test_speed_ec_c25519_i31(void)
906 {
907 test_speed_ec_inner("EC c25519_i31",
908 &br_ec_c25519_i31, &br_curve25519);
909 }
910
911 static void
912 test_speed_ec_c25519_m15(void)
913 {
914 test_speed_ec_inner("EC c25519_m15",
915 &br_ec_c25519_m15, &br_curve25519);
916 }
917
918 static void
919 test_speed_ec_c25519_m31(void)
920 {
921 test_speed_ec_inner("EC c25519_m31",
922 &br_ec_c25519_m31, &br_curve25519);
923 }
924
925 static void
926 test_speed_ecdsa_inner(const char *name,
927 const br_ec_impl *impl, const br_ec_curve_def *cd,
928 br_ecdsa_sign sign, br_ecdsa_vrfy vrfy)
929 {
930 unsigned char bx[80], U[160], hv[32], sig[160];
931 uint32_t x[22], n[22];
932 size_t nlen, ulen, sig_len;
933 int i;
934 long num;
935 br_ec_private_key sk;
936 br_ec_public_key pk;
937
938 nlen = cd->order_len;
939 br_i31_decode(n, cd->order, nlen);
940 memset(bx, 'T', sizeof bx);
941 br_i31_decode_reduce(x, bx, sizeof bx, n);
942 br_i31_encode(bx, nlen, x);
943 ulen = cd->generator_len;
944 memcpy(U, cd->generator, ulen);
945 impl->mul(U, ulen, bx, nlen, cd->curve);
946 sk.curve = cd->curve;
947 sk.x = bx;
948 sk.xlen = nlen;
949 pk.curve = cd->curve;
950 pk.q = U;
951 pk.qlen = ulen;
952
953 memset(hv, 'H', sizeof hv);
954 sig_len = sign(impl, &br_sha256_vtable, hv, &sk, sig);
955 if (vrfy(impl, hv, sizeof hv, &pk, sig, sig_len) != 1) {
956 fprintf(stderr, "self-test sign/verify failed\n");
957 exit(EXIT_FAILURE);
958 }
959
960 for (i = 0; i < 10; i ++) {
961 hv[1] ++;
962 sign(impl, &br_sha256_vtable, hv, &sk, sig);
963 vrfy(impl, hv, sizeof hv, &pk, sig, sig_len);
964 }
965
966 num = 10;
967 for (;;) {
968 clock_t begin, end;
969 double tt;
970 long k;
971
972 begin = clock();
973 for (k = num; k > 0; k --) {
974 hv[1] ++;
975 sig_len = sign(impl, &br_sha256_vtable, hv, &sk, sig);
976 }
977 end = clock();
978 tt = (double)(end - begin) / CLOCKS_PER_SEC;
979 if (tt >= 2.0) {
980 printf("%-30s %8.2f sign/s\n", name,
981 (double)num / tt);
982 fflush(stdout);
983 break;
984 }
985 num <<= 1;
986 }
987
988 num = 10;
989 for (;;) {
990 clock_t begin, end;
991 double tt;
992 long k;
993
994 begin = clock();
995 for (k = num; k > 0; k --) {
996 vrfy(impl, hv, sizeof hv, &pk, sig, sig_len);
997 }
998 end = clock();
999 tt = (double)(end - begin) / CLOCKS_PER_SEC;
1000 if (tt >= 2.0) {
1001 printf("%-30s %8.2f verify/s\n", name,
1002 (double)num / tt);
1003 fflush(stdout);
1004 break;
1005 }
1006 num <<= 1;
1007 }
1008 }
1009
1010 static void
1011 test_speed_ecdsa_p256_m15(void)
1012 {
1013 test_speed_ecdsa_inner("ECDSA m15 P-256",
1014 &br_ec_p256_m15, &br_secp256r1,
1015 &br_ecdsa_i15_sign_asn1,
1016 &br_ecdsa_i15_vrfy_asn1);
1017 }
1018
1019 static void
1020 test_speed_ecdsa_p256_m31(void)
1021 {
1022 test_speed_ecdsa_inner("ECDSA m31 P-256",
1023 &br_ec_p256_m31, &br_secp256r1,
1024 &br_ecdsa_i31_sign_asn1,
1025 &br_ecdsa_i31_vrfy_asn1);
1026 }
1027
1028 static void
1029 test_speed_ecdsa_i15(void)
1030 {
1031 test_speed_ecdsa_inner("ECDSA i15 P-256",
1032 &br_ec_prime_i15, &br_secp256r1,
1033 &br_ecdsa_i15_sign_asn1,
1034 &br_ecdsa_i15_vrfy_asn1);
1035 test_speed_ecdsa_inner("ECDSA i15 P-384",
1036 &br_ec_prime_i15, &br_secp384r1,
1037 &br_ecdsa_i15_sign_asn1,
1038 &br_ecdsa_i15_vrfy_asn1);
1039 test_speed_ecdsa_inner("ECDSA i15 P-521",
1040 &br_ec_prime_i15, &br_secp521r1,
1041 &br_ecdsa_i15_sign_asn1,
1042 &br_ecdsa_i15_vrfy_asn1);
1043 }
1044
1045 static void
1046 test_speed_ecdsa_i31(void)
1047 {
1048 test_speed_ecdsa_inner("ECDSA i31 P-256",
1049 &br_ec_prime_i31, &br_secp256r1,
1050 &br_ecdsa_i31_sign_asn1,
1051 &br_ecdsa_i31_vrfy_asn1);
1052 test_speed_ecdsa_inner("ECDSA i31 P-384",
1053 &br_ec_prime_i31, &br_secp384r1,
1054 &br_ecdsa_i31_sign_asn1,
1055 &br_ecdsa_i31_vrfy_asn1);
1056 test_speed_ecdsa_inner("ECDSA i31 P-521",
1057 &br_ec_prime_i31, &br_secp521r1,
1058 &br_ecdsa_i31_sign_asn1,
1059 &br_ecdsa_i31_vrfy_asn1);
1060 }
1061
1062 static void
1063 test_speed_i31(void)
1064 {
1065 static const unsigned char bp[] = {
1066 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00,
1067 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
1068 0xBC, 0xE6, 0xFA, 0xAD, 0xA7, 0x17, 0x9E, 0x84,
1069 0xF3, 0xB9, 0xCA, 0xC2, 0xFC, 0x63, 0x25, 0x51
1070 };
1071
1072 unsigned char tmp[60 + sizeof bp];
1073 uint32_t p[10], x[10], y[10], z[10], p0i;
1074 int i;
1075 long num;
1076
1077 br_i31_decode(p, bp, sizeof bp);
1078 p0i = br_i31_ninv31(p[1]);
1079 memset(tmp, 'T', sizeof tmp);
1080 br_i31_decode_reduce(x, tmp, sizeof tmp, p);
1081 memset(tmp, 'U', sizeof tmp);
1082 br_i31_decode_reduce(y, tmp, sizeof tmp, p);
1083
1084 for (i = 0; i < 10; i ++) {
1085 br_i31_to_monty(x, p);
1086 }
1087 num = 10;
1088 for (;;) {
1089 clock_t begin, end;
1090 double tt;
1091 long k;
1092
1093 begin = clock();
1094 for (k = num; k > 0; k --) {
1095 br_i31_to_monty(x, p);
1096 }
1097 end = clock();
1098 tt = (double)(end - begin) / CLOCKS_PER_SEC;
1099 if (tt >= 2.0) {
1100 printf("%-30s %8.2f ops/s\n", "i31 to_monty",
1101 (double)num / tt);
1102 fflush(stdout);
1103 break;
1104 }
1105 num <<= 1;
1106 }
1107
1108 for (i = 0; i < 10; i ++) {
1109 br_i31_from_monty(x, p, p0i);
1110 }
1111 num = 10;
1112 for (;;) {
1113 clock_t begin, end;
1114 double tt;
1115 long k;
1116
1117 begin = clock();
1118 for (k = num; k > 0; k --) {
1119 br_i31_from_monty(x, p, p0i);
1120 }
1121 end = clock();
1122 tt = (double)(end - begin) / CLOCKS_PER_SEC;
1123 if (tt >= 2.0) {
1124 printf("%-30s %8.2f ops/s\n", "i31 from_monty",
1125 (double)num / tt);
1126 fflush(stdout);
1127 break;
1128 }
1129 num <<= 1;
1130 }
1131
1132 for (i = 0; i < 10; i ++) {
1133 br_i31_montymul(z, x, y, p, p0i);
1134 }
1135 num = 10;
1136 for (;;) {
1137 clock_t begin, end;
1138 double tt;
1139 long k;
1140
1141 begin = clock();
1142 for (k = num; k > 0; k --) {
1143 br_i31_montymul(z, x, y, p, p0i);
1144 }
1145 end = clock();
1146 tt = (double)(end - begin) / CLOCKS_PER_SEC;
1147 if (tt >= 2.0) {
1148 printf("%-30s %8.2f ops/s\n", "i31 montymul",
1149 (double)num / tt);
1150 fflush(stdout);
1151 break;
1152 }
1153 num <<= 1;
1154 }
1155 }
1156
1157 #if 0
1158
1159 static unsigned char P2048[] = {
1160 0xFD, 0xB6, 0xE0, 0x3E, 0x00, 0x49, 0x4C, 0xF0, 0x69, 0x3A, 0xDD, 0x7D,
1161 0xF8, 0xA2, 0x41, 0xB0, 0x6C, 0x67, 0xC5, 0xBA, 0xB8, 0x46, 0x80, 0xF5,
1162 0xBF, 0xAB, 0x98, 0xFC, 0x84, 0x73, 0xA5, 0x63, 0xC9, 0x52, 0x12, 0xDA,
1163 0x4C, 0xC1, 0x5B, 0x9D, 0x8D, 0xDF, 0xCD, 0xFE, 0xC5, 0xAD, 0x5A, 0x6F,
1164 0xDD, 0x02, 0xD9, 0xEC, 0x71, 0xEF, 0xEB, 0xB6, 0x95, 0xED, 0x94, 0x25,
1165 0x0E, 0x63, 0xDD, 0x6A, 0x52, 0xC7, 0x93, 0xAF, 0x85, 0x9D, 0x2C, 0xBE,
1166 0x5C, 0xBE, 0x35, 0xD8, 0xDD, 0x39, 0xEF, 0x1B, 0xB1, 0x49, 0x67, 0xB2,
1167 0x33, 0xC9, 0x7C, 0xE1, 0x51, 0x79, 0x51, 0x59, 0xCA, 0x6E, 0x2A, 0xDF,
1168 0x0D, 0x76, 0x1C, 0xE7, 0xA5, 0xC0, 0x1E, 0x6C, 0x56, 0x3A, 0x32, 0xE5,
1169 0xB5, 0xC5, 0xD4, 0xDB, 0xFE, 0xFF, 0xF8, 0xF2, 0x96, 0xA9, 0xC9, 0x65,
1170 0x59, 0x9E, 0x01, 0x79, 0x9D, 0x38, 0x68, 0x0F, 0xAD, 0x43, 0x3A, 0xD6,
1171 0x84, 0x0A, 0xE2, 0xEF, 0x96, 0xC1, 0x6D, 0x89, 0x74, 0x19, 0x63, 0x82,
1172 0x3B, 0xA0, 0x9C, 0xBA, 0x78, 0xDE, 0xDC, 0xC2, 0xE7, 0xD4, 0xFA, 0xD6,
1173 0x19, 0x21, 0x29, 0xAE, 0x5E, 0xF4, 0x38, 0x81, 0xC6, 0x9E, 0x0E, 0x3C,
1174 0xCD, 0xC0, 0xDC, 0x93, 0x5D, 0xFD, 0x9A, 0x5C, 0xAB, 0x54, 0x1F, 0xFF,
1175 0x9C, 0x12, 0x1B, 0x4C, 0xDF, 0x2D, 0x9C, 0x85, 0xF9, 0x68, 0x15, 0x89,
1176 0x42, 0x9B, 0x6C, 0x45, 0x89, 0x3A, 0xBC, 0xE9, 0x19, 0x91, 0xBE, 0x0C,
1177 0xEF, 0x90, 0xCC, 0xF6, 0xD6, 0xF0, 0x3D, 0x5C, 0xF5, 0xE5, 0x0F, 0x2F,
1178 0x02, 0x8A, 0x83, 0x4B, 0x93, 0x2F, 0x14, 0x12, 0x1F, 0x56, 0x9A, 0x12,
1179 0x58, 0x88, 0xAE, 0x60, 0xB8, 0x5A, 0xE4, 0xA1, 0xBF, 0x4A, 0x81, 0x84,
1180 0xAB, 0xBB, 0xE4, 0xD0, 0x1D, 0x41, 0xD9, 0x0A, 0xAB, 0x1E, 0x47, 0x5B,
1181 0x31, 0xAC, 0x2B, 0x73
1182 };
1183
1184 static unsigned char G2048[] = {
1185 0x02
1186 };
1187
1188 static void
1189 test_speed_modpow(void)
1190 {
1191 uint32_t mx[65], mp[65], me[65], t1[65], t2[65], len;
1192 unsigned char e[64];
1193 int i;
1194 long num;
1195
1196 len = br_int_decode(mp, sizeof mp / sizeof mp[0],
1197 P2048, sizeof P2048);
1198 if (len != 65) {
1199 abort();
1200 }
1201 memset(e, 'P', sizeof e);
1202 if (!br_int_decode(me, sizeof me / sizeof me[0], e, sizeof e)) {
1203 abort();
1204 }
1205 if (!br_modint_decode(mx, mp, G2048, sizeof G2048)) {
1206 abort();
1207 }
1208 for (i = 0; i < 10; i ++) {
1209 br_modint_to_monty(mx, mp);
1210 br_modint_montypow(mx, me, mp, t1, t2);
1211 br_modint_from_monty(mx, mp);
1212 }
1213 num = 10;
1214 for (;;) {
1215 clock_t begin, end;
1216 double tt;
1217 long k;
1218
1219 begin = clock();
1220 for (k = num; k > 0; k --) {
1221 br_modint_to_monty(mx, mp);
1222 br_modint_montypow(mx, me, mp, t1, t2);
1223 br_modint_from_monty(mx, mp);
1224 }
1225 end = clock();
1226 tt = (double)(end - begin) / CLOCKS_PER_SEC;
1227 if (tt >= 2.0) {
1228 printf("%-30s %8.2f exp/s\n", "pow[2048:256]",
1229 (double)num / tt);
1230 fflush(stdout);
1231 return;
1232 }
1233 num <<= 1;
1234 }
1235 }
1236
1237 static void
1238 test_speed_moddiv(void)
1239 {
1240 uint32_t mx[65], my[65], mp[65], t1[65], t2[65], t3[65], len;
1241 unsigned char x[255], y[255];
1242 int i;
1243 long num;
1244
1245 len = br_int_decode(mp, sizeof mp / sizeof mp[0],
1246 P2048, sizeof P2048);
1247 if (len != 65) {
1248 abort();
1249 }
1250 memset(x, 'T', sizeof x);
1251 memset(y, 'P', sizeof y);
1252 if (!br_modint_decode(mx, mp, x, sizeof x)) {
1253 abort();
1254 }
1255 if (!br_modint_decode(my, mp, y, sizeof y)) {
1256 abort();
1257 }
1258 for (i = 0; i < 10; i ++) {
1259 br_modint_div(mx, my, mp, t1, t2, t3);
1260 }
1261 num = 10;
1262 for (;;) {
1263 clock_t begin, end;
1264 double tt;
1265 long k;
1266
1267 begin = clock();
1268 for (k = num; k > 0; k --) {
1269 br_modint_div(mx, my, mp, t1, t2, t3);
1270 }
1271 end = clock();
1272 tt = (double)(end - begin) / CLOCKS_PER_SEC;
1273 if (tt >= 2.0) {
1274 printf("%-30s %8.2f div/s\n", "div[2048]",
1275 (double)num / tt);
1276 fflush(stdout);
1277 return;
1278 }
1279 num <<= 1;
1280 }
1281 }
1282 #endif
1283
1284 #define STU(x) { test_speed_ ## x, #x }
1285
1286 static const struct {
1287 void (*fn)(void);
1288 char *name;
1289 } tfns[] = {
1290 STU(md5),
1291 STU(sha1),
1292 STU(sha256),
1293 STU(sha512),
1294
1295 STU(aes128_big_cbcenc),
1296 STU(aes128_big_cbcdec),
1297 STU(aes192_big_cbcenc),
1298 STU(aes192_big_cbcdec),
1299 STU(aes256_big_cbcenc),
1300 STU(aes256_big_cbcdec),
1301 STU(aes128_big_ctr),
1302 STU(aes192_big_ctr),
1303 STU(aes256_big_ctr),
1304
1305 STU(aes128_small_cbcenc),
1306 STU(aes128_small_cbcdec),
1307 STU(aes192_small_cbcenc),
1308 STU(aes192_small_cbcdec),
1309 STU(aes256_small_cbcenc),
1310 STU(aes256_small_cbcdec),
1311 STU(aes128_small_ctr),
1312 STU(aes192_small_ctr),
1313 STU(aes256_small_ctr),
1314
1315 STU(aes128_ct_cbcenc),
1316 STU(aes128_ct_cbcdec),
1317 STU(aes192_ct_cbcenc),
1318 STU(aes192_ct_cbcdec),
1319 STU(aes256_ct_cbcenc),
1320 STU(aes256_ct_cbcdec),
1321 STU(aes128_ct_ctr),
1322 STU(aes192_ct_ctr),
1323 STU(aes256_ct_ctr),
1324
1325 STU(aes128_ct64_cbcenc),
1326 STU(aes128_ct64_cbcdec),
1327 STU(aes192_ct64_cbcenc),
1328 STU(aes192_ct64_cbcdec),
1329 STU(aes256_ct64_cbcenc),
1330 STU(aes256_ct64_cbcdec),
1331 STU(aes128_ct64_ctr),
1332 STU(aes192_ct64_ctr),
1333 STU(aes256_ct64_ctr),
1334
1335 STU(aes128_x86ni_cbcenc),
1336 STU(aes128_x86ni_cbcdec),
1337 STU(aes192_x86ni_cbcenc),
1338 STU(aes192_x86ni_cbcdec),
1339 STU(aes256_x86ni_cbcenc),
1340 STU(aes256_x86ni_cbcdec),
1341 STU(aes128_x86ni_ctr),
1342 STU(aes192_x86ni_ctr),
1343 STU(aes256_x86ni_ctr),
1344
1345 STU(aes128_pwr8_cbcenc),
1346 STU(aes128_pwr8_cbcdec),
1347 STU(aes192_pwr8_cbcenc),
1348 STU(aes192_pwr8_cbcdec),
1349 STU(aes256_pwr8_cbcenc),
1350 STU(aes256_pwr8_cbcdec),
1351 STU(aes128_pwr8_ctr),
1352 STU(aes192_pwr8_ctr),
1353 STU(aes256_pwr8_ctr),
1354
1355 STU(des_tab_cbcenc),
1356 STU(des_tab_cbcdec),
1357 STU(3des_tab_cbcenc),
1358 STU(3des_tab_cbcdec),
1359
1360 STU(des_ct_cbcenc),
1361 STU(des_ct_cbcdec),
1362 STU(3des_ct_cbcenc),
1363 STU(3des_ct_cbcdec),
1364
1365 STU(chacha20_ct),
1366 STU(chacha20_sse2),
1367
1368 STU(ghash_ctmul),
1369 STU(ghash_ctmul32),
1370 STU(ghash_ctmul64),
1371 STU(ghash_pclmul),
1372 STU(ghash_pwr8),
1373
1374 STU(poly1305_ctmul),
1375 STU(poly1305_ctmul32),
1376 STU(poly1305_ctmulq),
1377 STU(poly1305_i15),
1378
1379 STU(eax_aes128_big),
1380 STU(eax_aes192_big),
1381 STU(eax_aes256_big),
1382 STU(eax_aes128_small),
1383 STU(eax_aes192_small),
1384 STU(eax_aes256_small),
1385 STU(eax_aes128_ct),
1386 STU(eax_aes192_ct),
1387 STU(eax_aes256_ct),
1388 STU(eax_aes128_ct64),
1389 STU(eax_aes192_ct64),
1390 STU(eax_aes256_ct64),
1391 STU(eax_aes128_x86ni),
1392 STU(eax_aes192_x86ni),
1393 STU(eax_aes256_x86ni),
1394
1395 STU(rsa_i15),
1396 STU(rsa_i31),
1397 STU(rsa_i32),
1398 STU(rsa_i62),
1399 STU(ec_prime_i15),
1400 STU(ec_prime_i31),
1401 STU(ec_p256_m15),
1402 STU(ec_p256_m31),
1403 STU(ec_c25519_i15),
1404 STU(ec_c25519_i31),
1405 STU(ec_c25519_m15),
1406 STU(ec_c25519_m31),
1407 STU(ecdsa_p256_m15),
1408 STU(ecdsa_p256_m31),
1409 STU(ecdsa_i15),
1410 STU(ecdsa_i31),
1411
1412 STU(i31)
1413 };
1414
1415 static int
1416 eq_name(const char *s1, const char *s2)
1417 {
1418 for (;;) {
1419 int c1, c2;
1420
1421 for (;;) {
1422 c1 = *s1 ++;
1423 if (c1 >= 'A' && c1 <= 'Z') {
1424 c1 += 'a' - 'A';
1425 } else {
1426 switch (c1) {
1427 case '-': case '_': case '.': case ' ':
1428 continue;
1429 }
1430 }
1431 break;
1432 }
1433 for (;;) {
1434 c2 = *s2 ++;
1435 if (c2 >= 'A' && c2 <= 'Z') {
1436 c2 += 'a' - 'A';
1437 } else {
1438 switch (c2) {
1439 case '-': case '_': case '.': case ' ':
1440 continue;
1441 }
1442 }
1443 break;
1444 }
1445 if (c1 != c2) {
1446 return 0;
1447 }
1448 if (c1 == 0) {
1449 return 1;
1450 }
1451 }
1452 }
1453
1454 int
1455 main(int argc, char *argv[])
1456 {
1457 size_t u;
1458
1459 if (argc <= 1) {
1460 printf("usage: testspeed all | name...\n");
1461 printf("individual test names:\n");
1462 for (u = 0; u < (sizeof tfns) / (sizeof tfns[0]); u ++) {
1463 printf(" %s\n", tfns[u].name);
1464 }
1465 } else {
1466 for (u = 0; u < (sizeof tfns) / (sizeof tfns[0]); u ++) {
1467 int i;
1468
1469 for (i = 1; i < argc; i ++) {
1470 if (eq_name(argv[i], tfns[u].name)
1471 || eq_name(argv[i], "all"))
1472 {
1473 tfns[u].fn();
1474 break;
1475 }
1476 }
1477 }
1478 }
1479 return 0;
1480 }