* mpi/ec.c (montgomery_mul_point, mpi_ec_mul_point_lli): Factor out
from _gcry_mpi_ec_mul_point.
(_gcry_mpi_ec_mul_point): Use montgomery_mul_point and
mpi_ec_mul_point_lli.

Signed-off-by: NIIBE Yutaka <gni...@fsij.org>
---
 mpi/ec.c | 331 +++++++++++++++++++++++++++++--------------------------
 1 file changed, 175 insertions(+), 156 deletions(-)

diff --git a/mpi/ec.c b/mpi/ec.c
index 3cfe11c6..4e24d817 100644
--- a/mpi/ec.c
+++ b/mpi/ec.c
@@ -1744,6 +1744,156 @@ _gcry_mpi_ec_sub_points (mpi_point_t result,
 }
 
 
+/* Compute scalar point multiplication with Montgomery Ladder.
+   Note that we don't use Y-coordinate in the points at all.
+   RESULT->Y will be filled by zero.  */
+static void
+montgomery_mul_point (mpi_point_t result,
+                      gcry_mpi_t scalar, mpi_point_t point,
+                      mpi_ec_t ctx)
+{
+  unsigned int nbits;
+  int j;
+  gcry_mpi_t z1;
+  mpi_point_struct p1, p2;
+  mpi_point_struct p1_, p2_;
+  mpi_point_t q1, q2, prd, sum;
+  unsigned long sw;
+  mpi_size_t rsize;
+  int scalar_copied = 0;
+
+  nbits = mpi_get_nbits (scalar);
+  point_init (&p1);
+  point_init (&p2);
+  point_init (&p1_);
+  point_init (&p2_);
+  mpi_set_ui (p1.x, 1);
+  mpi_free (p2.x);
+  p2.x  = mpi_copy (point->x);
+  mpi_set_ui (p2.z, 1);
+
+  if (mpi_is_opaque (scalar))
+    {
+      const unsigned int pbits = ctx->nbits;
+      gcry_mpi_t a;
+      unsigned int n;
+      unsigned char *raw;
+
+      scalar_copied = 1;
+
+      raw = _gcry_mpi_get_opaque_copy (scalar, &n);
+      if ((n+7)/8 != (pbits+7)/8)
+        log_fatal ("scalar size (%d) != prime size (%d)\n",
+                   (n+7)/8, (pbits+7)/8);
+
+      reverse_buffer (raw, (n+7)/8);
+      if ((pbits % 8))
+        raw[0] &= (1 << (pbits % 8)) - 1;
+      raw[0] |= (1 << ((pbits + 7) % 8));
+      raw[(pbits+7)/8 - 1] &= (256 - ctx->h);
+      a = mpi_is_secure (scalar) ? mpi_snew (pbits): mpi_new (pbits);
+      _gcry_mpi_set_buffer (a, raw, (n+7)/8, 0);
+      xfree (raw);
+
+      scalar = a;
+    }
+
+  mpi_point_resize (&p1, ctx);
+  mpi_point_resize (&p2, ctx);
+  mpi_point_resize (&p1_, ctx);
+  mpi_point_resize (&p2_, ctx);
+
+  mpi_resize (point->x, ctx->p->nlimbs);
+  point->x->nlimbs = ctx->p->nlimbs;
+
+  q1 = &p1;
+  q2 = &p2;
+  prd = &p1_;
+  sum = &p2_;
+
+  for (j=nbits-1; j >= 0; j--)
+    {
+      mpi_point_t t;
+
+      sw = mpi_test_bit (scalar, j);
+      point_swap_cond (q1, q2, sw, ctx);
+      montgomery_ladder (prd, sum, q1, q2, point->x, ctx);
+      point_swap_cond (prd, sum, sw, ctx);
+      t = q1;  q1 = prd;  prd = t;
+      t = q2;  q2 = sum;  sum = t;
+    }
+
+  mpi_clear (result->y);
+  sw = (nbits & 1);
+  point_swap_cond (&p1, &p1_, sw, ctx);
+
+  rsize = p1.z->nlimbs;
+  MPN_NORMALIZE (p1.z->d, rsize);
+  if (rsize == 0)
+    {
+      mpi_set_ui (result->x, 1);
+      mpi_set_ui (result->z, 0);
+    }
+  else
+    {
+      z1 = mpi_new (0);
+      ec_invm (z1, p1.z, ctx);
+      ec_mulm (result->x, p1.x, z1, ctx);
+      mpi_set_ui (result->z, 1);
+      mpi_free (z1);
+    }
+
+  point_free (&p1);
+  point_free (&p2);
+  point_free (&p1_);
+  point_free (&p2_);
+  if (scalar_copied)
+    _gcry_mpi_release (scalar);
+}
+
+
+/* Compute scalar point multiplication, Least Leak Intended.  */
+static void
+mpi_ec_mul_point_lli (mpi_point_t result,
+                      gcry_mpi_t scalar, mpi_point_t point,
+                      mpi_ec_t ctx)
+{
+  unsigned int nbits;
+  int j;
+  mpi_point_struct tmppnt;
+
+  if (mpi_cmp (scalar, ctx->p) >= 0)
+    nbits = mpi_get_nbits (scalar);
+  else
+    nbits = mpi_get_nbits (ctx->p);
+
+  if (ctx->model == MPI_EC_WEIERSTRASS)
+    {
+      mpi_set_ui (result->x, 1);
+      mpi_set_ui (result->y, 1);
+      mpi_set_ui (result->z, 0);
+    }
+  else
+    {
+      mpi_set_ui (result->x, 0);
+      mpi_set_ui (result->y, 1);
+      mpi_set_ui (result->z, 1);
+      mpi_point_resize (point, ctx);
+    }
+
+  point_init (&tmppnt);
+  mpi_point_resize (result, ctx);
+  mpi_point_resize (&tmppnt, ctx);
+  for (j=nbits-1; j >= 0; j--)
+    {
+      _gcry_mpi_ec_dup_point (result, result, ctx);
+      _gcry_mpi_ec_add_points (&tmppnt, result, point, ctx);
+      point_swap_cond (result, &tmppnt, mpi_test_bit (scalar, j), ctx);
+    }
+  point_free (&tmppnt);
+}
+
+
 /* Scalar point multiplication - the main function for ECC.  It takes
    an integer SCALAR and a POINT as well as the usual context CTX.
    RESULT will be set to the resulting point. */
