diff options
author | Pedram Fardzadeh <p.fardzadeh@protonmail.com> | 2024-03-04 22:25:40 +0100 |
---|---|---|
committer | Pedram Fardzadeh <p.fardzadeh@protonmail.com> | 2024-03-04 22:25:40 +0100 |
commit | 73a89e4f15b283c89350c3e2cd854e4cc95be30a (patch) | |
tree | 78f8b5c45acfccff223abcf01075728b421e6fbe | |
parent | 34759bf4db09b26efc7119015bbe7f568e3e32f4 (diff) | |
download | gnunet-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.h | 12 | ||||
-rw-r--r-- | src/lib/util/crypto_elligator.c | 21 | ||||
-rw-r--r-- | src/lib/util/test_crypto_elligator.c | 16 | ||||
-rw-r--r-- | src/service/transport/gnunet-communicator-udp.c | 71 |
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 | |||
2692 | GNUNET_CRYPTO_ecdhe_elligator_decoding (struct | 2692 | GNUNET_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 | */ |
2778 | enum GNUNET_GenericReturnValue | 2778 | enum GNUNET_GenericReturnValue |
2779 | GNUNET_CRYPTO_eddsa_elligator_kem_decaps (const struct | 2779 | GNUNET_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 | |||
447 | GNUNET_CRYPTO_ecdhe_elligator_decoding (struct | 447 | GNUNET_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 | ||
644 | enum GNUNET_GenericReturnValue | 643 | enum GNUNET_GenericReturnValue |
645 | GNUNET_CRYPTO_eddsa_elligator_kem_decaps (const struct | 644 | GNUNET_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) | |||
226 | static int | 226 | static int |
227 | elligatorKEM () | 227 | elligatorKEM () |
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 | |||
198 | struct InitialKX | 198 | struct 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 | */ | ||
1338 | static struct SharedSecret * | ||
1339 | setup_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 | */ | ||
1386 | static struct SharedSecret * | ||
1387 | setup_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, | |||
3466 | int | 3522 | int |
3467 | main (int argc, char *const *argv) | 3523 | main (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 | }; |