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