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