[PATCH 2/3] mpi: Add an API for EC point operations.
Werner Koch
wk at gnupg.org
Fri Mar 8 22:47:54 CET 2013
* mpi/ec.c (gcry_mpi_point_new, gcry_mpi_point_release): New.
(gcry_mpi_point_get, gcry_mpi_point_snatch_get): New.
(gcry_mpi_point_set, gcry_mpi_point_snatch_set): New.
* src/visibility.h, src/visibility.c: Add corresponding macros and
wrappers.
* src/gcrypt.h.in (struct gcry_mpi_point, gcry_mpi_point_t): New.
(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): New prototypes.
(mpi_point_new, mpi_point_release, mpi_point_get, mpi_point_snatch_get)
(mpi_point_set, mpi_point_snatch_set): New macros.
* src/libgcrypt.vers (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): New symbols.
* src/libgcrypt.def: Ditto.
* tests/t-mpi-point.c: New.
* tests/Makefile.am (TESTS): Add t-mpi-point
---
NEWS | 7 ++
mpi/ec.c | 111 ++++++++++++++++++++++++++++++++++
src/gcrypt.h.in | 42 +++++++++++++-
src/libgcrypt.def | 7 ++
src/libgcrypt.vers | 4 +
src/visibility.c | 39 ++++++++++++
src/visibility.h | 20 ++++++-
tests/Makefile.am | 2 +-
tests/t-mpi-point.c | 165 +++++++++++++++++++++++++++++++++++++++++++++++++++
9 files changed, 394 insertions(+), 3 deletions(-)
create mode 100644 tests/t-mpi-point.c
diff --git a/NEWS b/NEWS
index 1db71e9..e0ba536 100644
--- a/NEWS
+++ b/NEWS
@@ -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)
diff --git a/mpi/ec.c b/mpi/ec.c
index 7b1ef2b..bb9bea4 100644
--- a/mpi/ec.c
+++ b/mpi/ec.c
@@ -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 7d2b89d..5d2a779 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 cc49e74..8f14dff 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 200f04e..5c43b95 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 732f058..1fb29f2 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 429c246..f4507ce 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 d337840..c18142e 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 0000000..548d6c7
--- /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;
+}
--
1.7.7.1
--
Die Gedanken sind frei. Ausnahmen regelt ein Bundesgesetz.
More information about the Gcrypt-devel
mailing list