GNUnet  0.11.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_seti_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 {
70  struct GNUNET_HashCode session_id;
71 
75  struct GNUNET_PeerIdentity peer;
76 
80  struct GNUNET_SERVICE_Client *client;
81 
85  struct GNUNET_MQ_Handle *client_mq;
86 
90  struct GNUNET_MQ_Handle *cadet_mq;
91 
96  struct GNUNET_CONTAINER_MultiHashMap *intersected_elements;
97 
102  struct GNUNET_SETI_Handle *intersection_set;
103 
108  struct GNUNET_SETI_OperationHandle *intersection_op;
109 
113  struct GNUNET_SETI_ListenHandle *intersection_listen;
114 
118  struct GNUNET_CADET_Channel *channel;
119 
123  struct MpiElement *sorted_elements;
124 
129 
134 
139 
144 
148  gcry_mpi_t product;
149 
154  uint32_t total;
155 
161  uint32_t used_element_count;
162 
167  uint32_t client_received_element_count;
168 
174 
182 
187  int in_destroy;
188 };
189 
190 
194 static const struct GNUNET_CONFIGURATION_Handle *cfg;
195 
200 
205 
209 static gcry_mpi_t my_offset;
210 
215 
216 
225 static int
226 free_element_cb (void *cls, const struct GNUNET_HashCode *key, void *value)
227 {
229 
230  GNUNET_free (e);
231  return GNUNET_OK;
232 }
233 
234 
240 static void
242 {
243  if (GNUNET_YES == s->in_destroy)
244  return;
245  s->in_destroy = GNUNET_YES;
246  if (NULL != s->client)
247  {
248  struct GNUNET_SERVICE_Client *c = s->client;
249 
250  s->client = NULL;
252  }
253  if (NULL != s->channel)
254  {
256  s->channel = NULL;
257  }
258  if (NULL != s->intersected_elements)
259  {
262  s);
264  s->intersected_elements = NULL;
265  }
266  if (NULL != s->intersection_listen)
267  {
269  s->intersection_listen = NULL;
270  }
271  if (NULL != s->intersection_op)
272  {
274  s->intersection_op = NULL;
275  }
276  if (NULL != s->intersection_set)
277  {
279  s->intersection_set = NULL;
280  }
281  if (NULL != s->sorted_elements)
282  {
283  for (unsigned int i = 0; i < s->used_element_count; i++)
284  gcry_mpi_release (s->sorted_elements[i].value);
286  s->sorted_elements = NULL;
287  }
288  if (NULL != s->r)
289  {
290  GNUNET_free (s->r);
291  s->r = NULL;
292  }
293  if (NULL != s->r_prime)
294  {
295  GNUNET_free (s->r_prime);
296  s->r_prime = NULL;
297  }
298  if (NULL != s->product)
299  {
300  gcry_mpi_release (s->product);
301  s->product = NULL;
302  }
303  GNUNET_free (s);
304 }
305 
306 
313 static void
315 {
316  struct ClientResponseMessage *msg;
317  struct GNUNET_MQ_Envelope *e;
318 
319  if (NULL == session->client_mq)
320  return; /* no client left to be notified */
321  GNUNET_log (
323  "Sending session-end notification with status %d to client for session %s\n",
324  session->status,
325  GNUNET_h2s (&session->session_id));
327  msg->product_length = htonl (0);
328  msg->status = htonl (session->status);
329  GNUNET_MQ_send (session->client_mq, e);
330 }
331 
332 
339 static void
341 {
342  struct ClientResponseMessage *msg;
343  struct GNUNET_MQ_Envelope *e;
344  unsigned char *product_exported = NULL;
345  size_t product_length = 0;
346  int32_t range;
347  gcry_error_t rc;
348  int sign;
349  gcry_mpi_t value;
350 
351  if (NULL == s->product)
352  {
353  GNUNET_break (0);
355  return;
356  }
357  value = gcry_mpi_new (0);
358  sign = gcry_mpi_cmp_ui (s->product, 0);
359  if (0 > sign)
360  {
361  range = -1;
362  gcry_mpi_sub (value, value, s->product);
363  }
364  else if (0 < sign)
365  {
366  range = 1;
367  gcry_mpi_add (value, value, s->product);
368  }
369  else
370  {
371  /* result is exactly zero */
372  range = 0;
373  }
374  gcry_mpi_release (s->product);
375  s->product = NULL;
376 
377  if ((0 != range) && (0 != (rc = gcry_mpi_aprint (GCRYMPI_FMT_STD,
378  &product_exported,
379  &product_length,
380  value))))
381  {
382  LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_mpi_scan", rc);
384  return;
385  }
386  gcry_mpi_release (value);
387  e = GNUNET_MQ_msg_extra (msg,
388  product_length,
391  msg->range = htonl (range);
392  msg->product_length = htonl (product_length);
393  if (NULL != product_exported)
394  {
395  GNUNET_memcpy (&msg[1], product_exported, product_length);
396  GNUNET_free (product_exported);
397  }
398  GNUNET_MQ_send (s->client_mq, e);
400  "Sent result to client, session %s has ended!\n",
401  GNUNET_h2s (&s->session_id));
402 }
403 
404 
414 static void
415 cb_channel_destruction (void *cls, const struct GNUNET_CADET_Channel *channel)
416 {
417  struct AliceServiceSession *s = cls;
418 
420  "Peer disconnected, terminating session %s with peer %s\n",
421  GNUNET_h2s (&s->session_id),
422  GNUNET_i2s (&s->peer));
424  {
425  /* We didn't get an answer yet, fail with error */
428  }
429  s->channel = NULL;
430 }
431 
432 
440 static gcry_mpi_t
442  uint32_t length)
443 {
444  gcry_mpi_t elem;
445  gcry_mpi_t sum;
446  uint32_t i;
447 
448  GNUNET_assert (NULL != (sum = gcry_mpi_new (0)));
449  GNUNET_assert (NULL != (elem = gcry_mpi_new (0)));
450  for (i = 0; i < length; i++)
451  {
452  gcry_mpi_mul (elem, vector[i].value, vector[i].value);
453  gcry_mpi_add (sum, sum, elem);
454  }
455  gcry_mpi_release (elem);
456  return sum;
457 }
458 
459 
467 static gcry_mpi_t
468 compute_square_sum (const gcry_mpi_t *vector, uint32_t length)
469 {
470  gcry_mpi_t elem;
471  gcry_mpi_t sum;
472  uint32_t i;
473 
474  GNUNET_assert (NULL != (sum = gcry_mpi_new (0)));
475  GNUNET_assert (NULL != (elem = gcry_mpi_new (0)));
476  for (i = 0; i < length; i++)
477  {
478  gcry_mpi_mul (elem, vector[i], vector[i]);
479  gcry_mpi_add (sum, sum, elem);
480  }
481  gcry_mpi_release (elem);
482  return sum;
483 }
484 
485 
492 static gcry_mpi_t
494 {
495  uint32_t count;
496  gcry_mpi_t t;
497  gcry_mpi_t u;
498  gcry_mpi_t u_prime;
499  gcry_mpi_t p;
500  gcry_mpi_t p_prime;
501  gcry_mpi_t tmp;
502  gcry_mpi_t r[session->used_element_count];
503  gcry_mpi_t r_prime[session->used_element_count];
504  gcry_mpi_t s;
505  gcry_mpi_t s_prime;
506  unsigned int i;
507 
508  count = session->used_element_count;
509  // due to the introduced static offset S, we now also have to remove this
510  // from the E(a_pi)(+)E(-b_pi-r_pi) and E(a_qi)(+)E(-r_qi) twice each,
511  // the result is E((S + a_pi) + (S -b_pi-r_pi)) and E(S + a_qi + S - r_qi)
512  for (i = 0; i < count; i++)
513  {
514  r[i] = gcry_mpi_new (0);
516  &my_pubkey,
517  &session->r[i],
518  r[i]);
519  gcry_mpi_sub (r[i], r[i], my_offset);
520  gcry_mpi_sub (r[i], r[i], my_offset);
521  r_prime[i] = gcry_mpi_new (0);
523  &my_pubkey,
524  &session->r_prime[i],
525  r_prime[i]);
526  gcry_mpi_sub (r_prime[i], r_prime[i], my_offset);
527  gcry_mpi_sub (r_prime[i], r_prime[i], my_offset);
528  }
529 
530  // calculate t = sum(ai)
531  t = compute_square_sum_mpi_elements (session->sorted_elements, count);
532  // calculate U
533  u = gcry_mpi_new (0);
534  tmp = compute_square_sum (r, count);
535  gcry_mpi_sub (u, u, tmp);
536  gcry_mpi_release (tmp);
537 
538  // calculate U'
539  u_prime = gcry_mpi_new (0);
540  tmp = compute_square_sum (r_prime, count);
541  gcry_mpi_sub (u_prime, u_prime, tmp);
542 
543  GNUNET_assert (p = gcry_mpi_new (0));
544  GNUNET_assert (p_prime = gcry_mpi_new (0));
545  GNUNET_assert (s = gcry_mpi_new (0));
546  GNUNET_assert (s_prime = gcry_mpi_new (0));
547 
548  // compute P
551  &my_pubkey,
552  &session->s_prime,
553  s_prime);
554 
555  // compute P
556  gcry_mpi_add (p, s, t);
557  gcry_mpi_add (p, p, u);
558 
559  // compute P'
560  gcry_mpi_add (p_prime, s_prime, t);
561  gcry_mpi_add (p_prime, p_prime, u_prime);
562 
563  gcry_mpi_release (t);
564  gcry_mpi_release (u);
565  gcry_mpi_release (u_prime);
566  gcry_mpi_release (s);
567  gcry_mpi_release (s_prime);
568 
569  // compute product
570  gcry_mpi_sub (p, p, p_prime);
571  gcry_mpi_release (p_prime);
572  tmp = gcry_mpi_set_ui (tmp, 2);
573  gcry_mpi_div (p, NULL, p, tmp, 0);
574 
575  gcry_mpi_release (tmp);
576  for (i = 0; i < count; i++)
577  {
578  gcry_mpi_release (session->sorted_elements[i].value);
579  gcry_mpi_release (r[i]);
580  gcry_mpi_release (r_prime[i]);
581  }
582  GNUNET_free (session->sorted_elements);
583  session->sorted_elements = NULL;
584  GNUNET_free (session->r);
585  session->r = NULL;
586  GNUNET_free (session->r_prime);
587  session->r_prime = NULL;
588 
589  return p;
590 }
591 
592 
602 static int
604  void *cls,
605  const struct BobCryptodataMultipartMessage *msg)
606 {
607  struct AliceServiceSession *s = cls;
608  uint32_t contained;
609  size_t msg_size;
610  size_t required_size;
611 
612  msg_size = ntohs (msg->header.size);
613  contained = ntohl (msg->contained_element_count);
614  required_size =
615  sizeof(struct BobCryptodataMultipartMessage)
616  + 2 * contained * sizeof(struct GNUNET_CRYPTO_PaillierCiphertext);
617  if ((required_size != msg_size) ||
618  (s->cadet_received_element_count + contained > s->used_element_count))
619  {
620  GNUNET_break (0);
621  return GNUNET_SYSERR;
622  }
623  return GNUNET_OK;
624 }
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_SETI_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;
928 
930  s->intersection_op = NULL;
931  if (NULL != s->intersection_set)
932  {
934  s->intersection_set = NULL;
935  }
937  return;
939  /* unhandled status code */
940  LOG (GNUNET_ERROR_TYPE_DEBUG, "Set intersection failed!\n");
941  if (NULL != s->intersection_listen)
942  {
944  s->intersection_listen = NULL;
945  }
946  s->intersection_op = NULL;
947  if (NULL != s->intersection_set)
948  {
950  s->intersection_set = NULL;
951  }
954  return;
955 
956  default:
957  GNUNET_break (0);
958  return;
959  }
960 }
961 
962 
978 static void
980  const struct GNUNET_PeerIdentity *other_peer,
981  const struct GNUNET_MessageHeader *context_msg,
983 {
984  struct AliceServiceSession *s = cls;
985 
986  if (0 != GNUNET_memcmp (other_peer, &s->peer))
987  {
988  GNUNET_break_op (0);
989  return;
990  }
991  s->intersection_op = GNUNET_SETI_accept (request,
992  (struct
993  GNUNET_SETI_Option[]){ { 0 } },
995  s);
996  if (NULL == s->intersection_op)
997  {
998  GNUNET_break (0);
1001  return;
1002  }
1004  {
1005  GNUNET_break (0);
1008  return;
1009  }
1010 }
1011 
1012 
1018 static void
1020 {
1021  struct GNUNET_MQ_MessageHandler cadet_handlers[] =
1022  { GNUNET_MQ_hd_var_size (bobs_cryptodata_message,
1024  struct BobCryptodataMessage,
1025  s),
1027  bobs_cryptodata_multipart,
1030  s),
1031  GNUNET_MQ_handler_end () };
1032  struct ServiceRequestMessage *msg;
1033  struct GNUNET_MQ_Envelope *e;
1034 
1036  "Creating new channel for session with key %s.\n",
1037  GNUNET_h2s (&s->session_id));
1038  s->channel = GNUNET_CADET_channel_create (my_cadet,
1039  s,
1040  &s->peer,
1041  &s->session_id,
1042  NULL,
1044  cadet_handlers);
1045  if (NULL == s->channel)
1046  {
1049  return;
1050  }
1053  &s->session_id,
1055  s);
1056  if (NULL == s->intersection_listen)
1057  {
1060  s->channel = NULL;
1062  return;
1063  }
1064 
1065  e = GNUNET_MQ_msg (msg,
1067  msg->session_id = s->session_id;
1068  msg->public_key = my_pubkey;
1069  GNUNET_MQ_send (s->cadet_mq, e);
1070 }
1071 
1072 
1081 static int
1083  void *cls,
1085 {
1086  struct AliceServiceSession *s = cls;
1087  uint32_t contained_count;
1088  uint16_t msize;
1089 
1090  msize = ntohs (msg->header.size);
1091  contained_count = ntohl (msg->element_count_contained);
1092  if ((msize !=
1094  + contained_count * sizeof(struct GNUNET_SCALARPRODUCT_Element))) ||
1095  (0 == contained_count) ||
1096  (s->total == s->client_received_element_count) ||
1097  (s->total < s->client_received_element_count + contained_count))
1098  {
1099  GNUNET_break_op (0);
1100  return GNUNET_SYSERR;
1101  }
1102  return GNUNET_OK;
1103 }
1104 
1105 
1113 static void
1115  void *cls,
1117 {
1118  struct AliceServiceSession *s = cls;
1119  uint32_t contained_count;
1120  const struct GNUNET_SCALARPRODUCT_Element *elements;
1121  struct GNUNET_SETI_Element set_elem;
1122  struct GNUNET_SCALARPRODUCT_Element *elem;
1123 
1124  contained_count = ntohl (msg->element_count_contained);
1125  s->client_received_element_count += contained_count;
1126  elements = (const struct GNUNET_SCALARPRODUCT_Element *) &msg[1];
1127  for (uint32_t i = 0; i < contained_count; i++)
1128  {
1129  elem = GNUNET_new (struct GNUNET_SCALARPRODUCT_Element);
1130  GNUNET_memcpy (elem,
1131  &elements[i],
1132  sizeof(struct GNUNET_SCALARPRODUCT_Element));
1135  &elem->key,
1136  elem,
1138  {
1139  GNUNET_break (0);
1140  GNUNET_free (elem);
1141  continue;
1142  }
1143  set_elem.data = &elem->key;
1144  set_elem.size = sizeof(elem->key);
1145  set_elem.element_type = 0;
1146  GNUNET_SETI_add_element (s->intersection_set, &set_elem, NULL, NULL);
1147  s->used_element_count++;
1148  }
1150  if (s->total != s->client_received_element_count)
1151  {
1152  /* more to come */
1153  return;
1154  }
1156 }
1157 
1158 
1167 static int
1169  const struct AliceComputationMessage *msg)
1170 {
1171  struct AliceServiceSession *s = cls;
1172  uint16_t msize;
1173  uint32_t total_count;
1174  uint32_t contained_count;
1175 
1176  if (NULL != s->intersected_elements)
1177  {
1178  /* only one concurrent session per client connection allowed,
1179  simplifies logic a lot... */
1180  GNUNET_break (0);
1181  return GNUNET_SYSERR;
1182  }
1183  msize = ntohs (msg->header.size);
1184  total_count = ntohl (msg->element_count_total);
1185  contained_count = ntohl (msg->element_count_contained);
1186  if ((0 == total_count) || (0 == contained_count) ||
1187  (msize !=
1188  (sizeof(struct AliceComputationMessage)
1189  + contained_count * sizeof(struct GNUNET_SCALARPRODUCT_Element))))
1190  {
1191  GNUNET_break_op (0);
1192  return GNUNET_SYSERR;
1193  }
1194  return GNUNET_OK;
1195 }
1196 
1197 
1205 static void
1207  const struct AliceComputationMessage *msg)
1208 {
1209  struct AliceServiceSession *s = cls;
1210  uint32_t contained_count;
1211  uint32_t total_count;
1212  const struct GNUNET_SCALARPRODUCT_Element *elements;
1213  struct GNUNET_SETI_Element set_elem;
1214  struct GNUNET_SCALARPRODUCT_Element *elem;
1215 
1216  total_count = ntohl (msg->element_count_total);
1217  contained_count = ntohl (msg->element_count_contained);
1218  s->peer = msg->peer;
1220  s->total = total_count;
1221  s->client_received_element_count = contained_count;
1222  s->session_id = msg->session_key;
1223  elements = (const struct GNUNET_SCALARPRODUCT_Element *) &msg[1];
1227 
1228  for (uint32_t i = 0; i < contained_count; i++)
1229  {
1230  if (0 == GNUNET_ntohll (elements[i].value))
1231  continue;
1232  elem = GNUNET_new (struct GNUNET_SCALARPRODUCT_Element);
1233  GNUNET_memcpy (elem,
1234  &elements[i],
1235  sizeof(struct GNUNET_SCALARPRODUCT_Element));
1238  &elem->key,
1239  elem,
1241  {
1242  /* element with same key encountered twice! */
1243  GNUNET_break (0);
1244  GNUNET_free (elem);
1245  continue;
1246  }
1247  set_elem.data = &elem->key;
1248  set_elem.size = sizeof(elem->key);
1249  set_elem.element_type = 0;
1251  &set_elem,
1252  NULL,
1253  NULL);
1254  s->used_element_count++;
1255  }
1257  if (s->total != s->client_received_element_count)
1258  {
1259  /* wait for multipart msg */
1260  return;
1261  }
1263 }
1264 
1265 
1271 static void
1272 shutdown_task (void *cls)
1273 {
1274  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Shutting down, initiating cleanup.\n");
1275  // FIXME: we have to cut our connections to CADET first!
1276  if (NULL != my_cadet)
1277  {
1278  GNUNET_CADET_disconnect (my_cadet);
1279  my_cadet = NULL;
1280  }
1281 }
1282 
1283 
1294 static void *
1296  struct GNUNET_SERVICE_Client *client,
1297  struct GNUNET_MQ_Handle *mq)
1298 {
1299  struct AliceServiceSession *s;
1300 
1301  s = GNUNET_new (struct AliceServiceSession);
1302  s->client = client;
1303  s->client_mq = mq;
1304  return s;
1305 }
1306 
1307 
1318 static void
1320  struct GNUNET_SERVICE_Client *client,
1321  void *app_cls)
1322 {
1323  struct AliceServiceSession *s = app_cls;
1324 
1326  "Client %p disconnected from us.\n",
1327  client);
1328  s->client = NULL;
1329  s->client_mq = NULL;
1331 }
1332 
1333 
1341 static void
1342 run (void *cls,
1343  const struct GNUNET_CONFIGURATION_Handle *c,
1345 {
1346  cfg = c;
1347  /*
1348  offset has to be sufficiently small to allow computation of:
1349  m1+m2 mod n == (S + a) + (S + b) mod n,
1350  if we have more complex operations, this factor needs to be lowered */
1351  my_offset = gcry_mpi_new (GNUNET_CRYPTO_PAILLIER_BITS / 3);
1352  gcry_mpi_set_bit (my_offset, GNUNET_CRYPTO_PAILLIER_BITS / 3);
1354  my_cadet = GNUNET_CADET_connect (cfg);
1356  if (NULL == my_cadet)
1357  {
1358  GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _ ("Connect to CADET failed\n"));
1360  return;
1361  }
1362 }
1363 
1364 
1369  "scalarproduct-alice",
1371  &run,
1374  NULL,
1375  GNUNET_MQ_hd_var_size (alice_client_message,
1377  struct AliceComputationMessage,
1378  NULL),
1380  alice_client_message_multipart,
1383  NULL),
1385 
1386 
1387 /* 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:775
static struct GNUNET_CRYPTO_PaillierPrivateKey my_privkey
Service&#39;s own private key.
struct GNUNET_SETI_Handle * intersection_set
Set of elements for which will conduction an intersection.
static struct GNUNET_SERVICE_Handle * service
Handle to our service instance.
Success, all elements have been sent (and received).
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.
int GNUNET_SETI_add_element(struct GNUNET_SETI_Handle *set, const struct GNUNET_SETI_Element *element, GNUNET_SCHEDULER_TaskCallback cb, void *cb_cls)
Add an element to the given set.
Definition: seti_api.c:447
static struct GNUNET_VPN_RedirectionRequest * request
Opaque redirection request handle.
Definition: gnunet-vpn.c:41
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...
The other peer refused to do the operation with us, or something went wrong.
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.
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.
uint16_t size
Number of bytes in the buffer pointed to by data.
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).
int GNUNET_SETI_commit(struct GNUNET_SETI_OperationHandle *oh, struct GNUNET_SETI_Handle *set)
Commit a set to be used with a set operation.
Definition: seti_api.c:836
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:1331
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;".
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_SETI_ListenHandle * intersection_listen
Handle to Alice&#39;s Intersection operation listening for Bob.
Option for set operations.
#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:51
#define GNUNET_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
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.h:116
const char * GNUNET_h2s(const struct GNUNET_HashCode *hc)
Convert a hash value to a string (for printing debug messages).
#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:531
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.
struct GNUNET_SETI_ListenHandle * GNUNET_SETI_listen(const struct GNUNET_CONFIGURATION_Handle *cfg, const struct GNUNET_HashCode *app_id, GNUNET_SETI_ListenCallback listen_cb, void *listen_cls)
Wait for set operation requests for the given application ID.
Definition: seti_api.c:715
Opaque handle to a listen operation.
Definition: seti_api.c:162
Internal representation of the hash map.
Handle for a set operation request from another peer.
Definition: seti_api.c:85
#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:45
struct GNUNET_HashCode session_key
the transaction/session key used to identify a session
Definition: scalarproduct.h:71
static void cb_intersection_element_removed(void *cls, const struct GNUNET_SETI_Element *element, uint64_t current_size, enum GNUNET_SETI_Status status)
Callback for set operation results.
struct GNUNET_CADET_Handle * GNUNET_CADET_connect(const struct GNUNET_CONFIGURATION_Handle *cfg)
Connect to the MQ-based cadet service.
Definition: cadet_api.c:910
struct GNUNET_CRYPTO_PaillierCiphertext * r_prime
Bob&#39;s permutation q of R.
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:184
Handle to a client that is connected to a service.
Definition: service.c:250
static const struct GNUNET_CONFIGURATION_Handle * cfg
GNUnet configuration handle.
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
Opaque handle to a set.
Definition: seti_api.c:39
static int element_cmp(const void *a, const void *b)
Compare two struct MpiValues by key for sorting.
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.
struct GNUNET_SETI_OperationHandle * GNUNET_SETI_accept(struct GNUNET_SETI_Request *request, const struct GNUNET_SETI_Option options[], GNUNET_SETI_ResultIterator result_cb, void *result_cls)
Accept a request we got via GNUNET_SETI_listen().
Definition: seti_api.c:780
struct GNUNET_PeerIdentity peer
the identity of a remote peer we want to communicate with
Definition: scalarproduct.h:76
Scalar Product API Message Types.
void GNUNET_SETI_operation_cancel(struct GNUNET_SETI_OperationHandle *oh)
Cancel the given set operation.
Definition: seti_api.c:335
#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.
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.
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:56
Element stored in a set.
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.
const void * data
Actual data of the element.
#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.
struct GNUNET_SETI_Handle * GNUNET_SETI_create(const struct GNUNET_CONFIGURATION_Handle *cfg)
Create an empty set, supporting the specified operation.
Definition: seti_api.c:399
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:2323
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.
Handle to an operation.
Definition: seti_api.c:105
struct GNUNET_PeerIdentity peer
Alice or Bob&#39;s peerID.
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.
An encrypted element key-value pair.
scalarproduct service P2P messages
Multipart Message type passed between to supply additional elements for the peer. ...
uint32_t product_length
0 if no product attached
#define GNUNET_MESSAGE_TYPE_SCALARPRODUCT_BOB_CRYPTODATA_MULTIPART
Bob -> Alice SP crypto-data multipart.
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?
Element should be delete from the result set of the local peer, i.e.
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 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).
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:888
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:1031
struct GNUNET_MessageHeader header
GNUNET message header.
configuration data
Definition: configuration.c:84
GNUNET_SETI_Status
Status for the result callback.
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:311
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.
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:61
uint32_t contained_element_count
How many elements we appended to this message? In NBO.
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
multipart messages following struct ComputationMessage
Header for all communications.
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:355
struct GNUNET_SERVICE_Client * client
The client this request is related to.
static struct GNUNET_CADET_Handle * my_cadet
Handle to the CADET service.
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.
#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.
struct GNUNET_SETI_OperationHandle * intersection_op
Set of elements for which will conduction an intersection.
#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".
void GNUNET_SETI_listen_cancel(struct GNUNET_SETI_ListenHandle *lh)
Cancel the given listen operation.
Definition: seti_api.c:747
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:837
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:2242
static void cb_intersection_request_alice(void *cls, const struct GNUNET_PeerIdentity *other_peer, const struct GNUNET_MessageHeader *context_msg, struct GNUNET_SETI_Request *request)
Called when another peer wants to do a set operation with the local peer.
#define GNUNET_MQ_handler_end()
End-marker for the handlers array.
uint16_t element_type
Application-specific element type.
#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:53
#define GNUNET_MESSAGE_TYPE_SCALARPRODUCT_RESULT
Alice/Bob -> Client Result.
#define GNUNET_free(ptr)
Wrapper around free.
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.
void GNUNET_SETI_destroy(struct GNUNET_SETI_Handle *set)
Destroy the set handle, and free all associated resources.
Definition: seti_api.c:488
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:1082
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.