@@ -1764,176 +1914,45 @@ _gcry_mpi_ec_mul_point (mpi_point_t result,
       return;
     }
 
-  if (ctx->model == MPI_EC_EDWARDS
-      || (ctx->model == MPI_EC_WEIERSTRASS
-          && mpi_is_secure (scalar)))
+  if (ctx->model == MPI_EC_MONTGOMERY)
     {
-      /* Simple left to right binary method.  Algorithm 3.27 from
-       * {author={Hankerson, Darrel and Menezes, Alfred J. and Vanstone, Scott},
-       *  title = {Guide to Elliptic Curve Cryptography},
-       *  year = {2003}, isbn = {038795273X},
-       *  url = {http://www.cacr.math.uwaterloo.ca/ecc/},
-       *  publisher = {Springer-Verlag New York, Inc.}} */
-      unsigned int nbits;
-      int j;
-
-      if (mpi_cmp (scalar, ctx->p) >= 0)
-        nbits = mpi_get_nbits (scalar);
-      else
-        nbits = mpi_get_nbits (ctx->p);
-
-      if (ctx->model == MPI_EC_WEIERSTRASS)
-        {
-          mpi_set_ui (result->x, 1);
-          mpi_set_ui (result->y, 1);
-          mpi_set_ui (result->z, 0);
-        }
-      else
-        {
-          mpi_set_ui (result->x, 0);
-          mpi_set_ui (result->y, 1);
-          mpi_set_ui (result->z, 1);
-          mpi_point_resize (point, ctx);
-        }
-
-      if (mpi_is_secure (scalar))
-        {
-          /* If SCALAR is in secure memory we assume that it is the
-             secret key we use constant time operation.  */
-          mpi_point_struct tmppnt;
-
-          point_init (&tmppnt);
-          mpi_point_resize (result, ctx);
-          mpi_point_resize (&tmppnt, ctx);
-          for (j=nbits-1; j >= 0; j--)
-            {
-              _gcry_mpi_ec_dup_point (result, result, ctx);
-              _gcry_mpi_ec_add_points (&tmppnt, result, point, ctx);
-              point_swap_cond (result, &tmppnt, mpi_test_bit (scalar, j), ctx);
-            }
-          point_free (&tmppnt);
-        }
-      else
-        {
-          if (ctx->model == MPI_EC_EDWARDS)
-            {
-              mpi_point_resize (result, ctx);
-              mpi_point_resize (point, ctx);
-            }
-
-          for (j=nbits-1; j >= 0; j--)
-            {
-              _gcry_mpi_ec_dup_point (result, result, ctx);
-              if (mpi_test_bit (scalar, j))
-                _gcry_mpi_ec_add_points (result, result, point, ctx);
-            }
-        }
+      montgomery_mul_point (result, scalar, point, ctx);
+      return;
+    }
+  else if (mpi_is_secure (scalar))
+    {
+      mpi_ec_mul_point_lli (result, scalar, point, ctx);
       return;
     }
