diff options
author | Pedram Fardzadeh <p.fardzadeh@protonmail.com> | 2024-03-04 01:26:31 +0100 |
---|---|---|
committer | Pedram Fardzadeh <p.fardzadeh@protonmail.com> | 2024-03-04 01:26:31 +0100 |
commit | 34759bf4db09b26efc7119015bbe7f568e3e32f4 (patch) | |
tree | 24ae2fd1f2e2c0fdc8dbe8c014b34ed44cf203ce | |
parent | 85c0d81ca72dd02545f07ebdafe06457932fc334 (diff) |
elligator: kem encaps and decapsdev/pedram/elligator
-rw-r--r-- | src/include/gnunet_crypto_lib.h | 36 | ||||
-rw-r--r-- | src/lib/util/crypto_elligator.c | 33 | ||||
-rw-r--r-- | src/lib/util/test_crypto_elligator.c | 34 |
3 files changed, 103 insertions, 0 deletions
diff --git a/src/include/gnunet_crypto_lib.h b/src/include/gnunet_crypto_lib.h index 7b7d559cc..4af95af0f 100644 --- a/src/include/gnunet_crypto_lib.h +++ b/src/include/gnunet_crypto_lib.h @@ -2747,6 +2747,42 @@ GNUNET_CRYPTO_ecdhe_elligator_key_create ( struct GNUNET_CRYPTO_ElligatorRepresentative *repr, struct GNUNET_CRYPTO_EcdhePrivateKey *pk); +/** + * @ingroup crypto + * Carries out ecdh encapsulation with given public key and a freshly created ephemeral key pair. Ephemeral public key is given as a representative. + * + * Following the terminology in https://eprint.iacr.org/2021/509.pdf + * @param pub receivers edwards curve public key (X) + * @param r representative of ephemeral public key A to use for the ECDH (direct_map(r)=A=aG) + * @param key_material where to write the key material H(aX)=H(x(aG)) + * @return #GNUNET_SYSERR on error, #GNUNET_OK on success + */ +enum GNUNET_GenericReturnValue +GNUNET_CRYPTO_eddsa_elligator_kem_encaps (const struct + GNUNET_CRYPTO_EddsaPublicKey *pub, + struct + GNUNET_CRYPTO_ElligatorRepresentative + *r, + struct GNUNET_HashCode *key_material); + +/** + * @ingroup crypto + * Carries out ecdh decapsulation with given private key and the representative of received public key. + * + * Following the terminology in https://eprint.iacr.org/2021/509.pdf + * @param priv own private key (x) + * @param r received representative (direct_map(r)=A=aG) + * @param key_material where to write the key material H(xA)=H(a(xG)) + * @return #GNUNET_SYSERR on error, #GNUNET_OK on success + */ +enum GNUNET_GenericReturnValue +GNUNET_CRYPTO_eddsa_elligator_kem_decaps (const struct + GNUNET_CRYPTO_EddsaPrivateKey *priv, + struct + GNUNET_CRYPTO_ElligatorRepresentative + *r, + struct GNUNET_HashCode *key_material); + /** * Output the given MPI value to the given buffer in network diff --git a/src/lib/util/crypto_elligator.c b/src/lib/util/crypto_elligator.c index 7ff37be46..d7f4bb1dd 100644 --- a/src/lib/util/crypto_elligator.c +++ b/src/lib/util/crypto_elligator.c @@ -620,3 +620,36 @@ GNUNET_CRYPTO_ecdhe_elligator_key_create ( repr->r[31] |= 64; } } + + +enum GNUNET_GenericReturnValue +GNUNET_CRYPTO_eddsa_elligator_kem_encaps (const struct + GNUNET_CRYPTO_EddsaPublicKey *pub, + struct + GNUNET_CRYPTO_ElligatorRepresentative + *r, + struct GNUNET_HashCode *key_material) +{ + struct GNUNET_CRYPTO_EcdhePrivateKey sk_eph; + struct GNUNET_CRYPTO_EcdhePublicKey pub_eph; + + GNUNET_CRYPTO_ecdhe_elligator_key_create (r, &sk_eph); + // TODO: probably makes more sense if key_create outputs ecdhe pub instead of repr because ecdhe pub is needed for ecdh on senders side. + GNUNET_CRYPTO_ecdhe_elligator_decoding (&pub_eph, NULL, r); + + return GNUNET_CRYPTO_ecdh_eddsa (&sk_eph, pub, key_material); +} + + +enum GNUNET_GenericReturnValue +GNUNET_CRYPTO_eddsa_elligator_kem_decaps (const struct + GNUNET_CRYPTO_EddsaPrivateKey *priv, + struct + GNUNET_CRYPTO_ElligatorRepresentative + *r, + struct GNUNET_HashCode *key_material) +{ + struct GNUNET_CRYPTO_EcdhePublicKey pub; + GNUNET_CRYPTO_ecdhe_elligator_decoding (&pub, NULL, r); + return GNUNET_CRYPTO_eddsa_ecdh (priv, &pub, key_material); +}
\ No newline at end of file diff --git a/src/lib/util/test_crypto_elligator.c b/src/lib/util/test_crypto_elligator.c index 463cb0a0c..c42e1de3a 100644 --- a/src/lib/util/test_crypto_elligator.c +++ b/src/lib/util/test_crypto_elligator.c @@ -223,6 +223,34 @@ testTimeDecoding (void) } +static int +elligatorKEM () +{ + struct GNUNET_CRYPTO_EddsaPrivateKey pk; + struct GNUNET_CRYPTO_EddsaPublicKey pub; + GNUNET_CRYPTO_eddsa_key_create (&pk); + GNUNET_CRYPTO_eddsa_key_get_public (&pk,&pub); + + struct GNUNET_CRYPTO_ElligatorRepresentative r; + + // Sender side + struct GNUNET_HashCode key_material_encaps; + GNUNET_CRYPTO_eddsa_elligator_kem_encaps (&pub, &r, &key_material_encaps); + + // Receiving side + struct GNUNET_HashCode key_material_decaps; + GNUNET_CRYPTO_eddsa_elligator_kem_decaps (&pk,&r,&key_material_decaps); + + if (memcmp (&(key_material_encaps.bits),&(key_material_decaps.bits), + sizeof(key_material_encaps.bits)) != 0) + { + return GNUNET_SYSERR; + } + + return GNUNET_OK; +} + + /* *More tests to implement: * Adding more test vectors from different sources for inverse and direct map @@ -268,6 +296,12 @@ main (int argc, char *argv[]) failure_count++; } + if (GNUNET_OK != elligatorKEM ()) + { + printf ("Elligator KEM failed!"); + failure_count++; + } + if (0 != failure_count) { fprintf (stderr, |