GNUnet debian-0.24.3-29-g453fda2cf
 
Loading...
Searching...
No Matches
gnunet-service-scalarproduct_bob.c File Reference

scalarproduct service implementation More...

#include "platform.h"
#include <limits.h>
#include <gcrypt.h>
#include "gnunet_util_lib.h"
#include "gnunet_cadet_service.h"
#include "gnunet_protocols.h"
#include "gnunet_scalarproduct_service.h"
#include "gnunet_seti_service.h"
#include "scalarproduct.h"
#include "gnunet-service-scalarproduct.h"
#include "gnunet_constants.h"
Include dependency graph for gnunet-service-scalarproduct_bob.c:

Go to the source code of this file.

Data Structures

struct  MpiElement
 An encrypted element key-value pair. More...
 
struct  BobServiceSession
 A scalarproduct session which tracks an offer for a multiplication service by a local client. More...
 

Macros

#define LOG(kind, ...)   GNUNET_log_from (kind, "scalarproduct-bob", __VA_ARGS__)
 
#define ELEMENT_CAPACITY
 Maximum count of elements we can put into a multipart message.
 

Functions

static int free_element_cb (void *cls, const struct GNUNET_HashCode *key, void *value)
 Callback used to free the elements in the map.
 
static void destroy_service_session (struct BobServiceSession *s)
 Destroy session state, we are done with it.
 
static void prepare_client_end_notification (struct BobServiceSession *session)
 Notify the client that the session has succeeded or failed.
 
static void cb_channel_destruction (void *cls, const struct GNUNET_CADET_Channel *channel)
 Function called whenever a channel is destroyed.
 
static void bob_cadet_done_cb (void *cls)
 MQ finished giving our last message to CADET, now notify the client that we are finished.
 
static void transmit_bobs_cryptodata_message_multipart (struct BobServiceSession *s)
 Send a multipart chunk of a service response from Bob to Alice.
 
static void transmit_bobs_cryptodata_message (struct BobServiceSession *s)
 Bob generates the response message to be sent to Alice after computing the values (1), (2), S and S'.
 
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 int compute_service_response (struct BobServiceSession *session)
 Compute the values (1)[]: $E_A(a_{pi(i)}) otimes E_A(- r_{pi(i)} - b_{pi(i)}) &= E_A(a_{pi(i)} - r_{pi(i)} - b_{pi(i)})$ (2)[]: $E_A(a_{pi'(i)}) otimes E_A(- r_{pi'(i)}) &= E_A(a_{pi'(i)} - r_{pi'(i)})$ S: $S := E_A(sum (r_i + b_i)^2)$ S': $S' := E_A(sum r_i^2)$.
 
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.
 
static int element_cmp (const void *a, const void *b)
 Compare two struct MpiValues by key for sorting.
 
static void transmit_cryptographic_reply (struct BobServiceSession *s)
 Intersection operation and receiving data via CADET from Alice are both done, compute and transmit our reply via CADET.
 
static int check_alices_cryptodata_message (void *cls, const struct AliceCryptodataMessage *msg)
 Check a multipart-chunk of a request from another service to calculate a scalarproduct with us.
 
static void handle_alices_cryptodata_message (void *cls, const struct AliceCryptodataMessage *msg)
 Handle a multipart-chunk of a request from another service to calculate a scalarproduct with us.
 
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.
 
static void start_intersection (struct BobServiceSession *s)
 We've paired up a client session with an incoming CADET request.
 
static void handle_alices_computation_request (void *cls, const struct ServiceRequestMessage *msg)
 Handle a request from Alice to calculate a scalarproduct with us (Bob).
 
static void * cb_channel_incoming (void *cls, struct GNUNET_CADET_Channel *channel, const struct GNUNET_PeerIdentity *initiator)
 Function called for inbound channels on Bob's end.
 
static int check_bob_client_message_multipart (void *cls, const struct ComputationBobCryptodataMultipartMessage *msg)
 We're receiving additional set data.
 
static void handle_bob_client_message_multipart (void *cls, const struct ComputationBobCryptodataMultipartMessage *msg)
 We're receiving additional set data.
 
static int check_bob_client_message (void *cls, const struct BobComputationMessage *msg)
 Handler for Bob's a client request message.
 
static void handle_bob_client_message (void *cls, const struct BobComputationMessage *msg)
 Handler for Bob's a client request message.
 
static void shutdown_task (void *cls)
 Task run during shutdown.
 
static void * client_connect_cb (void *cls, struct GNUNET_SERVICE_Client *client, struct GNUNET_MQ_Handle *mq)
 A client connected.
 
static void client_disconnect_cb (void *cls, struct GNUNET_SERVICE_Client *client, void *app_cls)
 A client disconnected.
 
static void run (void *cls, const struct GNUNET_CONFIGURATION_Handle *c, struct GNUNET_SERVICE_Handle *service)
 Initialization of the program and message handlers.
 
 GNUNET_SERVICE_MAIN (GNUNET_OS_project_data_gnunet(), "scalarproduct-bob", GNUNET_SERVICE_OPTION_NONE, &run, &client_connect_cb, &client_disconnect_cb, NULL, GNUNET_MQ_hd_var_size(bob_client_message, GNUNET_MESSAGE_TYPE_SCALARPRODUCT_CLIENT_TO_BOB, struct BobComputationMessage, NULL), GNUNET_MQ_hd_var_size(bob_client_message_multipart, GNUNET_MESSAGE_TYPE_SCALARPRODUCT_CLIENT_MULTIPART_BOB, struct ComputationBobCryptodataMultipartMessage, NULL), GNUNET_MQ_handler_end())
 Define "main" method using service macro.
 

Variables

static const struct GNUNET_CONFIGURATION_Handlecfg
 GNUnet configuration handle.
 
static struct GNUNET_CRYPTO_PaillierPublicKey my_pubkey
 Service's own public key.
 
static struct GNUNET_CRYPTO_PaillierPrivateKey my_privkey
 Service's own private key.
 
static gcry_mpi_t my_offset
 Service's offset for values that could possibly be negative but are plaintext for encryption.
 
static struct GNUNET_CADET_Handlemy_cadet
 Handle to the CADET service.
 

Detailed Description

scalarproduct service implementation

Author
Christian M. Fuchs
Christian Grothoff

Definition in file gnunet-service-scalarproduct_bob.c.

Macro Definition Documentation

◆ LOG

#define LOG (   kind,
  ... 
)    GNUNET_log_from (kind, "scalarproduct-bob", __VA_ARGS__)

Definition at line 38 of file gnunet-service-scalarproduct_bob.c.

◆ ELEMENT_CAPACITY

