~ubuntu-branches/ubuntu/wily/nettle/wily

« back to all changes in this revision

Viewing changes to examples/hogweed-benchmark.c

  • Committer: Package Import Robot
  • Author(s): Magnus Holmgren
  • Date: 2013-05-07 22:57:14 UTC
  • mfrom: (8.1.8 sid)
  • Revision ID: package-import@ubuntu.com-20130507225714-s331yr8ov53dtt17
Tags: 2.7-2
Tag some (ECC related) symbols that only exist on some architectures.

Show diffs side-by-side

added added

removed removed

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