From 3175cde841a8a7836fcf74a3e1b804c71a3aa153 Mon Sep 17 00:00:00 2001 From: Christian Grothoff Date: Thu, 17 May 2018 11:29:41 +0200 Subject: [PATCH] deduplicate code in crypto_ecc --- src/util/crypto_ecc.c | 137 +++++++++++++----------------- src/util/test_crypto_ecdh_eddsa.c | 2 + src/util/test_crypto_ecdhe.c | 25 +++--- 3 files changed, 75 insertions(+), 89 deletions(-) diff --git a/src/util/crypto_ecc.c b/src/util/crypto_ecc.c index 5d5e8a9ce..8cc6c18cb 100644 --- a/src/util/crypto_ecc.c +++ b/src/util/crypto_ecc.c @@ -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; } /** diff --git a/src/util/test_crypto_ecdh_eddsa.c b/src/util/test_crypto_ecdh_eddsa.c index efb9e0992..246cec27f 100644 --- a/src/util/test_crypto_ecdh_eddsa.c +++ b/src/util/test_crypto_ecdh_eddsa.c @@ -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; } diff --git a/src/util/test_crypto_ecdhe.c b/src/util/test_crypto_ecdhe.c index 0cfb7f2c3..d59562552 100644 --- a/src/util/test_crypto_ecdhe.c +++ b/src/util/test_crypto_ecdhe.c @@ -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; } -- 2.25.1