#define ELEMENT_CAPACITY
Value:
- sizeof(struct BobCryptodataMultipartMessage)) \
/ sizeof(struct \
#define GNUNET_CONSTANTS_MAX_CADET_MESSAGE_SIZE
Maximum message size that can be sent on CADET.
Multipart Message type passed between to supply additional elements for the peer.

Maximum count of elements we can put into a multipart message.

Definition at line 398 of file gnunet-service-scalarproduct_bob.c.

411{
414 struct GNUNET_MQ_Envelope *e;
415 unsigned int i;
416 unsigned int j;
417 uint32_t todo_count;
418
419 while (s->cadet_transmitted_element_count != s->used_element_count)
420 {
421 todo_count = s->used_element_count - s->cadet_transmitted_element_count;
422 if (todo_count > ELEMENT_CAPACITY / 2)
423 todo_count = ELEMENT_CAPACITY / 2;
424
426 "Sending %u additional crypto values to Alice\n",
427 (unsigned int) todo_count);
429 todo_count * sizeof(struct
431 * 2,
433 msg->contained_element_count = htonl (todo_count);
435 for (i = s->cadet_transmitted_element_count, j = 0; i <
436 s->cadet_transmitted_element_count + todo_count; i++)
437 {
438 // r[i][p] and r[i][q]
439 GNUNET_memcpy (&payload[j++],
440 &s->r[i],
441 sizeof(struct GNUNET_CRYPTO_PaillierCiphertext));
442 GNUNET_memcpy (&payload[j++],
443 &s->r_prime[i],
444 sizeof(struct GNUNET_CRYPTO_PaillierCiphertext));
445 }
446 s->cadet_transmitted_element_count += todo_count;
447 if (s->cadet_transmitted_element_count == s->used_element_count)
450 s);
451 GNUNET_MQ_send (s->cadet_mq,
452 e);
453 }
455 "All values queued for Alice, Bob is done\n");
456}
457
458
470static void
472{
474 struct GNUNET_MQ_Envelope *e;
476 unsigned int i;
477
479 = ((GNUNET_CONSTANTS_MAX_CADET_MESSAGE_SIZE - 1 - sizeof(struct
481 / sizeof(struct GNUNET_CRYPTO_PaillierCiphertext) / 2) - 1;
484
487 * sizeof(struct GNUNET_CRYPTO_PaillierCiphertext),
489 msg->contained_element_count = htonl (s->cadet_transmitted_element_count);
490
492 "Sending %u/%u crypto values to Alice\n",
493 (unsigned int) s->cadet_transmitted_element_count,
494 (unsigned int) s->used_element_count);
495
498 &s->s,
499 sizeof(struct GNUNET_CRYPTO_PaillierCiphertext));
501 &s->s_prime,
502 sizeof(struct GNUNET_CRYPTO_PaillierCiphertext));
503
504 payload = &payload[2];
505 // convert k[][]
506 for (i = 0; i < s->cadet_transmitted_element_count; i++)
507 {
508 // k[i][p] and k[i][q]
509 GNUNET_memcpy (&payload[i * 2],
510 &s->r[i],
511 sizeof(struct GNUNET_CRYPTO_PaillierCiphertext));
512 GNUNET_memcpy (&payload[i * 2 + 1],
513 &s->r_prime[i],
514 sizeof(struct GNUNET_CRYPTO_PaillierCiphertext));
515 }
519 s);
521 e);
523}
524
525
526#undef ELEMENT_CAPACITY
527
528
537static gcry_mpi_t
538compute_square_sum (const gcry_mpi_t *vector,
539 uint32_t length)
540{
541 gcry_mpi_t elem;
542 gcry_mpi_t sum;
543 uint32_t i;
544
545 GNUNET_assert (NULL != (sum = gcry_mpi_new (0)));
546 GNUNET_assert (NULL != (elem = gcry_mpi_new (0)));
547 for (i = 0; i < length; i++)
548 {
549 gcry_mpi_mul (elem, vector[i], vector[i]);
550 gcry_mpi_add (sum, sum, elem);
551 }
552 gcry_mpi_release (elem);
553 return sum;
554}
555
556
567static int
569{
570 uint32_t i;
571 unsigned int *p;
572 unsigned int *q;
573 uint32_t count;
574 gcry_mpi_t *rand;
575 gcry_mpi_t tmp;
576 const struct MpiElement *b;
579 struct GNUNET_CRYPTO_PaillierCiphertext *r_prime;
580
581 count = session->used_element_count;
582 a = session->e_a;
583 b = session->sorted_elements;
585 count);
587 count);
588 rand = GNUNET_malloc (sizeof(gcry_mpi_t) * count);
589 for (i = 0; i < count; i++)
590 GNUNET_assert (NULL != (rand[i] = gcry_mpi_new (0)));
591 r = GNUNET_malloc (sizeof(struct GNUNET_CRYPTO_PaillierCiphertext) * count);
592 r_prime = GNUNET_malloc (sizeof(struct GNUNET_CRYPTO_PaillierCiphertext)
593 * count);
594
595 for (i = 0; i < count; i++)
596 {
597 int32_t svalue;
598
600 UINT32_MAX);
601 // long to gcry_mpi_t
602 if (svalue < 0)
603 gcry_mpi_sub_ui (rand[i],
604 rand[i],
605 -svalue);
606 else
607 rand[i] = gcry_mpi_set_ui (rand[i], svalue);
608 }
609
610 tmp = gcry_mpi_new (0);
611 // encrypt the element
612 // for the sake of readability I decided to have dedicated permutation
613 // vectors, which get rid of all the lookups in p/q.
614 // however, ap/aq are not absolutely necessary but are just abstraction
615 // Calculate Kp = E(S + a_pi) (+) E(S - r_pi - b_pi)
616 for (i = 0; i < count; i++)
617 {
618 // E(S - r_pi - b_pi)
619 gcry_mpi_sub (tmp, my_offset, rand[p[i]]);
620 gcry_mpi_sub (tmp, tmp, b[p[i]].value);
621 GNUNET_assert (2 ==
623 tmp,
624 2,
625 &r[i]));
626
627 // E(S - r_pi - b_pi) * E(S + a_pi) == E(2*S + a - r - b)
628 if (GNUNET_OK !=
630 &r[i],
631 &a[p[i]],
632 &r[i]))
633 {
634 GNUNET_break_op (0);
635 goto error_cleanup;
636 }
637 }
638
639 // Calculate Kq = E(S + a_qi) (+) E(S - r_qi)
640 for (i = 0; i < count; i++)
641 {
642 // E(S - r_qi)
643 gcry_mpi_sub (tmp, my_offset, rand[q[i]]);
644 GNUNET_assert (2 ==
646 tmp,
647 2,
648 &r_prime[i]));
649
650 // E(S - r_qi) * E(S + a_qi) == E(2*S + a_qi - r_qi)
651 if (GNUNET_OK !=
653 &r_prime[i],
654 &a[q[i]],
655 &r_prime[i]))
656 {
657 GNUNET_break_op (0);
658 goto error_cleanup;
659 }
660 }
661 gcry_mpi_release (tmp);
662
663 // Calculate S' = E(SUM( r_i^2 ))
664 tmp = compute_square_sum (rand, count);
665 GNUNET_assert (1 ==
667 tmp,
668 1,
669 &session->s_prime));
670 gcry_mpi_release (tmp);
671
672 // Calculate S = E(SUM( (r_i + b_i)^2 ))
673 for (i = 0; i < count; i++)
674 gcry_mpi_add (rand[i], rand[i], b[i].value);
675 tmp = compute_square_sum (rand, count);
676 GNUNET_assert (1 ==
678 tmp,
679 1,
680 &session->s));
681 gcry_mpi_release (tmp);
682
683 session->r = r;
684 session->r_prime = r_prime;
685
686 for (i = 0; i < count; i++)
687 gcry_mpi_release (rand[i]);
688 GNUNET_free (session->e_a);
689 session->e_a = NULL;
690 GNUNET_free (p);
691 GNUNET_free (q);
692 GNUNET_free (rand);
693 return GNUNET_OK;
694
695error_cleanup:
696 GNUNET_free (r);
697 GNUNET_free (r_prime);
698 gcry_mpi_release (tmp);
699 GNUNET_free (p);
700 GNUNET_free (q);
701 for (i = 0; i < count; i++)
702 gcry_mpi_release (rand[i]);
703 GNUNET_free (rand);
704 return GNUNET_SYSERR;
705}
706
707
717static int
718copy_element_cb (void *cls,
719 const struct GNUNET_HashCode *key,
720 void *value)
721{
722 struct BobServiceSession *s = cls;
724 gcry_mpi_t mval;
725 int64_t val;
726
727 mval = gcry_mpi_new (0);
728 val = (int64_t) GNUNET_ntohll (e->value);
729 if (0 > val)
730 gcry_mpi_sub_ui (mval, mval, -val);
731 else
732 gcry_mpi_add_ui (mval, mval, val);
736 return GNUNET_OK;
737}
738
739
748static int
749element_cmp (const void *a,
750 const void *b)
751{
752 const struct MpiElement *ma = a;
753 const struct MpiElement *mb = b;
754
755 return GNUNET_CRYPTO_hash_cmp (ma->key,
756 mb->key);
757}
758
759
767static void
769{
770 struct GNUNET_CADET_Channel *channel;
771
772 /* TODO: code duplication with Alice! */
774 "Received everything, building reply for Alice\n");
778 * sizeof(struct MpiElement));
779 s->used_element_count = 0;
782 s);
783 qsort (s->sorted_elements,
785 sizeof(struct MpiElement),
786 &element_cmp);
787 if (GNUNET_OK !=
789 {
790 channel = s->channel;
791 s->channel = NULL;
793 return;
794 }
796}
797
798
808static int
810 const struct AliceCryptodataMessage *msg)
811{
812 struct BobServiceSession *s = cls;
813 uint32_t contained_elements;
814 size_t msg_length;
815 uint16_t msize;
816 unsigned int max;
817
818 msize = ntohs (msg->header.size);
819 contained_elements = ntohl (msg->contained_element_count);
820 /* Our intersection may still be ongoing, but this is nevertheless
821 an upper bound on the required array size */
822 max = GNUNET_CONTAINER_multihashmap_size (s->intersected_elements);
823 msg_length = sizeof(struct AliceCryptodataMessage)
824 + contained_elements * sizeof(struct
826 if ((msize != msg_length) ||
827 (0 == contained_elements) ||
828 (contained_elements > UINT16_MAX) ||
829 (max < contained_elements + s->cadet_received_element_count))
830 {
831 GNUNET_break_op (0);
832 return GNUNET_SYSERR;
833 }
834 return GNUNET_OK;
835}
836
837
845static void
847 const struct AliceCryptodataMessage *msg)
848{
849 struct BobServiceSession *s = cls;
851 uint32_t contained_elements;
852 unsigned int max;
853
854 contained_elements = ntohl (msg->contained_element_count);
855 /* Our intersection may still be ongoing, but this is nevertheless
856 an upper bound on the required array size */
859 "Received %u crypto values from Alice\n",
860 (unsigned int) contained_elements);
861
862 payload = (const struct GNUNET_CRYPTO_PaillierCiphertext *) &msg[1];
863 if (NULL == s->e_a)
867 payload,
869 * contained_elements);
870 s->cadet_received_element_count += contained_elements;
871
872 if ((s->cadet_received_element_count == max) &&
873 (NULL == s->intersection_op))
874 {
875 /* intersection has finished also on our side, and
876 we got the full set, so we can proceed with the
877 CADET response(s) */
879 }
881}
882
883
893static void
895 const struct GNUNET_SETI_Element *element,
896 uint64_t current_size,
898{
899 struct BobServiceSession *s = cls;
901
902 switch (status)
903 {
905 /* this element has been removed from the set */
907 element->data);
908 GNUNET_assert (NULL != se);
910 "Removed element with key %s and value %lld\n",
911 GNUNET_h2s (&se->key),
912 (long long) GNUNET_ntohll (se->value));
916 element->data,
917 se));
918 GNUNET_free (se);
919 return;
921 s->intersection_op = NULL;
922 GNUNET_break (NULL == s->intersection_set);
925 "Finished intersection, %d items remain\n",
929 {
930 /* CADET transmission from Alice is also already done,
931 start with our own reply */
933 }
934 return;
936 /* unhandled status code */
938 "Set intersection failed!\n");
939 s->intersection_op = NULL;
940 if (NULL != s->intersection_set)
941 {
943 s->intersection_set = NULL;
944 }
947 return;
948 default:
949 GNUNET_break (0);
950 return;
951 }
952}
953
954
961static void
963{
965 "Got session with key %s and %u elements, starting intersection.\n",
967 (unsigned int) s->total);
968
971 &s->session_id,
972 NULL,
973 (struct GNUNET_SETI_Option[]) { { 0 } },
975 s);
976 if (GNUNET_OK !=
979 {
980 GNUNET_break (0);
983 return;
984 }
986 s->intersection_set = NULL;
987}
988
989
996static void
998 const struct ServiceRequestMessage *msg)
999{
1000 struct BobServiceSession *s = cls;
1001
1002 s->session_id = msg->session_id; // ??
1003 s->remote_pubkey = msg->public_key;
1004 if (s->client_received_element_count == s->total)
1006}
1007
1008
1019static void *
1020cb_channel_incoming (void *cls,
1022 const struct GNUNET_PeerIdentity *initiator)
1023{
1024 struct BobServiceSession *s = cls;
1025
1027 "New incoming channel from peer %s.\n",
1028 GNUNET_i2s (initiator));
1029 GNUNET_CADET_close_port (s->port);
1030 s->port = NULL;
1031 s->channel = channel;
1032 s->peer = *initiator;
1033 s->cadet_mq = GNUNET_CADET_get_mq (s->channel);
1034 return s;
1035}
1036
1037
1045static int
1047 const struct
1049 msg)
1050{
1051 struct BobServiceSession *s = cls;
1052 uint32_t contained_count;
1053 uint16_t msize;
1054
1055 msize = ntohs (msg->header.size);
1056 contained_count = ntohl (msg->element_count_contained);
1057 if ((msize != (sizeof(struct ComputationBobCryptodataMultipartMessage)
1058 + contained_count * sizeof(struct
1060 (0 == contained_count) ||
1061 (UINT16_MAX < contained_count) ||
1062 (s->total == s->client_received_element_count) ||
1063 (s->total < s->client_received_element_count + contained_count))
1064 {
1065 GNUNET_break (0);
1066 return GNUNET_SYSERR;
1067 }
1068 return GNUNET_OK;
1069}
1070
1071
1079static void
1081 const struct
1083 msg)
1084{
1085 struct BobServiceSession *s = cls;
1086 uint32_t contained_count;
1087 const struct GNUNET_SCALARPRODUCT_Element *elements;
1088 struct GNUNET_SETI_Element set_elem;
1089 struct GNUNET_SCALARPRODUCT_Element *elem;
1090
1091 contained_count = ntohl (msg->element_count_contained);
1092 elements = (const struct GNUNET_SCALARPRODUCT_Element *) &msg[1];
1093 for (uint32_t i = 0; i < contained_count; i++)
1094 {
1096 GNUNET_memcpy (elem,
1097 &elements[i],
1098 sizeof(struct GNUNET_SCALARPRODUCT_Element));
1099 if (GNUNET_SYSERR ==
1101 &elem->key,
1102 elem,
1104 {
1105 GNUNET_break (0);
1106 GNUNET_free (elem);
1107 continue;
1108 }
1109 set_elem.data = &elem->key;
1110 set_elem.size = sizeof(elem->key);
1111 set_elem.element_type = 0;
1113 &set_elem,
1114 NULL, NULL);
1115 }
1116 s->client_received_element_count += contained_count;
1119 {
1120 /* more to come */
1121 return;
1122 }
1123 if (NULL == s->channel)
1124 {
1125 /* no Alice waiting for this request, wait for Alice */
1126 return;
1127 }
1129}
1130
1131
1140static int
1141check_bob_client_message (void *cls,
1142 const struct BobComputationMessage *msg)
1143{
1144 struct BobServiceSession *s = cls;
1145 uint32_t contained_count;
1146 uint32_t total_count;
1147 uint16_t msize;
1148
1149 if (GNUNET_SCALARPRODUCT_STATUS_INIT != s->status)
1150 {
1151 GNUNET_break (0);
1152 return GNUNET_SYSERR;
1153 }
1154 msize = ntohs (msg->header.size);
1155 total_count = ntohl (msg->element_count_total);
1156 contained_count = ntohl (msg->element_count_contained);
1157 if ((0 == total_count) ||
1158 (0 == contained_count) ||
1159 (UINT16_MAX < contained_count) ||
1160 (msize != (sizeof(struct BobComputationMessage)
1161 + contained_count * sizeof(struct
1163 {
1164 GNUNET_break_op (0);
1165 return GNUNET_SYSERR;
1166 }
1167 return GNUNET_OK;
1168}
1169
1170
1179static void
1180handle_bob_client_message (void *cls,
1181 const struct BobComputationMessage *msg)
1182{
1183 struct BobServiceSession *s = cls;
1184 struct GNUNET_MQ_MessageHandler cadet_handlers[] = {
1185 GNUNET_MQ_hd_fixed_size (alices_computation_request,
1187 struct ServiceRequestMessage,
1188 NULL),
1189 GNUNET_MQ_hd_var_size (alices_cryptodata_message,
1192 NULL),
1194 };
1195 uint32_t contained_count;
1196 uint32_t total_count;
1197 const struct GNUNET_SCALARPRODUCT_Element *elements;
1198 struct GNUNET_SETI_Element set_elem;
1199 struct GNUNET_SCALARPRODUCT_Element *elem;
1200
1201 total_count = ntohl (msg->element_count_total);
1202 contained_count = ntohl (msg->element_count_contained);
1203
1205 s->total = total_count;
1206 s->client_received_element_count = contained_count;
1207 s->session_id = msg->session_key;
1208 elements = (const struct GNUNET_SCALARPRODUCT_Element *) &msg[1];
1211 GNUNET_YES);
1213 for (uint32_t i = 0; i < contained_count; i++)
1214 {
1215 if (0 == GNUNET_ntohll (elements[i].value))
1216 continue;
1218 GNUNET_memcpy (elem,
1219 &elements[i],
1220 sizeof(struct GNUNET_SCALARPRODUCT_Element));
1221 if (GNUNET_SYSERR ==
1223 &elem->key,
1224 elem,
1226 {
1227 GNUNET_break (0);
1228 GNUNET_free (elem);
1229 continue;
1230 }
1231 set_elem.data = &elem->key;
1232 set_elem.size = sizeof(elem->key);
1233 set_elem.element_type = 0;
1235 &set_elem,
1236 NULL, NULL);
1237 s->used_element_count++;
1238 }
1240 /* We're ready, open the port */
1242 &msg->session_key,
1244 s,
1245 NULL,
1247 cadet_handlers);
1248 if (NULL == s->port)
1249 {
1250 GNUNET_break (0);
1252 return;
1253 }
1254}
1255
1256
1262static void
1263shutdown_task (void *cls)
1264{
1266 "Shutting down, initiating cleanup.\n");
1267 // FIXME: we have to cut our connections to CADET first!
1268 if (NULL != my_cadet)
1269 {
1271 my_cadet = NULL;
1272 }
1273}
1274
1275
1286static void *
1287client_connect_cb (void *cls,
1288 struct GNUNET_SERVICE_Client *client,
1289 struct GNUNET_MQ_Handle *mq)
1290{
1291 struct BobServiceSession *s;
1292
1293 s = GNUNET_new (struct BobServiceSession);
1294 s->client = client;
1295 s->client_mq = mq;
1296 return s;
1297}
1298
1299
1310static void
1311client_disconnect_cb (void *cls,
1313 void *app_cls)
1314{
1315 struct BobServiceSession *s = app_cls;
1316
1318 "Client disconnected from us.\n");
1319 s->client = NULL;
1321}
1322
1323
1331static void
1332run (void *cls,
1333 const struct GNUNET_CONFIGURATION_Handle *c,
1335{
1336 cfg = c;
1337 /*
1338 offset has to be sufficiently small to allow computation of:
1339 m1+m2 mod n == (S + a) + (S + b) mod n,
1340 if we have more complex operations, this factor needs to be lowered */
1341 my_offset = gcry_mpi_new (GNUNET_CRYPTO_PAILLIER_BITS / 3);
1342 gcry_mpi_set_bit (my_offset,
1344
1346 &my_privkey);
1349 NULL);
1350 if (NULL == my_cadet)
1351 {
1353 _ ("Connect to CADET failed\n"));
1355 return;
1356 }
1357}
1358
1359
1365 "scalarproduct-bob",
1367 &run,
1370 NULL,
1371 GNUNET_MQ_hd_var_size (bob_client_message,
1373 struct BobComputationMessage,
1374 NULL),
1375 GNUNET_MQ_hd_var_size (bob_client_message_multipart,
1378 NULL),
1380
1381
1382/* end of gnunet-service-scalarproduct_bob.c */
struct GNUNET_MessageHeader * msg
Definition 005.c:2
struct GNUNET_HashCode key
The key used in the DHT.
struct GNUNET_SCHEDULER_Task * shutdown_task
static char * value
Value of the record to add/remove.
static int status
The program status; 0 for success.
Definition gnunet-nse.c:39
static struct GNUNET_REVOCATION_Query * q
Handle for revocation query.
static struct GNUNET_SERVICE_Handle * service
Handle to our service instance.
static unsigned long long payload
How much data are we currently storing in the database?
static void handle_bob_client_message_multipart(void *cls, const struct ComputationBobCryptodataMultipartMessage *msg)
We're receiving additional set data.
static void start_intersection(struct BobServiceSession *s)
We've paired up a client session with an incoming CADET request.
static void * cb_channel_incoming(void *cls, struct GNUNET_CADET_Channel *channel, const struct GNUNET_PeerIdentity *initiator)
Function called for inbound channels on Bob's end.
static struct GNUNET_CRYPTO_PaillierPrivateKey my_privkey
Service's own private key.
static void handle_alices_cryptodata_message(void *cls, const struct AliceCryptodataMessage *msg)
Handle a multipart-chunk of a request from another service to calculate a scalarproduct with us.
static struct GNUNET_CADET_Handle * my_cadet
Handle to the CADET service.
static const struct GNUNET_CONFIGURATION_Handle * cfg
GNUnet configuration handle.
static int check_bob_client_message_multipart(void *cls, const struct ComputationBobCryptodataMultipartMessage *msg)
We're receiving additional set data.
static void prepare_client_end_notification(struct BobServiceSession *session)
Notify the client that the session has succeeded or failed.
static void transmit_bobs_cryptodata_message(struct BobServiceSession *s)
Bob generates the response message to be sent to Alice after computing the values (1),...
static void client_disconnect_cb(void *cls, struct GNUNET_SERVICE_Client *client, void *app_cls)
A client disconnected.
#define ELEMENT_CAPACITY
Maximum count of elements we can put into a multipart message.
static int check_alices_cryptodata_message(void *cls, const struct AliceCryptodataMessage *msg)
Check a multipart-chunk of a request from another service to calculate a scalarproduct with us.
static void bob_cadet_done_cb(void *cls)
MQ finished giving our last message to CADET, now notify the client that we are finished.
static void * client_connect_cb(void *cls, struct GNUNET_SERVICE_Client *client, struct GNUNET_MQ_Handle *mq)
A client connected.
static void handle_alices_computation_request(void *cls, const struct ServiceRequestMessage *msg)
Handle a request from Alice to calculate a scalarproduct with us (Bob).
static void destroy_service_session(struct BobServiceSession *s)
Destroy session state, we are done with it.
static void handle_bob_client_message(void *cls, const struct BobComputationMessage *msg)
Handler for Bob's a client request message.
static void run(void *cls, const struct GNUNET_CONFIGURATION_Handle *c, struct GNUNET_SERVICE_Handle *service)
Initialization of the program and message handlers.
static int compute_service_response(struct BobServiceSession *session)
Compute the values (1)[]: $E_A(a_{pi(i)}) otimes E_A(- r_{pi(i)} - b_{pi(i)}) &= E_A(a_{pi(i)} - r_{p...
static int check_bob_client_message(void *cls, const struct BobComputationMessage *msg)
Handler for Bob's a client request message.
static void cb_channel_destruction(void *cls, const struct GNUNET_CADET_Channel *channel)
Function called whenever a channel is destroyed.
static int element_cmp(const void *a, const void *b)
Compare two struct MpiValues by key for sorting.
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.
#define LOG(kind,...)
static void transmit_cryptographic_reply(struct BobServiceSession *s)
Intersection operation and receiving data via CADET from Alice are both done, compute and transmit ou...
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.
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.
static struct GNUNET_CRYPTO_PaillierPublicKey my_pubkey
Service's own public key.
static gcry_mpi_t my_offset
Service's offset for values that could possibly be negative but are plaintext for encryption.
static void transmit_bobs_cryptodata_message_multipart(struct BobServiceSession *s)
Send a multipart chunk of a service response from Bob to Alice.
static struct GNUNET_OS_Process * p
Helper process we started.
Definition gnunet-uri.c:38
struct GNUNET_CADET_Handle * GNUNET_CADET_connect(const struct GNUNET_CONFIGURATION_Handle *cfg)
Connect to the MQ-based cadet service.
Definition cadet_api.c:897
void GNUNET_CADET_receive_done(struct GNUNET_CADET_Channel *channel)
Indicate readiness to receive the next message on a channel.
Definition cadet_api.c:875
void GNUNET_CADET_channel_destroy(struct GNUNET_CADET_Channel *channel)
Destroy an existing channel.
Definition cadet_api.c:833
struct GNUNET_MQ_Handle * GNUNET_CADET_get_mq(const struct GNUNET_CADET_Channel *channel)
Obtain the message queue for a connected channel.
Definition cadet_api.c:1081
struct GNUNET_CADET_Port * GNUNET_CADET_open_port(struct GNUNET_CADET_Handle *h, const struct GNUNET_HashCode *port, GNUNET_CADET_ConnectEventHandler connects, void *connects_cls, GNUNET_CADET_WindowSizeEventHandler window_changes, GNUNET_CADET_DisconnectEventHandler disconnects, const struct GNUNET_MQ_MessageHandler *handlers)
Open a port to receive incoming MQ-based channels.
Definition cadet_api.c:966
void GNUNET_CADET_disconnect(struct GNUNET_CADET_Handle *handle)
Disconnect from the cadet service.
Definition cadet_api.c:777
void GNUNET_CADET_close_port(struct GNUNET_CADET_Port *p)
Close a port opened with GNUNET_CADET_open_port.
Definition cadet_api.c:804
uint32_t GNUNET_CRYPTO_random_u32(enum GNUNET_CRYPTO_Quality mode, uint32_t i)
Produce a random value.
unsigned int * GNUNET_CRYPTO_random_permute(enum GNUNET_CRYPTO_Quality mode, unsigned int n)
Get an array with a random permutation of the numbers 0...n-1.
@ GNUNET_CRYPTO_QUALITY_WEAK
No good quality of the operation is needed (i.e., random numbers can be pseudo-random).
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.
int GNUNET_CONTAINER_multihashmap_iterate(struct GNUNET_CONTAINER_MultiHashMap *map, GNUNET_CONTAINER_MultiHashMapIteratorCallback it, void *it_cls)
Iterate over all entries in the map.
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.
enum GNUNET_GenericReturnValue 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.
enum GNUNET_GenericReturnValue 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.
unsigned int GNUNET_CONTAINER_multihashmap_size(const struct GNUNET_CONTAINER_MultiHashMap *map)
Get the number of key-value pairs in the map.
struct GNUNET_CONTAINER_MultiHashMap * GNUNET_CONTAINER_multihashmap_create(unsigned int len, int do_not_copy_keys)
Create a multi hash map.
@ GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY
There must only be one value per key; storing a value should fail if a value under the same key alrea...
#define GNUNET_log(kind,...)
#define GNUNET_CRYPTO_PAILLIER_BITS
Size of paillier plain texts and public keys.
uint64_t GNUNET_ntohll(uint64_t n)
Convert unsigned 64-bit integer to host byte order.
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.
void GNUNET_CRYPTO_paillier_create(struct GNUNET_CRYPTO_PaillierPublicKey *public_key, struct GNUNET_CRYPTO_PaillierPrivateKey *private_key)
Create a freshly generated paillier public key.
#define GNUNET_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
int GNUNET_CRYPTO_paillier_hom_add(const struct GNUNET_CRYPTO_PaillierPublicKey *public_key, const struct GNUNET_CRYPTO_PaillierCiphertext *c1, const struct GNUNET_CRYPTO_PaillierCiphertext *c2, struct GNUNET_CRYPTO_PaillierCiphertext *result)
Compute a ciphertext that represents the sum of the plaintext in c1 and c2.
uint16_t size
The length of the struct (in bytes, including the length field itself), in big-endian format.
@ GNUNET_OK
@ GNUNET_YES
@ GNUNET_SYSERR
#define GNUNET_break_op(cond)
Use this for assertion violations caused by other peers (i.e.
const char * GNUNET_i2s(const struct GNUNET_PeerIdentity *pid)
Convert a peer identity to a string (for printing debug messages).
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur.
const char * GNUNET_h2s(const struct GNUNET_HashCode *hc)
Convert a hash value to a string (for printing debug messages).
@ GNUNET_ERROR_TYPE_ERROR
@ GNUNET_ERROR_TYPE_DEBUG
#define GNUNET_new(type)
Allocate a struct or union of the given type.
#define GNUNET_malloc(size)
Wrapper around malloc.
#define GNUNET_new_array(n, type)
Allocate a size n array with structs or unions of the given type.
#define GNUNET_free(ptr)
Wrapper around free.
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:305
#define GNUNET_MQ_handler_end()
End-marker for the handlers array.
#define GNUNET_MQ_msg_extra(mvar, esize, type)
Allocate an envelope, with extra space allocated after the space needed by the message struct.
#define GNUNET_MQ_hd_var_size(name, code, str, ctx)
void GNUNET_MQ_notify_sent(struct GNUNET_MQ_Envelope *ev, GNUNET_SCHEDULER_TaskCallback cb, void *cb_cls)
Call a callback once the envelope has been sent, that is, sending it can not be canceled anymore.
Definition mq.c:655
#define GNUNET_MQ_hd_fixed_size(name, code, str, ctx)
const struct GNUNET_OS_ProjectData * GNUNET_OS_project_data_gnunet(void)
Return default project data used by 'libgnunetutil' for GNUnet.
#define GNUNET_MESSAGE_TYPE_SCALARPRODUCT_ALICE_CRYPTODATA
Alice -> Bob SP crypto-data (after intersection)
#define GNUNET_MESSAGE_TYPE_SCALARPRODUCT_BOB_CRYPTODATA
Bob -> Alice SP crypto-data.
#define GNUNET_MESSAGE_TYPE_SCALARPRODUCT_CLIENT_TO_BOB
Client -> Bob.
#define GNUNET_MESSAGE_TYPE_SCALARPRODUCT_CLIENT_MULTIPART_BOB
Client -> Bob multipart.
#define GNUNET_MESSAGE_TYPE_SCALARPRODUCT_SESSION_INITIALIZATION
Alice -> Bob session initialization.
#define GNUNET_MESSAGE_TYPE_SCALARPRODUCT_BOB_CRYPTODATA_MULTIPART
Bob -> Alice SP crypto-data multipart.
@ GNUNET_SCALARPRODUCT_STATUS_INIT
Operation is still active (never returned, used internally).
@ GNUNET_SCALARPRODUCT_STATUS_ACTIVE
Operation is still active (never returned, used internally).
@ GNUNET_SCALARPRODUCT_STATUS_FAILURE
We encountered some error.
void GNUNET_SCHEDULER_shutdown(void)
Request the shutdown of a scheduler.
Definition scheduler.c:567
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,...
Definition scheduler.c:1339
#define GNUNET_SERVICE_MAIN(pd, service_name, service_options, init_cb, connect_cb, disconnect_cb, cls,...)
Creates the "main" function for a GNUnet service.
void GNUNET_SERVICE_client_drop(struct GNUNET_SERVICE_Client *c)
Ask the server to disconnect from the given client.
Definition service.c:2462
void GNUNET_SERVICE_client_continue(struct GNUNET_SERVICE_Client *c)
Continue receiving further messages from the given client.
Definition service.c:2433
@ GNUNET_SERVICE_OPTION_NONE
Use defaults.
GNUNET_SETI_Status
Status for the result callback.
void GNUNET_SETI_destroy(struct GNUNET_SETI_Handle *set)
Destroy the set handle, and free all associated resources.
Definition seti_api.c:488
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
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:810
struct GNUNET_SETI_OperationHandle * GNUNET_SETI_prepare(const struct GNUNET_PeerIdentity *other_peer, const struct GNUNET_HashCode *app_id, const struct GNUNET_MessageHeader *context_msg, const struct GNUNET_SETI_Option options[], GNUNET_SETI_ResultIterator result_cb, void *result_cls)
Prepare a set operation to be evaluated with another peer.
Definition seti_api.c:513
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
@ GNUNET_SETI_STATUS_DONE
Success, all elements have been sent (and received).
@ GNUNET_SETI_STATUS_FAILURE
The other peer refused to do the operation with us, or something went wrong.
@ GNUNET_SETI_STATUS_DEL_LOCAL
Element should be delete from the result set of the local peer, i.e.
#define max(x, y)
#define _(String)
GNU gettext support macro.
Definition platform.h:179
static struct GNUNET_MQ_Handle * mq
Our connection to the resolver service, created on-demand, but then persists until error or shutdown.
Vector of Pallier-encrypted values sent by Alice to Bob (after set intersection).
Message type passed from client to service to initiate a request or responder role.
Message type passed from responding service Bob to responding service Alice to complete a request and...
A scalarproduct session which tracks an offer for a multiplication service by a local client.
struct GNUNET_HashCode session_id
(hopefully) unique transaction ID
struct MpiElement * sorted_elements
b(Bob)
struct GNUNET_CADET_Port * port
Our open port.
struct GNUNET_CADET_Channel * channel
The CADET channel.
struct GNUNET_CRYPTO_PaillierCiphertext * r_prime
Bob's permutation q of R.
struct GNUNET_CRYPTO_PaillierCiphertext s_prime
Bob's "s'".
uint32_t total
How many elements will be supplied in total from the client.
struct GNUNET_SETI_OperationHandle * intersection_op
Set of elements for which will conduction an intersection.
uint32_t cadet_received_element_count
Counts the number of values received from Alice by us.
struct GNUNET_CONTAINER_MultiHashMap * intersected_elements
All non-0-value'd elements transmitted to us.
uint32_t cadet_transmitted_element_count
Counts the number of values transmitted from us to Alice.
struct GNUNET_MQ_Handle * cadet_mq
The message queue for this channel.
struct GNUNET_SERVICE_Client * client
The client this request is related to.
uint32_t used_element_count
How many elements actually are used for the scalar product.
struct GNUNET_CRYPTO_PaillierCiphertext * e_a
E(ai)(Bob) after applying the mask.
struct GNUNET_CRYPTO_PaillierCiphertext s
Bob's "s".
struct GNUNET_CRYPTO_PaillierCiphertext * r
Bob's permutation p of R.
struct GNUNET_SETI_Handle * intersection_set
Set of elements for which we will be conducting an intersection.
struct GNUNET_CRYPTO_PaillierPublicKey remote_pubkey
Public key of the remote service.
enum GNUNET_SCALARPRODUCT_ResponseStatus status
State of this session.
struct GNUNET_PeerIdentity peer
Originator's peer identity.
uint32_t client_received_element_count
Already transferred elements (received) for multipart messages from client.
multipart messages following struct ComputationMessage
Opaque handle to a channel.
Definition cadet.h:116
A 512-bit hashcode.
Handle to a message queue.
Definition mq.c:87
Message handler for a specific message type.
The identity of the host (wraps the signing key of the peer).
An element key-value pair for scalarproduct.
struct GNUNET_HashCode key
Key used to identify matching pairs of values to multiply.
int64_t value
Value to multiply in scalar product, in NBO.
Handle to a client that is connected to a service.
Definition service.c:249
Handle to a service.
Definition service.c:116
Element stored in a set.
const void * data
Actual data of the element.
Option for set operations.
An encrypted element key-value pair.
const struct GNUNET_HashCode * key
Key used to identify matching pairs of values to multiply.
int64_t value
a_i value, not disclosed to Bob.
Message type passed from requesting service Alice to responding service Bob to initiate a request and...

Function Documentation

◆ free_element_cb()

static int free_element_cb ( void *  cls,
const struct GNUNET_HashCode key,
void *  value 
)
static

Callback used to free the elements in the map.

Parameters
clsNULL
keykey of the element
valuethe value to free

Definition at line 238 of file gnunet-service-scalarproduct_bob.c.

241{
242 struct GNUNET_SCALARPRODUCT_Element *element = value;
243
244 GNUNET_free (element);
245 return GNUNET_OK;
246}

References GNUNET_free, GNUNET_OK, and value.

Referenced by destroy_service_session().

Here is the caller graph for this function:

◆ destroy_service_session()

static void destroy_service_session ( struct BobServiceSession s)
static

Destroy session state, we are done with it.

Parameters
sessionthe session to free elements from

Definition at line 255 of file gnunet-service-scalarproduct_bob.c.

256{
257 unsigned int i;
258
259 if (GNUNET_YES == s->in_destroy)
260 return;
262 if (NULL != s->client)
263 {
264 struct GNUNET_SERVICE_Client *c = s->client;
265
266 s->client = NULL;
268 }
269 if (NULL != s->intersected_elements)
270 {
273 NULL);
275 s->intersected_elements = NULL;
276 }
277 if (NULL != s->intersection_op)
278 {
280 s->intersection_op = NULL;
281 }
282 if (NULL != s->intersection_set)
283 {
285 s->intersection_set = NULL;
286 }
287 if (NULL != s->e_a)
288 {
289 GNUNET_free (s->e_a);
290 s->e_a = NULL;
291 }
292 if (NULL != s->sorted_elements)
293 {
294 for (i = 0; i < s->used_element_count; i++)
295 gcry_mpi_release (s->sorted_elements[i].value);
297 s->sorted_elements = NULL;
298 }
299 if (NULL != s->r)
300 {
301 GNUNET_free (s->r);
302 s->r = NULL;
303 }
304 if (NULL != s->r_prime)
305 {
306 GNUNET_free (s->r_prime);
307 s->r_prime = NULL;
308 }
309 if (NULL != s->port)
310 {
312 s->port = NULL;
313 }
314 if (NULL != s->channel)
315 {
317 s->channel = NULL;
318 }
319 GNUNET_free (s);
320}
static int free_element_cb(void *cls, const struct GNUNET_HashCode *key, void *value)
Callback used to free the elements in the map.
void GNUNET_CONTAINER_multihashmap_destroy(struct GNUNET_CONTAINER_MultiHashMap *map)
Destroy a hash map.
void GNUNET_SETI_operation_cancel(struct GNUNET_SETI_OperationHandle *oh)
Cancel the given set operation.
Definition seti_api.c:335
int in_destroy
Are we already in destroy_service_session()?

References BobServiceSession::channel, BobServiceSession::client, BobServiceSession::e_a, free_element_cb(), GNUNET_CADET_channel_destroy(), GNUNET_CADET_close_port(), GNUNET_CONTAINER_multihashmap_destroy(), GNUNET_CONTAINER_multihashmap_iterate(), GNUNET_free, GNUNET_SERVICE_client_drop(), GNUNET_SETI_destroy(), GNUNET_SETI_operation_cancel(), GNUNET_YES, BobServiceSession::in_destroy, BobServiceSession::intersected_elements, BobServiceSession::intersection_op, BobServiceSession::intersection_set, BobServiceSession::port, BobServiceSession::r, BobServiceSession::r_prime, BobServiceSession::sorted_elements, BobServiceSession::used_element_count, and MpiElement::value.

Referenced by cb_channel_destruction(), and client_disconnect_cb().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ prepare_client_end_notification()

static void prepare_client_end_notification ( struct BobServiceSession session)
static

Notify the client that the session has succeeded or failed.

This message gets sent to Bob's client if the operation completed or Alice disconnected.

Parameters
sessionthe associated client session to fail or succeed

Definition at line 331 of file gnunet-service-scalarproduct_bob.c.

332{
334 struct GNUNET_MQ_Envelope *e;
335
336 if (NULL == session->client_mq)
337 return; /* no client left to be notified */
339 "Sending session-end notification with status %d to client for session %s\n",
340 session->status,
341 GNUNET_h2s (&session->session_id));
342 e = GNUNET_MQ_msg (msg,
344 msg->range = 0;
345 msg->product_length = htonl (0);
346 msg->status = htonl (session->status);
347 GNUNET_MQ_send (session->client_mq,
348 e);
349}
#define GNUNET_MQ_msg(mvar, type)
Allocate a GNUNET_MQ_Envelope.
#define GNUNET_MESSAGE_TYPE_SCALARPRODUCT_RESULT
Alice/Bob -> Client Result.
struct GNUNET_MQ_Handle * client_mq
Client message queue.
Message type passed from service client to finalize a session as requester or responder.

References BobServiceSession::client_mq, GNUNET_ERROR_TYPE_DEBUG, GNUNET_h2s(), GNUNET_log, GNUNET_MESSAGE_TYPE_SCALARPRODUCT_RESULT, GNUNET_MQ_msg, GNUNET_MQ_send(), msg, BobServiceSession::session_id, and BobServiceSession::status.

Referenced by bob_cadet_done_cb(), cb_channel_destruction(), and cb_intersection_element_removed().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ cb_channel_destruction()

static void cb_channel_destruction ( void *  cls,
const struct GNUNET_CADET_Channel channel 
)
static

Function called whenever a channel is destroyed.

Should clean up any associated state.

It must NOT call GNUNET_CADET_channel_destroy() on the channel.

Parameters
clsthe struct BobServiceSession
channelconnection to the other end (henceforth invalid)

Definition at line 362 of file gnunet-service-scalarproduct_bob.c.

364{
365 struct BobServiceSession *s = cls;
366
368 "Peer disconnected, terminating session %s with peer %s\n",
369 GNUNET_h2s (&s->session_id),
370 GNUNET_i2s (&s->peer));
372 {
375 }
376 s->channel = NULL;
378}

References destroy_service_session(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_h2s(), GNUNET_i2s(), GNUNET_log, GNUNET_SCALARPRODUCT_STATUS_ACTIVE, GNUNET_SCALARPRODUCT_STATUS_FAILURE, prepare_client_end_notification(), and BobServiceSession::s.

Referenced by handle_bob_client_message().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ bob_cadet_done_cb()

static void bob_cadet_done_cb ( void *  cls)
static

MQ finished giving our last message to CADET, now notify the client that we are finished.

Definition at line 386 of file gnunet-service-scalarproduct_bob.c.

387{
388 struct BobServiceSession *session = cls;
389
392}
@ GNUNET_SCALARPRODUCT_STATUS_SUCCESS
The computation was successful.

References GNUNET_SCALARPRODUCT_STATUS_SUCCESS, prepare_client_end_notification(), and BobServiceSession::status.

Referenced by transmit_bobs_cryptodata_message(), and transmit_bobs_cryptodata_message_multipart().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ transmit_bobs_cryptodata_message_multipart()

static void transmit_bobs_cryptodata_message_multipart ( struct BobServiceSession s)
static

Send a multipart chunk of a service response from Bob to Alice.

This element only contains the two permutations of R, R'.

Parameters
sthe associated service session

Definition at line 411 of file gnunet-service-scalarproduct_bob.c.

412{
415 struct GNUNET_MQ_Envelope *e;
416 unsigned int i;
417 unsigned int j;
418 uint32_t todo_count;
419
421 {
423 if (todo_count > ELEMENT_CAPACITY / 2)
424 todo_count = ELEMENT_CAPACITY / 2;
425
427 "Sending %u additional crypto values to Alice\n",
428 (unsigned int) todo_count);
430 todo_count * sizeof(struct
432 * 2,
434 msg->contained_element_count = htonl (todo_count);
436 for (i = s->cadet_transmitted_element_count, j = 0; i <
437 s->cadet_transmitted_element_count + todo_count; i++)
438 {
439 // r[i][p] and r[i][q]
440 GNUNET_memcpy (&payload[j++],
441 &s->r[i],
442 sizeof(struct GNUNET_CRYPTO_PaillierCiphertext));
443 GNUNET_memcpy (&payload[j++],
444 &s->r_prime[i],
445 sizeof(struct GNUNET_CRYPTO_PaillierCiphertext));
446 }
447 s->cadet_transmitted_element_count += todo_count;
451 s);
453 e);
454 }
456 "All values queued for Alice, Bob is done\n");
457}

