[git] GCRYPT - branch, master, updated. libgcrypt-1.5.0-281-ga2618c8

by Werner Koch cvs at cvs.gnupg.org
Mon Sep 30 21:23:11 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  a2618c822e666d4121cba29bee3fd50bf70c9743 (commit)
       via  c325adb8f5092b80a626bd3bb5e49cf7f3a29fc8 (commit)
       via  d69a13d3d1c14ad6a6aa7cd349d6d2dfb152d422 (commit)
      from  68cefd0f1d60ac33b58031df9b1d165cb1bf0f14 (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 a2618c822e666d4121cba29bee3fd50bf70c9743
Author: Werner Koch <wk at gnupg.org>
Date:   Mon Sep 30 20:32:20 2013 +0200

    ecc: Prepare for future Ed25519 optimization.
    
    * mpi/ec-ed25519.c: New but empty file.
    * mpi/ec-internal.h: New.
    * mpi/ec.c: Include ec-internal.h.
    (ec_mod): New.
    (ec_addm): Use ec_mod.
    (ec_mulm): Remove commented code.  Use ec_mod.
    (ec_subm): Call simple sub.
    (ec_pow2): Use ec_mulm.
    (ec_mul2): New.
    (dup_point_weierstrass): Use ec_mul2.
    (dup_point_twistededwards): Add special case for a == -1.  Use
    ec_mul2.
    (add_points_weierstrass): Use ec_mul2.
    (add_points_twistededwards): Add special case for a == -1.
    (_gcry_mpi_ec_curve_point): Ditto.
    (ec_p_init): Add hack to test Barrett functions.
    * src/ec-context.h (mpi_ec_ctx_s): Add P_BARRETT.
    
    * mpi/mpi-mod.c (_gcry_mpi_mod_barrett): Fix sign problem.
    
    Signed-off-by: Werner Koch <wk at gnupg.org>

diff --git a/mpi/Makefile.am b/mpi/Makefile.am
index e900539..c41b1ea 100644
--- a/mpi/Makefile.am
+++ b/mpi/Makefile.am
@@ -174,4 +174,4 @@ libmpi_la_SOURCES = longlong.h	   \
 	      mpih-div.c     \
 	      mpih-mul.c     \
 	      mpiutil.c      \
-              ec.c
+              ec.c ec-internal.h ec-ed25519.c
diff --git a/mpi/ec-ed25519.c b/mpi/ec-ed25519.c
new file mode 100644
index 0000000..acfe2a6
--- /dev/null
+++ b/mpi/ec-ed25519.c
@@ -0,0 +1,37 @@
+/* ec-ed25519.c -  Ed25519 optimized elliptic curve functions
+ * Copyright (C) 2013 g10 Code GmbH
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
+
+#include "mpi-internal.h"
+#include "longlong.h"
+#include "g10lib.h"
+#include "context.h"
+#include "ec-context.h"
+
+
+void
+_gcry_mpi_ec_ed25519_mod (gcry_mpi_t a)
+{
+  (void)a;
+
+}
diff --git a/mpi/ec-internal.h b/mpi/ec-internal.h
new file mode 100644
index 0000000..759335a
--- /dev/null
+++ b/mpi/ec-internal.h
@@ -0,0 +1,25 @@
+/* ec-internal.h - Internal declarations of ec*.c
+ * 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/>.
+ */
+
+#ifndef GCRY_EC_INTERNAL_H
+#define GCRY_EC_INTERNAL_H
+
+void _gcry_mpi_ec_ed25519_mod (gcry_mpi_t a);
+
+#endif /*GCRY_EC_INTERNAL_H*/
diff --git a/mpi/ec.c b/mpi/ec.c
index de681a1..889df8e 100644
--- a/mpi/ec.c
+++ b/mpi/ec.c
@@ -28,6 +28,7 @@
 #include "g10lib.h"
 #include "context.h"
 #include "ec-context.h"
+#include "ec-internal.h"
 
 
 #define point_init(a)  _gcry_mpi_point_init ((a))
@@ -224,131 +225,46 @@ gcry_mpi_point_snatch_set (mpi_point_t point,
 }
 
 
+/* W = W mod P.  */
+static void
+ec_mod (gcry_mpi_t w, mpi_ec_t ec)
+{
+  if (0 && ec->dialect == ECC_DIALECT_ED25519)
+    _gcry_mpi_ec_ed25519_mod (w);
+  else if (ec->t.p_barrett)
+    _gcry_mpi_mod_barrett (w, w, ec->t.p_barrett);
+  else
+    _gcry_mpi_mod (w, w, ec->p);
+}
+
 static void
 ec_addm (gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v, mpi_ec_t ctx)
 {
-  mpi_addm (w, u, v, ctx->p);
+  gcry_mpi_add (w, u, v);
+  ec_mod (w, ctx);
 }
 
 static void
-ec_subm (gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v, mpi_ec_t ctx)
+ec_subm (gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v, mpi_ec_t ec)
 {
-  mpi_subm (w, u, v, ctx->p);
+  (void)ec;
+  gcry_mpi_sub (w, u, v);
+  /*ec_mod (w, ec);*/
 }
 
 static void
 ec_mulm (gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v, mpi_ec_t ctx)
 {
-#if 0
-  /* NOTE: This code works only for limb sizes of 32 bit.  */
-  mpi_limb_t *wp, *sp;
+  mpi_mul (w, u, v);
+  ec_mod (w, ctx);
+}
 
-  if (ctx->nist_nbits == 192)
-    {
-      mpi_mul (w, u, v);
-      mpi_resize (w, 12);
-      wp = w->d;
-
-      sp = ctx->s[0]->d;
-      sp[0*2+0] = wp[0*2+0];
-      sp[0*2+1] = wp[0*2+1];
-      sp[1*2+0] = wp[1*2+0];
-      sp[1*2+1] = wp[1*2+1];
-      sp[2*2+0] = wp[2*2+0];
-      sp[2*2+1] = wp[2*2+1];
-
-      sp = ctx->s[1]->d;
-      sp[0*2+0] = wp[3*2+0];
-      sp[0*2+1] = wp[3*2+1];
-      sp[1*2+0] = wp[3*2+0];
-      sp[1*2+1] = wp[3*2+1];
-      sp[2*2+0] = 0;
-      sp[2*2+1] = 0;
-
-      sp = ctx->s[2]->d;
-      sp[0*2+0] = 0;
-      sp[0*2+1] = 0;
-      sp[1*2+0] = wp[4*2+0];
-      sp[1*2+1] = wp[4*2+1];
-      sp[2*2+0] = wp[4*2+0];
-      sp[2*2+1] = wp[4*2+1];
-
-      sp = ctx->s[3]->d;
-      sp[0*2+0] = wp[5*2+0];
-      sp[0*2+1] = wp[5*2+1];
-      sp[1*2+0] = wp[5*2+0];
-      sp[1*2+1] = wp[5*2+1];
-      sp[2*2+0] = wp[5*2+0];
-      sp[2*2+1] = wp[5*2+1];
-
-      ctx->s[0]->nlimbs = 6;
-      ctx->s[1]->nlimbs = 6;
-      ctx->s[2]->nlimbs = 6;
-      ctx->s[3]->nlimbs = 6;
-
-      mpi_add (ctx->c, ctx->s[0], ctx->s[1]);
-      mpi_add (ctx->c, ctx->c, ctx->s[2]);
-      mpi_add (ctx->c, ctx->c, ctx->s[3]);
-
-      while ( mpi_cmp (ctx->c, ctx->p ) >= 0 )
-        mpi_sub ( ctx->c, ctx->c, ctx->p );
-      mpi_set (w, ctx->c);
-    }
-  else if (ctx->nist_nbits == 384)
-    {
-      int i;
-      mpi_mul (w, u, v);
-      mpi_resize (w, 24);
-      wp = w->d;
-
-#define NEXT(a) do { ctx->s[(a)]->nlimbs = 12; \
-                     sp = ctx->s[(a)]->d; \
-                     i = 0; } while (0)
-#define X(a) do { sp[i++] = wp[(a)];} while (0)
-#define X0(a) do { sp[i++] = 0; } while (0)
-      NEXT(0);
-      X(0);X(1);X(2);X(3);X(4);X(5);X(6);X(7);X(8);X(9);X(10);X(11);
-      NEXT(1);
-      X0();X0();X0();X0();X(21);X(22);X(23);X0();X0();X0();X0();X0();
-      NEXT(2);
-      X(12);X(13);X(14);X(15);X(16);X(17);X(18);X(19);X(20);X(21);X(22);X(23);
-      NEXT(3);
-      X(21);X(22);X(23);X(12);X(13);X(14);X(15);X(16);X(17);X(18);X(19);X(20);
-      NEXT(4);
-      X0();X(23);X0();X(20);X(12);X(13);X(14);X(15);X(16);X(17);X(18);X(19);
-      NEXT(5);
-      X0();X0();X0();X0();X(20);X(21);X(22);X(23);X0();X0();X0();X0();
-      NEXT(6);
-      X(20);X0();X0();X(21);X(22);X(23);X0();X0();X0();X0();X0();X0();
-      NEXT(7);
-      X(23);X(12);X(13);X(14);X(15);X(16);X(17);X(18);X(19);X(20);X(21);X(22);
-      NEXT(8);
-      X0();X(20);X(21);X(22);X(23);X0();X0();X0();X0();X0();X0();X0();
-      NEXT(9);
-      X0();X0();X0();X(23);X(23);X0();X0();X0();X0();X0();X0();X0();
-#undef X0
-#undef X
-#undef NEXT
-      mpi_add (ctx->c, ctx->s[0], ctx->s[1]);
-      mpi_add (ctx->c, ctx->c, ctx->s[1]);
-      mpi_add (ctx->c, ctx->c, ctx->s[2]);
-      mpi_add (ctx->c, ctx->c, ctx->s[3]);
-      mpi_add (ctx->c, ctx->c, ctx->s[4]);
-      mpi_add (ctx->c, ctx->c, ctx->s[5]);
-      mpi_add (ctx->c, ctx->c, ctx->s[6]);
-      mpi_sub (ctx->c, ctx->c, ctx->s[7]);
-      mpi_sub (ctx->c, ctx->c, ctx->s[8]);
-      mpi_sub (ctx->c, ctx->c, ctx->s[9]);
-
-      while ( mpi_cmp (ctx->c, ctx->p ) >= 0 )
-        mpi_sub ( ctx->c, ctx->c, ctx->p );
-      while ( ctx->c->sign )
-        mpi_add ( ctx->c, ctx->c, ctx->p );
-      mpi_set (w, ctx->c);
-    }
-  else
-#endif /*0*/
-    mpi_mulm (w, u, v, ctx->p);
+/* W = 2 * U mod P.  */
+static void
+ec_mul2 (gcry_mpi_t w, gcry_mpi_t u, mpi_ec_t ctx)
+{
+  mpi_lshift (w, u, 1);
+  ec_mod (w, ctx);
 }
 
 static void
