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