References bob_cadet_done_cb(), BobServiceSession::cadet_mq, BobServiceSession::cadet_transmitted_element_count, ELEMENT_CAPACITY, GNUNET_ERROR_TYPE_DEBUG, GNUNET_log, GNUNET_memcpy, GNUNET_MESSAGE_TYPE_SCALARPRODUCT_BOB_CRYPTODATA_MULTIPART, GNUNET_MQ_msg_extra, GNUNET_MQ_notify_sent(), GNUNET_MQ_send(), msg, payload, BobServiceSession::r, BobServiceSession::r_prime, and BobServiceSession::used_element_count.

Referenced by transmit_bobs_cryptodata_message().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ transmit_bobs_cryptodata_message()

static void transmit_bobs_cryptodata_message ( struct BobServiceSession s)
static

Bob generates the response message to be sent to Alice after computing the values (1), (2), S and S'.

(1)[]: $E_A(a_{pi(i)}) times E_A(- r_{pi(i)} - b_{pi(i)}) &= E_A(a_{pi(i)} - r_{pi(i)} - b_{pi(i)})$ (2)[]: $E_A(a_{pi'(i)}) times E_A(- r_{pi'(i)}) &= E_A(a_{pi'(i)} - r_{pi'(i)})$ S: $S := E_A(sum (r_i + b_i)^2)$ S': $S' := E_A(sum r_i^2)$

