aboutsummaryrefslogtreecommitdiff
path: root/src/scalarproduct/gnunet-service-scalarproduct-ecc_bob.c
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2015-09-05 18:03:58 +0000
committerChristian Grothoff <christian@grothoff.org>2015-09-05 18:03:58 +0000
commit14f9ba0d86025dfd2defb1635899c75da4815d16 (patch)
treed88c4404b496a1fc27fc0c4b6239c5ec4aee4510 /src/scalarproduct/gnunet-service-scalarproduct-ecc_bob.c
parent29ee3958cd75cf5f91846f8235278061e6c9309f (diff)
downloadgnunet-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.c562
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
247static const struct GNUNET_CONFIGURATION_Handle *cfg; 216static const struct GNUNET_CONFIGURATION_Handle *cfg;
248 217
249/** 218/**
250 * Service's own public key
251 */
252static struct GNUNET_CRYPTO_PaillierPublicKey my_pubkey;
253
254/**
255 * Service's own private key
256 */
257static 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 */
262static 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 */
267static struct GNUNET_CONTAINER_MultiHashMap *client_sessions; 221static struct GNUNET_CONTAINER_MultiHashMap *client_sessions;
@@ -276,6 +230,11 @@ static struct GNUNET_CONTAINER_MultiHashMap *cadet_sessions;
276 */ 230 */
277static struct GNUNET_CADET_Handle *my_cadet; 231static struct GNUNET_CADET_Handle *my_cadet;
278 232
233/**
234 * Context for DLOG operations on a curve.
235 */
236static 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 */
554static void
555transmit_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 */
612static void 496static void
613transmit_bobs_cryptodata_message (struct BobServiceSession *s) 497transmit_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 */
676static gcry_mpi_t
677compute_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 */
706static int
707compute_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 */
905static void
906transmit_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 &copy_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 &copy_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 */