summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPedram Fardzadeh <p.fardzadeh@protonmail.com>2024-03-04 01:26:31 +0100
committerPedram Fardzadeh <p.fardzadeh@protonmail.com>2024-03-04 01:26:31 +0100
commit34759bf4db09b26efc7119015bbe7f568e3e32f4 (patch)
tree24ae2fd1f2e2c0fdc8dbe8c014b34ed44cf203ce
parent85c0d81ca72dd02545f07ebdafe06457932fc334 (diff)
elligator: kem encaps and decapsdev/pedram/elligator
-rw-r--r--src/include/gnunet_crypto_lib.h36
-rw-r--r--src/lib/util/crypto_elligator.c33
-rw-r--r--src/lib/util/test_crypto_elligator.c34
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,