From wk at gnupg.org Sun Mar 3 10:41:54 2013 From: wk at gnupg.org (Werner Koch) Date: Sun, 03 Mar 2013 10:41:54 +0100 Subject: MD5-HMAC 2x as slow after call to gcry_create_nonce In-Reply-To: <20130227231208.GU21743@thunk.cs.uwaterloo.ca> (Ian Goldberg's message of "Wed, 27 Feb 2013 18:12:08 -0500") References: <20130227231208.GU21743@thunk.cs.uwaterloo.ca> Message-ID: <877gloyg4d.fsf@vigenere.g10code.de> On Thu, 28 Feb 2013 00:12, linux at paip.net said: > This is odd. It appears that if we call gcry_create_nonce in our > program, subsequent calls to MD5-HMAC are about 2.5x as slow as when we > don't. The source for a test program is attached. The second argument It looks like you are bugged by this: /* The fast random pool function as called at some places in libgcrypt. This is merely a wrapper to make sure that this module is initialized and to lock the pool. Note, that this function is a NOP unless a random function has been used or _gcry_initialize (1) has been used. We use this hack so that the internal use of this function in cipher_open and md_open won't start filling up the random pool, even if no random will be required by the process. */ void _gcry_fast_random_poll (void) It sounds as if you would like an option to disable this feature. As always, the problem is with libraries - an application might decide that it can do without it but a library should not enforce such a policy. You may be interested in this feature: * Added a random number generator to directly use the system's RNG. Also added an interface to prefer the use of a specified RNG. GCRYCTL_SET_PREFERRED_RNG_TYPE NEW. GCRYCTL_GET_CURRENT_RNG_TYPE NEW. GCRY_RNG_TYPE_STANDARD NEW. GCRY_RNG_TYPE_FIPS NEW. GCRY_RNG_TYPE_SYSTEM NEW. See this comment for some background info: /* After any initialization has been done we only allow to upgrade to the standard RNG (handled above). All other requests are ignored. The idea is that the application needs to declare a preference for a weaker RNG as soon as possible and before any library sets a preference. We assume that a library which uses Libgcrypt calls an init function very early. This way --- even if the library gets initialized early by the application --- it is unlikely that it can select a lower priority RNG. This scheme helps to ensure that existing unmodified applications (e.g. gpg2), which don't known about the new RNG selection system, will continue to use the standard RNG and not be tricked by some library to use a lower priority RNG. There are some loopholes here but at least most GnuPG stuff should be save because it calls src_c{gcry_control (GCRYCTL_SUSPEND_SECMEM_WARN);} quite early and thus inhibits switching to a low priority RNG. */ Shalom-Salam, Werner -- Die Gedanken sind frei. Ausnahmen regelt ein Bundesgesetz. From wk at gnupg.org Fri Mar 8 22:47:28 2013 From: wk at gnupg.org (Werner Koch) Date: Fri, 08 Mar 2013 22:47:28 +0100 Subject: [PATCH 1/3] mpi: Add mpi_snatch and change an internal typedef. Message-ID: <878v5xbm33.fsf@vigenere.g10code.de> * src/mpi.h (struct mpi_point_s): Rename to struct gcry_mpi_point. (mpi_point_struct): New typedef. (mpi_point_t): Change typedef to a pointer. Replace all occurrences to use mpi_point_struct. * mpi/ec.c (_gcry_mpi_ec_point_init): Rename to .. (_gcry_mpi_point_init): this. Change all callers. (_gcry_mpi_ec_point_free): Rename to .. (_gcry_mpi_point_free_parts): this. Change all callers. * mpi/mpiutil.c (gcry_mpi_snatch): New function. * src/gcrypt.h.in (gcry_mpi_snatch, mpi_snatch): Add protoype and macro. * src/visibility.c (gcry_mpi_snatch): Add wrapper. * src/visibility.h (gcry_mpi_snatch): Add macro magic. * src/libgcrypt.def, src/libgcrypt.vers: Add new function. -- This patch is a prerequisite to implement a public point API. The new function gcry_mpi_snatch is actually not needed for this but is useful anyway and will be used to implement the point API. --- NEWS | 2 + cipher/ecc.c | 78 +++++++++++++++++++++++++-------------------------- doc/gcrypt.texi | 7 ++++ mpi/ec.c | 71 +++++++++++++++++++++++------------------------ mpi/mpiutil.c | 19 ++++++++++++ src/gcrypt.h.in | 5 +++ src/libgcrypt.def | 2 + src/libgcrypt.vers | 2 +- src/mpi.h | 30 ++++++++++++-------- src/visibility.c | 7 ++++ src/visibility.h | 3 ++ 11 files changed, 137 insertions(+), 89 deletions(-) diff --git a/NEWS b/NEWS index 45b892f..1db71e9 100644 --- a/NEWS +++ b/NEWS @@ -36,6 +36,7 @@ Noteworthy changes in version 1.6.0 (unreleased) GCRY_RNG_TYPE_STANDARD NEW. GCRY_RNG_TYPE_FIPS NEW. GCRY_RNG_TYPE_SYSTEM NEW. + gcry_mpi_snatch NEW. Noteworthy changes in version 1.5.0 (2011-06-29) @@ -705,6 +706,7 @@ Noteworthy changes in version 1.1.3 (2001-05-31) Copyright 2001, 2002, 2003, 2004, 2007, 2008, 2009, 2011 Free Software Foundation, Inc. +Copyright 2013 g10 Code GmbH This file is free software; as a special exception the author gives unlimited permission to copy and/or distribute it, with or without diff --git a/cipher/ecc.c b/cipher/ecc.c index 22de3d8..789fc6c 100644 --- a/cipher/ecc.c +++ b/cipher/ecc.c @@ -1,22 +1,22 @@ /* ecc.c - Elliptic Curve Cryptography - Copyright (C) 2007, 2008, 2010, 2011 Free Software Foundation, Inc. - - 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, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, - USA. */ + * 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 . + */ /* This code is originally based on the Patch 0.1.6 for the gnupg 1.4.x branch as retrieved on 2007-03-21 from @@ -46,8 +46,6 @@ - In mpi/ec.c we use mpi_powm for x^2 mod p: Either implement a special case in mpi_powm or check whether mpi_mulm is faster. - - - Decide whether we should hide the mpi_point_t definition. */ @@ -63,25 +61,25 @@ /* Definition of a curve. */ typedef struct { - gcry_mpi_t p; /* Prime specifying the field GF(p). */ - gcry_mpi_t a; /* First coefficient of the Weierstrass equation. */ - gcry_mpi_t b; /* Second coefficient of the Weierstrass equation. */ - mpi_point_t G; /* Base point (generator). */ - gcry_mpi_t n; /* Order of G. */ - const char *name; /* Name of curve or NULL. */ + gcry_mpi_t p; /* Prime specifying the field GF(p). */ + gcry_mpi_t a; /* First coefficient of the Weierstrass equation. */ + gcry_mpi_t b; /* Second coefficient of the Weierstrass equation. */ + mpi_point_struct G; /* Base point (generator). */ + gcry_mpi_t n; /* Order of G. */ + const char *name; /* Name of the curve or NULL. */ } elliptic_curve_t; typedef struct { elliptic_curve_t E; - mpi_point_t Q; /* Q = [d]G */ + mpi_point_struct Q; /* Q = [d]G */ } ECC_public_key; typedef struct { elliptic_curve_t E; - mpi_point_t Q; + mpi_point_struct Q; gcry_mpi_t d; } ECC_secret_key; @@ -292,8 +290,8 @@ static void (*progress_cb) (void *, const char*, int, int, int); static void *progress_cb_data; -#define point_init(a) _gcry_mpi_ec_point_init ((a)) -#define point_free(a) _gcry_mpi_ec_point_free ((a)) +#define point_init(a) _gcry_mpi_point_init ((a)) +#define point_free(a) _gcry_mpi_point_free_parts ((a)) @@ -333,7 +331,7 @@ _gcry_register_pk_ecc_progress (void (*cb) (void *, const char *, /* Set the value from S into D. */ static void -point_set (mpi_point_t *d, mpi_point_t *s) +point_set (mpi_point_t d, mpi_point_t s) { mpi_set (d->x, s->x); mpi_set (d->y, s->y); @@ -521,7 +519,7 @@ generate_key (ECC_secret_key *sk, unsigned int nbits, const char *name, gpg_err_code_t err; elliptic_curve_t E; gcry_mpi_t d; - mpi_point_t Q; + mpi_point_struct Q; mpi_ec_t ctx; gcry_random_level_t random_level; @@ -600,7 +598,7 @@ test_keys (ECC_secret_key *sk, unsigned int nbits) { ECC_public_key pk; gcry_mpi_t test = mpi_new (nbits); - mpi_point_t R_; + mpi_point_struct R_; gcry_mpi_t c = mpi_new (nbits); gcry_mpi_t out = mpi_new (nbits); gcry_mpi_t r = mpi_new (nbits); @@ -648,7 +646,7 @@ static int check_secret_key (ECC_secret_key * sk) { int rc = 1; - mpi_point_t Q; + mpi_point_struct Q; gcry_mpi_t y_2, y2; mpi_ec_t ctx = NULL; @@ -719,7 +717,7 @@ sign (gcry_mpi_t input, ECC_secret_key *skey, gcry_mpi_t r, gcry_mpi_t s) { gpg_err_code_t err = 0; gcry_mpi_t k, dr, sum, k_1, x; - mpi_point_t I; + mpi_point_struct I; mpi_ec_t ctx; if (DBG_CIPHER) @@ -790,7 +788,7 @@ verify (gcry_mpi_t input, ECC_public_key *pkey, gcry_mpi_t r, gcry_mpi_t s) { gpg_err_code_t err = 0; gcry_mpi_t h, h1, h2, x, y; - mpi_point_t Q, Q1, Q2; + mpi_point_struct Q, Q1, Q2; mpi_ec_t ctx; if( !(mpi_cmp_ui (r, 0) > 0 && mpi_cmp (r, pkey->E.n) < 0) ) @@ -925,7 +923,7 @@ ec2os (gcry_mpi_t x, gcry_mpi_t y, gcry_mpi_t p) /* RESULT must have been initialized and is set on success to the point given by VALUE. */ static gcry_error_t -os2ec (mpi_point_t *result, gcry_mpi_t value) +os2ec (mpi_point_t result, gcry_mpi_t value) { gcry_error_t err; size_t n; @@ -1430,7 +1428,7 @@ ecc_encrypt_raw (int algo, gcry_mpi_t *resarr, gcry_mpi_t k, /* The following is false: assert( mpi_cmp_ui( R.x, 1 )==0 );, so */ { - mpi_point_t R; /* Result that we return. */ + mpi_point_struct R; /* Result that we return. */ gcry_mpi_t x, y; x = mpi_new (0); @@ -1490,8 +1488,8 @@ ecc_decrypt_raw (int algo, gcry_mpi_t *result, gcry_mpi_t *data, gcry_mpi_t *skey, int flags) { ECC_secret_key sk; - mpi_point_t R; /* Result that we return. */ - mpi_point_t kG; + mpi_point_struct R; /* Result that we return. */ + mpi_point_struct kG; mpi_ec_t ctx; gcry_mpi_t r; int err; diff --git a/doc/gcrypt.texi b/doc/gcrypt.texi index fa24def..8bfcbfd 100644 --- a/doc/gcrypt.texi +++ b/doc/gcrypt.texi @@ -3600,6 +3600,13 @@ small values (usually up to the word size of the CPU). Swap the values of @var{a} and @var{b}. @end deftypefun + at deftypefun void gcry_mpi_snatch (@w{gcry_mpi_t @var{w}}, @ + @w{const gcry_mpi_t @var{u}}) + +Set @var{u} into @var{w} and release @var{u}. If @var{w} is + at code{NULL} only @var{u} will be released. + at end deftypefun + @node MPI formats @section MPI formats diff --git a/mpi/ec.c b/mpi/ec.c index e325358..7b1ef2b 100644 --- a/mpi/ec.c +++ b/mpi/ec.c @@ -1,23 +1,22 @@ /* ec.c - Elliptic Curve functions - Copyright (C) 2007 Free Software Foundation, Inc. - - 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, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, - USA. */ - + * Copyright (C) 2007 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 . + */ #include #include @@ -28,8 +27,8 @@ #include "g10lib.h" -#define point_init(a) _gcry_mpi_ec_point_init ((a)) -#define point_free(a) _gcry_mpi_ec_point_free ((a)) +#define point_init(a) _gcry_mpi_point_init ((a)) +#define point_free(a) _gcry_mpi_point_free_parts ((a)) /* Object to represent a point in projective coordinates. */ @@ -64,10 +63,10 @@ struct mpi_ec_ctx_s -/* Initialized a point object. gcry_mpi_ec_point_free shall be used - to release this object. */ +/* Initialize the fields of a point object. gcry_mpi_point_free_parts + may be used to release the fields. */ void -_gcry_mpi_ec_point_init (mpi_point_t *p) +_gcry_mpi_point_init (mpi_point_t p) { p->x = mpi_new (0); p->y = mpi_new (0); @@ -75,18 +74,19 @@ _gcry_mpi_ec_point_init (mpi_point_t *p) } -/* Release a point object. */ +/* Release the parts of a point object. */ void -_gcry_mpi_ec_point_free (mpi_point_t *p) +_gcry_mpi_point_free_parts (mpi_point_t p) { mpi_free (p->x); p->x = NULL; mpi_free (p->y); p->y = NULL; mpi_free (p->z); p->z = NULL; } + /* Set the value from S into D. */ static void -point_set (mpi_point_t *d, mpi_point_t *s) +point_set (mpi_point_t d, mpi_point_t s) { mpi_set (d->x, s->x); mpi_set (d->y, s->y); @@ -339,12 +339,13 @@ _gcry_mpi_ec_free (mpi_ec_t ctx) gcry_free (ctx); } + /* Compute the affine coordinates from the projective coordinates in POINT. Set them into X and Y. If one coordinate is not required, X or Y may be passed as NULL. CTX is the usual context. Returns: 0 on success or !0 if POINT is at infinity. */ int -_gcry_mpi_ec_get_affine (gcry_mpi_t x, gcry_mpi_t y, mpi_point_t *point, +_gcry_mpi_ec_get_affine (gcry_mpi_t x, gcry_mpi_t y, mpi_point_t point, mpi_ec_t ctx) { gcry_mpi_t z1, z2, z3; @@ -374,12 +375,10 @@ _gcry_mpi_ec_get_affine (gcry_mpi_t x, gcry_mpi_t y, mpi_point_t *point, } - - /* RESULT = 2 * POINT */ void -_gcry_mpi_ec_dup_point (mpi_point_t *result, mpi_point_t *point, mpi_ec_t ctx) +_gcry_mpi_ec_dup_point (mpi_point_t result, mpi_point_t point, mpi_ec_t ctx) { #define x3 (result->x) #define y3 (result->y) @@ -463,8 +462,8 @@ _gcry_mpi_ec_dup_point (mpi_point_t *result, mpi_point_t *point, mpi_ec_t ctx) /* RESULT = P1 + P2 */ void -_gcry_mpi_ec_add_points (mpi_point_t *result, - mpi_point_t *p1, mpi_point_t *p2, +_gcry_mpi_ec_add_points (mpi_point_t result, + mpi_point_t p1, mpi_point_t p2, mpi_ec_t ctx) { #define x1 (p1->x ) @@ -608,8 +607,8 @@ _gcry_mpi_ec_add_points (mpi_point_t *result, an integer SCALAR and a POINT as well as the usual context CTX. RESULT will be set to the resulting point. */ void -_gcry_mpi_ec_mul_point (mpi_point_t *result, - gcry_mpi_t scalar, mpi_point_t *point, +_gcry_mpi_ec_mul_point (mpi_point_t result, + gcry_mpi_t scalar, mpi_point_t point, mpi_ec_t ctx) { #if 0 @@ -632,7 +631,7 @@ _gcry_mpi_ec_mul_point (mpi_point_t *result, #else gcry_mpi_t x1, y1, z1, k, h, yy; unsigned int i, loops; - mpi_point_t p1, p2, p1inv; + mpi_point_struct p1, p2, p1inv; x1 = mpi_alloc_like (ctx->p); y1 = mpi_alloc_like (ctx->p); diff --git a/mpi/mpiutil.c b/mpi/mpiutil.c index 76630a6..d410d90 100644 --- a/mpi/mpiutil.c +++ b/mpi/mpiutil.c @@ -1,6 +1,7 @@ /* mpiutil.ac - Utility functions for MPI * Copyright (C) 1998, 2000, 2001, 2002, 2003, * 2007 Free Software Foundation, Inc. + * Copyright (C) 2013 g10 Code GmbH * * This file is part of Libgcrypt. * @@ -296,6 +297,24 @@ _gcry_mpi_alloc_like( gcry_mpi_t a ) } +/* Set U into W and release U. If W is NULL only U will be released. */ +void +gcry_mpi_snatch (gcry_mpi_t w, gcry_mpi_t u) +{ + if (w) + { + _gcry_mpi_assign_limb_space (w, u->d, u->alloced); + w->nlimbs = u->nlimbs; + w->sign = u->sign; + w->flags = u->flags; + u->alloced = 0; + u->nlimbs = 0; + u->d = NULL; + } + _gcry_mpi_free (u); +} + + gcry_mpi_t gcry_mpi_set( gcry_mpi_t w, gcry_mpi_t u) { diff --git a/src/gcrypt.h.in b/src/gcrypt.h.in index dae8d1c..7d2b89d 100644 --- a/src/gcrypt.h.in +++ b/src/gcrypt.h.in @@ -2,6 +2,7 @@ * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, * 2006, 2007, 2008, 2009, 2010, 2011, * 2012 Free Software Foundation, Inc. + * Copyright (C) 2012, 2013 g10 Code GmbH * * This file is part of Libgcrypt. * @@ -466,6 +467,9 @@ void gcry_mpi_release (gcry_mpi_t a); /* Create a new number with the same value as A. */ gcry_mpi_t gcry_mpi_copy (const gcry_mpi_t a); +/* Store the big integer value U in W and release U. */ +void gcry_mpi_snatch (gcry_mpi_t w, gcry_mpi_t u); + /* Store the big integer value U in W. */ gcry_mpi_t gcry_mpi_set (gcry_mpi_t w, const gcry_mpi_t u); @@ -629,6 +633,7 @@ int gcry_mpi_get_flag (gcry_mpi_t a, enum gcry_mpi_flag flag); while (0) #define mpi_copy( a ) gcry_mpi_copy( (a) ) +#define mpi_snatch( w, u) gcry_mpi_snatch( (w), (u) ) #define mpi_set( w, u) gcry_mpi_set( (w), (u) ) #define mpi_set_ui( w, u) gcry_mpi_set_ui( (w), (u) ) #define mpi_cmp( u, v ) gcry_mpi_cmp( (u), (v) ) diff --git a/src/libgcrypt.def b/src/libgcrypt.def index 9bf0167..cc49e74 100644 --- a/src/libgcrypt.def +++ b/src/libgcrypt.def @@ -211,3 +211,5 @@ EXPORTS gcry_pk_get_param @193 gcry_kdf_derive @194 + + gcry_mpi_snatch @195 diff --git a/src/libgcrypt.vers b/src/libgcrypt.vers index dcb3749..200f04e 100644 --- a/src/libgcrypt.vers +++ b/src/libgcrypt.vers @@ -86,7 +86,7 @@ GCRYPT_1.6 { gcry_mpi_set_flag; gcry_mpi_set_highbit; gcry_mpi_set_opaque; 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_lshift; gcry_mpi_snatch; local: *; diff --git a/src/mpi.h b/src/mpi.h index 65a4f97..b3f19e5 100644 --- a/src/mpi.h +++ b/src/mpi.h @@ -108,6 +108,7 @@ struct gcry_mpi #define mpi_is_secure(a) ((a) && ((a)->flags&1)) #define mpi_clear(a) _gcry_mpi_clear ((a)) #define mpi_alloc_like(a) _gcry_mpi_alloc_like((a)) +#define mpi_snatch(a,b) _gcry_mpi_snatch ((a),(b)) #define mpi_set(a,b) _gcry_mpi_set ((a),(b)) #define mpi_set_ui(a,b) _gcry_mpi_set_ui ((a),(b)) #define mpi_get_ui(a,b) _gcry_mpi_get_ui ((a),(b)) @@ -230,32 +231,37 @@ void _gcry_mpi_normalize( gcry_mpi_t a ); /*-- ec.c --*/ /* Object to represent a point in projective coordinates. */ -struct mpi_point_s; -typedef struct mpi_point_s mpi_point_t; -struct mpi_point_s +struct gcry_mpi_point { gcry_mpi_t x; gcry_mpi_t y; gcry_mpi_t z; }; +typedef struct gcry_mpi_point mpi_point_struct; +typedef struct gcry_mpi_point *mpi_point_t; + +void _gcry_mpi_point_init (mpi_point_t p); +void _gcry_mpi_point_free_parts (mpi_point_t p); +void _gcry_mpi_get_point (gcry_mpi_t x, gcry_mpi_t y, gcry_mpi_t z, + mpi_point_t point); +void _gcry_mpi_snatch_point (gcry_mpi_t x, gcry_mpi_t y, gcry_mpi_t z, + mpi_point_t point); /* Context used with elliptic curve functions. */ struct mpi_ec_ctx_s; typedef struct mpi_ec_ctx_s *mpi_ec_t; -void _gcry_mpi_ec_point_init (mpi_point_t *p); -void _gcry_mpi_ec_point_free (mpi_point_t *p); mpi_ec_t _gcry_mpi_ec_init (gcry_mpi_t p, gcry_mpi_t a); void _gcry_mpi_ec_free (mpi_ec_t ctx); -int _gcry_mpi_ec_get_affine (gcry_mpi_t x, gcry_mpi_t y, mpi_point_t *point, +int _gcry_mpi_ec_get_affine (gcry_mpi_t x, gcry_mpi_t y, mpi_point_t point, mpi_ec_t ctx); -void _gcry_mpi_ec_dup_point (mpi_point_t *result, - mpi_point_t *point, mpi_ec_t ctx); -void _gcry_mpi_ec_add_points (mpi_point_t *result, - mpi_point_t *p1, mpi_point_t *p2, +void _gcry_mpi_ec_dup_point (mpi_point_t result, + mpi_point_t point, mpi_ec_t ctx); +void _gcry_mpi_ec_add_points (mpi_point_t result, + mpi_point_t p1, mpi_point_t p2, mpi_ec_t ctx); -void _gcry_mpi_ec_mul_point (mpi_point_t *result, - gcry_mpi_t scalar, mpi_point_t *point, +void _gcry_mpi_ec_mul_point (mpi_point_t result, + gcry_mpi_t scalar, mpi_point_t point, mpi_ec_t ctx); diff --git a/src/visibility.c b/src/visibility.c index 2d3edbc..732f058 100644 --- a/src/visibility.c +++ b/src/visibility.c @@ -1,5 +1,6 @@ /* visibility.c - Wrapper for all public functions. * Copyright (C) 2007, 2008, 2011 Free Software Foundation, Inc. + * Copyright (C) 2013 g10 Code GmbH * * This file is part of Libgcrypt. * @@ -261,6 +262,12 @@ gcry_mpi_copy (const gcry_mpi_t a) return _gcry_mpi_copy (a); } +void +gcry_mpi_snatch (gcry_mpi_t w, const gcry_mpi_t u) +{ + return _gcry_mpi_snatch (w, u); +} + gcry_mpi_t gcry_mpi_set (gcry_mpi_t w, const gcry_mpi_t u) { diff --git a/src/visibility.h b/src/visibility.h index 4606a20..429c246 100644 --- a/src/visibility.h +++ b/src/visibility.h @@ -172,6 +172,7 @@ #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 @@ -378,6 +379,7 @@ gcry_err_code_t gcry_md_get (gcry_md_hd_t hd, int algo, #undef gcry_mpi_rshift #undef gcry_mpi_lshift #undef gcry_mpi_scan +#undef gcry_mpi_snatch #undef gcry_mpi_set #undef gcry_mpi_set_bit #undef gcry_mpi_set_flag @@ -544,6 +546,7 @@ MARK_VISIBLE (gcry_mpi_release) MARK_VISIBLE (gcry_mpi_rshift) MARK_VISIBLE (gcry_mpi_lshift) MARK_VISIBLE (gcry_mpi_scan) +MARK_VISIBLE (gcry_mpi_snatch) MARK_VISIBLE (gcry_mpi_set) MARK_VISIBLE (gcry_mpi_set_bit) MARK_VISIBLE (gcry_mpi_set_flag) -- 1.7.7.1 -- Die Gedanken sind frei. Ausnahmen regelt ein Bundesgesetz. From wk at gnupg.org Fri Mar 8 22:47:54 2013 From: wk at gnupg.org (Werner Koch) Date: Fri, 08 Mar 2013 22:47:54 +0100 Subject: [PATCH 2/3] mpi: Add an API for EC point operations. Message-ID: <874nglbm2d.fsf@vigenere.g10code.de> * 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 . + */ + +#ifdef HAVE_CONFIG_H +# include +#endif +#include +#include +#include +#include +#include + +#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. From wk at gnupg.org Fri Mar 8 22:48:33 2013 From: wk at gnupg.org (Werner Koch) Date: Fri, 08 Mar 2013 22:48:33 +0100 Subject: [PATCH 3/3] mpi: Add an API for EC math. Message-ID: <87zjyda7gu.fsf@vigenere.g10code.de> * src/context.c, src/context.h: New. * src/Makefile.am (libgcrypt_la_SOURCES): Add new files. * src/gcrypt.h.in (struct gcry_context, gcry_ctx_t): New types. (gcry_ctx_release): New prototype. (gcry_mpi_ec_p_new, gcry_mpi_ec_get_affine, gcry_mpi_ec_dup) (gcry_mpi_ec_add, gcry_mpi_ec_mul): New prototypes. * mpi/ec.c: Include errno.h and context.h. (_gcry_mpi_ec_init): Rename to .. (ec_p_init): this, make static, remove allocation and add arg CTX. (_gcry_mpi_ec_p_internal_new): New; to replace _gcry_mpi_ec_init. Change all callers to use this func. (_gcry_mpi_ec_free): Factor code out to .. (ec_deinit): New func. (gcry_mpi_ec_p_new): New. * src/visibility.c: Include context.h and mpi.h. (gcry_mpi_ec_p_new, gcry_mpi_ec_get_affine, gcry_mpi_ec_dup) (gcry_mpi_ec_add, gcry_mpi_ec_mul) (gcry_ctx_release): New wrapper functions. * src/visibility.h: Mark new wrapper functions visible. * src/libgcrypt.def, src/libgcrypt.vers: Add new symbols. * tests/t-mpi-point.c (print_mpi, hex2mpi, cmp_mpihex): New. (context_alloc): New. (make_point, basic_ec_math): New. -- This part finishes the basic API to do EC math. It provides a wrapper around all internal functions. tests/t-mpi-point.c may be useful as sample code. Eventually we will add function to retrieve curve parameters etc. --- NEWS | 6 ++ cipher/ecc.c | 14 ++-- mpi/ec.c | 84 ++++++++++++++++++++------ src/Makefile.am | 2 +- src/context.c | 118 +++++++++++++++++++++++++++++++++++ src/context.h | 31 +++++++++ src/gcrypt.h.in | 27 ++++++++ src/libgcrypt.def | 8 +++ src/libgcrypt.vers | 4 + src/mpi.h | 2 +- src/visibility.c | 46 +++++++++++++- src/visibility.h | 12 ++++ tests/t-mpi-point.c | 170 ++++++++++++++++++++++++++++++++++++++++++++++++++- 13 files changed, 493 insertions(+), 31 deletions(-) create mode 100644 src/context.c create mode 100644 src/context.h diff --git a/NEWS b/NEWS index e0ba536..733dd88 100644 --- a/NEWS +++ b/NEWS @@ -44,6 +44,12 @@ Noteworthy changes in version 1.6.0 (unreleased) gcry_mpi_point_snatch_get NEW. gcry_mpi_point_set NEW. gcry_mpi_point_snatch_set NEW. + gcry_ctx_t NEW. + gcry_ctx_release NEW. + gcry_mpi_ec_p_new NEW. + gcry_mpi_ec_dup NEW. + gcry_mpi_ec_add NEW. + gcry_mpi_ec_mul NEW. Noteworthy changes in version 1.5.0 (2011-06-29) diff --git a/cipher/ecc.c b/cipher/ecc.c index 789fc6c..4efbef4 100644 --- a/cipher/ecc.c +++ b/cipher/ecc.c @@ -547,7 +547,7 @@ generate_key (ECC_secret_key *sk, unsigned int nbits, const char *name, /* Compute Q. */ point_init (&Q); - ctx = _gcry_mpi_ec_init (E.p, E.a); + ctx = _gcry_mpi_ec_p_internal_new (E.p, E.a); _gcry_mpi_ec_mul_point (&Q, d, &E.G, ctx); /* Copy the stuff to the key structures. */ @@ -672,7 +672,7 @@ check_secret_key (ECC_secret_key * sk) goto leave; } - ctx = _gcry_mpi_ec_init (sk->E.p, sk->E.a); + ctx = _gcry_mpi_ec_p_internal_new (sk->E.p, sk->E.a); _gcry_mpi_ec_mul_point (&Q, sk->E.n, &sk->E.G, ctx); if (mpi_cmp_ui (Q.z, 0)) @@ -733,7 +733,7 @@ sign (gcry_mpi_t input, ECC_secret_key *skey, gcry_mpi_t r, gcry_mpi_t s) mpi_set_ui (s, 0); mpi_set_ui (r, 0); - ctx = _gcry_mpi_ec_init (skey->E.p, skey->E.a); + ctx = _gcry_mpi_ec_p_internal_new (skey->E.p, skey->E.a); while (!mpi_cmp_ui (s, 0)) /* s == 0 */ { @@ -805,7 +805,7 @@ verify (gcry_mpi_t input, ECC_public_key *pkey, gcry_mpi_t r, gcry_mpi_t s) point_init (&Q1); point_init (&Q2); - ctx = _gcry_mpi_ec_init (pkey->E.p, pkey->E.a); + ctx = _gcry_mpi_ec_p_internal_new (pkey->E.p, pkey->E.a); /* h = s^(-1) (mod n) */ mpi_invm (h, s, pkey->E.n); @@ -1095,7 +1095,7 @@ ecc_get_param (const char *name, gcry_mpi_t *pkey) g_x = mpi_new (0); g_y = mpi_new (0); - ctx = _gcry_mpi_ec_init (E.p, E.a); + ctx = _gcry_mpi_ec_p_internal_new (E.p, E.a); if (_gcry_mpi_ec_get_affine (g_x, g_y, &E.G, ctx)) log_fatal ("ecc get param: Failed to get affine coordinates\n"); _gcry_mpi_ec_free (ctx); @@ -1424,7 +1424,7 @@ ecc_encrypt_raw (int algo, gcry_mpi_t *resarr, gcry_mpi_t k, return err; } - ctx = _gcry_mpi_ec_init (pk.E.p, pk.E.a); + ctx = _gcry_mpi_ec_p_internal_new (pk.E.p, pk.E.a); /* The following is false: assert( mpi_cmp_ui( R.x, 1 )==0 );, so */ { @@ -1536,7 +1536,7 @@ ecc_decrypt_raw (int algo, gcry_mpi_t *result, gcry_mpi_t *data, } sk.d = skey[6]; - ctx = _gcry_mpi_ec_init (sk.E.p, sk.E.a); + ctx = _gcry_mpi_ec_p_internal_new (sk.E.p, sk.E.a); /* R = dkG */ point_init (&R); diff --git a/mpi/ec.c b/mpi/ec.c index bb9bea4..e85ec04 100644 --- a/mpi/ec.c +++ b/mpi/ec.c @@ -21,10 +21,12 @@ #include #include #include +#include #include "mpi-internal.h" #include "longlong.h" #include "g10lib.h" +#include "context.h" #define point_init(a) _gcry_mpi_point_init ((a)) @@ -348,16 +350,13 @@ ec_invm (gcry_mpi_t x, gcry_mpi_t a, mpi_ec_t ctx) -/* This function returns a new context for elliptic curve based on the - field GF(p). P is the prime specifying thuis field, A is the first - coefficient. - - This context needs to be released using _gcry_mpi_ec_free. */ -mpi_ec_t -_gcry_mpi_ec_init (gcry_mpi_t p, gcry_mpi_t a) +/* This function initialized a context for elliptic curve based on the + field GF(p). P is the prime specifying this field, A is the first + coefficient. CTX is expected to be zeroized. */ +static void +ec_p_init (mpi_ec_t ctx, gcry_mpi_t p, gcry_mpi_t a) { int i; - mpi_ec_t ctx; gcry_mpi_t tmp; mpi_normalize (p); @@ -367,8 +366,6 @@ _gcry_mpi_ec_init (gcry_mpi_t p, gcry_mpi_t a) a < p */ - ctx = gcry_xcalloc (1, sizeof *ctx); - ctx->p = mpi_copy (p); ctx->a = mpi_copy (a); @@ -408,18 +405,15 @@ _gcry_mpi_ec_init (gcry_mpi_t p, gcry_mpi_t a) /* ctx->s[i] = mpi_new (384); */ /* ctx->c = mpi_new (384*2); */ /* } */ - - return ctx; } -void -_gcry_mpi_ec_free (mpi_ec_t ctx) + +static void +ec_deinit (void *opaque) { + mpi_ec_t ctx = opaque; int i; - if (!ctx) - return; - mpi_free (ctx->p); mpi_free (ctx->a); @@ -446,8 +440,62 @@ _gcry_mpi_ec_free (mpi_ec_t ctx) /* mpi_free (ctx->s[i]); */ /* mpi_free (ctx->c); */ /* } */ +} + - gcry_free (ctx); +/* This function returns a new context for elliptic curve based on the + field GF(p). P is the prime specifying this field, A is the first + coefficient. This function is only used within Libgcrypt and not + part of the public API. + + This context needs to be released using _gcry_mpi_ec_free. */ +mpi_ec_t +_gcry_mpi_ec_p_internal_new (gcry_mpi_t p, gcry_mpi_t a) +{ + mpi_ec_t ctx; + + ctx = gcry_xcalloc (1, sizeof *ctx); + ec_p_init (ctx, p, a); + + return ctx; +} + + +void +_gcry_mpi_ec_free (mpi_ec_t ctx) +{ + if (ctx) + { + ec_deinit (ctx); + gcry_free (ctx); + } +} + + +/* This function returns a new context for elliptic curve operations + based on the field GF(p). P is the prime specifying this field, A + is the first coefficient. This function is part of the public API. + On error this function returns NULL and sets ERRNO. + The context needs to be released using gcry_ctx_release. */ +gcry_ctx_t +gcry_mpi_ec_p_new (gcry_mpi_t p, gcry_mpi_t a) +{ + gcry_ctx_t ctx; + mpi_ec_t ec; + + if (!p || !a || !mpi_cmp_ui (a, 0)) + { + gpg_err_set_errno (EINVAL); + return NULL; + } + + ctx = _gcry_ctx_alloc (CONTEXT_TYPE_EC, sizeof *ec, ec_deinit); + if (!ctx) + return NULL; + ec = _gcry_ctx_get_pointer (ctx, CONTEXT_TYPE_EC); + ec_p_init (ec, p, a); + + return ctx; } diff --git a/src/Makefile.am b/src/Makefile.am index 9e7dcd5..1869ad3 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -59,7 +59,7 @@ libgcrypt_la_SOURCES = g10lib.h visibility.c visibility.h types.h \ misc.c global.c sexp.c hwfeatures.c hwf-common.h \ stdmem.c stdmem.h secmem.c secmem.h \ mpi.h missing-string.c module.c fips.c \ - hmac256.c hmac256.h \ + hmac256.c hmac256.h context.c context.h \ ath.h ath.c EXTRA_libgcrypt_la_SOURCES = hwf-x86.c diff --git a/src/context.c b/src/context.c new file mode 100644 index 0000000..ae991c5 --- /dev/null +++ b/src/context.c @@ -0,0 +1,118 @@ +/* context.c - Context management + * 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 . + */ + +#include +#include +#include +#include +#include +#include + +#include "g10lib.h" +#include "mpi.h" +#include "context.h" + +#define CTX_MAGIC "cTx" +#define CTX_MAGIC_LEN 3 + + +/* The definition of the generic context object. The public typedef + gcry_ctx_t is used to access it. */ +struct gcry_context +{ + char magic[CTX_MAGIC_LEN]; /* Magic value to cross check that this + is really a context object. */ + char type; /* The type of the context (CONTEXT_TYPE_foo). */ + + void (*deinit)(void*); /* Function used to free the private part. */ + PROPERLY_ALIGNED_TYPE u; +}; + + +/* Allocate a fresh generic context of contect TYPE and allocate + LENGTH extra bytes for private use of the type handler. DEINIT is a + fucntion used called to deinitialize the private part; it may be + NULL if de-initialization is not required. Returns NULL and sets + ERRNO if memory allocation failed. */ +gcry_ctx_t +_gcry_ctx_alloc (int type, size_t length, void (*deinit)(void*)) +{ + gcry_ctx_t ctx; + + switch (type) + { + case CONTEXT_TYPE_EC: + break; + default: + log_bug ("bad context type %d given to _gcry_ctx_alloc\n", type); + break; + } + + if (length < sizeof (PROPERLY_ALIGNED_TYPE)) + length = sizeof (PROPERLY_ALIGNED_TYPE); + + ctx = gcry_calloc (1, sizeof *ctx - sizeof (PROPERLY_ALIGNED_TYPE) + length); + if (!ctx) + return NULL; + memcpy (ctx->magic, CTX_MAGIC, CTX_MAGIC_LEN); + ctx->type = type; + ctx->deinit = deinit; + + return ctx; +} + + +/* Return a pointer to the private part of the context CTX. TYPE is + the requested context type. Using an explicit type allows to cross + check the type and eventually allows to store several private + contexts in one context object. The function does not return an + error but aborts if the provided CTX is not valid. */ +void * +_gcry_ctx_get_pointer (gcry_ctx_t ctx, int type) +{ + if (memcmp (ctx->magic, CTX_MAGIC, CTX_MAGIC_LEN)) + log_fatal ("bad pointer %p passed to _gcry_ctx_get_pointer\n", ctx); + if (ctx->type != type) + log_fatal ("wrong context type %d request for context %p of type %d\n", + type, ctx, ctx->type); + return &ctx->u; +} + + +/* Release the generic context CTX. */ +void +gcry_ctx_release (gcry_ctx_t ctx) +{ + if (!ctx) + return; + if (memcmp (ctx->magic, CTX_MAGIC, CTX_MAGIC_LEN)) + log_fatal ("bad pointer %p passed to gcry_ctx_relase\n", ctx); + switch (ctx->type) + { + case CONTEXT_TYPE_EC: + break; + default: + log_fatal ("bad context type %d detected in gcry_ctx_relase\n", + ctx->type); + break; + } + if (ctx->deinit) + ctx->deinit (&ctx->u); + gcry_free (ctx); +} diff --git a/src/context.h b/src/context.h new file mode 100644 index 0000000..72f14d4 --- /dev/null +++ b/src/context.h @@ -0,0 +1,31 @@ +/* context.h - Declarations for the context management + * 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 . + */ + +#ifndef GCRY_CONTEXT_H +#define GCRY_CONTEXT_H + +/* Context types as used in struct gcry_context. */ +#define CONTEXT_TYPE_EC 1 /* The context is used with EC functions. */ + + +gcry_ctx_t _gcry_ctx_alloc (int type, size_t length, void (*deinit)(void*)); +void *_gcry_ctx_get_pointer (gcry_ctx_t ctx, int type); + + +#endif /*GCRY_CONTEXT_H*/ diff --git a/src/gcrypt.h.in b/src/gcrypt.h.in index 5d2a779..57b841e 100644 --- a/src/gcrypt.h.in +++ b/src/gcrypt.h.in @@ -212,6 +212,10 @@ struct gcry_thread_cbs +/* A generic context object as used by some functions. */ +struct gcry_context; +typedef struct gcry_context *gcry_ctx_t; + /* The data objects used to hold multi precision integers. */ struct gcry_mpi; typedef struct gcry_mpi *gcry_mpi_t; @@ -599,6 +603,26 @@ 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); +/* Allocate a new context for elliptic curve operations based on the + field GF(p). P is the prime specifying this field, A is the first + coefficient. Returns NULL on error. */ +gcry_ctx_t gcry_mpi_ec_p_new (gcry_mpi_t p, gcry_mpi_t a); + +/* Store the affine coordinates of POINT into X and Y. */ +int gcry_mpi_ec_get_affine (gcry_mpi_t x, gcry_mpi_t y, gcry_mpi_point_t point, + gcry_ctx_t ctx); + +/* W = 2 * U. */ +void gcry_mpi_ec_dup (gcry_mpi_point_t w, gcry_mpi_point_t u, gcry_ctx_t ctx); + +/* W = U + V. */ +void gcry_mpi_ec_add (gcry_mpi_point_t w, + gcry_mpi_point_t u, gcry_mpi_point_t v, gcry_ctx_t ctx); + +/* W = N * U. */ +void gcry_mpi_ec_mul (gcry_mpi_point_t w, gcry_mpi_t n, gcry_mpi_point_t u, + gcry_ctx_t ctx); + /* Return the number of bits required to represent A. */ unsigned int gcry_mpi_get_nbits (gcry_mpi_t a); @@ -1294,6 +1318,9 @@ gcry_error_t gcry_prime_check (gcry_mpi_t x, unsigned int flags); * * ************************************/ +/* Release the context object CTX. */ +void gcry_ctx_release (gcry_ctx_t ctx); + /* Log levels used by the internal logging facility. */ enum gcry_log_levels { diff --git a/src/libgcrypt.def b/src/libgcrypt.def index 8f14dff..611f10f 100644 --- a/src/libgcrypt.def +++ b/src/libgcrypt.def @@ -220,3 +220,11 @@ EXPORTS gcry_mpi_point_snatch_get @199 gcry_mpi_point_set @200 gcry_mpi_point_snatch_set @201 + + gcry_ctx_release @202 + + gcry_mpi_ec_p_new @203 + gcry_mpi_ec_get_affine @204 + gcry_mpi_ec_dup @205 + gcry_mpi_ec_add @206 + gcry_mpi_ec_mul @207 diff --git a/src/libgcrypt.vers b/src/libgcrypt.vers index 5c43b95..4a375b2 100644 --- a/src/libgcrypt.vers +++ b/src/libgcrypt.vers @@ -90,7 +90,11 @@ GCRYPT_1.6 { 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; + gcry_mpi_ec_p_new; + gcry_mpi_ec_get_affine; + gcry_mpi_ec_dup; gcry_mpi_ec_add; gcry_mpi_ec_mul; + gcry_ctx_release; local: *; diff --git a/src/mpi.h b/src/mpi.h index b3f19e5..23afa68 100644 --- a/src/mpi.h +++ b/src/mpi.h @@ -251,7 +251,7 @@ void _gcry_mpi_snatch_point (gcry_mpi_t x, gcry_mpi_t y, gcry_mpi_t z, struct mpi_ec_ctx_s; typedef struct mpi_ec_ctx_s *mpi_ec_t; -mpi_ec_t _gcry_mpi_ec_init (gcry_mpi_t p, gcry_mpi_t a); +mpi_ec_t _gcry_mpi_ec_p_internal_new (gcry_mpi_t p, gcry_mpi_t a); void _gcry_mpi_ec_free (mpi_ec_t ctx); int _gcry_mpi_ec_get_affine (gcry_mpi_t x, gcry_mpi_t y, mpi_point_t point, mpi_ec_t ctx); diff --git a/src/visibility.c b/src/visibility.c index 1fb29f2..5c3216d 100644 --- a/src/visibility.c +++ b/src/visibility.c @@ -24,8 +24,8 @@ #define _GCRY_INCLUDED_BY_VISIBILITY_C #include "g10lib.h" #include "cipher-proto.h" - - +#include "context.h" +#include "mpi.h" const char * gcry_strerror (gcry_error_t err) @@ -461,6 +461,42 @@ gcry_mpi_point_snatch_set (gcry_mpi_point_t point, return _gcry_mpi_point_snatch_set (point, x, y, z); } +gcry_ctx_t +gcry_mpi_ec_p_new (gcry_mpi_t p, gcry_mpi_t a) +{ + return _gcry_mpi_ec_p_new (p, a); +} + +int +gcry_mpi_ec_get_affine (gcry_mpi_t x, gcry_mpi_t y, gcry_mpi_point_t point, + gcry_ctx_t ctx) +{ + return _gcry_mpi_ec_get_affine (x, y, point, + _gcry_ctx_get_pointer (ctx, CONTEXT_TYPE_EC)); +} + +void +gcry_mpi_ec_dup (gcry_mpi_point_t w, gcry_mpi_point_t u, gcry_ctx_t ctx) +{ + _gcry_mpi_ec_dup_point (w, u, _gcry_ctx_get_pointer (ctx, CONTEXT_TYPE_EC)); +} + +void +gcry_mpi_ec_add (gcry_mpi_point_t w, + gcry_mpi_point_t u, gcry_mpi_point_t v, gcry_ctx_t ctx) +{ + _gcry_mpi_ec_add_points (w, u, v, + _gcry_ctx_get_pointer (ctx, CONTEXT_TYPE_EC)); +} + +void +gcry_mpi_ec_mul (gcry_mpi_point_t w, gcry_mpi_t n, gcry_mpi_point_t u, + gcry_ctx_t ctx) +{ + _gcry_mpi_ec_mul_point (w, n, u, + _gcry_ctx_get_pointer (ctx, CONTEXT_TYPE_EC)); +} + unsigned int gcry_mpi_get_nbits (gcry_mpi_t a) { @@ -1067,6 +1103,12 @@ gcry_prime_check (gcry_mpi_t x, unsigned int flags) } void +gcry_ctx_release (gcry_ctx_t ctx) +{ + _gcry_ctx_release (ctx); +} + +void gcry_set_progress_handler (gcry_handler_progress_t cb, void *cb_data) { _gcry_set_progress_handler (cb, cb_data); diff --git a/src/visibility.h b/src/visibility.h index f4507ce..90c6ad1 100644 --- a/src/visibility.h +++ b/src/visibility.h @@ -154,6 +154,7 @@ #define gcry_mpi_copy _gcry_mpi_copy #define gcry_mpi_div _gcry_mpi_div #define gcry_mpi_dump _gcry_mpi_dump +#define gcry_mpi_ec_p_new _gcry_mpi_ec_p_new #define gcry_mpi_gcd _gcry_mpi_gcd #define gcry_mpi_get_flag _gcry_mpi_get_flag #define gcry_mpi_get_nbits _gcry_mpi_get_nbits @@ -192,6 +193,8 @@ #define gcry_mpi_swap _gcry_mpi_swap #define gcry_mpi_test_bit _gcry_mpi_test_bit +#define gcry_ctx_release _gcry_ctx_release + /* Include the main header here so that public symbols are mapped to the internal underscored ones. */ @@ -367,6 +370,7 @@ gcry_err_code_t gcry_md_get (gcry_md_hd_t hd, int algo, #undef gcry_mpi_copy #undef gcry_mpi_div #undef gcry_mpi_dump +#undef gcry_mpi_ec_p_new #undef gcry_mpi_gcd #undef gcry_mpi_get_flag #undef gcry_mpi_get_nbits @@ -405,6 +409,8 @@ gcry_err_code_t gcry_md_get (gcry_md_hd_t hd, int algo, #undef gcry_mpi_swap #undef gcry_mpi_test_bit +#undef gcry_ctx_release + /* Now mark all symbols. */ @@ -540,6 +546,11 @@ MARK_VISIBLE (gcry_mpi_cmp_ui) MARK_VISIBLE (gcry_mpi_copy) MARK_VISIBLE (gcry_mpi_div) MARK_VISIBLE (gcry_mpi_dump) +MARK_VISIBLEX(gcry_mpi_ec_add) +MARK_VISIBLEX(gcry_mpi_ec_dup) +MARK_VISIBLEX(gcry_mpi_ec_get_affine) +MARK_VISIBLEX(gcry_mpi_ec_mul) +MARK_VISIBLE (gcry_mpi_ec_p_new) MARK_VISIBLE (gcry_mpi_gcd) MARK_VISIBLE (gcry_mpi_get_flag) MARK_VISIBLE (gcry_mpi_get_nbits) @@ -578,6 +589,7 @@ MARK_VISIBLE (gcry_mpi_subm) MARK_VISIBLE (gcry_mpi_swap) MARK_VISIBLE (gcry_mpi_test_bit) +MARK_VISIBLE (gcry_ctx_release) #undef MARK_VISIBLE diff --git a/tests/t-mpi-point.c b/tests/t-mpi-point.c index 548d6c7..8714d38 100644 --- a/tests/t-mpi-point.c +++ b/tests/t-mpi-point.c @@ -32,8 +32,10 @@ static const char *wherestr; static int verbose; +static int debug; static int error_count; + #define xmalloc(a) gcry_xmalloc ((a)) #define xcalloc(a,b) gcry_xcalloc ((a),(b)) #define xfree(a) gcry_free ((a)) @@ -83,6 +85,52 @@ die (const char *format, ...) } +static void +print_mpi (const char *text, gcry_mpi_t a) +{ + gcry_error_t err; + char *buf; + void *bufaddr = &buf; + + err = gcry_mpi_aprint (GCRYMPI_FMT_HEX, bufaddr, NULL, a); + if (err) + fprintf (stderr, "%s: [error printing number: %s]\n", + text, gpg_strerror (err)); + else + { + fprintf (stderr, "%s: %s\n", text, buf); + gcry_free (buf); + } +} + + +static gcry_mpi_t +hex2mpi (const char *string) +{ + gpg_error_t err; + gcry_mpi_t val; + + err = gcry_mpi_scan (&val, GCRYMPI_FMT_HEX, string, 0, NULL); + if (err) + die ("hex2mpi '%s' failed: %s\n", gpg_strerror (err)); + return val; +} + + +/* Compare A to B, where B is given as a hex string. */ +static int +cmp_mpihex (gcry_mpi_t a, const char *b) +{ + gcry_mpi_t bval; + int res; + + bval = hex2mpi (b); + res = gcry_mpi_cmp (a, bval); + gcry_mpi_release (bval); + return res; +} + + static void set_get_point (void) @@ -138,10 +186,127 @@ set_get_point (void) } +static void +context_alloc (void) +{ + gcry_ctx_t ctx; + gcry_mpi_t p, a; + + wherestr = "context_alloc"; + show ("checking context functions\n"); + + p = gcry_mpi_set_ui (NULL, 1); + a = gcry_mpi_set_ui (NULL, 1); + ctx = gcry_mpi_ec_p_new (p, a); + if (!ctx) + die ("gcry_mpi_ec_p_new returned an error: %s\n", + gpg_strerror (gpg_error_from_syserror ())); + gcry_mpi_release (p); + gcry_mpi_release (a); + gcry_ctx_release (ctx); + + p = gcry_mpi_set_ui (NULL, 0); + a = gcry_mpi_set_ui (NULL, 0); + ctx = gcry_mpi_ec_p_new (p, a); + if (ctx || gpg_err_code_from_syserror () != GPG_ERR_EINVAL) + fail ("gcry_mpi_ec_p_new: bad parameter detection failed (1)\n"); + + gcry_mpi_set_ui (p, 1); + ctx = gcry_mpi_ec_p_new (p, a); + if (ctx || gpg_err_code_from_syserror () != GPG_ERR_EINVAL) + fail ("gcry_mpi_ec_p_new: bad parameter detection failed (2)\n"); + + gcry_mpi_release (p); + p = NULL; + ctx = gcry_mpi_ec_p_new (p, a); + if (ctx || gpg_err_code_from_syserror () != GPG_ERR_EINVAL) + fail ("gcry_mpi_ec_p_new: bad parameter detection failed (3)\n"); + + gcry_mpi_release (a); + a = NULL; + ctx = gcry_mpi_ec_p_new (p, a); + if (ctx || gpg_err_code_from_syserror () != GPG_ERR_EINVAL) + fail ("gcry_mpi_ec_p_new: bad parameter detection failed (4)\n"); + +} + + +/* Create a new point from (X,Y,Z) given as hex strings. */ +gcry_mpi_point_t +make_point (const char *x, const char *y, const char *z) +{ + gcry_mpi_point_t point; + + point = gcry_mpi_point_new (0); + gcry_mpi_point_snatch_set (point, hex2mpi (x), hex2mpi (y), hex2mpi (z)); + + return point; +} + + +static void +basic_ec_math (void) +{ + gcry_ctx_t ctx; + gcry_mpi_t P, A; + gcry_mpi_point_t G, Q; + gcry_mpi_t d; + gcry_mpi_t x, y, z; + + wherestr = "set_get_point"; + show ("checking basic math functions for EC\n"); + + P = hex2mpi ("0xfffffffffffffffffffffffffffffffeffffffffffffffff"); + A = hex2mpi ("0xfffffffffffffffffffffffffffffffefffffffffffffffc"); + G = make_point ("188DA80EB03090F67CBF20EB43A18800F4FF0AFD82FF1012", + "7192B95FFC8DA78631011ED6B24CDD573F977A11E794811", + "1"); + d = hex2mpi ("D4EF27E32F8AD8E2A1C6DDEBB1D235A69E3CEF9BCE90273D"); + Q = gcry_mpi_point_new (0); + + ctx = gcry_mpi_ec_p_new (P, A); + gcry_mpi_ec_mul (Q, d, G, ctx); + + x = gcry_mpi_new (0); + y = gcry_mpi_new (0); + z = gcry_mpi_new (0); + gcry_mpi_point_get (x, y, z, Q); + if (cmp_mpihex (x, "222D9EC717C89D047E0898C9185B033CD11C0A981EE6DC66") + || cmp_mpihex (y, "605DE0A82D70D3E0F84A127D0739ED33D657DF0D054BFDE8") + || cmp_mpihex (z, "00B06B519071BC536999AC8F2D3934B3C1FC9EACCD0A31F88F")) + fail ("computed public key does not match\n"); + if (debug) + { + print_mpi ("Q.x", x); + print_mpi ("Q.y", y); + print_mpi ("Q.z", z); + } + + if (gcry_mpi_ec_get_affine (x, y, Q, ctx)) + fail ("failed to get affine coordinates\n"); + if (cmp_mpihex (x, "008532093BA023F4D55C0424FA3AF9367E05F309DC34CDC3FE") + || cmp_mpihex (y, "00C13CA9E617C6C8487BFF6A726E3C4F277913D97117939966")) + fail ("computed affine coordinates of public key do not match\n"); + if (debug) + { + print_mpi ("q.x", x); + print_mpi ("q.y", y); + } + + gcry_mpi_release (z); + gcry_mpi_release (y); + gcry_mpi_release (x); + gcry_mpi_point_release (Q); + gcry_mpi_release (d); + gcry_mpi_point_release (G); + gcry_mpi_release (A); + gcry_mpi_release (P); +} + + int main (int argc, char **argv) { - int debug = 0; if (argc > 1 && !strcmp (argv[1], "--verbose")) verbose = 1; @@ -158,7 +323,8 @@ main (int argc, char **argv) gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0); set_get_point (); - + context_alloc (); + basic_ec_math (); 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. From christian at grothoff.org Fri Mar 8 23:46:08 2013 From: christian at grothoff.org (Christian Grothoff) Date: Fri, 08 Mar 2013 23:46:08 +0100 Subject: mpi: EC point operations [discussion] Message-ID: <513A6A30.80603@grothoff.org> Hi Werner, Looking at your three patches, I think they should in theory suffice to implement ECDH using libgcrypt; however, the mismatch between the s-expression based public key APIs to create signatures (ECDSA) and the low-level MPI-API is pretty rough from a user's perspective. First of all, I didn't find how I would take a point from an S-expression (gcry_sexp_t) and convert that to a gcry_mpi_point_t. So that function would definitively still be needed to bridge the high and low-level APIs. Even with that, the result would still be a bit ugly. Right now, I generate a key with: gcry_sexp_build (&s_keyparam, NULL, "(genkey(ecdsa(curve \"NIST P256\"))))"); gcry_pk_genkey (&s_key, s_keyparam); this key I can then use for ECDSA. If I wanted to use it for ECDH, I would have to manually parse the S-expression and extract P, A, Q, d, G to run the gcry_mpi_ec_mul function that your testcase invokes as follows: + P = hex2mpi ("0xfffffffffffffffffffffffffffffffeffffffffffffffff"); + A = hex2mpi ("0xfffffffffffffffffffffffffffffffefffffffffffffffc"); + G = make_point ("188DA80EB03090F67CBF20EB43A18800F4FF0AFD82FF1012", + "7192B95FFC8DA78631011ED6B24CDD573F977A11E794811", + "1"); + d = hex2mpi ("D4EF27E32F8AD8E2A1C6DDEBB1D235A69E3CEF9BCE90273D"); + Q = gcry_mpi_point_new (0); + + ctx = gcry_mpi_ec_p_new (P, A); + gcry_mpi_ec_mul (Q, d, G, ctx); So having a higher-level API that can --- instead of a manually constructed 'ctx' --- take the "s_key" S-expression and 'd' and returns 'Q' would certainly be a nice extension. Note that I'm not suggesting to remove the low-level API your patches added; I'm generally not always happy that I have to box and unbox everything in S-expressions, but in cases where they are already in use (i.e. because of gcry_pk_*-operations), it would make sense to me to make the transition between the high- and low-level APIs as painless as possible. Finally, with respect to highly optimized code for a particular curve (like the ED25519 curve), I wonder if you'd not want some "other" means to initialize that 'ctx', say with a bunch of function pointers that point to curve-specific optimized operations. Right now, the gcry_mpi_ec_p_new function would have to do some semi-ugly test to check if the curve parameters happened to match a specialized curve to then use the custom logic. Having a way to initialize certain curves by name (or enum) would also make it trivial to replace generic ECC operator implementations with optimized versions. My 2 cents for tonight! Happy hacking! -Christian p.s.: I didn't see these in Git master; is there a branch I should be looking at? From wk at gnupg.org Mon Mar 11 09:15:15 2013 From: wk at gnupg.org (Werner Koch) Date: Mon, 11 Mar 2013 09:15:15 +0100 Subject: mpi: EC point operations [discussion] In-Reply-To: <513A6A30.80603@grothoff.org> (Christian Grothoff's message of "Fri, 08 Mar 2013 23:46:08 +0100") References: <513A6A30.80603@grothoff.org> Message-ID: <877gle8i98.fsf@vigenere.g10code.de> On Fri, 8 Mar 2013 23:46, christian at grothoff.org said: > using libgcrypt; however, the mismatch between the s-expression based public key > APIs to create signatures (ECDSA) and the low-level MPI-API is pretty rough from a > user's perspective. Agreed. Right now we only have a low level API for some math fucntions. This is similar to the RSA and the raw MPI functions. > + ctx = gcry_mpi_ec_p_new (P, A); I had the idea to add some more optional arguments to that function but then decided against it. As of now, this function is basically the same as the internally used one. A useful and more generic additional function would be ctx = gcry_mpi_ec_new ("(curve \"NIST P256\")"); and for ease of use would also accept the genkey parameter set like ctx = gcry_mpi_ec_new ("(genkey(ecdsa(curve \"NIST P256\")))") this solves parsing the s-exp for P and A. To retrieve the key parameters (or whatever) from the context I can image these functions: mpi = gcry_mpi_ec_get_mpi ("d", ctx); point = gcry_mpi_ec_get_point ("G", ctx) This requires additionalallocation etc. but it is a quite generic way to retrieve the needed values. > So having a higher-level API that can --- instead of a manually constructed 'ctx' --- take > the "s_key" S-expression and 'd' and returns 'Q' would certainly be a nice extension. See above. > but in cases where they are already in use (i.e. because of gcry_pk_*-operations), it > would make sense to me to make the transition between the high- and low-level APIs > as painless as possible. We have to see how we can optimize that further. > I wonder if you'd not want some "other" means to initialize that 'ctx', say with a bunch of > function pointers that point to curve-specific optimized operations. Right now, the That would be an internal operation and invisible to the API. Thus it can be done at any time without changing the API. gcry_mpi_ec_set_mpi ("d", mpi, ctx); gcry_mpi_ec_set_point ("G", point, ctx) might be auseful extension as well. > p.s.: I didn't see these in Git master; is there a branch I should be > looking I have a private branch for now. If you think the current interface and my proposed extensions are okay I can push that to master. Salam-Shalom, Werner -- Die Gedanken sind frei. Ausnahmen regelt ein Bundesgesetz. From christian at grothoff.org Mon Mar 11 09:28:14 2013 From: christian at grothoff.org (Christian Grothoff) Date: Mon, 11 Mar 2013 09:28:14 +0100 Subject: mpi: EC point operations [discussion] In-Reply-To: <877gle8i98.fsf@vigenere.g10code.de> References: <513A6A30.80603@grothoff.org> <877gle8i98.fsf@vigenere.g10code.de> Message-ID: <513D959E.7070703@grothoff.org> On 03/11/2013 09:15 AM, Werner Koch wrote: > On Fri, 8 Mar 2013 23:46, christian at grothoff.org said: > >> using libgcrypt; however, the mismatch between the s-expression based public key >> APIs to create signatures (ECDSA) and the low-level MPI-API is pretty rough from a >> user's perspective. > Agreed. Right now we only have a low level API for some math fucntions. > This is similar to the RSA and the raw MPI functions. > >> + ctx = gcry_mpi_ec_p_new (P, A); > I had the idea to add some more optional arguments to that function but > then decided against it. As of now, this function is basically the same > as the internally used one. A useful and more generic additional > function would be > > ctx = gcry_mpi_ec_new ("(curve \"NIST P256\")"); > > and for ease of use would also accept the genkey parameter set like > > ctx = gcry_mpi_ec_new ("(genkey(ecdsa(curve \"NIST P256\")))") > > this solves parsing the s-exp for P and A. To retrieve the key > parameters (or whatever) from the context I can image these functions: > > mpi = gcry_mpi_ec_get_mpi ("d", ctx); > point = gcry_mpi_ec_get_point ("G", ctx) > > This requires additionalallocation etc. but it is a quite generic way to > retrieve the needed values. Yes, that exact API would be beautiful. >> So having a higher-level API that can --- instead of a manually constructed 'ctx' --- take >> the "s_key" S-expression and 'd' and returns 'Q' would certainly be a nice extension. > See above. > >> but in cases where they are already in use (i.e. because of gcry_pk_*-operations), it >> would make sense to me to make the transition between the high- and low-level APIs >> as painless as possible. > We have to see how we can optimize that further. Once you have the proposed gcry_mpi_ec_new, you can easily add the hacks for this into the ctx-construction based on the name of the curve. >> I wonder if you'd not want some "other" means to initialize that 'ctx', say with a bunch of >> function pointers that point to curve-specific optimized operations. Right now, the > That would be an internal operation and invisible to the API. Thus it > can be done at any time without changing the API. > > gcry_mpi_ec_set_mpi ("d", mpi, ctx); > gcry_mpi_ec_set_point ("G", point, ctx) > > might be auseful extension as well. I very much agree. >> p.s.: I didn't see these in Git master; is there a branch I should be >> looking > I have a private branch for now. If you think the current interface and > my proposed extensions are okay I can push that to master. I see. With the extensions discussed here, I think it should be sufficient for at least my purpose ;-). Let me know once the changes have hit master ;-). Happy hacking! Christian From wk at gnupg.org Mon Mar 11 15:58:06 2013 From: wk at gnupg.org (Werner Koch) Date: Mon, 11 Mar 2013 15:58:06 +0100 Subject: mpi: EC point operations [discussion] In-Reply-To: <513D959E.7070703@grothoff.org> (Christian Grothoff's message of "Mon, 11 Mar 2013 09:28:14 +0100") References: <513A6A30.80603@grothoff.org> <877gle8i98.fsf@vigenere.g10code.de> <513D959E.7070703@grothoff.org> Message-ID: <87620y6l1d.fsf@vigenere.g10code.de> On Mon, 11 Mar 2013 09:28, christian at grothoff.org said: > my purpose ;-). Let me know once the changes have hit master ;-). I have not yet implemented the proposed functions but documented the functions from the patches and pushed them to master. Salam-Shalom, Werner -- Die Gedanken sind frei. Ausnahmen regelt ein Bundesgesetz. From wk at gnupg.org Fri Mar 15 14:59:11 2013 From: wk at gnupg.org (Werner Koch) Date: Fri, 15 Mar 2013 14:59:11 +0100 Subject: mpi: EC point operations [discussion] In-Reply-To: <87620y6l1d.fsf@vigenere.g10code.de> (Werner Koch's message of "Mon, 11 Mar 2013 15:58:06 +0100") References: <513A6A30.80603@grothoff.org> <877gle8i98.fsf@vigenere.g10code.de> <513D959E.7070703@grothoff.org> <87620y6l1d.fsf@vigenere.g10code.de> Message-ID: <878v5o228g.fsf@vigenere.g10code.de> On Mon, 11 Mar 2013 15:58, wk at gnupg.org said: > I have not yet implemented the proposed functions but documented the > functions from the patches and pushed them to master. I just pushed them to master. Note that there are some minor changes to my original suggestion. See tests/t-mpi-point.c and the manual on how to use this stuff. Not everything has been tested, though. gcry_mpi_ec_p_n() has gone, it was not generic enough. I have still some more ideas on how to improve that, for example to directly get and set encoded points. Shalom-Salam, Werner -- Die Gedanken sind frei. Ausnahmen regelt ein Bundesgesetz. From wk at gnupg.org Mon Mar 18 17:13:55 2013 From: wk at gnupg.org (Werner Koch) Date: Mon, 18 Mar 2013 17:13:55 +0100 Subject: Libgcrypt 1.5.1 released Message-ID: <87zjy08z3w.fsf@vigenere.g10code.de> Hello! The GNU project is pleased to announce the availability of Libgcrypt version 1.5.1. This is a maintenance release for the stable branch. Libgcrypt is a general purpose library of cryptographic building blocks. It is originally based on code used by GnuPG. It does not provide any implementation of OpenPGP or other protocols. Thorough understanding of applied cryptography is required to use Libgcrypt. Noteworthy changes in version 1.5.1: * Allow empty passphrase with PBKDF2. * Do not abort on an invalid algorithm number in gcry_cipher_get_algo_keylen and gcry_cipher_get_algo_blklen. * Fixed some Valgrind warnings. * Fixed a problem with select and high fd numbers. * Improved the build system * Various minor bug fixes. * Interface changes relative to the 1.5.0 release: GCRYCTL_SET_ENFORCED_FIPS_FLAG NEW. GCRYPT_VERSION_NUMBER NEW. Source code is hosted at the GnuPG FTP server and its mirrors as listed at http://www.gnupg.org/download/mirrors.html . On the primary server the source file and its digital signature is: ftp://ftp.gnupg.org/gcrypt/libgcrypt/libgcrypt-1.5.1.tar.bz2 (1468k) ftp://ftp.gnupg.org/gcrypt/libgcrypt/libgcrypt-1.5.1.tar.bz2.sig This file is bzip2 compressed. A gzip compressed version is also available: ftp://ftp.gnupg.org/gcrypt/libgcrypt/libgcrypt-1.5.1.tar.gz (1741k) ftp://ftp.gnupg.org/gcrypt/libgcrypt/libgcrypt-1.5.1.tar.gz.sig Alternativley you may upgrade version 1.5.0 using this patch file: ftp://ftp.gnupg.org/gcrypt/libgcrypt/libgcrypt-1.5.0-1.5.1.diff.bz2 (255k) The SHA-1 checksums are: 8b60a26b7eae1a727d58932d6b1efeb5716648ed libgcrypt-1.5.1.tar.bz2 f1ab9ce6ac8c7370d455c77c96b36bf18e2d9c95 libgcrypt-1.5.1.tar.gz e1b2f59a8771e8a0358dbd9a8eaa3250015cf49e libgcrypt-1.5.0-1.5.1.diff.bz2 For help on developing with Libgcrypt you should read the included manual and optional ask on the gcrypt-devel mailing list [1]. A listing with commercial support offers for Libgcrypt and related software is available at the GnuPG web site [2]. The driving force behind the development of Libgcrypt is my company g10 Code. Maintenance and improvement of Libgcrypt and related software takes up most of our resources. To allow us to continue our work on free software, we ask to either purchase a support contract, engage us for custom enhancements, or to donate money: http://g10code.com/gnupg-donation.html Many thanks to all who contributed to Libgcrypt development, be it bug fixes, code, documentation, testing or helping users. Happy hacking, Werner [1] See http://www.gnupg.org/documentation/mailing-lists.html . [2] See http://www.gnupg.org/service.html -- Die Gedanken sind frei. Ausnahmen regelt ein Bundesgesetz. -------------- next part -------------- A non-text attachment was scrubbed... Name: not available Type: application/pgp-signature Size: 204 bytes Desc: not available URL: From itsango at gmail.com Mon Mar 18 23:33:44 2013 From: itsango at gmail.com (1xx) Date: Tue, 19 Mar 2013 07:33:44 +0900 Subject: It seems that http://lists.gnupg.org/mailman/listinfo/gcrypt-devel should be corrected. Message-ID: Hi . The http://lists.gnupg.org/mailman/listinfo/gcrypt-devel links http://lists.gnupg.org/pipermail/ . However, this is not right. I think that it should be changed into http://lists.gnupg.org/pipermail/gcrypt-devel/ . Thanks . 2013/1/30 1xx : > I tried to visit from > http://lists.gnupg.org/mailman/listinfo/gcrypt-devel to archives . > Thank you for teaching the right URL . > > 2013/1/30 Werner Koch : >> On Wed, 30 Jan 2013 02:08, itsango at gmail.com said: >> >>> However, http://lists.gnupg.org/pipermail/ is set to "403 Forbidden", >> >> What about using the correct URL which is >> >> http://lists.gnupg.org/pipermail/gcrypt-devel/ -- 1xx From lrn1986 at gmail.com Wed Mar 20 17:20:22 2013 From: lrn1986 at gmail.com (LRN) Date: Wed, 20 Mar 2013 20:20:22 +0400 Subject: Wrong use of -export-symbols in src/Makefile.am Message-ID: <5149E1C6.2060106@gmail.com> -----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 Currently src/Makefile.am reads: export_symbols = -export-symbols $(srcdir)/libgcrypt.def - -export-symbols is a libtool option. It expects to be given a list of symbols to export. The list is a plain list, one symbol name per line (no EXPORTS header). It is *NOT* a .def file. Libtool does *NOT* understand .def files. If you want to use a .def file, feed it to gcc directly, like any other source file. Thus, if fixing the order of exports using ordinals is your intent, then Makefile.am should read: export_symbols = $(srcdir)/libgcrypt.def -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.11 (MingW32) Comment: Using GnuPG with Thunderbird - http://www.enigmail.net/ iQEcBAEBAgAGBQJRSeHFAAoJEOs4Jb6SI2CwI4gH/jefDG0Vv3wPL1xuWjhdcbCZ F5/AoQNu4LuosITROxPktF032d/krI7NyqatK2lpITFnwT+MVuT1AQS8rKJlHOEW iufvQIlUIw0EWZ76bMX9zAL2Wvhjv9VvpPR0ARvAxUyL7pYH49Y8W3vAvqghVQNW 7uamO/0b0loYf2CaxzQVby9zqvUm9xG8Do763nss9dq1Gm2cQypBQFYqE5WmLrCZ OgU1kXNs+tUom+IlF5OKE+NLtNylKTUON76rBW7c9lfb7jbqsc/tzFNVwRbgAD/V A63DTRp86+FysRhV4qA16yGe2YoDsdhSmzLEViMP9SPiULIuLj7H0nU0tRcczmE= =4ozW -----END PGP SIGNATURE----- From lrn1986 at gmail.com Wed Mar 20 16:53:56 2013 From: lrn1986 at gmail.com (LRN) Date: Wed, 20 Mar 2013 19:53:56 +0400 Subject: Missing backslash in src/Makefile.am Message-ID: <5149DB94.3040709@gmail.com> -----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 git master HEAD, src/Makefile.am:111 -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.11 (MingW32) Comment: Using GnuPG with Thunderbird - http://www.enigmail.net/ iQEcBAEBAgAGBQJRSduUAAoJEOs4Jb6SI2Cw8rEH/jAi7fMY+xeqU1TLSCXDe6mR fTckqv1TbprY11aDyJQzX2QLHnmCs3i5CVtqR917/hzjxVt/QF/97HzaEaeObXPF rh+viMkrgoB1pN6hBsC0JF5iy8cvPDrkC0jxVLTMJ41uRhUA+bmptvgl61/y/9t1 THgDw6Fa2qKcHmZ51BpOcGEZ7wPpASKo9c26tkgTAFxAhtN5ZRJIPm5l+v9pzW8N WeF2vsBiat4yGRsdPbX/Ufw8dCGHuC3TU2mmeje1p/CrU1q1/Mx/k+RHUIvPIzzc Fq6SawsUbhge12VB+vSaVBd0X+1gbX1ahExmLQwA9cOPAUhattrGPdw+AT3hedU= =Ug10 -----END PGP SIGNATURE----- From lrn1986 at gmail.com Wed Mar 20 18:34:51 2013 From: lrn1986 at gmail.com (LRN) Date: Wed, 20 Mar 2013 21:34:51 +0400 Subject: Smarter fig2dev detection Message-ID: <5149F33B.5060409@gmail.com> -----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 libgcrypt documentation fails to build when fig2dev is not available, because fig2dev is used unconditionally. Here's an easy fix for this, which detects fig2dev at configure time, and uses `true' instead, if it isn't found, thus `make' and `make install' do not fail when used on a git version of libgcrypt on systems that do not have fig2dev. `make online' still fails if fig2dev is missing, and images are not generated, obviously, but that target is not really used by anyone except the maintainer. -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.11 (MingW32) Comment: Using GnuPG with Thunderbird - http://www.enigmail.net/ iQEcBAEBAgAGBQJRSfM6AAoJEOs4Jb6SI2CwEVsH/A5yHuvzBV7ladGWlF7F+WN1 Njrp/RxBaFeLaSIjdoBYphn+NKuzS3C/yD9Eg3VB99gu+D7XdnJG33I+GpevI43k rkW47Z8DLaf5z8jb9ap+fVwiVTnAFX4bhHY6d5owb8aYfean+PeNwCVXelUdm4C3 MZ4su67OAH3m766/DXZLq0vdof0k/O6+3YNyCyHI6SWqPEKqe44KcADRhadUJw7k X6IpCQ1Q/WciuHgiLJkRUs5d1oBvEeLHSxAkw7Zk1pIgeDzPHyp61TkL4SM+RpDw gQGN0jdZls6nG1QmOwBjsyNV0b0G7bYvStraAxJpg0zwAv6xs9kmt8ghqNjwRsI= =UjJ0 -----END PGP SIGNATURE----- -------------- next part -------------- From 15cad0ff53ad39e569b796474ad534687ea33e32 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=A0=D1=83=D1=81=D0=BB=D0=B0=D0=BD=20=D0=98=D0=B6=D0=B1=D1?= =?UTF-8?q?=83=D0=BB=D0=B0=D1=82=D0=BE=D0=B2?= Date: Wed, 20 Mar 2013 20:31:57 +0400 Subject: [PATCH 1/2] Smarter fig2dev detection --- configure.ac | 5 +++++ doc/Makefile.am | 8 ++++---- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/configure.ac b/configure.ac index 7afd83d..a6d8bdc 100644 --- a/configure.ac +++ b/configure.ac @@ -654,6 +654,11 @@ AC_SUBST(PTH_CFLAGS) AC_SUBST(PTH_LIBS) # +# Find fig2dev +# +AC_PATH_PROG([FIG2DEV], [fig2dev], [true]) + +# # Check whether pthreads is available # AC_CHECK_LIB(pthread,pthread_create,have_pthread=yes) diff --git a/doc/Makefile.am b/doc/Makefile.am index 30330bb..42c7d4f 100644 --- a/doc/Makefile.am +++ b/doc/Makefile.am @@ -45,16 +45,16 @@ yat2m: yat2m.c $(CC_FOR_BUILD) -o $@ $(srcdir)/yat2m.c .fig.png: - fig2dev -L png `test -f '$<' || echo '$(srcdir)/'`$< $@ + $(FIG2DEV) -L png `test -f '$<' || echo '$(srcdir)/'`$< $@ .fig.jpg: - fig2dev -L jpg `test -f '$<' || echo '$(srcdir)/'`$< $@ + $(FIG2DEV) -L jpg `test -f '$<' || echo '$(srcdir)/'`$< $@ .fig.eps: - fig2dev -L eps `test -f '$<' || echo '$(srcdir)/'`$< $@ + $(FIG2DEV) -L eps `test -f '$<' || echo '$(srcdir)/'`$< $@ .fig.pdf: - fig2dev -L pdf `test -f '$<' || echo '$(srcdir)/'`$< $@ + $(FIG2DEV) -L pdf `test -f '$<' || echo '$(srcdir)/'`$< $@ yat2m-stamp: $(myman_sources) @rm -f yat2m-stamp.tmp -- 1.7.11 From lrn1986 at gmail.com Thu Mar 21 11:39:11 2013 From: lrn1986 at gmail.com (LRN) Date: Thu, 21 Mar 2013 14:39:11 +0400 Subject: Missing libdir when installing the .def file Message-ID: <514AE34F.6060402@gmail.com> -----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 src/Makefile.am reads: install-def-file: $(INSTALL) $(srcdir)/libgcrypt.def $(DESTDIR)$(libdir)/libgcrypt.def This normally works - except for the cases of installing into a staging directory. Staging directory is empty initially, it doesn't have libdir in it. When libgcrypt is installed concurrently (with make install -jX), libdir might not be created prior to running install-def-file recipe. This is fixed by doing $(INSTALL) -d $(DESTDIR)$(libdir) before installing the .def file. -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.11 (MingW32) Comment: Using GnuPG with Thunderbird - http://www.enigmail.net/ iQEcBAEBAgAGBQJRSuNPAAoJEOs4Jb6SI2CwFKIIAMOHEZLpYQBw5EV20p8JLRk3 96Ui5Jct3jpPgZy7E400d9xeuagdFLuMrWA2qMkmYv0rUZ7Twg1qJIjKsC87EQ6m 1FT9hrDWEnF3kVrpnCLHruRI+UFN7FULFFlnDFwThO1VlUsOVz+om7Iw+cDajsxD VUVs2CMBj/SqC50i1sWhabL6jwoyq4ix12GuTm2NaTJl2k24g20DATsjbEdULkZz tcECYmQOgWnFToKhbcNkwdCw2pl7nIwMTSZJrJyd2XXUi1PF0lVF3c1Y43k8rHGH cGPmyFGFI1BrnkeY4/JozX75Icm4MVmF1L9Jv/3bhhcU0GExgPSUgNjzb2PZZC4= =eG1Z -----END PGP SIGNATURE----- From wk at gnupg.org Thu Mar 21 11:41:12 2013 From: wk at gnupg.org (Werner Koch) Date: Thu, 21 Mar 2013 11:41:12 +0100 Subject: Missing backslash in src/Makefile.am In-Reply-To: <5149DB94.3040709@gmail.com> (LRN's message of "Wed, 20 Mar 2013 19:53:56 +0400") References: <5149DB94.3040709@gmail.com> Message-ID: <877gl1vxvb.fsf@vigenere.g10code.de> On Wed, 20 Mar 2013 16:53, lrn1986 at gmail.com said: > git master HEAD, src/Makefile.am:111 Thanks. I was actually wondering why the inter-directory dependency tracking was not anymore working. Too lazy right now to look for it. Shalom-Salam, Werner -- Die Gedanken sind frei. Ausnahmen regelt ein Bundesgesetz. From wachs at net.in.tum.de Thu Mar 21 10:42:18 2013 From: wachs at net.in.tum.de (Matthias Wachs) Date: Thu, 21 Mar 2013 10:42:18 +0100 Subject: Fail to build on freebsd 7.3 Message-ID: <1363858938.8265.122.camel@fulcrum.net.in.tum.de> Hi! I have an issue with the latest libgcrypt 1.6.0-beta101 from git. It fails to build on freebsd 7.3: libtool: compile: gcc -DHAVE_CONFIG_H -I. -I.. -I../src -I../src -D_THREAD_SAFE -I/usr/local/include -g -fvisibility=hidden -Wall -Wcast-align -Wshadow -Wstrict-prototypes -Wformat -Wno-format-y2k -Wformat-security -W -Wextra -Wbad-function-cast -Wwrite-strings -Wdeclaration-after-statement -Wno-missing-field-initializers -Wno-sign-compare -Wpointer-arith -MT rijndael.lo -MD -MP -MF .deps/rijndael.Tpo -c rijndael.c -fPIC -DPIC -o .libs/rijndael.o /var/tmp//ccwZLDVe.s: Assembler messages: /var/tmp//ccwZLDVe.s:15053: Error: no such instruction: `pshufb be_mask.6570(%rip),%xmm2' /var/tmp//ccwZLDVe.s:15062: Error: no such instruction: `pshufb be_mask.6570(%rip),%xmm2' /var/tmp//ccwZLDVe.s:15155: Error: no such instruction: `pshufb be_mask.6579(%rip),%xmm2' /var/tmp//ccwZLDVe.s:15182: Error: no such instruction: `pshufb be_mask.6579(%rip),%xmm2' /var/tmp//ccwZLDVe.s:15183: Error: no such instruction: `pshufb be_mask.6579(%rip),%xmm3' /var/tmp//ccwZLDVe.s:15184: Error: no such instruction: `pshufb be_mask.6579(%rip),%xmm4' /var/tmp//ccwZLDVe.s:15185: Error: no such instruction: `pshufb be_mask.6579(%rip),%xmm5' *** Error code 1 Stop in /root/libgcrypt.git/cipher. Both with "--disable-asm" and without: ./configure --enable-maintainer-mode --prefix=/opt/libgcrypt-dev --disable-asm: config.status: executing gcrypt-conf commands Libgcrypt v1.6.0-beta101 has been configured as follows: Platform: FreeBSD (x86_64-unknown-freebsd7.3) Hardware detection module: none Enabled cipher algorithms: arcfour blowfish cast5 des aes twofish serpent rfc2268 seed camellia idea Enabled digest algorithms: crc md4 md5 rmd160 sha1 sha256 sha512 tiger whirlpool Enabled pubkey algorithms: dsa elgamal rsa ecc Random number generator: default Using linux capabilities: no Try using Padlock crypto: yes Try using AES-NI crypto: yes Try using DRNG (RDRAND): yes Try using Intel AVX: no (unsupported by compiler) Any ideas about that? thx in advance! -Matthias -- Dipl.-Inf. Matthias Wachs Free Secure Network Systems Group Technische Universitaet Muenchen Chair for Network Architectures and Services Institute for Informatics / I8 Tel: +49 89 289 18037 Boltzmannstr. 3 / Room 03.05.042 Fax: +49 89 289 18033 D-85748 Garching b. Muenchen, Germany Email: wachs at net.in.tum.de From wk at gnupg.org Thu Mar 21 12:01:19 2013 From: wk at gnupg.org (Werner Koch) Date: Thu, 21 Mar 2013 12:01:19 +0100 Subject: Wrong use of -export-symbols in src/Makefile.am In-Reply-To: <5149E1C6.2060106@gmail.com> (LRN's message of "Wed, 20 Mar 2013 20:20:22 +0400") References: <5149E1C6.2060106@gmail.com> Message-ID: <8738vpvwxs.fsf@vigenere.g10code.de> On Wed, 20 Mar 2013 17:20, lrn1986 at gmail.com said: > -export-symbols is a libtool option. It expects to be given a list of > symbols to export. The list is a plain list, one symbol name per line Right and libtool allows to use a def file here. You can verify that by checking the exported symbols of the DLL (nm shows the ordinals one off). Salam-Shalom, Werner -- Die Gedanken sind frei. Ausnahmen regelt ein Bundesgesetz. From wk at gnupg.org Thu Mar 21 12:06:31 2013 From: wk at gnupg.org (Werner Koch) Date: Thu, 21 Mar 2013 12:06:31 +0100 Subject: Smarter fig2dev detection In-Reply-To: <5149F33B.5060409@gmail.com> (LRN's message of "Wed, 20 Mar 2013 21:34:51 +0400") References: <5149F33B.5060409@gmail.com> Message-ID: <87y5dhui4o.fsf@vigenere.g10code.de> On Wed, 20 Mar 2013 18:34, lrn1986 at gmail.com said: > libgcrypt documentation fails to build when fig2dev is not available, > because fig2dev is used unconditionally. I know, this eventually needs to be fixed. > Here's an easy fix for this, which detects fig2dev at configure time, If you want your patch to be included you need to follow the procedure in doc/HACKING. We can't accept pseudonyms or anonymous contributions; if that is a problem for you, you need to find a proxy. Shalom-Salam, Werner -- Die Gedanken sind frei. Ausnahmen regelt ein Bundesgesetz. From lrn1986 at gmail.com Thu Mar 21 12:28:51 2013 From: lrn1986 at gmail.com (LRN) Date: Thu, 21 Mar 2013 15:28:51 +0400 Subject: Wrong use of -export-symbols in src/Makefile.am In-Reply-To: <8738vpvwxs.fsf@vigenere.g10code.de> References: <5149E1C6.2060106@gmail.com> <8738vpvwxs.fsf@vigenere.g10code.de> Message-ID: <514AEEF3.6090609@gmail.com> -----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 On 21.03.2013 15:01, Werner Koch wrote: > On Wed, 20 Mar 2013 17:20, lrn1986 at gmail.com said: > >> -export-symbols is a libtool option. It expects to be given a >> list of symbols to export. The list is a plain list, one symbol >> name per line > > Right and libtool allows to use a def file here. OK, i might have been too hasty. libtool does have some code to allow .def files to be used. However, it doesn't really work as expected, see the output of `make' (attached). The reason is, i believe, that EXPORTS is not on the first line. If it's moved to the first line (above the comments), then libtool groks it correctly. libtool version: macro_version=2.4.2 macro_revision=1.3337 -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.11 (MingW32) Comment: Using GnuPG with Thunderbird - http://www.enigmail.net/ iQEcBAEBAgAGBQJRSu7zAAoJEOs4Jb6SI2CwAH0H/AyEGf6ifBxiRf9fU+KaZnpZ X0B36MITFM+Kbooo/zijriP9n+GJ1nb68JdCNNpSlmfnUp4YwzBP2bsUsFfpwMJl z6AGkO88Yw5Mz9arZqRV5wzgJfcyVSmYcCK2HkgaHWHuS751LCx3OwsZSJQTUDZf +XTPjvDdQxH0s41lOzDlqPP6H4bsOC6Sr5WyIducGhVA+zHYv9vzjGetdzRrqxc9 IzEIJDek4rfqXNoZB13hh3zx5Hz/62w9JutZ5ho6C6jMK88TzEB8sffQzALkI9fM oyp+LNC7JW3X0SgMEOp2wxzks6Q/qi0agLh7Y0i/m5ex1E/nRmn3ah39ZJ1LX9s= =ZvQk -----END PGP SIGNATURE----- -------------- next part -------------- libtool: link: /bin/nm -B .libs/libgcrypt_la-visibility.o .libs/libgcrypt_la-misc.o .libs/libgcrypt_la-global.o .libs/libgcrypt_la-sexp.o .libs/libgcrypt_la-hwfeatures.o .libs/libgcrypt_la-stdmem.o .libs/libgcrypt_la-secmem.o .libs/libgcrypt_la-missing-string.o .libs/libgcrypt_la-module.o .libs/libgcrypt_la-fips.o .libs/libgcrypt_la-hmac256.o .libs/libgcrypt_la-context.o .libs/libgcrypt_la-ath.o .libs/versioninfo.o .libs/hwf-x86.o ../cipher/.libs/libcipher.a ../random/.libs/librandom.a ../mpi/.libs/libmpi.a ../compat/.libs/libcompat.a | sed -n -e 's/^.*[ ]\([ABCDGIRSTW][ABCDGIRSTW]*\)[ ][ ]*_\([_A-Za-z][_A-Za-z0-9]*\)\{0,1\}$/\1 _\2 \2/p' | sed '/ __gnu_lto/d' | /bin/sed -e '/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1 DATA/;s/^.*[ ]__nm__\([^ ]*\)[ ][^ ]*/\1 DATA/;/^I[ ]/d;/^[AITW][ ]/s/.* //' | sort | uniq > .libs/libgcrypt.exp libtool: link: if test "x`/bin/sed 1q .libs/libgcrypt.def`" = xEXPORTS; then cp .libs/libgcrypt.def .libs/libgcrypt-20.dll.def; else echo EXPORTS > .libs/libgcrypt-20.dll.def; cat .libs/libgcrypt.def >> .libs/libgcrypt-20.dll.def; fi libtool: link: gcc -shared .libs/libgcrypt-20.dll.def .libs/libgcrypt_la-visibility.o .libs/libgcrypt_la-misc.o .libs/libgcrypt_la-global.o .libs/libgcrypt_la-sexp.o .libs/libgcrypt_la-hwfeatures.o .libs/libgcrypt_la-stdmem.o .libs/libgcrypt_la-secmem.o .libs/libgcrypt_la-missing-string.o .libs/libgcrypt_la-module.o .libs/libgcrypt_la-fips.o .libs/libgcrypt_la-hmac256.o .libs/libgcrypt_la-context.o .libs/libgcrypt_la-ath.o .libs/versioninfo.o .libs/hwf-x86.o -Wl,--whole-archive ../cipher/.libs/libcipher.a ../random/.libs/librandom.a ../mpi/.libs/libmpi.a ../compat/.libs/libcompat.a -Wl,--no-whole-archive -L/mingw/lib -lgpg-error -O2 -o .libs/libgcrypt-20.dll -Wl,--enable-auto-image-base -Xlinker --out-implib -Xlinker .libs/libgcrypt.dll.a f:/sbuild.20/mingw/bin/../lib/gcc/mingw32/4.7.2/../../../../mingw32/bin/ld.exe: .libs/libgcrypt-20.dll.def:6: syntax error f:/sbuild.20/mingw/bin/../lib/gcc/mingw32/4.7.2/../../../../mingw32/bin/ld.exe:.libs/libgcrypt-20.dll.def: file format not recognized; treating as linker script f:/sbuild.20/mingw/bin/../lib/gcc/mingw32/4.7.2/../../../../mingw32/bin/ld.exe:.libs/libgcrypt-20.dll.def:2: syntax error collect2.exe: error: ld returned 1 exit status make[2]: *** [libgcrypt.la] Error 1 From lrn1986 at gmail.com Thu Mar 21 12:38:53 2013 From: lrn1986 at gmail.com (LRN) Date: Thu, 21 Mar 2013 15:38:53 +0400 Subject: Smarter fig2dev detection In-Reply-To: <87y5dhui4o.fsf@vigenere.g10code.de> References: <5149F33B.5060409@gmail.com> <87y5dhui4o.fsf@vigenere.g10code.de> Message-ID: <514AF14D.1040107@gmail.com> -----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 On 21.03.2013 15:06, Werner Koch wrote: > On Wed, 20 Mar 2013 18:34, lrn1986 at gmail.com said: >> libgcrypt documentation fails to build when fig2dev is not >> available, because fig2dev is used unconditionally. > > I know, this eventually needs to be fixed. > >> Here's an easy fix for this, which detects fig2dev at configure >> time, > > If you want your patch to be included you need to follow the > procedure in doc/HACKING. We can't accept pseudonyms or anonymous > contributions; if that is a problem for you, you need to find a > proxy. OK, i'll just wait until you fix it, since you are aware of the problem. -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.11 (MingW32) Comment: Using GnuPG with Thunderbird - http://www.enigmail.net/ iQEcBAEBAgAGBQJRSvFGAAoJEOs4Jb6SI2CwPiwH/3iesBVeVuY+Og8ZWH3cfwmb AlLLxdrWcv55spNMKEQgS9Q3o54IzlH4YbYzx2jCxwAAKnw951b17u82H5YUmNPB ACV5WxQBmIFb59FEbAO+DWuoW1Aah2Rpr6EcpSYdK+WNK96VJ1K6YdomVOj1Nt1o x8IeSkmOAPUQc4FWWepWrMlCDFWutAdNDzRED2ZtsGfj3xPoNrxuBT3sRC5QtRw+ IQEdSIYSmUY61Ok96K/8rbsk9HSR3XpSnMdz0vg4o4SnLJVoX37rMMcQluOnEdi+ fm0BSsqNBS4kodlE8BcCHRuKEhvAlAjecAeSGAyAHO9N7qSbUs8gG+aAPF1rn0Y= =5RfH -----END PGP SIGNATURE----- From bart at net.in.tum.de Thu Mar 21 13:52:26 2013 From: bart at net.in.tum.de (Bart Polot) Date: Thu, 21 Mar 2013 13:52:26 +0100 Subject: Fix for build with automake v1.13.1 Message-ID: <1688430.glxUkjmkhG@saturn> Hi all, I tried to build libgcrypt on a Linux Arch system, which ships aclocal (automake) version 1.13.1. This results in the following error (and many subsequent ones): [...] Running aclocal -I m4 ... configure.ac:75: error: 'AM_CONFIG_HEADER': this macro is obsolete. You should use the 'AC_CONFIG_HEADERS' macro instead. The proposed change fixed the problem. In case it helps here is the diff: diff --git a/configure.ac b/configure.ac index 7504d76..e67ec69 100644 --- a/configure.ac +++ b/configure.ac @@ -72,7 +72,7 @@ VERSION=$PACKAGE_VERSION AC_CONFIG_SRCDIR([src/libgcrypt.vers]) AM_INIT_AUTOMAKE([]) -AM_CONFIG_HEADER(config.h) +AC_CONFIG_HEADERS(config.h) AC_CONFIG_MACRO_DIR([m4]) AC_CONFIG_LIBOBJ_DIR([compat]) AC_CANONICAL_HOST With this change the build process succeeds and the tests pass. On a debian system with automake 1.11.6 the change does not seem to break anything. Happy hacking, Bart Polot -------------- next part -------------- An HTML attachment was scrubbed... URL: -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 230 bytes Desc: This is a digitally signed message part. URL: From wk at gnupg.org Thu Mar 21 15:39:46 2013 From: wk at gnupg.org (Werner Koch) Date: Thu, 21 Mar 2013 15:39:46 +0100 Subject: Wrong use of -export-symbols in src/Makefile.am In-Reply-To: <514AEEF3.6090609@gmail.com> (LRN's message of "Thu, 21 Mar 2013 15:28:51 +0400") References: <5149E1C6.2060106@gmail.com> <8738vpvwxs.fsf@vigenere.g10code.de> <514AEEF3.6090609@gmail.com> Message-ID: <87li9gvmtp.fsf@vigenere.g10code.de> On Thu, 21 Mar 2013 12:28, lrn1986 at gmail.com said: > The reason is, i believe, that EXPORTS is not on the first line. If > it's moved to the first line (above the comments), then libtool groks > it correctly. Are we talking about master or 1.5? I tested 1.5 and it worked without problems. We are doing this for many years now. A new gpg4win release is due in April and by then existing problems will be fixed anyway. I know that there are some build problems on a Fedora build box which we plan to fix for the next Gog4win release. Is your plan to port master to Windows? I would like to postpone this until a release. It is just to much work to fix minor Windows incompatibilities during development. I don't test it anyway. Salam-Shalom, Werner -- Die Gedanken sind frei. Ausnahmen regelt ein Bundesgesetz. From wk at gnupg.org Thu Mar 21 15:56:06 2013 From: wk at gnupg.org (Werner Koch) Date: Thu, 21 Mar 2013 15:56:06 +0100 Subject: Fail to build on freebsd 7.3 In-Reply-To: <1363858938.8265.122.camel@fulcrum.net.in.tum.de> (Matthias Wachs's message of "Thu, 21 Mar 2013 10:42:18 +0100") References: <1363858938.8265.122.camel@fulcrum.net.in.tum.de> Message-ID: <87d2usvm2h.fsf@vigenere.g10code.de> On Thu, 21 Mar 2013 10:42, wachs at net.in.tum.de said: > /var/tmp//ccwZLDVe.s: Assembler messages: > /var/tmp//ccwZLDVe.s:15053: Error: no such instruction: `pshufb > be_mask.6570(%rip),%xmm2' Your as(1) is too old. Use --disable-aes-support or update the toolchain. We could also test whether the compiler supports this and directlt disable AES support. I think you are the first one to reports this problem, thus I am not sure whether a configure test is justified. Salam-Shalom, Werner -- Die Gedanken sind frei. Ausnahmen regelt ein Bundesgesetz. From lrn1986 at gmail.com Thu Mar 21 16:10:30 2013 From: lrn1986 at gmail.com (LRN) Date: Thu, 21 Mar 2013 19:10:30 +0400 Subject: Wrong use of -export-symbols in src/Makefile.am In-Reply-To: <87li9gvmtp.fsf@vigenere.g10code.de> References: <5149E1C6.2060106@gmail.com> <8738vpvwxs.fsf@vigenere.g10code.de> <514AEEF3.6090609@gmail.com> <87li9gvmtp.fsf@vigenere.g10code.de> Message-ID: <514B22E6.108@gmail.com> -----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 On 21.03.2013 18:39, Werner Koch wrote: > On Thu, 21 Mar 2013 12:28, lrn1986 at gmail.com said: > >> The reason is, i believe, that EXPORTS is not on the first line. >> If it's moved to the first line (above the comments), then >> libtool groks it correctly. > > Are we talking about master or 1.5? Both. I've had this problem with 1.5, and i still have it with git master HEAD. > I tested 1.5 and it worked without problems. Which version of libtool did you use? Did you cross-compile (not sure how that would affect libtool behaviour though...)? > Is your plan to port master to Windows? libgcrypt does not require porting (which is good!). It only has some small hiccups in the buildsystem: .def file EXPORTS placement, libdir creation, and fig2dev detection - that's all. It even passes all the tests (i have the output of `make check', if you need it). > I would like to postpone this until a release. As with everything else i've been pushing your way, i'm perfectly happy to apply my patches locally, until you fix the problems on your side. > It is just to much work to fix minor Windows incompatibilities > during development. Of the problems listed above: * the fig2dev issue does not affect tarballs, since they come with pre-generated image files, * libdir creation only affects package maintainers (i.e. when installing into empty staging directory and with -jX)., * EXPORTS placement issue is the only one that will screw people compiling from git AND from tarballs. Fix that, and, hopefully, 1.6.0 tarballs will come out fine. > I don't test it anyway. That's bad. -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.11 (MingW32) Comment: Using GnuPG with Thunderbird - http://www.enigmail.net/ iQEcBAEBAgAGBQJRSyLmAAoJEOs4Jb6SI2CwhyMH/ju9LbFdJVPS6ar3ztPGP7e6 CZL94l8UJO/a+vhuWKjerLyU+T/NxnCEtG/6dUFK3WNcCa+UAS9XGMSDeL9hIZ4R jk75tvMTmEBfktd+mPT3WFd0+P3hEWzmq1nt/ydMgm/9t+lek78aGQ7VM7p+cIeA JpxoNZrsmSwWzsILael5zLxZtGnfLTcdFbvu9o27KxpaZ2ntXZGGw+wWzMcRRPKm LxKLi65SHExlZra9KBjy4OfXyAXF9NYqjtsrvX7g9/jU0I32fSW+kvJSrmONiUwb Dw8l49L0s5kkhqAXZG/AmNbQ3SP2K4nnv0t3bq5QpuByj7fa5I9FTUtJ20IfAGE= =1yuB -----END PGP SIGNATURE----- From grothoff at in.tum.de Thu Mar 21 10:18:36 2013 From: grothoff at in.tum.de (Christian Grothoff) Date: Thu, 21 Mar 2013 10:18:36 +0100 Subject: linker issue on sparc Message-ID: <514AD06C.8000100@in.tum.de> Hi! We just tried to build libgcrypt HEAD on our Sparc, and the resulting binary has undefined symbols: # ldd -r /opt/libgcrypt-dev/lib/libgcrypt.so.20 libgpg-error.so.0 => /lib/sparc-linux-gnu/libgpg-error.so.0 (0xf7ab8000) libc.so.6 => /lib/sparc-linux-gnu/libc.so.6 (0xf792c000) /lib/ld-linux.so.2 (0x70000000) undefined symbol: __udiv_qrnnd (/opt/libgcrypt-dev/lib/libgcrypt.so.20) # uname -a Linux mamasparc 3.2.0-3-sparc64-smp #1 SMP Mon Jul 23 05:25:29 UTC 2012 sparc64 GNU/Linux Werner, if you want root on that system, please send me an SSH key. Happy hacking! Christian From grothoff at in.tum.de Thu Mar 21 13:39:55 2013 From: grothoff at in.tum.de (Christian Grothoff) Date: Thu, 21 Mar 2013 13:39:55 +0100 Subject: requesting another ECC function... Message-ID: <514AFF9B.6010408@in.tum.de> Hi Werner, Hacking more on our code, I discovered that there is another API call that is missing. Right now, I can convert an S-expression to a 'ctx' for 'low level' operations, but I cannot go back from a 'ctx' (where I can manipulate 'Q' freely) to an S-expression. So what I need is something like a function "gcry_sexp_from_ec_context", to be used as follows: /* initialize 'ctx' with 'q' */ gcry_mpi_ec_set_point ("q", q, ctx); gcry_mpi_point_release (q); /* convert 'ctx' to 'sexp' (this hurts) */ if (0 != (rc = gcry_sexp_from_ec_context (&pk_sexpr, ctx))) { LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_sexp_from_context", rc); gcry_ctx_release (ctx); gcry_sexp_release (data); gcry_sexp_release (sig_sexpr); return GNUNET_SYSERR; } gcry_ctx_release (ctx); /* finally, verify the signature */ rc = gcry_pk_verify (sig_sexpr, data, pk_sexpr); gcry_sexp_release (sig_sexpr); gcry_sexp_release (data); gcry_sexp_release (pk_sexpr); if (rc) { LOG (GNUNET_ERROR_TYPE_WARNING, _("ECDSA signature verification failed at %s:%d: %s\n"), __FILE__, __LINE__, gcry_strerror (rc)); return GNUNET_SYSERR; } Also, I noticed that there is point_get_affine, but no point_set_affine. As creating an MPI with value "1" is inconvenient, it might be nice (also for symmetry) to have a gcry_point_set_affine (x,y) API as well. Finally, I'm not sure 'gcry_ctx_t' is a great name for the ECC context, as it suggests a broader use; calling it 'gcry_ec_ctx_c' might be nicer; after all, all the functions that manipulate it are "_ec_" functions. Happy hacking! Christian From philip at shadowmagic.org.uk Thu Mar 21 16:07:26 2013 From: philip at shadowmagic.org.uk (Philip Kendall) Date: Thu, 21 Mar 2013 15:07:26 +0000 Subject: Fail to build on freebsd 7.3 In-Reply-To: <87d2usvm2h.fsf@vigenere.g10code.de> References: <1363858938.8265.122.camel@fulcrum.net.in.tum.de> <87d2usvm2h.fsf@vigenere.g10code.de> Message-ID: <20130321150725.GJ18530@sphinx.mythic-beasts.com> On Thu, Mar 21, 2013 at 03:56:06PM +0100, Werner Koch wrote: > On Thu, 21 Mar 2013 10:42, wachs at net.in.tum.de said: > > > /var/tmp//ccwZLDVe.s: Assembler messages: > > /var/tmp//ccwZLDVe.s:15053: Error: no such instruction: `pshufb > > be_mask.6570(%rip),%xmm2' > > Your as(1) is too old. Use --disable-aes-support or update the > toolchain. We could also test whether the compiler supports this and > directlt disable AES support. > > I think you are the first one to reports this problem, thus I am not > sure whether a configure test is justified. It is probably also worth noting that FreeBSD 7.3 hit end of life a year ago. Cheers, Phil -- Philip Kendall http://www.shadowmagic.org.uk/ From ametzler at downhill.at.eu.org Thu Mar 21 20:11:54 2013 From: ametzler at downhill.at.eu.org (Andreas Metzler) Date: Thu, 21 Mar 2013 20:11:54 +0100 Subject: broken sed in 1.5.1 cipher/Makefile.am Message-ID: Hello, 1.5.1 has this change compared to 1.5.0: -o_flag_munging = sed -e 's/-O[2-9s]*/-O1/g' +o_flag_munging = sed -e 's/-O([2-9s]|fast)*/-O1/g' I think the changed line should read +o_flag_munging = sed -e 's/-O([2-9s]*|fast)/-O1/g' instead. cu andreas -- `What a good friend you are to him, Dr. Maturin. His other friends are so grateful to you.' `I sew his ears on from time to time, sure' From christian at grothoff.org Thu Mar 21 20:20:42 2013 From: christian at grothoff.org (Christian Grothoff) Date: Thu, 21 Mar 2013 20:20:42 +0100 Subject: Christian Grothoff DCO Message-ID: <514B5D8A.6040705@grothoff.org> Libgcrypt Developer's Certificate of Origin. Version 1.0 ========================================================= By making a contribution to the Libgcrypt project, I certify that: (a) The contribution was created in whole or in part by me and I have the right to submit it under the free software license indicated in the file; or (b) The contribution is based upon previous work that, to the best of my knowledge, is covered under an appropriate free software license and I have the right under that license to submit that work with modifications, whether created in whole or in part by me, under the same free software license (unless I am permitted to submit under a different license), as indicated in the file; or (c) The contribution was provided directly to me by some other person who certified (a), (b) or (c) and I have not modified it. (d) I understand and agree that this project and the contribution are public and that a record of the contribution (including all personal information I submit with it, including my sign-off) is maintained indefinitely and may be redistributed consistent with this project or the free software license(s) involved. Signed-off-by: Christian Grothoff -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 262 bytes Desc: OpenPGP digital signature URL: From grothoff at gnunet.org Thu Mar 21 20:24:54 2013 From: grothoff at gnunet.org (Christian Grothoff) Date: Thu, 21 Mar 2013 20:24:54 +0100 Subject: Fail to build on freebsd 7.3 In-Reply-To: <87d2usvm2h.fsf@vigenere.g10code.de> References: <1363858938.8265.122.camel@fulcrum.net.in.tum.de> <87d2usvm2h.fsf@vigenere.g10code.de> Message-ID: <514B5E86.6080707@gnunet.org> On 03/21/2013 03:56 PM, Werner Koch wrote: > On Thu, 21 Mar 2013 10:42, wachs at net.in.tum.de said: > >> /var/tmp//ccwZLDVe.s: Assembler messages: >> /var/tmp//ccwZLDVe.s:15053: Error: no such instruction: `pshufb >> be_mask.6570(%rip),%xmm2' > > Your as(1) is too old. Use --disable-aes-support or update the > toolchain. We could also test whether the compiler supports this and > directlt disable AES support. Eh, but we need AES support, so disabling it is not an option. Matthias, if we cannot update 'as', we need to convince libgcrypt to revert to a C implementation. > I think you are the first one to reports this problem, thus I am not > sure whether a configure test is justified. Let's see if upgrading 'as' is much of a problem first. -Christian From wk at gnupg.org Fri Mar 22 10:59:38 2013 From: wk at gnupg.org (Werner Koch) Date: Fri, 22 Mar 2013 10:59:38 +0100 Subject: linker issue on sparc In-Reply-To: <514AD06C.8000100@in.tum.de> (Christian Grothoff's message of "Thu, 21 Mar 2013 10:18:36 +0100") References: <514AD06C.8000100@in.tum.de> Message-ID: <87d2uru54l.fsf@vigenere.g10code.de> On Thu, 21 Mar 2013 10:18, grothoff at in.tum.de said: > undefined symbol: __udiv_qrnnd (/opt/libgcrypt-dev/lib/libgcrypt.so.20) We also have a bus error for 1.4.1 on sparc32 . Not sure whether this is related. > # uname -a > Linux mamasparc 3.2.0-3-sparc64-smp #1 SMP Mon Jul 23 05:25:29 UTC > 2012 sparc64 GNU/Linux I can use the gcc63 from the gcc compile farm. Salam-Shalom, Werner -- Die Gedanken sind frei. Ausnahmen regelt ein Bundesgesetz. From wk at gnupg.org Fri Mar 22 11:02:33 2013 From: wk at gnupg.org (Werner Koch) Date: Fri, 22 Mar 2013 11:02:33 +0100 Subject: Fail to build on freebsd 7.3 In-Reply-To: <514B5E86.6080707@gnunet.org> (Christian Grothoff's message of "Thu, 21 Mar 2013 20:24:54 +0100") References: <1363858938.8265.122.camel@fulcrum.net.in.tum.de> <87d2usvm2h.fsf@vigenere.g10code.de> <514B5E86.6080707@gnunet.org> Message-ID: <878v5fu4zq.fsf@vigenere.g10code.de> On Thu, 21 Mar 2013 20:24, grothoff at gnunet.org said: > Eh, but we need AES support, so disabling it is not an option. Matthias, if we Actually the option is called --disable-aesni-support and affects only the Intel AES-NI based code. I better add the configure test to make it easier. Shalom-Salam, Werner -- Die Gedanken sind frei. Ausnahmen regelt ein Bundesgesetz. From grothoff at in.tum.de Fri Mar 22 10:19:31 2013 From: grothoff at in.tum.de (Christian Grothoff) Date: Fri, 22 Mar 2013 10:19:31 +0100 Subject: q not derived from d in gcry_pk_sign Message-ID: <514C2223.2070106@in.tum.de> Hi! I have a private ECC key 'd' for a given curve (NIST P-256) and would like to use 'gcry_pk_sign' given this information. So I use gcry_sexp_build (&spriv, &erroff, "(private-key(ecc(curve \"NIST P-256\")(d %m)))", d); gcry_pk_sign (&result, data, spriv); to create a signature; this fails, as in 'sexp_elements_extract_ecc' the 'q' value is not found (as it is neither in the curve nor explicitly in the S-expression); however, q can of course be calculated as q = dg from the private key and the curve. Fixing this inside 'sexp_elements_extract_ecc' is not trivial, as no context for the point multiplication exists (after all, we're just building that one). Similarly, having me calculate q first is ugly, as I'd have to first create another ECC context, do the multiplication, and then find a way to print the point correctly into the s-expression, just to create the context that could have done it internally with ease. The nicest fix I can think of right now would be a change to how 'sexp_elements_extract_ecc' works (i.e. reporting "got all" even if q was not found and forcing the caller to manually check & recompute); this might be done by marking some variables as 'optional'. Then the caller can check for q==NULL once the context has been initialized 'enough' to make the ECC multiplication to calculate q. Happy hacking! Christian p.s.: Werner, I had send you a related patch to do this 'q' calculation on-the-fly before, but this is a different path through the code. From grothoff at in.tum.de Fri Mar 22 12:59:16 2013 From: grothoff at in.tum.de (Christian Grothoff) Date: Fri, 22 Mar 2013 12:59:16 +0100 Subject: scrypt KDF support for libgcrypt Message-ID: <514C4794.6020001@in.tum.de> Hi! I've hacked up an implementation of scrypt for libgcrypt based on Simon's scrypt implementation in nettle. The code compiles on my system, but is completely untested otherwise. No test case is included at this point; Simon's internet draft on scrypt includes some test vectors that should be used for that eventually). Anyway, I think this should be a start towards fixing https://bugs.g10code.com/gnupg/issue1471 Happy hacking! Christian -------------- next part -------------- A non-text attachment was scrubbed... Name: scrypt.diff Type: text/x-patch Size: 3422 bytes Desc: not available URL: From wk at gnupg.org Fri Mar 22 15:43:19 2013 From: wk at gnupg.org (Werner Koch) Date: Fri, 22 Mar 2013 15:43:19 +0100 Subject: q not derived from d in gcry_pk_sign In-Reply-To: <514C2223.2070106@in.tum.de> (Christian Grothoff's message of "Fri, 22 Mar 2013 10:19:31 +0100") References: <514C2223.2070106@in.tum.de> Message-ID: <87fvznsdfc.fsf@vigenere.g10code.de> On Fri, 22 Mar 2013 10:19, grothoff at in.tum.de said: > 'q' value is not found (as it is neither in the curve nor explicitly in > the S-expression); however, q can of course be calculated as q = dg > from the private key and the curve. Right. That raises another question. In contrast to gcry_cipher_ and gcry_md_, the gcry_pk_ functions don't follow an open-process-close paradigm and thus have no associated context. For the fast ECC operations we have seen that a context is sometimes useful to speed up operations. To some degree this would also be true for the other algorithms. For example, I never implemented Montgomery multiplication because a real performance gain could only be achieved if we would be able to cache temporary values. The original idea was to employ a real cache for this, however that requires quite some code to get it right and thread safe. If we could use a caller provided context instead, this would shift the responsibility of caching to the caller, who better knows whether it makes sense. Given that we have an ABI break anyway, I consider to add a context argument to all gcry_pk_ functions which may eventually be used to implement such features. For now we would just pass NULL for the context but we may then start to experiment without breaking the ABI or API. gcry_error_t gcry_pk_sign_ext (gcry_sexp_t *result, gcry_sexp_t data, gcry_sexp_t skey, gcry_ctx_t ctx); #define gcry_pk_sign(a,b,c) gcry_pk_sign_ext ((a),(b),(c), NULL) (Or should we use gcry_pubkey_foo instead of gcry_pk_sign_ext ?) > The nicest fix I can think of right now would be a change to how > sexp_elements_extract_ecc' works (i.e. reporting "got all" even > if q was not found and forcing the caller to manually check & Given that ECC is not yet in widespread use it would be okay to go with this little interface change. Shalom-Salam, Werner -- Die Gedanken sind frei. Ausnahmen regelt ein Bundesgesetz. From grothoff at in.tum.de Fri Mar 22 17:26:09 2013 From: grothoff at in.tum.de (Christian Grothoff) Date: Fri, 22 Mar 2013 17:26:09 +0100 Subject: q not derived from d in gcry_pk_sign In-Reply-To: <87fvznsdfc.fsf@vigenere.g10code.de> References: <514C2223.2070106@in.tum.de> <87fvznsdfc.fsf@vigenere.g10code.de> Message-ID: <514C8621.5070602@in.tum.de> On 03/22/2013 03:43 PM, Werner Koch wrote: > On Fri, 22 Mar 2013 10:19, grothoff at in.tum.de said: > >> 'q' value is not found (as it is neither in the curve nor explicitly in >> the S-expression); however, q can of course be calculated as q = dg >> from the private key and the curve. > > Right. That raises another question. In contrast to gcry_cipher_ and > gcry_md_, the gcry_pk_ functions don't follow an open-process-close > paradigm and thus have no associated context. For the fast ECC > operations we have seen that a context is sometimes useful to speed up > operations. To some degree this would also be true for the other > algorithms. For example, I never implemented Montgomery multiplication > because a real performance gain could only be achieved if we would be > able to cache temporary values. The original idea was to employ a real > cache for this, however that requires quite some code to get it right > and thread safe. If we could use a caller provided context instead, > this would shift the responsibility of caching to the caller, who better > knows whether it makes sense. You might even require the caller to take care of the locking (i.e. you must only use each context in one thread at a time). > Given that we have an ABI break anyway, I consider to add a context > argument to all gcry_pk_ functions which may eventually be used to > implement such features. For now we would just pass NULL for the > context but we may then start to experiment without breaking the ABI or > API. I like the idea, but I'm not sure about why you'd risk breaking the API; in my experience that causes Debian to not update your package for about a decade, and that would be unfortunate. Introducing a gcry_pk_sign2 function with context and having the old one create a context on-the-fly (and destroy it immediately again) should suffice without causing too much bloat. The existing ABI changes for 1.6 seemed minor (i.e. didn't touch GNUnet at all, and we use libgcrypt a lot); that would not be true for adding the NULL context; also, moving to a macro breaks just as badly, so I'd keep gcry_pk_sign as a real, backwards-compatible, exported function. > gcry_error_t gcry_pk_sign_ext (gcry_sexp_t *result, > gcry_sexp_t data, gcry_sexp_t skey, > gcry_ctx_t ctx); > #define gcry_pk_sign(a,b,c) gcry_pk_sign_ext ((a),(b),(c), NULL) > > (Or should we use gcry_pubkey_foo instead of gcry_pk_sign_ext ?) I'd personally not use a generic context but one specific to the primitive and then it would be gcry_ec_sign (gcry_ec_ctx_t, ...), even if the interface would not be as generic. If we later need the super-generic interface with a context, we can always add a union gcry_pk_ctx with a generic pk_sign function. I'm just not sure that'll ever be needed; and if it is, I'd still want the low-level EC primitives to not use the generic pk_ctx as then the compiler wouldn't bark at passing an RSA ctx to a low-level EC operation. >> The nicest fix I can think of right now would be a change to how >> sexp_elements_extract_ecc' works (i.e. reporting "got all" even >> if q was not found and forcing the caller to manually check& > > Given that ECC is not yet in widespread use it would be okay to go with > this little interface change. What I proposed for sexp_elements_extract_ecc wasn't really an interface change, as the function that would change is completely internal. The only visible change to the outside is that ECC calls with d and without q would work instead of fail, whereas previously they'd fail. So that's pretty much just a bugfix, as no application should *rely* on that failure. My 2 cents Christian From wk at gnupg.org Fri Mar 22 20:20:31 2013 From: wk at gnupg.org (Werner Koch) Date: Fri, 22 Mar 2013 20:20:31 +0100 Subject: q not derived from d in gcry_pk_sign In-Reply-To: <514C8621.5070602@in.tum.de> (Christian Grothoff's message of "Fri, 22 Mar 2013 17:26:09 +0100") References: <514C2223.2070106@in.tum.de> <87fvznsdfc.fsf@vigenere.g10code.de> <514C8621.5070602@in.tum.de> Message-ID: <874ng3s0lc.fsf@vigenere.g10code.de> On Fri, 22 Mar 2013 17:26, grothoff at in.tum.de said: > You might even require the caller to take care of the locking > (i.e. you must only use each context in one thread at a time). Yeah sure, that is the nice thing with a contexts (or anchors as IBM used to call them in the past). > I like the idea, but I'm not sure about why you'd risk breaking the API; > in my experience that causes Debian to not update your package for about > a decade, and that would be unfortunate. Introducing a The macros will take of most cases except for rare usages, say, using gcry_pk via dlopen and own prototypes. And even, then we will still export the old functions for these cases. The just won't have a prototype in gcrypt.h. > without causing too much bloat. The existing ABI changes for 1.6 seemed > minor (i.e. didn't touch GNUnet at all, and we use libgcrypt a lot); It is a major change, for example the entire _ac_ interface has been dropped. We have a new SO number and thus you need to re-compile all software anyway. The advantage is that the rest of the API is mostly compatible to the old one. > I'd personally not use a generic context but one specific to the > primitive and then it would be gcry_ec_sign (gcry_ec_ctx_t, ...), > even if the interface would not be as generic. If we later need We already do that: /* The definition of the generic context object. The public typedef gcry_ctx_t is used to access it. */ struct gcry_context { char magic[CTX_MAGIC_LEN]; /* Magic value to cross check that this is really a context object. */ char type; /* The type of the context (CONTEXT_TYPE_foo). */ void (*deinit)(void*); /* Function used to free the private part. */ PROPERLY_ALIGNED_TYPE u; }; The internal function checks that the right context version has been passed. Sure there is no way for static type checking, but we don't have this for the s-expression based interface anyway. The nice thing with the generic context is that we can add more features over time, even those which are not directly related to a specific context. For example, it might be useful to have an MPI interface which returns an error instead of calling the fatal handler. Setting a flag in a context would allow to change this on a case by case base. And we won't run into an incompatible API break. > not sure that'll ever be needed; and if it is, I'd still want the > low-level EC primitives to not use the generic pk_ctx as then the > compiler wouldn't bark at passing an RSA ctx to a low-level You may want to use the same context for both types, they could even be linked to gether. As I said, it is the same as with the s-expression interface. > internal. The only visible change to the outside is that ECC calls > with d and without q would work instead of fail, whereas previously > they'd fail. So that's pretty much just a bugfix, as no application > should *rely* on that failure. It is a grey area. Magically computing missing values often comes to a surprise for the caller. But, yeah, here we can change it. While thinking about it, there is another fix due: D is usually in the secure memory area. Now, by computing Q the MPI subsystems puts Q also into secure memory, because it can't know that Q is not anymore a sensitive value. This could easily exhaust the secure memory without a fix. Shalom-Salam, Werner -- Die Gedanken sind frei. Ausnahmen regelt ein Bundesgesetz.