Revert "Merge branch 'upstream' into tizen"
[platform/upstream/nettle.git] / examples / ecc-benchmark.c
index 15df4c7..1faf6dc 100644 (file)
@@ -1,33 +1,24 @@
-/* ecc-benchmark.c
-
-   Copyright (C) 2013 Niels Möller
-
-   This file is part of GNU Nettle.
-
-   GNU Nettle is free software: you can redistribute it and/or
-   modify it under the terms of either:
-
-     * the GNU Lesser General Public License as published by the Free
-       Software Foundation; either version 3 of the License, or (at your
-       option) any later version.
-
-   or
-
-     * the GNU General Public License as published by the Free
-       Software Foundation; either version 2 of the License, or (at your
-       option) any later version.
-
-   or both in parallel, as here.
-
-   GNU Nettle is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-   General Public License for more details.
-
-   You should have received copies of the GNU General Public License and
-   the GNU Lesser General Public License along with this program.  If
-   not, see http://www.gnu.org/licenses/.
-*/
+/* ecc-benchmark.c */
+
+/* nettle, low-level cryptographics library
+ *
+ * Copyright (C) 2013 Niels Möller
+ *
+ * The nettle library is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or (at your
+ * option) any later version.
+ *
+ * The nettle library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
+ * License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with the nettle library; see the file COPYING.LIB.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02111-1301, USA.
+ */
 
 /* Development of Nettle's ECC support was funded by the .SE Internet Fund. */
 
@@ -108,12 +99,11 @@ time_function(void (*f)(void *arg), void *arg)
   return elapsed / ncalls;
 }
 
