diff options
-rw-r--r-- | src/scalarproduct/Makefile.am | 2 | ||||
-rw-r--r-- | src/scalarproduct/gnunet-service-scalarproduct.c | 951 | ||||
-rw-r--r-- | src/scalarproduct/scalarproduct.h | 17 |
3 files changed, 276 insertions, 694 deletions
diff --git a/src/scalarproduct/Makefile.am b/src/scalarproduct/Makefile.am index 0f838a7f9..81ee9c4fc 100644 --- a/src/scalarproduct/Makefile.am +++ b/src/scalarproduct/Makefile.am | |||
@@ -68,5 +68,5 @@ check_SCRIPTS = \ | |||
68 | 68 | ||
69 | if ENABLE_TEST_RUN | 69 | if ENABLE_TEST_RUN |
70 | AM_TESTS_ENVIRONMENT=export GNUNET_PREFIX=$${GNUNET_PREFIX:-@libdir@};export PATH=$${GNUNET_PREFIX:-@prefix@}/bin:$$PATH; | 70 | AM_TESTS_ENVIRONMENT=export GNUNET_PREFIX=$${GNUNET_PREFIX:-@libdir@};export PATH=$${GNUNET_PREFIX:-@prefix@}/bin:$$PATH; |
71 | TESTS = $(check_SCRIPTS) | 71 | # TESTS = $(check_SCRIPTS) |
72 | endif | 72 | endif |
diff --git a/src/scalarproduct/gnunet-service-scalarproduct.c b/src/scalarproduct/gnunet-service-scalarproduct.c index d21ff2b96..d7407e3ae 100644 --- a/src/scalarproduct/gnunet-service-scalarproduct.c +++ b/src/scalarproduct/gnunet-service-scalarproduct.c | |||
@@ -156,32 +156,37 @@ struct ServiceSession | |||
156 | /** | 156 | /** |
157 | * Public key of the remote service, only used by bob | 157 | * Public key of the remote service, only used by bob |
158 | */ | 158 | */ |
159 | struct GNUNET_CRYPTO_PaillierPublicKey remote_pubkey; | 159 | struct GNUNET_CRYPTO_PaillierPublicKey * remote_pubkey; |
160 | 160 | ||
161 | /** | 161 | /** |
162 | * E(ai)(Bob) or ai(Alice) after applying the mask | 162 | * ai(Alice) after applying the mask |
163 | */ | 163 | */ |
164 | gcry_mpi_t * a; | 164 | gcry_mpi_t * a; |
165 | 165 | ||
166 | /** | 166 | /** |
167 | * E(ai)(Bob) after applying the mask | ||
168 | */ | ||
169 | struct GNUNET_CRYPTO_PaillierCiphertext * e_a; | ||
170 | |||
171 | /** | ||
167 | * Bob's permutation p of R | 172 | * Bob's permutation p of R |
168 | */ | 173 | */ |
169 | gcry_mpi_t * r; | 174 | struct GNUNET_CRYPTO_PaillierCiphertext * r; |
170 | 175 | ||
171 | /** | 176 | /** |
172 | * Bob's permutation q of R | 177 | * Bob's permutation q of R |
173 | */ | 178 | */ |
174 | gcry_mpi_t * r_prime; | 179 | struct GNUNET_CRYPTO_PaillierCiphertext * r_prime; |
175 | 180 | ||
176 | /** | 181 | /** |
177 | * Bob's s | 182 | * Bob's s |
178 | */ | 183 | */ |
179 | gcry_mpi_t s; | 184 | struct GNUNET_CRYPTO_PaillierCiphertext * s; |
180 | 185 | ||
181 | /** | 186 | /** |
182 | * Bob's s' | 187 | * Bob's s' |
183 | */ | 188 | */ |
184 | gcry_mpi_t s_prime; | 189 | struct GNUNET_CRYPTO_PaillierCiphertext * s_prime; |
185 | 190 | ||
186 | /** | 191 | /** |
187 | * Bobs matching response session from the client | 192 | * Bobs matching response session from the client |
@@ -261,39 +266,14 @@ static struct GNUNET_MESH_Handle *my_mesh; | |||
261 | static struct GNUNET_PeerIdentity me; | 266 | static struct GNUNET_PeerIdentity me; |
262 | 267 | ||
263 | /** | 268 | /** |
264 | * Service's own public key represented as string | 269 | * Service's own public key |
265 | */ | ||
266 | static unsigned char * my_pubkey_external; | ||
267 | |||
268 | /** | ||
269 | * Service's own public key represented as string | ||
270 | */ | 270 | */ |
271 | static uint32_t my_pubkey_external_length = 0; | 271 | static struct GNUNET_CRYPTO_PaillierPublicKey my_pubkey; |
272 | 272 | ||
273 | /** | 273 | /** |
274 | * Service's own n | 274 | * Service's own private key |
275 | */ | 275 | */ |
276 | static gcry_mpi_t my_n; | 276 | static struct GNUNET_CRYPTO_PaillierPrivateKey my_privkey; |
277 | |||
278 | /** | ||
279 | * Service's own n^2 (kept for performance) | ||
280 | */ | ||
281 | static gcry_mpi_t my_nsquare; | ||
282 | |||
283 | /** | ||
284 | * Service's own public exponent | ||
285 | */ | ||
286 | static gcry_mpi_t my_g; | ||
287 | |||
288 | /** | ||
289 | * Service's own private multiplier | ||
290 | */ | ||
291 | static gcry_mpi_t my_mu; | ||
292 | |||
293 | /** | ||
294 | * Service's own private exponent | ||
295 | */ | ||
296 | static gcry_mpi_t my_lambda; | ||
297 | 277 | ||
298 | /** | 278 | /** |
299 | * Service's offset for values that could possibly be negative but are plaintext for encryption. | 279 | * Service's offset for values that could possibly be negative but are plaintext for encryption. |
@@ -338,160 +318,6 @@ static int do_shutdown; | |||
338 | 318 | ||
339 | 319 | ||
340 | /** | 320 | /** |
341 | * Generates an Paillier private/public keyset and extracts the values using libgrcypt only | ||
342 | */ | ||
343 | static void | ||
344 | generate_keyset () | ||
345 | { | ||
346 | gcry_sexp_t gen_params; | ||
347 | gcry_sexp_t key; | ||
348 | gcry_sexp_t tmp_sexp; | ||
349 | gcry_mpi_t p; | ||
350 | gcry_mpi_t q; | ||
351 | gcry_mpi_t tmp1; | ||
352 | gcry_mpi_t tmp2; | ||
353 | gcry_mpi_t gcd; | ||
354 | |||
355 | size_t erroff = 0; | ||
356 | |||
357 | // we can still use the RSA keygen for generating p,q,n, but using e is pointless. | ||
358 | GNUNET_assert (0 == gcry_sexp_build (&gen_params, &erroff, | ||
359 | "(genkey(rsa(nbits %d)(rsa-use-e 3:257)))", | ||
360 | KEYBITS)); | ||
361 | |||
362 | GNUNET_assert (0 == gcry_pk_genkey (&key, gen_params)); | ||
363 | gcry_sexp_release (gen_params); | ||
364 | |||
365 | // get n and d of our publickey as MPI | ||
366 | tmp_sexp = gcry_sexp_find_token (key, "n", 0); | ||
367 | GNUNET_assert (tmp_sexp); | ||
368 | my_n = gcry_sexp_nth_mpi (tmp_sexp, 1, GCRYMPI_FMT_USG); | ||
369 | gcry_sexp_release (tmp_sexp); | ||
370 | tmp_sexp = gcry_sexp_find_token (key, "p", 0); | ||
371 | GNUNET_assert (tmp_sexp); | ||
372 | p = gcry_sexp_nth_mpi (tmp_sexp, 1, GCRYMPI_FMT_USG); | ||
373 | gcry_sexp_release (tmp_sexp); | ||
374 | tmp_sexp = gcry_sexp_find_token (key, "q", 0); | ||
375 | GNUNET_assert (tmp_sexp); | ||
376 | q = gcry_sexp_nth_mpi (tmp_sexp, 1, GCRYMPI_FMT_USG); | ||
377 | gcry_sexp_release (key); | ||
378 | |||
379 | tmp1 = gcry_mpi_new (0); | ||
380 | tmp2 = gcry_mpi_new (0); | ||
381 | gcd = gcry_mpi_new (0); | ||
382 | my_g = gcry_mpi_new (0); | ||
383 | my_mu = gcry_mpi_new (0); | ||
384 | my_nsquare = gcry_mpi_new (0); | ||
385 | my_lambda = gcry_mpi_new (0); | ||
386 | |||
387 | // calculate lambda | ||
388 | // lambda = frac{(p-1)*(q-1)}{gcd(p-1,q-1)} | ||
389 | gcry_mpi_sub_ui (tmp1, p, 1); | ||
390 | gcry_mpi_sub_ui (tmp2, q, 1); | ||
391 | gcry_mpi_gcd (gcd, tmp1, tmp2); | ||
392 | gcry_mpi_set (my_lambda, tmp1); | ||
393 | gcry_mpi_mul (my_lambda, my_lambda, tmp2); | ||
394 | gcry_mpi_div (my_lambda, NULL, my_lambda, gcd, 0); | ||
395 | |||
396 | // generate a g | ||
397 | gcry_mpi_mul (my_nsquare, my_n, my_n); | ||
398 | do { | ||
399 | // find a matching g | ||
400 | do { | ||
401 | gcry_mpi_randomize (my_g, KEYBITS * 2, GCRY_WEAK_RANDOM); | ||
402 | // g must be smaller than n^2 | ||
403 | if (0 >= gcry_mpi_cmp (my_g, my_nsquare)) | ||
404 | continue; | ||
405 | |||
406 | // g must have gcd == 1 with n^2 | ||
407 | gcry_mpi_gcd (gcd, my_g, my_nsquare); | ||
408 | } | ||
409 | while (gcry_mpi_cmp_ui (gcd, 1)); | ||
410 | |||
411 | // is this a valid g? | ||
412 | // if so, gcd(((g^lambda mod n^2)-1 )/n, n) = 1 | ||
413 | gcry_mpi_powm (tmp1, my_g, my_lambda, my_nsquare); | ||
414 | gcry_mpi_sub_ui (tmp1, tmp1, 1); | ||
415 | gcry_mpi_div (tmp1, NULL, tmp1, my_n, 0); | ||
416 | gcry_mpi_gcd (gcd, tmp1, my_n); | ||
417 | } | ||
418 | while (gcry_mpi_cmp_ui (gcd, 1)); | ||
419 | |||
420 | // calculate our mu based on g and n. | ||
421 | // mu = (((g^lambda mod n^2)-1 )/n)^-1 mod n | ||
422 | gcry_mpi_invm (my_mu, tmp1, my_n); | ||
423 | |||
424 | GNUNET_assert (0 == gcry_sexp_build (&key, &erroff, | ||
425 | "(public-key (paillier (n %M)(g %M)))", | ||
426 | my_n, my_g)); | ||
427 | |||
428 | // get the length of this sexpression | ||
429 | my_pubkey_external_length = gcry_sexp_sprint (key, | ||
430 | GCRYSEXP_FMT_CANON, | ||
431 | NULL, | ||
432 | UINT16_MAX); | ||
433 | |||
434 | GNUNET_assert (my_pubkey_external_length > 0); | ||
435 | my_pubkey_external = GNUNET_malloc (my_pubkey_external_length); | ||
436 | |||
437 | // convert the sexpression to canonical format | ||
438 | gcry_sexp_sprint (key, | ||
439 | GCRYSEXP_FMT_CANON, | ||
440 | my_pubkey_external, | ||
441 | my_pubkey_external_length); | ||
442 | |||
443 | gcry_sexp_release (key); | ||
444 | |||
445 | // offset has to be sufficiently small to allow computation of: | ||
446 | // m1+m2 mod n == (S + a) + (S + b) mod n, | ||
447 | // if we have more complex operations, this factor needs to be lowered | ||
448 | my_offset = gcry_mpi_new (KEYBITS / 3); | ||
449 | gcry_mpi_set_bit (my_offset, KEYBITS / 3); | ||
450 | |||
451 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, _ ("Generated key set with key length %d bits.\n"), KEYBITS); | ||
452 | } | ||
453 | |||
454 | |||
455 | /** | ||
456 | * If target != size, move target bytes to the | ||
457 | * end of the size-sized buffer and zero out the | ||
458 | * first target-size bytes. | ||
459 | * | ||
460 | * @param buf original buffer | ||
461 | * @param size number of bytes in the buffer | ||
462 | * @param target target size of the buffer | ||
463 | */ | ||
464 | static void | ||
465 | adjust (unsigned char *buf, size_t size, size_t target) | ||
466 | { | ||
467 | if (size < target) { | ||
468 | memmove (&buf[target - size], buf, size); | ||
469 | memset (buf, 0, target - size); | ||
470 | } | ||
471 | } | ||
472 | |||
473 | |||
474 | /** | ||
475 | * decrypts an element using the paillier crypto system | ||
476 | * | ||
477 | * @param m plaintext (output) | ||
478 | * @param c the ciphertext | ||
479 | * @param mu the modifier to correct encryption | ||
480 | * @param lambda the private exponent | ||
481 | * @param n the outer module for decryption | ||
482 | * @param n_square the inner module for decryption | ||
483 | */ | ||
484 | static void | ||
485 | decrypt_element (gcry_mpi_t m, gcry_mpi_t c, gcry_mpi_t mu, gcry_mpi_t lambda, gcry_mpi_t n, gcry_mpi_t n_square) | ||
486 | { | ||
487 | gcry_mpi_powm (m, c, lambda, n_square); | ||
488 | gcry_mpi_sub_ui (m, m, 1); | ||
489 | gcry_mpi_div (m, NULL, m, n, 0); | ||
490 | gcry_mpi_mulm (m, m, mu, n); | ||
491 | } | ||
492 | |||
493 | |||
494 | /** | ||
495 | * computes the square sum over a vector of a given length. | 321 | * computes the square sum over a vector of a given length. |
496 | * | 322 | * |
497 | * @param vector the vector to encrypt | 323 | * @param vector the vector to encrypt |
@@ -598,35 +424,6 @@ initialize_mpi_vector (uint32_t length) | |||
598 | 424 | ||
599 | 425 | ||
600 | /** | 426 | /** |
601 | * permutes an MPI vector according to the given permutation vector | ||
602 | * | ||
603 | * @param vector the vector to permuted | ||
604 | * @param perm the permutation to use | ||
605 | * @param length the length of the vectors | ||
606 | * @return the permuted vector (same as input), never NULL | ||
607 | */ | ||
608 | static gcry_mpi_t * | ||
609 | permute_vector (gcry_mpi_t * vector, | ||
610 | unsigned int * perm, | ||
611 | uint32_t length) | ||
612 | { | ||
613 | gcry_mpi_t tmp[length]; | ||
614 | uint32_t i; | ||
615 | |||
616 | GNUNET_assert (length > 0); | ||
617 | |||
618 | // backup old layout | ||
619 | memcpy (tmp, vector, length * sizeof (gcry_mpi_t)); | ||
620 | |||
621 | // permute vector according to given | ||
622 | for (i = 0; i < length; i++) | ||
623 | vector[i] = tmp[perm[i]]; | ||
624 | |||
625 | return vector; | ||
626 | } | ||
627 | |||
628 | |||
629 | /** | ||
630 | * Finds a not terminated client/service session in the | 427 | * Finds a not terminated client/service session in the |
631 | * given DLL based on session key, element count and state. | 428 | * given DLL based on session key, element count and state. |
632 | * | 429 | * |
@@ -664,6 +461,7 @@ find_matching_session (struct ServiceSession * tail, | |||
664 | return NULL; | 461 | return NULL; |
665 | } | 462 | } |
666 | 463 | ||
464 | |||
667 | /** | 465 | /** |
668 | * Safely frees ALL memory areas referenced by a session. | 466 | * Safely frees ALL memory areas referenced by a session. |
669 | * | 467 | * |
@@ -680,40 +478,38 @@ free_session_variables (struct ServiceSession * session) | |||
680 | GNUNET_free (session->a); | 478 | GNUNET_free (session->a); |
681 | session->a = NULL; | 479 | session->a = NULL; |
682 | } | 480 | } |
481 | if (session->e_a) { | ||
482 | GNUNET_free (session->e_a); | ||
483 | session->e_a = NULL; | ||
484 | } | ||
683 | if (session->mask) { | 485 | if (session->mask) { |
684 | GNUNET_free (session->mask); | 486 | GNUNET_free (session->mask); |
685 | session->mask = NULL; | 487 | session->mask = NULL; |
686 | } | 488 | } |
687 | if (session->r) { | 489 | if (session->r) { |
688 | for (i = 0; i < session->used; i++) | ||
689 | if (session->r[i]) gcry_mpi_release (session->r[i]); | ||
690 | GNUNET_free (session->r); | 490 | GNUNET_free (session->r); |
691 | session->r = NULL; | 491 | session->r = NULL; |
692 | } | 492 | } |
693 | if (session->r_prime) { | 493 | if (session->r_prime) { |
694 | for (i = 0; i < session->used; i++) | ||
695 | if (session->r_prime[i]) gcry_mpi_release (session->r_prime[i]); | ||
696 | GNUNET_free (session->r_prime); | 494 | GNUNET_free (session->r_prime); |
697 | session->r_prime = NULL; | 495 | session->r_prime = NULL; |
698 | } | 496 | } |
699 | if (session->s) { | 497 | if (session->s) { |
700 | gcry_mpi_release (session->s); | 498 | GNUNET_free (session->s); |
701 | session->s = NULL; | 499 | session->s = NULL; |
702 | } | 500 | } |
703 | |||
704 | if (session->s_prime) { | 501 | if (session->s_prime) { |
705 | gcry_mpi_release (session->s_prime); | 502 | GNUNET_free (session->s_prime); |
706 | session->s_prime = NULL; | 503 | session->s_prime = NULL; |
707 | } | 504 | } |
708 | |||
709 | if (session->product) { | 505 | if (session->product) { |
710 | gcry_mpi_release (session->product); | 506 | gcry_mpi_release (session->product); |
711 | session->product = NULL; | 507 | session->product = NULL; |
712 | } | 508 | } |
713 | 509 | if (session->remote_pubkey) { | |
714 | memset (&session->remote_pubkey, | 510 | GNUNET_free (session->remote_pubkey); |
715 | 0, | 511 | session->remote_pubkey = NULL; |
716 | sizeof (session->remote_pubkey)); | 512 | } |
717 | if (session->vector) { | 513 | if (session->vector) { |
718 | GNUNET_free_non_null (session->vector); | 514 | GNUNET_free_non_null (session->vector); |
719 | session->s = NULL; | 515 | session->s = NULL; |
@@ -742,7 +538,7 @@ handle_client_disconnect (void *cls, | |||
742 | 538 | ||
743 | if (NULL != client) | 539 | if (NULL != client) |
744 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 540 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
745 | _ ("Client (%p) disconnected from us.\n"), client); | 541 | _ ("Client (%p) disconnected from us.\n"), client); |
746 | else | 542 | else |
747 | return; | 543 | return; |
748 | 544 | ||
@@ -884,8 +680,7 @@ prepare_client_response (void *cls, | |||
884 | msg = GNUNET_malloc (msg_length); | 680 | msg = GNUNET_malloc (msg_length); |
885 | msg->key = session->key; | 681 | msg->key = session->key; |
886 | msg->peer = session->peer; | 682 | msg->peer = session->peer; |
887 | if (product_exported != NULL) | 683 | if (product_exported != NULL) { |
888 | { | ||
889 | memcpy (&msg[1], product_exported, product_length); | 684 | memcpy (&msg[1], product_exported, product_length); |
890 | GNUNET_free (product_exported); | 685 | GNUNET_free (product_exported); |
891 | } | 686 | } |
@@ -931,13 +726,12 @@ static void | |||
931 | prepare_service_response_multipart (void *cls) | 726 | prepare_service_response_multipart (void *cls) |
932 | { | 727 | { |
933 | struct ServiceSession * session = cls; | 728 | struct ServiceSession * session = cls; |
934 | unsigned char * current; | 729 | struct GNUNET_CRYPTO_PaillierCiphertext * payload; |
935 | unsigned char * element_exported; | ||
936 | struct GNUNET_SCALARPRODUCT_multipart_message * msg; | 730 | struct GNUNET_SCALARPRODUCT_multipart_message * msg; |
937 | unsigned int i; | 731 | unsigned int i; |
732 | unsigned int j; | ||
938 | uint32_t msg_length; | 733 | uint32_t msg_length; |
939 | uint32_t todo_count; | 734 | uint32_t todo_count; |
940 | size_t element_length = 0; // initialized by gcry_mpi_print, but the compiler doesn't know that | ||
941 | 735 | ||
942 | msg_length = sizeof (struct GNUNET_SCALARPRODUCT_multipart_message); | 736 | msg_length = sizeof (struct GNUNET_SCALARPRODUCT_multipart_message); |
943 | todo_count = session->used - session->transferred; | 737 | todo_count = session->used - session->transferred; |
@@ -946,41 +740,17 @@ prepare_service_response_multipart (void *cls) | |||
946 | // send the currently possible maximum chunk, we always transfer both permutations | 740 | // send the currently possible maximum chunk, we always transfer both permutations |
947 | todo_count = MULTIPART_ELEMENT_CAPACITY / 2; | 741 | todo_count = MULTIPART_ELEMENT_CAPACITY / 2; |
948 | 742 | ||
949 | msg_length += todo_count * PAILLIER_ELEMENT_LENGTH * 2; | 743 | msg_length += todo_count * sizeof (struct GNUNET_CRYPTO_PaillierCiphertext) * 2; |
950 | msg = GNUNET_malloc (msg_length); | 744 | msg = GNUNET_malloc (msg_length); |
951 | msg->header.type = htons (GNUNET_MESSAGE_TYPE_SCALARPRODUCT_ALICE_TO_BOB_MULTIPART); | 745 | msg->header.type = htons (GNUNET_MESSAGE_TYPE_SCALARPRODUCT_ALICE_TO_BOB_MULTIPART); |
952 | msg->header.size = htons (msg_length); | 746 | msg->header.size = htons (msg_length); |
953 | msg->multipart_element_count = htonl (todo_count); | 747 | msg->multipart_element_count = htonl (todo_count); |
954 | 748 | ||
955 | element_exported = GNUNET_malloc (PAILLIER_ELEMENT_LENGTH); | 749 | payload = (struct GNUNET_CRYPTO_PaillierCiphertext *) &msg[1]; |
956 | current = (unsigned char *) &msg[1]; | 750 | for (i = session->transferred, j=0; i < session->transferred + todo_count; i++) { |
957 | // convert k[][] | 751 | //r[i][p] and r[i][q] |
958 | for (i = session->transferred; i < session->transferred + todo_count; i++) { | 752 | memcpy (&payload[j++], &session->r[i], sizeof (struct GNUNET_CRYPTO_PaillierCiphertext)); |
959 | //k[i][p] | 753 | memcpy (&payload[j++], &session->r_prime[i], sizeof (struct GNUNET_CRYPTO_PaillierCiphertext)); |
960 | memset (element_exported, 0, PAILLIER_ELEMENT_LENGTH); | ||
961 | GNUNET_assert (0 == gcry_mpi_print (GCRYMPI_FMT_USG, | ||
962 | element_exported, PAILLIER_ELEMENT_LENGTH, | ||
963 | &element_length, | ||
964 | session->r[i])); | ||
965 | adjust (element_exported, element_length, PAILLIER_ELEMENT_LENGTH); | ||
966 | memcpy (current, element_exported, PAILLIER_ELEMENT_LENGTH); | ||
967 | current += PAILLIER_ELEMENT_LENGTH; | ||
968 | //k[i][q] | ||
969 | memset (element_exported, 0, PAILLIER_ELEMENT_LENGTH); | ||
970 | GNUNET_assert (0 == gcry_mpi_print (GCRYMPI_FMT_USG, | ||
971 | element_exported, PAILLIER_ELEMENT_LENGTH, | ||
972 | &element_length, | ||
973 | session->r_prime[i])); | ||
974 | adjust (element_exported, element_length, PAILLIER_ELEMENT_LENGTH); | ||
975 | memcpy (current, element_exported, PAILLIER_ELEMENT_LENGTH); | ||
976 | current += PAILLIER_ELEMENT_LENGTH; | ||
977 | } | ||
978 | GNUNET_free (element_exported); | ||
979 | for (i = session->transferred; i < session->transferred; i++) { | ||
980 | gcry_mpi_release (session->r_prime[i]); | ||
981 | session->r_prime[i] = NULL; | ||
982 | gcry_mpi_release (session->r[i]); | ||
983 | session->r[i] = NULL; | ||
984 | } | 754 | } |
985 | session->transferred += todo_count; | 755 | session->transferred += todo_count; |
986 | session->msg = (struct GNUNET_MessageHeader *) msg; | 756 | session->msg = (struct GNUNET_MessageHeader *) msg; |
@@ -1004,11 +774,11 @@ prepare_service_response_multipart (void *cls) | |||
1004 | if (session->transferred != session->used) | 774 | if (session->transferred != session->used) |
1005 | // more multiparts | 775 | // more multiparts |
1006 | session->state = WAITING_FOR_MULTIPART_TRANSMISSION; | 776 | session->state = WAITING_FOR_MULTIPART_TRANSMISSION; |
1007 | else{ | 777 | else { |
1008 | // final part | 778 | // final part |
1009 | session->state = FINALIZED; | 779 | session->state = FINALIZED; |
1010 | GNUNET_free(session->r); | 780 | GNUNET_free (session->r_prime); |
1011 | GNUNET_free(session->r_prime); | 781 | GNUNET_free (session->r); |
1012 | session->r_prime = NULL; | 782 | session->r_prime = NULL; |
1013 | session->r = NULL; | 783 | session->r = NULL; |
1014 | } | 784 | } |
@@ -1024,34 +794,29 @@ prepare_service_response_multipart (void *cls) | |||
1024 | * S: $S := E_A(sum (r_i + b_i)^2)$ | 794 | * S: $S := E_A(sum (r_i + b_i)^2)$ |
1025 | * S': $S' := E_A(sum r_i^2)$ | 795 | * S': $S' := E_A(sum r_i^2)$ |
1026 | * | 796 | * |
1027 | * @param s S: $S := E_A(sum (r_i + b_i)^2)$ | ||
1028 | * @param s_prime S': $S' := E_A(sum r_i^2)$ | ||
1029 | * @param session the associated requesting session with alice | 797 | * @param session the associated requesting session with alice |
1030 | * @return #GNUNET_NO if we could not send our message | 798 | * @return #GNUNET_NO if we could not send our message |
1031 | * #GNUNET_OK if the operation succeeded | 799 | * #GNUNET_OK if the operation succeeded |
1032 | */ | 800 | */ |
1033 | static int | 801 | static int |
1034 | prepare_service_response (gcry_mpi_t s, | 802 | prepare_service_response (struct ServiceSession * session) |
1035 | gcry_mpi_t s_prime, | ||
1036 | struct ServiceSession * session) | ||
1037 | { | 803 | { |
1038 | struct GNUNET_SCALARPRODUCT_service_response * msg; | 804 | struct GNUNET_SCALARPRODUCT_service_response * msg; |
1039 | uint32_t msg_length = 0; | 805 | uint32_t msg_length = 0; |
1040 | unsigned char * current = NULL; | 806 | struct GNUNET_CRYPTO_PaillierCiphertext * payload; |
1041 | unsigned char * element_exported = NULL; | ||
1042 | size_t element_length = 0; | ||
1043 | int i; | 807 | int i; |
1044 | 808 | ||
1045 | msg_length = sizeof (struct GNUNET_SCALARPRODUCT_service_response) | 809 | msg_length = sizeof (struct GNUNET_SCALARPRODUCT_service_response) |
1046 | + 2 * PAILLIER_ELEMENT_LENGTH; // s, stick | 810 | + 2 * sizeof (struct GNUNET_CRYPTO_PaillierCiphertext); // s, stick |
1047 | 811 | ||
1048 | if (GNUNET_SERVER_MAX_MESSAGE_SIZE > msg_length + 2 * session->used * PAILLIER_ELEMENT_LENGTH) { //kp, kq | 812 | if (GNUNET_SERVER_MAX_MESSAGE_SIZE > |
1049 | msg_length += +2 * session->used * PAILLIER_ELEMENT_LENGTH; | 813 | msg_length + 2 * session->used * sizeof (struct GNUNET_CRYPTO_PaillierCiphertext)) { //r, r' |
814 | msg_length += 2 * session->used * sizeof (struct GNUNET_CRYPTO_PaillierCiphertext); | ||
1050 | session->transferred = session->used; | 815 | session->transferred = session->used; |
1051 | } | 816 | } |
1052 | else { | 817 | else |
1053 | session->transferred = (GNUNET_SERVER_MAX_MESSAGE_SIZE - 1 - msg_length) / (PAILLIER_ELEMENT_LENGTH * 2); | 818 | session->transferred = (GNUNET_SERVER_MAX_MESSAGE_SIZE - 1 - msg_length) / |
1054 | } | 819 | (sizeof (struct GNUNET_CRYPTO_PaillierCiphertext) * 2); |
1055 | 820 | ||
1056 | msg = GNUNET_malloc (msg_length); | 821 | msg = GNUNET_malloc (msg_length); |
1057 | 822 | ||
@@ -1061,65 +826,21 @@ prepare_service_response (gcry_mpi_t s, | |||
1061 | msg->used_element_count = htonl (session->used); | 826 | msg->used_element_count = htonl (session->used); |
1062 | msg->contained_element_count = htonl (session->transferred); | 827 | msg->contained_element_count = htonl (session->transferred); |
1063 | memcpy (&msg->key, &session->key, sizeof (struct GNUNET_HashCode)); | 828 | memcpy (&msg->key, &session->key, sizeof (struct GNUNET_HashCode)); |
1064 | current = (unsigned char *) &msg[1]; | ||
1065 | |||
1066 | element_exported = GNUNET_malloc (PAILLIER_ELEMENT_LENGTH); | ||
1067 | // 4 times the same logics with slight variations. | ||
1068 | // doesn't really justify having 2 functions for that | ||
1069 | // so i put it into blocks to enhance readability | ||
1070 | // convert s | ||
1071 | memset (element_exported, 0, PAILLIER_ELEMENT_LENGTH); | ||
1072 | GNUNET_assert (0 == gcry_mpi_print (GCRYMPI_FMT_USG, | ||
1073 | element_exported, PAILLIER_ELEMENT_LENGTH, | ||
1074 | &element_length, | ||
1075 | s)); | ||
1076 | adjust (element_exported, element_length, PAILLIER_ELEMENT_LENGTH); | ||
1077 | memcpy (current, element_exported, PAILLIER_ELEMENT_LENGTH); | ||
1078 | current += PAILLIER_ELEMENT_LENGTH; | ||
1079 | |||
1080 | // convert stick | ||
1081 | memset (element_exported, 0, PAILLIER_ELEMENT_LENGTH); | ||
1082 | GNUNET_assert (0 == gcry_mpi_print (GCRYMPI_FMT_USG, | ||
1083 | element_exported, PAILLIER_ELEMENT_LENGTH, | ||
1084 | &element_length, | ||
1085 | s_prime)); | ||
1086 | adjust (element_exported, element_length, PAILLIER_ELEMENT_LENGTH); | ||
1087 | memcpy (current, element_exported, PAILLIER_ELEMENT_LENGTH); | ||
1088 | current += PAILLIER_ELEMENT_LENGTH; | ||
1089 | 829 | ||
830 | payload = (struct GNUNET_CRYPTO_PaillierCiphertext *) &msg[1]; | ||
831 | memcpy (&payload[0], session->s, sizeof (struct GNUNET_CRYPTO_PaillierCiphertext)); | ||
832 | memcpy (&payload[1], session->s_prime, sizeof (struct GNUNET_CRYPTO_PaillierCiphertext)); | ||
833 | GNUNET_free (session->s_prime); | ||
834 | session->s_prime = NULL; | ||
835 | GNUNET_free (session->s); | ||
836 | session->s = NULL; | ||
837 | |||
1090 | // convert k[][] | 838 | // convert k[][] |
1091 | for (i = 0; i < session->transferred; i++) { | 839 | for (i = 0; i < session->transferred; i++) { |
1092 | //k[i][p] | 840 | //k[i][p] and k[i][q] |
1093 | memset (element_exported, 0, PAILLIER_ELEMENT_LENGTH); | 841 | memcpy (&payload[2 + i*2], &session->r[i], sizeof (struct GNUNET_CRYPTO_PaillierCiphertext)); |
1094 | GNUNET_assert (0 == gcry_mpi_print (GCRYMPI_FMT_USG, | 842 | memcpy (&payload[3 + i*2], &session->r_prime[i], sizeof (struct GNUNET_CRYPTO_PaillierCiphertext)); |
1095 | element_exported, PAILLIER_ELEMENT_LENGTH, | ||
1096 | &element_length, | ||
1097 | session->r[i])); | ||
1098 | adjust (element_exported, element_length, PAILLIER_ELEMENT_LENGTH); | ||
1099 | memcpy (current, element_exported, PAILLIER_ELEMENT_LENGTH); | ||
1100 | current += PAILLIER_ELEMENT_LENGTH; | ||
1101 | //k[i][q] | ||
1102 | memset (element_exported, 0, PAILLIER_ELEMENT_LENGTH); | ||
1103 | GNUNET_assert (0 == gcry_mpi_print (GCRYMPI_FMT_USG, | ||
1104 | element_exported, PAILLIER_ELEMENT_LENGTH, | ||
1105 | &element_length, | ||
1106 | session->r_prime[i])); | ||
1107 | adjust (element_exported, element_length, PAILLIER_ELEMENT_LENGTH); | ||
1108 | memcpy (current, element_exported, PAILLIER_ELEMENT_LENGTH); | ||
1109 | current += PAILLIER_ELEMENT_LENGTH; | ||
1110 | } | ||
1111 | |||
1112 | GNUNET_free (element_exported); | ||
1113 | for (i = 0; i < session->transferred; i++) { | ||
1114 | gcry_mpi_release (session->r_prime[i]); | ||
1115 | session->r_prime[i] = NULL; | ||
1116 | gcry_mpi_release (session->r[i]); | ||
1117 | session->r[i] = NULL; | ||
1118 | } | 843 | } |
1119 | gcry_mpi_release (s); | ||
1120 | session->s = NULL; | ||
1121 | gcry_mpi_release (s_prime); | ||
1122 | session->s_prime = NULL; | ||
1123 | 844 | ||
1124 | session->msg = (struct GNUNET_MessageHeader *) msg; | 845 | session->msg = (struct GNUNET_MessageHeader *) msg; |
1125 | session->service_transmit_handle = | 846 | session->service_transmit_handle = |
@@ -1142,13 +863,13 @@ prepare_service_response (gcry_mpi_t s, | |||
1142 | if (session->transferred != session->used) | 863 | if (session->transferred != session->used) |
1143 | // multipart | 864 | // multipart |
1144 | session->state = WAITING_FOR_MULTIPART_TRANSMISSION; | 865 | session->state = WAITING_FOR_MULTIPART_TRANSMISSION; |
1145 | else{ | 866 | else { |
1146 | //singlepart | 867 | //singlepart |
1147 | session->state = FINALIZED; | 868 | session->state = FINALIZED; |
1148 | GNUNET_free(session->r); | 869 | GNUNET_free (session->r); |
1149 | GNUNET_free(session->r_prime); | ||
1150 | session->r_prime = NULL; | ||
1151 | session->r = NULL; | 870 | session->r = NULL; |
871 | GNUNET_free (session->r_prime); | ||
872 | session->r_prime = NULL; | ||
1152 | } | 873 | } |
1153 | 874 | ||
1154 | return GNUNET_OK; | 875 | return GNUNET_OK; |
@@ -1179,59 +900,42 @@ compute_service_response (struct ServiceSession * request, | |||
1179 | unsigned int * q; | 900 | unsigned int * q; |
1180 | uint32_t count; | 901 | uint32_t count; |
1181 | gcry_mpi_t * rand = NULL; | 902 | gcry_mpi_t * rand = NULL; |
1182 | gcry_mpi_t * r = NULL; | 903 | gcry_mpi_t tmp; |
1183 | struct GNUNET_CRYPTO_PaillierCiphertext * R; | ||
1184 | gcry_mpi_t * r_prime = NULL; | ||
1185 | struct GNUNET_CRYPTO_PaillierCiphertext * R_prime; | ||
1186 | gcry_mpi_t * b; | 904 | gcry_mpi_t * b; |
1187 | gcry_mpi_t * a_pi; | 905 | struct GNUNET_CRYPTO_PaillierCiphertext * a; |
1188 | gcry_mpi_t * a_pi_prime; | 906 | struct GNUNET_CRYPTO_PaillierCiphertext * r; |
1189 | gcry_mpi_t * b_pi; | 907 | struct GNUNET_CRYPTO_PaillierCiphertext * r_prime; |
1190 | gcry_mpi_t * rand_pi; | 908 | struct GNUNET_CRYPTO_PaillierCiphertext * s; |
1191 | gcry_mpi_t * rand_pi_prime; | 909 | struct GNUNET_CRYPTO_PaillierCiphertext * s_prime; |
1192 | gcry_mpi_t * s = NULL; | ||
1193 | struct GNUNET_CRYPTO_PaillierCiphertext * S; | ||
1194 | gcry_mpi_t s_prime = NULL; | ||
1195 | struct GNUNET_CRYPTO_PaillierCiphertext * S_prime; | ||
1196 | |||
1197 | uint32_t value; | 910 | uint32_t value; |
1198 | 911 | ||
1199 | count = request->used; | 912 | count = request->used; |
1200 | 913 | a = request->e_a; | |
1201 | b = GNUNET_malloc (sizeof (gcry_mpi_t) * count); | 914 | b = initialize_mpi_vector (count); |
1202 | a_pi = GNUNET_malloc (sizeof (gcry_mpi_t) * count); | 915 | q = GNUNET_CRYPTO_random_permute (GNUNET_CRYPTO_QUALITY_WEAK, count); |
1203 | b_pi = GNUNET_malloc (sizeof (gcry_mpi_t) * count); | 916 | p = GNUNET_CRYPTO_random_permute (GNUNET_CRYPTO_QUALITY_WEAK, count); |
1204 | a_pi_prime = GNUNET_malloc (sizeof (gcry_mpi_t) * count); | 917 | rand = initialize_mpi_vector (count); |
1205 | rand_pi = GNUNET_malloc (sizeof (gcry_mpi_t) * count); | 918 | r = GNUNET_malloc (sizeof (struct GNUNET_CRYPTO_PaillierCiphertext) * count); |
1206 | rand_pi_prime = GNUNET_malloc (sizeof (gcry_mpi_t) * count); | 919 | r_prime = GNUNET_malloc (sizeof (struct GNUNET_CRYPTO_PaillierCiphertext) * count); |
920 | s = GNUNET_malloc (sizeof (struct GNUNET_CRYPTO_PaillierCiphertext)); | ||
921 | s_prime = GNUNET_malloc (sizeof (struct GNUNET_CRYPTO_PaillierCiphertext)); | ||
1207 | 922 | ||
1208 | // convert responder session to from long to mpi | 923 | // convert responder session to from long to mpi |
1209 | for (i = 0, j = 0; i < response->total && j < count; i++) | 924 | for (i = 0, j = 0; i < response->total && j < count; i++) { |
1210 | { | 925 | if (request->mask[i / 8] & (1 << (i % 8))) { |
1211 | if (request->mask[i / 8] & (1 << (i % 8))) | ||
1212 | { | ||
1213 | value = response->vector[i] >= 0 ? response->vector[i] : -response->vector[i]; | 926 | value = response->vector[i] >= 0 ? response->vector[i] : -response->vector[i]; |
1214 | // long to gcry_mpi_t | 927 | // long to gcry_mpi_t |
1215 | if (0 > response->vector[i]) | 928 | if (0 > response->vector[i]) |
1216 | { | ||
1217 | b[j] = gcry_mpi_new (0); | ||
1218 | gcry_mpi_sub_ui (b[j], b[j], value); | 929 | gcry_mpi_sub_ui (b[j], b[j], value); |
1219 | } | 930 | else |
1220 | else { | 931 | b[j] = gcry_mpi_set_ui (b[j], value); |
1221 | b[j] = gcry_mpi_set_ui (NULL, value); | ||
1222 | } | ||
1223 | j++; | 932 | j++; |
1224 | } | 933 | } |
1225 | } | 934 | } |
1226 | GNUNET_free (response->vector); | 935 | GNUNET_free (response->vector); |
1227 | response->vector = NULL; | 936 | response->vector = NULL; |
1228 | q = NULL; | ||
1229 | p = NULL; | ||
1230 | 937 | ||
1231 | // generate r, p and q | 938 | for (i = 0; i < count; i++) { |
1232 | rand = initialize_mpi_vector (count); | ||
1233 | for (i = 0; i < count; i++) | ||
1234 | { | ||
1235 | int32_t svalue; | 939 | int32_t svalue; |
1236 | 940 | ||
1237 | svalue = (int32_t) GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK, UINT32_MAX); | 941 | svalue = (int32_t) GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK, UINT32_MAX); |
@@ -1244,120 +948,88 @@ compute_service_response (struct ServiceSession * request, | |||
1244 | else | 948 | else |
1245 | rand[i] = gcry_mpi_set_ui (rand[i], svalue); | 949 | rand[i] = gcry_mpi_set_ui (rand[i], svalue); |
1246 | } | 950 | } |
1247 | p = GNUNET_CRYPTO_random_permute (GNUNET_CRYPTO_QUALITY_WEAK, count); | ||
1248 | q = GNUNET_CRYPTO_random_permute (GNUNET_CRYPTO_QUALITY_WEAK, count); | ||
1249 | //initialize the result vectors | ||
1250 | r = initialize_mpi_vector (count); | ||
1251 | r_prime = initialize_mpi_vector (count); | ||
1252 | |||
1253 | // copy the REFERNCES of a, b and r into aq and bq. we will not change | ||
1254 | // those values, thus we can work with the references | ||
1255 | memcpy (a_pi, request->a, sizeof (gcry_mpi_t) * count); | ||
1256 | memcpy (a_pi_prime, request->a, sizeof (gcry_mpi_t) * count); | ||
1257 | memcpy (b_pi, b, sizeof (gcry_mpi_t) * count); | ||
1258 | memcpy (rand_pi, rand, sizeof (gcry_mpi_t) * count); | ||
1259 | memcpy (rand_pi_prime, rand, sizeof (gcry_mpi_t) * count); | ||
1260 | |||
1261 | //todo get API-cryptoblocks, instead of MPI values | ||
1262 | |||
1263 | // generate p and q permutations for a, b and r | ||
1264 | // TODO: APIify | ||
1265 | GNUNET_assert (permute_vector (a_pi, p, count)); | ||
1266 | GNUNET_assert (permute_vector (b_pi, p, count)); | ||
1267 | GNUNET_assert (permute_vector (rand_pi, p, count)); | ||
1268 | GNUNET_assert (permute_vector (a_pi_prime, q, count)); | ||
1269 | GNUNET_assert (permute_vector (rand_pi_prime, q, count)); | ||
1270 | 951 | ||
952 | tmp = gcry_mpi_new (0); | ||
1271 | // encrypt the element | 953 | // encrypt the element |
1272 | // for the sake of readability I decided to have dedicated permutation | 954 | // for the sake of readability I decided to have dedicated permutation |
1273 | // vectors, which get rid of all the lookups in p/q. | 955 | // vectors, which get rid of all the lookups in p/q. |
1274 | // however, ap/aq are not absolutely necessary but are just abstraction | 956 | // however, ap/aq are not absolutely necessary but are just abstraction |
1275 | // Calculate Kp = E(S + a_pi) (+) E(S - r_pi - b_pi) | 957 | // Calculate Kp = E(S + a_pi) (+) E(S - r_pi - b_pi) |
1276 | for (i = 0; i < count; i++) | 958 | for (i = 0; i < count; i++) { |
1277 | { | ||
1278 | // E(S - r_pi - b_pi) | 959 | // E(S - r_pi - b_pi) |
1279 | gcry_mpi_sub (r[i], my_offset, rand_pi[i]); | 960 | gcry_mpi_sub (tmp, my_offset, rand[p[i]]); |
1280 | gcry_mpi_sub (r[i], r[i], b_pi[i]); | 961 | gcry_mpi_sub (tmp, tmp, b[p[i]]); |
1281 | GNUNET_CRYPTO_paillier_encrypt (&request->remote_pubkey, | 962 | GNUNET_CRYPTO_paillier_encrypt (request->remote_pubkey, |
1282 | r[i], | 963 | tmp, |
1283 | 2, | 964 | 2, |
1284 | &R[i]); | 965 | &r[i]); |
1285 | 966 | ||
1286 | // E(S - r_pi - b_pi) * E(S + a_pi) == E(2*S + a - r - b) | 967 | // E(S - r_pi - b_pi) * E(S + a_pi) == E(2*S + a - r - b) |
1287 | GNUNET_CRYPTO_paillier_hom_add (&request->remote_pubkey, | 968 | GNUNET_CRYPTO_paillier_hom_add (request->remote_pubkey, |
1288 | &R[i], | 969 | &r[i], |
1289 | &a_pi[i], | 970 | &a[p[i]], |
1290 | &R[i]); | 971 | &r[i]); |
1291 | } | 972 | } |
1292 | GNUNET_free (a_pi); | ||
1293 | GNUNET_free (b_pi); | ||
1294 | GNUNET_free (rand_pi); | ||
1295 | 973 | ||
1296 | // Calculate Kq = E(S + a_qi) (+) E(S - r_qi) | 974 | // Calculate Kq = E(S + a_qi) (+) E(S - r_qi) |
1297 | for (i = 0; i < count; i++) | 975 | for (i = 0; i < count; i++) { |
1298 | { | ||
1299 | // E(S - r_qi) | 976 | // E(S - r_qi) |
1300 | gcry_mpi_sub (r_prime[i], my_offset, rand_pi_prime[i]); | 977 | gcry_mpi_sub (tmp, my_offset, rand[q[i]]); |
1301 | GNUNET_CRYPTO_paillier_encrypt (&request->remote_pubkey, | 978 | GNUNET_assert (2 == GNUNET_CRYPTO_paillier_encrypt (request->remote_pubkey, |
1302 | r_prime[i], | 979 | tmp, |
1303 | 2, | 980 | 2, |
1304 | &R_prime[i]); | 981 | &r_prime[i])); |
1305 | 982 | ||
1306 | // E(S - r_qi) * E(S + a_qi) == E(2*S + a_qi - r_qi) | 983 | // E(S - r_qi) * E(S + a_qi) == E(2*S + a_qi - r_qi) |
1307 | GNUNET_CRYPTO_paillier_hom_add (&request->remote_pubkey, | 984 | GNUNET_assert (1 == GNUNET_CRYPTO_paillier_hom_add (request->remote_pubkey, |
1308 | &R_prime[i], | 985 | &r_prime[i], |
1309 | &a_pi_prime[i], | 986 | &a[q[i]], |
1310 | &R_prime[i]); | 987 | &r_prime[i])); |
1311 | } | 988 | } |
1312 | GNUNET_free (a_pi_prime); | ||
1313 | GNUNET_free (rand_pi_prime); | ||
1314 | |||
1315 | request->r = r; | ||
1316 | request->r_prime = r_prime; | ||
1317 | request->response = response; | ||
1318 | 989 | ||
1319 | // Calculate S' = E(SUM( r_i^2 )) | 990 | // Calculate S' = E(SUM( r_i^2 )) |
1320 | s_prime = compute_square_sum (rand, count); | 991 | tmp = compute_square_sum (rand, count); |
1321 | GNUNET_CRYPTO_paillier_encrypt (&request->remote_pubkey, | 992 | GNUNET_CRYPTO_paillier_encrypt (request->remote_pubkey, |
1322 | s_prime, | 993 | tmp, |
1323 | 1, | 994 | 1, |
1324 | &S_prime); | 995 | s_prime); |
1325 | 996 | ||
1326 | // Calculate S = E(SUM( (r_i + b_i)^2 )) | 997 | // Calculate S = E(SUM( (r_i + b_i)^2 )) |
1327 | for (i = 0; i < count; i++) { | 998 | for (i = 0; i < count; i++) |
1328 | gcry_mpi_add (rand[i], rand[i], b[i]); | 999 | gcry_mpi_add (rand[i], rand[i], b[i]); |
1329 | } | 1000 | tmp = compute_square_sum (rand, count); |
1330 | s = compute_square_sum (rand, count); | 1001 | GNUNET_CRYPTO_paillier_encrypt (request->remote_pubkey, |
1331 | GNUNET_CRYPTO_paillier_encrypt (&request->remote_pubkey, | 1002 | tmp, |
1332 | s[i], | ||
1333 | 1, | 1003 | 1, |
1334 | &S); | 1004 | s); |
1335 | 1005 | ||
1336 | // release r and tmp | 1006 | request->r = r; |
1337 | for (i = 0; i < count; i++) | 1007 | request->r_prime = r_prime; |
1338 | // rp, rq, aq, ap, bp, bq are released along with a, r, b respectively, (a and b are handled at except:) | 1008 | request->s = s; |
1009 | request->s_prime = s_prime; | ||
1010 | request->response = response; | ||
1011 | |||
1012 | // release rand, b and a | ||
1013 | for (i = 0; i < count; i++) { | ||
1339 | gcry_mpi_release (rand[i]); | 1014 | gcry_mpi_release (rand[i]); |
1015 | gcry_mpi_release (b[i]); | ||
1016 | gcry_mpi_release (request->a[i]); | ||
1017 | } | ||
1018 | gcry_mpi_release (tmp); | ||
1019 | GNUNET_free (request->a); | ||
1020 | request->a = NULL; | ||
1021 | GNUNET_free (p); | ||
1022 | GNUNET_free (q); | ||
1023 | GNUNET_free (b); | ||
1024 | GNUNET_free (rand); | ||
1340 | 1025 | ||
1341 | // copy the r[], r_prime[], S and Stick into a new message, prepare_service_response frees these | 1026 | // copy the r[], r_prime[], S and Stick into a new message, prepare_service_response frees these |
1342 | if (GNUNET_YES != prepare_service_response (S, S_prime, request)) | 1027 | if (GNUNET_YES != prepare_service_response (request)) |
1343 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, _ ("Failed to communicate with `%s', scalar product calculation aborted.\n"), | 1028 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, _ ("Failed to communicate with `%s', scalar product calculation aborted.\n"), |
1344 | GNUNET_i2s (&request->peer)); | 1029 | GNUNET_i2s (&request->peer)); |
1345 | else | 1030 | else |
1346 | ret = GNUNET_OK; | 1031 | ret = GNUNET_OK; |
1347 | 1032 | ||
1348 | except: | ||
1349 | for (i = 0; i < count; i++) | ||
1350 | { | ||
1351 | gcry_mpi_release (b[i]); | ||
1352 | gcry_mpi_release (request->a[i]); | ||
1353 | } | ||
1354 | |||
1355 | GNUNET_free (b); | ||
1356 | GNUNET_free (request->a); | ||
1357 | request->a = NULL; | ||
1358 | GNUNET_free_non_null (p); | ||
1359 | GNUNET_free_non_null (q); | ||
1360 | GNUNET_free (rand); | ||
1361 | return ret; | 1033 | return ret; |
1362 | } | 1034 | } |
1363 | 1035 | ||
@@ -1375,14 +1047,12 @@ static void | |||
1375 | prepare_service_request_multipart (void *cls) | 1047 | prepare_service_request_multipart (void *cls) |
1376 | { | 1048 | { |
1377 | struct ServiceSession * session = cls; | 1049 | struct ServiceSession * session = cls; |
1378 | unsigned char * current; | ||
1379 | unsigned char * element_exported; | ||
1380 | struct GNUNET_SCALARPRODUCT_multipart_message * msg; | 1050 | struct GNUNET_SCALARPRODUCT_multipart_message * msg; |
1051 | struct GNUNET_CRYPTO_PaillierCiphertext * payload; | ||
1381 | unsigned int i; | 1052 | unsigned int i; |
1382 | unsigned int j; | 1053 | unsigned int j; |
1383 | uint32_t msg_length; | 1054 | uint32_t msg_length; |
1384 | uint32_t todo_count; | 1055 | uint32_t todo_count; |
1385 | size_t element_length = 0; // initialized by gcry_mpi_print, but the compiler doesn't know that | ||
1386 | gcry_mpi_t a; | 1056 | gcry_mpi_t a; |
1387 | uint32_t value; | 1057 | uint32_t value; |
1388 | 1058 | ||
@@ -1393,24 +1063,21 @@ prepare_service_request_multipart (void *cls) | |||
1393 | // send the currently possible maximum chunk | 1063 | // send the currently possible maximum chunk |
1394 | todo_count = MULTIPART_ELEMENT_CAPACITY; | 1064 | todo_count = MULTIPART_ELEMENT_CAPACITY; |
1395 | 1065 | ||
1396 | msg_length += todo_count * PAILLIER_ELEMENT_LENGTH; | 1066 | msg_length += todo_count * sizeof(struct GNUNET_CRYPTO_PaillierCiphertext); |
1397 | msg = GNUNET_malloc (msg_length); | 1067 | msg = GNUNET_malloc (msg_length); |
1398 | msg->header.type = htons (GNUNET_MESSAGE_TYPE_SCALARPRODUCT_ALICE_TO_BOB_MULTIPART); | 1068 | msg->header.type = htons (GNUNET_MESSAGE_TYPE_SCALARPRODUCT_ALICE_TO_BOB_MULTIPART); |
1399 | msg->header.size = htons (msg_length); | 1069 | msg->header.size = htons (msg_length); |
1400 | msg->multipart_element_count = htonl (todo_count); | 1070 | msg->multipart_element_count = htonl (todo_count); |
1401 | 1071 | ||
1402 | element_exported = GNUNET_malloc (PAILLIER_ELEMENT_LENGTH); | 1072 | a = gcry_mpi_new (0); |
1403 | a = gcry_mpi_new (KEYBITS * 2); | 1073 | payload = (struct GNUNET_CRYPTO_PaillierCiphertext *) &msg[1]; |
1404 | current = (unsigned char *) &msg[1]; | ||
1405 | // encrypt our vector and generate string representations | 1074 | // encrypt our vector and generate string representations |
1406 | for (i = session->last_processed, j = 0; i < session->total; i++) | 1075 | for (i = session->last_processed, j = 0; i < session->total; i++) { |
1407 | { | ||
1408 | // is this a used element? | 1076 | // is this a used element? |
1409 | if (session->mask[i / 8] & 1 << (i % 8)) { | 1077 | if (session->mask[i / 8] & 1 << (i % 8)) { |
1410 | if (todo_count <= j) | 1078 | if (todo_count <= j) |
1411 | break; //reached end of this message, can't include more | 1079 | break; //reached end of this message, can't include more |
1412 | 1080 | ||
1413 | memset (element_exported, 0, PAILLIER_ELEMENT_LENGTH); | ||
1414 | value = session->vector[i] >= 0 ? session->vector[i] : -session->vector[i]; | 1081 | value = session->vector[i] >= 0 ? session->vector[i] : -session->vector[i]; |
1415 | 1082 | ||
1416 | a = gcry_mpi_set_ui (a, 0); | 1083 | a = gcry_mpi_set_ui (a, 0); |
@@ -1420,27 +1087,12 @@ prepare_service_request_multipart (void *cls) | |||
1420 | else | 1087 | else |
1421 | gcry_mpi_add_ui (a, a, value); | 1088 | gcry_mpi_add_ui (a, a, value); |
1422 | 1089 | ||
1423 | session->a[session->transferred + j++] = gcry_mpi_set (NULL, a); | 1090 | session->a[session->transferred + j] = gcry_mpi_set (NULL, a); |
1424 | gcry_mpi_add (a, a, my_offset); | 1091 | gcry_mpi_add (a, a, my_offset); |
1425 | // FIXME: encrypt_element (a, a, my_g, my_n, my_nsquare); | 1092 | GNUNET_CRYPTO_paillier_encrypt (&my_pubkey, a, 3, &payload[j++]); |
1426 | |||
1427 | // get representation as string | ||
1428 | // we always supply some value, so gcry_mpi_print fails only if it can't reserve memory | ||
1429 | GNUNET_assert (!gcry_mpi_print (GCRYMPI_FMT_USG, | ||
1430 | element_exported, PAILLIER_ELEMENT_LENGTH, | ||
1431 | &element_length, | ||
1432 | a)); | ||
1433 | |||
1434 | // move buffer content to the end of the buffer so it can easily be read by libgcrypt. also this now has fixed size | ||
1435 | adjust (element_exported, element_length, PAILLIER_ELEMENT_LENGTH); | ||
1436 | |||
1437 | // copy over to the message | ||
1438 | memcpy (current, element_exported, PAILLIER_ELEMENT_LENGTH); | ||
1439 | current += PAILLIER_ELEMENT_LENGTH; | ||
1440 | } | 1093 | } |
1441 | } | 1094 | } |
1442 | gcry_mpi_release (a); | 1095 | gcry_mpi_release (a); |
1443 | GNUNET_free (element_exported); | ||
1444 | session->transferred += todo_count; | 1096 | session->transferred += todo_count; |
1445 | 1097 | ||
1446 | session->msg = (struct GNUNET_MessageHeader *) msg; | 1098 | session->msg = (struct GNUNET_MessageHeader *) msg; |
@@ -1482,12 +1134,11 @@ prepare_service_request (void *cls, | |||
1482 | { | 1134 | { |
1483 | struct ServiceSession * session = cls; | 1135 | struct ServiceSession * session = cls; |
1484 | unsigned char * current; | 1136 | unsigned char * current; |
1485 | unsigned char * element_exported; | ||
1486 | struct GNUNET_SCALARPRODUCT_service_request * msg; | 1137 | struct GNUNET_SCALARPRODUCT_service_request * msg; |
1138 | struct GNUNET_CRYPTO_PaillierCiphertext * payload; | ||
1487 | unsigned int i; | 1139 | unsigned int i; |
1488 | unsigned int j; | 1140 | unsigned int j; |
1489 | uint32_t msg_length; | 1141 | uint32_t msg_length; |
1490 | size_t element_length = 0; // initialized by gcry_mpi_print, but the compiler doesn't know that | ||
1491 | gcry_mpi_t a; | 1142 | gcry_mpi_t a; |
1492 | uint32_t value; | 1143 | uint32_t value; |
1493 | 1144 | ||
@@ -1496,16 +1147,16 @@ prepare_service_request (void *cls, | |||
1496 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, _ ("Successfully created new channel to peer (%s)!\n"), GNUNET_i2s (&session->peer)); | 1147 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, _ ("Successfully created new channel to peer (%s)!\n"), GNUNET_i2s (&session->peer)); |
1497 | 1148 | ||
1498 | msg_length = sizeof (struct GNUNET_SCALARPRODUCT_service_request) | 1149 | msg_length = sizeof (struct GNUNET_SCALARPRODUCT_service_request) |
1499 | +session->mask_length | 1150 | + session->mask_length |
1500 | + my_pubkey_external_length; | 1151 | + sizeof(struct GNUNET_CRYPTO_PaillierPublicKey); |
1501 | 1152 | ||
1502 | if (GNUNET_SERVER_MAX_MESSAGE_SIZE > msg_length + session->used * PAILLIER_ELEMENT_LENGTH) { | 1153 | if (GNUNET_SERVER_MAX_MESSAGE_SIZE > msg_length + session->used * sizeof(struct GNUNET_CRYPTO_PaillierCiphertext)) { |
1503 | msg_length += session->used * PAILLIER_ELEMENT_LENGTH; | 1154 | msg_length += session->used * sizeof(struct GNUNET_CRYPTO_PaillierCiphertext); |
1504 | session->transferred = session->used; | 1155 | session->transferred = session->used; |
1505 | } | 1156 | } |
1506 | else { | 1157 | else { |
1507 | //create a multipart msg, first we calculate a new msg size for the head msg | 1158 | //create a multipart msg, first we calculate a new msg size for the head msg |
1508 | session->transferred = (GNUNET_SERVER_MAX_MESSAGE_SIZE - 1 - msg_length) / PAILLIER_ELEMENT_LENGTH; | 1159 | session->transferred = (GNUNET_SERVER_MAX_MESSAGE_SIZE - 1 - msg_length) / sizeof(struct GNUNET_CRYPTO_PaillierCiphertext); |
1509 | } | 1160 | } |
1510 | 1161 | ||
1511 | msg = GNUNET_malloc (msg_length); | 1162 | msg = GNUNET_malloc (msg_length); |
@@ -1514,7 +1165,6 @@ prepare_service_request (void *cls, | |||
1514 | msg->contained_element_count = htonl (session->transferred); | 1165 | msg->contained_element_count = htonl (session->transferred); |
1515 | memcpy (&msg->key, &session->key, sizeof (struct GNUNET_HashCode)); | 1166 | memcpy (&msg->key, &session->key, sizeof (struct GNUNET_HashCode)); |
1516 | msg->mask_length = htonl (session->mask_length); | 1167 | msg->mask_length = htonl (session->mask_length); |
1517 | msg->pk_length = htonl (my_pubkey_external_length); | ||
1518 | msg->element_count = htonl (session->total); | 1168 | msg->element_count = htonl (session->total); |
1519 | msg->header.size = htons (msg_length); | 1169 | msg->header.size = htons (msg_length); |
1520 | 1170 | ||
@@ -1524,13 +1174,13 @@ prepare_service_request (void *cls, | |||
1524 | memcpy (current, session->mask, session->mask_length); | 1174 | memcpy (current, session->mask, session->mask_length); |
1525 | // copy over our public key | 1175 | // copy over our public key |
1526 | current += session->mask_length; | 1176 | current += session->mask_length; |
1527 | memcpy (current, my_pubkey_external, my_pubkey_external_length); | 1177 | memcpy (current, &my_pubkey, sizeof(struct GNUNET_CRYPTO_PaillierPublicKey)); |
1528 | current += my_pubkey_external_length; | 1178 | current += sizeof(struct GNUNET_CRYPTO_PaillierPublicKey); |
1179 | payload = (struct GNUNET_CRYPTO_PaillierCiphertext *) current; | ||
1529 | 1180 | ||
1530 | // now copy over the element vector | 1181 | // now copy over the element vector |
1531 | element_exported = GNUNET_malloc (PAILLIER_ELEMENT_LENGTH); | ||
1532 | session->a = GNUNET_malloc (sizeof (gcry_mpi_t) * session->used); | 1182 | session->a = GNUNET_malloc (sizeof (gcry_mpi_t) * session->used); |
1533 | a = gcry_mpi_new (KEYBITS * 2); | 1183 | a = gcry_mpi_new (0); |
1534 | // encrypt our vector and generate string representations | 1184 | // encrypt our vector and generate string representations |
1535 | for (i = 0, j = 0; i < session->total; i++) { | 1185 | for (i = 0, j = 0; i < session->total; i++) { |
1536 | // if this is a used element... | 1186 | // if this is a used element... |
@@ -1538,7 +1188,6 @@ prepare_service_request (void *cls, | |||
1538 | if (session->transferred <= j) | 1188 | if (session->transferred <= j) |
1539 | break; //reached end of this message, can't include more | 1189 | break; //reached end of this message, can't include more |
1540 | 1190 | ||
1541 | memset (element_exported, 0, PAILLIER_ELEMENT_LENGTH); | ||
1542 | value = session->vector[i] >= 0 ? session->vector[i] : -session->vector[i]; | 1191 | value = session->vector[i] >= 0 ? session->vector[i] : -session->vector[i]; |
1543 | 1192 | ||
1544 | a = gcry_mpi_set_ui (a, 0); | 1193 | a = gcry_mpi_set_ui (a, 0); |
@@ -1548,27 +1197,12 @@ prepare_service_request (void *cls, | |||
1548 | else | 1197 | else |
1549 | gcry_mpi_add_ui (a, a, value); | 1198 | gcry_mpi_add_ui (a, a, value); |
1550 | 1199 | ||
1551 | session->a[j++] = gcry_mpi_set (NULL, a); | 1200 | session->a[j] = gcry_mpi_set (NULL, a); |
1552 | gcry_mpi_add (a, a, my_offset); | 1201 | gcry_mpi_add (a, a, my_offset); |
1553 | // FIXME: encrypt_element (a, a, my_g, my_n, my_nsquare); | 1202 | GNUNET_CRYPTO_paillier_encrypt (&my_pubkey, a, 3, &payload[j++]); |
1554 | |||
1555 | // get representation as string | ||
1556 | // we always supply some value, so gcry_mpi_print fails only if it can't reserve memory | ||
1557 | GNUNET_assert (!gcry_mpi_print (GCRYMPI_FMT_USG, | ||
1558 | element_exported, PAILLIER_ELEMENT_LENGTH, | ||
1559 | &element_length, | ||
1560 | a)); | ||
1561 | |||
1562 | // move buffer content to the end of the buffer so it can easily be read by libgcrypt. also this now has fixed size | ||
1563 | adjust (element_exported, element_length, PAILLIER_ELEMENT_LENGTH); | ||
1564 | |||
1565 | // copy over to the message | ||
1566 | memcpy (current, element_exported, PAILLIER_ELEMENT_LENGTH); | ||
1567 | current += PAILLIER_ELEMENT_LENGTH; | ||
1568 | } | 1203 | } |
1569 | } | 1204 | } |
1570 | gcry_mpi_release (a); | 1205 | gcry_mpi_release (a); |
1571 | GNUNET_free (element_exported); | ||
1572 | 1206 | ||
1573 | session->msg = (struct GNUNET_MessageHeader *) msg; | 1207 | session->msg = (struct GNUNET_MessageHeader *) msg; |
1574 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, _ ("Transmitting service request.\n")); | 1208 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, _ ("Transmitting service request.\n")); |
@@ -1650,7 +1284,7 @@ handle_client_request (void *cls, | |||
1650 | if ((ntohs (msg->header.size) != (sizeof (struct GNUNET_SCALARPRODUCT_client_request) +element_count * sizeof (int32_t) + mask_length)) | 1284 | if ((ntohs (msg->header.size) != (sizeof (struct GNUNET_SCALARPRODUCT_client_request) +element_count * sizeof (int32_t) + mask_length)) |
1651 | || (0 == element_count)) { | 1285 | || (0 == element_count)) { |
1652 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | 1286 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, |
1653 | _("Invalid message received from client, session information incorrect!\n")); | 1287 | _ ("Invalid message received from client, session information incorrect!\n")); |
1654 | GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); | 1288 | GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); |
1655 | return; | 1289 | return; |
1656 | } | 1290 | } |
@@ -1661,7 +1295,7 @@ handle_client_request (void *cls, | |||
1661 | element_count, | 1295 | element_count, |
1662 | NULL, NULL)) { | 1296 | NULL, NULL)) { |
1663 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | 1297 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, |
1664 | _("Duplicate session information received, cannot create new session with key `%s'\n"), | 1298 | _ ("Duplicate session information received, cannot create new session with key `%s'\n"), |
1665 | GNUNET_h2s (&msg->key)); | 1299 | GNUNET_h2s (&msg->key)); |
1666 | GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); | 1300 | GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); |
1667 | return; | 1301 | return; |
@@ -1679,10 +1313,9 @@ handle_client_request (void *cls, | |||
1679 | session->vector = GNUNET_malloc (sizeof (int32_t) * element_count); | 1313 | session->vector = GNUNET_malloc (sizeof (int32_t) * element_count); |
1680 | vector = (int32_t *) & msg[1]; | 1314 | vector = (int32_t *) & msg[1]; |
1681 | 1315 | ||
1682 | if (GNUNET_MESSAGE_TYPE_SCALARPRODUCT_CLIENT_TO_ALICE == msg_type) | 1316 | if (GNUNET_MESSAGE_TYPE_SCALARPRODUCT_CLIENT_TO_ALICE == msg_type) { |
1683 | { | ||
1684 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 1317 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
1685 | _("Got client-request-session with key %s, preparing channel to remote service.\n"), | 1318 | _ ("Got client-request-session with key %s, preparing channel to remote service.\n"), |
1686 | GNUNET_h2s (&session->key)); | 1319 | GNUNET_h2s (&session->key)); |
1687 | 1320 | ||
1688 | session->role = ALICE; | 1321 | session->role = ALICE; |
@@ -1692,8 +1325,7 @@ handle_client_request (void *cls, | |||
1692 | 1325 | ||
1693 | // copy over the elements | 1326 | // copy over the elements |
1694 | session->used = 0; | 1327 | session->used = 0; |
1695 | for (i = 0; i < element_count; i++) | 1328 | for (i = 0; i < element_count; i++) { |
1696 | { | ||
1697 | session->vector[i] = ntohl (vector[i]); | 1329 | session->vector[i] = ntohl (vector[i]); |
1698 | if (session->vector[i] == 0) | 1330 | if (session->vector[i] == 0) |
1699 | session->mask[i / 8] &= ~(1 << (i % 8)); | 1331 | session->mask[i / 8] &= ~(1 << (i % 8)); |
@@ -1701,8 +1333,7 @@ handle_client_request (void *cls, | |||
1701 | session->used++; | 1333 | session->used++; |
1702 | } | 1334 | } |
1703 | 1335 | ||
1704 | if (0 == session->used) | 1336 | if (0 == session->used) { |
1705 | { | ||
1706 | GNUNET_break_op (0); | 1337 | GNUNET_break_op (0); |
1707 | GNUNET_free (session->vector); | 1338 | GNUNET_free (session->vector); |
1708 | GNUNET_free (session); | 1339 | GNUNET_free (session); |
@@ -1710,8 +1341,7 @@ handle_client_request (void *cls, | |||
1710 | return; | 1341 | return; |
1711 | } | 1342 | } |
1712 | //session with ourself makes no sense! | 1343 | //session with ourself makes no sense! |
1713 | if (!memcmp (&msg->peer, &me, sizeof (struct GNUNET_PeerIdentity))) | 1344 | if (!memcmp (&msg->peer, &me, sizeof (struct GNUNET_PeerIdentity))) { |
1714 | { | ||
1715 | GNUNET_break (0); | 1345 | GNUNET_break (0); |
1716 | GNUNET_free (session->vector); | 1346 | GNUNET_free (session->vector); |
1717 | GNUNET_free (session); | 1347 | GNUNET_free (session); |
@@ -1724,9 +1354,9 @@ handle_client_request (void *cls, | |||
1724 | _ ("Creating new channel for session with key %s.\n"), | 1354 | _ ("Creating new channel for session with key %s.\n"), |
1725 | GNUNET_h2s (&session->key)); | 1355 | GNUNET_h2s (&session->key)); |
1726 | session->channel = GNUNET_MESH_channel_create (my_mesh, session, | 1356 | session->channel = GNUNET_MESH_channel_create (my_mesh, session, |
1727 | &session->peer, | 1357 | &session->peer, |
1728 | GNUNET_APPLICATION_TYPE_SCALARPRODUCT, | 1358 | GNUNET_APPLICATION_TYPE_SCALARPRODUCT, |
1729 | GNUNET_MESH_OPTION_RELIABLE); | 1359 | GNUNET_MESH_OPTION_RELIABLE); |
1730 | //prepare_service_request, channel_peer_disconnect_handler, | 1360 | //prepare_service_request, channel_peer_disconnect_handler, |
1731 | if (!session->channel) { | 1361 | if (!session->channel) { |
1732 | GNUNET_break (0); | 1362 | GNUNET_break (0); |
@@ -1744,8 +1374,7 @@ handle_client_request (void *cls, | |||
1744 | session); | 1374 | session); |
1745 | 1375 | ||
1746 | } | 1376 | } |
1747 | else | 1377 | else { |
1748 | { | ||
1749 | struct ServiceSession * requesting_session; | 1378 | struct ServiceSession * requesting_session; |
1750 | enum SessionState needed_state = SERVICE_REQUEST_RECEIVED; | 1379 | enum SessionState needed_state = SERVICE_REQUEST_RECEIVED; |
1751 | 1380 | ||
@@ -1765,10 +1394,9 @@ handle_client_request (void *cls, | |||
1765 | &session->key, | 1394 | &session->key, |
1766 | session->total, | 1395 | session->total, |
1767 | &needed_state, NULL); | 1396 | &needed_state, NULL); |
1768 | if (NULL != requesting_session) | 1397 | if (NULL != requesting_session) { |
1769 | { | ||
1770 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, | 1398 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, |
1771 | _("Got client-responder-session with key %s and a matching service-request-session set, processing.\n"), | 1399 | _ ("Got client-responder-session with key %s and a matching service-request-session set, processing.\n"), |
1772 | GNUNET_h2s (&session->key)); | 1400 | GNUNET_h2s (&session->key)); |
1773 | if (GNUNET_OK != compute_service_response (requesting_session, session)) | 1401 | if (GNUNET_OK != compute_service_response (requesting_session, session)) |
1774 | session->client_notification_task = | 1402 | session->client_notification_task = |
@@ -1776,10 +1404,9 @@ handle_client_request (void *cls, | |||
1776 | session); | 1404 | session); |
1777 | 1405 | ||
1778 | } | 1406 | } |
1779 | else | 1407 | else { |
1780 | { | ||
1781 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, | 1408 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, |
1782 | _("Got client-responder-session with key %s but NO matching service-request-session set, queuing element for later use.\n"), | 1409 | _ ("Got client-responder-session with key %s but NO matching service-request-session set, queuing element for later use.\n"), |
1783 | GNUNET_h2s (&session->key)); | 1410 | GNUNET_h2s (&session->key)); |
1784 | // no matching session exists yet, store the response | 1411 | // no matching session exists yet, store the response |
1785 | // for later processing by handle_service_request() | 1412 | // for later processing by handle_service_request() |
@@ -1802,14 +1429,14 @@ handle_client_request (void *cls, | |||
1802 | */ | 1429 | */ |
1803 | static void * | 1430 | static void * |
1804 | channel_incoming_handler (void *cls, | 1431 | channel_incoming_handler (void *cls, |
1805 | struct GNUNET_MESH_Channel *channel, | 1432 | struct GNUNET_MESH_Channel *channel, |
1806 | const struct GNUNET_PeerIdentity *initiator, | 1433 | const struct GNUNET_PeerIdentity *initiator, |
1807 | uint32_t port, enum GNUNET_MESH_ChannelOption options) | 1434 | uint32_t port, enum GNUNET_MESH_ChannelOption options) |
1808 | { | 1435 | { |
1809 | struct ServiceSession * c = GNUNET_new (struct ServiceSession); | 1436 | struct ServiceSession * c = GNUNET_new (struct ServiceSession); |
1810 | 1437 | ||
1811 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 1438 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
1812 | _("New incoming channel from peer %s.\n"), | 1439 | _ ("New incoming channel from peer %s.\n"), |
1813 | GNUNET_i2s (initiator)); | 1440 | GNUNET_i2s (initiator)); |
1814 | 1441 | ||
1815 | c->peer = *initiator; | 1442 | c->peer = *initiator; |
@@ -1833,8 +1460,8 @@ channel_incoming_handler (void *cls, | |||
1833 | */ | 1460 | */ |
1834 | static void | 1461 | static void |
1835 | channel_destruction_handler (void *cls, | 1462 | channel_destruction_handler (void *cls, |
1836 | const struct GNUNET_MESH_Channel *channel, | 1463 | const struct GNUNET_MESH_Channel *channel, |
1837 | void *channel_ctx) | 1464 | void *channel_ctx) |
1838 | { | 1465 | { |
1839 | struct ServiceSession * session = channel_ctx; | 1466 | struct ServiceSession * session = channel_ctx; |
1840 | struct ServiceSession * client_session; | 1467 | struct ServiceSession * client_session; |
@@ -1901,20 +1528,25 @@ compute_scalar_product (struct ServiceSession * session) | |||
1901 | gcry_mpi_t p; | 1528 | gcry_mpi_t p; |
1902 | gcry_mpi_t p_prime; | 1529 | gcry_mpi_t p_prime; |
1903 | gcry_mpi_t tmp; | 1530 | gcry_mpi_t tmp; |
1531 | gcry_mpi_t r[session->used]; | ||
1532 | gcry_mpi_t r_prime[session->used]; | ||
1533 | gcry_mpi_t s; | ||
1534 | gcry_mpi_t s_prime; | ||
1904 | unsigned int i; | 1535 | unsigned int i; |
1905 | 1536 | ||
1906 | count = session->used; | 1537 | count = session->used; |
1907 | // due to the introduced static offset S, we now also have to remove this | 1538 | // due to the introduced static offset S, we now also have to remove this |
1908 | // from the E(a_pi)(+)E(-b_pi-r_pi) and E(a_qi)(+)E(-r_qi) twice each, | 1539 | // from the E(a_pi)(+)E(-b_pi-r_pi) and E(a_qi)(+)E(-r_qi) twice each, |
1909 | // the result is E((S + a_pi) + (S -b_pi-r_pi)) and E(S + a_qi + S - r_qi) | 1540 | // the result is E((S + a_pi) + (S -b_pi-r_pi)) and E(S + a_qi + S - r_qi) |
1910 | for (i = 0; i < count; i++) | 1541 | for (i = 0; i < count; i++) { |
1911 | { | 1542 | GNUNET_CRYPTO_paillier_decrypt (&my_privkey, &my_pubkey, |
1912 | decrypt_element (session->r[i], session->r[i], my_mu, my_lambda, my_n, my_nsquare); | 1543 | &session->r[i], r[i]); |
1913 | gcry_mpi_sub (session->r[i], session->r[i], my_offset); | 1544 | gcry_mpi_sub (r[i], r[i], my_offset); |
1914 | gcry_mpi_sub (session->r[i], session->r[i], my_offset); | 1545 | gcry_mpi_sub (r[i], r[i], my_offset); |
1915 | decrypt_element (session->r_prime[i], session->r_prime[i], my_mu, my_lambda, my_n, my_nsquare); | 1546 | GNUNET_CRYPTO_paillier_decrypt (&my_privkey, &my_pubkey, |
1916 | gcry_mpi_sub (session->r_prime[i], session->r_prime[i], my_offset); | 1547 | &session->r_prime[i], r_prime[i]); |
1917 | gcry_mpi_sub (session->r_prime[i], session->r_prime[i], my_offset); | 1548 | gcry_mpi_sub (r_prime[i], r_prime[i], my_offset); |
1549 | gcry_mpi_sub (r_prime[i], r_prime[i], my_offset); | ||
1918 | } | 1550 | } |
1919 | 1551 | ||
1920 | // calculate t = sum(ai) | 1552 | // calculate t = sum(ai) |
@@ -1922,33 +1554,39 @@ compute_scalar_product (struct ServiceSession * session) | |||
1922 | 1554 | ||
1923 | // calculate U | 1555 | // calculate U |
1924 | u = gcry_mpi_new (0); | 1556 | u = gcry_mpi_new (0); |
1925 | tmp = compute_square_sum (session->r, count); | 1557 | tmp = compute_square_sum (r, count); |
1926 | gcry_mpi_sub (u, u, tmp); | 1558 | gcry_mpi_sub (u, u, tmp); |
1927 | gcry_mpi_release (tmp); | 1559 | gcry_mpi_release (tmp); |
1928 | 1560 | ||
1929 | //calculate U' | 1561 | //calculate U' |
1930 | u_prime = gcry_mpi_new (0); | 1562 | u_prime = gcry_mpi_new (0); |
1931 | tmp = compute_square_sum (session->r_prime, count); | 1563 | tmp = compute_square_sum (r_prime, count); |
1932 | gcry_mpi_sub (u_prime, u_prime, tmp); | 1564 | gcry_mpi_sub (u_prime, u_prime, tmp); |
1933 | 1565 | ||
1934 | GNUNET_assert (p = gcry_mpi_new (0)); | 1566 | GNUNET_assert (p = gcry_mpi_new (0)); |
1935 | GNUNET_assert (p_prime = gcry_mpi_new (0)); | 1567 | GNUNET_assert (p_prime = gcry_mpi_new (0)); |
1568 | GNUNET_assert (s = gcry_mpi_new (0)); | ||
1569 | GNUNET_assert (s_prime = gcry_mpi_new (0)); | ||
1936 | 1570 | ||
1937 | // compute P | 1571 | // compute P |
1938 | decrypt_element (session->s, session->s, my_mu, my_lambda, my_n, my_nsquare); | 1572 | GNUNET_CRYPTO_paillier_decrypt (&my_privkey, &my_pubkey, |
1939 | decrypt_element (session->s_prime, session->s_prime, my_mu, my_lambda, my_n, my_nsquare); | 1573 | session->s, s); |
1574 | GNUNET_CRYPTO_paillier_decrypt (&my_privkey, &my_pubkey, | ||
1575 | session->s_prime, s_prime); | ||
1940 | 1576 | ||
1941 | // compute P | 1577 | // compute P |
1942 | gcry_mpi_add (p, session->s, t); | 1578 | gcry_mpi_add (p, s, t); |
1943 | gcry_mpi_add (p, p, u); | 1579 | gcry_mpi_add (p, p, u); |
1944 | 1580 | ||
1945 | // compute P' | 1581 | // compute P' |
1946 | gcry_mpi_add (p_prime, session->s_prime, t); | 1582 | gcry_mpi_add (p_prime, s_prime, t); |
1947 | gcry_mpi_add (p_prime, p_prime, u_prime); | 1583 | gcry_mpi_add (p_prime, p_prime, u_prime); |
1948 | 1584 | ||
1949 | gcry_mpi_release (t); | 1585 | gcry_mpi_release (t); |
1950 | gcry_mpi_release (u); | 1586 | gcry_mpi_release (u); |
1951 | gcry_mpi_release (u_prime); | 1587 | gcry_mpi_release (u_prime); |
1588 | gcry_mpi_release (s); | ||
1589 | gcry_mpi_release (s_prime); | ||
1952 | 1590 | ||
1953 | // compute product | 1591 | // compute product |
1954 | gcry_mpi_sub (p, p, p_prime); | 1592 | gcry_mpi_sub (p, p, p_prime); |
@@ -1957,10 +1595,21 @@ compute_scalar_product (struct ServiceSession * session) | |||
1957 | gcry_mpi_div (p, NULL, p, tmp, 0); | 1595 | gcry_mpi_div (p, NULL, p, tmp, 0); |
1958 | 1596 | ||
1959 | gcry_mpi_release (tmp); | 1597 | gcry_mpi_release (tmp); |
1960 | for (i = 0; i < count; i++) | 1598 | for (i = 0; i < count; i++){ |
1961 | gcry_mpi_release (session->a[i]); | 1599 | gcry_mpi_release (session->a[i]); |
1600 | gcry_mpi_release (r[i]); | ||
1601 | gcry_mpi_release (r_prime[i]); | ||
1602 | } | ||
1962 | GNUNET_free (session->a); | 1603 | GNUNET_free (session->a); |
1963 | session->a = NULL; | 1604 | session->a = NULL; |
1605 | GNUNET_free (session->s); | ||
1606 | session->s = NULL; | ||
1607 | GNUNET_free (session->s_prime); | ||
1608 | session->s_prime = NULL; | ||
1609 | GNUNET_free (session->r); | ||
1610 | session->r = NULL; | ||
1611 | GNUNET_free (session->r_prime); | ||
1612 | session->r_prime = NULL; | ||
1964 | 1613 | ||
1965 | return p; | 1614 | return p; |
1966 | } | 1615 | } |
@@ -1984,12 +1633,10 @@ handle_service_request_multipart (void *cls, | |||
1984 | { | 1633 | { |
1985 | struct ServiceSession * session; | 1634 | struct ServiceSession * session; |
1986 | const struct GNUNET_SCALARPRODUCT_multipart_message * msg = (const struct GNUNET_SCALARPRODUCT_multipart_message *) message; | 1635 | const struct GNUNET_SCALARPRODUCT_multipart_message * msg = (const struct GNUNET_SCALARPRODUCT_multipart_message *) message; |
1636 | struct GNUNET_CRYPTO_PaillierCiphertext *payload; | ||
1987 | uint32_t used_elements; | 1637 | uint32_t used_elements; |
1988 | uint32_t contained_elements = 0; | 1638 | uint32_t contained_elements = 0; |
1989 | uint32_t msg_length; | 1639 | uint32_t msg_length; |
1990 | unsigned char * current; | ||
1991 | gcry_error_t rc; | ||
1992 | int32_t i = -1; | ||
1993 | 1640 | ||
1994 | // are we in the correct state? | 1641 | // are we in the correct state? |
1995 | session = (struct ServiceSession *) * channel_ctx; | 1642 | session = (struct ServiceSession *) * channel_ctx; |
@@ -2003,34 +1650,24 @@ handle_service_request_multipart (void *cls, | |||
2003 | used_elements = session->used; | 1650 | used_elements = session->used; |
2004 | contained_elements = ntohl (msg->multipart_element_count); | 1651 | contained_elements = ntohl (msg->multipart_element_count); |
2005 | msg_length = sizeof (struct GNUNET_SCALARPRODUCT_multipart_message) | 1652 | msg_length = sizeof (struct GNUNET_SCALARPRODUCT_multipart_message) |
2006 | +contained_elements * PAILLIER_ELEMENT_LENGTH; | 1653 | + contained_elements * sizeof(struct GNUNET_CRYPTO_PaillierCiphertext); |
2007 | //sanity check | 1654 | //sanity check |
2008 | if ((ntohs (msg->header.size) != msg_length) | 1655 | if ((ntohs (msg->header.size) != msg_length) |
2009 | || (used_elements < contained_elements + session->transferred)) { | 1656 | || (used_elements < contained_elements + session->transferred)) { |
2010 | goto except; | 1657 | goto except; |
2011 | } | 1658 | } |
2012 | current = (unsigned char *) &msg[1]; | 1659 | payload = (struct GNUNET_CRYPTO_PaillierCiphertext *) &msg[1]; |
2013 | if (contained_elements != 0) { | 1660 | if (contained_elements != 0) { |
2014 | // Convert each vector element to MPI_value | 1661 | // Convert each vector element to MPI_value |
2015 | for (i = session->transferred; i < session->transferred + contained_elements; i++) { | 1662 | memcpy(&session->e_a[session->transferred], payload, |
2016 | size_t read = 0; | 1663 | sizeof(struct GNUNET_CRYPTO_PaillierCiphertext) * contained_elements); |
2017 | if (0 != (rc = gcry_mpi_scan (&session->a[i], | 1664 | |
2018 | GCRYMPI_FMT_USG, | ||
2019 | ¤t[i * PAILLIER_ELEMENT_LENGTH], | ||
2020 | PAILLIER_ELEMENT_LENGTH, | ||
2021 | &read))) { | ||
2022 | LOG_GCRY (GNUNET_ERROR_TYPE_DEBUG, "gcry_mpi_scan", rc); | ||
2023 | goto except; | ||
2024 | } | ||
2025 | } | ||
2026 | session->transferred += contained_elements; | 1665 | session->transferred += contained_elements; |
2027 | 1666 | ||
2028 | if (session->transferred == used_elements) | 1667 | if (session->transferred == used_elements) { |
2029 | { | ||
2030 | // single part finished | 1668 | // single part finished |
2031 | session->state = SERVICE_REQUEST_RECEIVED; | 1669 | session->state = SERVICE_REQUEST_RECEIVED; |
2032 | if (session->response) | 1670 | if (session->response) { |
2033 | { | ||
2034 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, | 1671 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, |
2035 | _ ("Got session with key %s and a matching element set, processing.\n"), | 1672 | _ ("Got session with key %s and a matching element set, processing.\n"), |
2036 | GNUNET_h2s (&session->key)); | 1673 | GNUNET_h2s (&session->key)); |
@@ -2041,11 +1678,10 @@ handle_service_request_multipart (void *cls, | |||
2041 | } | 1678 | } |
2042 | else | 1679 | else |
2043 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, | 1680 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, |
2044 | _("Got session with key %s without a matching element set, queueing.\n"), | 1681 | _ ("Got session with key %s without a matching element set, queueing.\n"), |
2045 | GNUNET_h2s (&session->key)); | 1682 | GNUNET_h2s (&session->key)); |
2046 | } | 1683 | } |
2047 | else | 1684 | else { |
2048 | { | ||
2049 | // multipart message | 1685 | // multipart message |
2050 | } | 1686 | } |
2051 | } | 1687 | } |
@@ -2084,14 +1720,12 @@ handle_service_request (void *cls, | |||
2084 | struct ServiceSession * session; | 1720 | struct ServiceSession * session; |
2085 | const struct GNUNET_SCALARPRODUCT_service_request * msg = (const struct GNUNET_SCALARPRODUCT_service_request *) message; | 1721 | const struct GNUNET_SCALARPRODUCT_service_request * msg = (const struct GNUNET_SCALARPRODUCT_service_request *) message; |
2086 | uint32_t mask_length; | 1722 | uint32_t mask_length; |
2087 | uint32_t pk_length; | 1723 | struct GNUNET_CRYPTO_PaillierCiphertext *payload; |
2088 | uint32_t used_elements; | 1724 | uint32_t used_elements; |
2089 | uint32_t contained_elements = 0; | 1725 | uint32_t contained_elements = 0; |
2090 | uint32_t element_count; | 1726 | uint32_t element_count; |
2091 | uint32_t msg_length; | 1727 | uint32_t msg_length; |
2092 | unsigned char * current; | 1728 | unsigned char * current; |
2093 | gcry_error_t rc; | ||
2094 | int32_t i = -1; | ||
2095 | enum SessionState needed_state; | 1729 | enum SessionState needed_state; |
2096 | 1730 | ||
2097 | session = (struct ServiceSession *) * channel_ctx; | 1731 | session = (struct ServiceSession *) * channel_ctx; |
@@ -2111,20 +1745,19 @@ handle_service_request (void *cls, | |||
2111 | return GNUNET_SYSERR; | 1745 | return GNUNET_SYSERR; |
2112 | } | 1746 | } |
2113 | mask_length = ntohl (msg->mask_length); | 1747 | mask_length = ntohl (msg->mask_length); |
2114 | pk_length = ntohl (msg->pk_length); | ||
2115 | used_elements = ntohl (msg->total_element_count); | 1748 | used_elements = ntohl (msg->total_element_count); |
2116 | contained_elements = ntohl (msg->contained_element_count); | 1749 | contained_elements = ntohl (msg->contained_element_count); |
2117 | element_count = ntohl (msg->element_count); | 1750 | element_count = ntohl (msg->element_count); |
2118 | msg_length = sizeof (struct GNUNET_SCALARPRODUCT_service_request) | 1751 | msg_length = sizeof (struct GNUNET_SCALARPRODUCT_service_request) |
2119 | +mask_length + pk_length + contained_elements * PAILLIER_ELEMENT_LENGTH; | 1752 | + mask_length + sizeof(struct GNUNET_CRYPTO_PaillierPublicKey) |
1753 | + contained_elements * sizeof(struct GNUNET_CRYPTO_PaillierCiphertext); | ||
2120 | 1754 | ||
2121 | //sanity check: is the message as long as the message_count fields suggests? | 1755 | //sanity check: is the message as long as the message_count fields suggests? |
2122 | if ( (ntohs (msg->header.size) != msg_length) || | 1756 | if ((ntohs (msg->header.size) != msg_length) || |
2123 | (element_count < used_elements) || | 1757 | (element_count < used_elements) || |
2124 | (used_elements < contained_elements) || | 1758 | (used_elements < contained_elements) || |
2125 | (0 == used_elements) || | 1759 | (0 == used_elements) || |
2126 | (mask_length != (element_count / 8 + ((element_count % 8) ? 1 : 0))) ) | 1760 | (mask_length != (element_count / 8 + ((element_count % 8) ? 1 : 0)))) { |
2127 | { | ||
2128 | GNUNET_free (session); | 1761 | GNUNET_free (session); |
2129 | GNUNET_break_op (0); | 1762 | GNUNET_break_op (0); |
2130 | return GNUNET_SYSERR; | 1763 | return GNUNET_SYSERR; |
@@ -2133,8 +1766,7 @@ handle_service_request (void *cls, | |||
2133 | &msg->key, | 1766 | &msg->key, |
2134 | element_count, | 1767 | element_count, |
2135 | NULL, | 1768 | NULL, |
2136 | NULL)) | 1769 | NULL)) { |
2137 | { | ||
2138 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | 1770 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, |
2139 | _ ("Got message with duplicate session key (`%s'), ignoring service request.\n"), | 1771 | _ ("Got message with duplicate session key (`%s'), ignoring service request.\n"), |
2140 | (const char *) &(msg->key)); | 1772 | (const char *) &(msg->key)); |
@@ -2157,36 +1789,24 @@ handle_service_request (void *cls, | |||
2157 | current += mask_length; | 1789 | current += mask_length; |
2158 | 1790 | ||
2159 | //convert the publickey to sexp | 1791 | //convert the publickey to sexp |
2160 | if (0 != (rc = gcry_sexp_new (&session->remote_pubkey, current, pk_length, 1))) { | 1792 | session->remote_pubkey = GNUNET_malloc(sizeof(struct GNUNET_CRYPTO_PaillierPublicKey)); |
2161 | LOG_GCRY (GNUNET_ERROR_TYPE_DEBUG, "gcry_sexp_new", rc); | 1793 | memcpy(session->remote_pubkey, current, sizeof(struct GNUNET_CRYPTO_PaillierPublicKey)); |
2162 | GNUNET_free (session->mask); | 1794 | current += sizeof(struct GNUNET_CRYPTO_PaillierPublicKey); |
2163 | GNUNET_free (session); | 1795 | |
2164 | return GNUNET_SYSERR; | 1796 | payload = (struct GNUNET_CRYPTO_PaillierCiphertext*) current; |
2165 | } | ||
2166 | current += pk_length; | ||
2167 | //check if service queue contains a matching request | 1797 | //check if service queue contains a matching request |
2168 | needed_state = CLIENT_RESPONSE_RECEIVED; | 1798 | needed_state = CLIENT_RESPONSE_RECEIVED; |
2169 | session->response = find_matching_session (from_client_tail, | 1799 | session->response = find_matching_session (from_client_tail, |
2170 | &session->key, | 1800 | &session->key, |
2171 | session->total, | 1801 | session->total, |
2172 | &needed_state, NULL); | 1802 | &needed_state, NULL); |
2173 | |||
2174 | session->a = GNUNET_malloc (sizeof (gcry_mpi_t) * used_elements); | ||
2175 | session->state = WAITING_FOR_MULTIPART_TRANSMISSION; | 1803 | session->state = WAITING_FOR_MULTIPART_TRANSMISSION; |
2176 | GNUNET_CONTAINER_DLL_insert (from_service_head, from_service_tail, session); | 1804 | GNUNET_CONTAINER_DLL_insert (from_service_head, from_service_tail, session); |
1805 | |||
1806 | session->e_a = GNUNET_malloc (sizeof (struct GNUNET_CRYPTO_PaillierCiphertext) * used_elements); | ||
2177 | if (contained_elements != 0) { | 1807 | if (contained_elements != 0) { |
2178 | // Convert each vector element to MPI_value | 1808 | // Convert each vector element to MPI_value |
2179 | for (i = 0; i < contained_elements; i++) { | 1809 | memcpy(session->e_a, payload, sizeof (struct GNUNET_CRYPTO_PaillierCiphertext) * used_elements); |
2180 | size_t read = 0; | ||
2181 | if (0 != (rc = gcry_mpi_scan (&session->a[i], | ||
2182 | GCRYMPI_FMT_USG, | ||
2183 | ¤t[i * PAILLIER_ELEMENT_LENGTH], | ||
2184 | PAILLIER_ELEMENT_LENGTH, | ||
2185 | &read))) { | ||
2186 | LOG_GCRY (GNUNET_ERROR_TYPE_DEBUG, "gcry_mpi_scan", rc); | ||
2187 | goto invalid_msg; | ||
2188 | } | ||
2189 | } | ||
2190 | if (contained_elements == used_elements) { | 1810 | if (contained_elements == used_elements) { |
2191 | // single part finished | 1811 | // single part finished |
2192 | session->state = SERVICE_REQUEST_RECEIVED; | 1812 | session->state = SERVICE_REQUEST_RECEIVED; |
@@ -2238,13 +1858,11 @@ handle_service_response_multipart (void *cls, | |||
2238 | { | 1858 | { |
2239 | struct ServiceSession * session; | 1859 | struct ServiceSession * session; |
2240 | const struct GNUNET_SCALARPRODUCT_multipart_message * msg = (const struct GNUNET_SCALARPRODUCT_multipart_message *) message; | 1860 | const struct GNUNET_SCALARPRODUCT_multipart_message * msg = (const struct GNUNET_SCALARPRODUCT_multipart_message *) message; |
2241 | unsigned char * current; | 1861 | struct GNUNET_CRYPTO_PaillierCiphertext * payload; |
2242 | size_t read; | ||
2243 | size_t i; | 1862 | size_t i; |
2244 | uint32_t contained = 0; | 1863 | uint32_t contained = 0; |
2245 | size_t msg_size; | 1864 | size_t msg_size; |
2246 | size_t required_size; | 1865 | size_t required_size; |
2247 | int rc; | ||
2248 | 1866 | ||
2249 | GNUNET_assert (NULL != message); | 1867 | GNUNET_assert (NULL != message); |
2250 | // are we in the correct state? | 1868 | // are we in the correct state? |
@@ -2253,33 +1871,24 @@ handle_service_response_multipart (void *cls, | |||
2253 | goto invalid_msg; | 1871 | goto invalid_msg; |
2254 | } | 1872 | } |
2255 | msg_size = ntohs (msg->header.size); | 1873 | msg_size = ntohs (msg->header.size); |
2256 | required_size = sizeof (struct GNUNET_SCALARPRODUCT_multipart_message) + 2 * PAILLIER_ELEMENT_LENGTH; | 1874 | required_size = sizeof (struct GNUNET_SCALARPRODUCT_multipart_message) |
1875 | + 2 * sizeof (struct GNUNET_CRYPTO_PaillierCiphertext); | ||
2257 | // shorter than minimum? | 1876 | // shorter than minimum? |
2258 | if (required_size > msg_size) { | 1877 | if (required_size > msg_size) { |
2259 | goto invalid_msg; | 1878 | goto invalid_msg; |
2260 | } | 1879 | } |
2261 | contained = ntohl (msg->multipart_element_count); | 1880 | contained = ntohl (msg->multipart_element_count); |
2262 | required_size = sizeof (struct GNUNET_SCALARPRODUCT_multipart_message) | 1881 | required_size = sizeof (struct GNUNET_SCALARPRODUCT_multipart_message) |
2263 | + 2 * contained * PAILLIER_ELEMENT_LENGTH; | 1882 | + 2 * contained * sizeof (struct GNUNET_CRYPTO_PaillierCiphertext); |
2264 | //sanity check: is the message as long as the message_count fields suggests? | 1883 | //sanity check: is the message as long as the message_count fields suggests? |
2265 | if ((required_size != msg_size) || (session->used < session->transferred + contained)) { | 1884 | if ((required_size != msg_size) || (session->used < session->transferred + contained)) { |
2266 | goto invalid_msg; | 1885 | goto invalid_msg; |
2267 | } | 1886 | } |
2268 | current = (unsigned char *) &msg[1]; | 1887 | payload = (struct GNUNET_CRYPTO_PaillierCiphertext *) &msg[1]; |
2269 | // Convert each k[][perm] to its MPI_value | 1888 | // Convert each k[][perm] to its MPI_value |
2270 | for (i = 0; i < contained; i++) { | 1889 | for (i = 0; i < contained; i++) { |
2271 | if (0 != (rc = gcry_mpi_scan (&session->r[i], GCRYMPI_FMT_USG, current, | 1890 | memcpy(&session->r[session->transferred+i], &payload[2*i], sizeof (struct GNUNET_CRYPTO_PaillierCiphertext)); |
2272 | PAILLIER_ELEMENT_LENGTH, &read))) { | 1891 | memcpy(&session->r_prime[session->transferred+i], &payload[2*i], sizeof (struct GNUNET_CRYPTO_PaillierCiphertext)); |
2273 | LOG_GCRY (GNUNET_ERROR_TYPE_DEBUG, "gcry_mpi_scan", rc); | ||
2274 | goto invalid_msg; | ||
2275 | } | ||
2276 | current += PAILLIER_ELEMENT_LENGTH; | ||
2277 | if (0 != (rc = gcry_mpi_scan (&session->r_prime[i], GCRYMPI_FMT_USG, current, | ||
2278 | PAILLIER_ELEMENT_LENGTH, &read))) { | ||
2279 | LOG_GCRY (GNUNET_ERROR_TYPE_DEBUG, "gcry_mpi_scan", rc); | ||
2280 | goto invalid_msg; | ||
2281 | } | ||
2282 | current += PAILLIER_ELEMENT_LENGTH; | ||
2283 | } | 1892 | } |
2284 | session->transferred += contained; | 1893 | session->transferred += contained; |
2285 | if (session->transferred != session->used) | 1894 | if (session->transferred != session->used) |
@@ -2288,15 +1897,15 @@ handle_service_response_multipart (void *cls, | |||
2288 | session->product = compute_scalar_product (session); //never NULL | 1897 | session->product = compute_scalar_product (session); //never NULL |
2289 | 1898 | ||
2290 | invalid_msg: | 1899 | invalid_msg: |
2291 | GNUNET_break_op (NULL != session->product); | 1900 | GNUNET_break_op (NULL != session->product); //NULL if we never tried to compute it... |
2292 | 1901 | ||
2293 | // send message with product to client | 1902 | // send message with product to client |
2294 | if (ALICE == session->role){ | 1903 | if (ALICE == session->role) { |
2295 | session->state = FINALIZED; | 1904 | session->state = FINALIZED; |
2296 | session->channel = NULL; | 1905 | session->channel = NULL; |
2297 | session->client_notification_task = | 1906 | session->client_notification_task = |
2298 | GNUNET_SCHEDULER_add_now (&prepare_client_response, | 1907 | GNUNET_SCHEDULER_add_now (&prepare_client_response, |
2299 | session); | 1908 | session); |
2300 | } | 1909 | } |
2301 | // the channel has done its job, terminate our connection and the channel | 1910 | // the channel has done its job, terminate our connection and the channel |
2302 | // the peer will be notified that the channel was destroyed via channel_destruction_handler | 1911 | // the peer will be notified that the channel was destroyed via channel_destruction_handler |
@@ -2323,13 +1932,11 @@ handle_service_response (void *cls, | |||
2323 | { | 1932 | { |
2324 | struct ServiceSession * session; | 1933 | struct ServiceSession * session; |
2325 | const struct GNUNET_SCALARPRODUCT_service_response * msg = (const struct GNUNET_SCALARPRODUCT_service_response *) message; | 1934 | const struct GNUNET_SCALARPRODUCT_service_response * msg = (const struct GNUNET_SCALARPRODUCT_service_response *) message; |
2326 | unsigned char * current; | 1935 | struct GNUNET_CRYPTO_PaillierCiphertext * payload; |
2327 | size_t read; | ||
2328 | size_t i; | 1936 | size_t i; |
2329 | uint32_t contained = 0; | 1937 | uint32_t contained = 0; |
2330 | size_t msg_size; | 1938 | size_t msg_size; |
2331 | size_t required_size; | 1939 | size_t required_size; |
2332 | int rc; | ||
2333 | 1940 | ||
2334 | GNUNET_assert (NULL != message); | 1941 | GNUNET_assert (NULL != message); |
2335 | session = (struct ServiceSession *) * channel_ctx; | 1942 | session = (struct ServiceSession *) * channel_ctx; |
@@ -2339,15 +1946,15 @@ handle_service_response (void *cls, | |||
2339 | } | 1946 | } |
2340 | //we need at least a full message without elements attached | 1947 | //we need at least a full message without elements attached |
2341 | msg_size = ntohs (msg->header.size); | 1948 | msg_size = ntohs (msg->header.size); |
2342 | required_size = sizeof (struct GNUNET_SCALARPRODUCT_service_response) + 2 * PAILLIER_ELEMENT_LENGTH; | 1949 | required_size = sizeof (struct GNUNET_SCALARPRODUCT_service_response) + 2 * sizeof (struct GNUNET_CRYPTO_PaillierCiphertext); |
2343 | 1950 | ||
2344 | if (required_size > msg_size) { | 1951 | if (required_size > msg_size) { |
2345 | goto invalid_msg; | 1952 | goto invalid_msg; |
2346 | } | 1953 | } |
2347 | contained = ntohl (msg->contained_element_count); | 1954 | contained = ntohl (msg->contained_element_count); |
2348 | required_size = sizeof (struct GNUNET_SCALARPRODUCT_service_response) | 1955 | required_size = sizeof (struct GNUNET_SCALARPRODUCT_service_response) |
2349 | + 2 * contained * PAILLIER_ELEMENT_LENGTH | 1956 | + 2 * contained * sizeof (struct GNUNET_CRYPTO_PaillierCiphertext) |
2350 | + 2 * PAILLIER_ELEMENT_LENGTH; | 1957 | + 2 * sizeof (struct GNUNET_CRYPTO_PaillierCiphertext); |
2351 | //sanity check: is the message as long as the message_count fields suggests? | 1958 | //sanity check: is the message as long as the message_count fields suggests? |
2352 | if ((msg_size != required_size) || (session->used < contained)) { | 1959 | if ((msg_size != required_size) || (session->used < contained)) { |
2353 | goto invalid_msg; | 1960 | goto invalid_msg; |
@@ -2355,36 +1962,20 @@ handle_service_response (void *cls, | |||
2355 | session->state = WAITING_FOR_MULTIPART_TRANSMISSION; | 1962 | session->state = WAITING_FOR_MULTIPART_TRANSMISSION; |
2356 | session->transferred = contained; | 1963 | session->transferred = contained; |
2357 | //convert s | 1964 | //convert s |
2358 | current = (unsigned char *) &msg[1]; | 1965 | payload = (struct GNUNET_CRYPTO_PaillierCiphertext *) &msg[1]; |
2359 | if (0 != (rc = gcry_mpi_scan (&session->s, GCRYMPI_FMT_USG, current, | 1966 | |
2360 | PAILLIER_ELEMENT_LENGTH, &read))) { | 1967 | session->s = GNUNET_malloc(sizeof(struct GNUNET_CRYPTO_PaillierCiphertext)); |
2361 | LOG_GCRY (GNUNET_ERROR_TYPE_DEBUG, "gcry_mpi_scan", rc); | 1968 | session->s_prime = GNUNET_malloc(sizeof(struct GNUNET_CRYPTO_PaillierCiphertext)); |
2362 | goto invalid_msg; | 1969 | memcpy(session->s,&payload[0],sizeof(struct GNUNET_CRYPTO_PaillierCiphertext)); |
2363 | } | 1970 | memcpy(session->s_prime,&payload[1],sizeof(struct GNUNET_CRYPTO_PaillierCiphertext)); |
2364 | current += PAILLIER_ELEMENT_LENGTH; | 1971 | |
2365 | //convert stick | 1972 | session->r = GNUNET_malloc (sizeof (struct GNUNET_CRYPTO_PaillierCiphertext) * session->used); |
2366 | if (0 != (rc = gcry_mpi_scan (&session->s_prime, GCRYMPI_FMT_USG, current, | 1973 | session->r_prime = GNUNET_malloc (sizeof (struct GNUNET_CRYPTO_PaillierCiphertext) * session->used); |
2367 | PAILLIER_ELEMENT_LENGTH, &read))) { | 1974 | |
2368 | LOG_GCRY (GNUNET_ERROR_TYPE_DEBUG, "gcry_mpi_scan", rc); | ||
2369 | goto invalid_msg; | ||
2370 | } | ||
2371 | current += PAILLIER_ELEMENT_LENGTH; | ||
2372 | session->r = GNUNET_malloc (sizeof (gcry_mpi_t) * session->used); | ||
2373 | session->r_prime = GNUNET_malloc (sizeof (gcry_mpi_t) * session->used); | ||
2374 | // Convert each k[][perm] to its MPI_value | 1975 | // Convert each k[][perm] to its MPI_value |
2375 | for (i = 0; i < contained; i++) { | 1976 | for (i = 0; i < contained; i++) { |
2376 | if (0 != (rc = gcry_mpi_scan (&session->r[i], GCRYMPI_FMT_USG, current, | 1977 | memcpy(&session->r[i], &payload[2 + 2*i], sizeof (struct GNUNET_CRYPTO_PaillierCiphertext)); |
2377 | PAILLIER_ELEMENT_LENGTH, &read))) { | 1978 | memcpy(&session->r_prime[i], &payload[3 + 2*i], sizeof (struct GNUNET_CRYPTO_PaillierCiphertext)); |
2378 | LOG_GCRY (GNUNET_ERROR_TYPE_DEBUG, "gcry_mpi_scan", rc); | ||
2379 | goto invalid_msg; | ||
2380 | } | ||
2381 | current += PAILLIER_ELEMENT_LENGTH; | ||
2382 | if (0 != (rc = gcry_mpi_scan (&session->r_prime[i], GCRYMPI_FMT_USG, current, | ||
2383 | PAILLIER_ELEMENT_LENGTH, &read))) { | ||
2384 | LOG_GCRY (GNUNET_ERROR_TYPE_DEBUG, "gcry_mpi_scan", rc); | ||
2385 | goto invalid_msg; | ||
2386 | } | ||
2387 | current += PAILLIER_ELEMENT_LENGTH; | ||
2388 | } | 1979 | } |
2389 | if (session->transferred != session->used) | 1980 | if (session->transferred != session->used) |
2390 | return GNUNET_OK; //wait for the other multipart chunks | 1981 | return GNUNET_OK; //wait for the other multipart chunks |
@@ -2395,12 +1986,12 @@ handle_service_response (void *cls, | |||
2395 | invalid_msg: | 1986 | invalid_msg: |
2396 | GNUNET_break_op (NULL != session->product); | 1987 | GNUNET_break_op (NULL != session->product); |
2397 | // send message with product to client | 1988 | // send message with product to client |
2398 | if (ALICE == session->role){ | 1989 | if (ALICE == session->role) { |
2399 | session->state = FINALIZED; | 1990 | session->state = FINALIZED; |
2400 | session->channel = NULL; | 1991 | session->channel = NULL; |
2401 | session->client_notification_task = | 1992 | session->client_notification_task = |
2402 | GNUNET_SCHEDULER_add_now (&prepare_client_response, | 1993 | GNUNET_SCHEDULER_add_now (&prepare_client_response, |
2403 | session); | 1994 | session); |
2404 | } | 1995 | } |
2405 | // the channel has done its job, terminate our connection and the channel | 1996 | // the channel has done its job, terminate our connection and the channel |
2406 | // the peer will be notified that the channel was destroyed via channel_destruction_handler | 1997 | // the peer will be notified that the channel was destroyed via channel_destruction_handler |
@@ -2485,8 +2076,14 @@ run (void *cls, | |||
2485 | 0 | 2076 | 0 |
2486 | }; | 2077 | }; |
2487 | //generate private/public key set | 2078 | //generate private/public key set |
2488 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, _ ("Generating Paillier-Keyset.\n")); | 2079 | GNUNET_CRYPTO_paillier_create (&my_pubkey, &my_privkey); |
2489 | generate_keyset (); | 2080 | |
2081 | // offset has to be sufficiently small to allow computation of: | ||
2082 | // m1+m2 mod n == (S + a) + (S + b) mod n, | ||
2083 | // if we have more complex operations, this factor needs to be lowered | ||
2084 | my_offset = gcry_mpi_new (GNUNET_CRYPTO_PAILLIER_BITS / 3); | ||
2085 | gcry_mpi_set_bit (my_offset, GNUNET_CRYPTO_PAILLIER_BITS / 3); | ||
2086 | |||
2490 | // register server callbacks and disconnect handler | 2087 | // register server callbacks and disconnect handler |
2491 | GNUNET_SERVER_add_handlers (server, server_handlers); | 2088 | GNUNET_SERVER_add_handlers (server, server_handlers); |
2492 | GNUNET_SERVER_disconnect_notify (server, | 2089 | GNUNET_SERVER_disconnect_notify (server, |
diff --git a/src/scalarproduct/scalarproduct.h b/src/scalarproduct/scalarproduct.h index 66f05e76d..5682362fd 100644 --- a/src/scalarproduct/scalarproduct.h +++ b/src/scalarproduct/scalarproduct.h | |||
@@ -36,21 +36,11 @@ extern "C" | |||
36 | /////////////////////////////////////////////////////////////////////////////// | 36 | /////////////////////////////////////////////////////////////////////////////// |
37 | // Defines | 37 | // Defines |
38 | /////////////////////////////////////////////////////////////////////////////// | 38 | /////////////////////////////////////////////////////////////////////////////// |
39 | /** | ||
40 | * Length of the key used for encryption | ||
41 | */ | ||
42 | #define KEYBITS 2048 | ||
43 | |||
44 | /** | ||
45 | * When performing our crypto, we may add two encrypted values with each | ||
46 | * a maximal length of GNUNET_CRYPTO_RSA_DATA_ENCODING_LENGTH. | ||
47 | */ | ||
48 | #define PAILLIER_ELEMENT_LENGTH (2*KEYBITS/sizeof(char)) | ||
49 | 39 | ||
50 | /** | 40 | /** |
51 | * Maximum count of elements we can put into a multipart message | 41 | * Maximum count of elements we can put into a multipart message |
52 | */ | 42 | */ |
53 | #define MULTIPART_ELEMENT_CAPACITY ((GNUNET_SERVER_MAX_MESSAGE_SIZE - 1 - sizeof (struct GNUNET_SCALARPRODUCT_multipart_message)) / PAILLIER_ELEMENT_LENGTH) | 43 | #define MULTIPART_ELEMENT_CAPACITY ((GNUNET_SERVER_MAX_MESSAGE_SIZE - 1 - sizeof (struct GNUNET_SCALARPRODUCT_multipart_message)) / sizeof (struct GNUNET_CRYPTO_PaillierCiphertext)) |
54 | 44 | ||
55 | /** | 45 | /** |
56 | * Log an error message at log-level 'level' that indicates | 46 | * Log an error message at log-level 'level' that indicates |
@@ -125,11 +115,6 @@ struct GNUNET_SCALARPRODUCT_service_request { | |||
125 | uint32_t mask_length GNUNET_PACKED; | 115 | uint32_t mask_length GNUNET_PACKED; |
126 | 116 | ||
127 | /** | 117 | /** |
128 | * the length of the publickey contained within this message | ||
129 | */ | ||
130 | uint32_t pk_length GNUNET_PACKED; | ||
131 | |||
132 | /** | ||
133 | * the transaction/session key used to identify a session | 118 | * the transaction/session key used to identify a session |
134 | */ | 119 | */ |
135 | struct GNUNET_HashCode key; | 120 | struct GNUNET_HashCode key; |