summaryrefslogtreecommitdiff
path: root/cipher/ecc-curves.c
diff options
context:
space:
mode:
authorWerner Koch <wk@gnupg.org>2013-09-07 10:06:46 +0200
committerWerner Koch <wk@gnupg.org>2013-09-25 10:08:57 +0200
commit64a7d347847d606eb5f4c156e24ba060271b8f6b (patch)
tree63735c97112206ed17a2e8823b60df4749794109 /cipher/ecc-curves.c
parent1f5f4452e5bca105ec2197a4facbf9778e7dc31e (diff)
downloadlibgcrypt-64a7d347847d606eb5f4c156e24ba060271b8f6b.tar.gz
ecc: Refactor low-level access functions.
* 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>
Diffstat (limited to 'cipher/ecc-curves.c')
-rw-r--r--cipher/ecc-curves.c140
1 files changed, 140 insertions, 0 deletions
diff --git a/cipher/ecc-curves.c b/cipher/ecc-curves.c
index 49c0959c..e6a993f2 100644
--- a/cipher/ecc-curves.c
+++ b/cipher/ecc-curves.c
@@ -270,6 +270,23 @@ static const ecc_domain_parms_t domain_parms[] =
+/* 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;
+}