GNUnet  0.10.x
gnunet-service-scalarproduct_alice.c
Go to the documentation of this file.
1 /*
2  This file is part of GNUnet.
3  Copyright (C) 2013, 2014, 2017 GNUnet e.V.
4 
5  GNUnet is free software: you can redistribute it and/or modify it
6  under the terms of the GNU Affero General Public License as published
7  by the Free Software Foundation, either version 3 of the License,
8  or (at your option) any later version.
9 
10  GNUnet is distributed in the hope that it will be useful, but
11  WITHOUT ANY WARRANTY; without even the implied warranty of
12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13  Affero General Public License for more details.
14 
15  You should have received a copy of the GNU Affero General Public License
16  along with this program. If not, see <http://www.gnu.org/licenses/>.
17 
18  SPDX-License-Identifier: AGPL3.0-or-later
19  */
26 #include "platform.h"
27 #include <limits.h>
28 #include <gcrypt.h>
29 #include "gnunet_util_lib.h"
30 #include "gnunet_core_service.h"
31 #include "gnunet_cadet_service.h"
32 #include "gnunet_applications.h"
33 #include "gnunet_protocols.h"
35 #include "gnunet_set_service.h"
36 #include "scalarproduct.h"
38 
39 #define LOG(kind, ...) \
40  GNUNET_log_from (kind, "scalarproduct-alice", __VA_ARGS__)
41 
45 struct MpiElement
46 {
52  const struct GNUNET_HashCode *key;
53 
57  gcry_mpi_t value;
58 };
59 
60 
66 {
67 
71  struct GNUNET_HashCode session_id;
72 
76  struct GNUNET_PeerIdentity peer;
77 
81  struct GNUNET_SERVICE_Client *client;
82 
86  struct GNUNET_MQ_Handle *client_mq;
87 
91  struct GNUNET_MQ_Handle *cadet_mq;
92 
97  struct GNUNET_CONTAINER_MultiHashMap *intersected_elements;
98 
103  struct GNUNET_SET_Handle *intersection_set;
104 
109  struct GNUNET_SET_OperationHandle *intersection_op;
110 
114  struct GNUNET_SET_ListenHandle *intersection_listen;
115 
119  struct GNUNET_CADET_Channel *channel;
120 
124  struct MpiElement *sorted_elements;
125 
130 
135 
140 
145 
149  gcry_mpi_t product;
150 
155  uint32_t total;
156 
162  uint32_t used_element_count;
163 
168  uint32_t client_received_element_count;
169 
175 
183 
188  int in_destroy;
189 };
190 
191 
195 static const struct GNUNET_CONFIGURATION_Handle *cfg;
196 
201 
206 
210 static gcry_mpi_t my_offset;
211 
216 
217 
226 static int
227 free_element_cb (void *cls, const struct GNUNET_HashCode *key, void *value)
228 {
230 
231  GNUNET_free (e);
232  return GNUNET_OK;
233 }
234 
235 
241 static void
243 {
244  if (GNUNET_YES == s->in_destroy)
245  return;
246  s->in_destroy = GNUNET_YES;
247  if (NULL != s->client)
248  {
249  struct GNUNET_SERVICE_Client *c = s->client;
250 
251  s->client = NULL;
253  }
254  if (NULL != s->channel)
255  {
257  s->channel = NULL;
258  }
259  if (NULL != s->intersected_elements)
260  {
263  s);
265  s->intersected_elements = NULL;
266  }
267  if (NULL != s->intersection_listen)
268  {
270  s->intersection_listen = NULL;
271  }
272  if (NULL != s->intersection_op)
273  {
275  s->intersection_op = NULL;
276  }
277  if (NULL != s->intersection_set)
278  {
280  s->intersection_set = NULL;
281  }
282  if (NULL != s->sorted_elements)
283  {
284  for (unsigned int i = 0; i < s->used_element_count; i++)
285  gcry_mpi_release (s->sorted_elements[i].value);
287  s->sorted_elements = NULL;
288  }
289  if (NULL != s->r)
290  {
291  GNUNET_free (s->r);
292  s->r = NULL;
293  }
294  if (NULL != s->r_prime)
295  {
296  GNUNET_free (s->r_prime);
297  s->r_prime = NULL;
298  }
299  if (NULL != s->product)
300  {
301  gcry_mpi_release (s->product);
302  s->product = NULL;
303  }
304  GNUNET_free (s);
305 }
306 
307 
314 static void
316 {
317  struct ClientResponseMessage *msg;
318  struct GNUNET_MQ_Envelope *e;
319 
320  if (NULL == session->client_mq)
321  return; /* no client left to be notified */
322  GNUNET_log (
324  "Sending session-end notification with status %d to client for session %s\n",
325  session->status,
326  GNUNET_h2s (&session->session_id));
328  msg->product_length = htonl (0);
329  msg->status = htonl (session->status);
330  GNUNET_MQ_send (session->client_mq, e);
331 }
332 
333 
340 static void
342 {
343  struct ClientResponseMessage *msg;
344  struct GNUNET_MQ_Envelope *e;
345  unsigned char *product_exported = NULL;
346  size_t product_length = 0;
347  int32_t range;
348  gcry_error_t rc;
349  int sign;
350  gcry_mpi_t value;
351 
352  if (NULL == s->product)
353  {
354  GNUNET_break (0);
356  return;
357  }
358  value = gcry_mpi_new (0);
359  sign = gcry_mpi_cmp_ui (s->product, 0);
360  if (0 > sign)
361  {
362  range = -1;
363  gcry_mpi_sub (value, value, s->product);
364  }
365  else if (0 < sign)
366  {
367  range = 1;
368  gcry_mpi_add (value, value, s->product);
369  }
370  else
371  {
372  /* result is exactly zero */
373  range = 0;
374  }
375  gcry_mpi_release (s->product);
376  s->product = NULL;
377 
378  if ((0 != range) && (0 != (rc = gcry_mpi_aprint (GCRYMPI_FMT_STD,
379  &product_exported,
380  &product_length,
381  value))))
382  {
383  LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_mpi_scan", rc);
385  return;
386  }
387  gcry_mpi_release (value);
388  e = GNUNET_MQ_msg_extra (msg,
389  product_length,
392  msg->range = htonl (range);
393  msg->product_length = htonl (product_length);
394  if (NULL != product_exported)
395  {
396  GNUNET_memcpy (&msg[1], product_exported, product_length);
397  GNUNET_free (product_exported);
398  }
399  GNUNET_MQ_send (s->client_mq, e);
401  "Sent result to client, session %s has ended!\n",
402  GNUNET_h2s (&s->session_id));
403 }
404 
405 
415 static void
416 cb_channel_destruction (void *cls, const struct GNUNET_CADET_Channel *channel)
417 {
418  struct AliceServiceSession *s = cls;
419 
421  "Peer disconnected, terminating session %s with peer %s\n",
422  GNUNET_h2s (&s->session_id),
423  GNUNET_i2s (&s->peer));
425  {
426  /* We didn't get an answer yet, fail with error */
429  }
430  s->channel = NULL;
431 }
432 
433 
441 static gcry_mpi_t
443  uint32_t length)
444 {
445  gcry_mpi_t elem;
446  gcry_mpi_t sum;
447  uint32_t i;
448 
449  GNUNET_assert (NULL != (sum = gcry_mpi_new (0)));
450  GNUNET_assert (NULL != (elem = gcry_mpi_new (0)));
451  for (i = 0; i < length; i++)
452  {
453  gcry_mpi_mul (elem, vector[i].value, vector[i].value);
454  gcry_mpi_add (sum, sum, elem);
455  }
456  gcry_mpi_release (elem);
457  return sum;
458 }
459 
460 
468 static gcry_mpi_t
469 compute_square_sum (const gcry_mpi_t *vector, uint32_t length)
470 {
471  gcry_mpi_t elem;
472  gcry_mpi_t sum;
473  uint32_t i;
474 
475  GNUNET_assert (NULL != (sum = gcry_mpi_new (0)));
476  GNUNET_assert (NULL != (elem = gcry_mpi_new (0)));
477  for (i = 0; i < length; i++)
478  {
479  gcry_mpi_mul (elem, vector[i], vector[i]);
480  gcry_mpi_add (sum, sum, elem);
481  }
482  gcry_mpi_release (elem);
483  return sum;
484 }
485 
486 
493 static gcry_mpi_t
495 {
496  uint32_t count;
497  gcry_mpi_t t;
498  gcry_mpi_t u;
499  gcry_mpi_t u_prime;
500  gcry_mpi_t p;
501  gcry_mpi_t p_prime;
502  gcry_mpi_t tmp;
503  gcry_mpi_t r[session->used_element_count];
504  gcry_mpi_t r_prime[session->used_element_count];
505  gcry_mpi_t s;
506  gcry_mpi_t s_prime;
507  unsigned int i;
508 
509  count = session->used_element_count;
510  // due to the introduced static offset S, we now also have to remove this
511  // from the E(a_pi)(+)E(-b_pi-r_pi) and E(a_qi)(+)E(-r_qi) twice each,
512  // the result is E((S + a_pi) + (S -b_pi-r_pi)) and E(S + a_qi + S - r_qi)
513  for (i = 0; i < count; i++)
514  {
515  r[i] = gcry_mpi_new (0);
517  &my_pubkey,
518  &session->r[i],
519  r[i]);
520  gcry_mpi_sub (r[i], r[i], my_offset);
521  gcry_mpi_sub (r[i], r[i], my_offset);
522  r_prime[i] = gcry_mpi_new (0);
524  &my_pubkey,
525  &session->r_prime[i],
526  r_prime[i]);
527  gcry_mpi_sub (r_prime[i], r_prime[i], my_offset);
528  gcry_mpi_sub (r_prime[i], r_prime[i], my_offset);
529  }
530 
531  // calculate t = sum(ai)
532  t = compute_square_sum_mpi_elements (session->sorted_elements, count);
533  // calculate U
534  u = gcry_mpi_new (0);
535  tmp = compute_square_sum (r, count);
536  gcry_mpi_sub (u, u, tmp);
537  gcry_mpi_release (tmp);
538 
539  //calculate U'
540  u_prime = gcry_mpi_new (0);
541  tmp = compute_square_sum (r_prime, count);
542  gcry_mpi_sub (u_prime, u_prime, tmp);
543 
544  GNUNET_assert (p = gcry_mpi_new (0));
545  GNUNET_assert (p_prime = gcry_mpi_new (0));
546  GNUNET_assert (s = gcry_mpi_new (0));
547  GNUNET_assert (s_prime = gcry_mpi_new (0));
548 
549  // compute P
552  &my_pubkey,
553  &session->s_prime,
554  s_prime);
555 
556  // compute P
557  gcry_mpi_add (p, s, t);
558  gcry_mpi_add (p, p, u);
559 
560  // compute P'
561  gcry_mpi_add (p_prime, s_prime, t);
562  gcry_mpi_add (p_prime, p_prime, u_prime);
563 
564  gcry_mpi_release (t);
565  gcry_mpi_release (u);
566  gcry_mpi_release (u_prime);
567  gcry_mpi_release (s);
568  gcry_mpi_release (s_prime);
569 
570  // compute product
571  gcry_mpi_sub (p, p, p_prime);
572  gcry_mpi_release (p_prime);
573  tmp = gcry_mpi_set_ui (tmp, 2);
574  gcry_mpi_div (p, NULL, p, tmp, 0);
575 
576  gcry_mpi_release (tmp);
577  for (i = 0; i < count; i++)
578  {
579  gcry_mpi_release (session->sorted_elements[i].value);
580  gcry_mpi_release (r[i]);
581  gcry_mpi_release (r_prime[i]);
582  }
583  GNUNET_free (session->sorted_elements);
584  session->sorted_elements = NULL;
585  GNUNET_free (session->r);
586  session->r = NULL;
587  GNUNET_free (session->r_prime);
588  session->r_prime = NULL;
589 
590  return p;
591 }
592 
593 
603 static int
605  void *cls,
606  const struct BobCryptodataMultipartMessage *msg)
607 {
608  struct AliceServiceSession *s = cls;
609  uint32_t contained;
610  size_t msg_size;
611  size_t required_size;
612 
613  msg_size = ntohs (msg->header.size);
614  contained = ntohl (msg->contained_element_count);
615  required_size =
616  sizeof (struct BobCryptodataMultipartMessage) +
617  2 * contained * sizeof (struct GNUNET_CRYPTO_PaillierCiphertext);
618  if ((required_size != msg_size) ||
619  (s->cadet_received_element_count + contained > s->used_element_count))
620  {
621  GNUNET_break (0);
622  return GNUNET_SYSERR;
623  }
624  return GNUNET_OK;
625 }
626 
634 static void
636  void *cls,
637  const struct BobCryptodataMultipartMessage *msg)
638 {
639  struct AliceServiceSession *s = cls;
641  size_t i;
642  uint32_t contained;
643 
644  contained = ntohl (msg->contained_element_count);
646  "Received %u additional crypto values from Bob\n",
647  (unsigned int) contained);
648 
649  payload = (const struct GNUNET_CRYPTO_PaillierCiphertext *) &msg[1];
650  /* Convert each k[][perm] to its MPI_value */
651  for (i = 0; i < contained; i++)
652  {
654  &payload[2 * i],
655  sizeof (struct GNUNET_CRYPTO_PaillierCiphertext));
657  &payload[2 * i],
658  sizeof (struct GNUNET_CRYPTO_PaillierCiphertext));
659  }
660  s->cadet_received_element_count += contained;
663  return; /* more to come */
664 
667 }
668 
669 
679 static int
681  const struct BobCryptodataMessage *msg)
682 {
683  struct AliceServiceSession *s = cls;
684  uint32_t contained;
685  uint16_t msg_size;
686  size_t required_size;
687 
688  msg_size = ntohs (msg->header.size);
689  contained = ntohl (msg->contained_element_count);
690  required_size =
691  sizeof (struct BobCryptodataMessage) +
692  2 * contained * sizeof (struct GNUNET_CRYPTO_PaillierCiphertext) +
693  2 * sizeof (struct GNUNET_CRYPTO_PaillierCiphertext);
694  if ((msg_size != required_size) || (contained > UINT16_MAX) ||
695  (s->used_element_count < contained))
696  {
697  GNUNET_break_op (0);
698  return GNUNET_SYSERR;
699  }
700  if (NULL == s->sorted_elements)
701  {
702  /* we're not ready yet, how can Bob be? */
703  GNUNET_break_op (0);
704  return GNUNET_SYSERR;
705  }
707  {
708  /* we're not ready yet, how can Bob be? */
709  GNUNET_break_op (0);
710  return GNUNET_SYSERR;
711  }
712  return GNUNET_OK;
713 }
714 
715 
723 static void
725  const struct BobCryptodataMessage *msg)
726 {
727  struct AliceServiceSession *s = cls;
729  uint32_t i;
730  uint32_t contained;
731 
732  contained = ntohl (msg->contained_element_count);
734  "Received %u crypto values from Bob\n",
735  (unsigned int) contained);
736  payload = (const struct GNUNET_CRYPTO_PaillierCiphertext *) &msg[1];
737  GNUNET_memcpy (&s->s,
738  &payload[0],
739  sizeof (struct GNUNET_CRYPTO_PaillierCiphertext));
740  GNUNET_memcpy (&s->s_prime,
741  &payload[1],
742  sizeof (struct GNUNET_CRYPTO_PaillierCiphertext));
743  payload = &payload[2];
744 
749  for (i = 0; i < contained; i++)
750  {
751  GNUNET_memcpy (&s->r[i],
752  &payload[2 * i],
753  sizeof (struct GNUNET_CRYPTO_PaillierCiphertext));
754  GNUNET_memcpy (&s->r_prime[i],
755  &payload[2 * i + 1],
756  sizeof (struct GNUNET_CRYPTO_PaillierCiphertext));
757  }
758  s->cadet_received_element_count = contained;
760 
762  {
763  /* More to come */
764  return;
765  }
768 }
769 
770 
779 static int
780 copy_element_cb (void *cls, const struct GNUNET_HashCode *key, void *value)
781 {
782  struct AliceServiceSession *s = cls;
784  gcry_mpi_t mval;
785  int64_t val;
786 
787  mval = gcry_mpi_new (0);
788  val = (int64_t) GNUNET_ntohll (e->value);
789  if (0 > val)
790  gcry_mpi_sub_ui (mval, mval, -val);
791  else
792  gcry_mpi_add_ui (mval, mval, val);
795  s->used_element_count++;
796  return GNUNET_OK;
797 }
798 
799 
807 static int
808 element_cmp (const void *a, const void *b)
809 {
810  const struct MpiElement *ma = a;
811  const struct MpiElement *mb = b;
812 
813  return GNUNET_CRYPTO_hash_cmp (ma->key, mb->key);
814 }
815 
816 
821 #define ELEMENT_CAPACITY \
822  ((GNUNET_CONSTANTS_MAX_CADET_MESSAGE_SIZE - 1 - \
823  sizeof (struct AliceCryptodataMessage)) / \
824  sizeof (struct GNUNET_CRYPTO_PaillierCiphertext))
825 
826 
833 static void
835 {
836  struct AliceCryptodataMessage *msg;
837  struct GNUNET_MQ_Envelope *e;
839  unsigned int i;
840  uint32_t todo_count;
841  gcry_mpi_t a;
842  uint32_t off;
843 
846  sizeof (struct MpiElement));
847  s->used_element_count = 0;
850  s);
852  "Finished intersection, %d items remain\n",
853  s->used_element_count);
854  qsort (s->sorted_elements,
856  sizeof (struct MpiElement),
857  &element_cmp);
858  off = 0;
859  while (off < s->used_element_count)
860  {
861  todo_count = s->used_element_count - off;
862  if (todo_count > ELEMENT_CAPACITY)
863  todo_count = ELEMENT_CAPACITY;
865  "Sending %u/%u crypto values to Bob\n",
866  (unsigned int) todo_count,
867  (unsigned int) s->used_element_count);
868 
869  e =
870  GNUNET_MQ_msg_extra (msg,
871  todo_count *
872  sizeof (struct GNUNET_CRYPTO_PaillierCiphertext),
874  msg->contained_element_count = htonl (todo_count);
875  payload = (struct GNUNET_CRYPTO_PaillierCiphertext *) &msg[1];
876  a = gcry_mpi_new (0);
877  for (i = off; i < off + todo_count; i++)
878  {
879  gcry_mpi_add (a, s->sorted_elements[i].value, my_offset);
880  GNUNET_assert (
881  3 ==
882  GNUNET_CRYPTO_paillier_encrypt (&my_pubkey, a, 3, &payload[i - off]));
883  }
884  gcry_mpi_release (a);
885  off += todo_count;
886  GNUNET_MQ_send (s->cadet_mq, e);
887  }
888 }
889 
890 
901 static void
903  const struct GNUNET_SET_Element *element,
904  uint64_t current_size,
906 {
907  struct AliceServiceSession *s = cls;
908  struct GNUNET_SCALARPRODUCT_Element *se;
909 
910  switch (status)
911  {
913  /* this element has been removed from the set */
915  element->data);
916  GNUNET_assert (NULL != se);
918  "Intersection removed element with key %s and value %lld\n",
919  GNUNET_h2s (&se->key),
920  (long long) GNUNET_ntohll (se->value));
921  GNUNET_assert (
922  GNUNET_YES ==
924  element->data,
925  se));
926  GNUNET_free (se);
927  return;
929  s->intersection_op = NULL;
930  if (NULL != s->intersection_set)
931  {
933  s->intersection_set = NULL;
934  }
936  return;
938  /* unexpected for intersection */
939  GNUNET_break (0);
940  return;
942  /* unhandled status code */
943  LOG (GNUNET_ERROR_TYPE_DEBUG, "Set intersection failed!\n");
944  if (NULL != s->intersection_listen)
945  {
947  s->intersection_listen = NULL;
948  }
949  s->intersection_op = NULL;
950  if (NULL != s->intersection_set)
951  {
953  s->intersection_set = NULL;
954  }
957  return;
958  default:
959  GNUNET_break (0);
960  return;
961  }
962 }
963 
964 
980 static void
982  const struct GNUNET_PeerIdentity *other_peer,
983  const struct GNUNET_MessageHeader *context_msg,
984  struct GNUNET_SET_Request *request)
985 {
986  struct AliceServiceSession *s = cls;
987 
988  if (0 != GNUNET_memcmp (other_peer, &s->peer))
989  {
990  GNUNET_break_op (0);
991  return;
992  }
993  s->intersection_op = GNUNET_SET_accept (request,
995  (struct GNUNET_SET_Option[]){{0}},
997  s);
998  if (NULL == s->intersection_op)
999  {
1000  GNUNET_break (0);
1003  return;
1004  }
1006  {
1007  GNUNET_break (0);
1010  return;
1011  }
1012 }
1013 
1014 
1020 static void
1022 {
1023  struct GNUNET_MQ_MessageHandler cadet_handlers[] =
1024  {GNUNET_MQ_hd_var_size (bobs_cryptodata_message,
1026  struct BobCryptodataMessage,
1027  s),
1029  bobs_cryptodata_multipart,
1032  s),
1034  struct ServiceRequestMessage *msg;
1035  struct GNUNET_MQ_Envelope *e;
1036 
1038  "Creating new channel for session with key %s.\n",
1039  GNUNET_h2s (&s->session_id));
1040  s->channel = GNUNET_CADET_channel_create (my_cadet,
1041  s,
1042  &s->peer,
1043  &s->session_id,
1044  NULL,
1046  cadet_handlers);
1047  if (NULL == s->channel)
1048  {
1051  return;
1052  }
1056  &s->session_id,
1058  s);
1059  if (NULL == s->intersection_listen)
1060  {
1063  s->channel = NULL;
1065  return;
1066  }
1067 
1068  e = GNUNET_MQ_msg (msg,
1070  msg->session_id = s->session_id;
1071  msg->public_key = my_pubkey;
1072  GNUNET_MQ_send (s->cadet_mq, e);
1073 }
1074 
1075 
1084 static int
1086  void *cls,
1088 {
1089  struct AliceServiceSession *s = cls;
1090  uint32_t contained_count;
1091  uint16_t msize;
1092 
1093  msize = ntohs (msg->header.size);
1094  contained_count = ntohl (msg->element_count_contained);
1095  if ((msize !=
1096  (sizeof (struct ComputationBobCryptodataMultipartMessage) +
1097  contained_count * sizeof (struct GNUNET_SCALARPRODUCT_Element))) ||
1098  (0 == contained_count) ||
1099  (s->total == s->client_received_element_count) ||
1100  (s->total < s->client_received_element_count + contained_count))
1101  {
1102  GNUNET_break_op (0);
1103  return GNUNET_SYSERR;
1104  }
1105  return GNUNET_OK;
1106 }
1107 
1108 
1116 static void
1118  void *cls,
1120 {
1121  struct AliceServiceSession *s = cls;
1122  uint32_t contained_count;
1123  const struct GNUNET_SCALARPRODUCT_Element *elements;
1124  struct GNUNET_SET_Element set_elem;
1125  struct GNUNET_SCALARPRODUCT_Element *elem;
1126 
1127  contained_count = ntohl (msg->element_count_contained);
1128  s->client_received_element_count += contained_count;
1129  elements = (const struct GNUNET_SCALARPRODUCT_Element *) &msg[1];
1130  for (uint32_t i = 0; i < contained_count; i++)
1131  {
1132  elem = GNUNET_new (struct GNUNET_SCALARPRODUCT_Element);
1133  GNUNET_memcpy (elem,
1134  &elements[i],
1135  sizeof (struct GNUNET_SCALARPRODUCT_Element));
1138  &elem->key,
1139  elem,
1141  {
1142  GNUNET_break (0);
1143  GNUNET_free (elem);
1144  continue;
1145  }
1146  set_elem.data = &elem->key;
1147  set_elem.size = sizeof (elem->key);
1148  set_elem.element_type = 0;
1149  GNUNET_SET_add_element (s->intersection_set, &set_elem, NULL, NULL);
1150  s->used_element_count++;
1151  }
1153  if (s->total != s->client_received_element_count)
1154  {
1155  /* more to come */
1156  return;
1157  }
1159 }
1160 
1161 
1170 static int
1172  const struct AliceComputationMessage *msg)
1173 {
1174  struct AliceServiceSession *s = cls;
1175  uint16_t msize;
1176  uint32_t total_count;
1177  uint32_t contained_count;
1178 
1179  if (NULL != s->intersected_elements)
1180  {
1181  /* only one concurrent session per client connection allowed,
1182  simplifies logic a lot... */
1183  GNUNET_break (0);
1184  return GNUNET_SYSERR;
1185  }
1186  msize = ntohs (msg->header.size);
1187  total_count = ntohl (msg->element_count_total);
1188  contained_count = ntohl (msg->element_count_contained);
1189  if ((0 == total_count) || (0 == contained_count) ||
1190  (msize !=
1191  (sizeof (struct AliceComputationMessage) +
1192  contained_count * sizeof (struct GNUNET_SCALARPRODUCT_Element))))
1193  {
1194  GNUNET_break_op (0);
1195  return GNUNET_SYSERR;
1196  }
1197  return GNUNET_OK;
1198 }
1199 
1200 
1208 static void
1210  const struct AliceComputationMessage *msg)
1211 {
1212  struct AliceServiceSession *s = cls;
1213  uint32_t contained_count;
1214  uint32_t total_count;
1215  const struct GNUNET_SCALARPRODUCT_Element *elements;
1216  struct GNUNET_SET_Element set_elem;
1217  struct GNUNET_SCALARPRODUCT_Element *elem;
1218 
1219  total_count = ntohl (msg->element_count_total);
1220  contained_count = ntohl (msg->element_count_contained);
1221  s->peer = msg->peer;
1223  s->total = total_count;
1224  s->client_received_element_count = contained_count;
1225  s->session_id = msg->session_key;
1226  elements = (const struct GNUNET_SCALARPRODUCT_Element *) &msg[1];
1229  s->intersection_set =
1231 
1232  for (uint32_t i = 0; i < contained_count; i++)
1233  {
1234  if (0 == GNUNET_ntohll (elements[i].value))
1235  continue;
1236  elem = GNUNET_new (struct GNUNET_SCALARPRODUCT_Element);
1237  GNUNET_memcpy (elem,
1238  &elements[i],
1239  sizeof (struct GNUNET_SCALARPRODUCT_Element));
1242  &elem->key,
1243  elem,
1245  {
1246  /* element with same key encountered twice! */
1247  GNUNET_break (0);
1248  GNUNET_free (elem);
1249  continue;
1250  }
1251  set_elem.data = &elem->key;
1252  set_elem.size = sizeof (elem->key);
1253  set_elem.element_type = 0;
1254  GNUNET_SET_add_element (s->intersection_set, &set_elem, NULL, NULL);
1255  s->used_element_count++;
1256  }
1258  if (s->total != s->client_received_element_count)
1259  {
1260  /* wait for multipart msg */
1261  return;
1262  }
1264 }
1265 
1266 
1272 static void
1273 shutdown_task (void *cls)
1274 {
1275  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Shutting down, initiating cleanup.\n");
1276  // FIXME: we have to cut our connections to CADET first!
1277  if (NULL != my_cadet)
1278  {
1279  GNUNET_CADET_disconnect (my_cadet);
1280  my_cadet = NULL;
1281  }
1282 }
1283 
1284 
1295 static void *
1297  struct GNUNET_SERVICE_Client *client,
1298  struct GNUNET_MQ_Handle *mq)
1299 {
1300  struct AliceServiceSession *s;
1301 
1302  s = GNUNET_new (struct AliceServiceSession);
1303  s->client = client;
1304  s->client_mq = mq;
1305  return s;
1306 }
1307 
1308 
1319 static void
1321  struct GNUNET_SERVICE_Client *client,
1322  void *app_cls)
1323 {
1324  struct AliceServiceSession *s = app_cls;
1325 
1327  "Client %p disconnected from us.\n",
1328  client);
1329  s->client = NULL;
1330  s->client_mq = NULL;
1332 }
1333 
1334 
1342 static void
1343 run (void *cls,
1344  const struct GNUNET_CONFIGURATION_Handle *c,
1346 {
1347  cfg = c;
1348  /*
1349  offset has to be sufficiently small to allow computation of:
1350  m1+m2 mod n == (S + a) + (S + b) mod n,
1351  if we have more complex operations, this factor needs to be lowered */
1352  my_offset = gcry_mpi_new (GNUNET_CRYPTO_PAILLIER_BITS / 3);
1353  gcry_mpi_set_bit (my_offset, GNUNET_CRYPTO_PAILLIER_BITS / 3);
1355  my_cadet = GNUNET_CADET_connect (cfg);
1357  if (NULL == my_cadet)
1358  {
1359  GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _ ("Connect to CADET failed\n"));
1361  return;
1362  }
1363 }
1364 
1365 
1370  "scalarproduct-alice",
1372  &run,
1375  NULL,
1376  GNUNET_MQ_hd_var_size (alice_client_message,
1378  struct AliceComputationMessage,
1379  NULL),
1381  alice_client_message_multipart,
1384  NULL),
1386 
1387 
1388 /* end of gnunet-service-scalarproduct_alice.c */
A scalarproduct session which tracks a request form the client to our final response.
Message type passed from service client to finalize a session as requester or responder.
int in_destroy
Flag to prevent recursive calls to destroy_service_session() from doing harm.
void GNUNET_CADET_disconnect(struct GNUNET_CADET_Handle *handle)
Disconnect from the cadet service.
Definition: cadet_api.c:843
static struct GNUNET_CRYPTO_PaillierPrivateKey my_privkey
Service&#39;s own private key.
struct GNUNET_SET_ListenHandle * GNUNET_SET_listen(const struct GNUNET_CONFIGURATION_Handle *cfg, enum GNUNET_SET_OperationType op_type, const struct GNUNET_HashCode *app_id, GNUNET_SET_ListenCallback listen_cb, void *listen_cls)
Wait for set operation requests for the given application ID.
Definition: set_api.c:1013
static struct GNUNET_SERVICE_Handle * service
Handle to our service instance.
static gcry_mpi_t my_offset
Service&#39;s offset for values that could possibly be negative but are plaintext for encryption...
struct GNUNET_MessageHeader * msg
Definition: 005.c:2
struct GNUNET_CRYPTO_PaillierPublicKey public_key
Alice&#39;s public key.
struct GNUNET_CADET_Channel * channel
channel-handle associated with our cadet handle
#define GNUNET_MESSAGE_TYPE_SCALARPRODUCT_CLIENT_MULTIPART_ALICE
Client -> Alice multipart.
struct GNUNET_MQ_Handle * cadet_mq
The message queue for CADET.
static void handle_bobs_cryptodata_multipart(void *cls, const struct BobCryptodataMultipartMessage *msg)
Handle a multipart chunk of a response we got from another service we wanted to calculate a scalarpro...
unsigned int GNUNET_CONTAINER_multihashmap_size(const struct GNUNET_CONTAINER_MultiHashMap *map)
Get the number of key-value pairs in the map.
static struct GNUNET_CRYPTO_PaillierPublicKey my_pubkey
Service&#39;s own public key.
int GNUNET_SET_add_element(struct GNUNET_SET_Handle *set, const struct GNUNET_SET_Element *element, GNUNET_SET_Continuation cont, void *cont_cls)
Add an element to the given set.
Definition: set_api.c:686
Handle for a set operation request from another peer.
Definition: set_api.c:115
Opaque handle to the service.
Definition: cadet_api.c:38
Handle to a service.
Definition: service.c:116
#define GNUNET_MESSAGE_TYPE_SCALARPRODUCT_SESSION_INITIALIZATION
Alice -> Bob session initialization.
const struct GNUNET_HashCode * key
Key used to identify matching pairs of values to multiply.
static void prepare_client_end_notification(struct AliceServiceSession *session)
Notify the client that the session has failed.
Operation is still active (never returned, used internally).
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_shutdown(GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run on shutdown, that is when a CTRL-C signal is received, or when GNUNET_SCHEDULER_shutdown() is being invoked.
Definition: scheduler.c:1293
static void shutdown_task(void *cls)
Task run during shutdown.
struct GNUNET_HashCode key
Key used to identify matching pairs of values to multiply.
struct GNUNET_CRYPTO_PaillierCiphertext s_prime
Bob&#39;s "s&#39;".
Element stored in a set.
static int check_bobs_cryptodata_message(void *cls, const struct BobCryptodataMessage *msg)
Check a response we got from another service we wanted to calculate a scalarproduct with...
struct GNUNET_SET_Handle * GNUNET_SET_create(const struct GNUNET_CONFIGURATION_Handle *cfg, enum GNUNET_SET_OperationType op)
Create an empty set, supporting the specified operation.
Definition: set_api.c:656
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
static void send_alices_cryptodata_message(struct AliceServiceSession *s)
Send the cryptographic data from Alice to Bob.
int32_t range
Workaround for libgcrypt: -1 if negative, 0 if zero, else 1.
#define LOG_GCRY(level, cmd, rc)
Log an error message at log-level &#39;level&#39; that indicates a failure of the command &#39;cmd&#39; with the mess...
Definition: scalarproduct.h:35
Message type passed from responding service Bob to responding service Alice to complete a request and...
struct GNUNET_MessageHeader header
GNUNET message header with type GNUNET_MESSAGE_TYPE_SCALARPRODUCT_CLIENT_TO_ALICE.
Definition: scalarproduct.h:48
static void handle_alice_client_message_multipart(void *cls, const struct ComputationBobCryptodataMultipartMessage *msg)
We&#39;re receiving additional set data.
#define GNUNET_MQ_msg(mvar, type)
Allocate a GNUNET_MQ_Envelope.
Definition: gnunet_mq_lib.h:67
static struct Experiment * e
static void client_disconnect_cb(void *cls, struct GNUNET_SERVICE_Client *client, void *app_cls)
A client disconnected.
Opaque handle to a channel.
Definition: cadet_api.c:80
const char * GNUNET_h2s(const struct GNUNET_HashCode *hc)
Convert a hash value to a string (for printing debug messages).
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:78
#define GNUNET_new(type)
Allocate a struct or union of the given type.
static void handle_bobs_cryptodata_message(void *cls, const struct BobCryptodataMessage *msg)
Handle a response we got from another service we wanted to calculate a scalarproduct with...
enum GNUNET_SCALARPRODUCT_ResponseStatus status
State of this session.
struct GNUNET_MessageHeader header
GNUNET message header with type GNUNET_MESSAGE_TYPE_SCALARPRODUCT_BOB_CRYPTODATA. ...
struct GNUNET_MessageHeader header
GNUNET message header.
static void run(void *cls, const struct GNUNET_CONFIGURATION_Handle *c, struct GNUNET_SERVICE_Handle *service)
Initialization of the program and message handlers.
gcry_mpi_t value
a_i value, not disclosed to Bob.
static struct GNUNET_SCHEDULER_Task * t
Main task.
uint16_t size
The length of the struct (in bytes, including the length field itself), in big-endian format...
void GNUNET_SCHEDULER_shutdown(void)
Request the shutdown of a scheduler.
Definition: scheduler.c:524
static gcry_mpi_t compute_square_sum_mpi_elements(const struct MpiElement *vector, uint32_t length)
Computes the square sum over a vector of a given length.
Success, all elements have been sent (and received).
Internal representation of the hash map.
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur...
uint32_t total
How many elements we were supplied with from the client (total count before intersection).
Message type passed from client to service to initiate a request or responder role.
Definition: scalarproduct.h:42
struct GNUNET_HashCode session_key
the transaction/session key used to identify a session
Definition: scalarproduct.h:68
const void * data
Actual data of the element.
struct GNUNET_CADET_Handle * GNUNET_CADET_connect(const struct GNUNET_CONFIGURATION_Handle *cfg)
Connect to the MQ-based cadet service.
Definition: cadet_api.c:977
struct GNUNET_CRYPTO_PaillierCiphertext * r_prime
Bob&#39;s permutation q of R.
struct GNUNET_SET_OperationHandle * intersection_op
Set of elements for which will conduction an intersection.
void GNUNET_CRYPTO_paillier_create(struct GNUNET_CRYPTO_PaillierPublicKey *public_key, struct GNUNET_CRYPTO_PaillierPrivateKey *private_key)
Create a freshly generated paillier public key.
void * GNUNET_CONTAINER_multihashmap_get(const struct GNUNET_CONTAINER_MultiHashMap *map, const struct GNUNET_HashCode *key)
Given a key find a value in the map matching the key.
#define _(String)
GNU gettext support macro.
Definition: platform.h:208
Handle to a client that is connected to a service.
Definition: service.c:249
static const struct GNUNET_CONFIGURATION_Handle * cfg
GNUnet configuration handle.
void GNUNET_SET_destroy(struct GNUNET_SET_Handle *set)
Destroy the set handle, and free all associated resources.
Definition: set_api.c:771
static int check_bobs_cryptodata_multipart(void *cls, const struct BobCryptodataMultipartMessage *msg)
Check a multipart chunk of a response we got from another service we wanted to calculate a scalarprod...
static int copy_element_cb(void *cls, const struct GNUNET_HashCode *key, void *value)
Iterator to copy over messages from the hash map into an array for sorting.
uint32_t status
Status information about the outcome of this session, An enum GNUNET_SCALARPRODUCT_ResponseStatus (in...
#define GNUNET_MQ_msg_extra(mvar, esize, type)
Allocate an envelope, with extra space allocated after the space needed by the message struct...
Definition: gnunet_mq_lib.h:52
static int element_cmp(const void *a, const void *b)
Compare two struct MpiValues by key for sorting.
#define GNUNET_memcpy(dst, src, n)
static struct GNUNET_OS_Process * p
Helper process we started.
Definition: gnunet-qr.c:59
struct MpiElement * sorted_elements
a(Alice), sorted array by key of length used_element_count.
The other peer refused to to the operation with us, or something went wrong.
Success, all elements have been returned (but the other peer might still be receiving some from us...
struct GNUNET_PeerIdentity peer
the identity of a remote peer we want to communicate with
Definition: scalarproduct.h:73
Scalar Product API Message Types.
#define GNUNET_MQ_hd_var_size(name, code, str, ctx)
#define GNUNET_break_op(cond)
Use this for assertion violations caused by other peers (i.e.
Everything went ok, we are transmitting an element of the result (in set, or to be removed from set...
static void cb_intersection_element_removed(void *cls, const struct GNUNET_SET_Element *element, uint64_t current_size, enum GNUNET_SET_Status status)
Callback for set operation results.
void GNUNET_CONTAINER_multihashmap_destroy(struct GNUNET_CONTAINER_MultiHashMap *map)
Destroy a hash map.
static gcry_mpi_t compute_square_sum(const gcry_mpi_t *vector, uint32_t length)
Computes the square sum over a vector of a given length.
GNUNET_SET_Status
Status for the result callback.
static void destroy_service_session(struct AliceServiceSession *s)
Destroy session state, we are done with it.
uint32_t element_count_total
how many elements the vector in payload contains
Definition: scalarproduct.h:53
Message type passed from requesting service Alice to responding service Bob to initiate a request and...
uint16_t status
See PRISM_STATUS_*-constants.
#define GNUNET_new_array(n, type)
Allocate a size n array with structs or unions of the given type.
uint32_t cadet_received_element_count
Already transferred elements from Bob to us.
int GNUNET_CONTAINER_multihashmap_remove(struct GNUNET_CONTAINER_MultiHashMap *map, const struct GNUNET_HashCode *key, const void *value)
Remove the given key-value pair from the map.
#define GNUNET_MESSAGE_TYPE_SCALARPRODUCT_BOB_CRYPTODATA
Bob -> Alice SP crypto-data.
struct GNUNET_HashCode session_id
The transaction/session key used to identify a session.
void GNUNET_CRYPTO_paillier_decrypt(const struct GNUNET_CRYPTO_PaillierPrivateKey *private_key, const struct GNUNET_CRYPTO_PaillierPublicKey *public_key, const struct GNUNET_CRYPTO_PaillierCiphertext *ciphertext, gcry_mpi_t m)
Decrypt a paillier ciphertext with a private key.
GNUNET_SERVICE_MAIN("scalarproduct-alice", GNUNET_SERVICE_OPTION_NONE, &run, &client_connect_cb, &client_disconnect_cb, NULL, GNUNET_MQ_hd_var_size(alice_client_message, GNUNET_MESSAGE_TYPE_SCALARPRODUCT_CLIENT_TO_ALICE, struct AliceComputationMessage, NULL), GNUNET_MQ_hd_var_size(alice_client_message_multipart, GNUNET_MESSAGE_TYPE_SCALARPRODUCT_CLIENT_MULTIPART_ALICE, struct ComputationBobCryptodataMultipartMessage, NULL), GNUNET_MQ_handler_end())
Define "main" method using service macro.
A 512-bit hashcode.
static void handle_alice_client_message(void *cls, const struct AliceComputationMessage *msg)
Handler for Alice&#39;s client request message.
void GNUNET_SERVICE_client_drop(struct GNUNET_SERVICE_Client *c)
Ask the server to disconnect from the given client.
Definition: service.c:2618
Message handler for a specific message type.
static void transmit_client_response(struct AliceServiceSession *s)
Prepare the final (positive) response we will send to Alice&#39;s client.
Opaque handle to a set.
Definition: set_api.c:49
struct GNUNET_PeerIdentity peer
Alice or Bob&#39;s peerID.
static void cb_intersection_request_alice(void *cls, const struct GNUNET_PeerIdentity *other_peer, const struct GNUNET_MessageHeader *context_msg, struct GNUNET_SET_Request *request)
Called when another peer wants to do a set operation with the local peer.
struct GNUNET_HashCode session_id
(hopefully) unique transaction ID
There must only be one value per key; storing a value should fail if a value under the same key alrea...
Vector of Pallier-encrypted values sent by Alice to Bob (after set intersection). ...
#define GNUNET_MESSAGE_TYPE_SCALARPRODUCT_CLIENT_TO_ALICE
Client -> Alice.
#define GNUNET_SYSERR
Definition: gnunet_common.h:79
An encrypted element key-value pair.
scalarproduct service P2P messages
Multipart Message type passed between to supply additional elements for the peer. ...
void GNUNET_SET_listen_cancel(struct GNUNET_SET_ListenHandle *lh)
Cancel the given listen operation.
Definition: set_api.c:1047
uint32_t product_length
0 if no product attached
#define GNUNET_MESSAGE_TYPE_SCALARPRODUCT_BOB_CRYPTODATA_MULTIPART
Bob -> Alice SP crypto-data multipart.
Option for set operations.
int64_t value
Value to multiply in scalar product, in NBO.
int GNUNET_CONTAINER_multihashmap_put(struct GNUNET_CONTAINER_MultiHashMap *map, const struct GNUNET_HashCode *key, void *value, enum GNUNET_CONTAINER_MultiHashMapOption opt)
Store a key-value pair in the map.
static unsigned long long payload
How much data are we currently storing in the database?
uint32_t used_element_count
How many elements actually are used for the scalar product.
#define GNUNET_memcmp(a, b)
Compare memory in a and b, where both must be of the same pointer type.
struct GNUNET_CONTAINER_MultiHashMap * intersected_elements
all non-0-value&#39;d elements transmitted to us.
#define LOG(kind,...)
gcry_mpi_t product
The computed scalar.
Handle to an operation.
Definition: set_api.c:135
Handle to a message queue.
Definition: mq.c:85
#define GNUNET_MESSAGE_TYPE_SCALARPRODUCT_ALICE_CRYPTODATA
Alice -> Bob SP crypto-data (after intersection)
The identity of the host (wraps the signing key of the peer).
int GNUNET_SET_commit(struct GNUNET_SET_OperationHandle *oh, struct GNUNET_SET_Handle *set)
Commit a set to be used with a set operation.
Definition: set_api.c:1124
void GNUNET_CADET_receive_done(struct GNUNET_CADET_Channel *channel)
Send an ack on the channel to confirm the processing of a message.
Definition: cadet_api.c:955
static int check_alice_client_message_multipart(void *cls, const struct ComputationBobCryptodataMultipartMessage *msg)
We&#39;re receiving additional set data.
struct GNUNET_CADET_Channel * GNUNET_CADET_channel_create(struct GNUNET_CADET_Handle *h, void *channel_cls, const struct GNUNET_PeerIdentity *destination, const struct GNUNET_HashCode *port, GNUNET_CADET_WindowSizeEventHandler window_changes, GNUNET_CADET_DisconnectEventHandler disconnects, const struct GNUNET_MQ_MessageHandler *handlers)
Create a new channel towards a remote peer.
Definition: cadet_api.c:1070
struct GNUNET_MessageHeader header
GNUNET message header.
configuration data
Definition: configuration.c:85
static int free_element_cb(void *cls, const struct GNUNET_HashCode *key, void *value)
Iterator called to free elements.
static void * client_connect_cb(void *cls, struct GNUNET_SERVICE_Client *client, struct GNUNET_MQ_Handle *mq)
A client connected.
int GNUNET_CRYPTO_hash_cmp(const struct GNUNET_HashCode *h1, const struct GNUNET_HashCode *h2)
Compare function for HashCodes, producing a total ordering of all hashcodes.
Definition: crypto_hash.c:278
static int check_alice_client_message(void *cls, const struct AliceComputationMessage *msg)
Handler for Alice&#39;s client request message.
uint32_t contained_element_count
How many elements we supply within this message? In NBO.
uint16_t size
Number of bytes in the buffer pointed to by data.
struct GNUNET_MQ_Handle * mq
Definition: 003.c:5
#define GNUNET_log(kind,...)
uint32_t element_count_contained
contained elements the vector in payload contains
Definition: scalarproduct.h:58
uint32_t contained_element_count
How many elements we appended to this message? In NBO.
Opaque handle to a listen operation.
Definition: set_api.c:186
Client gets only elements that have been removed from the set.
struct GNUNET_CONTAINER_MultiHashMap * GNUNET_CONTAINER_multihashmap_create(unsigned int len, int do_not_copy_keys)
Create a multi hash map.
uint32_t element_count_contained
contained elements the vector in payload contains
void GNUNET_SET_operation_cancel(struct GNUNET_SET_OperationHandle *oh)
Cancel the given set operation.
Definition: set_api.c:515
multipart messages following struct ComputationMessage
Header for all communications.
#define GNUNET_YES
Definition: gnunet_common.h:80
struct GNUNET_SET_Handle * intersection_set
Set of elements for which will conduction an intersection.
void GNUNET_MQ_send(struct GNUNET_MQ_Handle *mq, struct GNUNET_MQ_Envelope *ev)
Send a message with the given message queue.
Definition: mq.c:353
struct GNUNET_SERVICE_Client * client
The client this request is related to.
static struct GNUNET_CADET_Handle * my_cadet
Handle to the CADET service.
Set intersection, only return elements that are in both sets.
uint32_t contained_element_count
How many elements this individual message delivers (in NBO).
GNUNET_SCALARPRODUCT_ResponseStatus
Result status values for the computation.
struct GNUNET_MQ_Handle * client_mq
The message queue for the client.
struct GNUNET_SET_ListenHandle * intersection_listen
Handle to Alice&#39;s Intersection operation listening for Bob.
#define ELEMENT_CAPACITY
Maximum number of elements we can put into a single cryptodata message.
struct GNUNET_CRYPTO_PaillierCiphertext * r
Bob&#39;s permutation p of R.
#define GNUNET_CRYPTO_PAILLIER_BITS
Size of paillier plain texts and public keys.
int GNUNET_CONTAINER_multihashmap_iterate(struct GNUNET_CONTAINER_MultiHashMap *map, GNUNET_CONTAINER_MulitHashMapIteratorCallback it, void *it_cls)
Iterate over all entries in the map.
struct GNUNET_CRYPTO_PaillierCiphertext s
Bob&#39;s "s".
uint32_t client_received_element_count
Already transferred elements from client to us.
void GNUNET_CADET_channel_destroy(struct GNUNET_CADET_Channel *channel)
Destroy an existing channel.
Definition: cadet_api.c:905
static gcry_mpi_t compute_scalar_product(struct AliceServiceSession *session)
Compute our scalar product, done by Alice.
const char * GNUNET_i2s(const struct GNUNET_PeerIdentity *pid)
Convert a peer identity to a string (for printing debug messages).
void GNUNET_SERVICE_client_continue(struct GNUNET_SERVICE_Client *c)
Continue receiving further messages from the given client.
Definition: service.c:2533
#define GNUNET_MQ_handler_end()
End-marker for the handlers array.
#define GNUNET_malloc(size)
Wrapper around malloc.
An element key-value pair for scalarproduct.
uint64_t GNUNET_ntohll(uint64_t n)
Convert unsigned 64-bit integer to host byte order.
Definition: common_endian.c:48
#define GNUNET_MESSAGE_TYPE_SCALARPRODUCT_RESULT
Alice/Bob -> Client Result.
#define GNUNET_free(ptr)
Wrapper around free.
uint16_t element_type
Application-specific element type.
struct GNUNET_SET_OperationHandle * GNUNET_SET_accept(struct GNUNET_SET_Request *request, enum GNUNET_SET_ResultMode result_mode, struct GNUNET_SET_Option options[], GNUNET_SET_ResultIterator result_cb, void *result_cls)
Accept a request we got via GNUNET_SET_listen().
Definition: set_api.c:1081
static void client_request_complete_alice(struct AliceServiceSession *s)
Our client has finished sending us its multipart message.
static void cb_channel_destruction(void *cls, const struct GNUNET_CADET_Channel *channel)
Function called whenever a channel is destroyed.
struct GNUNET_MQ_Handle * GNUNET_CADET_get_mq(const struct GNUNET_CADET_Channel *channel)
Obtain the message queue for a connected peer.
Definition: cadet_api.c:1121
int GNUNET_CRYPTO_paillier_encrypt(const struct GNUNET_CRYPTO_PaillierPublicKey *public_key, const gcry_mpi_t m, int desired_ops, struct GNUNET_CRYPTO_PaillierCiphertext *ciphertext)
Encrypt a plaintext with a paillier public key.