diff options
-rw-r--r-- | NEWS | 7 | ||||
-rw-r--r-- | mpi/ec.c | 111 | ||||
-rw-r--r-- | src/gcrypt.h.in | 42 | ||||
-rw-r--r-- | src/libgcrypt.def | 7 | ||||
-rw-r--r-- | src/libgcrypt.vers | 4 | ||||
-rw-r--r-- | src/visibility.c | 39 | ||||
-rw-r--r-- | src/visibility.h | 20 | ||||
-rw-r--r-- | tests/Makefile.am | 2 | ||||
-rw-r--r-- | tests/t-mpi-point.c | 165 |
9 files changed, 394 insertions, 3 deletions
@@ -37,6 +37,13 @@ Noteworthy changes in version 1.6.0 (unreleased) GCRY_RNG_TYPE_FIPS NEW. GCRY_RNG_TYPE_SYSTEM NEW. gcry_mpi_snatch NEW. + gcry_mpi_point_t NEW. + gcry_mpi_point_new NEW. + gcry_mpi_point_release NEW. + gcry_mpi_point_get NEW. + gcry_mpi_point_snatch_get NEW. + gcry_mpi_point_set NEW. + gcry_mpi_point_snatch_set NEW. Noteworthy changes in version 1.5.0 (2011-06-29) @@ -62,6 +62,33 @@ struct mpi_ec_ctx_s }; +/* Create a new point option. NBITS gives the size in bits of one + coordinate; it is only used to pre-allocate some resources and + might also be passed as 0 to use a default value. */ +mpi_point_t +gcry_mpi_point_new (unsigned int nbits) +{ + mpi_point_t p; + + (void)nbits; /* Currently not used. */ + + p = gcry_xmalloc (sizeof *p); + _gcry_mpi_point_init (p); + return p; +} + + +/* Release the point object P. P may be NULL. */ +void +gcry_mpi_point_release (mpi_point_t p) +{ + if (p) + { + _gcry_mpi_point_free_parts (p); + gcry_free (p); + } +} + /* Initialize the fields of a point object. gcry_mpi_point_free_parts may be used to release the fields. */ @@ -93,6 +120,90 @@ point_set (mpi_point_t d, mpi_point_t s) mpi_set (d->z, s->z); } +/* 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 +gcry_mpi_point_get (gcry_mpi_t x, gcry_mpi_t y, gcry_mpi_t z, + mpi_point_t point) +{ + if (x) + mpi_set (x, point->x); + if (y) + mpi_set (y, point->y); + if (z) + mpi_set (z, point->z); +} + + +/* Set the projective coordinates from POINT into X, Y, and Z and + release POINT. If a coordinate is not required, X, Y, or Z may be + passed as NULL. */ +void +gcry_mpi_point_snatch_get (gcry_mpi_t x, gcry_mpi_t y, gcry_mpi_t z, + mpi_point_t point) +{ + mpi_snatch (x, point->x); + mpi_snatch (y, point->y); + mpi_snatch (z, point->z); + gcry_free (point); +} + + +/* Set the projective coordinates from X, Y, and Z into POINT. If a + coordinate is given as NULL, the value 0 is stored into point. If + POINT is given as NULL a new point object is allocated. Returns + POINT or the newly allocated point object. */ +mpi_point_t +gcry_mpi_point_set (mpi_point_t point, + gcry_mpi_t x, gcry_mpi_t y, gcry_mpi_t z) +{ + if (!point) + point = gcry_mpi_point_new (0); + + if (x) + mpi_set (point->x, x); + else + mpi_clear (point->x); + if (y) + mpi_set (point->y, y); + else + mpi_clear (point->y); + if (z) + mpi_set (point->z, z); + else + mpi_clear (point->z); + + return point; +} + + +/* Set the projective coordinates from X, Y, and Z into POINT. If a + coordinate is given as NULL, the value 0 is stored into point. If + POINT is given as NULL a new point object is allocated. The + coordinates X, Y, and Z are released. Returns POINT or the newly + allocated point object. */ +mpi_point_t +gcry_mpi_point_snatch_set (mpi_point_t point, + gcry_mpi_t x, gcry_mpi_t y, gcry_mpi_t z) +{ + if (!point) + point = gcry_mpi_point_new (0); + + if (x) + mpi_snatch (point->x, x); + else + mpi_clear (point->x); + if (y) + mpi_snatch (point->y, y); + else + mpi_clear (point->y); + if (z) + mpi_snatch (point->z, z); + else + mpi_clear (point->z); + + return point; +} static void diff --git a/src/gcrypt.h.in b/src/gcrypt.h.in index 7d2b89db..5d2a7792 100644 --- a/src/gcrypt.h.in +++ b/src/gcrypt.h.in @@ -212,9 +212,11 @@ struct gcry_thread_cbs -/* The data object used to hold a multi precision integer. */ +/* The data objects used to hold multi precision integers. */ struct gcry_mpi; typedef struct gcry_mpi *gcry_mpi_t; +struct gcry_mpi_point; +typedef struct gcry_mpi_point *gcry_mpi_point_t; #ifndef GCRYPT_NO_DEPRECATED typedef struct gcry_mpi *GCRY_MPI _GCRY_GCC_ATTR_DEPRECATED; @@ -572,6 +574,31 @@ int gcry_mpi_gcd (gcry_mpi_t g, gcry_mpi_t a, gcry_mpi_t b); Return true if the value exists. */ int gcry_mpi_invm (gcry_mpi_t x, gcry_mpi_t a, gcry_mpi_t m); +/* Create a new point object. NBITS is usually 0. */ +gcry_mpi_point_t gcry_mpi_point_new (unsigned int nbits); + +/* Release the object POINT. POINT may be NULL. */ +void gcry_mpi_point_release (gcry_mpi_point_t point); + +/* Store the projective coordinates from POINT into X, Y, and Z. */ +void gcry_mpi_point_get (gcry_mpi_t x, gcry_mpi_t y, gcry_mpi_t z, + gcry_mpi_point_t point); + +/* Store the projective coordinates from POINT into X, Y, and Z and + release POINT. */ +void gcry_mpi_point_snatch_get (gcry_mpi_t x, gcry_mpi_t y, gcry_mpi_t z, + gcry_mpi_point_t point); + +/* Store the projective coordinates X, Y, and Z into POINT. */ +gcry_mpi_point_t gcry_mpi_point_set (gcry_mpi_point_t point, + gcry_mpi_t x, gcry_mpi_t y, gcry_mpi_t z); + +/* Store the projective coordinates X, Y, and Z into POINT and release + X, Y, and Z. */ +gcry_mpi_point_t gcry_mpi_point_snatch_set (gcry_mpi_point_t point, + gcry_mpi_t x, gcry_mpi_t y, + gcry_mpi_t z); + /* Return the number of bits required to represent A. */ unsigned int gcry_mpi_get_nbits (gcry_mpi_t a); @@ -656,6 +683,19 @@ int gcry_mpi_get_flag (gcry_mpi_t a, enum gcry_mpi_flag flag); #define mpi_gcd(g,a,b) gcry_mpi_gcd ( (g), (a), (b) ) #define mpi_invm(g,a,b) gcry_mpi_invm ( (g), (a), (b) ) +#define mpi_point_new(n) gcry_mpi_point_new((n)) +#define mpi_point_release(p) \ + do \ + { \ + gcry_mpi_point_release ((p)); \ + (p) = NULL; \ + } \ + while (0) +#define mpi_point_get(x,y,z,p) gcry_mpi_point_get((x),(y),(z),(p)) +#define mpi_point_snatch_get(x,y,z,p) gcry_mpi_point_snatch_get((x),(y),(z),(p)) +#define mpi_point_set(p,x,y,z) gcry_mpi_point_set((p),(x),(y),(z)) +#define mpi_point_snatch_set(p,x,y,z) gcry_mpi_point_snatch_set((p),(x),(y),(z)) + #define mpi_get_nbits(a) gcry_mpi_get_nbits ((a)) #define mpi_test_bit(a,b) gcry_mpi_test_bit ((a),(b)) #define mpi_set_bit(a,b) gcry_mpi_set_bit ((a),(b)) diff --git a/src/libgcrypt.def b/src/libgcrypt.def index cc49e748..8f14dff6 100644 --- a/src/libgcrypt.def +++ b/src/libgcrypt.def @@ -213,3 +213,10 @@ EXPORTS gcry_kdf_derive @194 gcry_mpi_snatch @195 + + gcry_mpi_point_new @196 + gcry_mpi_point_release @197 + gcry_mpi_point_get @198 + gcry_mpi_point_snatch_get @199 + gcry_mpi_point_set @200 + gcry_mpi_point_snatch_set @201 diff --git a/src/libgcrypt.vers b/src/libgcrypt.vers index 200f04e6..5c43b959 100644 --- a/src/libgcrypt.vers +++ b/src/libgcrypt.vers @@ -87,6 +87,10 @@ GCRYPT_1.6 { gcry_mpi_set_ui; gcry_mpi_snew; gcry_mpi_sub; gcry_mpi_sub_ui; gcry_mpi_subm; gcry_mpi_swap; gcry_mpi_test_bit; gcry_mpi_lshift; gcry_mpi_snatch; + gcry_mpi_point_new; gcry_mpi_point_release; + gcry_mpi_point_get; gcry_mpi_point_snatch_get; + gcry_mpi_point_set; gcry_mpi_point_snatch_set; + local: *; diff --git a/src/visibility.c b/src/visibility.c index 732f0582..1fb29f2b 100644 --- a/src/visibility.c +++ b/src/visibility.c @@ -421,6 +421,45 @@ gcry_mpi_invm (gcry_mpi_t x, gcry_mpi_t a, gcry_mpi_t m) return _gcry_mpi_invm (x, a, m); } +gcry_mpi_point_t +gcry_mpi_point_new (unsigned int nbits) +{ + return _gcry_mpi_point_new (nbits); +} + +void +gcry_mpi_point_release (gcry_mpi_point_t point) +{ + _gcry_mpi_point_release (point); +} + +void +gcry_mpi_point_get (gcry_mpi_t x, gcry_mpi_t y, gcry_mpi_t z, + gcry_mpi_point_t point) +{ + _gcry_mpi_point_get (x, y, z, point); +} + +void +gcry_mpi_point_snatch_get (gcry_mpi_t x, gcry_mpi_t y, gcry_mpi_t z, + gcry_mpi_point_t point) +{ + _gcry_mpi_point_snatch_get (x, y, z, point); +} + +gcry_mpi_point_t +gcry_mpi_point_set (gcry_mpi_point_t point, + gcry_mpi_t x, gcry_mpi_t y, gcry_mpi_t z) +{ + return _gcry_mpi_point_set (point, x, y, z); +} + +gcry_mpi_point_t +gcry_mpi_point_snatch_set (gcry_mpi_point_t point, + gcry_mpi_t x, gcry_mpi_t y, gcry_mpi_t z) +{ + return _gcry_mpi_point_snatch_set (point, x, y, z); +} unsigned int gcry_mpi_get_nbits (gcry_mpi_t a) diff --git a/src/visibility.h b/src/visibility.h index 429c2461..f4507ceb 100644 --- a/src/visibility.h +++ b/src/visibility.h @@ -165,6 +165,12 @@ #define gcry_mpi_mul_ui _gcry_mpi_mul_ui #define gcry_mpi_mulm _gcry_mpi_mulm #define gcry_mpi_new _gcry_mpi_new +#define gcry_mpi_point_get _gcry_mpi_point_get +#define gcry_mpi_point_new _gcry_mpi_point_new +#define gcry_mpi_point_release _gcry_mpi_point_release +#define gcry_mpi_point_set _gcry_mpi_point_set +#define gcry_mpi_point_snatch_get _gcry_mpi_point_snatch_get +#define gcry_mpi_point_snatch_set _gcry_mpi_point_snatch_set #define gcry_mpi_powm _gcry_mpi_powm #define gcry_mpi_print _gcry_mpi_print #define gcry_mpi_randomize _gcry_mpi_randomize @@ -172,13 +178,13 @@ #define gcry_mpi_rshift _gcry_mpi_rshift #define gcry_mpi_lshift _gcry_mpi_lshift #define gcry_mpi_scan _gcry_mpi_scan -#define gcry_mpi_snatch _gcry_mpi_snatch #define gcry_mpi_set _gcry_mpi_set #define gcry_mpi_set_bit _gcry_mpi_set_bit #define gcry_mpi_set_flag _gcry_mpi_set_flag #define gcry_mpi_set_highbit _gcry_mpi_set_highbit #define gcry_mpi_set_opaque _gcry_mpi_set_opaque #define gcry_mpi_set_ui _gcry_mpi_set_ui +#define gcry_mpi_snatch _gcry_mpi_snatch #define gcry_mpi_snew _gcry_mpi_snew #define gcry_mpi_sub _gcry_mpi_sub #define gcry_mpi_sub_ui _gcry_mpi_sub_ui @@ -372,6 +378,12 @@ gcry_err_code_t gcry_md_get (gcry_md_hd_t hd, int algo, #undef gcry_mpi_mul_ui #undef gcry_mpi_mulm #undef gcry_mpi_new +#undef gcry_mpi_point_get +#undef gcry_mpi_point_new +#undef gcry_mpi_point_release +#undef gcry_mpi_point_set +#undef gcry_mpi_point_snatch_get +#undef gcry_mpi_point_snatch_set #undef gcry_mpi_powm #undef gcry_mpi_print #undef gcry_mpi_randomize @@ -539,6 +551,12 @@ MARK_VISIBLE (gcry_mpi_mul_2exp) MARK_VISIBLE (gcry_mpi_mul_ui) MARK_VISIBLE (gcry_mpi_mulm) MARK_VISIBLE (gcry_mpi_new) +MARK_VISIBLE (gcry_mpi_point_get) +MARK_VISIBLE (gcry_mpi_point_new) +MARK_VISIBLE (gcry_mpi_point_release) +MARK_VISIBLE (gcry_mpi_point_set) +MARK_VISIBLE (gcry_mpi_point_snatch_get) +MARK_VISIBLE (gcry_mpi_point_snatch_set) MARK_VISIBLE (gcry_mpi_powm) MARK_VISIBLE (gcry_mpi_print) MARK_VISIBLE (gcry_mpi_randomize) diff --git a/tests/Makefile.am b/tests/Makefile.am index d337840f..c18142e0 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -18,7 +18,7 @@ ## Process this file with automake to produce Makefile.in -TESTS = version t-mpi-bit prime basic \ +TESTS = version t-mpi-bit t-mpi-point prime basic \ mpitests tsexp keygen pubkey hmac keygrip fips186-dsa aeswrap \ curves t-kdf pkcs1v2 random diff --git a/tests/t-mpi-point.c b/tests/t-mpi-point.c new file mode 100644 index 00000000..548d6c7c --- /dev/null +++ b/tests/t-mpi-point.c @@ -0,0 +1,165 @@ +/* t-mpi-point.c - Tests for mpi point functions + * 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/>. + */ + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <assert.h> +#include <stdarg.h> + +#include "../src/gcrypt.h" + +#define PGM "t-mpi-point" + +static const char *wherestr; +static int verbose; +static int error_count; + +#define xmalloc(a) gcry_xmalloc ((a)) +#define xcalloc(a,b) gcry_xcalloc ((a),(b)) +#define xfree(a) gcry_free ((a)) +#define pass() do { ; } while (0) + +static void +show (const char *format, ...) +{ + va_list arg_ptr; + + if (!verbose) + return; + fprintf (stderr, "%s: ", PGM); + va_start (arg_ptr, format); + vfprintf (stderr, format, arg_ptr); + va_end (arg_ptr); +} + +static void +fail (const char *format, ...) +{ + va_list arg_ptr; + + fflush (stdout); + fprintf (stderr, "%s: ", PGM); + if (wherestr) + fprintf (stderr, "%s: ", wherestr); + va_start (arg_ptr, format); + vfprintf (stderr, format, arg_ptr); + va_end (arg_ptr); + error_count++; +} + +static void +die (const char *format, ...) +{ + va_list arg_ptr; + + fflush (stdout); + fprintf (stderr, "%s: ", PGM); + if (wherestr) + fprintf (stderr, "%s: ", wherestr); + va_start (arg_ptr, format); + vfprintf (stderr, format, arg_ptr); + va_end (arg_ptr); + exit (1); +} + + + +static void +set_get_point (void) +{ + gcry_mpi_point_t point; + gcry_mpi_t x, y, z; + + wherestr = "set_get_point"; + show ("checking point setting functions\n"); + + point = gcry_mpi_point_new (0); + x = gcry_mpi_set_ui (NULL, 17); + y = gcry_mpi_set_ui (NULL, 42); + z = gcry_mpi_set_ui (NULL, 11371); + gcry_mpi_point_get (x, y, z, point); + if (gcry_mpi_cmp_ui (x, 0) + || gcry_mpi_cmp_ui (y, 0) || gcry_mpi_cmp_ui (z, 0)) + fail ("new point not initialized to (0,0,0)\n"); + gcry_mpi_point_snatch_get (x, y, z, point); + point = NULL; + if (gcry_mpi_cmp_ui (x, 0) + || gcry_mpi_cmp_ui (y, 0) || gcry_mpi_cmp_ui (z, 0)) + fail ("snatch_get failed\n"); + gcry_mpi_release (x); + gcry_mpi_release (y); + gcry_mpi_release (z); + + point = gcry_mpi_point_new (0); + x = gcry_mpi_set_ui (NULL, 17); + y = gcry_mpi_set_ui (NULL, 42); + z = gcry_mpi_set_ui (NULL, 11371); + gcry_mpi_point_set (point, x, y, z); + gcry_mpi_set_ui (x, 23); + gcry_mpi_set_ui (y, 24); + gcry_mpi_set_ui (z, 25); + gcry_mpi_point_get (x, y, z, point); + if (gcry_mpi_cmp_ui (x, 17) + || gcry_mpi_cmp_ui (y, 42) || gcry_mpi_cmp_ui (z, 11371)) + fail ("point_set/point_get failed\n"); + gcry_mpi_point_snatch_set (point, x, y, z); + x = gcry_mpi_new (0); + y = gcry_mpi_new (0); + z = gcry_mpi_new (0); + gcry_mpi_point_get (x, y, z, point); + if (gcry_mpi_cmp_ui (x, 17) + || gcry_mpi_cmp_ui (y, 42) || gcry_mpi_cmp_ui (z, 11371)) + fail ("point_snatch_set/point_get failed\n"); + + gcry_mpi_point_release (point); + gcry_mpi_release (x); + gcry_mpi_release (y); + gcry_mpi_release (z); +} + + +int +main (int argc, char **argv) +{ + int debug = 0; + + if (argc > 1 && !strcmp (argv[1], "--verbose")) + verbose = 1; + else if (argc > 1 && !strcmp (argv[1], "--debug")) + verbose = debug = 1; + + if (!gcry_check_version (GCRYPT_VERSION)) + die ("version mismatch\n"); + + gcry_control (GCRYCTL_DISABLE_SECMEM, 0); + gcry_control (GCRYCTL_ENABLE_QUICK_RANDOM, 0); + if (debug) + gcry_control (GCRYCTL_SET_DEBUG_FLAGS, 1u, 0); + gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0); + + set_get_point (); + + + show ("All tests completed. Errors: %d\n", error_count); + return error_count ? 1 : 0; +} |