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