3 /* nettle, low-level cryptographics library
5 * Copyright (C) 2013 Niels Möller
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.
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.
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,
23 /* Development of Nettle's ECC support was funded by the .SE Internet Fund. */
41 #include "../ecc-internal.h"
42 #include "../gmp-glue.h"
44 #define BENCH_INTERVAL 0.1
46 static void NORETURN
PRINTF_STYLE(1,2)
47 die(const char *format
, ...)
50 va_start(args
, format
);
51 vfprintf(stderr
, format
, args
);
60 void *p
= malloc (size
);
63 fprintf (stderr
, "Virtual memory exhausted\n");
70 xalloc_limbs (mp_size_t size
)
72 return xalloc (size
* sizeof(mp_limb_t
));
75 /* Returns second per function call */
77 time_function(void (*f
)(void *arg
), void *arg
)
89 for (i
= 0; i
< ncalls
; i
++)
92 if (elapsed
> BENCH_INTERVAL
)
94 else if (elapsed
< BENCH_INTERVAL
/ 10)
99 return elapsed
/ ncalls
;
103 modinv_gcd (const struct ecc_curve
*ecc
,
104 mp_limb_t
*rp
, mp_limb_t
*ap
, mp_limb_t
*tp
)
106 mp_size_t size
= ecc
->size
;
108 mp_limb_t
*vp
= tp
+ size
+1;
109 mp_limb_t
*gp
= tp
+ 2*(size
+1);
110 mp_limb_t
*sp
= tp
+ 3*(size
+1);
113 mpn_copyi (up
, ap
, size
);
114 mpn_copyi (vp
, ecc
->p
, size
);
115 gn
= mpn_gcdext (gp
, sp
, &sn
, up
, size
, vp
, size
);
116 if (gn
!= 1 || gp
[0] != 1)
120 mpn_sub (sp
, ecc
->p
, size
, sp
, -sn
);
123 mpn_zero (sp
+ sn
, size
- sn
);
125 mpn_copyi (rp
, sp
, size
);
130 const struct ecc_curve
*ecc
;
140 struct ecc_ctx
*ctx
= (struct ecc_ctx
*) p
;
141 mpn_copyi (ctx
->rp
, ctx
->ap
, 2*ctx
->ecc
->size
);
142 ctx
->ecc
->modp (ctx
->ecc
, ctx
->rp
);
148 struct ecc_ctx
*ctx
= (struct ecc_ctx
*) p
;
149 mpn_copyi (ctx
->rp
, ctx
->ap
, 2*ctx
->ecc
->size
);
150 ctx
->ecc
->redc (ctx
->ecc
, ctx
->rp
);
156 struct ecc_ctx
*ctx
= (struct ecc_ctx
*) p
;
157 mpn_copyi (ctx
->rp
, ctx
->ap
, 2*ctx
->ecc
->size
);
158 ctx
->ecc
->modq (ctx
->ecc
, ctx
->rp
);
162 bench_modinv (void *p
)
164 struct ecc_ctx
*ctx
= (struct ecc_ctx
*) p
;
165 mpn_copyi (ctx
->rp
+ ctx
->ecc
->size
, ctx
->ap
, ctx
->ecc
->size
);
166 ecc_modp_inv (ctx
->ecc
, ctx
->rp
, ctx
->rp
+ ctx
->ecc
->size
, ctx
->tp
);
170 bench_modinv_gcd (void *p
)
172 struct ecc_ctx
*ctx
= (struct ecc_ctx
*) p
;
173 mpn_copyi (ctx
->rp
+ ctx
->ecc
->size
, ctx
->ap
, ctx
->ecc
->size
);
174 modinv_gcd (ctx
->ecc
, ctx
->rp
, ctx
->rp
+ ctx
->ecc
->size
, ctx
->tp
);
178 bench_dup_jj (void *p
)
180 struct ecc_ctx
*ctx
= (struct ecc_ctx
*) p
;
181 ecc_dup_jj (ctx
->ecc
, ctx
->rp
, ctx
->ap
, ctx
->tp
);
185 bench_add_jja (void *p
)
187 struct ecc_ctx
*ctx
= (struct ecc_ctx
*) p
;
188 ecc_add_jja (ctx
->ecc
, ctx
->rp
, ctx
->ap
, ctx
->bp
, ctx
->tp
);
192 bench_add_jjj (void *p
)
194 struct ecc_ctx
*ctx
= (struct ecc_ctx
*) p
;
195 ecc_add_jjj (ctx
->ecc
, ctx
->rp
, ctx
->ap
, ctx
->bp
, ctx
->tp
);
199 bench_mul_g (void *p
)
201 struct ecc_ctx
*ctx
= (struct ecc_ctx
*) p
;
202 ecc_mul_g (ctx
->ecc
, ctx
->rp
, ctx
->ap
, ctx
->tp
);
206 bench_mul_a (void *p
)
208 struct ecc_ctx
*ctx
= (struct ecc_ctx
*) p
;
209 ecc_mul_a (ctx
->ecc
, 1, ctx
->rp
, ctx
->ap
, ctx
->bp
, ctx
->tp
);
213 bench_curve (const struct ecc_curve
*ecc
)
216 double modp
, redc
, modq
, modinv
, modinv_gcd
,
217 dup_jj
, add_jja
, add_jjj
,
223 ctx
.rp
= xalloc_limbs (3*ecc
->size
);
224 ctx
.ap
= xalloc_limbs (3*ecc
->size
);
225 ctx
.bp
= xalloc_limbs (3*ecc
->size
);
226 ctx
.tp
= xalloc_limbs (ECC_MUL_A_ITCH (ecc
->size
));
228 mpn_random (ctx
.ap
, 3*ecc
->size
);
229 mpn_random (ctx
.bp
, 3*ecc
->size
);
231 mask
= (~(mp_limb_t
) 0) >> (ecc
->size
* GMP_NUMB_BITS
- ecc
->bit_size
);
232 ctx
.ap
[ecc
->size
- 1] &= mask
;
233 ctx
.ap
[2*ecc
->size
- 1] &= mask
;
234 ctx
.ap
[3*ecc
->size
- 1] &= mask
;
235 ctx
.bp
[ecc
->size
- 1] &= mask
;
236 ctx
.bp
[2*ecc
->size
- 1] &= mask
;
237 ctx
.bp
[3*ecc
->size
- 1] &= mask
;
239 modp
= time_function (bench_modp
, &ctx
);
240 redc
= ecc
->redc
? time_function (bench_redc
, &ctx
) : 0;
242 modq
= time_function (bench_modq
, &ctx
);
244 modinv
= time_function (bench_modinv
, &ctx
);
245 modinv_gcd
= time_function (bench_modinv_gcd
, &ctx
);
246 dup_jj
= time_function (bench_dup_jj
, &ctx
);
247 add_jja
= time_function (bench_add_jja
, &ctx
);
248 add_jjj
= time_function (bench_add_jjj
, &ctx
);
249 mul_g
= time_function (bench_mul_g
, &ctx
);
250 mul_a
= time_function (bench_mul_a
, &ctx
);
257 printf ("%4d %6.4f %6.4f %6.4f %6.2f %6.3f %6.3f %6.3f %6.3f %6.1f %6.1f\n",
258 ecc
->bit_size
, 1e6
* modp
, 1e6
* redc
, 1e6
* modq
,
259 1e6
* modinv
, 1e6
* modinv_gcd
,
260 1e6
* dup_jj
, 1e6
* add_jja
, 1e6
* add_jjj
,
261 1e6
* mul_g
, 1e6
* mul_a
);
264 const struct ecc_curve
* const curves
[] = {
272 #define numberof(x) (sizeof (x) / sizeof ((x)[0]))
275 main (int argc UNUSED
, char **argv UNUSED
)
280 printf ("%4s %6s %6s %6s %6s %6s %6s %6s %6s %6s %6s (us)\n",
281 "size", "modp", "redc", "modq", "modinv", "mi_gcd",
282 "dup_jj", "ad_jja", "ad_jjj",
284 for (i
= 0; i
< numberof (curves
); i
++)
285 bench_curve (curves
[i
]);