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