diff options
author | Werner Koch <wk@gnupg.org> | 2013-08-29 21:37:30 +0200 |
---|---|---|
committer | Werner Koch <wk@gnupg.org> | 2013-08-30 15:10:28 +0200 |
commit | 800d4e01376d52a94a157b53978c7c3f957fc476 (patch) | |
tree | 729aa54f2b501dedabacb3eed100ab3b668aedf9 /cipher/ecc-misc.c | |
parent | 040aa7688296e93659cb32ca31e9a001a6ab1edd (diff) | |
download | libgcrypt-800d4e01376d52a94a157b53978c7c3f957fc476.tar.gz |
Refactor the ECC code into 3 files.
* cipher/ecc-common.h, cipher/ecc-curves.c, cipher/ecc-misc.c: New.
* cipher/Makefile.am (EXTRA_libcipher_la_SOURCES): Add new files.
* configure.ac (GCRYPT_PUBKEY_CIPHERS): Add new .c files.
* cipher/ecc.c (curve_aliases, ecc_domain_parms_t, domain_parms)
(scanval): Move to ecc-curves.c.
(fill_in_curve): Move to ecc-curve.c as _gcry_ecc_fill_in_curve.
(ecc_get_curve): Move to ecc-curve.c as _gcry_ecc_get_curve.
(_gcry_mpi_ec_ec2os): Move to ecc-misc.c.
(ec2os): Move to ecc-misc.c as _gcry_ecc_ec2os.
(os2ec): Move to ecc-misc.c as _gcry_ecc_os2ec.
(point_set): Move as inline function to ecc-common.h.
(_gcry_ecc_curve_free): Move to ecc-misc.c as _gcry_ecc_curve_free.
(_gcry_ecc_curve_copy): Move to ecc-misc.c as _gcry_ecc_curve_copy.
(mpi_from_keyparam, point_from_keyparam): Move to ecc-curves.c.
(_gcry_mpi_ec_new): Move to ecc-curves.c.
(ecc_get_param): Move to ecc-curves.c as _gcry_ecc_get_param.
(ecc_get_param_sexp): Move to ecc-curves.c as _gcry_ecc_get_param_sexp.
Signed-off-by: Werner Koch <wk@gnupg.org>
Diffstat (limited to 'cipher/ecc-misc.c')
-rw-r--r-- | cipher/ecc-misc.c | 183 |
1 files changed, 183 insertions, 0 deletions
diff --git a/cipher/ecc-misc.c b/cipher/ecc-misc.c new file mode 100644 index 00000000..5e06bef9 --- /dev/null +++ b/cipher/ecc-misc.c @@ -0,0 +1,183 @@ +/* ecc-misc.c - Elliptic Curve miscellaneous functions + * Copyright (C) 2007, 2008, 2010, 2011 Free Software Foundation, Inc. + * Copyright (C) 2013 g10 Code GmbH + * + * This file is part of Libgcrypt. + * + * Libgcrypt 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. + * + * Libgcrypt 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 this program; if not, see <http://www.gnu.org/licenses/>. + */ + +#include <config.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <errno.h> + +#include "g10lib.h" +#include "mpi.h" +#include "context.h" +#include "ec-context.h" +#include "ecc-common.h" + + +/* + * Release a curve object. + */ +void +_gcry_ecc_curve_free (elliptic_curve_t *E) +{ + mpi_free (E->p); E->p = NULL; + mpi_free (E->a); E->a = NULL; + mpi_free (E->b); E->b = NULL; + _gcry_mpi_point_free_parts (&E->G); + mpi_free (E->n); E->n = NULL; +} + + +/* + * Return a copy of a curve object. + */ +elliptic_curve_t +_gcry_ecc_curve_copy (elliptic_curve_t E) +{ + elliptic_curve_t R; + + R.p = mpi_copy (E.p); + R.a = mpi_copy (E.a); + R.b = mpi_copy (E.b); + _gcry_mpi_point_init (&R.G); + point_set (&R.G, &E.G); + R.n = mpi_copy (E.n); + + return R; +} + + +gcry_mpi_t +_gcry_ecc_ec2os (gcry_mpi_t x, gcry_mpi_t y, gcry_mpi_t p) +{ + gpg_error_t err; + int pbytes = (mpi_get_nbits (p)+7)/8; + size_t n; + unsigned char *buf, *ptr; + gcry_mpi_t result; + + buf = gcry_xmalloc ( 1 + 2*pbytes ); + *buf = 04; /* Uncompressed point. */ + ptr = buf+1; + err = gcry_mpi_print (GCRYMPI_FMT_USG, ptr, pbytes, &n, x); + if (err) + log_fatal ("mpi_print failed: %s\n", gpg_strerror (err)); + if (n < pbytes) + { + memmove (ptr+(pbytes-n), ptr, n); + memset (ptr, 0, (pbytes-n)); + } + ptr += pbytes; + err = gcry_mpi_print (GCRYMPI_FMT_USG, ptr, pbytes, &n, y); + if (err) + log_fatal ("mpi_print failed: %s\n", gpg_strerror (err)); + if (n < pbytes) + { + memmove (ptr+(pbytes-n), ptr, n); + memset (ptr, 0, (pbytes-n)); + } + + err = gcry_mpi_scan (&result, GCRYMPI_FMT_USG, buf, 1+2*pbytes, NULL); + if (err) + log_fatal ("mpi_scan failed: %s\n", gpg_strerror (err)); + gcry_free (buf); + + return result; +} + + +/* Convert POINT into affine coordinates using the context CTX and + return a newly allocated MPI. If the conversion is not possible + NULL is returned. This function won't print an error message. */ +gcry_mpi_t +_gcry_mpi_ec_ec2os (gcry_mpi_point_t point, mpi_ec_t ectx) +{ + gcry_mpi_t g_x, g_y, result; + + g_x = mpi_new (0); + g_y = mpi_new (0); + if (_gcry_mpi_ec_get_affine (g_x, g_y, point, ectx)) + result = NULL; + else + result = _gcry_ecc_ec2os (g_x, g_y, ectx->p); + mpi_free (g_x); + mpi_free (g_y); + + return result; +} + + +/* RESULT must have been initialized and is set on success to the + point given by VALUE. */ +gcry_error_t +_gcry_ecc_os2ec (mpi_point_t result, gcry_mpi_t value) +{ + gcry_error_t err; + size_t n; + unsigned char *buf; + gcry_mpi_t x, y; + + n = (mpi_get_nbits (value)+7)/8; + buf = gcry_xmalloc (n); + err = gcry_mpi_print (GCRYMPI_FMT_USG, buf, n, &n, value); + if (err) + { + gcry_free (buf); + return err; + } + if (n < 1) + { + gcry_free (buf); + return GPG_ERR_INV_OBJ; + } + if (*buf != 4) + { + gcry_free (buf); + return GPG_ERR_NOT_IMPLEMENTED; /* No support for point compression. */ + } + if ( ((n-1)%2) ) + { + gcry_free (buf); + return GPG_ERR_INV_OBJ; + } + n = (n-1)/2; + err = gcry_mpi_scan (&x, GCRYMPI_FMT_USG, buf+1, n, NULL); + if (err) + { + gcry_free (buf); + return err; + } + err = gcry_mpi_scan (&y, GCRYMPI_FMT_USG, buf+1+n, n, NULL); + gcry_free (buf); + if (err) + { + mpi_free (x); + return err; + } + + mpi_set (result->x, x); + mpi_set (result->y, y); + mpi_set_ui (result->z, 1); + + mpi_free (x); + mpi_free (y); + + return 0; +} |