GNUnet  0.11.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_seti_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 {
86 
91 
96 
101 
106 
112 
118 
124 
129 
134 
139 
143  gcry_mpi_t product;
144 
149  uint32_t total;
150 
157 
163 
171 
177 };
178 
179 
183 static const struct GNUNET_CONFIGURATION_Handle *cfg;
184 
189 
193 static gcry_mpi_t my_privkey;
194 
198 static gcry_mpi_t my_privkey_inv;
199 
204 
205 
214 static int
215 free_element_cb (void *cls, const struct GNUNET_HashCode *key, void *value)
216 {
218 
219  GNUNET_free (e);
220  return GNUNET_OK;
221 }
222 
223 
229 static void
231 {
232  unsigned int i;
233 
234  if (GNUNET_YES == s->in_destroy)
235  return;
236  s->in_destroy = GNUNET_YES;
237  if (NULL != s->client)
238  {
239  struct GNUNET_SERVICE_Client *c = s->client;
240 
241  s->client = NULL;
243  }
244  if (NULL != s->channel)
245  {
247  s->channel = NULL;
248  }
249  if (NULL != s->intersected_elements)
250  {
253  s);
255  s->intersected_elements = NULL;
256  }
257  if (NULL != s->intersection_listen)
258  {
260  s->intersection_listen = NULL;
261  }
262  if (NULL != s->intersection_op)
263  {
264  LOG (GNUNET_ERROR_TYPE_DEBUG, "Set intersection, op still ongoing!\n");
266  s->intersection_op = NULL;
267  }
268  if (NULL != s->intersection_set)
269  {
271  s->intersection_set = NULL;
272  }
273  if (NULL != s->sorted_elements)
274  {
275  for (i = 0; i < s->used_element_count; i++)
276  gcry_mpi_release (s->sorted_elements[i].value);
278  s->sorted_elements = NULL;
279  }
280  if (NULL != s->product)
281  {
282  gcry_mpi_release (s->product);
283  s->product = NULL;
284  }
285  GNUNET_free (s);
286 }
287 
288 
295 static void
297 {
298  struct ClientResponseMessage *msg;
299  struct GNUNET_MQ_Envelope *e;
300 
301  if (NULL == session->client_mq)
302  return; /* no client left to be notified */
303  GNUNET_log (
305  "Sending session-end notification with status %d to client for session %s\n",
306  session->status,
307  GNUNET_h2s (&session->session_id));
309  msg->product_length = htonl (0);
310  msg->status = htonl (session->status);
311  GNUNET_MQ_send (session->client_mq, e);
312 }
313 
314 
321 static void
323 {
324  struct ClientResponseMessage *msg;
325  struct GNUNET_MQ_Envelope *e;
326  unsigned char *product_exported = NULL;
327  size_t product_length = 0;
328  int32_t range;
329  gcry_error_t rc;
330  int sign;
331  gcry_mpi_t value;
332 
333  if (NULL == s->product)
334  {
335  GNUNET_break (0);
337  return;
338  }
339  value = gcry_mpi_new (0);
340  sign = gcry_mpi_cmp_ui (s->product, 0);
341  if (0 > sign)
342  {
343  range = -1;
344  gcry_mpi_sub (value, value, s->product);
345  }
346  else if (0 < sign)
347  {
348  range = 1;
349  gcry_mpi_add (value, value, s->product);
350  }
351  else
352  {
353  /* result is exactly zero */
354  range = 0;
355  }
356  gcry_mpi_release (s->product);
357  s->product = NULL;
358 
359  if ((0 != range) && (0 != (rc = gcry_mpi_aprint (GCRYMPI_FMT_STD,
360  &product_exported,
361  &product_length,
362  value))))
363  {
364  LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_mpi_scan", rc);
366  return;
367  }
368  gcry_mpi_release (value);
369  e = GNUNET_MQ_msg_extra (msg,
370  product_length,
373  msg->range = htonl (range);
374  msg->product_length = htonl (product_length);
375  if (NULL != product_exported)
376  {
377  GNUNET_memcpy (&msg[1], product_exported, product_length);
378  GNUNET_free (product_exported);
379  }
380  GNUNET_MQ_send (s->client_mq, e);
382  "Sent result to client, session %s has ended!\n",
383  GNUNET_h2s (&s->session_id));
384 }
385 
386 
396 static void
397 cb_channel_destruction (void *cls, const struct GNUNET_CADET_Channel *channel)
398 {
399  struct AliceServiceSession *s = cls;
400 
402  "Peer disconnected, terminating session %s with peer %s\n",
403  GNUNET_h2s (&s->session_id),
404  GNUNET_i2s (&s->peer));
405  s->channel = NULL;
407  {
408  /* We didn't get an answer yet, fail with error */
411  }
412 }
413 
414 
423 static gcry_mpi_t
425  gcry_mpi_point_t prod_g_i_b_i,
426  gcry_mpi_point_t prod_h_i_b_i)
427 {
428  gcry_mpi_point_t g_i_b_i_a_inv;
429  gcry_mpi_point_t g_ai_bi;
430  int ai_bi;
431  gcry_mpi_t ret;
432 
433  g_i_b_i_a_inv =
434  GNUNET_CRYPTO_ecc_pmul_mpi (edc, prod_g_i_b_i, my_privkey_inv);
435  g_ai_bi = GNUNET_CRYPTO_ecc_add (edc, g_i_b_i_a_inv, prod_h_i_b_i);
436  gcry_mpi_point_release (g_i_b_i_a_inv);
437  ai_bi = GNUNET_CRYPTO_ecc_dlog (edc, g_ai_bi);
438  gcry_mpi_point_release (g_ai_bi);
439  if (INT_MAX == ai_bi)
440  {
441  /* result too big */
443  "Scalar product result out of range\n");
444  return NULL;
445  }
446  ret = gcry_mpi_new (0);
447  if (ai_bi > 0)
448  {
449  gcry_mpi_set_ui (ret, ai_bi);
450  }
451  else
452  {
453  gcry_mpi_set_ui (ret, -ai_bi);
454  gcry_mpi_neg (ret, ret);
455  }
456  return ret;
457 }
458 
459 
467 static void
469  const struct EccBobCryptodataMessage *msg)
470 {
471  struct AliceServiceSession *s = cls;
472  gcry_mpi_point_t prod_g_i_b_i;
473  gcry_mpi_point_t prod_h_i_b_i;
474  uint32_t contained;
475 
476  contained = ntohl (msg->contained_element_count);
477  if (2 != contained)
478  {
479  GNUNET_break_op (0);
481  return;
482  }
483  if (NULL == s->sorted_elements)
484  {
485  /* we're not ready yet, how can Bob be? */
486  GNUNET_break_op (0);
488  return;
489  }
491  {
492  /* we're not ready yet, how can Bob be? */
493  GNUNET_break_op (0);
495  return;
496  }
497 
499  "Received %u crypto values from Bob\n",
500  (unsigned int) contained);
502  prod_g_i_b_i = GNUNET_CRYPTO_ecc_bin_to_point (edc, &msg->prod_g_i_b_i);
503  prod_h_i_b_i = GNUNET_CRYPTO_ecc_bin_to_point (edc, &msg->prod_h_i_b_i);
504  s->product = compute_scalar_product (s, prod_g_i_b_i, prod_h_i_b_i);
505  gcry_mpi_point_release (prod_g_i_b_i);
506  gcry_mpi_point_release (prod_h_i_b_i);
508 }
509 
510 
519 static int
520 copy_element_cb (void *cls, const struct GNUNET_HashCode *key, void *value)
521 {
522  struct AliceServiceSession *s = cls;
524  gcry_mpi_t mval;
525  int64_t val;
526 
527  mval = gcry_mpi_new (0);
528  val = (int64_t) GNUNET_ntohll (e->value);
529  if (0 > val)
530  gcry_mpi_sub_ui (mval, mval, -val);
531  else
532  gcry_mpi_add_ui (mval, mval, val);
535  s->used_element_count++;
536  return GNUNET_OK;
537 }
538 
539 
547 static int
548 element_cmp (const void *a, const void *b)
549 {
550  const struct MpiElement *ma = a;
551  const struct MpiElement *mb = b;
552 
553  return GNUNET_CRYPTO_hash_cmp (ma->key, mb->key);
554 }
555 
556 
561 #define ELEMENT_CAPACITY \
562  ((GNUNET_CONSTANTS_MAX_CADET_MESSAGE_SIZE - 1 \
563  - sizeof(struct EccAliceCryptodataMessage)) \
564  / sizeof(struct GNUNET_CRYPTO_EccPoint))
565 
566 
573 static void
575 {
577  struct GNUNET_MQ_Envelope *e;
579  gcry_mpi_t r_ia;
580  gcry_mpi_t r_ia_ai;
581  unsigned int i;
582  unsigned int off;
583  unsigned int todo_count;
584 
587  struct MpiElement);
588  s->used_element_count = 0;
591  s);
593  "Finished intersection, %d items remain\n",
594  s->used_element_count);
595  qsort (s->sorted_elements,
597  sizeof(struct MpiElement),
598  &element_cmp);
599  off = 0;
600  while (off < s->used_element_count)
601  {
602  todo_count = s->used_element_count - off;
603  if (todo_count > ELEMENT_CAPACITY)
604  todo_count = ELEMENT_CAPACITY;
606  "Sending %u/%u crypto values to Bob\n",
607  (unsigned int) todo_count,
608  (unsigned int) s->used_element_count);
609 
610  e =
611  GNUNET_MQ_msg_extra (msg,
612  todo_count * 2
613  * sizeof(struct GNUNET_CRYPTO_EccPoint),
615  msg->contained_element_count = htonl (todo_count);
616  payload = (struct GNUNET_CRYPTO_EccPoint *) &msg[1];
617  r_ia = gcry_mpi_new (0);
618  r_ia_ai = gcry_mpi_new (0);
619  for (i = off; i < off + todo_count; i++)
620  {
621  gcry_mpi_t r_i;
622  gcry_mpi_point_t g_i;
623  gcry_mpi_point_t h_i;
624 
625  r_i = GNUNET_CRYPTO_ecc_random_mod_n (edc);
626  g_i = GNUNET_CRYPTO_ecc_dexp_mpi (edc, r_i);
627  /* r_ia = r_i * a */
628  gcry_mpi_mul (r_ia, r_i, my_privkey);
629  gcry_mpi_release (r_i);
630  /* r_ia_ai = r_ia + a_i */
631  gcry_mpi_add (r_ia_ai, r_ia, s->sorted_elements[i].value);
632  h_i = GNUNET_CRYPTO_ecc_dexp_mpi (edc, r_ia_ai);
633  GNUNET_CRYPTO_ecc_point_to_bin (edc, g_i, &payload[(i - off) * 2]);
634  GNUNET_CRYPTO_ecc_point_to_bin (edc, h_i, &payload[(i - off) * 2 + 1]);
635  gcry_mpi_point_release (g_i);
636  gcry_mpi_point_release (h_i);
637  }
638  gcry_mpi_release (r_ia);
639  gcry_mpi_release (r_ia_ai);
640  off += todo_count;
641  GNUNET_MQ_send (s->cadet_mq, e);
642  }
643 }
644 
645 
656 static void
658  const struct GNUNET_SETI_Element *element,
659  uint64_t current_size,
661 {
662  struct AliceServiceSession *s = cls;
663  struct GNUNET_SCALARPRODUCT_Element *se;
664 
665  switch (status)
666  {
668  /* this element has been removed from the set */
670  element->data);
671  GNUNET_assert (NULL != se);
673  "Intersection removed element with key %s and value %lld\n",
674  GNUNET_h2s (&se->key),
675  (long long) GNUNET_ntohll (se->value));
676  GNUNET_assert (
677  GNUNET_YES ==
679  element->data,
680  se));
681  GNUNET_free (se);
682  return;
684  s->intersection_op = NULL;
685  if (NULL != s->intersection_set)
686  {
688  s->intersection_set = NULL;
689  }
691  return;
693  /* unhandled status code */
694  LOG (GNUNET_ERROR_TYPE_DEBUG, "Set intersection failed!\n");
695  if (NULL != s->intersection_listen)
696  {
698  s->intersection_listen = NULL;
699  }
700  s->intersection_op = NULL;
701  if (NULL != s->intersection_set)
702  {
704  s->intersection_set = NULL;
705  }
708  return;
709 
710  default:
711  GNUNET_break (0);
712  return;
713  }
714 }
715 
716 
732 static void
734  const struct GNUNET_PeerIdentity *other_peer,
735  const struct GNUNET_MessageHeader *context_msg,
737 {
738  struct AliceServiceSession *s = cls;
739 
741  "Received intersection request from %s!\n",
742  GNUNET_i2s (other_peer));
743  if (0 != GNUNET_memcmp (other_peer, &s->peer))
744  {
745  GNUNET_break_op (0);
746  return;
747  }
748  s->intersection_op = GNUNET_SETI_accept (request,
749  (struct
750  GNUNET_SETI_Option[]){ { 0 } },
752  s);
753  if (NULL == s->intersection_op)
754  {
755  GNUNET_break (0);
758  return;
759  }
761  {
762  GNUNET_break (0);
765  return;
766  }
767 }
768 
769 
775 static void
777 {
778  struct GNUNET_MQ_MessageHandler cadet_handlers[] =
779  { GNUNET_MQ_hd_fixed_size (bobs_cryptodata_message,
782  s),
785  struct GNUNET_MQ_Envelope *e;
786  struct GNUNET_HashCode set_sid;
787 
789  sizeof(struct GNUNET_HashCode),
790  &set_sid);
792  "Creating new channel for session with key %s.\n",
793  GNUNET_h2s (&s->session_id));
794  s->channel = GNUNET_CADET_channel_create (my_cadet,
795  s,
796  &s->peer,
797  &s->session_id,
798  NULL,
800  cadet_handlers);
801  if (NULL == s->channel)
802  {
805  return;
806  }
809  &set_sid,
811  s);
812  if (NULL == s->intersection_listen)
813  {
816  s->channel = NULL;
818  return;
819  }
820 
821  e =
822  GNUNET_MQ_msg (msg,
825  msg->session_id = s->session_id;
826  GNUNET_MQ_send (s->cadet_mq, e);
827 }
828 
829 
838 static int
840  void *cls,
842 {
843  struct AliceServiceSession *s = cls;
844  uint32_t contained_count;
845  uint16_t msize;
846 
847  msize = ntohs (msg->header.size);
848  contained_count = ntohl (msg->element_count_contained);
849  if ((msize !=
851  + contained_count * sizeof(struct GNUNET_SCALARPRODUCT_Element))) ||
852  (0 == contained_count) ||
854  (s->total < s->client_received_element_count + contained_count))
855  {
856  GNUNET_break_op (0);
857  return GNUNET_SYSERR;
858  }
859  return GNUNET_OK;
860 }
861 
862 
870 static void
872  void *cls,
874 {
875  struct AliceServiceSession *s = cls;
876  uint32_t contained_count;
877  const struct GNUNET_SCALARPRODUCT_Element *elements;
878  struct GNUNET_SETI_Element set_elem;
879  struct GNUNET_SCALARPRODUCT_Element *elem;
880 
881  contained_count = ntohl (msg->element_count_contained);
882  s->client_received_element_count += contained_count;
883  elements = (const struct GNUNET_SCALARPRODUCT_Element *) &msg[1];
884  for (uint32_t i = 0; i < contained_count; i++)
885  {
887  GNUNET_memcpy (elem,
888  &elements[i],
889  sizeof(struct GNUNET_SCALARPRODUCT_Element));
892  &elem->key,
893  elem,
895  {
896  GNUNET_break (0);
897  GNUNET_free (elem);
898  continue;
899  }
900  set_elem.data = &elem->key;
901  set_elem.size = sizeof(elem->key);
902  set_elem.element_type = 0;
903  GNUNET_SETI_add_element (s->intersection_set, &set_elem, NULL, NULL);
904  s->used_element_count++;
905  }
908  {
909  /* more to come */
911  "Received client multipart data, waiting for more!\n");
912  return;
913  }
914  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Launching computation\n");
916 }
917 
918 
927 static int
929  const struct AliceComputationMessage *msg)
930 {
931  struct AliceServiceSession *s = cls;
932  uint16_t msize;
933  uint32_t total_count;
934  uint32_t contained_count;
935 
936  if (NULL != s->intersected_elements)
937  {
938  /* only one concurrent session per client connection allowed,
939  simplifies logic a lot... */
940  GNUNET_break (0);
941  return GNUNET_SYSERR;
942  }
943  msize = ntohs (msg->header.size);
944  total_count = ntohl (msg->element_count_total);
945  contained_count = ntohl (msg->element_count_contained);
946  if ((0 == total_count) || (0 == contained_count) ||
947  (msize !=
948  (sizeof(struct AliceComputationMessage)
949  + contained_count * sizeof(struct GNUNET_SCALARPRODUCT_Element))))
950  {
951  GNUNET_break_op (0);
952  return GNUNET_SYSERR;
953  }
954  return GNUNET_OK;
955 }
956 
957 
965 static void
967  const struct AliceComputationMessage *msg)
968 {
969  struct AliceServiceSession *s = cls;
970  uint32_t contained_count;
971  uint32_t total_count;
972  const struct GNUNET_SCALARPRODUCT_Element *elements;
973  struct GNUNET_SETI_Element set_elem;
974  struct GNUNET_SCALARPRODUCT_Element *elem;
975 
976  total_count = ntohl (msg->element_count_total);
977  contained_count = ntohl (msg->element_count_contained);
978  s->peer = msg->peer;
980  s->total = total_count;
981  s->client_received_element_count = contained_count;
982  s->session_id = msg->session_key;
983  elements = (const struct GNUNET_SCALARPRODUCT_Element *) &msg[1];
987  for (uint32_t i = 0; i < contained_count; i++)
988  {
989  if (0 == GNUNET_ntohll (elements[i].value))
990  continue;
992  GNUNET_memcpy (elem,
993  &elements[i],
994  sizeof(struct GNUNET_SCALARPRODUCT_Element));
997  &elem->key,
998  elem,
1000  {
1001  /* element with same key encountered twice! */
1002  GNUNET_break (0);
1003  GNUNET_free (elem);
1004  continue;
1005  }
1006  set_elem.data = &elem->key;
1007  set_elem.size = sizeof(elem->key);
1008  set_elem.element_type = 0;
1009  GNUNET_SETI_add_element (s->intersection_set, &set_elem, NULL, NULL);
1010  s->used_element_count++;
1011  }
1013  if (s->total != s->client_received_element_count)
1014  {
1015  /* wait for multipart msg */
1017  "Received partial client request, waiting for more!\n");
1018  return;
1019  }
1020  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Launching computation\n");
1022 }
1023 
1024 
1031 static void
1032 shutdown_task (void *cls)
1033 {
1034  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Shutting down, initiating cleanup.\n");
1035  // FIXME: we have to cut our connections to CADET first!
1036  if (NULL != my_cadet)
1037  {
1038  GNUNET_CADET_disconnect (my_cadet);
1039  my_cadet = NULL;
1040  }
1041  if (NULL != edc)
1042  {
1044  edc = NULL;
1045  }
1046 }
1047 
1048 
1059 static void *
1061  struct GNUNET_SERVICE_Client *client,
1062  struct GNUNET_MQ_Handle *mq)
1063 {
1064  struct AliceServiceSession *s;
1065 
1066  s = GNUNET_new (struct AliceServiceSession);
1067  s->client = client;
1068  s->client_mq = mq;
1069  return s;
1070 }
1071 
1072 
1083 static void
1085  struct GNUNET_SERVICE_Client *client,
1086  void *app_cls)
1087 {
1088  struct AliceServiceSession *s = app_cls;
1089 
1091  "Client %p disconnected from us.\n",
1092  client);
1093  s->client = NULL;
1094  s->client_mq = NULL;
1096 }
1097 
1098 
1106 static void
1107 run (void *cls,
1108  const struct GNUNET_CONFIGURATION_Handle *c,
1110 {
1111  cfg = c;
1113  /* Select a random 'a' value for Alice */
1115  my_cadet = GNUNET_CADET_connect (cfg);
1116  if (NULL == my_cadet)
1117  {
1118  GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _ ("Connect to CADET failed\n"));
1120  return;
1121  }
1123 }
1124 
1125 
1130  "scalarproduct-alice",
1132  &run,
1135  NULL,
1136  GNUNET_MQ_hd_var_size (alice_client_message,
1138  struct AliceComputationMessage,
1139  NULL),
1141  alice_client_message_multipart,
1144  NULL),
1146 
1147 
1148 /* 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.
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.
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
Vector of ECC-encrypted values sent by Alice to Bob (after set intersection).
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.
Point on a curve (always for Curve25519) encoded in a format suitable for network transmission (ECDH)...
Success, all elements have been sent (and received).
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...
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.
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 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.
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.
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
struct GNUNET_HashCode key
Key used to identify matching pairs of values to multiply.
struct GNUNET_SETI_ListenHandle * intersection_listen
Handle to Alice&#39;s Intersection operation listening for Bob.
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.
#define GNUNET_MESSAGE_TYPE_SCALARPRODUCT_ECC_ALICE_CRYPTODATA
Alice -> Bob ECC crypto data.
Option for set operations.
#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:1022
struct GNUNET_MessageHeader header
GNUNET message header with type GNUNET_MESSAGE_TYPE_SCALARPRODUCT_CLIENT_TO_ALICE.
Definition: scalarproduct.h:51
static void send_alices_cryptodata_message(struct AliceServiceSession *s)
Send the cryptographic data from Alice to Bob.
#define GNUNET_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
#define GNUNET_MQ_hd_fixed_size(name, code, str, ctx)
static struct GNUNET_CADET_Handle * my_cadet
Handle to the CADET service.
static int ret
Return value of the commandline.
Definition: gnunet-abd.c:81
#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.h:116
const char * GNUNET_h2s(const struct GNUNET_HashCode *hc)
Convert a hash value to a string (for printing debug messages).
static void shutdown_task(void *cls)
Task run during shutdown.
#define GNUNET_new(type)
Allocate a struct or union of the given type.
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.
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:531
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...
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:45
struct GNUNET_HashCode session_key
the transaction/session key used to identify a session
Definition: scalarproduct.h:71
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
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 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.
Opaque handle to a set.
Definition: seti_api.c:39
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_CRYPTO_hash(const void *block, size_t size, struct GNUNET_HashCode *ret)
Compute hash of a given block.
Definition: crypto_hash.c:48
void GNUNET_CONTAINER_multihashmap_destroy(struct GNUNET_CONTAINER_MultiHashMap *map)
Destroy a hash map.
uint32_t element_count_total
how many elements the vector in payload contains
Definition: scalarproduct.h:56
Element stored in a set.
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.
const void * data
Actual data of the element.
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
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.
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:2323
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.
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...
#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...
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.
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.
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...
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.
gcry_mpi_t product
The computed scalar.
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).
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
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.
#define GNUNET_MESSAGE_TYPE_SCALARPRODUCT_ECC_BOB_CRYPTODATA
Bob -> Alice ECC crypto data.
configuration data
Definition: configuration.c:84
GNUNET_SETI_Status
Status for the result callback.
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 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.
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:61
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.
Internal structure used to cache pre-calculated values for DLOG calculation.
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
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.
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.
Highest priority, control traffic (i.e.
#define LOG(kind,...)
struct GNUNET_SETI_OperationHandle * intersection_op
Set of elements for which will conduction an intersection.
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".
void GNUNET_SETI_listen_cancel(struct GNUNET_SETI_ListenHandle *lh)
Cancel the given listen operation.
Definition: seti_api.c:747
#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:837
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:2242
#define GNUNET_MQ_handler_end()
End-marker for the handlers array.
uint16_t element_type
Application-specific element type.
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:53
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.
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
static void * client_connect_cb(void *cls, struct GNUNET_SERVICE_Client *client, struct GNUNET_MQ_Handle *mq)
A client connected.