[git] GCRYPT - branch, master, updated. libgcrypt-1.5.0-145-g99b18aa

by Werner Koch cvs at cvs.gnupg.org
Fri May 24 17:18:23 CEST 2013


This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "The GNU crypto library".

The branch, master has been updated
       via  99b18aa536703ef90c9a1f5c8f40bc68b2064593 (commit)
       via  9711384f75564a71979e3fb971b5f4cadcf1afef (commit)
      from  0bdf26eea8cdbffefe7e37578f8f896c4f5f5275 (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
commit 99b18aa536703ef90c9a1f5c8f40bc68b2064593
Author: Werner Koch <wk at gnupg.org>
Date:   Fri May 24 16:54:52 2013 +0200

    ecc: Simplify the compliant point generation.
    
    * cipher/ecc.c (generate_key): Use point_snatch_set, replaces unneeded
    variable copies, etc.
    
    Signed-off-by: Werner Koch <wk at gnupg.org>

diff --git a/cipher/ecc.c b/cipher/ecc.c
index 63ee2d0..e5a925b 100644
--- a/cipher/ecc.c
+++ b/cipher/ecc.c
@@ -504,7 +504,6 @@ 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_struct Q;
   mpi_ec_t ctx;
   gcry_random_level_t random_level;
@@ -529,12 +528,12 @@ generate_key (ECC_secret_key *sk, unsigned int nbits, const char *name,
     }
 
   random_level = transient_key ? GCRY_STRONG_RANDOM : GCRY_VERY_STRONG_RANDOM;
-  d = _gcry_dsa_gen_k (E.n, random_level);
+  sk->d = _gcry_dsa_gen_k (E.n, random_level);
 
   /* Compute Q.  */
   point_init (&Q);
   ctx = _gcry_mpi_ec_p_internal_new (E.p, E.a);
-  _gcry_mpi_ec_mul_point (&Q, d, &E.G, ctx);
+  _gcry_mpi_ec_mul_point (&Q, sk->d, &E.G, ctx);
 
   /* Copy the stuff to the key structures. */
   sk->E.p = mpi_copy (E.p);
@@ -553,47 +552,38 @@ generate_key (ECC_secret_key *sk, unsigned int nbits, const char *name,
    * dropped because we know that it's a minimum of the two
    * possibilities without any loss of security.  */
   {
-    gcry_mpi_t x, p_y, y;
-    const unsigned int nbits = mpi_get_nbits (E.p);
+    gcry_mpi_t x, y, p_y;
+    const unsigned int pbits = mpi_get_nbits (E.p);
 
-    x = mpi_new (nbits);
-    p_y = mpi_new (nbits);
-    y = mpi_new (nbits);
+    x = mpi_new (pbits);
+    y = mpi_new (pbits);
+    p_y = mpi_new (pbits);
 
     if (_gcry_mpi_ec_get_affine (x, y, &Q, ctx))
-      log_fatal ("ecgen: Failed to get affine coordinates for Q\n");
+      log_fatal ("ecgen: Failed to get affine coordinates for %s\n", "Q");
 
-    mpi_sub( p_y, E.p, y );	/* p_y = p-y */
+    mpi_sub (p_y, E.p, y);	/* p_y = p - y */
 
-    if (mpi_cmp( p_y /*p-y*/, y ) < 0) /* is p-y < p ? */
+    if (mpi_cmp (p_y, y) < 0)   /* p - y < p */
       {
-        gcry_mpi_t z = mpi_copy (mpi_const (MPI_C_ONE));
-
-        /* log_mpidump ("ecgen p-y", p_y); */
-        /* log_mpidump ("ecgen y  ", y); */
-        /* log_debug   ("ecgen will replace y with p-y\n"); */
-        /* log_mpidump ("ecgen d before", d); */
-
         /* We need to end up with -Q; this assures that new Q's y is
            the smallest one */
-        sk->d = mpi_new (nbits);
-        mpi_sub (sk->d, E.n, d);  /* d = order-d */
-        /* log_mpidump ("ecgen d after ", sk->d); */
-	gcry_mpi_point_set (&sk->Q, x, p_y/*p-y*/, z);	/* Q = -Q */
+        mpi_sub (sk->d, E.n, sk->d);   /* d = order - d */
+	gcry_mpi_point_snatch_set (&sk->Q, x, p_y, mpi_alloc_set_ui (1));
+
         if (DBG_CIPHER)
           log_debug ("ecgen converted Q to a compliant point\n");
-        mpi_free (z);
       }
-    else
+    else /* p - y >= p */
       {
         /* No change is needed exactly 50% of the time: just copy. */
-        sk->d = mpi_copy (d);
 	point_set (&sk->Q, &Q);
         if (DBG_CIPHER)
           log_debug ("ecgen didn't need to convert Q to a compliant point\n");
+
+        mpi_free (p_y);
+        mpi_free (x);
       }
-    mpi_free (x);
-    mpi_free (p_y);
     mpi_free (y);
   }
 
@@ -612,7 +602,6 @@ generate_key (ECC_secret_key *sk, unsigned int nbits, const char *name,
   _gcry_mpi_ec_free (ctx);
 
   point_free (&Q);
-  mpi_free (d);
 
   *r_usedcurve = E.name;
   curve_free (&E);

commit 9711384f75564a71979e3fb971b5f4cadcf1afef
Author: Werner Koch <wk at gnupg.org>
Date:   Fri May 24 15:52:37 2013 +0200

    ecc: Fix a minor flaw in the generation of K.
    
    * cipher/dsa.c (gen_k): Factor code out to ..
    * cipher/dsa-common.c (_gcry_dsa_gen_k): new file and function.  Add
    arg security_level and re-indent a bit.
    * cipher/ecc.c (gen_k): Remove and change callers to _gcry_dsa_gen_k.
    * cipher/dsa.c: Include pubkey-internal.
    * cipher/Makefile.am (libcipher_la_SOURCES): Add dsa-common.c
    --
    
    The ECDSA code used the simple $k = k \bmod p$ method which introduces
    a small bias.  We now use the bias free method we have always used
    with DSA.
    
    Signed-off-by: Werner Koch <wk at gnupg.org>

diff --git a/cipher/Makefile.am b/cipher/Makefile.am
index 1e2696f..687c599 100644
--- a/cipher/Makefile.am
+++ b/cipher/Makefile.am
@@ -49,6 +49,7 @@ bithelp.h  \
 bufhelp.h  \
 primegen.c  \
 hash-common.c hash-common.h \
+dsa-common.c \
 rmd.h
 
 EXTRA_libcipher_la_SOURCES = \
diff --git a/cipher/dsa-common.c b/cipher/dsa-common.c
new file mode 100644
index 0000000..a5854ce
--- /dev/null
+++ b/cipher/dsa-common.c
@@ -0,0 +1,101 @@
+/* dsa-common.c - Common code for DSA
+ * Copyright (C) 1998, 1999 Free Software Foundation, Inc.
+ * Copyright (C) 2013  g10 Code GmbH
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "g10lib.h"
+#include "mpi.h"
+#include "cipher.h"
+#include "pubkey-internal.h"
+
+
+/*
+ * Generate a random secret exponent K less than Q.
+ * Note that ECDSA uses this code also to generate D.
+ */
+gcry_mpi_t
+_gcry_dsa_gen_k (gcry_mpi_t q, int security_level)
+{
+  gcry_mpi_t k        = mpi_alloc_secure (mpi_get_nlimbs (q));
+  unsigned int nbits  = mpi_get_nbits (q);
+  unsigned int nbytes = (nbits+7)/8;
+  char *rndbuf = NULL;
+
+  /* To learn why we don't use mpi_mod to get the requested bit size,
+     read the paper: "The Insecurity of the Digital Signature
+     Algorithm with Partially Known Nonces" by Nguyen and Shparlinski.
+     Journal of Cryptology, New York. Vol 15, nr 3 (2003)  */
+
+  if (DBG_CIPHER)
+    log_debug ("choosing a random k of %u bits at seclevel %d\n",
+               nbits, security_level);
+  for (;;)
+    {
+      if ( !rndbuf || nbits < 32 )
+        {
+          gcry_free (rndbuf);
+          rndbuf = gcry_random_bytes_secure (nbytes, security_level);
+	}
+      else
+        { /* Change only some of the higher bits.  We could improve
+	     this by directly requesting more memory at the first call
+	     to get_random_bytes() and use these extra bytes here.
+	     However the required management code is more complex and
+	     thus we better use this simple method.  */
+          char *pp = gcry_random_bytes_secure (4, security_level);
+          memcpy (rndbuf, pp, 4);
+          gcry_free (pp);
+	}
+      _gcry_mpi_set_buffer (k, rndbuf, nbytes, 0);
+
+      /* Make sure we have the requested number of bits.  This code
+         looks a bit funny but it is easy to understand if you
+         consider that mpi_set_highbit clears all higher bits.  We
+         don't have a clear_highbit, thus we first set the high bit
+         and then clear it again.  */
+      if (mpi_test_bit (k, nbits-1))
+        mpi_set_highbit (k, nbits-1);
+      else
+        {
+          mpi_set_highbit (k, nbits-1);
+          mpi_clear_bit (k, nbits-1);
+	}
+
+      if (!(mpi_cmp (k, q) < 0))    /* check: k < q */
+        {
+          if (DBG_CIPHER)
+            log_debug ("\tk too large - again");
+          continue; /* no  */
+        }
+      if (!(mpi_cmp_ui (k, 0) > 0)) /* check: k > 0 */
+        {
+          if (DBG_CIPHER)
+            log_debug ("\tk is zero - again");
+          continue; /* no */
+        }
+      break;	/* okay */
+    }
+  gcry_free (rndbuf);
+
+  return k;
+}
diff --git a/cipher/dsa.c b/cipher/dsa.c
index 883a815..90edeb5 100644
--- a/cipher/dsa.c
+++ b/cipher/dsa.c
@@ -26,6 +26,8 @@
 #include "g10lib.h"
 #include "mpi.h"
 #include "cipher.h"
+#include "pubkey-internal.h"
+
 
 typedef struct
 {
@@ -94,7 +96,6 @@ static const char sample_public_key[] =
 
 
 

-static gcry_mpi_t gen_k (gcry_mpi_t q);
 static int test_keys (DSA_secret_key *sk, unsigned int qbits);
 static int check_secret_key (DSA_secret_key *sk);
 static gpg_err_code_t generate (DSA_secret_key *sk,
@@ -130,81 +131,6 @@ progress (int c)
 }
 
 
-/*
- * Generate a random secret exponent k less than q.
- */
-static gcry_mpi_t
-gen_k( gcry_mpi_t q )
-{
-  gcry_mpi_t k = mpi_alloc_secure( mpi_get_nlimbs(q) );
-  unsigned int nbits = mpi_get_nbits(q);
-  unsigned int nbytes = (nbits+7)/8;
-  char *rndbuf = NULL;
-
-  /* To learn why we don't use mpi_mod to get the requested bit size,
-     read the paper: "The Insecurity of the Digital Signature
-     Algorithm with Partially Known Nonces" by Nguyen and Shparlinski.
-     Journal of Cryptology, New York. Vol 15, nr 3 (2003)  */
-
-  if ( DBG_CIPHER )
-    log_debug("choosing a random k ");
-  for (;;)
-    {
-      if( DBG_CIPHER )
-        progress('.');
-
-      if ( !rndbuf || nbits < 32 )
-        {
-          gcry_free(rndbuf);
-          rndbuf = gcry_random_bytes_secure( (nbits+7)/8, GCRY_STRONG_RANDOM );
-	}
-      else
-        { /* Change only some of the higher bits.  We could improve
-	     this by directly requesting more memory at the first call
-	     to get_random_bytes() and use these extra bytes here.
-	     However the required management code is more complex and
-	     thus we better use this simple method.  */
-          char *pp = gcry_random_bytes_secure( 4, GCRY_STRONG_RANDOM );
-          memcpy( rndbuf,pp, 4 );
-          gcry_free(pp);
-	}
-      _gcry_mpi_set_buffer( k, rndbuf, nbytes, 0 );
-
-      /* Make sure we have the requested number of bits.  This code
-         looks a bit funny but it is easy to understand if you
-         consider that mpi_set_highbit clears all higher bits.  We
-         don't have a clear_highbit, thus we first set the high bit
-         and then clear it again.  */
-      if ( mpi_test_bit( k, nbits-1 ) )
-        mpi_set_highbit( k, nbits-1 );
-      else
-        {
-          mpi_set_highbit( k, nbits-1 );
-          mpi_clear_bit( k, nbits-1 );
-	}
-
-      if( !(mpi_cmp( k, q ) < 0) ) /* check: k < q */
-        {
-          if( DBG_CIPHER )
-            progress('+');
-          continue; /* no  */
-        }
-      if( !(mpi_cmp_ui( k, 0 ) > 0) )  /* check: k > 0 */
-        {
-          if( DBG_CIPHER )
-            progress('-');
-          continue; /* no */
-        }
-      break;	/* okay */
-    }
-  gcry_free(rndbuf);
-  if( DBG_CIPHER )
-    progress('\n');
-
-  return k;
-}
-
-
 /* Check that a freshly generated key actually works.  Returns 0 on success. */
 static int
 test_keys (DSA_secret_key *sk, unsigned int qbits)
@@ -333,6 +259,13 @@ generate (DSA_secret_key *sk, unsigned int nbits, unsigned int qbits,
 
   /* Select a random number X with the property:
    *	 0 < x < q-1
+   *
+   * FIXME: Why do we use the requirement x < q-1 ? It should be
+   * sufficient to test for x < q.  FIPS-186-3 check x < q-1 but it
+   * does not check for 0 < x because it makes sure that Q is unsigned
+   * and finally adds one to the result so that 0 will never be
+   * returned.  We should replace the code below with _gcry_dsa_gen_k.
+   *
    * This must be a very good random number because this is the secret
    * part.  The random quality depends on the transient_key flag.  */
   random_level = transient_key ? GCRY_STRONG_RANDOM : GCRY_VERY_STRONG_RANDOM;
@@ -613,7 +546,7 @@ sign(gcry_mpi_t r, gcry_mpi_t s, gcry_mpi_t hash, DSA_secret_key *skey )
   gcry_mpi_t tmp;
 
   /* Select a random k with 0 < k < q */
-  k = gen_k( skey->q );
+  k = _gcry_dsa_gen_k (skey->q, GCRY_STRONG_RANDOM);
 
   /* r = (a^k mod p) mod q */
   gcry_mpi_powm( r, skey->g, k, skey->p );
diff --git a/cipher/ecc.c b/cipher/ecc.c
index ea1de3f..63ee2d0 100644
--- a/cipher/ecc.c
+++ b/cipher/ecc.c
@@ -306,7 +306,6 @@ static void *progress_cb_data;
 
 

 /* Local prototypes. */
-static gcry_mpi_t gen_k (gcry_mpi_t p, int security_level);
 static void test_keys (ECC_secret_key * sk, unsigned int nbits);
 static int check_secret_key (ECC_secret_key * sk);
 static gpg_err_code_t sign (gcry_mpi_t input, ECC_secret_key *skey,
@@ -424,30 +423,6 @@ gen_y_2 (gcry_mpi_t x, elliptic_curve_t *base)
 }
 
 
-/* Generate a random secret scalar k with an order of p
-
-   At the beginning this was identical to the code is in elgamal.c.
-   Later imporved by mmr.   Further simplified by wk.  */
-static gcry_mpi_t
-gen_k (gcry_mpi_t p, int security_level)
-{
-  gcry_mpi_t k;
-  unsigned int nbits;
-
-  nbits = mpi_get_nbits (p);
-  k = mpi_snew (nbits);
-  if (DBG_CIPHER)
-    log_debug ("choosing a random k of %u bits at seclevel %d\n",
-               nbits, security_level);
-
-  gcry_mpi_randomize (k, nbits, security_level);
-
-  mpi_mod (k, k, p);  /*  k = k mod p  */
-
-  return k;
-}
-
-
 /* Generate the crypto system setup.  This function takes the NAME of
    a curve or the desired number of bits and stores at R_CURVE the
    parameters of the named curve or those of a suitable curve.  If
@@ -554,7 +529,7 @@ generate_key (ECC_secret_key *sk, unsigned int nbits, const char *name,
     }
 
   random_level = transient_key ? GCRY_STRONG_RANDOM : GCRY_VERY_STRONG_RANDOM;
-  d = gen_k (E.n, random_level);
+  d = _gcry_dsa_gen_k (E.n, random_level);
 
   /* Compute Q.  */
   point_init (&Q);
@@ -806,7 +781,7 @@ sign (gcry_mpi_t input, ECC_secret_key *skey, gcry_mpi_t r, gcry_mpi_t s)
              do_while because we want to keep the value of R even if S
              has to be recomputed.  */
           mpi_free (k);
-          k = gen_k (skey->E.n, GCRY_STRONG_RANDOM);
+          k = _gcry_dsa_gen_k (skey->E.n, GCRY_STRONG_RANDOM);
           _gcry_mpi_ec_mul_point (&I, k, &skey->E.G, ctx);
           if (_gcry_mpi_ec_get_affine (x, NULL, &I, ctx))
             {
diff --git a/cipher/pubkey-internal.h b/cipher/pubkey-internal.h
index 0ca17a5..ae7e77b 100644
--- a/cipher/pubkey-internal.h
+++ b/cipher/pubkey-internal.h
@@ -20,6 +20,9 @@
 #ifndef GCRY_PUBKEY_INTERNAL_H
 #define GCRY_PUBKEY_INTERNAL_H
 
+/*-- dsa-common.h --*/
+gcry_mpi_t _gcry_dsa_gen_k (gcry_mpi_t q, int security_level);
+
 
 /*-- ecc.c --*/
 gpg_err_code_t _gcry_pk_ecc_get_sexp (gcry_sexp_t *r_sexp, int mode,

-----------------------------------------------------------------------

Summary of changes:
 cipher/Makefile.am       |    1 +
 cipher/dsa-common.c      |  101 ++++++++++++++++++++++++++++++++++++++++++++++
 cipher/dsa.c             |   87 +++++-----------------------------------
 cipher/ecc.c             |   72 ++++++++------------------------
 cipher/pubkey-internal.h |    3 +
 5 files changed, 133 insertions(+), 131 deletions(-)
 create mode 100644 cipher/dsa-common.c


hooks/post-receive
-- 
The GNU crypto library
http://git.gnupg.org




More information about the Gnupg-commits mailing list