-  else if (ctx->model == MPI_EC_MONTGOMERY)
+  else if (ctx->model == MPI_EC_EDWARDS)
     {
-      unsigned int nbits;
       int j;
-      mpi_point_struct p1_, p2_;
-      mpi_point_t q1, q2, prd, sum;
-      unsigned long sw;
-      mpi_size_t rsize;
-      int scalar_copied = 0;
-
-      /* Compute scalar point multiplication with Montgomery Ladder.
-         Note that we don't use Y-coordinate in the points at all.
-         RESULT->Y will be filled by zero.  */
-
-      nbits = mpi_get_nbits (scalar);
-      point_init (&p1);
-      point_init (&p2);
-      point_init (&p1_);
-      point_init (&p2_);
-      mpi_set_ui (p1.x, 1);
-      mpi_free (p2.x);
-      p2.x  = mpi_copy (point->x);
-      mpi_set_ui (p2.z, 1);
-
-      if (mpi_is_opaque (scalar))
-        {
-          const unsigned int pbits = ctx->nbits;
-          gcry_mpi_t a;
-          unsigned int n;
-          unsigned char *raw;
-
-          scalar_copied = 1;
-
-          raw = _gcry_mpi_get_opaque_copy (scalar, &n);
-          if ((n+7)/8 != (pbits+7)/8)
-            log_fatal ("scalar size (%d) != prime size (%d)\n",
-                       (n+7)/8, (pbits+7)/8);
-
-          reverse_buffer (raw, (n+7)/8);
-          if ((pbits % 8))
-            raw[0] &= (1 << (pbits % 8)) - 1;
-          raw[0] |= (1 << ((pbits + 7) % 8));
-          raw[(pbits+7)/8 - 1] &= (256 - ctx->h);
-          a = mpi_is_secure (scalar) ? mpi_snew (pbits): mpi_new (pbits);
-          _gcry_mpi_set_buffer (a, raw, (n+7)/8, 0);
-          xfree (raw);
-
-          scalar = a;
-        }
+      unsigned int nbits = mpi_get_nbits (scalar);
 
-      mpi_point_resize (&p1, ctx);
-      mpi_point_resize (&p2, ctx);
-      mpi_point_resize (&p1_, ctx);
-      mpi_point_resize (&p2_, ctx);
+      mpi_set_ui (result->x, 0);
+      mpi_set_ui (result->y, 1);
+      mpi_set_ui (result->z, 1);
 
-      mpi_resize (point->x, ctx->p->nlimbs);
-      point->x->nlimbs = ctx->p->nlimbs;
-
-      q1 = &p1;
-      q2 = &p2;
-      prd = &p1_;
-      sum = &p2_;
+      mpi_point_resize (result, ctx);
+      mpi_point_resize (point, ctx);
 
+      /* Simple left to right binary method.  Algorithm 3.27 from
+       * {author={Hankerson, Darrel and Menezes, Alfred J. and Vanstone, Scott},
+       *  title = {Guide to Elliptic Curve Cryptography},
+       *  year = {2003}, isbn = {038795273X},
+       *  url = {http://www.cacr.math.uwaterloo.ca/ecc/},
+       *  publisher = {Springer-Verlag New York, Inc.}} */
       for (j=nbits-1; j >= 0; j--)
         {
-          mpi_point_t t;
-
-          sw = mpi_test_bit (scalar, j);
-          point_swap_cond (q1, q2, sw, ctx);
-          montgomery_ladder (prd, sum, q1, q2, point->x, ctx);
-          point_swap_cond (prd, sum, sw, ctx);
-          t = q1;  q1 = prd;  prd = t;
-          t = q2;  q2 = sum;  sum = t;
-        }
-
-      mpi_clear (result->y);
-      sw = (nbits & 1);
-      point_swap_cond (&p1, &p1_, sw, ctx);
-
-      rsize = p1.z->nlimbs;
-      MPN_NORMALIZE (p1.z->d, rsize);
-      if (rsize == 0)
-        {
-          mpi_set_ui (result->x, 1);
-          mpi_set_ui (result->z, 0);
+          _gcry_mpi_ec_dup_point (result, result, ctx);
+          if (mpi_test_bit (scalar, j))
+            _gcry_mpi_ec_add_points (result, result, point, ctx);
         }
-      else
-        {
-          z1 = mpi_new (0);
-          ec_invm (z1, p1.z, ctx);
-          ec_mulm (result->x, p1.x, z1, ctx);
-          mpi_set_ui (result->z, 1);
-          mpi_free (z1);
-        }
-
-      point_free (&p1);
-      point_free (&p2);
-      point_free (&p1_);
-      point_free (&p2_);
-      if (scalar_copied)
-        _gcry_mpi_release (scalar);
       return;
     }
 
+  /* The case of Weierstrass curve.  */
+
   x1 = mpi_alloc_like (ctx->p);
   y1 = mpi_alloc_like (ctx->p);
   h  = mpi_alloc_like (ctx->p);
_______________________________________________
Gcrypt-devel mailing list
Gcrypt-devel@gnupg.org
https://lists.gnupg.org/mailman/listinfo/gcrypt-devel

Reply via email to