diff options
author | Werner Koch <wk@gnupg.org> | 2013-09-07 10:06:46 +0200 |
---|---|---|
committer | Werner Koch <wk@gnupg.org> | 2013-09-25 10:08:57 +0200 |
commit | 64a7d347847d606eb5f4c156e24ba060271b8f6b (patch) | |
tree | 63735c97112206ed17a2e8823b60df4749794109 | |
parent | 1f5f4452e5bca105ec2197a4facbf9778e7dc31e (diff) | |
download | libgcrypt-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>
-rw-r--r-- | cipher/ecc-common.h | 2 | ||||
-rw-r--r-- | cipher/ecc-curves.c | 140 | ||||
-rw-r--r-- | cipher/ecc-misc.c | 21 | ||||
-rw-r--r-- | mpi/ec.c | 126 | ||||
-rw-r--r-- | src/ec-context.h | 15 | ||||
-rw-r--r-- | src/mpi.h | 2 |
6 files changed, 185 insertions, 121 deletions
diff --git a/cipher/ecc-common.h b/cipher/ecc-common.h index e806059b..031994a3 100644 --- a/cipher/ecc-common.h +++ b/cipher/ecc-common.h @@ -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*/ 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; +} diff --git a/cipher/ecc-misc.c b/cipher/ecc-misc.c index f8db81a8..1dc0480f 100644 --- a/cipher/ecc-misc.c +++ b/cipher/ecc-misc.c @@ -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; +} @@ -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); } diff --git a/src/ec-context.h b/src/ec-context.h index f2ad19b4..fdfbc0a3 100644 --- a/src/ec-context.h +++ b/src/ec-context.h @@ -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*/ @@ -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); |