-#if !NETTLE_USE_MINI_GMP
 static int
 modinv_gcd (const struct ecc_curve *ecc,
            mp_limb_t *rp, mp_limb_t *ap, mp_limb_t *tp)
 {
-  mp_size_t size = ecc->p.size;
+  mp_size_t size = ecc->size;
   mp_limb_t *up = tp;
   mp_limb_t *vp = tp + size+1;
   mp_limb_t *gp = tp + 2*(size+1);
@@ -121,13 +111,13 @@ modinv_gcd (const struct ecc_curve *ecc,
   mp_size_t gn, sn;
 
   mpn_copyi (up, ap, size);
-  mpn_copyi (vp, ecc->p.m, size);
+  mpn_copyi (vp, ecc->p, size);
   gn = mpn_gcdext (gp, sp, &sn, up, size, vp, size);
   if (gn != 1 || gp[0] != 1)
     return 0;
   
   if (sn < 0)
-    mpn_sub (sp, ecc->p.m, size, sp, -sn);
+    mpn_sub (sp, ecc->p, size, sp, -sn);
   else if (sn < size)
     /* Zero-pad. */
     mpn_zero (sp + sn, size - sn);
@@ -135,7 +125,6 @@ modinv_gcd (const struct ecc_curve *ecc,
   mpn_copyi (rp, sp, size);
   return 1;
 }
-#endif
 
 struct ecc_ctx {
   const struct ecc_curve *ecc;
@@ -149,57 +138,41 @@ static void
 bench_modp (void *p)
 {
   struct ecc_ctx *ctx = (struct ecc_ctx *) p;
-  mpn_copyi (ctx->rp, ctx->ap, 2*ctx->ecc->p.size);
-  ctx->ecc->p.mod (&ctx->ecc->p, ctx->rp);
+  mpn_copyi (ctx->rp, ctx->ap, 2*ctx->ecc->size);
+  ctx->ecc->modp (ctx->ecc, ctx->rp);
 }
 
 static void
-bench_reduce (void *p)
+bench_redc (void *p)
 {
   struct ecc_ctx *ctx = (struct ecc_ctx *) p;
-  mpn_copyi (ctx->rp, ctx->ap, 2*ctx->ecc->p.size);
-  ctx->ecc->p.reduce (&ctx->ecc->p, ctx->rp);
+  mpn_copyi (ctx->rp, ctx->ap, 2*ctx->ecc->size);
+  ctx->ecc->redc (ctx->ecc, ctx->rp);
 }
 
 static void
 bench_modq (void *p)
 {
   struct ecc_ctx *ctx = (struct ecc_ctx *) p;
-  mpn_copyi (ctx->rp, ctx->ap, 2*ctx->ecc->p.size);
-  ctx->ecc->q.mod(&ctx->ecc->q, ctx->rp);
+  mpn_copyi (ctx->rp, ctx->ap, 2*ctx->ecc->size);
+  ctx->ecc->modq (ctx->ecc, ctx->rp);
 }
 
 static void
 bench_modinv (void *p)
 {
   struct ecc_ctx *ctx = (struct ecc_ctx *) p;
-  ctx->ecc->p.invert (&ctx->ecc->p, ctx->rp, ctx->ap, ctx->tp);
+  mpn_copyi (ctx->rp + ctx->ecc->size, ctx->ap, ctx->ecc->size);
+  ecc_modp_inv (ctx->ecc, ctx->rp, ctx->rp + ctx->ecc->size, ctx->tp);
 }
 
-#if !NETTLE_USE_MINI_GMP
 static void
 bench_modinv_gcd (void *p)
 {
   struct ecc_ctx *ctx = (struct ecc_ctx *) p;
-  mpn_copyi (ctx->rp + ctx->ecc->p.size, ctx->ap, ctx->ecc->p.size);
-  modinv_gcd (ctx->ecc, ctx->rp, ctx->rp + ctx->ecc->p.size, ctx->tp);  
+  mpn_copyi (ctx->rp + ctx->ecc->size, ctx->ap, ctx->ecc->size);
+  modinv_gcd (ctx->ecc, ctx->rp, ctx->rp + ctx->ecc->size, ctx->tp);  
 }
-#endif
-
-#ifdef mpn_sec_powm
-static void
-bench_modinv_powm (void *p)
-{
-  struct ecc_ctx *ctx = (struct ecc_ctx *) p;
-  const struct ecc_curve *ecc = ctx->ecc;
-  mp_size_t size = ecc->p.size;
-  
-  mpn_sub_1 (ctx->rp + size, ecc->p.m, size, 2);
-  mpn_sec_powm (ctx->rp, ctx->ap, size,
-               ctx->rp + size, ecc->p.bit_size,
-               ecc->p.m, size, ctx->tp);
-}
-#endif
 
 static void
 bench_dup_jj (void *p)
@@ -216,115 +189,63 @@ bench_add_jja (void *p)
 }
 
 static void
-bench_add_hhh (void *p)
+bench_add_jjj (void *p)
 {
   struct ecc_ctx *ctx = (struct ecc_ctx *) p;
-  ctx->ecc->add_hhh (ctx->ecc, ctx->rp, ctx->ap, ctx->bp, ctx->tp);
+  ecc_add_jjj (ctx->ecc, ctx->rp, ctx->ap, ctx->bp, ctx->tp);
 }
 
 static void
 bench_mul_g (void *p)
 {
   struct ecc_ctx *ctx = (struct ecc_ctx *) p;
-  ctx->ecc->mul_g (ctx->ecc, ctx->rp, ctx->ap, ctx->tp);
+  ecc_mul_g (ctx->ecc, ctx->rp, ctx->ap, ctx->tp);
 }
 
 static void
 bench_mul_a (void *p)
 {
   struct ecc_ctx *ctx = (struct ecc_ctx *) p;
-  ctx->ecc->mul (ctx->ecc, ctx->rp, ctx->ap, ctx->bp, ctx->tp);
-}
-
-static void
-bench_dup_eh (void *p)
-{
-  struct ecc_ctx *ctx = (struct ecc_ctx *) p;
-  ecc_dup_eh (ctx->ecc, ctx->rp, ctx->ap, ctx->tp);
+  ecc_mul_a (ctx->ecc, 1, ctx->rp, ctx->ap, ctx->bp, ctx->tp);
 }
 
 static void
-bench_add_eh (void *p)
-{
-  struct ecc_ctx *ctx = (struct ecc_ctx *) p;
-  ecc_add_eh (ctx->ecc, ctx->rp, ctx->ap, ctx->bp, ctx->tp);
-}
-
-#if NETTLE_USE_MINI_GMP
-static void
-mpn_random (mp_limb_t *xp, mp_size_t n)
-{
-  mp_size_t i;
-  for (i = 0; i < n; i++)
-    xp[i] = rand();
-}
-#endif
-
-static void
 bench_curve (const struct ecc_curve *ecc)
 {
   struct ecc_ctx ctx;  
-  double modp, reduce, modq, modinv, modinv_gcd, modinv_powm,
-    dup_jj, add_jja, add_hhh,
+  double modp, redc, modq, modinv, modinv_gcd,
+    dup_jj, add_jja, add_jjj,
     mul_g, mul_a;
 
   mp_limb_t mask;
-  mp_size_t itch;
 
   ctx.ecc = ecc;
-  ctx.rp = xalloc_limbs (3*ecc->p.size);
-  ctx.ap = xalloc_limbs (3*ecc->p.size);
-  ctx.bp = xalloc_limbs (3*ecc->p.size);
-  itch = ecc->mul_itch;
-#ifdef mpn_sec_powm
-  {
-    mp_size_t powm_itch
-      = mpn_sec_powm_itch (ecc->p.size, ecc->p.bit_size, ecc->p.size);
-    if (powm_itch > itch)
-      itch = powm_itch;
-  }
-#endif
-  ctx.tp = xalloc_limbs (itch);
-
-  mpn_random (ctx.ap, 3*ecc->p.size);
-  mpn_random (ctx.bp, 3*ecc->p.size);
-
-  mask = (~(mp_limb_t) 0) >> (ecc->p.size * GMP_NUMB_BITS - ecc->p.bit_size);
-  ctx.ap[ecc->p.size - 1] &= mask;
-  ctx.ap[2*ecc->p.size - 1] &= mask;
-  ctx.ap[3*ecc->p.size - 1] &= mask;
-  ctx.bp[ecc->p.size - 1] &= mask;
-  ctx.bp[2*ecc->p.size - 1] &= mask;
-  ctx.bp[3*ecc->p.size - 1] &= mask;
+  ctx.rp = xalloc_limbs (3*ecc->size);
+  ctx.ap = xalloc_limbs (3*ecc->size);
+  ctx.bp = xalloc_limbs (3*ecc->size);
+  ctx.tp = xalloc_limbs (ECC_MUL_A_ITCH (ecc->size));
+
+  mpn_random (ctx.ap, 3*ecc->size);
+  mpn_random (ctx.bp, 3*ecc->size);
+
+  mask = (~(mp_limb_t) 0) >> (ecc->size * GMP_NUMB_BITS - ecc->bit_size);
+  ctx.ap[ecc->size - 1] &= mask;
+  ctx.ap[2*ecc->size - 1] &= mask;
+  ctx.ap[3*ecc->size - 1] &= mask;
+  ctx.bp[ecc->size - 1] &= mask;
+  ctx.bp[2*ecc->size - 1] &= mask;
+  ctx.bp[3*ecc->size - 1] &= mask;
 
   modp = time_function (bench_modp, &ctx);
-  reduce = time_function (bench_reduce, &ctx);
+  redc = ecc->redc ? time_function (bench_redc, &ctx) : 0;
 
   modq = time_function (bench_modq, &ctx);
 
   modinv = time_function (bench_modinv, &ctx);
-#if !NETTLE_USE_MINI_GMP
   modinv_gcd = time_function (bench_modinv_gcd, &ctx);
-#else
-  modinv_gcd = 0;
-#endif
-#ifdef mpn_sec_powm
-  modinv_powm = time_function (bench_modinv_powm, &ctx);
-#else
-  modinv_powm = 0;
-#endif
-  if (ecc->p.bit_size == 255)
-    {
-      /* For now, curve25519 is a special case */
-      dup_jj = time_function (bench_dup_eh, &ctx);
-      add_jja = time_function (bench_add_eh, &ctx);
-    }
-  else
-    {
-      dup_jj = time_function (bench_dup_jj, &ctx);
-      add_jja = time_function (bench_add_jja, &ctx);
-    }
-  add_hhh = time_function (bench_add_hhh, &ctx);
+  dup_jj = time_function (bench_dup_jj, &ctx);
+  add_jja = time_function (bench_add_jja, &ctx);
+  add_jjj = time_function (bench_add_jjj, &ctx);
   mul_g = time_function (bench_mul_g, &ctx);
   mul_a = time_function (bench_mul_a, &ctx);
 
@@ -333,17 +254,16 @@ bench_curve (const struct ecc_curve *ecc)
   free (ctx.bp);
   free (ctx.tp);
 
-  printf ("%4d %6.4f %6.4f %6.4f %6.2f %6.3f %6.2f %6.3f %6.3f %6.3f %6.1f %6.1f\n",
-         ecc->p.bit_size, 1e6 * modp, 1e6 * reduce, 1e6 * modq,
-         1e6 * modinv, 1e6 * modinv_gcd, 1e6 * modinv_powm,
-         1e6 * dup_jj, 1e6 * add_jja, 1e6 * add_hhh,
+  printf ("%4d %6.4f %6.4f %6.4f %6.2f %6.3f %6.3f %6.3f %6.3f %6.1f %6.1f\n",
+         ecc->bit_size, 1e6 * modp, 1e6 * redc, 1e6 * modq,
+         1e6 * modinv, 1e6 * modinv_gcd,
+         1e6 * dup_jj, 1e6 * add_jja, 1e6 * add_jjj,
          1e6 * mul_g, 1e6 * mul_a);
 }
 
 const struct ecc_curve * const curves[] = {
   &nettle_secp_192r1,
   &nettle_secp_224r1,
-  &_nettle_curve25519,
   &nettle_secp_256r1,
   &nettle_secp_384r1,
   &nettle_secp_521r1,
@@ -357,9 +277,9 @@ main (int argc UNUSED, char **argv UNUSED)
   unsigned i;
 
   time_init();
-  printf ("%4s %6s %6s %6s %6s %6s %6s %6s %6s %6s %6s %6s (us)\n",
-         "size", "modp", "reduce", "modq", "modinv", "mi_gcd", "mi_pow",
-         "dup_jj", "ad_jja", "ad_hhh",
+  printf ("%4s %6s %6s %6s %6s %6s %6s %6s %6s %6s %6s (us)\n",
+         "size", "modp", "redc", "modq", "modinv", "mi_gcd",
+         "dup_jj", "ad_jja", "ad_jjj",
          "mul_g", "mul_a");
   for (i = 0; i < numberof (curves); i++)
     bench_curve (curves[i]);