Parameters
sthe associated requesting session with Alice

Definition at line 472 of file gnunet-service-scalarproduct_bob.c.

473{
475 struct GNUNET_MQ_Envelope *e;
477 unsigned int i;
478
480 = ((GNUNET_CONSTANTS_MAX_CADET_MESSAGE_SIZE - 1 - sizeof(struct
482 / sizeof(struct GNUNET_CRYPTO_PaillierCiphertext) / 2) - 1;
485
488 * sizeof(struct GNUNET_CRYPTO_PaillierCiphertext),
490 msg->contained_element_count = htonl (s->cadet_transmitted_element_count);
491
493 "Sending %u/%u crypto values to Alice\n",
494 (unsigned int) s->cadet_transmitted_element_count,
495 (unsigned int) s->used_element_count);
496
499 &s->s,
500 sizeof(struct GNUNET_CRYPTO_PaillierCiphertext));
502 &s->s_prime,
503 sizeof(struct GNUNET_CRYPTO_PaillierCiphertext));
504
505 payload = &payload[2];
506 // convert k[][]
507 for (i = 0; i < s->cadet_transmitted_element_count; i++)
508 {
509 // k[i][p] and k[i][q]
510 GNUNET_memcpy (&payload[i * 2],
511 &s->r[i],
512 sizeof(struct GNUNET_CRYPTO_PaillierCiphertext));
513 GNUNET_memcpy (&payload[i * 2 + 1],
514 &s->r_prime[i],
515 sizeof(struct GNUNET_CRYPTO_PaillierCiphertext));
516 }
520 s);
522 e);
524}

