ecc: Refactor low-level access functions.
authorWerner Koch <wk@gnupg.org>
Sat, 7 Sep 2013 08:06:46 +0000 (10:06 +0200)
committerWerner Koch <wk@gnupg.org>
Wed, 25 Sep 2013 08:08:57 +0000 (10:08 +0200)
* mpi/ec.c (point_copy): Move to cipher/ecc-curves.c.
(ec_get_reset): Rename to _gcry_mpi_ec_get_reset and make global.
(_gcry_mpi_ec_get_mpi): Factor most code out to _gcry_ecc_get_mpi.
(_gcry_mpi_ec_get_point): Factor most code out to _gcry_ecc_get_point.
(_gcry_mpi_ec_set_mpi): Factor most code out to _gcry_ecc_set_mpi.
(_gcry_mpi_ec_set_point): Factor most code out to _gcry_ecc_set_point.
* cipher/ecc-curves.c (_gcry_ecc_get_mpi): New.
(_gcry_ecc_get_point, _gcry_ecc_set_mpi, _gcry_ecc_set_point): New.
* cipher/ecc-misc.c (_gcry_ecc_compute_public): New.

Signed-off-by: Werner Koch <wk@gnupg.org>
cipher/ecc-common.h
cipher/ecc-curves.c
cipher/ecc-misc.c
mpi/ec.c
src/ec-context.h
src/mpi.h

index e806059..031994a 100644 (file)
@@ -82,5 +82,7 @@ const char *_gcry_ecc_dialect2str (enum ecc_dialects dialect);
 gcry_mpi_t   _gcry_ecc_ec2os (gcry_mpi_t x, gcry_mpi_t y, gcry_mpi_t p);
 gcry_error_t _gcry_ecc_os2ec (mpi_point_t result, gcry_mpi_t value);
 
+mpi_point_t  _gcry_ecc_compute_public (mpi_point_t Q, mpi_ec_t ec);
+
 
 #endif /*GCRY_ECC_COMMON_H*/
index 49c0959..e6a993f 100644 (file)
@@ -270,6 +270,23 @@ static const ecc_domain_parms_t domain_parms[] =
 
 
 \f
+/* Return a copy of POINT.  */
+static gcry_mpi_point_t
+point_copy (gcry_mpi_point_t point)
+{
+  gcry_mpi_point_t newpoint;
+
+  if (point)
+    {
+      newpoint = gcry_mpi_point_new (0);
+      point_set (newpoint, point);
+    }
+  else
+    newpoint = NULL;
+  return newpoint;
+}
+
+
 /* Helper to scan a hex string. */
 static gcry_mpi_t
 scanval (const char *string)
@@ -787,3 +804,126 @@ _gcry_ecc_get_param_sexp (const char *name)
 
   return result;
 }
