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