References bob_cadet_done_cb(), BobServiceSession::cadet_mq, BobServiceSession::cadet_transmitted_element_count, GNUNET_CONSTANTS_MAX_CADET_MESSAGE_SIZE, GNUNET_ERROR_TYPE_DEBUG, GNUNET_log, GNUNET_memcpy, GNUNET_MESSAGE_TYPE_SCALARPRODUCT_BOB_CRYPTODATA, GNUNET_MQ_msg_extra, GNUNET_MQ_notify_sent(), GNUNET_MQ_send(), msg, payload, BobServiceSession::r, BobServiceSession::r_prime, BobServiceSession::s, BobServiceSession::s_prime, transmit_bobs_cryptodata_message_multipart(), and BobServiceSession::used_element_count.

Referenced by transmit_cryptographic_reply().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ compute_square_sum()

static gcry_mpi_t compute_square_sum ( const gcry_mpi_t *  vector,
uint32_t  length 
)
static

Computes the square sum over a vector of a given length.

Parameters
vectorthe vector to compute over
lengththe length of the vector
Returns
an MPI value containing the calculated sum, never NULL TODO: code duplication with Alice!

Definition at line 539 of file gnunet-service-scalarproduct_bob.c.

541{
542 gcry_mpi_t elem;
543 gcry_mpi_t sum;
544 uint32_t i;
545
546 GNUNET_assert (NULL != (sum = gcry_mpi_new (0)));
547 GNUNET_assert (NULL != (elem = gcry_mpi_new (0)));
548 for (i = 0; i < length; i++)
549 {
550 gcry_mpi_mul (elem, vector[i], vector[i]);
551 gcry_mpi_add (sum, sum, elem);
552 }
553 gcry_mpi_release (elem);
554 return sum;
555}

