aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPedram Fardzadeh <p.fardzadeh@protonmail.com>2024-03-04 22:25:40 +0100
committerPedram Fardzadeh <p.fardzadeh@protonmail.com>2024-03-04 22:25:40 +0100
commit73a89e4f15b283c89350c3e2cd854e4cc95be30a (patch)
tree78f8b5c45acfccff223abcf01075728b421e6fbe
parent34759bf4db09b26efc7119015bbe7f568e3e32f4 (diff)
downloadgnunet-dev/pedram/elligator.tar.gz
gnunet-dev/pedram/elligator.zip
udp communicator: ECDH with elligatordev/pedram/elligator
-rw-r--r--src/include/gnunet_crypto_lib.h12
-rw-r--r--src/lib/util/crypto_elligator.c21
-rw-r--r--src/lib/util/test_crypto_elligator.c16
-rw-r--r--src/service/transport/gnunet-communicator-udp.c71
4 files changed, 89 insertions, 31 deletions
diff --git a/src/include/gnunet_crypto_lib.h b/src/include/gnunet_crypto_lib.h
index 4af95af0f..a19e1e519 100644
--- a/src/include/gnunet_crypto_lib.h
+++ b/src/include/gnunet_crypto_lib.h
@@ -2692,7 +2692,7 @@ bool
2692GNUNET_CRYPTO_ecdhe_elligator_decoding (struct 2692GNUNET_CRYPTO_ecdhe_elligator_decoding (struct
2693 GNUNET_CRYPTO_EcdhePublicKey *point, 2693 GNUNET_CRYPTO_EcdhePublicKey *point,
2694 bool *high_y, 2694 bool *high_y,
2695 struct 2695 const struct
2696 GNUNET_CRYPTO_ElligatorRepresentative * 2696 GNUNET_CRYPTO_ElligatorRepresentative *
2697 seriliazed_representative); 2697 seriliazed_representative);
2698 2698
@@ -2749,10 +2749,10 @@ GNUNET_CRYPTO_ecdhe_elligator_key_create (
2749 2749
2750/** 2750/**
2751 * @ingroup crypto 2751 * @ingroup crypto
2752 * Carries out ecdh encapsulation with given public key and a freshly created ephemeral key pair. Ephemeral public key is given as a representative. 2752 * Carries out ecdh encapsulation with given public key and the private key from a freshly created ephemeral key pair.
2753 * 2753 *
2754 * Following the terminology in https://eprint.iacr.org/2021/509.pdf 2754 * Following the terminology in https://eprint.iacr.org/2021/509.pdf
2755 * @param pub receivers edwards curve public key (X) 2755 * @param pub given edwards curve public key (X)
2756 * @param r representative of ephemeral public key A to use for the ECDH (direct_map(r)=A=aG) 2756 * @param r representative of ephemeral public key A to use for the ECDH (direct_map(r)=A=aG)
2757 * @param key_material where to write the key material H(aX)=H(x(aG)) 2757 * @param key_material where to write the key material H(aX)=H(x(aG))
2758 * @return #GNUNET_SYSERR on error, #GNUNET_OK on success 2758 * @return #GNUNET_SYSERR on error, #GNUNET_OK on success
@@ -2767,18 +2767,18 @@ GNUNET_CRYPTO_eddsa_elligator_kem_encaps (const struct
2767 2767
2768/** 2768/**
2769 * @ingroup crypto 2769 * @ingroup crypto
2770 * Carries out ecdh decapsulation with given private key and the representative of received public key. 2770 * Carries out ecdh decapsulation with own private key and the representative of the received public key.
2771 * 2771 *
2772 * Following the terminology in https://eprint.iacr.org/2021/509.pdf 2772 * Following the terminology in https://eprint.iacr.org/2021/509.pdf
2773 * @param priv own private key (x) 2773 * @param priv own private key (x)
2774 * @param r received representative (direct_map(r)=A=aG) 2774 * @param r received representative r, from which we can obtain the public key A (direct_map(r)=A=aG)
2775 * @param key_material where to write the key material H(xA)=H(a(xG)) 2775 * @param key_material where to write the key material H(xA)=H(a(xG))
2776 * @return #GNUNET_SYSERR on error, #GNUNET_OK on success 2776 * @return #GNUNET_SYSERR on error, #GNUNET_OK on success
2777 */ 2777 */
2778enum GNUNET_GenericReturnValue 2778enum GNUNET_GenericReturnValue
2779GNUNET_CRYPTO_eddsa_elligator_kem_decaps (const struct 2779GNUNET_CRYPTO_eddsa_elligator_kem_decaps (const struct
2780 GNUNET_CRYPTO_EddsaPrivateKey *priv, 2780 GNUNET_CRYPTO_EddsaPrivateKey *priv,
2781 struct 2781 const struct
2782 GNUNET_CRYPTO_ElligatorRepresentative 2782 GNUNET_CRYPTO_ElligatorRepresentative
2783 *r, 2783 *r,
2784 struct GNUNET_HashCode *key_material); 2784 struct GNUNET_HashCode *key_material);
diff --git a/src/lib/util/crypto_elligator.c b/src/lib/util/crypto_elligator.c
index d7f4bb1dd..5ceebedbe 100644
--- a/src/lib/util/crypto_elligator.c
+++ b/src/lib/util/crypto_elligator.c
@@ -447,11 +447,11 @@ bool
447GNUNET_CRYPTO_ecdhe_elligator_decoding (struct 447GNUNET_CRYPTO_ecdhe_elligator_decoding (struct
448 GNUNET_CRYPTO_EcdhePublicKey *point, 448 GNUNET_CRYPTO_EcdhePublicKey *point,
449 bool *high_y, 449 bool *high_y,
450 struct 450 const struct
451 GNUNET_CRYPTO_ElligatorRepresentative * 451 GNUNET_CRYPTO_ElligatorRepresentative *
452 representative) 452 representative)
453{ 453{
454 // if sign of direct map transformation not needed whether throw it away 454 // if sign of direct map transformation not needed throw it away
455 bool high_y_local; 455 bool high_y_local;
456 bool *high_y_ptr; 456 bool *high_y_ptr;
457 if (NULL == high_y) 457 if (NULL == high_y)
@@ -459,11 +459,13 @@ GNUNET_CRYPTO_ecdhe_elligator_decoding (struct
459 else 459 else
460 high_y_ptr = high_y; 460 high_y_ptr = high_y;
461 461
462 representative->r[31] &= 63; 462 struct GNUNET_CRYPTO_ElligatorRepresentative r_tmp;
463 memcpy (&r_tmp, &representative->r, sizeof(r_tmp.r));
464 r_tmp.r[31] &= 63;
463 // GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,"Print high_y\n"); 465 // GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,"Print high_y\n");
464 return GNUNET_CRYPTO_ecdhe_elligator_direct_map ((uint8_t *) point->q_y, 466 return GNUNET_CRYPTO_ecdhe_elligator_direct_map ((uint8_t *) point->q_y,
465 high_y_ptr, 467 high_y_ptr,
466 (uint8_t *) representative->r); 468 (uint8_t *) r_tmp.r);
467} 469}
468 470
469 471
@@ -630,21 +632,18 @@ GNUNET_CRYPTO_eddsa_elligator_kem_encaps (const struct
630 *r, 632 *r,
631 struct GNUNET_HashCode *key_material) 633 struct GNUNET_HashCode *key_material)
632{ 634{
633 struct GNUNET_CRYPTO_EcdhePrivateKey sk_eph; 635 struct GNUNET_CRYPTO_EcdhePrivateKey sk;
634 struct GNUNET_CRYPTO_EcdhePublicKey pub_eph;
635 636
636 GNUNET_CRYPTO_ecdhe_elligator_key_create (r, &sk_eph); 637 GNUNET_CRYPTO_ecdhe_elligator_key_create (r, &sk);
637 // TODO: probably makes more sense if key_create outputs ecdhe pub instead of repr because ecdhe pub is needed for ecdh on senders side.
638 GNUNET_CRYPTO_ecdhe_elligator_decoding (&pub_eph, NULL, r);
639 638
640 return GNUNET_CRYPTO_ecdh_eddsa (&sk_eph, pub, key_material); 639 return GNUNET_CRYPTO_ecdh_eddsa (&sk, pub, key_material);
641} 640}
642 641
643 642
644enum GNUNET_GenericReturnValue 643enum GNUNET_GenericReturnValue
645GNUNET_CRYPTO_eddsa_elligator_kem_decaps (const struct 644GNUNET_CRYPTO_eddsa_elligator_kem_decaps (const struct
646 GNUNET_CRYPTO_EddsaPrivateKey *priv, 645 GNUNET_CRYPTO_EddsaPrivateKey *priv,
647 struct 646 const struct
648 GNUNET_CRYPTO_ElligatorRepresentative 647 GNUNET_CRYPTO_ElligatorRepresentative
649 *r, 648 *r,
650 struct GNUNET_HashCode *key_material) 649 struct GNUNET_HashCode *key_material)
diff --git a/src/lib/util/test_crypto_elligator.c b/src/lib/util/test_crypto_elligator.c
index c42e1de3a..bd357a259 100644
--- a/src/lib/util/test_crypto_elligator.c
+++ b/src/lib/util/test_crypto_elligator.c
@@ -226,20 +226,22 @@ testTimeDecoding (void)
226static int 226static int
227elligatorKEM () 227elligatorKEM ()
228{ 228{
229 struct GNUNET_CRYPTO_EddsaPrivateKey pk; 229 struct GNUNET_CRYPTO_EddsaPrivateKey pk_receiver;
230 struct GNUNET_CRYPTO_EddsaPublicKey pub; 230 struct GNUNET_CRYPTO_EddsaPublicKey pub_receiver;
231 GNUNET_CRYPTO_eddsa_key_create (&pk); 231 GNUNET_CRYPTO_eddsa_key_create (&pk_receiver);
232 GNUNET_CRYPTO_eddsa_key_get_public (&pk,&pub); 232 GNUNET_CRYPTO_eddsa_key_get_public (&pk_receiver, &pub_receiver);
233 233
234 struct GNUNET_CRYPTO_ElligatorRepresentative r; 234 struct GNUNET_CRYPTO_ElligatorRepresentative r_sender;
235 235
236 // Sender side 236 // Sender side
237 struct GNUNET_HashCode key_material_encaps; 237 struct GNUNET_HashCode key_material_encaps;
238 GNUNET_CRYPTO_eddsa_elligator_kem_encaps (&pub, &r, &key_material_encaps); 238 GNUNET_CRYPTO_eddsa_elligator_kem_encaps (&pub_receiver, &r_sender,
239 &key_material_encaps);
239 240
240 // Receiving side 241 // Receiving side
241 struct GNUNET_HashCode key_material_decaps; 242 struct GNUNET_HashCode key_material_decaps;
242 GNUNET_CRYPTO_eddsa_elligator_kem_decaps (&pk,&r,&key_material_decaps); 243 GNUNET_CRYPTO_eddsa_elligator_kem_decaps (&pk_receiver, &r_sender,
244 &key_material_decaps);
243 245
244 if (memcmp (&(key_material_encaps.bits),&(key_material_decaps.bits), 246 if (memcmp (&(key_material_encaps.bits),&(key_material_decaps.bits),
245 sizeof(key_material_encaps.bits)) != 0) 247 sizeof(key_material_encaps.bits)) != 0)
diff --git a/src/service/transport/gnunet-communicator-udp.c b/src/service/transport/gnunet-communicator-udp.c
index 29beb4e37..48319461e 100644
--- a/src/service/transport/gnunet-communicator-udp.c
+++ b/src/service/transport/gnunet-communicator-udp.c
@@ -198,9 +198,9 @@ struct UdpHandshakeSignature
198struct InitialKX 198struct InitialKX
199{ 199{
200 /** 200 /**
201 * Ephemeral key for KX. 201 * Representative of ephemeral key for KX.
202 */ 202 */
203 struct GNUNET_CRYPTO_EcdhePublicKey ephemeral; 203 struct GNUNET_CRYPTO_ElligatorRepresentative representative;
204 204
205 /** 205 /**
206 * HMAC for the following encrypted message, using GCM. HMAC uses 206 * HMAC for the following encrypted message, using GCM. HMAC uses
@@ -1330,6 +1330,27 @@ setup_shared_secret_dec (const struct GNUNET_CRYPTO_EcdhePublicKey *ephemeral)
1330 1330
1331 1331
1332/** 1332/**
1333 * Setup shared secret for decryption for initial handshake.
1334 *
1335 * @param representative of ephemeral key we received from the other peer
1336 * @return new shared secret
1337 */
1338static struct SharedSecret *
1339setup_initial_shared_secret_dec (const struct
1340 GNUNET_CRYPTO_ElligatorRepresentative *
1341 representative)
1342{
1343 struct SharedSecret *ss;
1344
1345 ss = GNUNET_new (struct SharedSecret);
1346 GNUNET_CRYPTO_eddsa_elligator_kem_decaps (my_private_key, representative,
1347 &ss->master);
1348 calculate_cmac (ss);
1349 return ss;
1350}
1351
1352
1353/**
1333 * Setup new shared secret for encryption using KEM. 1354 * Setup new shared secret for encryption using KEM.
1334 * 1355 *
1335 * @param[out] ephemeral ephemeral key to be sent to other peer (encapsulated key from KEM) 1356 * @param[out] ephemeral ephemeral key to be sent to other peer (encapsulated key from KEM)
@@ -1356,6 +1377,35 @@ setup_shared_secret_ephemeral (struct GNUNET_CRYPTO_EcdhePublicKey *ephemeral,
1356 1377
1357 1378
1358/** 1379/**
1380 * Setup new shared secret for encryption using KEM for initial handshake.
1381 *
1382 * @param[out] representative of ephemeral key to be sent to other peer (encapsulated key from KEM)
1383 * @param[in,out] receiver queue to initialize encryption key for
1384 * @return new shared secret
1385 */
1386static struct SharedSecret *
1387setup_initial_shared_secret_ephemeral (struct
1388 GNUNET_CRYPTO_ElligatorRepresentative *
1389 representative,
1390 struct ReceiverAddress *receiver)
1391{
1392 struct SharedSecret *ss;
1393 struct GNUNET_HashCode k;
1394
1395 GNUNET_CRYPTO_eddsa_elligator_kem_encaps (&receiver->target.public_key,
1396 representative, &k);
1397 ss = GNUNET_new (struct SharedSecret);
1398 memcpy (&ss->master, &k, sizeof (k));
1399 calculate_cmac (ss);
1400 ss->receiver = receiver;
1401 GNUNET_CONTAINER_DLL_insert (receiver->ss_head, receiver->ss_tail, ss);
1402 receiver->num_secrets++;
1403 GNUNET_STATISTICS_update (stats, "# Secrets active", 1, GNUNET_NO);
1404 return ss;
1405}
1406
1407
1408/**
1359 * Setup the MQ for the @a receiver. If a queue exists, 1409 * Setup the MQ for the @a receiver. If a queue exists,
1360 * the existing one is destroyed. Then the MTU is 1410 * the existing one is destroyed. Then the MTU is
1361 * recalculated and a fresh queue is initialized. 1411 * recalculated and a fresh queue is initialized.
@@ -2072,7 +2122,7 @@ sock_read (void *cls)
2072 struct SenderAddress *sender; 2122 struct SenderAddress *sender;
2073 2123
2074 kx = (const struct InitialKX *) buf; 2124 kx = (const struct InitialKX *) buf;
2075 ss = setup_shared_secret_dec (&kx->ephemeral); 2125 ss = setup_initial_shared_secret_dec (&kx->representative);
2076 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 2126 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2077 "Before DEC\n"); 2127 "Before DEC\n");
2078 2128
@@ -2097,7 +2147,11 @@ sock_read (void *cls)
2097 "Before VERIFY\n"); 2147 "Before VERIFY\n");
2098 2148
2099 uc = (const struct UDPConfirmation *) pbuf; 2149 uc = (const struct UDPConfirmation *) pbuf;
2100 if (GNUNET_OK != verify_confirmation (&kx->ephemeral, uc)) 2150
2151 struct GNUNET_CRYPTO_EcdhePublicKey pub_ephemeral;
2152 GNUNET_CRYPTO_ecdhe_elligator_decoding (&pub_ephemeral, NULL,
2153 &kx->representative);
2154 if (GNUNET_OK != verify_confirmation (&pub_ephemeral, uc)) // TODO: need ephemeral instead of representative
2101 { 2155 {
2102 GNUNET_break_op (0); 2156 GNUNET_break_op (0);
2103 GNUNET_free (ss); 2157 GNUNET_free (ss);
@@ -2330,8 +2384,10 @@ send_msg_with_kx (const struct GNUNET_MessageHeader *msg, struct
2330 reschedule_receiver_timeout (receiver); 2384 reschedule_receiver_timeout (receiver);
2331 2385
2332 /* setup key material */ 2386 /* setup key material */
2333 2387 struct GNUNET_CRYPTO_ElligatorRepresentative repr;
2334 ss = setup_shared_secret_ephemeral (&uhs.ephemeral, receiver); 2388 ss = setup_initial_shared_secret_ephemeral (&repr, receiver);
2389 GNUNET_CRYPTO_ecdhe_elligator_decoding (&uhs.ephemeral, NULL,
2390 &repr);
2335 2391
2336 if (receiver->num_secrets > MAX_SECRETS) 2392 if (receiver->num_secrets > MAX_SECRETS)
2337 { 2393 {
@@ -2371,7 +2427,7 @@ send_msg_with_kx (const struct GNUNET_MessageHeader *msg, struct
2371 dpos += msize; 2427 dpos += msize;
2372 do_pad (out_cipher, &dgram[dpos], sizeof(dgram) - dpos); 2428 do_pad (out_cipher, &dgram[dpos], sizeof(dgram) - dpos);
2373 /* Datagram starts with kx */ 2429 /* Datagram starts with kx */
2374 kx.ephemeral = uhs.ephemeral; 2430 kx.representative = repr;
2375 GNUNET_assert ( 2431 GNUNET_assert (
2376 0 == gcry_cipher_gettag (out_cipher, kx.gcm_tag, sizeof(kx.gcm_tag))); 2432 0 == gcry_cipher_gettag (out_cipher, kx.gcm_tag, sizeof(kx.gcm_tag)));
2377 gcry_cipher_close (out_cipher); 2433 gcry_cipher_close (out_cipher);
@@ -3466,6 +3522,7 @@ run (void *cls,
3466int 3522int
3467main (int argc, char *const *argv) 3523main (int argc, char *const *argv)
3468{ 3524{
3525 GNUNET_CRYPTO_ecdhe_elligator_initialize ();
3469 static const struct GNUNET_GETOPT_CommandLineOption options[] = { 3526 static const struct GNUNET_GETOPT_CommandLineOption options[] = {
3470 GNUNET_GETOPT_OPTION_END 3527 GNUNET_GETOPT_OPTION_END
3471 }; 3528 };