1 /* hogweed-benchmark.c
2
3 Copyright (C) 2013, 2014 Niels Möller
4
5 This file is part of GNU Nettle.
6
7 GNU Nettle is free software: you can redistribute it and/or
8 modify it under the terms of either:
9
10 * the GNU Lesser General Public License as published by the Free
11 Software Foundation; either version 3 of the License, or (at your
12 option) any later version.
13
14 or
15
16 * the GNU General Public License as published by the Free
17 Software Foundation; either version 2 of the License, or (at your
18 option) any later version.
19
20 or both in parallel, as here.
21
22 GNU Nettle is distributed in the hope that it will be useful,
23 but WITHOUT ANY WARRANTY; without even the implied warranty of
24 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
25 General Public License for more details.
26
27 You should have received copies of the GNU General Public License and
28 the GNU Lesser General Public License along with this program. If
29 not, see http://www.gnu.org/licenses/.
30 */
31
32 #if HAVE_CONFIG_H
33 # include "config.h"
34 #endif
35
36 #include <assert.h>
37 #include <stdarg.h>
38 #include <stdio.h>
39 #include <stdlib.h>
40 #include <string.h>
41
42 #include <errno.h>
43
44 #include <time.h>
45
46 #include "timing.h"
47
48 #include "dsa.h"
49 #include "rsa.h"
50 #include "curve25519.h"
51
52 #include "nettle-meta.h"
53 #include "sexp.h"
54 #include "knuth-lfib.h"
55
56 #include "../ecdsa.h"
57 #include "../ecc-internal.h"
58 #include "../gmp-glue.h"
59
60 #if WITH_OPENSSL
61 #include <openssl/rsa.h>
62 #include <openssl/bn.h>
63 #include <openssl/ec.h>
64 #include <openssl/ecdsa.h>
65 #include <openssl/objects.h>
66 #endif
67
68 #define BENCH_INTERVAL 0.1
69
70 static void NORETURN PRINTF_STYLE(1,2)
die(const char * format,...)71 die(const char *format, ...)
72 {
73 va_list args;
74 va_start(args, format);
75 vfprintf(stderr, format, args);
76 va_end(args);
77
78 exit(EXIT_FAILURE);
79 }
80
81 static void *
xalloc(size_t size)82 xalloc (size_t size)
83 {
84 void *p = malloc (size);
85 if (!p)
86 {
87 fprintf (stderr, "Virtual memory exhausted\n");
88 abort ();
89 }
90 return p;
91 }
92
93 static uint8_t *
hash_string(const struct nettle_hash * hash,const char * s)94 hash_string (const struct nettle_hash *hash, const char *s)
95 {
96 void *ctx = xalloc (hash->context_size);
97 uint8_t *digest = xalloc (hash->digest_size);
98 hash->init (ctx);
99 hash->update (ctx, strlen(s), (const uint8_t *) s);
100 hash->digest (ctx, hash->digest_size, digest);
101 free (ctx);
102
103 return digest;
104 }
105
106 struct alg {
107 const char *name;
108 unsigned size;
109 void *(*init) (unsigned size);
110 void (*sign) (void *);
111 void (*verify)(void *);
112 void (*clear) (void *);
113 };
114
115 /* Returns second per function call */
116 static double
time_function(void (* f)(void * arg),void * arg)117 time_function(void (*f)(void *arg), void *arg)
118 {
119 unsigned ncalls;
120 double elapsed;
121
122 /* Warm up */
123 f(arg);
124 for (ncalls = 10 ;;)
125 {
126 unsigned i;
127
128 time_start();
129 for (i = 0; i < ncalls; i++)
130 f(arg);
131 elapsed = time_end();
132 if (elapsed > BENCH_INTERVAL)
133 break;
134 else if (elapsed < BENCH_INTERVAL / 10)
135 ncalls *= 10;
136 else
137 ncalls *= 2;
138 }
139 return elapsed / ncalls;
140 }
141
142 static void
bench_alg(const struct alg * alg)143 bench_alg (const struct alg *alg)
144 {
145 double sign;
146 double verify;
147 void *ctx;
148
149 ctx = alg->init(alg->size);
150 if (ctx == NULL)
151 {
152 printf("%16s %4d N/A\n", alg->name, alg->size);
153 return;
154 }
155
156 sign = time_function (alg->sign, ctx);
157 verify = time_function (alg->verify, ctx);
158
159 alg->clear (ctx);
160
161 printf("%16s %4d %9.4f %9.4f\n",
162 alg->name, alg->size, 1e-3/sign, 1e-3/verify);
163 }
164
165 struct rsa_ctx
166 {
167 struct rsa_public_key pub;
168 struct rsa_private_key key;
169 struct knuth_lfib_ctx lfib;
170 uint8_t *digest;
171 mpz_t s;
172 };
173
174 static void *
bench_rsa_init(unsigned size)175 bench_rsa_init (unsigned size)
176 {
177 unsigned char rsa1024[] =
178 "{KDExOnByaXZhdGUta2V5KDE0OnJzYS1wa2NzMS1zaGExKDE6bjEyOToA90+K5EmjbFJBeJD"
179 " xP2KD2Df+0Twc9425uB+vhqTrVijtd2PnwEQDfR2VoducgkKcXJzYYyCNILQJbFAi2Km/sD"
180 " jImERBqDtaI217Ze+tOKEmImexYTAgFuqEptp2F3M4DqgRQ7s/3nJQ/bPE5Hfi1OZhJSShu"
181 " I80ATTU4fUgrPspKDE6ZTM6AQABKSgxOmQxMjk6APAhKckzvxxkWfHJOpXDACWnaSKcbbvo"
182 " vtWK3pGr/F2ya7CrLtE+uOx5F1sLs9G+/7flCy5k4uNILIYg4VTirZ1zQ8fNKPrjK1VMRls"
183 " JiRRU/0VAs9d7HdncJfs6rbvRQbCRSRYURo4hWir3Lq8V3UUQVBprc4dO+uWmplvwQ5qxKS"
184 " gxOnA2NToA+8aIVkdbk8Jg8dJOuzc7m/hZnwkKSs6eVDw4N/2T0CJKGJYT+B3Ct+fPkxhUR"
185 " ggd2DQ9OpkTra7SXHTNkzdPVSkoMTpxNjU6APt11P8vXNnGYF0OC/cPsR8zhSYuFmtRuX6G"
186 " ES+DdG0VCU07UeNQkok1UoW5sXqY0IGr1jkJq8AMSgKoNbLQ6w8pKDE6YTY0Ohzkxsan/8F"
187 " wQDHgQbrIduXKVXaj0fONzKu8EXOTfUAYf0pdBsOlnq/+QVsPIrS6v7oNHK253YFEG84SdX"
188 " kcktUpKDE6YjY1OgCR+cRtY3RWY+f6/TWK9gwPndv03xpasLWrMm71ky1aSbT9pasS9+opR"
189 " tAiGzthfSbFsBiLQgb3VOr+AeIybT+XKSgxOmM2NDojigqARWN5u1CVDVuD2L2ManpoGiM6"
190 " kQ6FaJjqRjxeRRKFrQxGJa9tM1hqStxokC1oJidgaOLGnn60iwzToug9KSkp}";
191
192 unsigned char rsa2048[] =
193 "{KDExOnByaXZhdGUta2V5KDE0OnJzYS1wa2NzMS1zaGExKDE6bjI1NzoAtxWXiglIdunDK48"
194 " 8I0vW0wTqnh/riW9pLk8n1F8MUPBFdhvkkl0bDQqSJPUvSHy+w4fLVwcEzeI4qFyo3b2Avz"
195 " JK20MFbt/WfHD1TbxuK8rNqXyqmqjJ9vgjtV9nPzAz7CM9ogs3/RJHpcfZPQF15ifizleUZ"
196 " aQT0GAXHZL7cePj10yGI2u3hgTkokVzdNC/1T34guKYpErg0pt0B/KejWpsFTb84z3tkR+B"
197 " YVx07p/OoByZwoABgncS/uALl31fRS8jyJ2JqUiZOqe7XoO9hkDHYNCWUGUfNGQ7ZgVp9+e"
198 " NQpracSjrp6Jnrj7r/oxJUx5ZDVNi18AzQadE/oKOrSkoMTplMzoBAAEpKDE6ZDI1NjogBT"
199 " C5vaHk2kF+LtDvw2XRBj0aZq7FHK0ioklvBSicR0l+vKYfSxVeFIk22YLphJfAjtFraRjYA"
200 " Uaze3E1Rt1rkxoweupKV++lWAQvElOaaR/LErirz/Vysjdck1D1ZjLOi+NNofSq2DWbsvY1"
201 " iznZhQRP3lVf6XBls0iXrYs4gb0pBZqXLQW+j9Ihx6eantf1/6ZMKPgCkzcAZ0ABsCfaFSg"
202 " ouNCzilblsgFEspEbb8QqrNQoStS3F/gMwWgDsr3+vQzBqt+7ykWoCJ9wctbYy9kEPq+hX3"
203 " GP0hG6HdS81r9E8pgdf3wloNNMzYUHwn7poXGpOi8tG0pmR56TqD/BKSgxOnAxMjk6AN4AJ"
204 " TiGPm9We2ga3Y0jpTfA3mWpUbhYgaXYLWA1/riniwq16fqxRIkWQT/O2KKpBVe6WSvNYq9u"
205 " lM8N6bdPtDytJs6AOXy0X5vtJ953ZYVMhHbhmUxhIL9I+s0O1+LxMF8b9U4CrFyaTxd8Un/"
206 " FXP1BvYJRrkoup6HYvOlGx36lKSgxOnExMjk6ANMfrfH6z/3o7K56aW6kSiloDDbKZQ0+W5"
207 " 8LzP2ZOBLf6LX6jLhN3olU1Z0KGTM0S/1AxvwGjuRqhu+LcOJ7oUCUH3uusR5c5nSnArYPq"
208 " +0wbco4BQngot/HmGN7U0EDsIWqPt/qoa/b8bCk+TOwJlknNq/PnZU26SPj48XS05lpKSgx"
209 " OmExMjk6AJM2n3gLNW3ZeH5BindkktQU9qWNkV5geqDCaNyrEZ3bpI1WsrEGSj9p3Zz1ipz"
210 " a3msdbLJqQS26c72WKUzg8tFltR0s1HJInjolGtIgdNbfNdwrn9+RbQjL2VyPokOg0wXO4W"
211 " 14wlmqDhax33dRJmfe50964MvaglkGA8fhorrtKSgxOmIxMjk6AKMe+vrX2xRHf3dfxU5jS"
212 " ZmsdqNuxZzx7UB5kazvUU/kCJ1yNH/CSoq5LULkpovVgFDwV84qEwWQ+SjkCBg1hWWsDJc3"
213 " ZkobZUQENigM+72LiYiQt/PlyHI2eRuEEdNN0nm0DFhdpQeHXLoq/RBerYJ8tdgpBYxgnMn"
214 " KLhaOykbhKSgxOmMxMjg6MVlKj2bjb7qFQVkLO1OPg28jSrtRpnQCR+qegN4ZmNam/qbest"
215 " 8yn0JQ6gxX7PvP382+jx7uHHWHYYqPq/Flf8gqtOOcjqS5TJgVHz3F3xHWquo1ZofGtCMro"
216 " Dd2c0xjRjIVGvLV6Ngs+HRdljRav40vRpTyEoEdlzHBQiILesopKSk=}";
217
218 struct rsa_ctx *ctx;
219 struct sexp_iterator i;
220
221 int res;
222
223 ctx = xalloc(sizeof(*ctx));
224
225 rsa_public_key_init (&ctx->pub);
226 rsa_private_key_init (&ctx->key);
227 mpz_init (ctx->s);
228 knuth_lfib_init (&ctx->lfib, 1);
229
230 /* NOTE: Base64-decodes the strings in-place */
231 if (size == 1024)
232 res = sexp_transport_iterator_first (&i, sizeof(rsa1024) - 1, rsa1024);
233 else if (size == 2048)
234 res = sexp_transport_iterator_first (&i, sizeof(rsa2048) - 1, rsa2048);
235 else
236 die ("Internal error.\n");
237
238 if (! (res
239 && sexp_iterator_check_type (&i, "private-key")
240 && sexp_iterator_check_type (&i, "rsa-pkcs1-sha1")
241 && rsa_keypair_from_sexp_alist (&ctx->pub, &ctx->key, 0, &i)))
242 die ("Internal error.\n");
243
244 ctx->digest = hash_string (&nettle_sha256, "foo");
245
246 rsa_sha256_sign_digest (&ctx->key, ctx->digest, ctx->s);
247
248 return ctx;
249 }
250
251 static void
bench_rsa_sign(void * p)252 bench_rsa_sign (void *p)
253 {
254 struct rsa_ctx *ctx = p;
255
256 mpz_t s;
257 mpz_init (s);
258 rsa_sha256_sign_digest (&ctx->key, ctx->digest, s);
259 mpz_clear (s);
260 }
261
262 static void
bench_rsa_sign_tr(void * p)263 bench_rsa_sign_tr (void *p)
264 {
265 struct rsa_ctx *ctx = p;
266
267 mpz_t s;
268 mpz_init (s);
269 rsa_sha256_sign_digest_tr (&ctx->pub, &ctx->key,
270 &ctx->lfib, (nettle_random_func *)knuth_lfib_random,
271 ctx->digest, s);
272 mpz_clear (s);
273 }
274
275 static void
bench_rsa_verify(void * p)276 bench_rsa_verify (void *p)
277 {
278 struct rsa_ctx *ctx = p;
279 if (! rsa_sha256_verify_digest (&ctx->pub, ctx->digest, ctx->s))
280 die ("Internal error, rsa_sha256_verify_digest failed.\n");
281 }
282
283 static void
bench_rsa_clear(void * p)284 bench_rsa_clear (void *p)
285 {
286 struct rsa_ctx *ctx = p;
287
288 rsa_public_key_clear (&ctx->pub);
289 rsa_private_key_clear (&ctx->key);
290 mpz_clear (ctx->s);
291
292 free (ctx->digest);
293 free (ctx);
294 }
295
296 struct dsa_ctx
297 {
298 struct dsa_params params;
299 mpz_t pub;
300 mpz_t key;
301 struct knuth_lfib_ctx lfib;
302 struct dsa_signature s;
303 uint8_t *digest;
304 };
305
306 static void *
bench_dsa_init(unsigned size)307 bench_dsa_init (unsigned size)
308 {
309 struct dsa_ctx *ctx;
310 struct sexp_iterator i;
311
312 unsigned char dsa1024[] =
313 "{KDExOnByaXZhdGUta2V5KDM6ZHNhKDE6cDEyOToA2q4hOXEClLMXXMOl9xaPcGC/GeGmCMv"
314 " VCaaW0uWc50DvvmJDPQPdCehyfZr/1dv2UDbx06TC7ls/IFd+BsDzGBRxqIQ44J20cn+0gt"
315 " NMIXAocE1QhCCFaT5gXrk8zMlqBEGaP3RdpgxNanEXkTj2Wma8r1GtrLX3HPafio62jicpK"
316 " DE6cTIxOgDN9pcW3exdVAesC9WsxwCGoJK24ykoMTpnMTI5OgCJr9DmKdiE0WJZB7HACESv"
317 " Tpg1qZgc8E15byQ+OsHUyOTRrJRTcrgKZJW7dFRJ9cXmyi7XYCd3bJtu/2HRHLY1vd4qMvU"
318 " 7Y8x08ooCoABGV7nGqcmdQfEho1OY6TZh2NikmPKZLeur3PZFpcZ8Dl+KVWtwC55plNC7Om"
319 " iAQy8MaCkoMTp5MTI5OgDakk0LOUQwzOKt9FHOBmBKrWsvTm7549eScTUqH4OMm3btjUsXz"
320 " MmlqEe+imwQCOW/AE3Xw9pXZeETWK0jlLe8k5vnKcNskerFwZ1eQKtOPPQty8IqQ9PEfF6B"
321 " 0oVQiJg2maHUDWFnDkIBd7ZR1z8FnZMUxH9mH4kEUo6YQgtCdykoMTp4MjA6cOl3ijiiMjI"
322 " pesFD8jxESWb2mn8pKSk=}";
323
324 ctx = xalloc(sizeof(*ctx));
325
326 dsa_params_init (&ctx->params);
327 mpz_init (ctx->pub);
328 mpz_init (ctx->key);
329 dsa_signature_init (&ctx->s);
330 knuth_lfib_init (&ctx->lfib, 1);
331
332 if (size != 1024)
333 die ("Internal error.\n");
334
335 if (! (sexp_transport_iterator_first (&i, sizeof(dsa1024) - 1, dsa1024)
336 && sexp_iterator_check_type (&i, "private-key")
337 && sexp_iterator_check_type (&i, "dsa")
338 && dsa_keypair_from_sexp_alist (&ctx->params, ctx->pub, ctx->key,
339 0, DSA_SHA1_Q_BITS, &i)) )
340 die ("Internal error.\n");
341
342 ctx->digest = hash_string (&nettle_sha1, "foo");
343
344 dsa_sign (&ctx->params, ctx->key,
345 &ctx->lfib, (nettle_random_func *)knuth_lfib_random,
346 SHA1_DIGEST_SIZE, ctx->digest, &ctx->s);
347
348 return ctx;
349 }
350
351 static void
bench_dsa_sign(void * p)352 bench_dsa_sign (void *p)
353 {
354 struct dsa_ctx *ctx = p;
355 struct dsa_signature s;
356
357 dsa_signature_init (&s);
358 dsa_sign (&ctx->params, ctx->key,
359 &ctx->lfib, (nettle_random_func *)knuth_lfib_random,
360 SHA1_DIGEST_SIZE, ctx->digest, &s);
361 dsa_signature_clear (&s);
362 }
363
364 static void
bench_dsa_verify(void * p)365 bench_dsa_verify (void *p)
366 {
367 struct dsa_ctx *ctx = p;
368 if (! dsa_verify (&ctx->params, ctx->pub, SHA1_DIGEST_SIZE, ctx->digest, &ctx->s))
369 die ("Internal error, dsa_sha1_verify_digest failed.\n");
370 }
371
372 static void
bench_dsa_clear(void * p)373 bench_dsa_clear (void *p)
374 {
375 struct dsa_ctx *ctx = p;
376 dsa_params_clear (&ctx->params);
377 mpz_clear (ctx->pub);
378 mpz_clear (ctx->key);
379 dsa_signature_clear (&ctx->s);
380 free (ctx->digest);
381 free (ctx);
382 }
383
384 struct ecdsa_ctx
385 {
386 struct ecc_point pub;
387 struct ecc_scalar key;
388 struct knuth_lfib_ctx rctx;
389 unsigned digest_size;
390 uint8_t *digest;
391 struct dsa_signature s;
392 };
393
394 static void *
bench_ecdsa_init(unsigned size)395 bench_ecdsa_init (unsigned size)
396 {
397 struct ecdsa_ctx *ctx;
398 const struct ecc_curve *ecc;
399
400 const char *xs;
401 const char *ys;
402 const char *zs;
403 mpz_t x, y, z;
404
405 ctx = xalloc (sizeof(*ctx));
406
407 dsa_signature_init (&ctx->s);
408 knuth_lfib_init (&ctx->rctx, 17);
409
410 switch (size)
411 {
412 case 192:
413 ecc = &_nettle_secp_192r1;
414 xs = "8e8e07360350fb6b7ad8370cfd32fa8c6bba785e6e200599";
415 ys = "7f82ddb58a43d59ff8dc66053002b918b99bd01bd68d6736";
416 zs = "f2e620e086d658b4b507996988480917640e4dc107808bdd";
417 ctx->digest = hash_string (&nettle_sha1, "abc");
418 ctx->digest_size = 20;
419 break;
420 case 224:
421 ecc = &_nettle_secp_224r1;
422 xs = "993bf363f4f2bc0f255f22563980449164e9c894d9efd088d7b77334";
423 ys = "b75fff9849997d02d135140e4d0030944589586e22df1fc4b629082a";
424 zs = "cdfd01838247f5de3cc70b688418046f10a2bfaca6de9ec836d48c27";
425 ctx->digest = hash_string (&nettle_sha224, "abc");
426 ctx->digest_size = 28;
427 break;
428
429 /* From RFC 4754 */
430 case 256:
431 ecc = &_nettle_secp_256r1;
432 xs = "2442A5CC 0ECD015F A3CA31DC 8E2BBC70 BF42D60C BCA20085 E0822CB0 4235E970";
433 ys = "6FC98BD7 E50211A4 A27102FA 3549DF79 EBCB4BF2 46B80945 CDDFE7D5 09BBFD7D";
434 zs = "DC51D386 6A15BACD E33D96F9 92FCA99D A7E6EF09 34E70975 59C27F16 14C88A7F";
435 ctx->digest = hash_string (&nettle_sha256, "abc");
436 ctx->digest_size = 32;
437 break;
438 case 384:
439 ecc = &_nettle_secp_384r1;
440 xs = "96281BF8 DD5E0525 CA049C04 8D345D30 82968D10 FEDF5C5A CA0C64E6 465A97EA"
441 "5CE10C9D FEC21797 41571072 1F437922";
442 ys = "447688BA 94708EB6 E2E4D59F 6AB6D7ED FF9301D2 49FE49C3 3096655F 5D502FAD"
443 "3D383B91 C5E7EDAA 2B714CC9 9D5743CA";
444 zs = "0BEB6466 34BA8773 5D77AE48 09A0EBEA 865535DE 4C1E1DCB 692E8470 8E81A5AF"
445 "62E528C3 8B2A81B3 5309668D 73524D9F";
446 ctx->digest = hash_string (&nettle_sha384, "abc");
447 ctx->digest_size = 48;
448 break;
449 case 521:
450 ecc = &_nettle_secp_521r1;
451 xs = "0151518F 1AF0F563 517EDD54 85190DF9 5A4BF57B 5CBA4CF2 A9A3F647 4725A35F"
452 "7AFE0A6D DEB8BEDB CD6A197E 592D4018 8901CECD 650699C9 B5E456AE A5ADD190"
453 "52A8";
454 ys = "006F3B14 2EA1BFFF 7E2837AD 44C9E4FF 6D2D34C7 3184BBAD 90026DD5 E6E85317"
455 "D9DF45CA D7803C6C 20035B2F 3FF63AFF 4E1BA64D 1C077577 DA3F4286 C58F0AEA"
456 "E643";
457 zs = "0065FDA3 409451DC AB0A0EAD 45495112 A3D813C1 7BFD34BD F8C1209D 7DF58491"
458 "20597779 060A7FF9 D704ADF7 8B570FFA D6F062E9 5C7E0C5D 5481C5B1 53B48B37"
459 "5FA1";
460
461 ctx->digest = hash_string (&nettle_sha512, "abc");
462 ctx->digest_size = 64;
463 break;
464 default:
465 die ("Internal error.\n");
466 }
467 ecc_point_init (&ctx->pub, ecc);
468 ecc_scalar_init (&ctx->key, ecc);
469
470 mpz_init_set_str (x, xs, 16);
471 mpz_init_set_str (y, ys, 16);
472 mpz_init_set_str (z, zs, 16);
473
474 ecc_point_set (&ctx->pub, x, y);
475 ecc_scalar_set (&ctx->key, z);
476
477 mpz_clear (x);
478 mpz_clear (y);
479 mpz_clear (z);
480
481 ecdsa_sign (&ctx->key,
482 &ctx->rctx, (nettle_random_func *) knuth_lfib_random,
483 ctx->digest_size, ctx->digest,
484 &ctx->s);
485
486 return ctx;
487 }
488
489 static void
bench_ecdsa_sign(void * p)490 bench_ecdsa_sign (void *p)
491 {
492 struct ecdsa_ctx *ctx = p;
493 struct dsa_signature s;
494
495 dsa_signature_init (&s);
496 ecdsa_sign (&ctx->key,
497 &ctx->rctx, (nettle_random_func *) knuth_lfib_random,
498 ctx->digest_size, ctx->digest,
499 &s);
500 dsa_signature_clear (&s);
501 }
502
503 static void
bench_ecdsa_verify(void * p)504 bench_ecdsa_verify (void *p)
505 {
506 struct ecdsa_ctx *ctx = p;
507 if (! ecdsa_verify (&ctx->pub,
508 ctx->digest_size, ctx->digest,
509 &ctx->s))
510 die ("Internal error, _ecdsa_verify failed.\n");
511 }
512
513 static void
bench_ecdsa_clear(void * p)514 bench_ecdsa_clear (void *p)
515 {
516 struct ecdsa_ctx *ctx = p;
517
518 ecc_point_clear (&ctx->pub);
519 ecc_scalar_clear (&ctx->key);
520 dsa_signature_clear (&ctx->s);
521 free (ctx->digest);
522
523 free (ctx);
524 }
525
526 #if WITH_OPENSSL
527 struct openssl_rsa_ctx
528 {
529 RSA *key;
530 unsigned char *ref;
531 unsigned char *signature;
532 unsigned int siglen;
533 uint8_t *digest;
534 };
535
536 static struct openssl_rsa_ctx*
make_openssl_rsa_ctx(unsigned size)537 make_openssl_rsa_ctx (unsigned size)
538 {
539 struct openssl_rsa_ctx *ctx = xalloc (sizeof (*ctx));
540 BIGNUM *e = BN_new();
541 BN_set_word(e, 65537);
542 ctx->key = RSA_new();
543 RSA_generate_key_ex (ctx->key, size, e, NULL);
544 ctx->ref = xalloc (RSA_size (ctx->key));
545 ctx->signature = xalloc (RSA_size (ctx->key));
546 ctx->digest = hash_string (&nettle_sha1, "foo");
547
548 if (! RSA_sign (NID_sha1, ctx->digest, SHA1_DIGEST_SIZE,
549 ctx->ref, &ctx->siglen, ctx->key))
550 die ("OpenSSL RSA_sign failed.\n");
551
552 BN_free(e);
553 return ctx;
554 }
555
556 static void *
bench_openssl_rsa_init(unsigned size)557 bench_openssl_rsa_init (unsigned size)
558 {
559 struct openssl_rsa_ctx *ctx = make_openssl_rsa_ctx (size);
560 RSA_blinding_off(ctx->key);
561 return ctx;
562 }
563
564 static void *
bench_openssl_rsa_tr_init(unsigned size)565 bench_openssl_rsa_tr_init (unsigned size)
566 {
567 return make_openssl_rsa_ctx (size);
568 }
569
570 static void
bench_openssl_rsa_sign(void * p)571 bench_openssl_rsa_sign (void *p)
572 {
573 const struct openssl_rsa_ctx *ctx = p;
574 unsigned siglen;
575
576 if (! RSA_sign (NID_sha1, ctx->digest, SHA1_DIGEST_SIZE,
577 ctx->signature, &siglen, ctx->key))
578 die ("OpenSSL RSA_sign failed.\n");
579 }
580
581 static void
bench_openssl_rsa_verify(void * p)582 bench_openssl_rsa_verify (void *p)
583 {
584 const struct openssl_rsa_ctx *ctx = p;
585 if (! RSA_verify (NID_sha1, ctx->digest, SHA1_DIGEST_SIZE,
586 ctx->ref, ctx->siglen, ctx->key))
587 die ("OpenSSL RSA_verify failed.\n");
588 }
589
590 static void
bench_openssl_rsa_clear(void * p)591 bench_openssl_rsa_clear (void *p)
592 {
593 struct openssl_rsa_ctx *ctx = p;
594 RSA_free (ctx->key);
595 free (ctx->ref);
596 free (ctx->signature);
597 free (ctx->digest);
598 free (ctx);
599 }
600
601 struct openssl_ecdsa_ctx
602 {
603 EC_KEY *key;
604 ECDSA_SIG *signature;
605 unsigned digest_length;
606 uint8_t *digest;
607 };
608
609 static void *
bench_openssl_ecdsa_init(unsigned size)610 bench_openssl_ecdsa_init (unsigned size)
611 {
612 struct openssl_ecdsa_ctx *ctx = xalloc (sizeof (*ctx));
613
614 switch (size)
615 {
616 case 192:
617 ctx->key = EC_KEY_new_by_curve_name (NID_X9_62_prime192v1);
618 ctx->digest_length = 24; /* truncated */
619 ctx->digest = hash_string (&nettle_sha224, "abc");
620 break;
621 case 224:
622 ctx->key = EC_KEY_new_by_curve_name (NID_secp224r1);
623 ctx->digest_length = SHA224_DIGEST_SIZE;
624 ctx->digest = hash_string (&nettle_sha224, "abc");
625 break;
626 case 256:
627 ctx->key = EC_KEY_new_by_curve_name (NID_X9_62_prime256v1);
628 ctx->digest_length = SHA256_DIGEST_SIZE;
629 ctx->digest = hash_string (&nettle_sha256, "abc");
630 break;
631 case 384:
632 ctx->key = EC_KEY_new_by_curve_name (NID_secp384r1);
633 ctx->digest_length = SHA384_DIGEST_SIZE;
634 ctx->digest = hash_string (&nettle_sha384, "abc");
635 break;
636 case 521:
637 ctx->key = EC_KEY_new_by_curve_name (NID_secp521r1);
638 ctx->digest_length = SHA512_DIGEST_SIZE;
639 ctx->digest = hash_string (&nettle_sha512, "abc");
640 break;
641 default:
642 die ("Internal error.\n");
643 }
644
645 /* This curve isn't supported in this build of openssl */
646 if (ctx->key == NULL)
647 {
648 free(ctx);
649 return NULL;
650 }
651
652 if (!EC_KEY_generate_key( ctx->key))
653 die ("Openssl EC_KEY_generate_key failed.\n");
654
655 ctx->signature = ECDSA_do_sign (ctx->digest, ctx->digest_length, ctx->key);
656
657 return ctx;
658 }
659
660 static void
bench_openssl_ecdsa_sign(void * p)661 bench_openssl_ecdsa_sign (void *p)
662 {
663 const struct openssl_ecdsa_ctx *ctx = p;
664 ECDSA_SIG *sig = ECDSA_do_sign (ctx->digest, ctx->digest_length, ctx->key);
665 ECDSA_SIG_free (sig);
666 }
667
668 static void
bench_openssl_ecdsa_verify(void * p)669 bench_openssl_ecdsa_verify (void *p)
670 {
671 const struct openssl_ecdsa_ctx *ctx = p;
672 if (ECDSA_do_verify (ctx->digest, ctx->digest_length,
673 ctx->signature, ctx->key) != 1)
674 die ("Openssl ECDSA_do_verify failed.\n");
675 }
676 static void
bench_openssl_ecdsa_clear(void * p)677 bench_openssl_ecdsa_clear (void *p)
678 {
679 struct openssl_ecdsa_ctx *ctx = p;
680 ECDSA_SIG_free (ctx->signature);
681 EC_KEY_free (ctx->key);
682 free (ctx->digest);
683 free (ctx);
684 }
685 #endif
686
687 struct curve25519_ctx
688 {
689 uint8_t x[CURVE25519_SIZE];
690 uint8_t s[CURVE25519_SIZE];
691 };
692
693 static void
bench_curve25519_mul_g(void * p)694 bench_curve25519_mul_g (void *p)
695 {
696 struct curve25519_ctx *ctx = p;
697 uint8_t q[CURVE25519_SIZE];
698 curve25519_mul_g (q, ctx->s);
699 }
700
701 static void
bench_curve25519_mul(void * p)702 bench_curve25519_mul (void *p)
703 {
704 struct curve25519_ctx *ctx = p;
705 uint8_t q[CURVE25519_SIZE];
706 curve25519_mul (q, ctx->s, ctx->x);
707 }
708
709 static void
bench_curve25519(void)710 bench_curve25519 (void)
711 {
712 double mul_g;
713 double mul;
714 struct knuth_lfib_ctx lfib;
715 struct curve25519_ctx ctx;
716 knuth_lfib_init (&lfib, 2);
717
718 knuth_lfib_random (&lfib, sizeof(ctx.s), ctx.s);
719 curve25519_mul_g (ctx.x, ctx.s);
720
721 mul_g = time_function (bench_curve25519_mul_g, &ctx);
722 mul = time_function (bench_curve25519_mul, &ctx);
723
724 printf("%16s %4d %9.4f %9.4f\n",
725 "curve25519", 255, 1e-3/mul_g, 1e-3/mul);
726 }
727
728 struct alg alg_list[] = {
729 { "rsa", 1024, bench_rsa_init, bench_rsa_sign, bench_rsa_verify, bench_rsa_clear },
730 { "rsa", 2048, bench_rsa_init, bench_rsa_sign, bench_rsa_verify, bench_rsa_clear },
731 { "rsa-tr", 1024, bench_rsa_init, bench_rsa_sign_tr, bench_rsa_verify, bench_rsa_clear },
732 { "rsa-tr", 2048, bench_rsa_init, bench_rsa_sign_tr, bench_rsa_verify, bench_rsa_clear },
733 #if WITH_OPENSSL
734 { "rsa (openssl)", 1024, bench_openssl_rsa_init, bench_openssl_rsa_sign, bench_openssl_rsa_verify, bench_openssl_rsa_clear },
735 { "rsa (openssl)", 2048, bench_openssl_rsa_init, bench_openssl_rsa_sign, bench_openssl_rsa_verify, bench_openssl_rsa_clear },
736 { "rsa-tr (openssl)", 1024, bench_openssl_rsa_tr_init, bench_openssl_rsa_sign, bench_openssl_rsa_verify, bench_openssl_rsa_clear },
737 { "rsa-tr (openssl)", 2048, bench_openssl_rsa_tr_init, bench_openssl_rsa_sign, bench_openssl_rsa_verify, bench_openssl_rsa_clear },
738 #endif
739 { "dsa", 1024, bench_dsa_init, bench_dsa_sign, bench_dsa_verify, bench_dsa_clear },
740 #if 0
741 { "dsa",2048, bench_dsa_init, bench_dsa_sign, bench_dsa_verify, bench_dsa_clear },
742 #endif
743 { "ecdsa", 192, bench_ecdsa_init, bench_ecdsa_sign, bench_ecdsa_verify, bench_ecdsa_clear },
744 { "ecdsa", 224, bench_ecdsa_init, bench_ecdsa_sign, bench_ecdsa_verify, bench_ecdsa_clear },
745 { "ecdsa", 256, bench_ecdsa_init, bench_ecdsa_sign, bench_ecdsa_verify, bench_ecdsa_clear },
746 { "ecdsa", 384, bench_ecdsa_init, bench_ecdsa_sign, bench_ecdsa_verify, bench_ecdsa_clear },
747 { "ecdsa", 521, bench_ecdsa_init, bench_ecdsa_sign, bench_ecdsa_verify, bench_ecdsa_clear },
748 #if WITH_OPENSSL
749 { "ecdsa (openssl)", 192, bench_openssl_ecdsa_init, bench_openssl_ecdsa_sign, bench_openssl_ecdsa_verify, bench_openssl_ecdsa_clear },
750 { "ecdsa (openssl)", 224, bench_openssl_ecdsa_init, bench_openssl_ecdsa_sign, bench_openssl_ecdsa_verify, bench_openssl_ecdsa_clear },
751 { "ecdsa (openssl)", 256, bench_openssl_ecdsa_init, bench_openssl_ecdsa_sign, bench_openssl_ecdsa_verify, bench_openssl_ecdsa_clear },
752 { "ecdsa (openssl)", 384, bench_openssl_ecdsa_init, bench_openssl_ecdsa_sign, bench_openssl_ecdsa_verify, bench_openssl_ecdsa_clear },
753 { "ecdsa (openssl)", 521, bench_openssl_ecdsa_init, bench_openssl_ecdsa_sign, bench_openssl_ecdsa_verify, bench_openssl_ecdsa_clear },
754 #endif
755 };
756
757 #define numberof(x) (sizeof (x) / sizeof ((x)[0]))
758
759 int
main(int argc,char ** argv)760 main (int argc, char **argv)
761 {
762 const char *filter = NULL;
763 unsigned i;
764
765 if (argc > 1)
766 filter = argv[1];
767
768 time_init();
769 printf ("%16s %4s %9s %9s\n",
770 "name", "size", "sign/ms", "verify/ms");
771
772 for (i = 0; i < numberof(alg_list); i++)
773 if (!filter || strstr (alg_list[i].name, filter))
774 bench_alg (&alg_list[i]);
775
776 if (!filter || strstr("curve25519", filter))
777 bench_curve25519();
778
779 return EXIT_SUCCESS;
780 }
781