References GNUNET_assert.

Referenced by compute_service_response().

Here is the caller graph for this function:

◆ compute_service_response()

static int compute_service_response ( struct BobServiceSession session)
static

Compute the values (1)[]: $E_A(a_{pi(i)}) otimes E_A(- r_{pi(i)} - b_{pi(i)}) &= E_A(a_{pi(i)} - r_{pi(i)} - b_{pi(i)})$ (2)[]: $E_A(a_{pi'(i)}) otimes E_A(- r_{pi'(i)}) &= E_A(a_{pi'(i)} - r_{pi'(i)})$ S: $S := E_A(sum (r_i + b_i)^2)$ S': $S' := E_A(sum r_i^2)$.

Parameters
sessionthe requesting session + bob's requesting peer
Returns
GNUNET_OK on success

Definition at line 569 of file gnunet-service-scalarproduct_bob.c.

570{
571 uint32_t i;
572 unsigned int *p;
573 unsigned int *q;
574 uint32_t count;
575 gcry_mpi_t *rand;
576 gcry_mpi_t tmp;
577 const struct MpiElement *b;
580 struct GNUNET_CRYPTO_PaillierCiphertext *r_prime;
581
582 count = session->used_element_count;
583 a = session->e_a;
584 b = session->sorted_elements;
586 count);
588 count);
589 rand = GNUNET_malloc (sizeof(gcry_mpi_t) * count);
590 for (i = 0; i < count; i++)
591 GNUNET_assert (NULL != (rand[i] = gcry_mpi_new (0)));
592 r = GNUNET_malloc (sizeof(struct GNUNET_CRYPTO_PaillierCiphertext) * count);
593 r_prime = GNUNET_malloc (sizeof(struct GNUNET_CRYPTO_PaillierCiphertext)
594 * count);
595
596 for (i = 0; i < count; i++)
597 {
598 int32_t svalue;
599
601 UINT32_MAX);
602 // long to gcry_mpi_t
603 if (svalue < 0)
604 gcry_mpi_sub_ui (rand[i],
605 rand[i],
606 -svalue);
607 else
608 rand[i] = gcry_mpi_set_ui (rand[i], svalue);
609 }
610
611 tmp = gcry_mpi_new (0);
612 // encrypt the element
613 // for the sake of readability I decided to have dedicated permutation
614 // vectors, which get rid of all the lookups in p/q.
615 // however, ap/aq are not absolutely necessary but are just abstraction
616 // Calculate Kp = E(S + a_pi) (+) E(S - r_pi - b_pi)
617 for (i = 0; i < count; i++)
618 {
619 // E(S - r_pi - b_pi)
620 gcry_mpi_sub (tmp, my_offset, rand[p[i]]);
621 gcry_mpi_sub (tmp, tmp, b[p[i]].value);
622 GNUNET_assert (2 ==
624 tmp,
625 2,
626 &r[i]));
627
628 // E(S - r_pi - b_pi) * E(S + a_pi) == E(2*S + a - r - b)
629 if (GNUNET_OK !=
631 &r[i],
632 &a[p[i]],
633 &r[i]))
634 {
635 GNUNET_break_op (0);
636 goto error_cleanup;
637 }
638 }
639
640 // Calculate Kq = E(S + a_qi) (+) E(S - r_qi)
641 for (i = 0; i < count; i++)
642 {
643 // E(S - r_qi)
644 gcry_mpi_sub (tmp, my_offset, rand[q[i]]);
645 GNUNET_assert (2 ==
647 tmp,
648 2,
649 &r_prime[i]));
650
651 // E(S - r_qi) * E(S + a_qi) == E(2*S + a_qi - r_qi)
652 if (GNUNET_OK !=
654 &r_prime[i],
655 &a[q[i]],
656 &r_prime[i]))
657 {
658 GNUNET_break_op (0);
659 goto error_cleanup;
660 }
661 }
662 gcry_mpi_release (tmp);
663
664 // Calculate S' = E(SUM( r_i^2 ))
665 tmp = compute_square_sum (rand, count);
666 GNUNET_assert (1 ==
668 tmp,
669 1,
670 &session->s_prime));
671 gcry_mpi_release (tmp);
672
673 // Calculate S = E(SUM( (r_i + b_i)^2 ))
674 for (i = 0; i < count; i++)
675 gcry_mpi_add (rand[i], rand[i], b[i].value);
676 tmp = compute_square_sum (rand, count);
677 GNUNET_assert (1 ==
679 tmp,
680 1,
681 &session->s));
682 gcry_mpi_release (tmp);
683
684 session->r = r;
685 session->r_prime = r_prime;
686
687 for (i = 0; i < count; i++)
688 gcry_mpi_release (rand[i]);
689 GNUNET_free (session->e_a);
690 session->e_a = NULL;
691 GNUNET_free (p);
692 GNUNET_free (q);
693 GNUNET_free (rand);
694 return GNUNET_OK;
695
696error_cleanup:
697 GNUNET_free (r);
698 GNUNET_free (r_prime);
699 gcry_mpi_release (tmp);
700 GNUNET_free (p);
701 GNUNET_free (q);
702 for (i = 0; i < count; i++)
703 gcry_mpi_release (rand[i]);
704 GNUNET_free (rand);
705 return GNUNET_SYSERR;
706}

References compute_square_sum(), BobServiceSession::e_a, GNUNET_assert, GNUNET_break_op, GNUNET_CRYPTO_paillier_encrypt(), GNUNET_CRYPTO_paillier_hom_add(), GNUNET_CRYPTO_QUALITY_WEAK, GNUNET_CRYPTO_random_permute(), GNUNET_CRYPTO_random_u32(), GNUNET_free, GNUNET_malloc, GNUNET_OK, GNUNET_SYSERR, my_offset, p, q, BobServiceSession::r, BobServiceSession::r_prime, BobServiceSession::remote_pubkey, BobServiceSession::s, BobServiceSession::s_prime, BobServiceSession::sorted_elements, BobServiceSession::used_element_count, and value.

Referenced by transmit_cryptographic_reply().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ copy_element_cb()

static int copy_element_cb ( void *  cls,
const struct GNUNET_HashCode key,
void *  value 
)
static

Iterator to copy over messages from the hash map into an array for sorting.

Parameters
clsthe struct BobServiceSession *
keythe key (unused)
valuethe struct GNUNET_SCALARPRODUCT_Element * TODO: code duplication with Alice!

Definition at line 719 of file gnunet-service-scalarproduct_bob.c.

722{
723 struct BobServiceSession *s = cls;
725 gcry_mpi_t mval;
726 int64_t val;
727
728 mval = gcry_mpi_new (0);
729 val = (int64_t) GNUNET_ntohll (e->value);
730 if (0 > val)
731 gcry_mpi_sub_ui (mval, mval, -val);
732 else
733 gcry_mpi_add_ui (mval, mval, val);
737 return GNUNET_OK;
738}

References GNUNET_ntohll(), GNUNET_OK, MpiElement::key, GNUNET_SCALARPRODUCT_Element::key, BobServiceSession::s, BobServiceSession::sorted_elements, BobServiceSession::used_element_count, value, MpiElement::value, and GNUNET_SCALARPRODUCT_Element::value.

Referenced by transmit_cryptographic_reply().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ element_cmp()

static int element_cmp ( const void *  a,
const void *  b 
)
static

Compare two struct MpiValues by key for sorting.

Parameters
apointer to first struct MpiValue *
bpointer to first struct MpiValue *
Returns
-1 for a < b, 0 for a=b, 1 for a > b. TODO: code duplication with Alice!

Definition at line 750 of file gnunet-service-scalarproduct_bob.c.

752{
753 const struct MpiElement *ma = a;
754 const struct MpiElement *mb = b;
755
756 return GNUNET_CRYPTO_hash_cmp (ma->key,
757 mb->key);
758}

References GNUNET_CRYPTO_hash_cmp(), and MpiElement::key.

Referenced by transmit_cryptographic_reply().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ transmit_cryptographic_reply()

static void transmit_cryptographic_reply ( struct BobServiceSession s)
static

Intersection operation and receiving data via CADET from Alice are both done, compute and transmit our reply via CADET.

Parameters
ssession to transmit reply for.

Definition at line 769 of file gnunet-service-scalarproduct_bob.c.

770{
771 struct GNUNET_CADET_Channel *channel;
772
773 /* TODO: code duplication with Alice! */
775 "Received everything, building reply for Alice\n");
779 * sizeof(struct MpiElement));
780 s->used_element_count = 0;
783 s);
784 qsort (s->sorted_elements,
786 sizeof(struct MpiElement),
787 &element_cmp);
788 if (GNUNET_OK !=
790 {
791 channel = s->channel;
792 s->channel = NULL;
794 return;
795 }
797}