+
+
+/* Return an MPI (or opaque MPI) described by NAME and the context EC.
+   If COPY is true a copy is returned, if not a const MPI may be
+   returned.  In any case mpi_free must be used.  */
+gcry_mpi_t
+_gcry_ecc_get_mpi (const char *name, mpi_ec_t ec, int copy)
+{
+  if (!strcmp (name, "p") && ec->p)
+    return mpi_is_const (ec->p) && !copy? ec->p : mpi_copy (ec->p);
+  if (!strcmp (name, "a") && ec->a)
+    return mpi_is_const (ec->a) && !copy? ec->a : mpi_copy (ec->a);
+  if (!strcmp (name, "b") && ec->b)
+    return mpi_is_const (ec->b) && !copy? ec->b : mpi_copy (ec->b);
+  if (!strcmp (name, "n") && ec->n)
+    return mpi_is_const (ec->n) && !copy? ec->n : mpi_copy (ec->n);
+  if (!strcmp (name, "d") && ec->d)
+    return mpi_is_const (ec->d) && !copy? ec->d : mpi_copy (ec->d);
+
+  /* Return a requested point coordinate.  */
+  if (!strcmp (name, "g.x") && ec->G && ec->G->x)
+    return mpi_is_const (ec->G->x) && !copy? ec->G->x : mpi_copy (ec->G->x);
+  if (!strcmp (name, "g.y") && ec->G && ec->G->y)
+    return mpi_is_const (ec->G->y) && !copy? ec->G->y : mpi_copy (ec->G->y);
+  if (!strcmp (name, "q.x") && ec->Q && ec->Q->x)
+    return mpi_is_const (ec->Q->x) && !copy? ec->Q->x : mpi_copy (ec->Q->x);
+  if (!strcmp (name, "q.y") && ec->Q && ec->Q->y)
+    return mpi_is_const (ec->G->y) && !copy? ec->Q->y : mpi_copy (ec->Q->y);
+
+  /* If a point has been requested, return it in standard encoding.  */
+  if (!strcmp (name, "g") && ec->G)
+    return _gcry_mpi_ec_ec2os (ec->G, ec);
+  if (!strcmp (name, "q"))
+    {
+      /* If only the private key is given, compute the public key.  */
+      if (!ec->Q)
+        ec->Q = _gcry_ecc_compute_public (NULL, ec);
+
+      if (ec->Q)
+        return _gcry_mpi_ec_ec2os (ec->Q, ec);
+    }
+
+  return NULL;
+}
+
+
+/* Return a point described by NAME and the context EC.  */
+gcry_mpi_point_t
+_gcry_ecc_get_point (const char *name, mpi_ec_t ec)
+{
+  if (!strcmp (name, "g") && ec->G)
+    return point_copy (ec->G);
+  if (!strcmp (name, "q"))
+    {
+      /* If only the private key is given, compute the public key.  */
+      if (!ec->Q)
+        ec->Q = _gcry_ecc_compute_public (NULL, ec);
+
+      if (ec->Q)
+        return point_copy (ec->Q);
+    }
+
+  return NULL;
+}
+
+
+/* Store the MPI NEWVALUE into the context EC under NAME. */
+gpg_err_code_t
+_gcry_ecc_set_mpi (const char *name, gcry_mpi_t newvalue, mpi_ec_t ec)
+{
+  if (!strcmp (name, "p"))
+    {
+      mpi_free (ec->p);
+      ec->p = mpi_copy (newvalue);
+      _gcry_mpi_ec_get_reset (ec);
+    }
+  else if (!strcmp (name, "a"))
+    {
+      mpi_free (ec->a);
+      ec->a = mpi_copy (newvalue);
+      _gcry_mpi_ec_get_reset (ec);
+    }
+  else if (!strcmp (name, "b"))
+    {
+      mpi_free (ec->b);
+      ec->b = mpi_copy (newvalue);
+    }
+  else if (!strcmp (name, "n"))
+    {
+      mpi_free (ec->n);
+      ec->n = mpi_copy (newvalue);
+    }
+  else if (!strcmp (name, "d"))
+    {
+      mpi_free (ec->d);
+      ec->d = mpi_copy (newvalue);
+    }
+  else
+    return GPG_ERR_UNKNOWN_NAME;
+
+  return 0;
+}
+
+
+/* Store the point NEWVALUE into the context EC under NAME.  */
+gpg_err_code_t
+_gcry_ecc_set_point (const char *name, gcry_mpi_point_t newvalue, mpi_ec_t ec)
+{
+  if (!strcmp (name, "g"))
+    {
+      gcry_mpi_point_release (ec->G);
+      ec->G = point_copy (newvalue);
+    }
+  else if (!strcmp (name, "q"))
+    {
+      gcry_mpi_point_release (ec->Q);
+      ec->Q = point_copy (newvalue);
+    }
+  else
+    return GPG_ERR_UNKNOWN_NAME;
+
+  return 0;
+}
index f8db81a..1dc0480 100644 (file)
@@ -232,3 +232,24 @@ _gcry_ecc_os2ec (mpi_point_t result, gcry_mpi_t value)
 
   return 0;
 }
+
+
+/* Compute the public key from the the context EC.  Obviously a
+   requirement is that the secret key is available in EC.  On success
+   Q is returned; on error NULL.  If Q is NULL a newly allocated pint
+   is returned.  */
+mpi_point_t
+_gcry_ecc_compute_public (mpi_point_t Q, mpi_ec_t ec)
+{
+  if (!ec->d || !ec->G || !ec->p || !ec->a)
+    return NULL;
+  if (ec->model == MPI_EC_TWISTEDEDWARDS && !ec->b)
+    return NULL;
+
+  if (!Q)
+    Q = gcry_mpi_point_new (0);
+  if (!Q)
+    return NULL;
+  _gcry_mpi_ec_mul_point (Q, ec->d, ec->G, ec);
+  return Q;
+}
index e52facd..883d8f6 100644 (file)
--- a/mpi/ec.c
+++ b/mpi/ec.c
@@ -132,23 +132,6 @@ point_set (mpi_point_t d, mpi_point_t s)
 }
 
 
