[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[gnunet] branch master updated: edx25519: use libsodium, tweak KDF call
From: |
gnunet |
Subject: |
[gnunet] branch master updated: edx25519: use libsodium, tweak KDF call |
Date: |
Tue, 19 Apr 2022 14:45:28 +0200 |
This is an automated email from the git hooks/post-receive script.
dold pushed a commit to branch master
in repository gnunet.
The following commit(s) were added to refs/heads/master by this push:
new 0487df9a0 edx25519: use libsodium, tweak KDF call
0487df9a0 is described below
commit 0487df9a041ac7ecde00d4ea4c6a204eaab06e70
Author: Florian Dold <florian@dold.me>
AuthorDate: Tue Apr 19 14:43:30 2022 +0200
edx25519: use libsodium, tweak KDF call
---
src/util/crypto_edx25519.c | 198 +++++++++++++++------------------------------
1 file changed, 64 insertions(+), 134 deletions(-)
diff --git a/src/util/crypto_edx25519.c b/src/util/crypto_edx25519.c
index 26b45407e..2a7f75030 100644
--- a/src/util/crypto_edx25519.c
+++ b/src/util/crypto_edx25519.c
@@ -210,53 +210,28 @@ GNUNET_CRYPTO_edx25519_verify_ (
* @param pub public key for deriviation
* @param seed seed for key the deriviation
* @param seedsize the size of the seed
- * @param n The value for the modulus 'n'
* @param[out] phc if not NULL, the output of H() will be written into
* return h_mod_n (allocated by this function)
*/
-static gcry_mpi_t
-derive_h_mod_n (
+static void
+derive_h (
const struct GNUNET_CRYPTO_Edx25519PublicKey *pub,
const void *seed,
size_t seedsize,
- const gcry_mpi_t n,
struct GNUNET_HashCode *phc)
{
static const char *const salt = "edx2559-derivation";
- struct GNUNET_HashCode hc;
- gcry_mpi_t h;
- gcry_mpi_t h_mod_n;
-
- if (NULL == phc)
- phc = &hc;
- GNUNET_CRYPTO_kdf (phc, sizeof(*phc),
- salt, strlen (salt),
+ GNUNET_CRYPTO_kdf (/* output*/
+ phc, sizeof(*phc),
+ /* salt */
pub, sizeof(*pub),
+ /* ikm */
seed, seedsize,
+ /* ctx chunks*/
+ salt, strlen (salt),
NULL, 0);
- /* calculate h_mod_n = h % n */
- GNUNET_CRYPTO_mpi_scan_unsigned (&h,
- (unsigned char *) phc,
- sizeof(*phc));
- h_mod_n = gcry_mpi_new (256);
- gcry_mpi_mod (h_mod_n, h, n);
-
-#ifdef CHECK_RARE_CASES
- /**
- * Note that the following cases would be problematic:
- * 1.) h == 0 mod n
- * 2.) h == 1 mod n
- * 3.) [h] * P == E
- * We assume that the probalities for these cases to occur are neglegible.
- */
- GNUNET_assert (! gcry_mpi_cmp_ui (h_mod_n, 0));
- GNUNET_assert (! gcry_mpi_cmp_ui (h_mod_n, 1));
-#endif
-
- gcry_mpi_release(h);
- return h_mod_n;
}
@@ -270,40 +245,37 @@ GNUNET_CRYPTO_edx25519_private_key_derive (
struct GNUNET_CRYPTO_Edx25519PublicKey pub;
struct GNUNET_HashCode hc;
uint8_t a[32];
- gcry_ctx_t ctx;
- gcry_mpi_t h_mod_n;
- gcry_mpi_t x;
- gcry_mpi_t n;
- gcry_mpi_t a1;
- gcry_mpi_t a2;
- gcry_mpi_t ap; // a'
+ uint8_t eight[32] = { 8 };
+ uint8_t eight_inv[32];
+ uint8_t h[64] = { 0 };
GNUNET_CRYPTO_edx25519_key_get_public (priv, &pub);
- /**
- * Libsodium does not offer an API with arbitrary arithmetic.
- * Hence we have to use libgcrypt here.
- */
- GNUNET_assert (0 == gcry_mpi_ec_new (&ctx, NULL, "Ed25519"));
-
- /**
- * Get our modulo
- */
- n = gcry_mpi_ec_get_mpi ("n", ctx, 1);
- GNUNET_assert (NULL != n);
+ /* Get h mod n */
+ derive_h (&pub,
+ seed,
+ seedsize,
+ &hc);
+ memcpy (h, &hc, 64);
+ crypto_core_ed25519_scalar_reduce (h,
+ h);
+#ifdef CHECK_RARE_CASES
/**
- * Get h mod n
+ * Note that the following cases would be problematic:
+ * 1.) h == 0 mod n
+ * 2.) h == 1 mod n
+ * 3.) [h] * P == E
+ * We assume that the probalities for these cases to occur are neglegible.
*/
- h_mod_n = derive_h_mod_n (&pub,
- seed,
- seedsize,
- n,
- &hc);
+ {
+ char zero[32] = { 0 };
+ char one[32] = { 1 };
- /* Convert priv->a scalar to big endian for libgcrypt */
- for (size_t i = 0; i < 32; i++)
- a[i] = priv->a[31 - i];
+ GNUNET_assert (0 != memcmp (zero, h, 32));
+ GNUNET_assert (0 != memcmp (one, h, 32));
+ }
+#endif
/**
* dc now contains the private scalar "a".
@@ -313,37 +285,29 @@ GNUNET_CRYPTO_edx25519_private_key_derive (
* a2 := h * a1 mod n
* a' := a2 * 8 mod n
*/
- GNUNET_CRYPTO_mpi_scan_unsigned (&x, a, sizeof(a)); // a
- a1 = gcry_mpi_new (256);
- gcry_mpi_t eight = gcry_mpi_set_ui (NULL, 8);
- gcry_mpi_div (a1, NULL, x, eight, 0); // a1 := a / 8
- a2 = gcry_mpi_new (256);
- gcry_mpi_mulm (a2, h_mod_n, a1, n); // a2 := h * a1 mod n
- ap = gcry_mpi_new (256);
- gcry_mpi_mul (ap, a2, eight); // a' := a2 * 8
+
+ GNUNET_assert (0 == crypto_core_ed25519_scalar_invert (eight_inv,
+ eight));
+
+ crypto_core_ed25519_scalar_mul (a, priv->a, eight_inv);
+ crypto_core_ed25519_scalar_mul (a, a, h);
+ crypto_core_ed25519_scalar_mul (a, a, eight);
#ifdef CHECK_RARE_CASES
/* The likelihood for a' == 0 or a' == 1 is neglegible */
- GNUNET_assert (! gcry_mpi_cmp_ui (ap, 0));
- GNUNET_assert (! gcry_mpi_cmp_ui (ap, 1));
-#endif
+ {
+ char zero[32] = { 0 };
+ char one[32] = { 1 };
- gcry_mpi_release (h_mod_n);
- gcry_mpi_release (eight);
- gcry_mpi_release (x);
- gcry_mpi_release (n);
- gcry_mpi_release (a1);
- gcry_mpi_release (a2);
- gcry_ctx_release (ctx);
- GNUNET_CRYPTO_mpi_print_unsigned (a, sizeof(a), ap);
- gcry_mpi_release (ap);
+ GNUNET_assert (0 != memcmp (zero, a, 32));
+ GNUNET_assert (0 != memcmp (one, a, 32));
+ }
+#endif
- /**
- * We hash the derived "h" parameter with the other half of the expanded
+ /* We hash the derived "h" parameter with the other half of the expanded
* private key (that is: priv->b). This ensures that for signature
* generation, the "R" is derived from the same derivation path as "h" and is
- * not reused.
- */
+ * not reused. */
{
crypto_hash_sha256_state hs;
crypto_hash_sha256_init (&hs);
@@ -352,9 +316,8 @@ GNUNET_CRYPTO_edx25519_private_key_derive (
crypto_hash_sha256_final (&hs, result->b);
}
- /* Convert to little endian for libsodium */
for (size_t i = 0; i < 32; i++)
- result->a[i] = a[31 - i];
+ result->a[i] = a[i];
sodium_memzero (a, sizeof(a));
}
@@ -367,52 +330,19 @@ GNUNET_CRYPTO_edx25519_public_key_derive (
size_t seedsize,
struct GNUNET_CRYPTO_Edx25519PublicKey *result)
{
- gcry_ctx_t ctx;
- gcry_mpi_t q_y;
- gcry_mpi_t n;
- gcry_mpi_t h_mod_n;
- gcry_mpi_point_t q;
- gcry_mpi_point_t v;
-
- GNUNET_assert (0 == gcry_mpi_ec_new (&ctx, NULL, "Ed25519"));
-
- /* obtain point 'q' from original public key. The provided 'q' is
- compressed thus we first store it in the context and then get it
- back as a (decompresssed) point. */
- q_y = gcry_mpi_set_opaque_copy (NULL,
- pub->q_y,
- 8 * sizeof(pub->q_y));
- GNUNET_assert (NULL != q_y);
- GNUNET_assert (0 == gcry_mpi_ec_set_mpi ("q", q_y, ctx));
- gcry_mpi_release (q_y);
- q = gcry_mpi_ec_get_point ("q", ctx, 0);
- GNUNET_assert (q);
-
- /**
- * Get h mod n
- */
- n = gcry_mpi_ec_get_mpi ("n", ctx, 1);
- GNUNET_assert (NULL != n);
- GNUNET_assert (NULL != pub);
- h_mod_n = derive_h_mod_n (pub,
- seed,
- seedsize,
- n,
- NULL /* We don't need hc here */);
-
- /* calculate v = h_mod_n * q */
- v = gcry_mpi_point_new (0);
- gcry_mpi_ec_mul (v, h_mod_n, q, ctx);
- gcry_mpi_release (h_mod_n);
- gcry_mpi_release (n);
- gcry_mpi_point_release (q);
-
- /* convert point 'v' to public key that we return */
- GNUNET_assert (0 == gcry_mpi_ec_set_point ("q", v, ctx));
- gcry_mpi_point_release (v);
- q_y = gcry_mpi_ec_get_mpi ("q@eddsa", ctx, 0);
- GNUNET_assert (q_y);
- GNUNET_CRYPTO_mpi_print_unsigned (result->q_y, sizeof(result->q_y), q_y);
- gcry_mpi_release (q_y);
- gcry_ctx_release (ctx);
+ struct GNUNET_HashCode hc;
+ uint8_t h[64] = { 0 };
+
+ derive_h (pub,
+ seed,
+ seedsize,
+ &hc);
+ memcpy (h,
+ &hc,
+ 64);
+ crypto_core_ed25519_scalar_reduce (h,
+ h);
+ GNUNET_assert (0 == crypto_scalarmult_ed25519_noclamp (result->q_y,
+ h,
+ pub->q_y));
}
--
To stop receiving notification emails like this one, please contact
gnunet@gnunet.org.
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [gnunet] branch master updated: edx25519: use libsodium, tweak KDF call,
gnunet <=