References BobServiceSession::channel, compute_service_response(), copy_element_cb(), element_cmp(), GNUNET_CADET_channel_destroy(), GNUNET_CONTAINER_multihashmap_iterate(), GNUNET_CONTAINER_multihashmap_size(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_malloc, GNUNET_OK, BobServiceSession::intersected_elements, LOG, BobServiceSession::sorted_elements, transmit_bobs_cryptodata_message(), and BobServiceSession::used_element_count.

Referenced by cb_intersection_element_removed(), and handle_alices_cryptodata_message().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ check_alices_cryptodata_message()

static int check_alices_cryptodata_message ( void *  cls,
const struct AliceCryptodataMessage msg 
)
static

Check a multipart-chunk of a request from another service to calculate a scalarproduct with us.

Parameters
clsthe struct BobServiceSession *
msgthe actual message
Returns
GNUNET_OK to keep the connection open, GNUNET_SYSERR to close it (signal serious error)

Definition at line 810 of file gnunet-service-scalarproduct_bob.c.

812{
813 struct BobServiceSession *s = cls;
814 uint32_t contained_elements;
815 size_t msg_length;
816 uint16_t msize;
817 unsigned int max;
818
819 msize = ntohs (msg->header.size);
820 contained_elements = ntohl (msg->contained_element_count);
821 /* Our intersection may still be ongoing, but this is nevertheless
822 an upper bound on the required array size */
823 max = GNUNET_CONTAINER_multihashmap_size (s->intersected_elements);
824 msg_length = sizeof(struct AliceCryptodataMessage)
825 + contained_elements * sizeof(struct
827 if ((msize != msg_length) ||
828 (0 == contained_elements) ||
829 (contained_elements > UINT16_MAX) ||
830 (max < contained_elements + s->cadet_received_element_count))
831 {
832 GNUNET_break_op (0);
833 return GNUNET_SYSERR;
834 }
835 return GNUNET_OK;
836}

References BobServiceSession::cadet_received_element_count, GNUNET_break_op, GNUNET_CONTAINER_multihashmap_size(), GNUNET_OK, GNUNET_SYSERR, max, msg, BobServiceSession::s, and GNUNET_MessageHeader::size.

Here is the call graph for this function:

◆ handle_alices_cryptodata_message()

static void handle_alices_cryptodata_message ( void *  cls,
const struct AliceCryptodataMessage msg 
)
static

Handle a multipart-chunk of a request from another service to calculate a scalarproduct with us.

Parameters
clsthe struct BobServiceSession *
msgthe actual message

Definition at line 847 of file gnunet-service-scalarproduct_bob.c.

849{
850 struct BobServiceSession *s = cls;
852 uint32_t contained_elements;
853 unsigned int max;
854
855 contained_elements = ntohl (msg->contained_element_count);
856 /* Our intersection may still be ongoing, but this is nevertheless
857 an upper bound on the required array size */
860 "Received %u crypto values from Alice\n",
861 (unsigned int) contained_elements);
862
863 payload = (const struct GNUNET_CRYPTO_PaillierCiphertext *) &msg[1];
864 if (NULL == s->e_a)
868 payload,
870 * contained_elements);
871 s->cadet_received_element_count += contained_elements;
872
873 if ((s->cadet_received_element_count == max) &&
874 (NULL == s->intersection_op))
875 {
876 /* intersection has finished also on our side, and
877 we got the full set, so we can proceed with the
878 CADET response(s) */
880 }
882}

References BobServiceSession::cadet_received_element_count, BobServiceSession::channel, BobServiceSession::e_a, GNUNET_CADET_receive_done(), GNUNET_CONTAINER_multihashmap_size(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_log, GNUNET_memcpy, GNUNET_new_array, BobServiceSession::intersected_elements, BobServiceSession::intersection_op, max, msg, payload, BobServiceSession::s, and transmit_cryptographic_reply().

Here is the call graph for this function:

◆ cb_intersection_element_removed()

static void cb_intersection_element_removed ( void *  cls,
const struct GNUNET_SETI_Element element,
uint64_t  current_size,
enum GNUNET_SETI_Status  status 
)
static

Callback for set operation results.

Called for each element that needs to be removed from the result set.

Parameters
clsclosure with the struct BobServiceSession
elementa result element, only valid if status is #GNUNET_SETI_STATUS_OK
current_sizecurrent set size
statuswhat has happened with the set intersection?

Definition at line 895 of file gnunet-service-scalarproduct_bob.c.

899{
900 struct BobServiceSession *s = cls;
902
903 switch (status)
904 {
906 /* this element has been removed from the set */
908 element->data);
909 GNUNET_assert (NULL != se);
911 "Removed element with key %s and value %lld\n",
912 GNUNET_h2s (&se->key),
913 (long long) GNUNET_ntohll (se->value));
917 element->data,
918 se));
919 GNUNET_free (se);
920 return;
922 s->intersection_op = NULL;
923 GNUNET_break (NULL == s->intersection_set);
926 "Finished intersection, %d items remain\n",
930 {
931 /* CADET transmission from Alice is also already done,
932 start with our own reply */
934 }
935 return;
937 /* unhandled status code */
939 "Set intersection failed!\n");
940 s->intersection_op = NULL;
941 if (NULL != s->intersection_set)
942 {
944 s->intersection_set = NULL;
945 }
948 return;
949 default:
950 GNUNET_break (0);
951 return;
952 }
953}

References BobServiceSession::channel, BobServiceSession::client_received_element_count, GNUNET_SETI_Element::data, GNUNET_assert, GNUNET_break, GNUNET_CADET_receive_done(), GNUNET_CONTAINER_multihashmap_get(), GNUNET_CONTAINER_multihashmap_remove(), GNUNET_CONTAINER_multihashmap_size(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_free, GNUNET_h2s(), GNUNET_ntohll(), GNUNET_SCALARPRODUCT_STATUS_FAILURE, GNUNET_SETI_destroy(), GNUNET_SETI_STATUS_DEL_LOCAL, GNUNET_SETI_STATUS_DONE, GNUNET_SETI_STATUS_FAILURE, GNUNET_YES, BobServiceSession::intersected_elements, BobServiceSession::intersection_op, BobServiceSession::intersection_set, GNUNET_SCALARPRODUCT_Element::key, LOG, prepare_client_end_notification(), BobServiceSession::s, status, BobServiceSession::status, transmit_cryptographic_reply(), and GNUNET_SCALARPRODUCT_Element::value.

Here is the call graph for this function:

◆ start_intersection()

static void start_intersection ( struct BobServiceSession s)
static

We've paired up a client session with an incoming CADET request.

Initiate set intersection work.

Parameters
sclient session to start intersection for

Definition at line 963 of file gnunet-service-scalarproduct_bob.c.

964{
966 "Got session with key %s and %u elements, starting intersection.\n",
968 (unsigned int) s->total);
969
972 &s->session_id,
973 NULL,
974 (struct GNUNET_SETI_Option[]) { { 0 } },
976 s);
977 if (GNUNET_OK !=
980 {
981 GNUNET_break (0);
984 return;
985 }
987 s->intersection_set = NULL;
988}

References GNUNET_ERROR_TYPE_DEBUG, GNUNET_h2s(), GNUNET_log, GNUNET_SETI_prepare(), BobServiceSession::intersection_op, BobServiceSession::peer, BobServiceSession::session_id, and BobServiceSession::total.

Referenced by handle_alices_computation_request(), and handle_bob_client_message_multipart().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ handle_alices_computation_request()

static void handle_alices_computation_request ( void *  cls,
const struct ServiceRequestMessage msg 
)
static

Handle a request from Alice to calculate a scalarproduct with us (Bob).

Parameters
clsthe struct BobServiceSession *
msgthe actual message

Definition at line 998 of file gnunet-service-scalarproduct_bob.c.

1000{
1001 struct BobServiceSession *s = cls;
1002
1003 s->session_id = msg->session_id; // ??
1004 s->remote_pubkey = msg->public_key;
1005 if (s->client_received_element_count == s->total)
1007}

References msg, BobServiceSession::s, and start_intersection().

Here is the call graph for this function:

◆ cb_channel_incoming()

static void * cb_channel_incoming ( void *  cls,
struct GNUNET_CADET_Channel channel,
const struct GNUNET_PeerIdentity initiator 
)
static

Function called for inbound channels on Bob's end.

Does some preliminary initialization, more happens after we get Alice's first message.

Parameters
clsclosure with the struct BobServiceSession
channelnew handle to the channel
initiatorpeer that started the channel
Returns
session associated with the channel

Definition at line 1021 of file gnunet-service-scalarproduct_bob.c.

1024{
1025 struct BobServiceSession *s = cls;
1026
1028 "New incoming channel from peer %s.\n",
1029 GNUNET_i2s (initiator));
1030 GNUNET_CADET_close_port (s->port);
1031 s->port = NULL;
1032 s->channel = channel;
1033 s->peer = *initiator;
1034 s->cadet_mq = GNUNET_CADET_get_mq (s->channel);
1035 return s;
1036}

