aboutsummaryrefslogtreecommitdiff
path: root/src/scalarproduct
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2021-04-18 21:11:08 +0200
committerChristian Grothoff <christian@grothoff.org>2021-04-18 21:11:08 +0200
commit75cfa6370bc902765c26b50bb858c9a5bc1e8e48 (patch)
treefdadaf6e2736ad79c9f79576bf9a056ea9d0a6f5 /src/scalarproduct
parent5ec7af75ea9f8ed86cf28a8efed9a917345d1681 (diff)
downloadgnunet-75cfa6370bc902765c26b50bb858c9a5bc1e8e48.tar.gz
gnunet-75cfa6370bc902765c26b50bb858c9a5bc1e8e48.zip
SCALARPRODUCT: migrating logic from libgcrypt to libsodium (#6818).
Diffstat (limited to 'src/scalarproduct')
-rw-r--r--src/scalarproduct/Makefile.am4
-rw-r--r--src/scalarproduct/gnunet-service-scalarproduct-ecc_alice.c297
-rw-r--r--src/scalarproduct/gnunet-service-scalarproduct-ecc_bob.c131
-rwxr-xr-xsrc/scalarproduct/perf_scalarproduct.sh19
-rw-r--r--src/scalarproduct/scalarproduct_api.c50
-rw-r--r--src/scalarproduct/test_ecc_scalarproduct.c211
-rwxr-xr-xsrc/scalarproduct/test_scalarproduct_negative.sh3
7 files changed, 365 insertions, 350 deletions
diff --git a/src/scalarproduct/Makefile.am b/src/scalarproduct/Makefile.am
index f3448725a..cf05e8377 100644
--- a/src/scalarproduct/Makefile.am
+++ b/src/scalarproduct/Makefile.am
@@ -63,6 +63,7 @@ gnunet_service_scalarproduct_ecc_alice_LDADD = \
63 $(top_builddir)/src/cadet/libgnunetcadet.la \ 63 $(top_builddir)/src/cadet/libgnunetcadet.la \
64 $(top_builddir)/src/seti/libgnunetseti.la \ 64 $(top_builddir)/src/seti/libgnunetseti.la \
65 $(LIBGCRYPT_LIBS) \ 65 $(LIBGCRYPT_LIBS) \
66 -lsodium \
66 -lgcrypt \ 67 -lgcrypt \
67 $(GN_LIBINTL) 68 $(GN_LIBINTL)
68 69
@@ -74,6 +75,7 @@ gnunet_service_scalarproduct_ecc_bob_LDADD = \
74 $(top_builddir)/src/cadet/libgnunetcadet.la \ 75 $(top_builddir)/src/cadet/libgnunetcadet.la \
75 $(top_builddir)/src/seti/libgnunetseti.la \ 76 $(top_builddir)/src/seti/libgnunetseti.la \
76 $(LIBGCRYPT_LIBS) \ 77 $(LIBGCRYPT_LIBS) \
78 -lsodium \
77 -lgcrypt \ 79 -lgcrypt \
78 $(GN_LIBINTL) 80 $(GN_LIBINTL)
79 81
@@ -111,4 +113,4 @@ test_ecc_scalarproduct_SOURCES = \
111 test_ecc_scalarproduct.c 113 test_ecc_scalarproduct.c
112test_ecc_scalarproduct_LDADD = \ 114test_ecc_scalarproduct_LDADD = \
113 $(top_builddir)/src/util/libgnunetutil.la \ 115 $(top_builddir)/src/util/libgnunetutil.la \
114 -lgcrypt 116 -lsodium
diff --git a/src/scalarproduct/gnunet-service-scalarproduct-ecc_alice.c b/src/scalarproduct/gnunet-service-scalarproduct-ecc_alice.c
index 447451aef..e33d589be 100644
--- a/src/scalarproduct/gnunet-service-scalarproduct-ecc_alice.c
+++ b/src/scalarproduct/gnunet-service-scalarproduct-ecc_alice.c
@@ -1,6 +1,6 @@
1/* 1/*
2 This file is part of GNUnet. 2 This file is part of GNUnet.
3 Copyright (C) 2013-2017 GNUnet e.V. 3 Copyright (C) 2013-2017, 2021 GNUnet e.V.
4 4
5 GNUnet is free software: you can redistribute it and/or modify it 5 GNUnet is free software: you can redistribute it and/or modify it
6 under the terms of the GNU Affero General Public License as published 6 under the terms of the GNU Affero General Public License as published
@@ -69,7 +69,7 @@ struct MpiElement
69 /** 69 /**
70 * a_i value, not disclosed to Bob. 70 * a_i value, not disclosed to Bob.
71 */ 71 */
72 gcry_mpi_t value; 72 int64_t value;
73}; 73};
74 74
75 75
@@ -138,9 +138,9 @@ struct AliceServiceSession
138 struct MpiElement *sorted_elements; 138 struct MpiElement *sorted_elements;
139 139
140 /** 140 /**
141 * The computed scalar 141 * The computed scalar product. INT_MAX if the computation failed.
142 */ 142 */
143 gcry_mpi_t product; 143 int product;
144 144
145 /** 145 /**
146 * How many elements we were supplied with from the client (total 146 * How many elements we were supplied with from the client (total
@@ -190,12 +190,12 @@ static struct GNUNET_CRYPTO_EccDlogContext *edc;
190/** 190/**
191 * Alice's private key ('a'). 191 * Alice's private key ('a').
192 */ 192 */
193static gcry_mpi_t my_privkey; 193static struct GNUNET_CRYPTO_EccScalar my_privkey;
194 194
195/** 195/**
196 * Inverse of Alice's private key ('a_inv'). 196 * Inverse of Alice's private key ('a_inv').
197 */ 197 */
198static gcry_mpi_t my_privkey_inv; 198static struct GNUNET_CRYPTO_EccScalar my_privkey_inv;
199 199
200/** 200/**
201 * Handle to the CADET service. 201 * Handle to the CADET service.
@@ -212,7 +212,9 @@ static struct GNUNET_CADET_Handle *my_cadet;
212 * @return #GNUNET_OK (continue to iterate) 212 * @return #GNUNET_OK (continue to iterate)
213 */ 213 */
214static int 214static int
215free_element_cb (void *cls, const struct GNUNET_HashCode *key, void *value) 215free_element_cb (void *cls,
216 const struct GNUNET_HashCode *key,
217 void *value)
216{ 218{
217 struct GNUNET_SCALARPRODUCT_Element *e = value; 219 struct GNUNET_SCALARPRODUCT_Element *e = value;
218 220
@@ -229,8 +231,6 @@ free_element_cb (void *cls, const struct GNUNET_HashCode *key, void *value)
229static void 231static void
230destroy_service_session (struct AliceServiceSession *s) 232destroy_service_session (struct AliceServiceSession *s)
231{ 233{
232 unsigned int i;
233
234 if (GNUNET_YES == s->in_destroy) 234 if (GNUNET_YES == s->in_destroy)
235 return; 235 return;
236 s->in_destroy = GNUNET_YES; 236 s->in_destroy = GNUNET_YES;
@@ -261,7 +261,8 @@ destroy_service_session (struct AliceServiceSession *s)
261 } 261 }
262 if (NULL != s->intersection_op) 262 if (NULL != s->intersection_op)
263 { 263 {
264 LOG (GNUNET_ERROR_TYPE_DEBUG, "Set intersection, op still ongoing!\n"); 264 LOG (GNUNET_ERROR_TYPE_DEBUG,
265 "Set intersection, op still ongoing!\n");
265 GNUNET_SETI_operation_cancel (s->intersection_op); 266 GNUNET_SETI_operation_cancel (s->intersection_op);
266 s->intersection_op = NULL; 267 s->intersection_op = NULL;
267 } 268 }
@@ -272,16 +273,9 @@ destroy_service_session (struct AliceServiceSession *s)
272 } 273 }
273 if (NULL != s->sorted_elements) 274 if (NULL != s->sorted_elements)
274 { 275 {
275 for (i = 0; i < s->used_element_count; i++)
276 gcry_mpi_release (s->sorted_elements[i].value);
277 GNUNET_free (s->sorted_elements); 276 GNUNET_free (s->sorted_elements);
278 s->sorted_elements = NULL; 277 s->sorted_elements = NULL;
279 } 278 }
280 if (NULL != s->product)
281 {
282 gcry_mpi_release (s->product);
283 s->product = NULL;
284 }
285 GNUNET_free (s); 279 GNUNET_free (s);
286} 280}
287 281
@@ -305,10 +299,12 @@ prepare_client_end_notification (struct AliceServiceSession *session)
305 "Sending session-end notification with status %d to client for session %s\n", 299 "Sending session-end notification with status %d to client for session %s\n",
306 session->status, 300 session->status,
307 GNUNET_h2s (&session->session_id)); 301 GNUNET_h2s (&session->session_id));
308 e = GNUNET_MQ_msg (msg, GNUNET_MESSAGE_TYPE_SCALARPRODUCT_RESULT); 302 e = GNUNET_MQ_msg (msg,
303 GNUNET_MESSAGE_TYPE_SCALARPRODUCT_RESULT);
309 msg->product_length = htonl (0); 304 msg->product_length = htonl (0);
310 msg->status = htonl (session->status); 305 msg->status = htonl (session->status);
311 GNUNET_MQ_send (session->client_mq, e); 306 GNUNET_MQ_send (session->client_mq,
307 e);
312} 308}
313 309
314 310
@@ -327,41 +323,41 @@ transmit_client_response (struct AliceServiceSession *s)
327 size_t product_length = 0; 323 size_t product_length = 0;
328 int32_t range; 324 int32_t range;
329 gcry_error_t rc; 325 gcry_error_t rc;
330 int sign;
331 gcry_mpi_t value; 326 gcry_mpi_t value;
332 327
333 if (NULL == s->product) 328 if (INT_MAX == s->product)
334 { 329 {
335 GNUNET_break (0); 330 GNUNET_break (0);
336 prepare_client_end_notification (s); 331 prepare_client_end_notification (s);
337 return; 332 return;
338 } 333 }
339 value = gcry_mpi_new (0); 334 value = gcry_mpi_new (32);
340 sign = gcry_mpi_cmp_ui (s->product, 0); 335 if (0 > s->product)
341 if (0 > sign)
342 { 336 {
343 range = -1; 337 range = -1;
344 gcry_mpi_sub (value, value, s->product); 338 gcry_mpi_set_ui (value,
339 -s->product);
345 } 340 }
346 else if (0 < sign) 341 else if (0 < s->product)
347 { 342 {
348 range = 1; 343 range = 1;
349 gcry_mpi_add (value, value, s->product); 344 gcry_mpi_set_ui (value,
345 s->product);
350 } 346 }
351 else 347 else
352 { 348 {
353 /* result is exactly zero */ 349 /* result is exactly zero */
354 range = 0; 350 range = 0;
355 } 351 }
356 gcry_mpi_release (s->product); 352 if ( (0 != range) &&
357 s->product = NULL; 353 (0 != (rc = gcry_mpi_aprint (GCRYMPI_FMT_STD,
358 354 &product_exported,
359 if ((0 != range) && (0 != (rc = gcry_mpi_aprint (GCRYMPI_FMT_STD, 355 &product_length,
360 &product_exported, 356 value))))
361 &product_length,
362 value))))
363 { 357 {
364 LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_mpi_scan", rc); 358 LOG_GCRY (GNUNET_ERROR_TYPE_ERROR,
359 "gcry_mpi_scan",
360 rc);
365 prepare_client_end_notification (s); 361 prepare_client_end_notification (s);
366 return; 362 return;
367 } 363 }
@@ -374,10 +370,13 @@ transmit_client_response (struct AliceServiceSession *s)
374 msg->product_length = htonl (product_length); 370 msg->product_length = htonl (product_length);
375 if (NULL != product_exported) 371 if (NULL != product_exported)
376 { 372 {
377 GNUNET_memcpy (&msg[1], product_exported, product_length); 373 GNUNET_memcpy (&msg[1],
374 product_exported,
375 product_length);
378 GNUNET_free (product_exported); 376 GNUNET_free (product_exported);
379 } 377 }
380 GNUNET_MQ_send (s->client_mq, e); 378 GNUNET_MQ_send (s->client_mq,
379 e);
381 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 380 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
382 "Sent result to client, session %s has ended!\n", 381 "Sent result to client, session %s has ended!\n",
383 GNUNET_h2s (&s->session_id)); 382 GNUNET_h2s (&s->session_id));
@@ -394,7 +393,8 @@ transmit_client_response (struct AliceServiceSession *s)
394 * @param channel connection to the other end (henceforth invalid) 393 * @param channel connection to the other end (henceforth invalid)
395 */ 394 */
396static void 395static void
397cb_channel_destruction (void *cls, const struct GNUNET_CADET_Channel *channel) 396cb_channel_destruction (void *cls,
397 const struct GNUNET_CADET_Channel *channel)
398{ 398{
399 struct AliceServiceSession *s = cls; 399 struct AliceServiceSession *s = cls;
400 400
@@ -413,51 +413,6 @@ cb_channel_destruction (void *cls, const struct GNUNET_CADET_Channel *channel)
413 413
414 414
415/** 415/**
416 * Compute our scalar product, done by Alice
417 *
418 * @param session the session associated with this computation
419 * @param prod_g_i_b_i value from Bob
420 * @param prod_h_i_b_i value from Bob
421 * @return product as MPI, never NULL
422 */
423static gcry_mpi_t
424compute_scalar_product (struct AliceServiceSession *session,
425 gcry_mpi_point_t prod_g_i_b_i,
426 gcry_mpi_point_t prod_h_i_b_i)
427{
428 gcry_mpi_point_t g_i_b_i_a_inv;
429 gcry_mpi_point_t g_ai_bi;
430 int ai_bi;
431 gcry_mpi_t ret;
432
433 g_i_b_i_a_inv =
434 GNUNET_CRYPTO_ecc_pmul_mpi (edc, prod_g_i_b_i, my_privkey_inv);
435 g_ai_bi = GNUNET_CRYPTO_ecc_add (edc, g_i_b_i_a_inv, prod_h_i_b_i);
436 gcry_mpi_point_release (g_i_b_i_a_inv);
437 ai_bi = GNUNET_CRYPTO_ecc_dlog (edc, g_ai_bi);
438 gcry_mpi_point_release (g_ai_bi);
439 if (INT_MAX == ai_bi)
440 {
441 /* result too big */
442 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
443 "Scalar product result out of range\n");
444 return NULL;
445 }
446 ret = gcry_mpi_new (0);
447 if (ai_bi > 0)
448 {
449 gcry_mpi_set_ui (ret, ai_bi);
450 }
451 else
452 {
453 gcry_mpi_set_ui (ret, -ai_bi);
454 gcry_mpi_neg (ret, ret);
455 }
456 return ret;
457}
458
459
460/**
461 * Handle a response we got from another service we wanted to 416 * Handle a response we got from another service we wanted to
462 * calculate a scalarproduct with. 417 * calculate a scalarproduct with.
463 * 418 *
@@ -469,8 +424,6 @@ handle_bobs_cryptodata_message (void *cls,
469 const struct EccBobCryptodataMessage *msg) 424 const struct EccBobCryptodataMessage *msg)
470{ 425{
471 struct AliceServiceSession *s = cls; 426 struct AliceServiceSession *s = cls;
472 gcry_mpi_point_t prod_g_i_b_i;
473 gcry_mpi_point_t prod_h_i_b_i;
474 uint32_t contained; 427 uint32_t contained;
475 428
476 contained = ntohl (msg->contained_element_count); 429 contained = ntohl (msg->contained_element_count);
@@ -494,16 +447,33 @@ handle_bobs_cryptodata_message (void *cls,
494 destroy_service_session (s); 447 destroy_service_session (s);
495 return; 448 return;
496 } 449 }
497
498 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 450 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
499 "Received %u crypto values from Bob\n", 451 "Received %u crypto values from Bob\n",
500 (unsigned int) contained); 452 (unsigned int) contained);
501 GNUNET_CADET_receive_done (s->channel); 453 GNUNET_CADET_receive_done (s->channel);
502 prod_g_i_b_i = GNUNET_CRYPTO_ecc_bin_to_point (edc, &msg->prod_g_i_b_i); 454 {
503 prod_h_i_b_i = GNUNET_CRYPTO_ecc_bin_to_point (edc, &msg->prod_h_i_b_i); 455 struct GNUNET_CRYPTO_EccPoint g_i_b_i_a_inv;
504 s->product = compute_scalar_product (s, prod_g_i_b_i, prod_h_i_b_i); 456 struct GNUNET_CRYPTO_EccPoint g_ai_bi;
505 gcry_mpi_point_release (prod_g_i_b_i); 457
506 gcry_mpi_point_release (prod_h_i_b_i); 458 GNUNET_assert (
459 GNUNET_OK ==
460 GNUNET_CRYPTO_ecc_pmul_mpi (&msg->prod_g_i_b_i,
461 &my_privkey_inv,
462 &g_i_b_i_a_inv));
463 GNUNET_assert (
464 GNUNET_OK ==
465 GNUNET_CRYPTO_ecc_add (&g_i_b_i_a_inv,
466 &msg->prod_h_i_b_i,
467 &g_ai_bi));
468 s->product = GNUNET_CRYPTO_ecc_dlog (edc,
469 &g_ai_bi);
470 if (INT_MAX == s->product)
471 {
472 /* result too big */
473 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
474 "Scalar product result out of range\n");
475 }
476 }
507 transmit_client_response (s); 477 transmit_client_response (s);
508} 478}
509 479
@@ -517,20 +487,15 @@ handle_bobs_cryptodata_message (void *cls,
517 * @param value the `struct GNUNET_SCALARPRODUCT_Element *` 487 * @param value the `struct GNUNET_SCALARPRODUCT_Element *`
518 */ 488 */
519static int 489static int
520copy_element_cb (void *cls, const struct GNUNET_HashCode *key, void *value) 490copy_element_cb (void *cls,
491 const struct GNUNET_HashCode *key,
492 void *value)
521{ 493{
522 struct AliceServiceSession *s = cls; 494 struct AliceServiceSession *s = cls;
523 struct GNUNET_SCALARPRODUCT_Element *e = value; 495 struct GNUNET_SCALARPRODUCT_Element *e = value;
524 gcry_mpi_t mval;
525 int64_t val;
526 496
527 mval = gcry_mpi_new (0); 497 s->sorted_elements[s->used_element_count].value = (int64_t) GNUNET_ntohll (
528 val = (int64_t) GNUNET_ntohll (e->value); 498 e->value);
529 if (0 > val)
530 gcry_mpi_sub_ui (mval, mval, -val);
531 else
532 gcry_mpi_add_ui (mval, mval, val);
533 s->sorted_elements[s->used_element_count].value = mval;
534 s->sorted_elements[s->used_element_count].key = &e->key; 499 s->sorted_elements[s->used_element_count].key = &e->key;
535 s->used_element_count++; 500 s->used_element_count++;
536 return GNUNET_OK; 501 return GNUNET_OK;
@@ -545,12 +510,14 @@ copy_element_cb (void *cls, const struct GNUNET_HashCode *key, void *value)
545 * @return -1 for a < b, 0 for a=b, 1 for a > b. 510 * @return -1 for a < b, 0 for a=b, 1 for a > b.
546 */ 511 */
547static int 512static int
548element_cmp (const void *a, const void *b) 513element_cmp (const void *a,
514 const void *b)
549{ 515{
550 const struct MpiElement *ma = a; 516 const struct MpiElement *ma = a;
551 const struct MpiElement *mb = b; 517 const struct MpiElement *mb = b;
552 518
553 return GNUNET_CRYPTO_hash_cmp (ma->key, mb->key); 519 return GNUNET_CRYPTO_hash_cmp (ma->key,
520 mb->key);
554} 521}
555 522
556 523
@@ -576,9 +543,8 @@ send_alices_cryptodata_message (struct AliceServiceSession *s)
576 struct EccAliceCryptodataMessage *msg; 543 struct EccAliceCryptodataMessage *msg;
577 struct GNUNET_MQ_Envelope *e; 544 struct GNUNET_MQ_Envelope *e;
578 struct GNUNET_CRYPTO_EccPoint *payload; 545 struct GNUNET_CRYPTO_EccPoint *payload;
579 gcry_mpi_t r_ia; 546 struct GNUNET_CRYPTO_EccScalar r_ia;
580 gcry_mpi_t r_ia_ai; 547 struct GNUNET_CRYPTO_EccScalar r_ia_ai;
581 unsigned int i;
582 unsigned int off; 548 unsigned int off;
583 unsigned int todo_count; 549 unsigned int todo_count;
584 550
@@ -614,31 +580,53 @@ send_alices_cryptodata_message (struct AliceServiceSession *s)
614 GNUNET_MESSAGE_TYPE_SCALARPRODUCT_ECC_ALICE_CRYPTODATA); 580 GNUNET_MESSAGE_TYPE_SCALARPRODUCT_ECC_ALICE_CRYPTODATA);
615 msg->contained_element_count = htonl (todo_count); 581 msg->contained_element_count = htonl (todo_count);
616 payload = (struct GNUNET_CRYPTO_EccPoint *) &msg[1]; 582 payload = (struct GNUNET_CRYPTO_EccPoint *) &msg[1];
617 r_ia = gcry_mpi_new (0); 583 for (unsigned int i = off; i < off + todo_count; i++)
618 r_ia_ai = gcry_mpi_new (0);
619 for (i = off; i < off + todo_count; i++)
620 { 584 {
621 gcry_mpi_t r_i; 585 struct GNUNET_CRYPTO_EccScalar r_i;
622 gcry_mpi_point_t g_i; 586 struct GNUNET_CRYPTO_EccPoint g_i;
623 gcry_mpi_point_t h_i; 587 struct GNUNET_CRYPTO_EccPoint h_i;
624 588
625 r_i = GNUNET_CRYPTO_ecc_random_mod_n (edc); 589 /* r_i = random() mod n */
626 g_i = GNUNET_CRYPTO_ecc_dexp_mpi (edc, r_i); 590 GNUNET_CRYPTO_ecc_random_mod_n (&r_i);
591 /* g_i = g^{r_i} */
592 GNUNET_assert (GNUNET_OK ==
593 GNUNET_CRYPTO_ecc_dexp_mpi (&r_i,
594 &g_i));
627 /* r_ia = r_i * a */ 595 /* r_ia = r_i * a */
628 gcry_mpi_mul (r_ia, r_i, my_privkey); 596 crypto_core_ed25519_scalar_mul (r_ia.v,
629 gcry_mpi_release (r_i); 597 r_i.v,
598 my_privkey.v);
630 /* r_ia_ai = r_ia + a_i */ 599 /* r_ia_ai = r_ia + a_i */
631 gcry_mpi_add (r_ia_ai, r_ia, s->sorted_elements[i].value); 600 {
632 h_i = GNUNET_CRYPTO_ecc_dexp_mpi (edc, r_ia_ai); 601 int64_t val = s->sorted_elements[i].value;
633 GNUNET_CRYPTO_ecc_point_to_bin (edc, g_i, &payload[(i - off) * 2]); 602 struct GNUNET_CRYPTO_EccScalar vali;
634 GNUNET_CRYPTO_ecc_point_to_bin (edc, h_i, &payload[(i - off) * 2 + 1]); 603
635 gcry_mpi_point_release (g_i); 604 GNUNET_assert (INT64_MIN != val);
636 gcry_mpi_point_release (h_i); 605 GNUNET_CRYPTO_ecc_scalar_from_int (val > 0 ? val : -val,
606 &vali);
607 if (val > 0)
608 crypto_core_ed25519_scalar_add (r_ia_ai.v,
609 r_ia.v,
610 vali.v);
611 else
612 crypto_core_ed25519_scalar_sub (r_ia_ai.v,
613 r_ia.v,
614 vali.v);
615 }
616 /* h_i = g^{r_ia_ai} */
617 GNUNET_assert (GNUNET_OK ==
618 GNUNET_CRYPTO_ecc_dexp_mpi (&r_ia_ai,
619 &h_i));
620 memcpy (&payload[(i - off) * 2],
621 &g_i,
622 sizeof (g_i));
623 memcpy (&payload[(i - off) * 2 + 1],
624 &h_i,
625 sizeof (h_i));
637 } 626 }
638 gcry_mpi_release (r_ia);
639 gcry_mpi_release (r_ia_ai);
640 off += todo_count; 627 off += todo_count;
641 GNUNET_MQ_send (s->cadet_mq, e); 628 GNUNET_MQ_send (s->cadet_mq,
629 e);
642 } 630 }
643} 631}
644 632
@@ -740,16 +728,17 @@ cb_intersection_request_alice (void *cls,
740 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 728 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
741 "Received intersection request from %s!\n", 729 "Received intersection request from %s!\n",
742 GNUNET_i2s (other_peer)); 730 GNUNET_i2s (other_peer));
743 if (0 != GNUNET_memcmp (other_peer, &s->peer)) 731 if (0 != GNUNET_memcmp (other_peer,
732 &s->peer))
744 { 733 {
745 GNUNET_break_op (0); 734 GNUNET_break_op (0);
746 return; 735 return;
747 } 736 }
748 s->intersection_op = GNUNET_SETI_accept (request, 737 s->intersection_op
749 (struct 738 = GNUNET_SETI_accept (request,
750 GNUNET_SETI_Option[]){ { 0 } }, 739 (struct GNUNET_SETI_Option[]){ { 0 } },
751 &cb_intersection_element_removed, 740 &cb_intersection_element_removed,
752 s); 741 s);
753 if (NULL == s->intersection_op) 742 if (NULL == s->intersection_op)
754 { 743 {
755 GNUNET_break (0); 744 GNUNET_break (0);
@@ -757,7 +746,9 @@ cb_intersection_request_alice (void *cls,
757 prepare_client_end_notification (s); 746 prepare_client_end_notification (s);
758 return; 747 return;
759 } 748 }
760 if (GNUNET_OK != GNUNET_SETI_commit (s->intersection_op, s->intersection_set)) 749 if (GNUNET_OK !=
750 GNUNET_SETI_commit (s->intersection_op,
751 s->intersection_set))
761 { 752 {
762 GNUNET_break (0); 753 GNUNET_break (0);
763 s->status = GNUNET_SCALARPRODUCT_STATUS_FAILURE; 754 s->status = GNUNET_SCALARPRODUCT_STATUS_FAILURE;
@@ -775,12 +766,13 @@ cb_intersection_request_alice (void *cls,
775static void 766static void
776client_request_complete_alice (struct AliceServiceSession *s) 767client_request_complete_alice (struct AliceServiceSession *s)
777{ 768{
778 struct GNUNET_MQ_MessageHandler cadet_handlers[] = 769 struct GNUNET_MQ_MessageHandler cadet_handlers[] = {
779 { GNUNET_MQ_hd_fixed_size (bobs_cryptodata_message, 770 GNUNET_MQ_hd_fixed_size (bobs_cryptodata_message,
780 GNUNET_MESSAGE_TYPE_SCALARPRODUCT_ECC_BOB_CRYPTODATA, 771 GNUNET_MESSAGE_TYPE_SCALARPRODUCT_ECC_BOB_CRYPTODATA,
781 struct EccBobCryptodataMessage, 772 struct EccBobCryptodataMessage,
782 s), 773 s),
783 GNUNET_MQ_handler_end () }; 774 GNUNET_MQ_handler_end ()
775 };
784 struct EccServiceRequestMessage *msg; 776 struct EccServiceRequestMessage *msg;
785 struct GNUNET_MQ_Envelope *e; 777 struct GNUNET_MQ_Envelope *e;
786 struct GNUNET_HashCode set_sid; 778 struct GNUNET_HashCode set_sid;
@@ -982,17 +974,17 @@ handle_alice_client_message (void *cls,
982 s->session_id = msg->session_key; 974 s->session_id = msg->session_key;
983 elements = (const struct GNUNET_SCALARPRODUCT_Element *) &msg[1]; 975 elements = (const struct GNUNET_SCALARPRODUCT_Element *) &msg[1];
984 s->intersected_elements = 976 s->intersected_elements =
985 GNUNET_CONTAINER_multihashmap_create (s->total, GNUNET_YES); 977 GNUNET_CONTAINER_multihashmap_create (s->total,
978 GNUNET_YES);
986 s->intersection_set = GNUNET_SETI_create (cfg); 979 s->intersection_set = GNUNET_SETI_create (cfg);
987 for (uint32_t i = 0; i < contained_count; i++) 980 for (uint32_t i = 0; i < contained_count; i++)
988 { 981 {
989 if (0 == GNUNET_ntohll (elements[i].value)) 982 if (0 == GNUNET_ntohll (elements[i].value))
990 continue; 983 continue;
991 elem = GNUNET_new (struct GNUNET_SCALARPRODUCT_Element); 984 elem = GNUNET_new (struct GNUNET_SCALARPRODUCT_Element);
992 GNUNET_memcpy (elem, 985 *elem = elements[i];
993 &elements[i], 986 if (GNUNET_SYSERR ==
994 sizeof(struct GNUNET_SCALARPRODUCT_Element)); 987 GNUNET_CONTAINER_multihashmap_put (
995 if (GNUNET_SYSERR == GNUNET_CONTAINER_multihashmap_put (
996 s->intersected_elements, 988 s->intersected_elements,
997 &elem->key, 989 &elem->key,
998 elem, 990 elem,
@@ -1006,7 +998,10 @@ handle_alice_client_message (void *cls,
1006 set_elem.data = &elem->key; 998 set_elem.data = &elem->key;
1007 set_elem.size = sizeof(elem->key); 999 set_elem.size = sizeof(elem->key);
1008 set_elem.element_type = 0; 1000 set_elem.element_type = 0;
1009 GNUNET_SETI_add_element (s->intersection_set, &set_elem, NULL, NULL); 1001 GNUNET_SETI_add_element (s->intersection_set,
1002 &set_elem,
1003 NULL,
1004 NULL);
1010 s->used_element_count++; 1005 s->used_element_count++;
1011 } 1006 }
1012 GNUNET_SERVICE_client_continue (s->client); 1007 GNUNET_SERVICE_client_continue (s->client);
@@ -1017,7 +1012,8 @@ handle_alice_client_message (void *cls,
1017 "Received partial client request, waiting for more!\n"); 1012 "Received partial client request, waiting for more!\n");
1018 return; 1013 return;
1019 } 1014 }
1020 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Launching computation\n"); 1015 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1016 "Launching computation\n");
1021 client_request_complete_alice (s); 1017 client_request_complete_alice (s);
1022} 1018}
1023 1019
@@ -1031,7 +1027,8 @@ handle_alice_client_message (void *cls,
1031static void 1027static void
1032shutdown_task (void *cls) 1028shutdown_task (void *cls)
1033{ 1029{
1034 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Shutting down, initiating cleanup.\n"); 1030 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1031 "Shutting down, initiating cleanup.\n");
1035 // FIXME: we have to cut our connections to CADET first! 1032 // FIXME: we have to cut our connections to CADET first!
1036 if (NULL != my_cadet) 1033 if (NULL != my_cadet)
1037 { 1034 {
@@ -1109,17 +1106,21 @@ run (void *cls,
1109 struct GNUNET_SERVICE_Handle *service) 1106 struct GNUNET_SERVICE_Handle *service)
1110{ 1107{
1111 cfg = c; 1108 cfg = c;
1112 edc = GNUNET_CRYPTO_ecc_dlog_prepare (MAX_RESULT, MAX_RAM); 1109 edc = GNUNET_CRYPTO_ecc_dlog_prepare (MAX_RESULT,
1110 MAX_RAM);
1113 /* Select a random 'a' value for Alice */ 1111 /* Select a random 'a' value for Alice */
1114 GNUNET_CRYPTO_ecc_rnd_mpi (edc, &my_privkey, &my_privkey_inv); 1112 GNUNET_CRYPTO_ecc_rnd_mpi (&my_privkey,
1113 &my_privkey_inv);
1115 my_cadet = GNUNET_CADET_connect (cfg); 1114 my_cadet = GNUNET_CADET_connect (cfg);
1116 if (NULL == my_cadet) 1115 if (NULL == my_cadet)
1117 { 1116 {
1118 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _ ("Connect to CADET failed\n")); 1117 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1118 _ ("Connect to CADET failed\n"));
1119 GNUNET_SCHEDULER_shutdown (); 1119 GNUNET_SCHEDULER_shutdown ();
1120 return; 1120 return;
1121 } 1121 }
1122 GNUNET_SCHEDULER_add_shutdown (&shutdown_task, NULL); 1122 GNUNET_SCHEDULER_add_shutdown (&shutdown_task,
1123 NULL);
1123} 1124}
1124 1125
1125 1126
diff --git a/src/scalarproduct/gnunet-service-scalarproduct-ecc_bob.c b/src/scalarproduct/gnunet-service-scalarproduct-ecc_bob.c
index 4c835d52a..02a62c164 100644
--- a/src/scalarproduct/gnunet-service-scalarproduct-ecc_bob.c
+++ b/src/scalarproduct/gnunet-service-scalarproduct-ecc_bob.c
@@ -1,6 +1,6 @@
1/* 1/*
2 This file is part of GNUnet. 2 This file is part of GNUnet.
3 Copyright (C) 2013-2017 GNUnet e.V. 3 Copyright (C) 2013-2017, 2021 GNUnet e.V.
4 4
5 GNUnet is free software: you can redistribute it and/or modify it 5 GNUnet is free software: you can redistribute it and/or modify it
6 under the terms of the GNU Affero General Public License as published 6 under the terms of the GNU Affero General Public License as published
@@ -54,7 +54,7 @@ struct MpiElement
54 /** 54 /**
55 * Value represented (a). 55 * Value represented (a).
56 */ 56 */
57 gcry_mpi_t value; 57 int64_t value;
58}; 58};
59 59
60 60
@@ -104,12 +104,12 @@ struct BobServiceSession
104 /** 104 /**
105 * Product of the g_i^{b_i} 105 * Product of the g_i^{b_i}
106 */ 106 */
107 gcry_mpi_point_t prod_g_i_b_i; 107 struct GNUNET_CRYPTO_EccPoint prod_g_i_b_i;
108 108
109 /** 109 /**
110 * Product of the h_i^{b_i} 110 * Product of the h_i^{b_i}
111 */ 111 */
112 gcry_mpi_point_t prod_h_i_b_i; 112 struct GNUNET_CRYPTO_EccPoint prod_h_i_b_i;
113 113
114 /** 114 /**
115 * How many elements will be supplied in total from the client. 115 * How many elements will be supplied in total from the client.
@@ -213,8 +213,6 @@ free_element_cb (void *cls,
213static void 213static void
214destroy_service_session (struct BobServiceSession *s) 214destroy_service_session (struct BobServiceSession *s)
215{ 215{
216 unsigned int i;
217
218 if (GNUNET_YES == s->in_destroy) 216 if (GNUNET_YES == s->in_destroy)
219 return; 217 return;
220 s->in_destroy = GNUNET_YES; 218 s->in_destroy = GNUNET_YES;
@@ -245,21 +243,9 @@ destroy_service_session (struct BobServiceSession *s)
245 } 243 }
246 if (NULL != s->sorted_elements) 244 if (NULL != s->sorted_elements)
247 { 245 {
248 for (i = 0; i < s->used_element_count; i++)
249 gcry_mpi_release (s->sorted_elements[i].value);
250 GNUNET_free (s->sorted_elements); 246 GNUNET_free (s->sorted_elements);
251 s->sorted_elements = NULL; 247 s->sorted_elements = NULL;
252 } 248 }
253 if (NULL != s->prod_g_i_b_i)
254 {
255 gcry_mpi_point_release (s->prod_g_i_b_i);
256 s->prod_g_i_b_i = NULL;
257 }
258 if (NULL != s->prod_h_i_b_i)
259 {
260 gcry_mpi_point_release (s->prod_h_i_b_i);
261 s->prod_h_i_b_i = NULL;
262 }
263 if (NULL != s->port) 249 if (NULL != s->port)
264 { 250 {
265 GNUNET_CADET_close_port (s->port); 251 GNUNET_CADET_close_port (s->port);
@@ -364,14 +350,8 @@ transmit_bobs_cryptodata_message (struct BobServiceSession *s)
364 e = GNUNET_MQ_msg (msg, 350 e = GNUNET_MQ_msg (msg,
365 GNUNET_MESSAGE_TYPE_SCALARPRODUCT_ECC_BOB_CRYPTODATA); 351 GNUNET_MESSAGE_TYPE_SCALARPRODUCT_ECC_BOB_CRYPTODATA);
366 msg->contained_element_count = htonl (2); 352 msg->contained_element_count = htonl (2);
367 if (NULL != s->prod_g_i_b_i) 353 msg->prod_g_i_b_i = s->prod_g_i_b_i;
368 GNUNET_CRYPTO_ecc_point_to_bin (edc, 354 msg->prod_h_i_b_i = s->prod_h_i_b_i;
369 s->prod_g_i_b_i,
370 &msg->prod_g_i_b_i);
371 if (NULL != s->prod_h_i_b_i)
372 GNUNET_CRYPTO_ecc_point_to_bin (edc,
373 s->prod_h_i_b_i,
374 &msg->prod_h_i_b_i);
375 GNUNET_MQ_notify_sent (e, 355 GNUNET_MQ_notify_sent (e,
376 &bob_cadet_done_cb, 356 &bob_cadet_done_cb,
377 s); 357 s);
@@ -384,10 +364,9 @@ transmit_bobs_cryptodata_message (struct BobServiceSession *s)
384 * Iterator to copy over messages from the hash map 364 * Iterator to copy over messages from the hash map
385 * into an array for sorting. 365 * into an array for sorting.
386 * 366 *
387 * @param cls the `struct BobServiceSession *` 367 * @param cls the `struct AliceServiceSession *`
388 * @param key the key (unused) 368 * @param key the key (unused)
389 * @param value the `struct GNUNET_SCALARPRODUCT_Element *` 369 * @param value the `struct GNUNET_SCALARPRODUCT_Element *`
390 * TODO: code duplication with Alice!
391 */ 370 */
392static int 371static int
393copy_element_cb (void *cls, 372copy_element_cb (void *cls,
@@ -396,17 +375,10 @@ copy_element_cb (void *cls,
396{ 375{
397 struct BobServiceSession *s = cls; 376 struct BobServiceSession *s = cls;
398 struct GNUNET_SCALARPRODUCT_Element *e = value; 377 struct GNUNET_SCALARPRODUCT_Element *e = value;
399 gcry_mpi_t mval; 378
400 int64_t val; 379 s->sorted_elements[s->used_element_count].value = (int64_t) GNUNET_ntohll (
401 380 e->value);
402 mval = gcry_mpi_new (0); 381 s->sorted_elements[s->used_element_count].key = &e->key;
403 val = (int64_t) GNUNET_ntohll (e->value);
404 if (0 > val)
405 gcry_mpi_sub_ui (mval, mval, -val);
406 else
407 gcry_mpi_add_ui (mval, mval, val);
408 s->sorted_elements [s->used_element_count].value = mval;
409 s->sorted_elements [s->used_element_count].key = &e->key;
410 s->used_element_count++; 382 s->used_element_count++;
411 return GNUNET_OK; 383 return GNUNET_OK;
412} 384}
@@ -490,13 +462,10 @@ handle_alices_cryptodata_message (void *cls,
490 const struct GNUNET_CRYPTO_EccPoint *payload; 462 const struct GNUNET_CRYPTO_EccPoint *payload;
491 uint32_t contained_elements; 463 uint32_t contained_elements;
492 unsigned int max; 464 unsigned int max;
493 unsigned int i; 465 const struct GNUNET_CRYPTO_EccPoint *g_i;
494 const struct MpiElement *b_i; 466 const struct GNUNET_CRYPTO_EccPoint *h_i;
495 gcry_mpi_point_t tmp; 467 struct GNUNET_CRYPTO_EccPoint g_i_b_i;
496 gcry_mpi_point_t g_i; 468 struct GNUNET_CRYPTO_EccPoint h_i_b_i;
497 gcry_mpi_point_t h_i;
498 gcry_mpi_point_t g_i_b_i;
499 gcry_mpi_point_t h_i_b_i;
500 469
501 contained_elements = ntohl (msg->contained_element_count); 470 contained_elements = ntohl (msg->contained_element_count);
502 max = GNUNET_CONTAINER_multihashmap_size (s->intersected_elements); 471 max = GNUNET_CONTAINER_multihashmap_size (s->intersected_elements);
@@ -522,21 +491,29 @@ handle_alices_cryptodata_message (void *cls,
522 (unsigned int) contained_elements); 491 (unsigned int) contained_elements);
523 payload = (const struct GNUNET_CRYPTO_EccPoint *) &msg[1]; 492 payload = (const struct GNUNET_CRYPTO_EccPoint *) &msg[1];
524 493
525 for (i = 0; i < contained_elements; i++) 494 for (unsigned int i = 0; i < contained_elements; i++)
526 { 495 {
527 b_i = &s->sorted_elements[i + s->cadet_received_element_count]; 496 int64_t val = s->sorted_elements[i + s->cadet_received_element_count].value;
528 g_i = GNUNET_CRYPTO_ecc_bin_to_point (edc, 497 struct GNUNET_CRYPTO_EccScalar vali;
529 &payload[i * 2]); 498
530 g_i_b_i = GNUNET_CRYPTO_ecc_pmul_mpi (edc, 499 GNUNET_assert (INT64_MIN != val);
531 g_i, 500 GNUNET_CRYPTO_ecc_scalar_from_int (val > 0 ? val : -val,
532 b_i->value); 501 &vali);
533 gcry_mpi_point_release (g_i); 502 if (val < 0)
534 h_i = GNUNET_CRYPTO_ecc_bin_to_point (edc, 503 crypto_core_ed25519_scalar_negate (vali.v,
535 &payload[i * 2 + 1]); 504 vali.v);
536 h_i_b_i = GNUNET_CRYPTO_ecc_pmul_mpi (edc, 505 g_i = &payload[i * 2];
537 h_i, 506 /* g_i_b_i = g_i^vali */
538 b_i->value); 507 GNUNET_assert (GNUNET_OK ==
539 gcry_mpi_point_release (h_i); 508 GNUNET_CRYPTO_ecc_pmul_mpi (g_i,
509 &vali,
510 &g_i_b_i));
511 h_i = &payload[i * 2 + 1];
512 /* h_i_b_i = h_i^vali */
513 GNUNET_assert (GNUNET_OK ==
514 GNUNET_CRYPTO_ecc_pmul_mpi (h_i,
515 &vali,
516 &h_i_b_i));
540 if (0 == i + s->cadet_received_element_count) 517 if (0 == i + s->cadet_received_element_count)
541 { 518 {
542 /* first iteration, nothing to add */ 519 /* first iteration, nothing to add */
@@ -546,18 +523,14 @@ handle_alices_cryptodata_message (void *cls,
546 else 523 else
547 { 524 {
548 /* further iterations, cummulate resulting value */ 525 /* further iterations, cummulate resulting value */
549 tmp = GNUNET_CRYPTO_ecc_add (edc, 526 GNUNET_assert (GNUNET_OK ==
550 s->prod_g_i_b_i, 527 GNUNET_CRYPTO_ecc_add (&s->prod_g_i_b_i,
551 g_i_b_i); 528 &g_i_b_i,
552 gcry_mpi_point_release (s->prod_g_i_b_i); 529 &s->prod_g_i_b_i));
553 gcry_mpi_point_release (g_i_b_i); 530 GNUNET_assert (GNUNET_OK ==
554 s->prod_g_i_b_i = tmp; 531 GNUNET_CRYPTO_ecc_add (&s->prod_h_i_b_i,
555 tmp = GNUNET_CRYPTO_ecc_add (edc, 532 &h_i_b_i,
556 s->prod_h_i_b_i, 533 &s->prod_h_i_b_i));
557 h_i_b_i);
558 gcry_mpi_point_release (s->prod_h_i_b_i);
559 gcry_mpi_point_release (h_i_b_i);
560 s->prod_h_i_b_i = tmp;
561 } 534 }
562 } 535 }
563 s->cadet_received_element_count += contained_elements; 536 s->cadet_received_element_count += contained_elements;
@@ -747,10 +720,9 @@ cb_channel_incoming (void *cls,
747 * @return #GNUNET_OK if @a msg is well-formed 720 * @return #GNUNET_OK if @a msg is well-formed
748 */ 721 */
749static int 722static int
750check_bob_client_message_multipart (void *cls, 723check_bob_client_message_multipart (
751 const struct 724 void *cls,
752 ComputationBobCryptodataMultipartMessage * 725 const struct ComputationBobCryptodataMultipartMessage *msg)
753 msg)
754{ 726{
755 struct BobServiceSession *s = cls; 727 struct BobServiceSession *s = cls;
756 uint32_t contained_count; 728 uint32_t contained_count;
@@ -781,10 +753,9 @@ check_bob_client_message_multipart (void *cls,
781 * @param msg the actual message 753 * @param msg the actual message
782 */ 754 */
783static void 755static void
784handle_bob_client_message_multipart (void *cls, 756handle_bob_client_message_multipart (
785 const struct 757 void *cls,
786 ComputationBobCryptodataMultipartMessage * 758 const struct ComputationBobCryptodataMultipartMessage *msg)
787 msg)
788{ 759{
789 struct BobServiceSession *s = cls; 760 struct BobServiceSession *s = cls;
790 uint32_t contained_count; 761 uint32_t contained_count;
diff --git a/src/scalarproduct/perf_scalarproduct.sh b/src/scalarproduct/perf_scalarproduct.sh
index a7935873e..b15465c9a 100755
--- a/src/scalarproduct/perf_scalarproduct.sh
+++ b/src/scalarproduct/perf_scalarproduct.sh
@@ -1,7 +1,7 @@
1#!/bin/bash 1#!/bin/bash
2# Computes a simple scalar product, with configurable vector size. 2# Computes a simple scalar product, with configurable vector size.
3# 3#
4# Some results (wall-clock for Alice+Bob, single-core, i7): 4# Some results (wall-clock for Alice+Bob, single-core, i7, libgcrypt):
5# SIZE 2048-H(s) 2048-O(s) 1024-O(s) ECC-2^20-H(s) ECC-2^28-H(s) 5# SIZE 2048-H(s) 2048-O(s) 1024-O(s) ECC-2^20-H(s) ECC-2^28-H(s)
6# 25 10 14 3 2 29 6# 25 10 14 3 2 29
7# 50 17 21 5 2 29 7# 50 17 21 5 2 29
@@ -11,8 +11,21 @@
11# 800 304 32 OOR 33 11# 800 304 32 OOR 33
12 12
13# Bandwidth (including set intersection): 13# Bandwidth (including set intersection):
14# RSA-2048 ECC 14# RSA-1024 RSA-2048 ECC
15# 800: 3846 kb 70 kb 15# 800: 629 kb 1234 kb 65 kb
16#
17# LIBSODIUM, AMD Threadripper 1950:
18#
19# SIZE 2048-O(s) 1024-O(s) ECC-2^20-H(s) ECC-2^28-H(s)
20# 25 4.3 0.7 0.129 4.233
21# 50 7.7 1.2 0.143 4.267
22# 100 10.3 2.4 0.163 4.282
23# 200 19.8 3.0 0.192 4.326
24# 400 35.9 6.0 0.253 4.358
25# 800 73.7 12.6 0.379 4.533
26
27#
28#
16# Configure benchmark size: 29# Configure benchmark size:
17SIZE=800 30SIZE=800
18# 31#
diff --git a/src/scalarproduct/scalarproduct_api.c b/src/scalarproduct/scalarproduct_api.c
index b2a90c222..4ac39614a 100644
--- a/src/scalarproduct/scalarproduct_api.c
+++ b/src/scalarproduct/scalarproduct_api.c
@@ -42,14 +42,10 @@
42 * @param status processing status code 42 * @param status processing status code
43 */ 43 */
44typedef void 44typedef void
45(*GNUNET_SCALARPRODUCT_ResponseMessageHandler) (struct 45(*GNUNET_SCALARPRODUCT_ResponseMessageHandler) (
46 GNUNET_SCALARPRODUCT_ComputationHandle 46 struct GNUNET_SCALARPRODUCT_ComputationHandle *h,
47 *h, 47 const struct ClientResponseMessage *msg,
48 const struct 48 enum GNUNET_SCALARPRODUCT_ResponseStatus status);
49 ClientResponseMessage *msg,
50 enum
51 GNUNET_SCALARPRODUCT_ResponseStatus
52 status);
53 49
54 50
55/** 51/**
@@ -172,13 +168,12 @@ check_unique (const struct GNUNET_SCALARPRODUCT_Element *elements,
172 uint32_t element_count) 168 uint32_t element_count)
173{ 169{
174 struct GNUNET_CONTAINER_MultiHashMap *map; 170 struct GNUNET_CONTAINER_MultiHashMap *map;
175 uint32_t i;
176 int ok; 171 int ok;
177 172
178 ok = GNUNET_OK; 173 ok = GNUNET_OK;
179 map = GNUNET_CONTAINER_multihashmap_create (2 * element_count, 174 map = GNUNET_CONTAINER_multihashmap_create (2 * element_count,
180 GNUNET_YES); 175 GNUNET_YES);
181 for (i = 0; i < element_count; i++) 176 for (uint32_t i = 0; i < element_count; i++)
182 if (GNUNET_OK != 177 if (GNUNET_OK !=
183 GNUNET_CONTAINER_multihashmap_put (map, 178 GNUNET_CONTAINER_multihashmap_put (map,
184 &elements[i].key, 179 &elements[i].key,
@@ -227,16 +222,13 @@ mq_error_handler (void *cls,
227 * @return a new handle for this computation 222 * @return a new handle for this computation
228 */ 223 */
229struct GNUNET_SCALARPRODUCT_ComputationHandle * 224struct GNUNET_SCALARPRODUCT_ComputationHandle *
230GNUNET_SCALARPRODUCT_accept_computation (const struct 225GNUNET_SCALARPRODUCT_accept_computation (
231 GNUNET_CONFIGURATION_Handle *cfg, 226 const struct GNUNET_CONFIGURATION_Handle *cfg,
232 const struct 227 const struct GNUNET_HashCode *session_key,
233 GNUNET_HashCode *session_key, 228 const struct GNUNET_SCALARPRODUCT_Element *elements,
234 const struct 229 uint32_t element_count,
235 GNUNET_SCALARPRODUCT_Element *elements, 230 GNUNET_SCALARPRODUCT_ContinuationWithStatus cont,
236 uint32_t element_count, 231 void *cont_cls)
237 GNUNET_SCALARPRODUCT_ContinuationWithStatus
238 cont,
239 void *cont_cls)
240{ 232{
241 struct GNUNET_SCALARPRODUCT_ComputationHandle *h 233 struct GNUNET_SCALARPRODUCT_ComputationHandle *h
242 = GNUNET_new (struct GNUNET_SCALARPRODUCT_ComputationHandle); 234 = GNUNET_new (struct GNUNET_SCALARPRODUCT_ComputationHandle);
@@ -389,16 +381,14 @@ process_result_message (struct GNUNET_SCALARPRODUCT_ComputationHandle *h,
389 * @return a new handle for this computation 381 * @return a new handle for this computation
390 */ 382 */
391struct GNUNET_SCALARPRODUCT_ComputationHandle * 383struct GNUNET_SCALARPRODUCT_ComputationHandle *
392GNUNET_SCALARPRODUCT_start_computation (const struct 384GNUNET_SCALARPRODUCT_start_computation (
393 GNUNET_CONFIGURATION_Handle *cfg, 385 const struct GNUNET_CONFIGURATION_Handle *cfg,
394 const struct 386 const struct GNUNET_HashCode *session_key,
395 GNUNET_HashCode *session_key, 387 const struct GNUNET_PeerIdentity *peer,
396 const struct GNUNET_PeerIdentity *peer, 388 const struct GNUNET_SCALARPRODUCT_Element *elements,
397 const struct 389 uint32_t element_count,
398 GNUNET_SCALARPRODUCT_Element *elements, 390 GNUNET_SCALARPRODUCT_DatumProcessor cont,
399 uint32_t element_count, 391 void *cont_cls)
400 GNUNET_SCALARPRODUCT_DatumProcessor cont,
401 void *cont_cls)
402{ 392{
403 struct GNUNET_SCALARPRODUCT_ComputationHandle *h 393 struct GNUNET_SCALARPRODUCT_ComputationHandle *h
404 = GNUNET_new (struct GNUNET_SCALARPRODUCT_ComputationHandle); 394 = GNUNET_new (struct GNUNET_SCALARPRODUCT_ComputationHandle);
diff --git a/src/scalarproduct/test_ecc_scalarproduct.c b/src/scalarproduct/test_ecc_scalarproduct.c
index eced3ef6a..85460cb05 100644
--- a/src/scalarproduct/test_ecc_scalarproduct.c
+++ b/src/scalarproduct/test_ecc_scalarproduct.c
@@ -45,20 +45,12 @@ test_sp (const unsigned int *avec,
45 const unsigned int *bvec) 45 const unsigned int *bvec)
46{ 46{
47 unsigned int len; 47 unsigned int len;
48 unsigned int i; 48 struct GNUNET_CRYPTO_EccScalar a;
49 gcry_mpi_t a; 49 struct GNUNET_CRYPTO_EccScalar a_neg;
50 gcry_mpi_t a_inv; 50 struct GNUNET_CRYPTO_EccPoint *g;
51 gcry_mpi_t ri; 51 struct GNUNET_CRYPTO_EccPoint *h;
52 gcry_mpi_t val; 52 struct GNUNET_CRYPTO_EccPoint pg;
53 gcry_mpi_t ria; 53 struct GNUNET_CRYPTO_EccPoint ph;
54 gcry_mpi_t tmp;
55 gcry_mpi_point_t *g;
56 gcry_mpi_point_t *h;
57 gcry_mpi_point_t pg;
58 gcry_mpi_point_t ph;
59 gcry_mpi_point_t pgi;
60 gcry_mpi_point_t gsp;
61 int sp;
62 54
63 /* determine length */ 55 /* determine length */
64 for (len = 0; 0 != avec[len]; len++) 56 for (len = 0; 0 != avec[len]; len++)
@@ -67,90 +59,133 @@ test_sp (const unsigned int *avec,
67 return 0; 59 return 0;
68 60
69 /* Alice */ 61 /* Alice */
70 GNUNET_CRYPTO_ecc_rnd_mpi (edc, 62 GNUNET_CRYPTO_ecc_rnd_mpi (&a,
71 &a, &a_inv); 63 &a_neg);
72 g = GNUNET_new_array (len, 64 g = GNUNET_new_array (len,
73 gcry_mpi_point_t); 65 struct GNUNET_CRYPTO_EccPoint);
74 h = GNUNET_new_array (len, 66 h = GNUNET_new_array (len,
75 gcry_mpi_point_t); 67 struct GNUNET_CRYPTO_EccPoint);
76 ria = gcry_mpi_new (0); 68 for (unsigned int i = 0; i < len; i++)
77 tmp = gcry_mpi_new (0);
78 for (i = 0; i < len; i++)
79 { 69 {
80 ri = GNUNET_CRYPTO_ecc_random_mod_n (edc); 70 struct GNUNET_CRYPTO_EccScalar tmp;
81 g[i] = GNUNET_CRYPTO_ecc_dexp_mpi (edc, 71 struct GNUNET_CRYPTO_EccScalar ri;
82 ri); 72 struct GNUNET_CRYPTO_EccScalar ria;
83 /* ria = ri * a */ 73
84 gcry_mpi_mul (ria, 74 GNUNET_CRYPTO_ecc_random_mod_n (&ri);
85 ri, 75 GNUNET_assert (GNUNET_OK ==
86 a); 76 GNUNET_CRYPTO_ecc_dexp_mpi (&ri,
77 &g[i]));
78 /* ria = ri * a mod L, where L is the order of the main subgroup */
79 crypto_core_ed25519_scalar_mul (ria.v,
80 ri.v,
81 a.v);
87 /* tmp = ria + avec[i] */ 82 /* tmp = ria + avec[i] */
88 gcry_mpi_add_ui (tmp, 83 {
89 ria, 84 int64_t val = avec[i];
90 avec[i]); 85 struct GNUNET_CRYPTO_EccScalar vali;
91 h[i] = GNUNET_CRYPTO_ecc_dexp_mpi (edc, 86
92 tmp); 87 GNUNET_assert (INT64_MIN != val);
88 GNUNET_CRYPTO_ecc_scalar_from_int (val > 0 ? val : -val,
89 &vali);
90 if (val > 0)
91 crypto_core_ed25519_scalar_add (tmp.v,
92 ria.v,
93 vali.v);
94 else
95 crypto_core_ed25519_scalar_sub (tmp.v,
96 ria.v,
97 vali.v);
98 }
99 /* h[i] = g^tmp = g^{ria + avec[i]} */
100 GNUNET_assert (GNUNET_OK ==
101 GNUNET_CRYPTO_ecc_dexp_mpi (&tmp,
102 &h[i]));
93 } 103 }
94 gcry_mpi_release (ria);
95 gcry_mpi_release (tmp);
96 104
97 /* Bob */ 105 /* Bob */
98 val = gcry_mpi_new (0); 106 for (unsigned int i = 0; i < len; i++)
99 gcry_mpi_set_ui (val, bvec[0]);
100 pg = GNUNET_CRYPTO_ecc_pmul_mpi (edc,
101 g[0],
102 val);
103 ph = GNUNET_CRYPTO_ecc_pmul_mpi (edc,
104 h[0],
105 val);
106 for (i = 1; i < len; i++)
107 { 107 {
108 gcry_mpi_point_t m; 108 struct GNUNET_CRYPTO_EccPoint gm;
109 gcry_mpi_point_t tmp; 109 struct GNUNET_CRYPTO_EccPoint hm;
110 110
111 gcry_mpi_set_ui (val, bvec[i]); 111 {
112 m = GNUNET_CRYPTO_ecc_pmul_mpi (edc, 112 int64_t val = bvec[i];
113 g[i], 113 struct GNUNET_CRYPTO_EccScalar vali;
114 val); 114
115 tmp = GNUNET_CRYPTO_ecc_add (edc, 115 GNUNET_assert (INT64_MIN != val);
116 m, 116 GNUNET_CRYPTO_ecc_scalar_from_int (val > 0 ? val : -val,
117 pg); 117 &vali);
118 gcry_mpi_point_release (m); 118 if (val < 0)
119 gcry_mpi_point_release (pg); 119 crypto_core_ed25519_scalar_negate (vali.v,
120 gcry_mpi_point_release (g[i]); 120 vali.v);
121 pg = tmp; 121 /* gm = g[i]^vali */
122 122 GNUNET_assert (GNUNET_OK ==
123 m = GNUNET_CRYPTO_ecc_pmul_mpi (edc, 123 GNUNET_CRYPTO_ecc_pmul_mpi (&g[i],
124 h[i], 124 &vali,
125 val); 125 &gm));
126 tmp = GNUNET_CRYPTO_ecc_add (edc, 126 /* hm = h[i]^vali */
127 m, 127 GNUNET_assert (GNUNET_OK ==
128 ph); 128 GNUNET_CRYPTO_ecc_pmul_mpi (&h[i],
129 gcry_mpi_point_release (m); 129 &vali,
130 gcry_mpi_point_release (ph); 130 &hm));
131 gcry_mpi_point_release (h[i]); 131 }
132 ph = tmp; 132 if (0 != i)
133 {
134 /* pg += gm */
135 GNUNET_assert (GNUNET_OK ==
136 GNUNET_CRYPTO_ecc_add (&gm,
137 &pg,
138 &pg));
139 /* ph += hm */
140 GNUNET_assert (GNUNET_OK ==
141 GNUNET_CRYPTO_ecc_add (&hm,
142 &ph,
143 &ph));
144 }
145 else
146 {
147 pg = gm;
148 ph = hm;
149 }
133 } 150 }
134 gcry_mpi_release (val);
135 GNUNET_free (g); 151 GNUNET_free (g);
136 GNUNET_free (h); 152 GNUNET_free (h);
137 153
138 /* Alice */ 154 /* Alice */
139 pgi = GNUNET_CRYPTO_ecc_pmul_mpi (edc, 155 {
140 pg, 156 struct GNUNET_CRYPTO_EccPoint pgi;
141 a_inv); 157 struct GNUNET_CRYPTO_EccPoint gsp;
142 gsp = GNUNET_CRYPTO_ecc_add (edc, 158
143 pgi, 159 /* pgi = pg^inv */
144 ph); 160 GNUNET_assert (GNUNET_OK ==
145 gcry_mpi_point_release (pgi); 161 GNUNET_CRYPTO_ecc_pmul_mpi (&pg,
146 gcry_mpi_point_release (ph); 162 &a_neg,
147 sp = GNUNET_CRYPTO_ecc_dlog (edc, 163 &pgi));
148 gsp); 164 /* gsp = pgi + ph */
149 gcry_mpi_point_release (gsp); 165 GNUNET_assert (GNUNET_OK ==
150 return sp; 166 GNUNET_CRYPTO_ecc_add (&pgi,
167 &ph,
168 &gsp));
169 return GNUNET_CRYPTO_ecc_dlog (edc,
170 &gsp);
171 }
151} 172}
152 173
153 174
175/**
176 * Macro that checks that @a want is equal to @a have and
177 * if not returns with a failure code.
178 */
179#define CHECK(want,have) do { \
180 if (want != have) { \
181 GNUNET_break (0); \
182 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, \
183 "Wanted %d, got %d\n", want, have); \
184 GNUNET_CRYPTO_ecc_dlog_release (edc); \
185 return 1; \
186 } } while (0)
187
188
154int 189int
155main (int argc, char *argv[]) 190main (int argc, char *argv[])
156{ 191{
@@ -163,12 +198,12 @@ main (int argc, char *argv[])
163 "WARNING", 198 "WARNING",
164 NULL); 199 NULL);
165 edc = GNUNET_CRYPTO_ecc_dlog_prepare (128, 128); 200 edc = GNUNET_CRYPTO_ecc_dlog_prepare (128, 128);
166 GNUNET_assert (2 == test_sp (v11, v11)); 201 CHECK (2, test_sp (v11, v11));
167 GNUNET_assert (4 == test_sp (v22, v11)); 202 CHECK (4, test_sp (v22, v11));
168 GNUNET_assert (8 == test_sp (v35, v11)); 203 CHECK (8, test_sp (v35, v11));
169 GNUNET_assert (26 == test_sp (v35, v24)); 204 CHECK (26, test_sp (v35, v24));
170 GNUNET_assert (26 == test_sp (v24, v35)); 205 CHECK (26, test_sp (v24, v35));
171 GNUNET_assert (16 == test_sp (v22, v35)); 206 CHECK (16, test_sp (v22, v35));
172 GNUNET_CRYPTO_ecc_dlog_release (edc); 207 GNUNET_CRYPTO_ecc_dlog_release (edc);
173 return 0; 208 return 0;
174} 209}
diff --git a/src/scalarproduct/test_scalarproduct_negative.sh b/src/scalarproduct/test_scalarproduct_negative.sh
index b08e4527f..459406836 100755
--- a/src/scalarproduct/test_scalarproduct_negative.sh
+++ b/src/scalarproduct/test_scalarproduct_negative.sh
@@ -5,6 +5,9 @@ INPUTALICE="-k CCC -e 'AB,10;RO,-3;FL,-3;LOL,1;'"
5INPUTBOB="-k CCC -e 'BC,-20000;RO,1000;FL,100;LOL,24;'" 5INPUTBOB="-k CCC -e 'BC,-20000;RO,1000;FL,100;LOL,24;'"
6 6
7# necessary to make the testing prefix deterministic, so we can access the config files 7# necessary to make the testing prefix deterministic, so we can access the config files
8unset XDG_DATA_HOME
9unset XDG_CONFIG_HOME
10
8PREFIX=/tmp/test-scalarproduct`date +%H%M%S` 11PREFIX=/tmp/test-scalarproduct`date +%H%M%S`
9 12
10# where can we find the peers config files? 13# where can we find the peers config files?