-/* Return a copy of POINT.  */
-static gcry_mpi_point_t
-point_copy (gcry_mpi_point_t point)
-{
-  gcry_mpi_point_t newpoint;
-
-  if (point)
-    {
-      newpoint = gcry_mpi_point_new (0);
-      point_set (newpoint, point);
-    }
-  else
-    newpoint = NULL;
-  return newpoint;
-}
-
-
 /* Set the projective coordinates from POINT into X, Y, and Z.  If a
    coordinate is not required, X, Y, or Z may be passed as NULL.  */
 void
@@ -396,8 +379,8 @@ ec_invm (gcry_mpi_t x, gcry_mpi_t a, mpi_ec_t ctx)
 
 
 /* Force recomputation of all helper variables.  */
-static void
-ec_get_reset (mpi_ec_t ec)
+void
+_gcry_mpi_ec_get_reset (mpi_ec_t ec)
 {
   ec->t.valid.a_is_pminus3 = 0;
   ec->t.valid.two_inv_p = 0;
@@ -458,7 +441,7 @@ ec_p_init (mpi_ec_t ctx, enum gcry_mpi_ec_models model,
   if (b && model == MPI_EC_TWISTEDEDWARDS)
     ctx->b = mpi_copy (b);
 
-  ec_get_reset (ctx);
+  _gcry_mpi_ec_get_reset (ctx);
 
   /* Allocate scratch variables.  */
   for (i=0; i< DIM(ctx->t.scratch); i++)
@@ -590,44 +573,7 @@ _gcry_mpi_ec_get_mpi (const char *name, gcry_ctx_t ctx, int copy)
 {
   mpi_ec_t ec = _gcry_ctx_get_pointer (ctx, CONTEXT_TYPE_EC);
 
-  if (!strcmp (name, "p") && ec->p)
-    return mpi_is_const (ec->p) && !copy? ec->p : mpi_copy (ec->p);
-  if (!strcmp (name, "a") && ec->a)
-    return mpi_is_const (ec->a) && !copy? ec->a : mpi_copy (ec->a);
-  if (!strcmp (name, "b") && ec->b)
-    return mpi_is_const (ec->b) && !copy? ec->b : mpi_copy (ec->b);
-  if (!strcmp (name, "n") && ec->n)
-    return mpi_is_const (ec->n) && !copy? ec->n : mpi_copy (ec->n);
-  if (!strcmp (name, "d") && ec->d)
-    return mpi_is_const (ec->d) && !copy? ec->d : mpi_copy (ec->d);
-
-  /* Return a requested point coordinate.  */
-  if (!strcmp (name, "g.x") && ec->G && ec->G->x)
-    return mpi_is_const (ec->G->x) && !copy? ec->G->x : mpi_copy (ec->G->x);
-  if (!strcmp (name, "g.y") && ec->G && ec->G->y)
-    return mpi_is_const (ec->G->y) && !copy? ec->G->y : mpi_copy (ec->G->y);
-  if (!strcmp (name, "q.x") && ec->Q && ec->Q->x)
-    return mpi_is_const (ec->Q->x) && !copy? ec->Q->x : mpi_copy (ec->Q->x);
-  if (!strcmp (name, "q.y") && ec->Q && ec->Q->y)
-    return mpi_is_const (ec->G->y) && !copy? ec->Q->y : mpi_copy (ec->Q->y);
-
-  /* If a point has been requested, return it in standard encoding.  */
-  if (!strcmp (name, "g") && ec->G)
-    return _gcry_mpi_ec_ec2os (ec->G, ec);
-  if (!strcmp (name, "q"))
-    {
-      /* If only the private key is given, compute the public key.  */
-      if (!ec->Q && ec->d && ec->G && ec->p && ec->a)
-        {
-          ec->Q = gcry_mpi_point_new (0);
-          _gcry_mpi_ec_mul_point (ec->Q, ec->d, ec->G, ec);
-        }
-
-      if (ec->Q)
-        return _gcry_mpi_ec_ec2os (ec->Q, ec);
-    }
-
-  return NULL;
+  return _gcry_ecc_get_mpi (name, ec, copy);
 }
 
 
@@ -638,22 +584,7 @@ _gcry_mpi_ec_get_point (const char *name, gcry_ctx_t ctx, int copy)
 
   (void)copy;  /* Not used.  */
 
-  if (!strcmp (name, "g") && ec->G)
-    return point_copy (ec->G);
-  if (!strcmp (name, "q"))
-    {
-      /* If only the private key is given, compute the public key.  */
-      if (!ec->Q && ec->d && ec->G && ec->p && ec->a)
-        {
-          ec->Q = gcry_mpi_point_new (0);
-          _gcry_mpi_ec_mul_point (ec->Q, ec->d, ec->G, ec);
-        }
-
-      if (ec->Q)
-        return point_copy (ec->Q);
-    }
-
-  return NULL;
+  return _gcry_ecc_get_point (name, ec);
 }
 
 
@@ -663,37 +594,7 @@ _gcry_mpi_ec_set_mpi (const char *name, gcry_mpi_t newvalue,
 {
   mpi_ec_t ec = _gcry_ctx_get_pointer (ctx, CONTEXT_TYPE_EC);
 
-  if (!strcmp (name, "p"))
-    {
-      mpi_free (ec->p);
-      ec->p = mpi_copy (newvalue);
-      ec_get_reset (ec);
-    }
-  else if (!strcmp (name, "a"))
-    {
-      mpi_free (ec->a);
-      ec->a = mpi_copy (newvalue);
-      ec_get_reset (ec);
-    }
-  else if (!strcmp (name, "b"))
-    {
-      mpi_free (ec->b);
-      ec->b = mpi_copy (newvalue);
-    }
-  else if (!strcmp (name, "n"))
-    {
-      mpi_free (ec->n);
-      ec->n = mpi_copy (newvalue);
-    }
-  else if (!strcmp (name, "d"))
-    {
-      mpi_free (ec->d);
-      ec->d = mpi_copy (newvalue);
-    }
-  else
-    return GPG_ERR_UNKNOWN_NAME;
-
-  return 0;
+  return _gcry_ecc_set_mpi (name, newvalue, ec);
 }
 
 
@@ -703,20 +604,7 @@ _gcry_mpi_ec_set_point (const char *name, gcry_mpi_point_t newvalue,
 {
   mpi_ec_t ec = _gcry_ctx_get_pointer (ctx, CONTEXT_TYPE_EC);
 
-  if (!strcmp (name, "g"))
-    {
-      gcry_mpi_point_release (ec->G);
-      ec->G = point_copy (newvalue);
-    }
-  else if (!strcmp (name, "q"))
-    {
-      gcry_mpi_point_release (ec->Q);
-      ec->Q = point_copy (newvalue);
-    }
-  else
-    return GPG_ERR_UNKNOWN_NAME;
-
-  return 0;
+  return _gcry_ecc_set_point (name, newvalue, ec);
 }
 
 
index f2ad19b..fdfbc0a 100644 (file)
@@ -62,5 +62,20 @@ struct mpi_ec_ctx_s
 };
 
 
+/*-- mpi/ec.c --*/
+void _gcry_mpi_ec_get_reset (mpi_ec_t ec);
+
+
+/*-- cipher/ecc-curves.c --*/
+gpg_err_code_t   _gcry_mpi_ec_new (gcry_ctx_t *r_ctx,
+                                   gcry_sexp_t keyparam, const char *curvename);
+
+gcry_mpi_t       _gcry_ecc_get_mpi (const char *name, mpi_ec_t ec, int copy);
+gcry_mpi_point_t _gcry_ecc_get_point (const char *name, mpi_ec_t ec);
+gpg_err_code_t   _gcry_ecc_set_mpi (const char *name,
+                                    gcry_mpi_t newvalue, mpi_ec_t ec);
+gpg_err_code_t   _gcry_ecc_set_point (const char *name,
+                                      gcry_mpi_point_t newvalue, mpi_ec_t ec);
+
 
 #endif /*GCRY_EC_CONTEXT_H*/
index 3466951..279c485 100644 (file)
--- a/src/mpi.h
+++ b/src/mpi.h
@@ -333,8 +333,6 @@ int  _gcry_mpi_ec_curve_point (gcry_mpi_point_t point, mpi_ec_t ctx);
 
 gcry_mpi_t _gcry_mpi_ec_ec2os (gcry_mpi_point_t point, mpi_ec_t ectx);
 
-gpg_err_code_t _gcry_mpi_ec_new (gcry_ctx_t *r_ctx,
-                                 gcry_sexp_t keyparam, const char *curvename);
 gcry_mpi_t _gcry_mpi_ec_get_mpi (const char *name, gcry_ctx_t ctx, int copy);
 gcry_mpi_point_t _gcry_mpi_ec_get_point (const char *name,
                                          gcry_ctx_t ctx, int copy);