References BobServiceSession::channel, GNUNET_CADET_close_port(), GNUNET_CADET_get_mq(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_i2s(), GNUNET_log, and BobServiceSession::s.

Referenced by handle_bob_client_message().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ check_bob_client_message_multipart()

static int check_bob_client_message_multipart ( void *  cls,
const struct ComputationBobCryptodataMultipartMessage msg 
)
static

We're receiving additional set data.

Check it is well-formed.

Parameters
clsidentification of the client
msgthe actual message
Returns
GNUNET_OK if msg is well-formed

Definition at line 1047 of file gnunet-service-scalarproduct_bob.c.

1051{
1052 struct BobServiceSession *s = cls;
1053 uint32_t contained_count;
1054 uint16_t msize;
1055
1056 msize = ntohs (msg->header.size);
1057 contained_count = ntohl (msg->element_count_contained);
1058 if ((msize != (sizeof(struct ComputationBobCryptodataMultipartMessage)
1059 + contained_count * sizeof(struct
1061 (0 == contained_count) ||
1062 (UINT16_MAX < contained_count) ||
1063 (s->total == s->client_received_element_count) ||
1064 (s->total < s->client_received_element_count + contained_count))
1065 {
1066 GNUNET_break (0);
1067 return GNUNET_SYSERR;
1068 }
1069 return GNUNET_OK;
1070}

References GNUNET_break, GNUNET_OK, GNUNET_SYSERR, msg, BobServiceSession::s, and GNUNET_MessageHeader::size.

◆ handle_bob_client_message_multipart()

static void handle_bob_client_message_multipart ( void *  cls,
const struct ComputationBobCryptodataMultipartMessage msg 
)
static

We're receiving additional set data.

Add it to our set and if we are done, initiate the transaction.

Parameters
clsidentification of the client
msgthe actual message

Definition at line 1081 of file gnunet-service-scalarproduct_bob.c.

1085{
1086 struct BobServiceSession *s = cls;
1087 uint32_t contained_count;
1088 const struct GNUNET_SCALARPRODUCT_Element *elements;
1089 struct GNUNET_SETI_Element set_elem;
1090 struct GNUNET_SCALARPRODUCT_Element *elem;
1091
1092 contained_count = ntohl (msg->element_count_contained);
1093 elements = (const struct GNUNET_SCALARPRODUCT_Element *) &msg[1];
1094 for (uint32_t i = 0; i < contained_count; i++)
1095 {
1097 GNUNET_memcpy (elem,
1098 &elements[i],
1099 sizeof(struct GNUNET_SCALARPRODUCT_Element));
1100 if (GNUNET_SYSERR ==
1102 &elem->key,
1103 elem,
1105 {
1106 GNUNET_break (0);
1107 GNUNET_free (elem);
1108 continue;
1109 }
1110 set_elem.data = &elem->key;
1111 set_elem.size = sizeof(elem->key);
1112 set_elem.element_type = 0;
1114 &set_elem,
1115 NULL, NULL);
1116 }
1117 s->client_received_element_count += contained_count;
1120 {
1121 /* more to come */
1122 return;
1123 }
1124 if (NULL == s->channel)
1125 {
1126 /* no Alice waiting for this request, wait for Alice */
1127 return;
1128 }
1130}

References BobServiceSession::channel, BobServiceSession::client, BobServiceSession::client_received_element_count, GNUNET_SETI_Element::data, GNUNET_SETI_Element::element_type, GNUNET_break, GNUNET_CONTAINER_multihashmap_put(), GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY, GNUNET_free, GNUNET_memcpy, GNUNET_new, GNUNET_SERVICE_client_continue(), GNUNET_SETI_add_element(), GNUNET_SYSERR, BobServiceSession::intersected_elements, BobServiceSession::intersection_set, GNUNET_SCALARPRODUCT_Element::key, msg, BobServiceSession::s, GNUNET_SETI_Element::size, start_intersection(), and BobServiceSession::total.

Here is the call graph for this function:

◆ check_bob_client_message()

static int check_bob_client_message ( void *  cls,
const struct BobComputationMessage msg 
)
static

Handler for Bob's a client request message.

Check msg is well-formed.

Parameters
clsidentification of the client
msgthe actual message
Returns
GNUNET_OK if msg is well-formed

Definition at line 1142 of file gnunet-service-scalarproduct_bob.c.

1144{
1145 struct BobServiceSession *s = cls;
1146 uint32_t contained_count;
1147 uint32_t total_count;
1148 uint16_t msize;
1149
1150 if (GNUNET_SCALARPRODUCT_STATUS_INIT != s->status)
1151 {
1152 GNUNET_break (0);
1153 return GNUNET_SYSERR;
1154 }
1155 msize = ntohs (msg->header.size);
1156 total_count = ntohl (msg->element_count_total);
1157 contained_count = ntohl (msg->element_count_contained);
1158 if ((0 == total_count) ||
1159 (0 == contained_count) ||
1160 (UINT16_MAX < contained_count) ||
1161 (msize != (sizeof(struct BobComputationMessage)
1162 + contained_count * sizeof(struct
1164 {
1165 GNUNET_break_op (0);
1166 return GNUNET_SYSERR;
1167 }
1168 return GNUNET_OK;
1169}

References GNUNET_break, GNUNET_break_op, GNUNET_OK, GNUNET_SCALARPRODUCT_STATUS_INIT, GNUNET_SYSERR, msg, BobServiceSession::s, and GNUNET_MessageHeader::size.

◆ handle_bob_client_message()

static void handle_bob_client_message ( void *  cls,
const struct BobComputationMessage msg 
)
static

Handler for Bob's a client request message.

Bob is in the response role, keep the values + session and waiting for a matching session or process a waiting request from Alice.

Parameters
clsidentification of the client
msgthe actual message

Definition at line 1181 of file gnunet-service-scalarproduct_bob.c.

1183{
1184 struct BobServiceSession *s = cls;
1185 struct GNUNET_MQ_MessageHandler cadet_handlers[] = {
1186 GNUNET_MQ_hd_fixed_size (alices_computation_request,
1188 struct ServiceRequestMessage,
1189 NULL),
1190 GNUNET_MQ_hd_var_size (alices_cryptodata_message,
1193 NULL),
1195 };
1196 uint32_t contained_count;
1197 uint32_t total_count;
1198 const struct GNUNET_SCALARPRODUCT_Element *elements;
1199 struct GNUNET_SETI_Element set_elem;
1200 struct GNUNET_SCALARPRODUCT_Element *elem;
1201
1202 total_count = ntohl (msg->element_count_total);
1203 contained_count = ntohl (msg->element_count_contained);
1204
1206 s->total = total_count;
1207 s->client_received_element_count = contained_count;
1208 s->session_id = msg->session_key;
1209 elements = (const struct GNUNET_SCALARPRODUCT_Element *) &msg[1];
1212 GNUNET_YES);
1214 for (uint32_t i = 0; i < contained_count; i++)
1215 {
1216 if (0 == GNUNET_ntohll (elements[i].value))
1217 continue;
1219 GNUNET_memcpy (elem,
1220 &elements[i],
1221 sizeof(struct GNUNET_SCALARPRODUCT_Element));
1222 if (GNUNET_SYSERR ==
1224 &elem->key,
1225 elem,
1227 {
1228 GNUNET_break (0);
1229 GNUNET_free (elem);
1230 continue;
1231 }
1232 set_elem.data = &elem->key;
1233 set_elem.size = sizeof(elem->key);
1234 set_elem.element_type = 0;
1236 &set_elem,
1237 NULL, NULL);
1238 s->used_element_count++;
1239 }
1241 /* We're ready, open the port */
1243 &msg->session_key,
1245 s,
1246 NULL,
1248 cadet_handlers);
1249 if (NULL == s->port)
1250 {
1251 GNUNET_break (0);
1253 return;
1254 }
1255}

References cb_channel_destruction(), cb_channel_incoming(), cfg, BobServiceSession::client, BobServiceSession::client_received_element_count, GNUNET_SETI_Element::data, GNUNET_SETI_Element::element_type, GNUNET_break, GNUNET_CADET_open_port(), GNUNET_CONTAINER_multihashmap_create(), GNUNET_CONTAINER_multihashmap_put(), GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY, GNUNET_free, GNUNET_memcpy, GNUNET_MESSAGE_TYPE_SCALARPRODUCT_ALICE_CRYPTODATA, GNUNET_MESSAGE_TYPE_SCALARPRODUCT_SESSION_INITIALIZATION, GNUNET_MQ_handler_end, GNUNET_MQ_hd_fixed_size, GNUNET_MQ_hd_var_size, GNUNET_new, GNUNET_ntohll(), GNUNET_SCALARPRODUCT_STATUS_ACTIVE, GNUNET_SERVICE_client_continue(), GNUNET_SERVICE_client_drop(), GNUNET_SETI_add_element(), GNUNET_SETI_create(), GNUNET_SYSERR, GNUNET_YES, BobServiceSession::intersected_elements, BobServiceSession::intersection_set, GNUNET_SCALARPRODUCT_Element::key, msg, my_cadet, BobServiceSession::port, BobServiceSession::s, BobServiceSession::session_id, GNUNET_SETI_Element::size, BobServiceSession::status, BobServiceSession::total, BobServiceSession::used_element_count, and value.

Here is the call graph for this function:

◆ shutdown_task()

static void shutdown_task ( void *  cls)
static

Task run during shutdown.

Parameters
clsunused

Definition at line 1264 of file gnunet-service-scalarproduct_bob.c.

1265{
1267 "Shutting down, initiating cleanup.\n");
1268 // FIXME: we have to cut our connections to CADET first!
1269 if (NULL != my_cadet)
1270 {
1272 my_cadet = NULL;
1273 }
1274}

References GNUNET_CADET_disconnect(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_log, and my_cadet.

Here is the call graph for this function:

◆ client_connect_cb()

static void * client_connect_cb ( void *  cls,
struct GNUNET_SERVICE_Client client,
struct GNUNET_MQ_Handle mq 
)
static

A client connected.

Setup the associated data structure.

Parameters
clsclosure, NULL
clientidentification of the client
mqmessage queue to communicate with client
Returns
our struct BobServiceSession

Definition at line 1288 of file gnunet-service-scalarproduct_bob.c.

1291{
1292 struct BobServiceSession *s;
1293
1294 s = GNUNET_new (struct BobServiceSession);
1295 s->client = client;
1296 s->client_mq = mq;
1297 return s;
1298}

References BobServiceSession::client, GNUNET_new, mq, and BobServiceSession::s.

◆ client_disconnect_cb()

static void client_disconnect_cb ( void *  cls,
struct GNUNET_SERVICE_Client client,
void *  app_cls 
)
static

A client disconnected.

Remove the associated session(s), release data structures and cancel pending outgoing transmissions to the client.

Parameters
clsclosure, NULL
clientidentification of the client
app_clsour struct BobServiceSession

Definition at line 1312 of file gnunet-service-scalarproduct_bob.c.

1315{
1316 struct BobServiceSession *s = app_cls;
1317
1319 "Client disconnected from us.\n");
1320 s->client = NULL;
1322}

References destroy_service_session(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_log, and BobServiceSession::s.

Here is the call graph for this function:

◆ run()

static void run ( void *  cls,
const struct GNUNET_CONFIGURATION_Handle c,
struct GNUNET_SERVICE_Handle service 
)
static

Initialization of the program and message handlers.

Parameters
clsclosure
cconfiguration to use
servicethe initialized service

Definition at line 1333 of file gnunet-service-scalarproduct_bob.c.

1336{
1337 cfg = c;
1338 /*
1339 offset has to be sufficiently small to allow computation of:
1340 m1+m2 mod n == (S + a) + (S + b) mod n,
1341 if we have more complex operations, this factor needs to be lowered */
1342 my_offset = gcry_mpi_new (GNUNET_CRYPTO_PAILLIER_BITS / 3);
1343 gcry_mpi_set_bit (my_offset,
1345
1347 &my_privkey);
1350 NULL);
1351 if (NULL == my_cadet)
1352 {
1354 _ ("Connect to CADET failed\n"));
1356 return;
1357 }
1358}

References _, cfg, GNUNET_CADET_connect(), GNUNET_CRYPTO_PAILLIER_BITS, GNUNET_CRYPTO_paillier_create(), GNUNET_ERROR_TYPE_ERROR, GNUNET_log, GNUNET_SCHEDULER_add_shutdown(), GNUNET_SCHEDULER_shutdown(), my_cadet, my_offset, my_privkey, my_pubkey, and shutdown_task.

Here is the call graph for this function:

◆ GNUNET_SERVICE_MAIN()

GNUNET_SERVICE_MAIN ( GNUNET_OS_project_data_gnunet()  ,
"scalarproduct-bob"  ,
GNUNET_SERVICE_OPTION_NONE  ,
run,
client_connect_cb,
client_disconnect_cb,
NULL  ,
GNUNET_MQ_hd_var_size(bob_client_message, GNUNET_MESSAGE_TYPE_SCALARPRODUCT_CLIENT_TO_BOB, struct BobComputationMessage, NULL)  ,
GNUNET_MQ_hd_var_size(bob_client_message_multipart, GNUNET_MESSAGE_TYPE_SCALARPRODUCT_CLIENT_MULTIPART_BOB, struct ComputationBobCryptodataMultipartMessage, NULL)  ,
GNUNET_MQ_handler_end()   
)

Define "main" method using service macro.

Variable Documentation

◆ cfg

const struct GNUNET_CONFIGURATION_Handle* cfg
static

GNUnet configuration handle.

Definition at line 207 of file gnunet-service-scalarproduct_bob.c.

Referenced by handle_bob_client_message(), and run().

◆ my_pubkey

struct GNUNET_CRYPTO_PaillierPublicKey my_pubkey
static

Service's own public key.

Definition at line 212 of file gnunet-service-scalarproduct_bob.c.

Referenced by run().

◆ my_privkey

struct GNUNET_CRYPTO_PaillierPrivateKey my_privkey
static

Service's own private key.

Definition at line 217 of file gnunet-service-scalarproduct_bob.c.

Referenced by run().

◆ my_offset

gcry_mpi_t my_offset
static

Service's offset for values that could possibly be negative but are plaintext for encryption.

Definition at line 222 of file gnunet-service-scalarproduct_bob.c.

Referenced by compute_service_response(), and run().

◆ my_cadet

struct GNUNET_CADET_Handle* my_cadet
static

Handle to the CADET service.

Definition at line 227 of file gnunet-service-scalarproduct_bob.c.

Referenced by handle_bob_client_message(), run(), and shutdown_task().