deduplicate code in crypto_ecc
authorChristian Grothoff <christian@grothoff.org>
Thu, 17 May 2018 09:29:41 +0000 (11:29 +0200)
committerChristian Grothoff <christian@grothoff.org>
Thu, 17 May 2018 09:29:41 +0000 (11:29 +0200)
src/util/crypto_ecc.c
src/util/test_crypto_ecdh_eddsa.c
src/util/test_crypto_ecdhe.c

index 5d5e8a9cec5b2d1c2717f5c0d7ac9d151524d85f..8cc6c18cbdab5118fe51f2755e0e4e08c62aa6d3 100644 (file)
@@ -1278,6 +1278,48 @@ eddsa_d_to_a (gcry_mpi_t d)
 }
 
 
+/**
+ * Take point from ECDH and convert it to key material.
+ *
+ * @param result point from ECDH
+ * @param ctx ECC context
+ * @param key_material[out] set to derived key material
+ * @return #GNUNET_OK on success
+ */
+static int
+point_to_hash (gcry_mpi_point_t result,
+               gcry_ctx_t ctx,
+               struct GNUNET_HashCode *key_material)
+{
+  gcry_mpi_t result_x;
+  unsigned char xbuf[256 / 8];
+  size_t rsize;
+
+  /* finally, convert point to string for hashing */
+  result_x = gcry_mpi_new (256);
+  if (gcry_mpi_ec_get_affine (result_x, NULL, result, ctx))
+  {
+    LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "get_affine failed", 0);
+    return GNUNET_SYSERR;
+  }
+
+  rsize = sizeof (xbuf);
+  GNUNET_assert (! gcry_mpi_get_flag (result_x, GCRYMPI_FLAG_OPAQUE));
+  /* result_x can be negative here, so we do not use 'GNUNET_CRYPTO_mpi_print_unsigned'
+     as that does not include the sign bit; x should be a 255-bit
+     value, so with the sign it should fit snugly into the 256-bit
+     xbuf */
+  GNUNET_assert (0 ==
+                 gcry_mpi_print (GCRYMPI_FMT_STD, xbuf, rsize, &rsize,
+                                 result_x));
+  GNUNET_CRYPTO_hash (xbuf,
+                      rsize,
+                      key_material);
+  gcry_mpi_release (result_x);
+  return GNUNET_OK;
+}
+
+
 /**
  * @ingroup crypto
  * Derive key material from a ECDH public key and a private EdDSA key.
@@ -1299,9 +1341,7 @@ GNUNET_CRYPTO_eddsa_ecdh (const struct GNUNET_CRYPTO_EddsaPrivateKey *priv,
   gcry_mpi_t a;
   gcry_ctx_t ctx;
   gcry_sexp_t pub_sexpr;
-  gcry_mpi_t result_x;
-  unsigned char xbuf[256 / 8];
-  size_t rsize;
+  int ret;
 
   /* first, extract the q = dP value from the public key */
   if (0 != gcry_sexp_build (&pub_sexpr, NULL,
@@ -1325,34 +1365,15 @@ GNUNET_CRYPTO_eddsa_ecdh (const struct GNUNET_CRYPTO_EddsaPrivateKey *priv,
   gcry_mpi_point_release (q);
   gcry_mpi_release (a);
 
-  /* finally, convert point to string for hashing */
-  result_x = gcry_mpi_new (256);
-  if (gcry_mpi_ec_get_affine (result_x, NULL, result, ctx))
-  {
-    LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "get_affine failed", 0);
-    gcry_mpi_point_release (result);
-    gcry_ctx_release (ctx);
-    return GNUNET_SYSERR;
-  }
+  ret = point_to_hash (result,
+                       ctx,
+                       key_material);
   gcry_mpi_point_release (result);
   gcry_ctx_release (ctx);
-
-  rsize = sizeof (xbuf);
-  GNUNET_assert (! gcry_mpi_get_flag (result_x, GCRYMPI_FLAG_OPAQUE));
-  /* result_x can be negative here, so we do not use 'GNUNET_CRYPTO_mpi_print_unsigned'
-     as that does not include the sign bit; x should be a 255-bit
-     value, so with the sign it should fit snugly into the 256-bit
-     xbuf */
-  GNUNET_assert (0 ==
-                 gcry_mpi_print (GCRYMPI_FMT_STD, xbuf, rsize, &rsize,
-                                 result_x));
-  GNUNET_CRYPTO_hash (xbuf,
-                      rsize,
-                      key_material);
-  gcry_mpi_release (result_x);
-  return GNUNET_OK;
+  return ret;
 }
 
+
 /**
  * @ingroup crypto
  * Derive key material from a ECDH public key and a private ECDSA key.
@@ -1373,9 +1394,7 @@ GNUNET_CRYPTO_ecdsa_ecdh (const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv,
   gcry_mpi_t d;
   gcry_ctx_t ctx;
   gcry_sexp_t pub_sexpr;
-  gcry_mpi_t result_x;
-  unsigned char xbuf[256 / 8];
-  size_t rsize;
+  int ret;
 
   /* first, extract the q = dP value from the public key */
   if (0 != gcry_sexp_build (&pub_sexpr, NULL,
@@ -1396,31 +1415,12 @@ GNUNET_CRYPTO_ecdsa_ecdh (const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv,
   gcry_mpi_release (d);
 
   /* finally, convert point to string for hashing */
-  result_x = gcry_mpi_new (256);
-  if (gcry_mpi_ec_get_affine (result_x, NULL, result, ctx))
-  {
-    LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "get_affine failed", 0);
-    gcry_mpi_point_release (result);
-    gcry_ctx_release (ctx);
-    return GNUNET_SYSERR;
-  }
+  ret = point_to_hash (result,
+                       ctx,
+                       key_material);
   gcry_mpi_point_release (result);
   gcry_ctx_release (ctx);
-
-  rsize = sizeof (xbuf);
-  GNUNET_assert (! gcry_mpi_get_flag (result_x, GCRYMPI_FLAG_OPAQUE));
-  /* result_x can be negative here, so we do not use 'GNUNET_CRYPTO_mpi_print_unsigned'
-     as that does not include the sign bit; x should be a 255-bit
-     value, so with the sign it should fit snugly into the 256-bit
-     xbuf */
-  GNUNET_assert (0 ==
-                 gcry_mpi_print (GCRYMPI_FMT_STD, xbuf, rsize, &rsize,
-                                 result_x));
-  GNUNET_CRYPTO_hash (xbuf,
-                      rsize,
-                      key_material);
-  gcry_mpi_release (result_x);
-  return GNUNET_OK;
+  return ret;
 }
 
 
@@ -1445,9 +1445,7 @@ GNUNET_CRYPTO_ecdh_eddsa (const struct GNUNET_CRYPTO_EcdhePrivateKey *priv,
   gcry_mpi_t d;
   gcry_ctx_t ctx;
   gcry_sexp_t pub_sexpr;
-  gcry_mpi_t result_x;
-  unsigned char xbuf[256 / 8];
-  size_t rsize;
+  int ret;
 
   /* first, extract the q = dP value from the public key */
   if (0 != gcry_sexp_build (&pub_sexpr, NULL,
@@ -1468,31 +1466,12 @@ GNUNET_CRYPTO_ecdh_eddsa (const struct GNUNET_CRYPTO_EcdhePrivateKey *priv,
   gcry_mpi_release (d);
 
   /* finally, convert point to string for hashing */
-  result_x = gcry_mpi_new (256);
-  if (gcry_mpi_ec_get_affine (result_x, NULL, result, ctx))
-  {
-    LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "get_affine failed", 0);
-    gcry_mpi_point_release (result);
-    gcry_ctx_release (ctx);
-    return GNUNET_SYSERR;
-  }
+  ret = point_to_hash (result,
+                       ctx,
+                       key_material);
   gcry_mpi_point_release (result);
   gcry_ctx_release (ctx);
-
-  rsize = sizeof (xbuf);
-  GNUNET_assert (! gcry_mpi_get_flag (result_x, GCRYMPI_FLAG_OPAQUE));
-  /* result_x can be negative here, so we do not use 'GNUNET_CRYPTO_mpi_print_unsigned'
-     as that does not include the sign bit; x should be a 255-bit
-     value, so with the sign it should fit snugly into the 256-bit
-     xbuf */
-  GNUNET_assert (0 ==
-                 gcry_mpi_print (GCRYMPI_FMT_STD, xbuf, rsize, &rsize,
-                                 result_x));
-  GNUNET_CRYPTO_hash (xbuf,
-                      rsize,
-                      key_material);
-  gcry_mpi_release (result_x);
-  return GNUNET_OK;
+  return ret;
 }
 
 /**
index efb9e0992caa7f1584975437ade3bc03835e34df..246cec27f84a90f6cc243a7aec00e165781d7e02 100644 (file)
@@ -80,6 +80,8 @@ main (int argc, char *argv[])
   GNUNET_log_setup ("test-crypto-ecdh-eddsa", "WARNING", NULL);
   for (unsigned int i=0;i<10000;i++)
   {
+    fprintf (stderr,
+             ".");
     if (0 != test_ecdh())
       return 1;
   }
index 0cfb7f2c361772622f27b1e8e0f3937f6af456e2..d595625527cb47f5089522d86e098a7cb006b219 100644 (file)
@@ -50,16 +50,21 @@ main (int argc, char *argv[])
     gcry_control (GCRYCTL_SET_DEBUG_FLAGS, 1u , 0);
   GNUNET_log_setup ("test-crypto-ecdhe", "WARNING", NULL);
 
-  priv1 = GNUNET_CRYPTO_ecdhe_key_create ();
-  priv2 = GNUNET_CRYPTO_ecdhe_key_create ();
-  GNUNET_CRYPTO_ecdhe_key_get_public (priv1, &pub1);
-  GNUNET_CRYPTO_ecdhe_key_get_public (priv2, &pub2);
-  GNUNET_CRYPTO_ecc_ecdh (priv1, &pub2, &ecdh1);
-  GNUNET_CRYPTO_ecc_ecdh (priv2, &pub1, &ecdh2);
-  GNUNET_assert (0 == memcmp (&ecdh1, &ecdh2,
-                             sizeof (struct GNUNET_HashCode)));
-  GNUNET_free (priv1);
-  GNUNET_free (priv2);
+  for (unsigned int i=0;i<100;i++)
+  {
+    fprintf (stderr,
+             ".");
+    priv1 = GNUNET_CRYPTO_ecdhe_key_create ();
+    priv2 = GNUNET_CRYPTO_ecdhe_key_create ();
+    GNUNET_CRYPTO_ecdhe_key_get_public (priv1, &pub1);
+    GNUNET_CRYPTO_ecdhe_key_get_public (priv2, &pub2);
+    GNUNET_CRYPTO_ecc_ecdh (priv1, &pub2, &ecdh1);
+    GNUNET_CRYPTO_ecc_ecdh (priv2, &pub1, &ecdh2);
+    GNUNET_assert (0 == memcmp (&ecdh1, &ecdh2,
+                                sizeof (struct GNUNET_HashCode)));
+    GNUNET_free (priv1);
+    GNUNET_free (priv2);
+  }
   return 0;
 }