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