const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv,
struct GNUNET_CRYPTO_EcdsaPublicKey *pub)
{
- gcry_sexp_t sexp;
- gcry_ctx_t ctx;
- gcry_mpi_t q;
-
BENCHMARK_START (ecdsa_key_get_public);
-
- sexp = decode_private_ecdsa_key (priv);
- GNUNET_assert (NULL != sexp);
- GNUNET_assert (0 == gcry_mpi_ec_new (&ctx, sexp, NULL));
- gcry_sexp_release (sexp);
- q = gcry_mpi_ec_get_mpi ("q@eddsa", ctx, 0);
- GNUNET_assert (NULL != q);
- GNUNET_CRYPTO_mpi_print_unsigned (pub->q_y, sizeof(pub->q_y), q);
- gcry_mpi_release (q);
- gcry_ctx_release (ctx);
-
+ GNUNET_TWEETNACL_scalarmult_le_ed25519_base (pub->q_y, priv->d);
BENCHMARK_END (ecdsa_key_get_public);
}
}
-/**
- * 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.
const struct GNUNET_CRYPTO_EcdhePublicKey *pub,
struct GNUNET_HashCode *key_material)
{
- gcry_mpi_point_t result;
- gcry_mpi_point_t q;
- gcry_mpi_t d;
- gcry_ctx_t ctx;
- gcry_sexp_t pub_sexpr;
- int ret;
+ uint8_t p[GNUNET_TWEETNACL_SCALARMULT_BYTES];
+ uint8_t d_rev[GNUNET_TWEETNACL_SCALARMULT_BYTES];
BENCHMARK_START (ecdsa_ecdh);
-
- /* first, extract the q = dP value from the public key */
- if (0 != gcry_sexp_build (&pub_sexpr,
- NULL,
- "(public-key(ecc(curve " CURVE ")(q %b)))",
- (int) sizeof(pub->q_y),
- pub->q_y))
- return GNUNET_SYSERR;
- GNUNET_assert (0 == gcry_mpi_ec_new (&ctx, pub_sexpr, NULL));
- gcry_sexp_release (pub_sexpr);
- q = gcry_mpi_ec_get_point ("q", ctx, 0);
-
- /* second, extract the d value from our private key */
- GNUNET_CRYPTO_mpi_scan_unsigned (&d, priv->d, sizeof(priv->d));
-
- /* then call the 'multiply' function, to compute the product */
- result = gcry_mpi_point_new (0);
- gcry_mpi_ec_mul (result, d, q, ctx);
- gcry_mpi_point_release (q);
- gcry_mpi_release (d);
-
- /* finally, convert point to string for hashing */
- ret = point_to_hash (result, ctx, key_material);
- gcry_mpi_point_release (result);
- gcry_ctx_release (ctx);
+ for (size_t i = 0; i < 32; i++)
+ d_rev[i] = priv->d[31 - i];
+ GNUNET_TWEETNACL_scalarmult_curve25519 (p, d_rev, pub->q_y);
+ GNUNET_CRYPTO_hash (p,
+ GNUNET_TWEETNACL_SCALARMULT_BYTES,
+ key_material);
BENCHMARK_END (ecdsa_ecdh);
- return ret;
+ return GNUNET_OK;
}
/**
* @ingroup crypto
* Derive key material from a ECDSA public key and a private ECDH key.
- * Dual to #GNUNET_CRRYPTO_eddsa_ecdh.
+ * Dual to #GNUNET_CRYPTO_ecdsa_ecdh.
*
* @param priv private key to use for the ECDH (y)
* @param pub public key from ECDSA to use for the ECDH (X=h(x)G)
const struct GNUNET_CRYPTO_EcdsaPublicKey *pub,
struct GNUNET_HashCode *key_material)
{
- return GNUNET_CRYPTO_ecdh_eddsa (priv,
- (const struct GNUNET_CRYPTO_EddsaPublicKey *)
- pub,
- key_material);
+ uint8_t p[GNUNET_TWEETNACL_SCALARMULT_BYTES];
+ uint8_t curve25510_pk[GNUNET_TWEETNACL_SIGN_PUBLICBYTES];
+
+ GNUNET_TWEETNACL_sign_ed25519_pk_to_curve25519 (curve25510_pk, pub->q_y);
+ GNUNET_TWEETNACL_scalarmult_curve25519 (p, priv->d, curve25510_pk);
+ GNUNET_CRYPTO_hash (p, GNUNET_TWEETNACL_SCALARMULT_BYTES, key_material);
+ return GNUNET_OK;
}