@@ -368,7 +284,7 @@ ec_pow2 (gcry_mpi_t w, const gcry_mpi_t b, mpi_ec_t ctx)
 {
   /* Using mpi_mul is slightly faster (at least on amd64).  */
   /* mpi_powm (w, b, mpi_const (MPI_C_TWO), ctx->p); */
-  mpi_mulm (w, b, b, ctx->p);
+  ec_mulm (w, b, b, ctx);
 }
 
 
@@ -437,6 +353,15 @@ ec_p_init (mpi_ec_t ctx, enum gcry_mpi_ec_models model,
            gcry_mpi_t p, gcry_mpi_t a, gcry_mpi_t b)
 {
   int i;
+  static int use_barrett;
+
+  if (!use_barrett)
+    {
+      if (getenv ("GCRYPT_BARRETT"))
+        use_barrett = 1;
+      else
+        use_barrett = -1;
+    }
 
   /* Fixme: Do we want to check some constraints? e.g.  a < p  */
 
@@ -451,6 +376,8 @@ ec_p_init (mpi_ec_t ctx, enum gcry_mpi_ec_models model,
   if (b && model == MPI_EC_TWISTEDEDWARDS)
     ctx->b = mpi_copy (b);
 
+  ctx->t.p_barrett = use_barrett > 0? _gcry_mpi_barrett_init (ctx->p, 0):NULL;
+
   _gcry_mpi_ec_get_reset (ctx);
 
   /* Allocate scratch variables.  */
@@ -483,6 +410,8 @@ ec_deinit (void *opaque)
   mpi_ec_t ctx = opaque;
   int i;
 
+  _gcry_mpi_barrett_free (ctx->t.p_barrett);
+
   /* Domain parameter.  */
   mpi_free (ctx->p);
   mpi_free (ctx->a);
@@ -732,7 +661,7 @@ dup_point_weierstrass (mpi_point_t result, mpi_point_t point, mpi_ec_t ctx)
         }
       /* Z3 = 2YZ */
       ec_mulm (z3, point->y, point->z, ctx);
-      ec_mulm (z3, z3, mpi_const (MPI_C_TWO), ctx);
+      ec_mul2 (z3, z3, ctx);
 
       /* L2 = 4XY^2 */
       /*                              T2: used for Y2; required later. */
@@ -743,7 +672,7 @@ dup_point_weierstrass (mpi_point_t result, mpi_point_t point, mpi_ec_t ctx)
       /* X3 = L1^2 - 2L2 */
       /*                              T1: used for L2^2. */
       ec_pow2 (x3, l1, ctx);
-      ec_mulm (t1, l2, mpi_const (MPI_C_TWO), ctx);
+      ec_mul2 (t1, l2, ctx);
       ec_subm (x3, x3, t1, ctx);
 
       /* L3 = 8Y^4 */
@@ -811,7 +740,13 @@ dup_point_twistededwards (mpi_point_t result, mpi_point_t point, mpi_ec_t ctx)
   ec_pow2 (D, Y1, ctx);
 
   /* E = aC */
-  ec_mulm (E, ctx->a, C, ctx);
+  if (ctx->dialect == ECC_DIALECT_ED25519)
+    {
+      mpi_set (E, C);
+      _gcry_mpi_neg (E, E);
+    }
+  else
+    ec_mulm (E, ctx->a, C, ctx);
 
   /* F = E + D */
   ec_addm (F, E, D, ctx);
@@ -820,7 +755,7 @@ dup_point_twistededwards (mpi_point_t result, mpi_point_t point, mpi_ec_t ctx)
   ec_pow2 (H, Z1, ctx);
 
   /* J = F - 2H */
-  ec_mulm (J, H, mpi_const (MPI_C_TWO), ctx);
+  ec_mul2 (J, H, ctx);
   ec_subm (J, F, J, ctx);
 
   /* X_3 = (B - C - D) · J */
@@ -978,7 +913,7 @@ add_points_weierstrass (mpi_point_t result,
           ec_mulm (t2, t2, l7, ctx);
           ec_subm (x3, t1, t2, ctx);
           /* l9 = l7 l3^2 - 2 x3  */
-          ec_mulm (t1, x3, mpi_const (MPI_C_TWO), ctx);
+          ec_mul2 (t1, x3, ctx);
           ec_subm (l9, t2, t1, ctx);
           /* y3 = (l9 l6 - l8 l3^3)/2  */
           ec_mulm (l9, l9, l6, ctx);
@@ -1085,8 +1020,19 @@ add_points_twistededwards (mpi_point_t result,
   ec_mulm (X3, X3, A, ctx);
 
   /* Y_3 = A · G · (D - aC) */
-  ec_mulm (Y3, ctx->a, C, ctx);
-  ec_subm (Y3, D, Y3, ctx);
+  if (ctx->dialect == ECC_DIALECT_ED25519)
+    {
+      /* Using ec_addm (Y3, D, C, ctx) is possible but a litte bit
+         slower because a subm does currently skip the mod step.  */
+      mpi_set (Y3, C);
+      _gcry_mpi_neg (Y3, Y3);
+      ec_subm (Y3, D, Y3, ctx);
+    }
+  else
+    {
+      ec_mulm (Y3, ctx->a, C, ctx);
+      ec_subm (Y3, D, Y3, ctx);
+    }
   ec_mulm (Y3, Y3, G, ctx);
   ec_mulm (Y3, Y3, A, ctx);
 
@@ -1282,7 +1228,13 @@ _gcry_mpi_ec_curve_point (gcry_mpi_point_t point, mpi_ec_t ctx)
         /* a · x^2 + y^2 - 1 - b · x^2 · y^2 == 0 */
         ec_pow2 (x, x, ctx);
         ec_pow2 (y, y, ctx);
-        ec_mulm (w, ctx->a, x, ctx);
+        if (ctx->dialect == ECC_DIALECT_ED25519)
+          {
+            mpi_set (w, x);
+            _gcry_mpi_neg (w, w);
+          }
+        else
+          ec_mulm (w, ctx->a, x, ctx);
         ec_addm (w, w, y, ctx);
         ec_subm (w, w, mpi_const (MPI_C_ONE), ctx);
         ec_mulm (x, x, y, ctx);
diff --git a/mpi/mpi-mod.c b/mpi/mpi-mod.c
index 795826e..3d6248b 100644
--- a/mpi/mpi-mod.c
+++ b/mpi/mpi-mod.c
@@ -111,7 +111,7 @@ _gcry_mpi_barrett_free (mpi_barrett_t ctx)
    _gcry_mpi_barrett_init must have been called to do the
    precalculations.  CTX is the context created by this precalculation
    and also conveys M.  If the Barret reduction could no be done a
-   starightforward reduction method is used.
+   straightforward reduction method is used.
 
    We assume that these conditions are met:
    Input:  x =(x_2k-1 ...x_0)_b
@@ -126,6 +126,7 @@ _gcry_mpi_mod_barrett (gcry_mpi_t r, gcry_mpi_t x, mpi_barrett_t ctx)
   gcry_mpi_t y = ctx->y;
   gcry_mpi_t r1 = ctx->r1;
   gcry_mpi_t r2 = ctx->r2;
+  int sign;
 
   mpi_normalize (x);
   if (mpi_get_nlimbs (x) > 2*k )
@@ -134,6 +135,9 @@ _gcry_mpi_mod_barrett (gcry_mpi_t r, gcry_mpi_t x, mpi_barrett_t ctx)
       return;
     }
 
+  sign = x->sign;
+  x->sign = 0;
+
   /* 1. q1 = floor( x / b^k-1)
    *    q2 = q1 * y
    *    q3 = floor( q2 / b^k+1 )
@@ -172,6 +176,7 @@ _gcry_mpi_mod_barrett (gcry_mpi_t r, gcry_mpi_t x, mpi_barrett_t ctx)
   while ( mpi_cmp( r, m ) >= 0 )
     mpi_sub ( r, r, m );
 
+  x->sign = sign;
 }
 
 
diff --git a/src/ec-context.h b/src/ec-context.h
index 8dce7a7..ba6bdfc 100644
--- a/src/ec-context.h
+++ b/src/ec-context.h
@@ -53,6 +53,8 @@ struct mpi_ec_ctx_s
 
     gcry_mpi_t two_inv_p;
 
+    mpi_barrett_t p_barrett;
+
     /* Scratch variables.  */
     gcry_mpi_t scratch[11];
 
diff --git a/src/misc.c b/src/misc.c
index d577b24..912039a 100644
--- a/src/misc.c
+++ b/src/misc.c
@@ -396,7 +396,8 @@ _gcry_log_printsxp (const char *text, gcry_sexp_t sexp)
     {
       int any = 0;
       int n_closing;
-      char *buf, *p, *pend;
+      char *buf, *pend;
+      const char *p;
       size_t size;
 
       size = gcry_sexp_sprint (sexp, GCRYSEXP_FMT_ADVANCED, NULL, 0);

commit c325adb8f5092b80a626bd3bb5e49cf7f3a29fc8
Author: Werner Koch <wk at gnupg.org>
Date:   Mon Sep 30 20:17:05 2013 +0200

    ecc: Fix recomputing of Q for Ed25519.
    
    * cipher/ecc-misc.c (reverse_buffer): New.
    (_gcry_ecc_compute_public): Add ED255519 specific code.
    * cipher/ecc.c (sign_eddsa): Allocate DIGEST in secure memory.  Get
    rid of HASH_D.
    * tests/t-mpi-point.c (context_param): Test recomputing of Q for
    Ed25519.
    
    Signed-off-by: Werner Koch <wk at gnupg.org>

diff --git a/cipher/ecc-misc.c b/cipher/ecc-misc.c
index 1dc0480..d89971f 100644
--- a/cipher/ecc-misc.c
+++ b/cipher/ecc-misc.c
@@ -234,22 +234,96 @@ _gcry_ecc_os2ec (mpi_point_t result, gcry_mpi_t value)
 }
 
 
+static void
+reverse_buffer (unsigned char *buffer, unsigned int length)
+{
+  unsigned int tmp, i;
+
+  for (i=0; i < length/2; i++)
+    {
+      tmp = buffer[i];
+      buffer[i] = buffer[length-1-i];
+      buffer[length-1-i] = tmp;
+    }
+}
+
+
 /* Compute the public key from the the context EC.  Obviously a
    requirement is that the secret key is available in EC.  On success
-   Q is returned; on error NULL.  If Q is NULL a newly allocated pint
+   Q is returned; on error NULL.  If Q is NULL a newly allocated point
    is returned.  */
 mpi_point_t
 _gcry_ecc_compute_public (mpi_point_t Q, mpi_ec_t ec)
 {
+  int rc;
+
   if (!ec->d || !ec->G || !ec->p || !ec->a)
     return NULL;
   if (ec->model == MPI_EC_TWISTEDEDWARDS && !ec->b)
     return NULL;
 
-  if (!Q)
-    Q = gcry_mpi_point_new (0);
-  if (!Q)
-    return NULL;
-  _gcry_mpi_ec_mul_point (Q, ec->d, ec->G, ec);
+  switch (ec->dialect)
+    {
+    case ECC_DIALECT_ED25519:
+      {
+        gcry_mpi_t a;
+        unsigned char *rawmpi = NULL;
+        unsigned int rawmpilen;
+        unsigned char *digest;
+        gcry_buffer_t hvec[2];
+        int b = (ec->nbits+7)/8;
+
+        gcry_assert (b >= 32);
+        digest = gcry_calloc_secure (2, b);
+        if (!digest)
+          return NULL;
+        memset (hvec, 0, sizeof hvec);
+
+        rawmpi = _gcry_mpi_get_buffer (ec->d, 0, &rawmpilen, NULL);
+        if (!rawmpi)
+          return NULL;
+        memset (digest, 0, b);
+        hvec[0].data = digest;
+        hvec[0].off = 0;
+        hvec[0].len = b > rawmpilen? b - rawmpilen : 0;
+        hvec[1].data = rawmpi;
+        hvec[1].off = 0;
+        hvec[1].len = rawmpilen;
+        /* FIXME: Put and take the hash algo from the context.  */
+        rc = _gcry_md_hash_buffers (GCRY_MD_SHA512, 0, digest, hvec, 2);
+        gcry_free (rawmpi);
+        if (rc)
+          {
+            gcry_free (digest);
+            return NULL;
+          }
+
+        /* Compute the A value.  */
+        reverse_buffer (digest, 32);  /* Only the first half of the hash.  */
+        digest[0] = (digest[0] & 0x7f) | 0x40;
+        digest[31] &= 0xf8;
+        a = mpi_snew (0);
+        _gcry_mpi_set_buffer (a, digest, 32, 0);
+        gcry_free (digest);
+
+        /* And finally the public key.  */
+        if (!Q)
+          Q = gcry_mpi_point_new (0);
+        if (Q)
+          _gcry_mpi_ec_mul_point (Q, a, ec->G, ec);
+        mpi_free (a);
+      }
+      break;
+
+    default:
+      {
+        if (!Q)
+          Q = gcry_mpi_point_new (0);
+        if (Q)
+          _gcry_mpi_ec_mul_point (Q, ec->d, ec->G, ec);
+      }
+      break;
+    }
+
   return Q;
 }
diff --git a/cipher/ecc.c b/cipher/ecc.c
index abd501f..a7fb90f 100644
--- a/cipher/ecc.c
+++ b/cipher/ecc.c
@@ -909,8 +909,7 @@ sign_eddsa (gcry_mpi_t input, ECC_secret_key *skey,
   mpi_ec_t ctx = NULL;
   int b;
   unsigned int tmp;
-  unsigned char hash_d[64];  /* Fixme: malloc in secure memory */
-  unsigned char digest[64];
+  unsigned char *digest;
   gcry_buffer_t hvec[3];
   const void *mbuf;
   size_t mlen;
@@ -938,37 +937,41 @@ sign_eddsa (gcry_mpi_t input, ECC_secret_key *skey,
   r = mpi_new (0);
   ctx = _gcry_mpi_ec_p_internal_new (skey->E.model, skey->E.dialect,
                                      skey->E.p, skey->E.a, skey->E.b);
-  b = ctx->nbits/8;
+  b = (ctx->nbits+7)/8;
   if (b != 256/8)
     return GPG_ERR_INTERNAL; /* We only support 256 bit. */
 
+  digest = gcry_calloc_secure (2, b);
+  if (!digest)
+    {
+      rc = gpg_err_code_from_syserror ();
+      goto leave;
+    }
 
-  /* Hash the secret key.  We clear DIGEST so we can use it to left
-     pad the key with zeroes for hashing.  */
+  /* Hash the secret key.  We clear DIGEST so we can use it as input
+     to left pad the key with zeroes for hashing.  */
   rawmpi = _gcry_mpi_get_buffer (skey->d, 0, &rawmpilen, NULL);
   if (!rawmpi)
     {
       rc = gpg_err_code_from_syserror ();
       goto leave;
     }
-  memset (digest, 0, b);
   hvec[0].data = digest;
   hvec[0].off = 0;
   hvec[0].len = b > rawmpilen? b - rawmpilen : 0;
   hvec[1].data = rawmpi;
   hvec[1].off = 0;
   hvec[1].len = rawmpilen;
-  rc = _gcry_md_hash_buffers (hashalgo, 0, hash_d, hvec, 2);
+  rc = _gcry_md_hash_buffers (hashalgo, 0, digest, hvec, 2);
   gcry_free (rawmpi); rawmpi = NULL;
   if (rc)
     goto leave;
 
-  /* Compute the A value (this modifies hash_d).  */
-  reverse_buffer (hash_d, 32);  /* Only the first half of the hash.  */
-  hash_d[0] = (hash_d[0] & 0x7f) | 0x40;
-  hash_d[31] &= 0xf8;
-  _gcry_mpi_set_buffer (a, hash_d, 32, 0);
-  /* log_printmpi ("     a", a); */
+  /* Compute the A value (this modifies DIGEST).  */
+  reverse_buffer (digest, 32);  /* Only the first half of the hash.  */
+  digest[0] = (digest[0] & 0x7f) | 0x40;
+  digest[31] &= 0xf8;
+  _gcry_mpi_set_buffer (a, digest, 32, 0);
 
   /* Compute the public key if it has not been supplied as optional
      parameter.  */
@@ -1001,7 +1004,7 @@ sign_eddsa (gcry_mpi_t input, ECC_secret_key *skey,
   if (DBG_CIPHER)
     log_printhex ("     m", mbuf, mlen);
 
-  hvec[0].data = hash_d;
+  hvec[0].data = digest;
   hvec[0].off  = 32;
   hvec[0].len  = 32;
   hvec[1].data = (char*)mbuf;
@@ -1063,6 +1066,7 @@ sign_eddsa (gcry_mpi_t input, ECC_secret_key *skey,
   gcry_mpi_release (x);
   gcry_mpi_release (y);
   gcry_mpi_release (r);
+  gcry_free (digest);
   _gcry_mpi_ec_free (ctx);
   point_free (&I);
   point_free (&Q);
diff --git a/tests/t-mpi-point.c b/tests/t-mpi-point.c
index 0641779..5a0b311 100644
--- a/tests/t-mpi-point.c
+++ b/tests/t-mpi-point.c
@@ -666,9 +666,17 @@ context_param (void)
                          "Ed25519", ctx);
       get_and_cmp_mpi ("q at eddsa", sample_ed25519_q_eddsa, "Ed25519", ctx);
 
-      /* Delete Q by setting d and the clearing d.  The clearing is
+      /* Set d tosee whether Q is correctly re-computed.  */
+      d = hex2mpi (sample_ed25519_d);
+      err = gcry_mpi_ec_set_mpi ("d", d, ctx);
+      if (err)
+        fail ("setting d for Ed25519 failed: %s\n", gpg_strerror (err));
+      gcry_mpi_release (d);
+      get_and_cmp_mpi ("q", sample_ed25519_q, "Ed25519(recompute Q)", ctx);
+
+      /* Delete Q by setting d and then clearing d.  The clearing is
          required so that we can check whether Q has been cleared and
-         because further tests only expect a public key. */
+         because further tests only expect a public key.  */
       d = hex2mpi (sample_ed25519_d);
       err = gcry_mpi_ec_set_mpi ("d", d, ctx);
       if (err)

commit d69a13d3d1c14ad6a6aa7cd349d6d2dfb152d422
Author: Werner Koch <wk at gnupg.org>
Date:   Mon Sep 30 13:20:06 2013 +0200

    log: Try to print s-expressions in a more compact format.
    
    * src/misc.c (count_closing_parens): New.
    (_gcry_log_printsxp): Use new function.
    * mpi/ec.c (_gcry_mpi_point_log): Take care of a NULL point.
    
    Signed-off-by: Werner Koch <wk at gnupg.org>

diff --git a/mpi/ec.c b/mpi/ec.c
index c6d0fc8..de681a1 100644
--- a/mpi/ec.c
+++ b/mpi/ec.c
@@ -42,6 +42,12 @@ _gcry_mpi_point_log (const char *name, mpi_point_t point, mpi_ec_t ctx)
   gcry_mpi_t x, y;
   char buf[100];
 
+  if (!point)
+    {
+      snprintf (buf, sizeof buf - 1, "%s.*", name);
+      log_mpidump (buf, NULL);
+      return;
+    }
   snprintf (buf, sizeof buf - 1, "%s.X", name);
 
   if (ctx)
diff --git a/src/misc.c b/src/misc.c
index d9b85cb..d577b24 100644
--- a/src/misc.c
+++ b/src/misc.c
@@ -361,6 +361,22 @@ _gcry_log_printmpi (const char *text, gcry_mpi_t mpi)
     }
 }
 
+
+static int
+count_closing_parens (const char *p)
+{
+  int count = 0;
+
+  for (; *p; p++)
+    if (*p == ')')
+      count++;
+    else if (!strchr ("\n \t", *p))
+      return 0;
+
+  return count;
+}
+
+
 /* Print SEXP in human readabale format.  With TEXT of NULL print just the raw
    dump without any wrappping, with TEXT an empty string, print a
    trailing linefeed, otherwise print the full debug output. */
@@ -371,7 +387,7 @@ _gcry_log_printsxp (const char *text, gcry_sexp_t sexp)
 
   if (text && *text)
     {
-      if ((with_lf = strchr (text, '\n')))
+      if ((with_lf = !!strchr (text, '\n')))
         log_debug ("%s", text);
       else
         log_debug ("%s: ", text);
@@ -379,6 +395,7 @@ _gcry_log_printsxp (const char *text, gcry_sexp_t sexp)
   if (sexp)
     {
       int any = 0;
+      int n_closing;
       char *buf, *p, *pend;
       size_t size;
 
@@ -395,18 +412,26 @@ _gcry_log_printsxp (const char *text, gcry_sexp_t sexp)
           pend = strchr (p, '\n');
           size = pend? (pend - p) : strlen (p);
           if (with_lf)
-            log_debug ("%.*s\n", (int)size, p);
+            log_debug ("%.*s", (int)size, p);
           else
-            log_printf ("%.*s\n", (int)size, p);
+            log_printf ("%.*s", (int)size, p);
           if (pend)
             p = pend + 1;
           else
             p += size;
+          n_closing = count_closing_parens (p);
+          if (n_closing)
+            {
+              while (n_closing--)
+                log_printf (")");
+              p = "";
+            }
+          log_printf ("\n");
         }
       while (*p);
       gcry_free (buf);
     }
-  if (text)
+  else if (text)
     log_printf ("\n");
 }
 

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

Summary of changes:
 cipher/ecc-misc.c                     |   86 +++++++++++++-
 cipher/ecc.c                          |   32 +++---
 mpi/Makefile.am                       |    2 +-
 cipher/gost.h => mpi/ec-ed25519.c     |   30 +++--
 src/hwf-common.h => mpi/ec-internal.h |   16 +--
 mpi/ec.c                              |  200 +++++++++++++--------------------
 mpi/mpi-mod.c                         |    7 +-
 src/ec-context.h                      |    2 +
 src/misc.c                            |   36 +++++-
 tests/t-mpi-point.c                   |   12 ++-
 10 files changed, 251 insertions(+), 172 deletions(-)
 copy cipher/gost.h => mpi/ec-ed25519.c (63%)
 copy src/hwf-common.h => mpi/ec-internal.h (67%)


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


_______________________________________________
Gnupg-commits mailing list
Gnupg-commits at gnupg.org
http://lists.gnupg.org/mailman/listinfo/gnupg-commits


More information about the Gcrypt-devel mailing list