diff options
author | Christian Grothoff <christian@grothoff.org> | 2015-09-05 18:03:58 +0000 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2015-09-05 18:03:58 +0000 |
commit | 14f9ba0d86025dfd2defb1635899c75da4815d16 (patch) | |
tree | d88c4404b496a1fc27fc0c4b6239c5ec4aee4510 /src/scalarproduct/gnunet-service-scalarproduct-ecc_bob.c | |
parent | 29ee3958cd75cf5f91846f8235278061e6c9309f (diff) | |
download | gnunet-14f9ba0d86025dfd2defb1635899c75da4815d16.tar.gz gnunet-14f9ba0d86025dfd2defb1635899c75da4815d16.zip |
-towards ECC variant of SP
Diffstat (limited to 'src/scalarproduct/gnunet-service-scalarproduct-ecc_bob.c')
-rw-r--r-- | src/scalarproduct/gnunet-service-scalarproduct-ecc_bob.c | 562 |
1 files changed, 125 insertions, 437 deletions
diff --git a/src/scalarproduct/gnunet-service-scalarproduct-ecc_bob.c b/src/scalarproduct/gnunet-service-scalarproduct-ecc_bob.c index d08f5b858..80a0dc941 100644 --- a/src/scalarproduct/gnunet-service-scalarproduct-ecc_bob.c +++ b/src/scalarproduct/gnunet-service-scalarproduct-ecc_bob.c | |||
@@ -1,6 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | This file is part of GNUnet. | 2 | This file is part of GNUnet. |
3 | Copyright (C) 2013, 2014 Christian Grothoff (and other contributing authors) | 3 | Copyright (C) 2013-2015 Christian Grothoff (and other contributing authors) |
4 | 4 | ||
5 | GNUnet is free software; you can redistribute it and/or modify | 5 | GNUnet is free software; you can redistribute it and/or modify |
6 | it under the terms of the GNU General Public License as published | 6 | it under the terms of the GNU General Public License as published |
@@ -18,7 +18,7 @@ | |||
18 | Boston, MA 02110-1301, USA. | 18 | Boston, MA 02110-1301, USA. |
19 | */ | 19 | */ |
20 | /** | 20 | /** |
21 | * @file scalarproduct/gnunet-service-scalarproduct_bob.c | 21 | * @file scalarproduct/gnunet-service-scalarproduct-ecc_bob.c |
22 | * @brief scalarproduct service implementation | 22 | * @brief scalarproduct service implementation |
23 | * @author Christian M. Fuchs | 23 | * @author Christian M. Fuchs |
24 | * @author Christian Grothoff | 24 | * @author Christian Grothoff |
@@ -34,7 +34,7 @@ | |||
34 | #include "gnunet_scalarproduct_service.h" | 34 | #include "gnunet_scalarproduct_service.h" |
35 | #include "gnunet_set_service.h" | 35 | #include "gnunet_set_service.h" |
36 | #include "scalarproduct.h" | 36 | #include "scalarproduct.h" |
37 | #include "gnunet-service-scalarproduct.h" | 37 | #include "gnunet-service-scalarproduct-ecc.h" |
38 | 38 | ||
39 | #define LOG(kind,...) GNUNET_log_from (kind, "scalarproduct-bob", __VA_ARGS__) | 39 | #define LOG(kind,...) GNUNET_log_from (kind, "scalarproduct-bob", __VA_ARGS__) |
40 | 40 | ||
@@ -104,34 +104,19 @@ struct BobServiceSession | |||
104 | struct GNUNET_SET_OperationHandle *intersection_op; | 104 | struct GNUNET_SET_OperationHandle *intersection_op; |
105 | 105 | ||
106 | /** | 106 | /** |
107 | * a(Alice) | 107 | * b(Bob) |
108 | */ | 108 | */ |
109 | struct MpiElement *sorted_elements; | 109 | struct MpiElement *sorted_elements; |
110 | 110 | ||
111 | /** | 111 | /** |
112 | * E(ai)(Bob) after applying the mask | 112 | * Product of the g_i^{b_i} |
113 | */ | 113 | */ |
114 | struct GNUNET_CRYPTO_PaillierCiphertext *e_a; | 114 | gcry_mpi_point_t prod_g_i_b_i; |
115 | 115 | ||
116 | /** | 116 | /** |
117 | * Bob's permutation p of R | 117 | * Product of the h_i^{b_i} |
118 | */ | 118 | */ |
119 | struct GNUNET_CRYPTO_PaillierCiphertext *r; | 119 | gcry_mpi_point_t prod_h_i_b_i; |
120 | |||
121 | /** | ||
122 | * Bob's permutation q of R | ||
123 | */ | ||
124 | struct GNUNET_CRYPTO_PaillierCiphertext *r_prime; | ||
125 | |||
126 | /** | ||
127 | * Bob's "s" | ||
128 | */ | ||
129 | struct GNUNET_CRYPTO_PaillierCiphertext s; | ||
130 | |||
131 | /** | ||
132 | * Bob's "s'" | ||
133 | */ | ||
134 | struct GNUNET_CRYPTO_PaillierCiphertext s_prime; | ||
135 | 120 | ||
136 | /** | 121 | /** |
137 | * Handle for our associated incoming CADET session, or NULL | 122 | * Handle for our associated incoming CADET session, or NULL |
@@ -140,11 +125,6 @@ struct BobServiceSession | |||
140 | struct CadetIncomingSession *cadet; | 125 | struct CadetIncomingSession *cadet; |
141 | 126 | ||
142 | /** | 127 | /** |
143 | * The computed scalar | ||
144 | */ | ||
145 | gcry_mpi_t product; | ||
146 | |||
147 | /** | ||
148 | * How many elements will be supplied in total from the client. | 128 | * How many elements will be supplied in total from the client. |
149 | */ | 129 | */ |
150 | uint32_t total; | 130 | uint32_t total; |
@@ -169,12 +149,6 @@ struct BobServiceSession | |||
169 | uint32_t cadet_received_element_count; | 149 | uint32_t cadet_received_element_count; |
170 | 150 | ||
171 | /** | 151 | /** |
172 | * Counts the number of values transmitted from us to Alice. | ||
173 | * Always less than @e used_element_count. | ||
174 | */ | ||
175 | uint32_t cadet_transmitted_element_count; | ||
176 | |||
177 | /** | ||
178 | * State of this session. In | 152 | * State of this session. In |
179 | * #GNUNET_SCALARPRODUCT_STATUS_ACTIVE while operation is | 153 | * #GNUNET_SCALARPRODUCT_STATUS_ACTIVE while operation is |
180 | * ongoing, afterwards in #GNUNET_SCALARPRODUCT_STATUS_SUCCESS or | 154 | * ongoing, afterwards in #GNUNET_SCALARPRODUCT_STATUS_SUCCESS or |
@@ -217,11 +191,6 @@ struct CadetIncomingSession | |||
217 | struct GNUNET_HashCode session_id; | 191 | struct GNUNET_HashCode session_id; |
218 | 192 | ||
219 | /** | 193 | /** |
220 | * Public key of the remote service. | ||
221 | */ | ||
222 | struct GNUNET_CRYPTO_PaillierPublicKey remote_pubkey; | ||
223 | |||
224 | /** | ||
225 | * The message queue for this channel. | 194 | * The message queue for this channel. |
226 | */ | 195 | */ |
227 | struct GNUNET_MQ_Handle *cadet_mq; | 196 | struct GNUNET_MQ_Handle *cadet_mq; |
@@ -247,21 +216,6 @@ struct CadetIncomingSession | |||
247 | static const struct GNUNET_CONFIGURATION_Handle *cfg; | 216 | static const struct GNUNET_CONFIGURATION_Handle *cfg; |
248 | 217 | ||
249 | /** | 218 | /** |
250 | * Service's own public key | ||
251 | */ | ||
252 | static struct GNUNET_CRYPTO_PaillierPublicKey my_pubkey; | ||
253 | |||
254 | /** | ||
255 | * Service's own private key | ||
256 | */ | ||
257 | static struct GNUNET_CRYPTO_PaillierPrivateKey my_privkey; | ||
258 | |||
259 | /** | ||
260 | * Service's offset for values that could possibly be negative but are plaintext for encryption. | ||
261 | */ | ||
262 | static gcry_mpi_t my_offset; | ||
263 | |||
264 | /** | ||
265 | * Map of `struct BobServiceSession`, by session keys. | 219 | * Map of `struct BobServiceSession`, by session keys. |
266 | */ | 220 | */ |
267 | static struct GNUNET_CONTAINER_MultiHashMap *client_sessions; | 221 | static struct GNUNET_CONTAINER_MultiHashMap *client_sessions; |
@@ -276,6 +230,11 @@ static struct GNUNET_CONTAINER_MultiHashMap *cadet_sessions; | |||
276 | */ | 230 | */ |
277 | static struct GNUNET_CADET_Handle *my_cadet; | 231 | static struct GNUNET_CADET_Handle *my_cadet; |
278 | 232 | ||
233 | /** | ||
234 | * Context for DLOG operations on a curve. | ||
235 | */ | ||
236 | static struct GNUNET_CRYPTO_EccDlogContext *edc; | ||
237 | |||
279 | 238 | ||
280 | 239 | ||
281 | /** | 240 | /** |
@@ -386,11 +345,6 @@ destroy_service_session (struct BobServiceSession *s) | |||
386 | GNUNET_SET_destroy (s->intersection_set); | 345 | GNUNET_SET_destroy (s->intersection_set); |
387 | s->intersection_set = NULL; | 346 | s->intersection_set = NULL; |
388 | } | 347 | } |
389 | if (NULL != s->e_a) | ||
390 | { | ||
391 | GNUNET_free (s->e_a); | ||
392 | s->e_a = NULL; | ||
393 | } | ||
394 | if (NULL != s->sorted_elements) | 348 | if (NULL != s->sorted_elements) |
395 | { | 349 | { |
396 | for (i=0;i<s->used_element_count;i++) | 350 | for (i=0;i<s->used_element_count;i++) |
@@ -398,20 +352,15 @@ destroy_service_session (struct BobServiceSession *s) | |||
398 | GNUNET_free (s->sorted_elements); | 352 | GNUNET_free (s->sorted_elements); |
399 | s->sorted_elements = NULL; | 353 | s->sorted_elements = NULL; |
400 | } | 354 | } |
401 | if (NULL != s->r) | 355 | if (NULL != s->prod_g_i_b_i) |
402 | { | 356 | { |
403 | GNUNET_free (s->r); | 357 | gcry_mpi_point_release (s->prod_g_i_b_i); |
404 | s->r = NULL; | 358 | s->prod_g_i_b_i = NULL; |
405 | } | 359 | } |
406 | if (NULL != s->r_prime) | 360 | if (NULL != s->prod_g_i_b_i) |
407 | { | 361 | { |
408 | GNUNET_free (s->r_prime); | 362 | gcry_mpi_point_release (s->prod_h_i_b_i); |
409 | s->r_prime = NULL; | 363 | s->prod_h_i_b_i = NULL; |
410 | } | ||
411 | if (NULL != s->product) | ||
412 | { | ||
413 | gcry_mpi_release (s->product); | ||
414 | s->product = NULL; | ||
415 | } | 364 | } |
416 | GNUNET_free (s); | 365 | GNUNET_free (s); |
417 | } | 366 | } |
@@ -540,306 +489,34 @@ bob_cadet_done_cb (void *cls) | |||
540 | 489 | ||
541 | 490 | ||
542 | /** | 491 | /** |
543 | * Maximum count of elements we can put into a multipart message | 492 | * Bob generates the response message to be sent to Alice. |
544 | */ | ||
545 | #define ELEMENT_CAPACITY ((GNUNET_CONSTANTS_MAX_CADET_MESSAGE_SIZE - 1 - sizeof (struct BobCryptodataMultipartMessage)) / sizeof (struct GNUNET_CRYPTO_PaillierCiphertext)) | ||
546 | |||
547 | |||
548 | /** | ||
549 | * Send a multipart chunk of a service response from Bob to Alice. | ||
550 | * This element only contains the two permutations of R, R'. | ||
551 | * | ||
552 | * @param s the associated service session | ||
553 | */ | ||
554 | static void | ||
555 | transmit_bobs_cryptodata_message_multipart (struct BobServiceSession *s) | ||
556 | { | ||
557 | struct GNUNET_CRYPTO_PaillierCiphertext *payload; | ||
558 | struct BobCryptodataMultipartMessage *msg; | ||
559 | struct GNUNET_MQ_Envelope *e; | ||
560 | unsigned int i; | ||
561 | unsigned int j; | ||
562 | uint32_t todo_count; | ||
563 | |||
564 | while (s->cadet_transmitted_element_count != s->used_element_count) | ||
565 | { | ||
566 | todo_count = s->used_element_count - s->cadet_transmitted_element_count; | ||
567 | if (todo_count > ELEMENT_CAPACITY / 2) | ||
568 | todo_count = ELEMENT_CAPACITY / 2; | ||
569 | |||
570 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
571 | "Sending %u additional crypto values to Alice\n", | ||
572 | (unsigned int) todo_count); | ||
573 | e = GNUNET_MQ_msg_extra (msg, | ||
574 | todo_count * sizeof (struct GNUNET_CRYPTO_PaillierCiphertext) * 2, | ||
575 | GNUNET_MESSAGE_TYPE_SCALARPRODUCT_BOB_CRYPTODATA_MULTIPART); | ||
576 | msg->contained_element_count = htonl (todo_count); | ||
577 | payload = (struct GNUNET_CRYPTO_PaillierCiphertext *) &msg[1]; | ||
578 | for (i = s->cadet_transmitted_element_count, j = 0; i < s->cadet_transmitted_element_count + todo_count; i++) | ||
579 | { | ||
580 | //r[i][p] and r[i][q] | ||
581 | memcpy (&payload[j++], | ||
582 | &s->r[i], | ||
583 | sizeof (struct GNUNET_CRYPTO_PaillierCiphertext)); | ||
584 | memcpy (&payload[j++], | ||
585 | &s->r_prime[i], | ||
586 | sizeof (struct GNUNET_CRYPTO_PaillierCiphertext)); | ||
587 | } | ||
588 | s->cadet_transmitted_element_count += todo_count; | ||
589 | if (s->cadet_transmitted_element_count == s->used_element_count) | ||
590 | GNUNET_MQ_notify_sent (e, | ||
591 | &bob_cadet_done_cb, | ||
592 | s); | ||
593 | GNUNET_MQ_send (s->cadet->cadet_mq, | ||
594 | e); | ||
595 | } | ||
596 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
597 | "All values queued for Alice, Bob is done\n"); | ||
598 | } | ||
599 | |||
600 | |||
601 | /** | ||
602 | * Bob generates the response message to be sent to Alice after | ||
603 | * computing the values (1), (2), S and S'. | ||
604 | * | ||
605 | * (1)[]: $E_A(a_{pi(i)}) times E_A(- r_{pi(i)} - b_{pi(i)}) &= E_A(a_{pi(i)} - r_{pi(i)} - b_{pi(i)})$ | ||
606 | * (2)[]: $E_A(a_{pi'(i)}) times E_A(- r_{pi'(i)}) &= E_A(a_{pi'(i)} - r_{pi'(i)})$ | ||
607 | * S: $S := E_A(sum (r_i + b_i)^2)$ | ||
608 | * S': $S' := E_A(sum r_i^2)$ | ||
609 | * | 493 | * |
610 | * @param s the associated requesting session with Alice | 494 | * @param s the associated requesting session with Alice |
611 | */ | 495 | */ |
612 | static void | 496 | static void |
613 | transmit_bobs_cryptodata_message (struct BobServiceSession *s) | 497 | transmit_bobs_cryptodata_message (struct BobServiceSession *s) |
614 | { | 498 | { |
615 | struct BobCryptodataMessage *msg; | 499 | struct EccBobCryptodataMessage *msg; |
616 | struct GNUNET_MQ_Envelope *e; | 500 | struct GNUNET_MQ_Envelope *e; |
617 | struct GNUNET_CRYPTO_PaillierCiphertext *payload; | ||
618 | unsigned int i; | ||
619 | |||
620 | s->cadet_transmitted_element_count | ||
621 | = ((GNUNET_CONSTANTS_MAX_CADET_MESSAGE_SIZE - 1 - sizeof (struct BobCryptodataMessage)) | ||
622 | / sizeof (struct GNUNET_CRYPTO_PaillierCiphertext) / 2) - 1; | ||
623 | if (s->cadet_transmitted_element_count > s->used_element_count) | ||
624 | s->cadet_transmitted_element_count = s->used_element_count; | ||
625 | |||
626 | e = GNUNET_MQ_msg_extra (msg, | ||
627 | (2 + s->cadet_transmitted_element_count * 2) | ||
628 | * sizeof (struct GNUNET_CRYPTO_PaillierCiphertext), | ||
629 | GNUNET_MESSAGE_TYPE_SCALARPRODUCT_BOB_CRYPTODATA); | ||
630 | msg->contained_element_count = htonl (s->cadet_transmitted_element_count); | ||
631 | 501 | ||
632 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 502 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
633 | "Sending %u/%u crypto values to Alice\n", | 503 | "Sending response to Alice\n"); |
634 | (unsigned int) s->cadet_transmitted_element_count, | 504 | e = GNUNET_MQ_msg (msg, |
635 | (unsigned int) s->used_element_count); | 505 | GNUNET_MESSAGE_TYPE_SCALARPRODUCT_ECC_BOB_CRYPTODATA); |
636 | 506 | msg->contained_element_count = htonl (2); | |
637 | payload = (struct GNUNET_CRYPTO_PaillierCiphertext *) &msg[1]; | 507 | if (NULL != s->prod_g_i_b_i) |
638 | memcpy (&payload[0], | 508 | GNUNET_CRYPTO_ecc_point_to_bin (edc, |
639 | &s->s, | 509 | s->prod_g_i_b_i, |
640 | sizeof (struct GNUNET_CRYPTO_PaillierCiphertext)); | 510 | &msg->prod_g_i_b_i); |
641 | memcpy (&payload[1], | 511 | if (NULL != s->prod_h_i_b_i) |
642 | &s->s_prime, | 512 | GNUNET_CRYPTO_ecc_point_to_bin (edc, |
643 | sizeof (struct GNUNET_CRYPTO_PaillierCiphertext)); | 513 | s->prod_h_i_b_i, |
644 | 514 | &msg->prod_h_i_b_i); | |
645 | payload = &payload[2]; | 515 | GNUNET_MQ_notify_sent (e, |
646 | // convert k[][] | 516 | &bob_cadet_done_cb, |
647 | for (i = 0; i < s->cadet_transmitted_element_count; i++) | 517 | s); |
648 | { | ||
649 | //k[i][p] and k[i][q] | ||
650 | memcpy (&payload[i * 2], | ||
651 | &s->r[i], | ||
652 | sizeof (struct GNUNET_CRYPTO_PaillierCiphertext)); | ||
653 | memcpy (&payload[i * 2 + 1], | ||
654 | &s->r_prime[i], | ||
655 | sizeof (struct GNUNET_CRYPTO_PaillierCiphertext)); | ||
656 | } | ||
657 | if (s->cadet_transmitted_element_count == s->used_element_count) | ||
658 | GNUNET_MQ_notify_sent (e, | ||
659 | &bob_cadet_done_cb, | ||
660 | s); | ||
661 | GNUNET_MQ_send (s->cadet->cadet_mq, | 518 | GNUNET_MQ_send (s->cadet->cadet_mq, |
662 | e); | 519 | e); |
663 | transmit_bobs_cryptodata_message_multipart (s); | ||
664 | } | ||
665 | #undef ELEMENT_CAPACITY | ||
666 | |||
667 | |||
668 | /** | ||
669 | * Computes the square sum over a vector of a given length. | ||
670 | * | ||
671 | * @param vector the vector to compute over | ||
672 | * @param length the length of the vector | ||
673 | * @return an MPI value containing the calculated sum, never NULL | ||
674 | * TODO: code duplication with Alice! | ||
675 | */ | ||
676 | static gcry_mpi_t | ||
677 | compute_square_sum (const gcry_mpi_t *vector, | ||
678 | uint32_t length) | ||
679 | { | ||
680 | gcry_mpi_t elem; | ||
681 | gcry_mpi_t sum; | ||
682 | uint32_t i; | ||
683 | |||
684 | GNUNET_assert (NULL != (sum = gcry_mpi_new (0))); | ||
685 | GNUNET_assert (NULL != (elem = gcry_mpi_new (0))); | ||
686 | for (i = 0; i < length; i++) | ||
687 | { | ||
688 | gcry_mpi_mul (elem, vector[i], vector[i]); | ||
689 | gcry_mpi_add (sum, sum, elem); | ||
690 | } | ||
691 | gcry_mpi_release (elem); | ||
692 | return sum; | ||
693 | } | ||
694 | |||
695 | |||
696 | /** | ||
697 | * Compute the values | ||
698 | * (1)[]: $E_A(a_{pi(i)}) otimes E_A(- r_{pi(i)} - b_{pi(i)}) &= E_A(a_{pi(i)} - r_{pi(i)} - b_{pi(i)})$ | ||
699 | * (2)[]: $E_A(a_{pi'(i)}) otimes E_A(- r_{pi'(i)}) &= E_A(a_{pi'(i)} - r_{pi'(i)})$ | ||
700 | * S: $S := E_A(sum (r_i + b_i)^2)$ | ||
701 | * S': $S' := E_A(sum r_i^2)$ | ||
702 | * | ||
703 | * @param request the requesting session + bob's requesting peer | ||
704 | * @return #GNUNET_OK on success | ||
705 | */ | ||
706 | static int | ||
707 | compute_service_response (struct BobServiceSession *session) | ||
708 | { | ||
709 | uint32_t i; | ||
710 | unsigned int *p; | ||
711 | unsigned int *q; | ||
712 | uint32_t count; | ||
713 | gcry_mpi_t *rand; | ||
714 | gcry_mpi_t tmp; | ||
715 | const struct MpiElement *b; | ||
716 | struct GNUNET_CRYPTO_PaillierCiphertext *a; | ||
717 | struct GNUNET_CRYPTO_PaillierCiphertext *r; | ||
718 | struct GNUNET_CRYPTO_PaillierCiphertext *r_prime; | ||
719 | |||
720 | count = session->used_element_count; | ||
721 | a = session->e_a; | ||
722 | b = session->sorted_elements; | ||
723 | q = GNUNET_CRYPTO_random_permute (GNUNET_CRYPTO_QUALITY_WEAK, | ||
724 | count); | ||
725 | p = GNUNET_CRYPTO_random_permute (GNUNET_CRYPTO_QUALITY_WEAK, | ||
726 | count); | ||
727 | rand = GNUNET_malloc (sizeof (gcry_mpi_t) * count); | ||
728 | for (i = 0; i < count; i++) | ||
729 | GNUNET_assert (NULL != (rand[i] = gcry_mpi_new (0))); | ||
730 | r = GNUNET_malloc (sizeof (struct GNUNET_CRYPTO_PaillierCiphertext) * count); | ||
731 | r_prime = GNUNET_malloc (sizeof (struct GNUNET_CRYPTO_PaillierCiphertext) * count); | ||
732 | |||
733 | for (i = 0; i < count; i++) | ||
734 | { | ||
735 | int32_t svalue; | ||
736 | |||
737 | svalue = (int32_t) GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK, | ||
738 | UINT32_MAX); | ||
739 | // long to gcry_mpi_t | ||
740 | if (svalue < 0) | ||
741 | gcry_mpi_sub_ui (rand[i], | ||
742 | rand[i], | ||
743 | - svalue); | ||
744 | else | ||
745 | rand[i] = gcry_mpi_set_ui (rand[i], svalue); | ||
746 | } | ||
747 | |||
748 | tmp = gcry_mpi_new (0); | ||
749 | // encrypt the element | ||
750 | // for the sake of readability I decided to have dedicated permutation | ||
751 | // vectors, which get rid of all the lookups in p/q. | ||
752 | // however, ap/aq are not absolutely necessary but are just abstraction | ||
753 | // Calculate Kp = E(S + a_pi) (+) E(S - r_pi - b_pi) | ||
754 | for (i = 0; i < count; i++) | ||
755 | { | ||
756 | // E(S - r_pi - b_pi) | ||
757 | gcry_mpi_sub (tmp, my_offset, rand[p[i]]); | ||
758 | gcry_mpi_sub (tmp, tmp, b[p[i]].value); | ||
759 | GNUNET_assert (2 == | ||
760 | GNUNET_CRYPTO_paillier_encrypt (&session->cadet->remote_pubkey, | ||
761 | tmp, | ||
762 | 2, | ||
763 | &r[i])); | ||
764 | |||
765 | // E(S - r_pi - b_pi) * E(S + a_pi) == E(2*S + a - r - b) | ||
766 | if (GNUNET_OK != | ||
767 | GNUNET_CRYPTO_paillier_hom_add (&session->cadet->remote_pubkey, | ||
768 | &r[i], | ||
769 | &a[p[i]], | ||
770 | &r[i])) | ||
771 | { | ||
772 | GNUNET_break_op (0); | ||
773 | goto error_cleanup; | ||
774 | } | ||
775 | } | ||
776 | |||
777 | // Calculate Kq = E(S + a_qi) (+) E(S - r_qi) | ||
778 | for (i = 0; i < count; i++) | ||
779 | { | ||
780 | // E(S - r_qi) | ||
781 | gcry_mpi_sub (tmp, my_offset, rand[q[i]]); | ||
782 | GNUNET_assert (2 == | ||
783 | GNUNET_CRYPTO_paillier_encrypt (&session->cadet->remote_pubkey, | ||
784 | tmp, | ||
785 | 2, | ||
786 | &r_prime[i])); | ||
787 | |||
788 | // E(S - r_qi) * E(S + a_qi) == E(2*S + a_qi - r_qi) | ||
789 | if (GNUNET_OK != | ||
790 | GNUNET_CRYPTO_paillier_hom_add (&session->cadet->remote_pubkey, | ||
791 | &r_prime[i], | ||
792 | &a[q[i]], | ||
793 | &r_prime[i])) | ||
794 | { | ||
795 | GNUNET_break_op (0); | ||
796 | goto error_cleanup; | ||
797 | } | ||
798 | } | ||
799 | gcry_mpi_release (tmp); | ||
800 | |||
801 | // Calculate S' = E(SUM( r_i^2 )) | ||
802 | tmp = compute_square_sum (rand, count); | ||
803 | GNUNET_assert (1 == | ||
804 | GNUNET_CRYPTO_paillier_encrypt (&session->cadet->remote_pubkey, | ||
805 | tmp, | ||
806 | 1, | ||
807 | &session->s_prime)); | ||
808 | gcry_mpi_release (tmp); | ||
809 | |||
810 | // Calculate S = E(SUM( (r_i + b_i)^2 )) | ||
811 | for (i = 0; i < count; i++) | ||
812 | gcry_mpi_add (rand[i], rand[i], b[i].value); | ||
813 | tmp = compute_square_sum (rand, count); | ||
814 | GNUNET_assert (1 == | ||
815 | GNUNET_CRYPTO_paillier_encrypt (&session->cadet->remote_pubkey, | ||
816 | tmp, | ||
817 | 1, | ||
818 | &session->s)); | ||
819 | gcry_mpi_release (tmp); | ||
820 | |||
821 | session->r = r; | ||
822 | session->r_prime = r_prime; | ||
823 | |||
824 | for (i = 0; i < count; i++) | ||
825 | gcry_mpi_release (rand[i]); | ||
826 | GNUNET_free (session->e_a); | ||
827 | session->e_a = NULL; | ||
828 | GNUNET_free (p); | ||
829 | GNUNET_free (q); | ||
830 | GNUNET_free (rand); | ||
831 | return GNUNET_OK; | ||
832 | |||
833 | error_cleanup: | ||
834 | GNUNET_free (r); | ||
835 | GNUNET_free (r_prime); | ||
836 | gcry_mpi_release (tmp); | ||
837 | GNUNET_free (p); | ||
838 | GNUNET_free (q); | ||
839 | for (i = 0; i < count; i++) | ||
840 | gcry_mpi_release (rand[i]); | ||
841 | GNUNET_free (rand); | ||
842 | return GNUNET_SYSERR; | ||
843 | } | 520 | } |
844 | 521 | ||
845 | 522 | ||
@@ -896,44 +573,6 @@ element_cmp (const void *a, | |||
896 | 573 | ||
897 | 574 | ||
898 | /** | 575 | /** |
899 | * Intersection operation and receiving data via CADET from | ||
900 | * Alice are both done, compute and transmit our reply via | ||
901 | * CADET. | ||
902 | * | ||
903 | * @param s session to transmit reply for. | ||
904 | */ | ||
905 | static void | ||
906 | transmit_cryptographic_reply (struct BobServiceSession *s) | ||
907 | { | ||
908 | struct GNUNET_CADET_Channel *channel; | ||
909 | |||
910 | /* TODO: code duplication with Alice! */ | ||
911 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
912 | "Received everything, building reply for Alice\n"); | ||
913 | s->sorted_elements | ||
914 | = GNUNET_malloc (GNUNET_CONTAINER_multihashmap_size (s->intersected_elements) * | ||
915 | sizeof (struct MpiElement)); | ||
916 | s->used_element_count = 0; | ||
917 | GNUNET_CONTAINER_multihashmap_iterate (s->intersected_elements, | ||
918 | ©_element_cb, | ||
919 | s); | ||
920 | qsort (s->sorted_elements, | ||
921 | s->used_element_count, | ||
922 | sizeof (struct MpiElement), | ||
923 | &element_cmp); | ||
924 | if (GNUNET_OK != | ||
925 | compute_service_response (s)) | ||
926 | { | ||
927 | channel = s->cadet->channel; | ||
928 | s->cadet->channel = NULL; | ||
929 | GNUNET_CADET_channel_destroy (channel); | ||
930 | return; | ||
931 | } | ||
932 | transmit_bobs_cryptodata_message (s); | ||
933 | } | ||
934 | |||
935 | |||
936 | /** | ||
937 | * Handle a multipart-chunk of a request from another service to | 576 | * Handle a multipart-chunk of a request from another service to |
938 | * calculate a scalarproduct with us. | 577 | * calculate a scalarproduct with us. |
939 | * | 578 | * |
@@ -952,13 +591,21 @@ handle_alices_cryptodata_message (void *cls, | |||
952 | { | 591 | { |
953 | struct CadetIncomingSession *in = *channel_ctx; | 592 | struct CadetIncomingSession *in = *channel_ctx; |
954 | struct BobServiceSession *s; | 593 | struct BobServiceSession *s; |
955 | const struct AliceCryptodataMessage *msg; | 594 | const struct EccAliceCryptodataMessage *msg; |
956 | const struct GNUNET_CRYPTO_PaillierCiphertext *payload; | 595 | const struct GNUNET_CRYPTO_EccPoint *payload; |
957 | uint32_t contained_elements; | 596 | uint32_t contained_elements; |
958 | size_t msg_length; | 597 | size_t msg_length; |
959 | uint16_t msize; | 598 | uint16_t msize; |
960 | unsigned int max; | 599 | unsigned int max; |
961 | 600 | unsigned int i; | |
601 | const struct MpiElement *b_i; | ||
602 | gcry_mpi_point_t tmp; | ||
603 | gcry_mpi_point_t g_i; | ||
604 | gcry_mpi_point_t h_i; | ||
605 | gcry_mpi_point_t g_i_b_i; | ||
606 | gcry_mpi_point_t h_i_b_i; | ||
607 | |||
608 | /* sanity checks */ | ||
962 | if (NULL == in) | 609 | if (NULL == in) |
963 | { | 610 | { |
964 | GNUNET_break_op (0); | 611 | GNUNET_break_op (0); |
@@ -970,19 +617,36 @@ handle_alices_cryptodata_message (void *cls, | |||
970 | GNUNET_break_op (0); | 617 | GNUNET_break_op (0); |
971 | return GNUNET_SYSERR; | 618 | return GNUNET_SYSERR; |
972 | } | 619 | } |
620 | /* sort our vector for the computation */ | ||
621 | if (NULL == s->sorted_elements) | ||
622 | { | ||
623 | s->sorted_elements | ||
624 | = GNUNET_malloc (GNUNET_CONTAINER_multihashmap_size (s->intersected_elements) * | ||
625 | sizeof (struct MpiElement)); | ||
626 | s->used_element_count = 0; | ||
627 | GNUNET_CONTAINER_multihashmap_iterate (s->intersected_elements, | ||
628 | ©_element_cb, | ||
629 | s); | ||
630 | qsort (s->sorted_elements, | ||
631 | s->used_element_count, | ||
632 | sizeof (struct MpiElement), | ||
633 | &element_cmp); | ||
634 | } | ||
635 | |||
636 | /* parse message */ | ||
973 | msize = ntohs (message->size); | 637 | msize = ntohs (message->size); |
974 | if (msize <= sizeof (struct AliceCryptodataMessage)) | 638 | if (msize <= sizeof (struct EccAliceCryptodataMessage)) |
975 | { | 639 | { |
976 | GNUNET_break_op (0); | 640 | GNUNET_break_op (0); |
977 | return GNUNET_SYSERR; | 641 | return GNUNET_SYSERR; |
978 | } | 642 | } |
979 | msg = (const struct AliceCryptodataMessage *) message; | 643 | msg = (const struct EccAliceCryptodataMessage *) message; |
980 | contained_elements = ntohl (msg->contained_element_count); | 644 | contained_elements = ntohl (msg->contained_element_count); |
981 | /* Our intersection may still be ongoing, but this is nevertheless | 645 | /* Our intersection may still be ongoing, but this is nevertheless |
982 | an upper bound on the required array size */ | 646 | an upper bound on the required array size */ |
983 | max = GNUNET_CONTAINER_multihashmap_size (s->intersected_elements); | 647 | max = GNUNET_CONTAINER_multihashmap_size (s->intersected_elements); |
984 | msg_length = sizeof (struct AliceCryptodataMessage) | 648 | msg_length = sizeof (struct EccAliceCryptodataMessage) |
985 | + contained_elements * sizeof (struct GNUNET_CRYPTO_PaillierCiphertext); | 649 | + contained_elements * sizeof (struct GNUNET_CRYPTO_EccPoint); |
986 | if ( (msize != msg_length) || | 650 | if ( (msize != msg_length) || |
987 | (0 == contained_elements) || | 651 | (0 == contained_elements) || |
988 | (contained_elements > UINT16_MAX) || | 652 | (contained_elements > UINT16_MAX) || |
@@ -994,23 +658,54 @@ handle_alices_cryptodata_message (void *cls, | |||
994 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 658 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
995 | "Received %u crypto values from Alice\n", | 659 | "Received %u crypto values from Alice\n", |
996 | (unsigned int) contained_elements); | 660 | (unsigned int) contained_elements); |
661 | payload = (const struct GNUNET_CRYPTO_EccPoint *) &msg[1]; | ||
997 | 662 | ||
998 | payload = (const struct GNUNET_CRYPTO_PaillierCiphertext *) &msg[1]; | 663 | for (i=0;i<contained_elements;i++) |
999 | if (NULL == s->e_a) | 664 | { |
1000 | s->e_a = GNUNET_malloc (sizeof (struct GNUNET_CRYPTO_PaillierCiphertext) * | 665 | b_i = &s->sorted_elements[i + s->cadet_received_element_count]; |
1001 | max); | 666 | g_i = GNUNET_CRYPTO_ecc_bin_to_point (edc, |
1002 | memcpy (&s->e_a[s->cadet_received_element_count], | 667 | &payload[i * 2]); |
1003 | payload, | 668 | g_i_b_i = GNUNET_CRYPTO_ecc_pmul_mpi (edc, |
1004 | sizeof (struct GNUNET_CRYPTO_PaillierCiphertext) * contained_elements); | 669 | g_i, |
670 | b_i->value); | ||
671 | gcry_mpi_point_release (g_i); | ||
672 | h_i = GNUNET_CRYPTO_ecc_bin_to_point (edc, | ||
673 | &payload[i * 2 + 1]); | ||
674 | h_i_b_i = GNUNET_CRYPTO_ecc_pmul_mpi (edc, | ||
675 | h_i, | ||
676 | b_i->value); | ||
677 | gcry_mpi_point_release (h_i); | ||
678 | if (0 == i + s->cadet_received_element_count) | ||
679 | { | ||
680 | /* first iteration, nothing to add */ | ||
681 | s->prod_g_i_b_i = g_i_b_i; | ||
682 | s->prod_h_i_b_i = h_i_b_i; | ||
683 | } | ||
684 | else | ||
685 | { | ||
686 | /* further iterations, cummulate resulting value */ | ||
687 | tmp = GNUNET_CRYPTO_ecc_add (edc, | ||
688 | s->prod_g_i_b_i, | ||
689 | g_i_b_i); | ||
690 | gcry_mpi_point_release (s->prod_g_i_b_i); | ||
691 | gcry_mpi_point_release (g_i_b_i); | ||
692 | s->prod_g_i_b_i = tmp; | ||
693 | tmp = GNUNET_CRYPTO_ecc_add (edc, | ||
694 | s->prod_h_i_b_i, | ||
695 | h_i_b_i); | ||
696 | gcry_mpi_point_release (s->prod_h_i_b_i); | ||
697 | gcry_mpi_point_release (h_i_b_i); | ||
698 | s->prod_h_i_b_i = tmp; | ||
699 | } | ||
700 | } | ||
1005 | s->cadet_received_element_count += contained_elements; | 701 | s->cadet_received_element_count += contained_elements; |
1006 | |||
1007 | if ( (s->cadet_received_element_count == max) && | 702 | if ( (s->cadet_received_element_count == max) && |
1008 | (NULL == s->intersection_op) ) | 703 | (NULL == s->intersection_op) ) |
1009 | { | 704 | { |
1010 | /* intersection has finished also on our side, and | 705 | /* intersection has finished also on our side, and |
1011 | we got the full set, so we can proceed with the | 706 | we got the full set, so we can proceed with the |
1012 | CADET response(s) */ | 707 | CADET response(s) */ |
1013 | transmit_cryptographic_reply (s); | 708 | transmit_bobs_cryptodata_message (s); |
1014 | } | 709 | } |
1015 | GNUNET_CADET_receive_done (s->cadet->channel); | 710 | GNUNET_CADET_receive_done (s->cadet->channel); |
1016 | return GNUNET_OK; | 711 | return GNUNET_OK; |
@@ -1062,7 +757,7 @@ cb_intersection_element_removed (void *cls, | |||
1062 | { | 757 | { |
1063 | /* CADET transmission from Alice is also already done, | 758 | /* CADET transmission from Alice is also already done, |
1064 | start with our own reply */ | 759 | start with our own reply */ |
1065 | transmit_cryptographic_reply (s); | 760 | transmit_bobs_cryptodata_message (s); |
1066 | } | 761 | } |
1067 | return; | 762 | return; |
1068 | case GNUNET_SET_STATUS_HALF_DONE: | 763 | case GNUNET_SET_STATUS_HALF_DONE: |
@@ -1142,14 +837,9 @@ handle_alices_computation_request (void *cls, | |||
1142 | { | 837 | { |
1143 | struct CadetIncomingSession *in = *channel_ctx; | 838 | struct CadetIncomingSession *in = *channel_ctx; |
1144 | struct BobServiceSession *s; | 839 | struct BobServiceSession *s; |
1145 | const struct ServiceRequestMessage *msg; | 840 | const struct EccServiceRequestMessage *msg; |
1146 | 841 | ||
1147 | if (ntohs (message->size) != sizeof (struct ServiceRequestMessage)) | 842 | msg = (const struct EccServiceRequestMessage *) message; |
1148 | { | ||
1149 | GNUNET_break_op (0); | ||
1150 | return GNUNET_SYSERR; | ||
1151 | } | ||
1152 | msg = (const struct ServiceRequestMessage *) message; | ||
1153 | if (GNUNET_YES == in->in_map) | 843 | if (GNUNET_YES == in->in_map) |
1154 | { | 844 | { |
1155 | GNUNET_break_op (0); | 845 | GNUNET_break_op (0); |
@@ -1162,7 +852,6 @@ handle_alices_computation_request (void *cls, | |||
1162 | return GNUNET_SYSERR; | 852 | return GNUNET_SYSERR; |
1163 | } | 853 | } |
1164 | in->session_id = msg->session_id; | 854 | in->session_id = msg->session_id; |
1165 | in->remote_pubkey = msg->public_key; | ||
1166 | GNUNET_assert (GNUNET_YES == | 855 | GNUNET_assert (GNUNET_YES == |
1167 | GNUNET_CONTAINER_multihashmap_put (cadet_sessions, | 856 | GNUNET_CONTAINER_multihashmap_put (cadet_sessions, |
1168 | &in->session_id, | 857 | &in->session_id, |
@@ -1462,6 +1151,11 @@ shutdown_task (void *cls, | |||
1462 | GNUNET_CADET_disconnect (my_cadet); | 1151 | GNUNET_CADET_disconnect (my_cadet); |
1463 | my_cadet = NULL; | 1152 | my_cadet = NULL; |
1464 | } | 1153 | } |
1154 | if (NULL != edc) | ||
1155 | { | ||
1156 | GNUNET_CRYPTO_ecc_dlog_release (edc); | ||
1157 | edc = NULL; | ||
1158 | } | ||
1465 | GNUNET_CONTAINER_multihashmap_destroy (client_sessions); | 1159 | GNUNET_CONTAINER_multihashmap_destroy (client_sessions); |
1466 | client_sessions = NULL; | 1160 | client_sessions = NULL; |
1467 | GNUNET_CONTAINER_multihashmap_destroy (cadet_sessions); | 1161 | GNUNET_CONTAINER_multihashmap_destroy (cadet_sessions); |
@@ -1521,29 +1215,23 @@ run (void *cls, | |||
1521 | }; | 1215 | }; |
1522 | static const struct GNUNET_CADET_MessageHandler cadet_handlers[] = { | 1216 | static const struct GNUNET_CADET_MessageHandler cadet_handlers[] = { |
1523 | { &handle_alices_computation_request, | 1217 | { &handle_alices_computation_request, |
1524 | GNUNET_MESSAGE_TYPE_SCALARPRODUCT_SESSION_INITIALIZATION, | 1218 | GNUNET_MESSAGE_TYPE_SCALARPRODUCT_ECC_SESSION_INITIALIZATION, |
1525 | sizeof (struct ServiceRequestMessage) }, | 1219 | sizeof (struct EccServiceRequestMessage) }, |
1526 | { &handle_alices_cryptodata_message, | 1220 | { &handle_alices_cryptodata_message, |
1527 | GNUNET_MESSAGE_TYPE_SCALARPRODUCT_ALICE_CRYPTODATA, | 1221 | GNUNET_MESSAGE_TYPE_SCALARPRODUCT_ECC_ALICE_CRYPTODATA, |
1528 | 0}, | 1222 | 0}, |
1529 | { NULL, 0, 0} | 1223 | { NULL, 0, 0} |
1530 | }; | 1224 | }; |
1531 | static const uint32_t ports[] = { | 1225 | static const uint32_t ports[] = { |
1532 | GNUNET_APPLICATION_TYPE_SCALARPRODUCT, | 1226 | GNUNET_APPLICATION_TYPE_SCALARPRODUCT_ECC, |
1533 | 0 | 1227 | 0 |
1534 | }; | 1228 | }; |
1535 | 1229 | ||
1536 | cfg = c; | 1230 | cfg = c; |
1537 | /* | 1231 | /* We don't really do DLOG, so we can setup with very minimal resources */ |
1538 | offset has to be sufficiently small to allow computation of: | 1232 | edc = GNUNET_CRYPTO_ecc_dlog_prepare (4 /* max value */, |
1539 | m1+m2 mod n == (S + a) + (S + b) mod n, | 1233 | 2 /* RAM */); |
1540 | if we have more complex operations, this factor needs to be lowered */ | 1234 | |
1541 | my_offset = gcry_mpi_new (GNUNET_CRYPTO_PAILLIER_BITS / 3); | ||
1542 | gcry_mpi_set_bit (my_offset, | ||
1543 | GNUNET_CRYPTO_PAILLIER_BITS / 3); | ||
1544 | |||
1545 | GNUNET_CRYPTO_paillier_create (&my_pubkey, | ||
1546 | &my_privkey); | ||
1547 | GNUNET_SERVER_add_handlers (server, | 1235 | GNUNET_SERVER_add_handlers (server, |
1548 | server_handlers); | 1236 | server_handlers); |
1549 | GNUNET_SERVER_disconnect_notify (server, | 1237 | GNUNET_SERVER_disconnect_notify (server, |
@@ -1589,4 +1277,4 @@ main (int argc, | |||
1589 | &run, NULL)) ? 0 : 1; | 1277 | &run, NULL)) ? 0 : 1; |
1590 | } | 1278 | } |
1591 | 1279 | ||
1592 | /* end of gnunet-service-scalarproduct_bob.c */ | 1280 | /* end of gnunet-service-scalarproduct-ecc_bob.c */ |