GNUnet  0.10.x
gnunet-service-scalarproduct-ecc_alice.c
Go to the documentation of this file.
1 /*
2  This file is part of GNUnet.
3  Copyright (C) 2013-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 
47 #define MAX_RESULT (1024 * 1024)
48 
55 #define MAX_RAM (1024)
56 
60 struct MpiElement
61 {
67  const struct GNUNET_HashCode *key;
68 
72  gcry_mpi_t value;
73 };
74 
75 
81 {
82 
87 
92 
97 
102 
107 
113 
119 
125 
130 
135 
140 
144  gcry_mpi_t product;
145 
150  uint32_t total;
151 
158 
164 
172 
178 };
179 
180 
184 static const struct GNUNET_CONFIGURATION_Handle *cfg;
185 
190 
194 static gcry_mpi_t my_privkey;
195 
199 static gcry_mpi_t my_privkey_inv;
200 
205 
206 
215 static int
216 free_element_cb (void *cls, const struct GNUNET_HashCode *key, void *value)
217 {
219 
220  GNUNET_free (e);
221  return GNUNET_OK;
222 }
223 
224 
230 static void
232 {
233  unsigned int i;
234 
235  if (GNUNET_YES == s->in_destroy)
236  return;
237  s->in_destroy = GNUNET_YES;
238  if (NULL != s->client)
239  {
240  struct GNUNET_SERVICE_Client *c = s->client;
241 
242  s->client = NULL;
244  }
245  if (NULL != s->channel)
246  {
248  s->channel = NULL;
249  }
250  if (NULL != s->intersected_elements)
251  {
254  s);
256  s->intersected_elements = NULL;
257  }
258  if (NULL != s->intersection_listen)
259  {
261  s->intersection_listen = NULL;
262  }
263  if (NULL != s->intersection_op)
264  {
265  LOG (GNUNET_ERROR_TYPE_DEBUG, "Set intersection, op still ongoing!\n");
267  s->intersection_op = NULL;
268  }
269  if (NULL != s->intersection_set)
270  {
272  s->intersection_set = NULL;
273  }
274  if (NULL != s->sorted_elements)
275  {
276  for (i = 0; i < s->used_element_count; i++)
277  gcry_mpi_release (s->sorted_elements[i].value);
279  s->sorted_elements = NULL;
280  }
281  if (NULL != s->product)
282  {
283  gcry_mpi_release (s->product);
284  s->product = NULL;
285  }
286  GNUNET_free (s);
287 }
288 
289 
296 static void
298 {
299  struct ClientResponseMessage *msg;
300  struct GNUNET_MQ_Envelope *e;
301 
302  if (NULL == session->client_mq)
303  return; /* no client left to be notified */
304  GNUNET_log (
306  "Sending session-end notification with status %d to client for session %s\n",
307  session->status,
308  GNUNET_h2s (&session->session_id));
310  msg->product_length = htonl (0);
311  msg->status = htonl (session->status);
312  GNUNET_MQ_send (session->client_mq, e);
313 }
314 
315 
322 static void
324 {
325  struct ClientResponseMessage *msg;
326  struct GNUNET_MQ_Envelope *e;
327  unsigned char *product_exported = NULL;
328  size_t product_length = 0;
329  int32_t range;
330  gcry_error_t rc;
331  int sign;
332  gcry_mpi_t value;
333 
334  if (NULL == s->product)
335  {
336  GNUNET_break (0);
338  return;
339  }
340  value = gcry_mpi_new (0);
341  sign = gcry_mpi_cmp_ui (s->product, 0);
342  if (0 > sign)
343  {
344  range = -1;
345  gcry_mpi_sub (value, value, s->product);
346  }
347  else if (0 < sign)
348  {
349  range = 1;
350  gcry_mpi_add (value, value, s->product);
351  }
352  else
353  {
354  /* result is exactly zero */
355  range = 0;
356  }
357  gcry_mpi_release (s->product);
358  s->product = NULL;
359 
360  if ((0 != range) && (0 != (rc = gcry_mpi_aprint (GCRYMPI_FMT_STD,
361  &product_exported,
362  &product_length,
363  value))))
364  {
365  LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_mpi_scan", rc);
367  return;
368  }
369  gcry_mpi_release (value);
370  e = GNUNET_MQ_msg_extra (msg,
371  product_length,
374  msg->range = htonl (range);
375  msg->product_length = htonl (product_length);
376  if (NULL != product_exported)
377  {
378  GNUNET_memcpy (&msg[1], product_exported, product_length);
379  GNUNET_free (product_exported);
380  }
381  GNUNET_MQ_send (s->client_mq, e);
383  "Sent result to client, session %s has ended!\n",
384  GNUNET_h2s (&s->session_id));
385 }
386 
387 
397 static void
398 cb_channel_destruction (void *cls, const struct GNUNET_CADET_Channel *channel)
399 {
400  struct AliceServiceSession *s = cls;
401 
403  "Peer disconnected, terminating session %s with peer %s\n",
404  GNUNET_h2s (&s->session_id),
405  GNUNET_i2s (&s->peer));
406  s->channel = NULL;
408  {
409  /* We didn't get an answer yet, fail with error */
412  }
413 }
414 
415 
424 static gcry_mpi_t
426  gcry_mpi_point_t prod_g_i_b_i,
427  gcry_mpi_point_t prod_h_i_b_i)
428 {
429  gcry_mpi_point_t g_i_b_i_a_inv;
430  gcry_mpi_point_t g_ai_bi;
431  int ai_bi;
432  gcry_mpi_t ret;
433 
434  g_i_b_i_a_inv =
435  GNUNET_CRYPTO_ecc_pmul_mpi (edc, prod_g_i_b_i, my_privkey_inv);
436  g_ai_bi = GNUNET_CRYPTO_ecc_add (edc, g_i_b_i_a_inv, prod_h_i_b_i);
437  gcry_mpi_point_release (g_i_b_i_a_inv);
438  ai_bi = GNUNET_CRYPTO_ecc_dlog (edc, g_ai_bi);
439  gcry_mpi_point_release (g_ai_bi);
440  if (INT_MAX == ai_bi)
441  {
442  /* result too big */
444  "Scalar product result out of range\n");
445  return NULL;
446  }
447  ret = gcry_mpi_new (0);
448  if (ai_bi > 0)
449  {
450  gcry_mpi_set_ui (ret, ai_bi);
451  }
452  else
453  {
454  gcry_mpi_set_ui (ret, -ai_bi);
455  gcry_mpi_neg (ret, ret);
456  }
457  return ret;
458 }
459 
460 
468 static void
470  const struct EccBobCryptodataMessage *msg)
471 {
472  struct AliceServiceSession *s = cls;
473  gcry_mpi_point_t prod_g_i_b_i;
474  gcry_mpi_point_t prod_h_i_b_i;
475  uint32_t contained;
476 
477  contained = ntohl (msg->contained_element_count);
478  if (2 != contained)
479  {
480  GNUNET_break_op (0);
482  return;
483  }
484  if (NULL == s->sorted_elements)
485  {
486  /* we're not ready yet, how can Bob be? */
487  GNUNET_break_op (0);
489  return;
490  }
492  {
493  /* we're not ready yet, how can Bob be? */
494  GNUNET_break_op (0);
496  return;
497  }
498 
500  "Received %u crypto values from Bob\n",
501  (unsigned int) contained);
503  prod_g_i_b_i = GNUNET_CRYPTO_ecc_bin_to_point (edc, &msg->prod_g_i_b_i);
504  prod_h_i_b_i = GNUNET_CRYPTO_ecc_bin_to_point (edc, &msg->prod_h_i_b_i);
505  s->product = compute_scalar_product (s, prod_g_i_b_i, prod_h_i_b_i);
506  gcry_mpi_point_release (prod_g_i_b_i);
507  gcry_mpi_point_release (prod_h_i_b_i);
509 }
510 
511 
520 static int
521 copy_element_cb (void *cls, const struct GNUNET_HashCode *key, void *value)
522 {
523  struct AliceServiceSession *s = cls;
525  gcry_mpi_t mval;
526  int64_t val;
527 
528  mval = gcry_mpi_new (0);
529  val = (int64_t) GNUNET_ntohll (e->value);
530  if (0 > val)
531  gcry_mpi_sub_ui (mval, mval, -val);
532  else
533  gcry_mpi_add_ui (mval, mval, val);
536  s->used_element_count++;
537  return GNUNET_OK;
538 }
539 
540 
548 static int
549 element_cmp (const void *a, const void *b)
550 {
551  const struct MpiElement *ma = a;
552  const struct MpiElement *mb = b;
553 
554  return GNUNET_CRYPTO_hash_cmp (ma->key, mb->key);
555 }
556 
557 
562 #define ELEMENT_CAPACITY \
563  ((GNUNET_CONSTANTS_MAX_CADET_MESSAGE_SIZE - 1 - \
564  sizeof (struct EccAliceCryptodataMessage)) / \
565  sizeof (struct GNUNET_CRYPTO_EccPoint))
566 
567 
574 static void
576 {
578  struct GNUNET_MQ_Envelope *e;
580  gcry_mpi_t r_ia;
581  gcry_mpi_t r_ia_ai;
582  unsigned int i;
583  unsigned int off;
584  unsigned int todo_count;
585 
588  struct MpiElement);
589  s->used_element_count = 0;
592  s);
594  "Finished intersection, %d items remain\n",
595  s->used_element_count);
596  qsort (s->sorted_elements,
598  sizeof (struct MpiElement),
599  &element_cmp);
600  off = 0;
601  while (off < s->used_element_count)
602  {
603  todo_count = s->used_element_count - off;
604  if (todo_count > ELEMENT_CAPACITY)
605  todo_count = ELEMENT_CAPACITY;
607  "Sending %u/%u crypto values to Bob\n",
608  (unsigned int) todo_count,
609  (unsigned int) s->used_element_count);
610 
611  e =
612  GNUNET_MQ_msg_extra (msg,
613  todo_count * 2 *
614  sizeof (struct GNUNET_CRYPTO_EccPoint),
616  msg->contained_element_count = htonl (todo_count);
617  payload = (struct GNUNET_CRYPTO_EccPoint *) &msg[1];
618  r_ia = gcry_mpi_new (0);
619  r_ia_ai = gcry_mpi_new (0);
620  for (i = off; i < off + todo_count; i++)
621  {
622  gcry_mpi_t r_i;
623  gcry_mpi_point_t g_i;
624  gcry_mpi_point_t h_i;
625 
626  r_i = GNUNET_CRYPTO_ecc_random_mod_n (edc);
627  g_i = GNUNET_CRYPTO_ecc_dexp_mpi (edc, r_i);
628  /* r_ia = r_i * a */
629  gcry_mpi_mul (r_ia, r_i, my_privkey);
630  gcry_mpi_release (r_i);
631  /* r_ia_ai = r_ia + a_i */
632  gcry_mpi_add (r_ia_ai, r_ia, s->sorted_elements[i].value);
633  h_i = GNUNET_CRYPTO_ecc_dexp_mpi (edc, r_ia_ai);
634  GNUNET_CRYPTO_ecc_point_to_bin (edc, g_i, &payload[(i - off) * 2]);
635  GNUNET_CRYPTO_ecc_point_to_bin (edc, h_i, &payload[(i - off) * 2 + 1]);
636  gcry_mpi_point_release (g_i);
637  gcry_mpi_point_release (h_i);
638  }
639  gcry_mpi_release (r_ia);
640  gcry_mpi_release (r_ia_ai);
641  off += todo_count;
642  GNUNET_MQ_send (s->cadet_mq, e);
643  }
644 }
645 
646 
657 static void
659  const struct GNUNET_SET_Element *element,
660  uint64_t current_size,
662 {
663  struct AliceServiceSession *s = cls;
664  struct GNUNET_SCALARPRODUCT_Element *se;
665 
666  switch (status)
667  {
669  /* this element has been removed from the set */
671  element->data);
672  GNUNET_assert (NULL != se);
674  "Intersection removed element with key %s and value %lld\n",
675  GNUNET_h2s (&se->key),
676  (long long) GNUNET_ntohll (se->value));
677  GNUNET_assert (
678  GNUNET_YES ==
680  element->data,
681  se));
682  GNUNET_free (se);
683  return;
685  s->intersection_op = NULL;
686  if (NULL != s->intersection_set)
687  {
689  s->intersection_set = NULL;
690  }
692  return;
694  /* unexpected for intersection */
695  GNUNET_break (0);
696  return;
698  /* unhandled status code */
699  LOG (GNUNET_ERROR_TYPE_DEBUG, "Set intersection failed!\n");
700  if (NULL != s->intersection_listen)
701  {
703  s->intersection_listen = NULL;
704  }
705  s->intersection_op = NULL;
706  if (NULL != s->intersection_set)
707  {
709  s->intersection_set = NULL;
710  }
713  return;
714  default:
715  GNUNET_break (0);
716  return;
717  }
718 }
719 
720 
736 static void
738  const struct GNUNET_PeerIdentity *other_peer,
739  const struct GNUNET_MessageHeader *context_msg,
740  struct GNUNET_SET_Request *request)
741 {
742  struct AliceServiceSession *s = cls;
743 
745  "Received intersection request from %s!\n",
746  GNUNET_i2s (other_peer));
747  if (0 != GNUNET_memcmp (other_peer, &s->peer))
748  {
749  GNUNET_break_op (0);
750  return;
751  }
752  s->intersection_op = GNUNET_SET_accept (request,
754  (struct GNUNET_SET_Option[]){{0}},
756  s);
757  if (NULL == s->intersection_op)
758  {
759  GNUNET_break (0);
762  return;
763  }
765  {
766  GNUNET_break (0);
769  return;
770  }
771 }
772 
773 
779 static void
781 {
782  struct GNUNET_MQ_MessageHandler cadet_handlers[] =
783  {GNUNET_MQ_hd_fixed_size (bobs_cryptodata_message,
786  s),
789  struct GNUNET_MQ_Envelope *e;
790  struct GNUNET_HashCode set_sid;
791 
793  sizeof (struct GNUNET_HashCode),
794  &set_sid);
796  "Creating new channel for session with key %s.\n",
797  GNUNET_h2s (&s->session_id));
798  s->channel = GNUNET_CADET_channel_create (my_cadet,
799  s,
800  &s->peer,
801  &s->session_id,
802  NULL,
804  cadet_handlers);
805  if (NULL == s->channel)
806  {
809  return;
810  }
814  &set_sid,
816  s);
817  if (NULL == s->intersection_listen)
818  {
821  s->channel = NULL;
823  return;
824  }
825 
826  e =
827  GNUNET_MQ_msg (msg,
830  msg->session_id = s->session_id;
831  GNUNET_MQ_send (s->cadet_mq, e);
832 }
833 
834 
843 static int
845  void *cls,
847 {
848  struct AliceServiceSession *s = cls;
849  uint32_t contained_count;
850  uint16_t msize;
851 
852  msize = ntohs (msg->header.size);
853  contained_count = ntohl (msg->element_count_contained);
854  if ((msize !=
856  contained_count * sizeof (struct GNUNET_SCALARPRODUCT_Element))) ||
857  (0 == contained_count) ||
859  (s->total < s->client_received_element_count + contained_count))
860  {
861  GNUNET_break_op (0);
862  return GNUNET_SYSERR;
863  }
864  return GNUNET_OK;
865 }
866 
867 
875 static void
877  void *cls,
879 {
880  struct AliceServiceSession *s = cls;
881  uint32_t contained_count;
882  const struct GNUNET_SCALARPRODUCT_Element *elements;
883  struct GNUNET_SET_Element set_elem;
884  struct GNUNET_SCALARPRODUCT_Element *elem;
885 
886  contained_count = ntohl (msg->element_count_contained);
887  s->client_received_element_count += contained_count;
888  elements = (const struct GNUNET_SCALARPRODUCT_Element *) &msg[1];
889  for (uint32_t i = 0; i < contained_count; i++)
890  {
892  GNUNET_memcpy (elem,
893  &elements[i],
894  sizeof (struct GNUNET_SCALARPRODUCT_Element));
897  &elem->key,
898  elem,
900  {
901  GNUNET_break (0);
902  GNUNET_free (elem);
903  continue;
904  }
905  set_elem.data = &elem->key;
906  set_elem.size = sizeof (elem->key);
907  set_elem.element_type = 0;
908  GNUNET_SET_add_element (s->intersection_set, &set_elem, NULL, NULL);
909  s->used_element_count++;
910  }
913  {
914  /* more to come */
916  "Received client multipart data, waiting for more!\n");
917  return;
918  }
919  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Launching computation\n");
921 }
922 
923 
932 static int
934  const struct AliceComputationMessage *msg)
935 {
936  struct AliceServiceSession *s = cls;
937  uint16_t msize;
938  uint32_t total_count;
939  uint32_t contained_count;
940 
941  if (NULL != s->intersected_elements)
942  {
943  /* only one concurrent session per client connection allowed,
944  simplifies logic a lot... */
945  GNUNET_break (0);
946  return GNUNET_SYSERR;
947  }
948  msize = ntohs (msg->header.size);
949  total_count = ntohl (msg->element_count_total);
950  contained_count = ntohl (msg->element_count_contained);
951  if ((0 == total_count) || (0 == contained_count) ||
952  (msize !=
953  (sizeof (struct AliceComputationMessage) +
954  contained_count * sizeof (struct GNUNET_SCALARPRODUCT_Element))))
955  {
956  GNUNET_break_op (0);
957  return GNUNET_SYSERR;
958  }
959  return GNUNET_OK;
960 }
961 
962 
970 static void
972  const struct AliceComputationMessage *msg)
973 {
974  struct AliceServiceSession *s = cls;
975  uint32_t contained_count;
976  uint32_t total_count;
977  const struct GNUNET_SCALARPRODUCT_Element *elements;
978  struct GNUNET_SET_Element set_elem;
979  struct GNUNET_SCALARPRODUCT_Element *elem;
980 
981  total_count = ntohl (msg->element_count_total);
982  contained_count = ntohl (msg->element_count_contained);
983  s->peer = msg->peer;
985  s->total = total_count;
986  s->client_received_element_count = contained_count;
987  s->session_id = msg->session_key;
988  elements = (const struct GNUNET_SCALARPRODUCT_Element *) &msg[1];
991  s->intersection_set =
993  for (uint32_t i = 0; i < contained_count; i++)
994  {
995  if (0 == GNUNET_ntohll (elements[i].value))
996  continue;
998  GNUNET_memcpy (elem,
999  &elements[i],
1000  sizeof (struct GNUNET_SCALARPRODUCT_Element));
1003  &elem->key,
1004  elem,
1006  {
1007  /* element with same key encountered twice! */
1008  GNUNET_break (0);
1009  GNUNET_free (elem);
1010  continue;
1011  }
1012  set_elem.data = &elem->key;
1013  set_elem.size = sizeof (elem->key);
1014  set_elem.element_type = 0;
1015  GNUNET_SET_add_element (s->intersection_set, &set_elem, NULL, NULL);
1016  s->used_element_count++;
1017  }
1019  if (s->total != s->client_received_element_count)
1020  {
1021  /* wait for multipart msg */
1023  "Received partial client request, waiting for more!\n");
1024  return;
1025  }
1026  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Launching computation\n");
1028 }
1029 
1030 
1037 static void
1038 shutdown_task (void *cls)
1039 {
1040  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Shutting down, initiating cleanup.\n");
1041  // FIXME: we have to cut our connections to CADET first!
1042  if (NULL != my_cadet)
1043  {
1044  GNUNET_CADET_disconnect (my_cadet);
1045  my_cadet = NULL;
1046  }
1047  if (NULL != edc)
1048  {
1050  edc = NULL;
1051  }
1052 }
1053 
1054 
1065 static void *
1067  struct GNUNET_SERVICE_Client *client,
1068  struct GNUNET_MQ_Handle *mq)
1069 {
1070  struct AliceServiceSession *s;
1071 
1072  s = GNUNET_new (struct AliceServiceSession);
1073  s->client = client;
1074  s->client_mq = mq;
1075  return s;
1076 }
1077 
1078 
1089 static void
1091  struct GNUNET_SERVICE_Client *client,
1092  void *app_cls)
1093 {
1094  struct AliceServiceSession *s = app_cls;
1095 
1097  "Client %p disconnected from us.\n",
1098  client);
1099  s->client = NULL;
1100  s->client_mq = NULL;
1102 }
1103 
1104 
1112 static void
1113 run (void *cls,
1114  const struct GNUNET_CONFIGURATION_Handle *c,
1116 {
1117  cfg = c;
1119  /* Select a random 'a' value for Alice */
1121  my_cadet = GNUNET_CADET_connect (cfg);
1122  if (NULL == my_cadet)
1123  {
1124  GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _ ("Connect to CADET failed\n"));
1126  return;
1127  }
1129 }
1130 
1131 
1136  "scalarproduct-alice",
1138  &run,
1141  NULL,
1142  GNUNET_MQ_hd_var_size (alice_client_message,
1144  struct AliceComputationMessage,
1145  NULL),
1147  alice_client_message_multipart,
1150  NULL),
1152 
1153 
1154 /* end of gnunet-service-scalarproduct-ecc_alice.c */
uint32_t contained_element_count
How many elements we appended to this message? In NBO.
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 scalarproduct session which tracks a request form the client to our final response.
struct GNUNET_CRYPTO_EccPoint prod_g_i_b_i
The product of the g_i^{b_i} values.
Message type passed from service client to finalize a session as requester or responder.
struct GNUNET_HashCode session_id
The transaction/session key used to identify a session.
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
Vector of ECC-encrypted values sent by Alice to Bob (after set intersection).
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.
Point on a curve (always for Curve25519) encoded in a format suitable for network transmission (ECDH)...
gcry_mpi_point_t GNUNET_CRYPTO_ecc_bin_to_point(struct GNUNET_CRYPTO_EccDlogContext *edc, const struct GNUNET_CRYPTO_EccPoint *bin)
Convert binary representation of a point to computational representation.
struct GNUNET_MessageHeader * msg
Definition: 005.c:2
void GNUNET_CRYPTO_ecc_rnd_mpi(struct GNUNET_CRYPTO_EccDlogContext *edc, gcry_mpi_t *r, gcry_mpi_t *r_inv)
Obtain a random scalar for point multiplication on the curve and its multiplicative inverse...
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.
unsigned int GNUNET_CONTAINER_multihashmap_size(const struct GNUNET_CONTAINER_MultiHashMap *map)
Get the number of key-value pairs in the map.
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
static void handle_alice_client_message(void *cls, const struct AliceComputationMessage *msg)
Handler for Alice&#39;s client request message.
Opaque handle to the service.
Definition: cadet_api.c:38
Handle to a service.
Definition: service.c:116
gcry_mpi_t GNUNET_CRYPTO_ecc_random_mod_n(struct GNUNET_CRYPTO_EccDlogContext *edc)
Generate a random value mod n.
scalarproduct service P2P messages
static const struct GNUNET_CONFIGURATION_Handle * cfg
GNUnet configuration handle.
const struct GNUNET_HashCode * key
Key used to identify matching pairs of values to multiply.
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
struct GNUNET_HashCode key
Key used to identify matching pairs of values to multiply.
Element stored in a set.
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.
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_MESSAGE_TYPE_SCALARPRODUCT_ECC_ALICE_CRYPTODATA
Alice -> Bob ECC crypto data.
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
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
void GNUNET_MQ_env_set_options(struct GNUNET_MQ_Envelope *env, enum GNUNET_MQ_PriorityPreferences pp)
Set application-specific options for this envelope.
Definition: mq.c:1005
struct GNUNET_MessageHeader header
GNUNET message header with type GNUNET_MESSAGE_TYPE_SCALARPRODUCT_CLIENT_TO_ALICE.
Definition: scalarproduct.h:48
static void send_alices_cryptodata_message(struct AliceServiceSession *s)
Send the cryptographic data from Alice to Bob.
#define GNUNET_MQ_hd_fixed_size(name, code, str, ctx)
static struct GNUNET_CADET_Handle * my_cadet
Handle to the CADET service.
#define GNUNET_MQ_msg(mvar, type)
Allocate a GNUNET_MQ_Envelope.
Definition: gnunet_mq_lib.h:67
static struct Experiment * e
static struct GNUNET_HashCode session_id
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
static void shutdown_task(void *cls)
Task run during shutdown.
#define GNUNET_new(type)
Allocate a struct or union of the given type.
enum GNUNET_SCALARPRODUCT_ResponseStatus status
State of this session.
struct GNUNET_CRYPTO_EccDlogContext * GNUNET_CRYPTO_ecc_dlog_prepare(unsigned int max, unsigned int mem)
Do pre-calculation for ECC discrete logarithm for small factors.
gcry_mpi_t value
a_i value, not disclosed to Bob.
uint16_t size
The length of the struct (in bytes, including the length field itself), in big-endian format...
void GNUNET_CRYPTO_ecc_point_to_bin(struct GNUNET_CRYPTO_EccDlogContext *edc, gcry_mpi_point_t point, struct GNUNET_CRYPTO_EccPoint *bin)
Convert point value to binary representation.
void GNUNET_SCHEDULER_shutdown(void)
Request the shutdown of a scheduler.
Definition: scheduler.c:524
static int ret
Final status code.
Definition: gnunet-arm.c:89
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...
static void handle_bobs_cryptodata_message(void *cls, const struct EccBobCryptodataMessage *msg)
Handle a response we got from another service we wanted to calculate a scalarproduct with...
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_SET_OperationHandle * intersection_op
Set of elements for which will conduction an intersection.
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
void GNUNET_SET_destroy(struct GNUNET_SET_Handle *set)
Destroy the set handle, and free all associated resources.
Definition: set_api.c:771
static void transmit_client_response(struct AliceServiceSession *s)
Prepare the final (positive) response we will send to Alice&#39;s client.
#define INT_MAX
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 struct GNUNET_CRYPTO_EccDlogContext * edc
Context for DLOG operations on a curve.
#define GNUNET_memcpy(dst, src, n)
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.
void GNUNET_CRYPTO_hash(const void *block, size_t size, struct GNUNET_HashCode *ret)
Compute hash of a given block.
Definition: crypto_hash.c:44
Everything went ok, we are transmitting an element of the result (in set, or to be removed from set...
void GNUNET_CONTAINER_multihashmap_destroy(struct GNUNET_CONTAINER_MultiHashMap *map)
Destroy a hash map.
GNUNET_SET_Status
Status for the result callback.
uint32_t element_count_total
how many elements the vector in payload contains
Definition: scalarproduct.h:53
uint16_t status
See PRISM_STATUS_*-constants.
gcry_mpi_point_t GNUNET_CRYPTO_ecc_add(struct GNUNET_CRYPTO_EccDlogContext *edc, gcry_mpi_point_t a, gcry_mpi_point_t b)
Add two points on the elliptic curve.
#define GNUNET_new_array(n, type)
Allocate a size n array with structs or unions of the given type.
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.
struct GNUNET_CRYPTO_EccPoint prod_h_i_b_i
The product of the h_i^{b_i} values.
uint32_t contained_element_count
How many elements this individual message delivers (in NBO), always TWO.
static void run(void *cls, const struct GNUNET_CONFIGURATION_Handle *c, struct GNUNET_SERVICE_Handle *service)
Initialization of the program and message handlers.
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.
A 512-bit hashcode.
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 cb_channel_destruction(void *cls, const struct GNUNET_CADET_Channel *channel)
Function called whenever a channel is destroyed.
Opaque handle to a set.
Definition: set_api.c:49
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...
#define GNUNET_MESSAGE_TYPE_SCALARPRODUCT_CLIENT_TO_ALICE
Client -> Alice.
struct GNUNET_TESTBED_Peer * peer
The peer associated with this model.
Message type passed from responding service Bob to responding service Alice to complete a request and...
#define GNUNET_SYSERR
Definition: gnunet_common.h:79
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.
static int free_element_cb(void *cls, const struct GNUNET_HashCode *key, void *value)
Iterator called to free elements.
#define MAX_RESULT
Maximum allowed result value for the scalarproduct computation.
An encrypted element key-value pair.
static int check_alice_client_message_multipart(void *cls, const struct ComputationBobCryptodataMultipartMessage *msg)
We&#39;re receiving additional set data.
void GNUNET_CRYPTO_ecc_dlog_release(struct GNUNET_CRYPTO_EccDlogContext *dlc)
Release precalculated values.
Message type passed from requesting service Alice to responding service Bob to initiate a request and...
static void client_disconnect_cb(void *cls, struct GNUNET_SERVICE_Client *client, void *app_cls)
A client disconnected.
void GNUNET_SET_listen_cancel(struct GNUNET_SET_ListenHandle *lh)
Cancel the given listen operation.
Definition: set_api.c:1047
static gcry_mpi_t my_privkey
Alice&#39;s private key (&#39;a&#39;).
uint32_t product_length
0 if no product attached
#define GNUNET_MESSAGE_TYPE_SCALARPRODUCT_ECC_SESSION_INITIALIZATION
Alice -> Bob ECC session initialization.
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?
gcry_mpi_point_t GNUNET_CRYPTO_ecc_dexp_mpi(struct GNUNET_CRYPTO_EccDlogContext *edc, gcry_mpi_t val)
Multiply the generator g of the elliptic curve by val to obtain the point on the curve representing v...
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.
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
static int check_alice_client_message(void *cls, const struct AliceComputationMessage *msg)
Handler for Alice&#39;s client request message.
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
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.
#define GNUNET_MESSAGE_TYPE_SCALARPRODUCT_ECC_BOB_CRYPTODATA
Bob -> Alice ECC crypto data.
configuration data
Definition: configuration.c:85
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 gcry_mpi_t compute_scalar_product(struct AliceServiceSession *session, gcry_mpi_point_t prod_g_i_b_i, gcry_mpi_point_t prod_h_i_b_i)
Compute our scalar product, done by Alice.
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,...)
#define ELEMENT_CAPACITY
Maximum number of elements we can put into a single cryptodata message.
uint32_t element_count_contained
contained elements the vector in payload contains
Definition: scalarproduct.h:58
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.
Internal structure used to cache pre-calculated values for DLOG calculation.
#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
static gcry_mpi_t my_privkey_inv
Inverse of Alice&#39;s private key (&#39;a_inv&#39;).
struct GNUNET_SERVICE_Client * client
The client this request is related to.
static void client_request_complete_alice(struct AliceServiceSession *s)
Our client has finished sending us its multipart message.
Set intersection, only return elements that are in both sets.
GNUNET_SCALARPRODUCT_ResponseStatus
Result status values for the computation.
static void handle_alice_client_message_multipart(void *cls, const struct ComputationBobCryptodataMultipartMessage *msg)
We&#39;re receiving additional set data.
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.
Highest priority, control traffic (i.e.
#define LOG(kind,...)
int GNUNET_CRYPTO_ecc_dlog(struct GNUNET_CRYPTO_EccDlogContext *edc, gcry_mpi_point_t input)
Calculate ECC discrete logarithm for small factors.
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".
#define MAX_RAM
How many values should DLOG store in memory (determines baseline RAM consumption, roughly 100 bytes t...
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
gcry_mpi_point_t GNUNET_CRYPTO_ecc_pmul_mpi(struct GNUNET_CRYPTO_EccDlogContext *edc, gcry_mpi_point_t p, gcry_mpi_t val)
Multiply the point p on the elliptic curve by val.
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.
static void destroy_service_session(struct AliceServiceSession *s)
Destroy session state, we are done with it.
static void prepare_client_end_notification(struct AliceServiceSession *session)
Notify the client that the session has failed.
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
static int element_cmp(const void *a, const void *b)
Compare two struct MpiValues by key for sorting.
#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
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
static void * client_connect_cb(void *cls, struct GNUNET_SERVICE_Client *client, struct GNUNET_MQ_Handle *mq)
A client connected.