GNUnet 0.21.1
gnunet-service-scalarproduct_alice.c File Reference

scalarproduct service implementation More...

#include "platform.h"
#include <limits.h>
#include <gcrypt.h>
#include "gnunet_util_lib.h"
#include "gnunet_core_service.h"
#include "gnunet_cadet_service.h"
#include "gnunet_applications.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_alice.c:

Go to the source code of this file.

Data Structures

struct  MpiElement
 An encrypted element key-value pair. More...
 
struct  AliceServiceSession
 A scalarproduct session which tracks a request form the client to our final response. More...
 

Macros

#define LOG(kind, ...)    GNUNET_log_from (kind, "scalarproduct-alice", __VA_ARGS__)
 
#define ELEMENT_CAPACITY
 Maximum number of elements we can put into a single cryptodata message. More...
 

Functions

static int free_element_cb (void *cls, const struct GNUNET_HashCode *key, void *value)
 Iterator called to free elements. More...
 
static void destroy_service_session (struct AliceServiceSession *s)
 Destroy session state, we are done with it. More...
 
static void prepare_client_end_notification (struct AliceServiceSession *session)
 Notify the client that the session has failed. More...
 
static void transmit_client_response (struct AliceServiceSession *s)
 Prepare the final (positive) response we will send to Alice's client. More...
 
static void cb_channel_destruction (void *cls, const struct GNUNET_CADET_Channel *channel)
 Function called whenever a channel is destroyed. More...
 
static gcry_mpi_t compute_square_sum_mpi_elements (const struct MpiElement *vector, uint32_t length)
 Computes the square sum over a vector of a given length. More...
 
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. More...
 
static gcry_mpi_t compute_scalar_product (struct AliceServiceSession *session)
 Compute our scalar product, done by Alice. More...
 
static int check_bobs_cryptodata_multipart (void *cls, const struct BobCryptodataMultipartMessage *msg)
 Check a multipart chunk of a response we got from another service we wanted to calculate a scalarproduct with. More...
 
static void handle_bobs_cryptodata_multipart (void *cls, const struct BobCryptodataMultipartMessage *msg)
 Handle a multipart chunk of a response we got from another service we wanted to calculate a scalarproduct with. More...
 
static int check_bobs_cryptodata_message (void *cls, const struct BobCryptodataMessage *msg)
 Check a response we got from another service we wanted to calculate a scalarproduct with. More...
 
static void handle_bobs_cryptodata_message (void *cls, const struct BobCryptodataMessage *msg)
 Handle a response we got from another service we wanted to calculate a scalarproduct with. More...
 
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. More...
 
static int element_cmp (const void *a, const void *b)
 Compare two struct MpiValues by key for sorting. More...
 
static void send_alices_cryptodata_message (struct AliceServiceSession *s)
 Send the cryptographic data from Alice to Bob. More...
 
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. More...
 
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. More...
 
static void client_request_complete_alice (struct AliceServiceSession *s)
 Our client has finished sending us its multipart message. More...
 
static int check_alice_client_message_multipart (void *cls, const struct ComputationBobCryptodataMultipartMessage *msg)
 We're receiving additional set data. More...
 
static void handle_alice_client_message_multipart (void *cls, const struct ComputationBobCryptodataMultipartMessage *msg)
 We're receiving additional set data. More...
 
static int check_alice_client_message (void *cls, const struct AliceComputationMessage *msg)
 Handler for Alice's client request message. More...
 
static void handle_alice_client_message (void *cls, const struct AliceComputationMessage *msg)
 Handler for Alice's client request message. More...
 
static void shutdown_task (void *cls)
 Task run during shutdown. More...
 
static void * client_connect_cb (void *cls, struct GNUNET_SERVICE_Client *client, struct GNUNET_MQ_Handle *mq)
 A client connected. More...
 
static void client_disconnect_cb (void *cls, struct GNUNET_SERVICE_Client *client, void *app_cls)
 A client disconnected. More...
 
static void run (void *cls, const struct GNUNET_CONFIGURATION_Handle *c, struct GNUNET_SERVICE_Handle *service)
 Initialization of the program and message handlers. More...
 
 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. More...
 

Variables

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

Detailed Description

scalarproduct service implementation

Author
Christian M. Fuchs
Christian Grothoff

Definition in file gnunet-service-scalarproduct_alice.c.

Macro Definition Documentation

◆ LOG

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

Definition at line 40 of file gnunet-service-scalarproduct_alice.c.

◆ ELEMENT_CAPACITY

#define ELEMENT_CAPACITY
Value:
- sizeof(struct AliceCryptodataMessage)) \
#define GNUNET_CONSTANTS_MAX_CADET_MESSAGE_SIZE
Maximum message size that can be sent on CADET.
Vector of Pallier-encrypted values sent by Alice to Bob (after set intersection).

Maximum number of elements we can put into a single cryptodata message.

Definition at line 822 of file gnunet-service-scalarproduct_alice.c.

Function Documentation

◆ free_element_cb()

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

Iterator called to free elements.

Parameters
clsthe struct AliceServiceSession * (unused)
keythe key (unused)
valuevalue to free
Returns
GNUNET_OK (continue to iterate)

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

228{
230
231 GNUNET_free (e);
232 return GNUNET_OK;
233}
static char * value
Value of the record to add/remove.
@ GNUNET_OK
#define GNUNET_free(ptr)
Wrapper around free.
An element key-value pair for scalarproduct.

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 AliceServiceSession s)
static

Destroy session state, we are done with it.

Parameters
sthe session to free elements from

Definition at line 242 of file gnunet-service-scalarproduct_alice.c.

243{
244 if (GNUNET_YES == s->in_destroy)
245 return;
247 if (NULL != s->client)
248 {
249 struct GNUNET_SERVICE_Client *c = s->client;
250
251 s->client = NULL;
253 }
254 if (NULL != s->channel)
255 {
257 s->channel = NULL;
258 }
259 if (NULL != s->intersected_elements)
260 {
263 s);
265 s->intersected_elements = NULL;
266 }
267 if (NULL != s->intersection_listen)
268 {
270 s->intersection_listen = NULL;
271 }
272 if (NULL != s->intersection_op)
273 {
275 s->intersection_op = NULL;
276 }
277 if (NULL != s->intersection_set)
278 {
280 s->intersection_set = NULL;
281 }
282 if (NULL != s->sorted_elements)
283 {
284 for (unsigned int i = 0; i < s->used_element_count; i++)
285 gcry_mpi_release (s->sorted_elements[i].value);
287 s->sorted_elements = NULL;
288 }
289 if (NULL != s->r)
290 {
291 GNUNET_free (s->r);
292 s->r = NULL;
293 }
294 if (NULL != s->r_prime)
295 {
296 GNUNET_free (s->r_prime);
297 s->r_prime = NULL;
298 }
299 if (NULL != s->product)
300 {
301 gcry_mpi_release (s->product);
302 s->product = NULL;
303 }
304 GNUNET_free (s);
305}
static int free_element_cb(void *cls, const struct GNUNET_HashCode *key, void *value)
Iterator called to free elements.
void GNUNET_CADET_channel_destroy(struct GNUNET_CADET_Channel *channel)
Destroy an existing channel.
Definition: cadet_api.c:830
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_destroy(struct GNUNET_CONTAINER_MultiHashMap *map)
Destroy a hash map.
@ GNUNET_YES
void GNUNET_SERVICE_client_drop(struct GNUNET_SERVICE_Client *c)
Ask the server to disconnect from the given client.
Definition: service.c:2489
void GNUNET_SETI_destroy(struct GNUNET_SETI_Handle *set)
Destroy the set handle, and free all associated resources.
Definition: seti_api.c:488
void GNUNET_SETI_operation_cancel(struct GNUNET_SETI_OperationHandle *oh)
Cancel the given set operation.
Definition: seti_api.c:335
void GNUNET_SETI_listen_cancel(struct GNUNET_SETI_ListenHandle *lh)
Cancel the given listen operation.
Definition: seti_api.c:734
struct MpiElement * sorted_elements
a(Alice), sorted array by key of length used_element_count.
struct GNUNET_CONTAINER_MultiHashMap * intersected_elements
all non-0-value'd elements transmitted to us.
int product
The computed scalar product.
struct GNUNET_SETI_Handle * intersection_set
Set of elements for which will conduction an intersection.
struct GNUNET_CRYPTO_PaillierCiphertext * r
Bob's permutation p of R.
int in_destroy
Flag to prevent recursive calls to destroy_service_session() from doing harm.
struct GNUNET_SETI_OperationHandle * intersection_op
Set of elements for which will conduction an intersection.
struct GNUNET_CRYPTO_PaillierCiphertext * r_prime
Bob's permutation q of R.
struct GNUNET_SERVICE_Client * client
The client this request is related to.
struct GNUNET_CADET_Channel * channel
channel-handle associated with our cadet handle
struct GNUNET_SETI_ListenHandle * intersection_listen
Handle to Alice's Intersection operation listening for Bob.
uint32_t used_element_count
How many elements actually are used for the scalar product.
Handle to a client that is connected to a service.
Definition: service.c:252
int64_t value
a_i value, not disclosed to Bob.

References AliceServiceSession::channel, AliceServiceSession::client, free_element_cb(), GNUNET_CADET_channel_destroy(), GNUNET_CONTAINER_multihashmap_destroy(), GNUNET_CONTAINER_multihashmap_iterate(), GNUNET_free, GNUNET_SERVICE_client_drop(), GNUNET_SETI_destroy(), GNUNET_SETI_listen_cancel(), GNUNET_SETI_operation_cancel(), GNUNET_YES, AliceServiceSession::in_destroy, AliceServiceSession::intersected_elements, AliceServiceSession::intersection_listen, AliceServiceSession::intersection_op, AliceServiceSession::intersection_set, AliceServiceSession::product, AliceServiceSession::r, AliceServiceSession::r_prime, AliceServiceSession::sorted_elements, AliceServiceSession::used_element_count, and MpiElement::value.

Referenced by 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 AliceServiceSession session)
static

Notify the client that the session has failed.

A message gets sent to Alice's client if we encountered any error.

Parameters
sessionthe associated client session to fail or succeed

Definition at line 315 of file gnunet-service-scalarproduct_alice.c.

316{
318 struct GNUNET_MQ_Envelope *e;
319
320 if (NULL == session->client_mq)
321 return; /* no client left to be notified */
322 GNUNET_log (
324 "Sending session-end notification with status %d to client for session %s\n",
325 session->status,
326 GNUNET_h2s (&session->session_id));
328 msg->product_length = htonl (0);
329 msg->status = htonl (session->status);
330 GNUNET_MQ_send (session->client_mq, e);
331}
struct GNUNET_MessageHeader * msg
Definition: 005.c:2
#define GNUNET_log(kind,...)
const char * GNUNET_h2s(const struct GNUNET_HashCode *hc)
Convert a hash value to a string (for printing debug messages).
@ GNUNET_ERROR_TYPE_DEBUG
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:304
#define GNUNET_MQ_msg(mvar, type)
Allocate a GNUNET_MQ_Envelope.
Definition: gnunet_mq_lib.h:78
#define GNUNET_MESSAGE_TYPE_SCALARPRODUCT_RESULT
Alice/Bob -> Client Result.
struct GNUNET_HashCode session_id
(hopefully) unique transaction ID
struct GNUNET_MQ_Handle * client_mq
The message queue for the client.
enum GNUNET_SCALARPRODUCT_ResponseStatus status
State of this session.
Message type passed from service client to finalize a session as requester or responder.

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

Referenced by cb_channel_destruction(), cb_intersection_element_removed(), cb_intersection_request_alice(), client_request_complete_alice(), and transmit_client_response().

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

◆ transmit_client_response()

static void transmit_client_response ( struct AliceServiceSession s)
static

Prepare the final (positive) response we will send to Alice's client.

Parameters
sthe session associated with our client.

Definition at line 341 of file gnunet-service-scalarproduct_alice.c.

342{
344 struct GNUNET_MQ_Envelope *e;
345 unsigned char *product_exported = NULL;
346 size_t product_length = 0;
347 int32_t range;
348 gcry_error_t rc;
349 int sign;
350 gcry_mpi_t value;
351
352 if (NULL == s->product)
353 {
354 GNUNET_break (0);
356 return;
357 }
358 value = gcry_mpi_new (0);
359 sign = gcry_mpi_cmp_ui (s->product, 0);
360 if (0 > sign)
361 {
362 range = -1;
363 gcry_mpi_sub (value, value, s->product);
364 }
365 else if (0 < sign)
366 {
367 range = 1;
368 gcry_mpi_add (value, value, s->product);
369 }
370 else
371 {
372 /* result is exactly zero */
373 range = 0;
374 }
375 gcry_mpi_release (s->product);
376 s->product = NULL;
377
378 if ((0 != range) && (0 != (rc = gcry_mpi_aprint (GCRYMPI_FMT_STD,
379 &product_exported,
380 &product_length,
381 value))))
382 {
383 LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_mpi_scan", rc);
385 return;
386 }
387 gcry_mpi_release (value);
389 product_length,
392 msg->range = htonl (range);
393 msg->product_length = htonl (product_length);
394 if (NULL != product_exported)
395 {
396 GNUNET_memcpy (&msg[1], product_exported, product_length);
397 GNUNET_free (product_exported);
398 }
401 "Sent result to client, session %s has ended!\n",
402 GNUNET_h2s (&s->session_id));
403}
static void prepare_client_end_notification(struct AliceServiceSession *session)
Notify the client that the session has failed.
#define GNUNET_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur.
@ GNUNET_ERROR_TYPE_ERROR
#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:63
@ GNUNET_SCALARPRODUCT_STATUS_SUCCESS
The computation was successful.
#define LOG_GCRY(level, cmd, rc)
Log an error message at log-level 'level' that indicates a failure of the command 'cmd' with the mess...
Definition: scalarproduct.h:35

References AliceServiceSession::client_mq, GNUNET_break, GNUNET_ERROR_TYPE_DEBUG, GNUNET_ERROR_TYPE_ERROR, GNUNET_free, GNUNET_h2s(), GNUNET_log, GNUNET_memcpy, GNUNET_MESSAGE_TYPE_SCALARPRODUCT_RESULT, GNUNET_MQ_msg_extra, GNUNET_MQ_send(), GNUNET_SCALARPRODUCT_STATUS_SUCCESS, LOG_GCRY, msg, prepare_client_end_notification(), AliceServiceSession::product, AliceServiceSession::session_id, and value.

Referenced by handle_bobs_cryptodata_message(), and handle_bobs_cryptodata_multipart().

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
clsour struct AliceServiceSession
channelconnection to the other end (henceforth invalid)

Definition at line 416 of file gnunet-service-scalarproduct_alice.c.

417{
418 struct AliceServiceSession *s = cls;
419
421 "Peer disconnected, terminating session %s with peer %s\n",
422 GNUNET_h2s (&s->session_id),
423 GNUNET_i2s (&s->peer));
425 {
426 /* We didn't get an answer yet, fail with error */
429 }
430 s->channel = NULL;
431}
const char * GNUNET_i2s(const struct GNUNET_PeerIdentity *pid)
Convert a peer identity to a string (for printing debug messages).
@ GNUNET_SCALARPRODUCT_STATUS_ACTIVE
Operation is still active (never returned, used internally).
@ GNUNET_SCALARPRODUCT_STATUS_FAILURE
We encountered some error.
A scalarproduct session which tracks a request form the client to our final response.
struct GNUNET_CRYPTO_PaillierCiphertext s
Bob's "s".

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

Referenced by client_request_complete_alice().

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

◆ compute_square_sum_mpi_elements()

static gcry_mpi_t compute_square_sum_mpi_elements ( const struct MpiElement 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

Definition at line 442 of file gnunet-service-scalarproduct_alice.c.

444{
445 gcry_mpi_t elem;
446 gcry_mpi_t sum;
447 uint32_t i;
448
449 GNUNET_assert (NULL != (sum = gcry_mpi_new (0)));
450 GNUNET_assert (NULL != (elem = gcry_mpi_new (0)));
451 for (i = 0; i < length; i++)
452 {
453 gcry_mpi_mul (elem, vector[i].value, vector[i].value);
454 gcry_mpi_add (sum, sum, elem);
455 }
456 gcry_mpi_release (elem);
457 return sum;
458}
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.

References GNUNET_assert, consensus-simulation::sum, and value.

Referenced by compute_scalar_product().

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

Definition at line 469 of file gnunet-service-scalarproduct_alice.c.

470{
471 gcry_mpi_t elem;
472 gcry_mpi_t sum;
473 uint32_t i;
474
475 GNUNET_assert (NULL != (sum = gcry_mpi_new (0)));
476 GNUNET_assert (NULL != (elem = gcry_mpi_new (0)));
477 for (i = 0; i < length; i++)
478 {
479 gcry_mpi_mul (elem, vector[i], vector[i]);
480 gcry_mpi_add (sum, sum, elem);
481 }
482 gcry_mpi_release (elem);
483 return sum;
484}

References GNUNET_assert, and consensus-simulation::sum.

Referenced by compute_scalar_product().

Here is the caller graph for this function:

◆ compute_scalar_product()

static gcry_mpi_t compute_scalar_product ( struct AliceServiceSession session)
static

Compute our scalar product, done by Alice.

Parameters
sessionthe session associated with this computation
Returns
product as MPI, never NULL

Definition at line 494 of file gnunet-service-scalarproduct_alice.c.

495{
496 uint32_t count;
497 gcry_mpi_t t;
498 gcry_mpi_t u;
499 gcry_mpi_t u_prime;
500 gcry_mpi_t p;
501 gcry_mpi_t p_prime;
502 gcry_mpi_t tmp;
503 gcry_mpi_t r[session->used_element_count];
504 gcry_mpi_t r_prime[session->used_element_count];
505 gcry_mpi_t s;
506 gcry_mpi_t s_prime;
507 unsigned int i;
508
509 count = session->used_element_count;
510 // due to the introduced static offset S, we now also have to remove this
511 // from the E(a_pi)(+)E(-b_pi-r_pi) and E(a_qi)(+)E(-r_qi) twice each,
512 // the result is E((S + a_pi) + (S -b_pi-r_pi)) and E(S + a_qi + S - r_qi)
513 for (i = 0; i < count; i++)
514 {
515 r[i] = gcry_mpi_new (0);
517 &my_pubkey,
518 &session->r[i],
519 r[i]);
520 gcry_mpi_sub (r[i], r[i], my_offset);
521 gcry_mpi_sub (r[i], r[i], my_offset);
522 r_prime[i] = gcry_mpi_new (0);
524 &my_pubkey,
525 &session->r_prime[i],
526 r_prime[i]);
527 gcry_mpi_sub (r_prime[i], r_prime[i], my_offset);
528 gcry_mpi_sub (r_prime[i], r_prime[i], my_offset);
529 }
530
531 // calculate t = sum(ai)
533 // calculate U
534 u = gcry_mpi_new (0);
535 tmp = compute_square_sum (r, count);
536 gcry_mpi_sub (u, u, tmp);
537 gcry_mpi_release (tmp);
538
539 // calculate U'
540 u_prime = gcry_mpi_new (0);
541 tmp = compute_square_sum (r_prime, count);
542 gcry_mpi_sub (u_prime, u_prime, tmp);
543
544 GNUNET_assert (p = gcry_mpi_new (0));
545 GNUNET_assert (p_prime = gcry_mpi_new (0));
546 GNUNET_assert (s = gcry_mpi_new (0));
547 GNUNET_assert (s_prime = gcry_mpi_new (0));
548
549 // compute P
552 &my_pubkey,
553 &session->s_prime,
554 s_prime);
555
556 // compute P
557 gcry_mpi_add (p, s, t);
558 gcry_mpi_add (p, p, u);
559
560 // compute P'
561 gcry_mpi_add (p_prime, s_prime, t);
562 gcry_mpi_add (p_prime, p_prime, u_prime);
563
564 gcry_mpi_release (t);
565 gcry_mpi_release (u);
566 gcry_mpi_release (u_prime);
567 gcry_mpi_release (s);
568 gcry_mpi_release (s_prime);
569
570 // compute product
571 gcry_mpi_sub (p, p, p_prime);
572 gcry_mpi_release (p_prime);
573 tmp = gcry_mpi_set_ui (tmp, 2);
574 gcry_mpi_div (p, NULL, p, tmp, 0);
575
576 gcry_mpi_release (tmp);
577 for (i = 0; i < count; i++)
578 {
579 gcry_mpi_release (session->sorted_elements[i].value);
580 gcry_mpi_release (r[i]);
581 gcry_mpi_release (r_prime[i]);
582 }
583 GNUNET_free (session->sorted_elements);
584 session->sorted_elements = NULL;
585 GNUNET_free (session->r);
586 session->r = NULL;
587 GNUNET_free (session->r_prime);
588 session->r_prime = NULL;
589
590 return p;
591}
static mp_limb_t u[(((256)+GMP_NUMB_BITS - 1)/GMP_NUMB_BITS)]
static struct GNUNET_CRYPTO_PaillierPrivateKey my_privkey
Service's own private key.
static gcry_mpi_t compute_square_sum_mpi_elements(const struct MpiElement *vector, uint32_t length)
Computes the square sum over a vector of a given length.
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 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 struct GNUNET_OS_Process * p
Helper process we started.
Definition: gnunet-uri.c:38
static struct GNUNET_SCHEDULER_Task * t
Main task.
void GNUNET_CRYPTO_paillier_decrypt(const struct GNUNET_CRYPTO_PaillierPrivateKey *private_key, const struct GNUNET_CRYPTO_PaillierPublicKey *public_key, const struct GNUNET_CRYPTO_PaillierCiphertext *ciphertext, gcry_mpi_t m)
Decrypt a paillier ciphertext with a private key.
struct GNUNET_CRYPTO_PaillierCiphertext s_prime
Bob's "s'".

References compute_square_sum(), compute_square_sum_mpi_elements(), GNUNET_assert, GNUNET_CRYPTO_paillier_decrypt(), GNUNET_free, my_offset, my_privkey, my_pubkey, p, AliceServiceSession::r, AliceServiceSession::r_prime, AliceServiceSession::s, AliceServiceSession::s_prime, AliceServiceSession::sorted_elements, t, u, AliceServiceSession::used_element_count, and MpiElement::value.

Referenced by handle_bobs_cryptodata_message(), and handle_bobs_cryptodata_multipart().

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

◆ check_bobs_cryptodata_multipart()

static int check_bobs_cryptodata_multipart ( void *  cls,
const struct BobCryptodataMultipartMessage msg 
)
static

Check a multipart chunk of a response we got from another service we wanted to calculate a scalarproduct with.

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

Definition at line 604 of file gnunet-service-scalarproduct_alice.c.

607{
608 struct AliceServiceSession *s = cls;
609 uint32_t contained;
610 size_t msg_size;
611 size_t required_size;
612
613 msg_size = ntohs (msg->header.size);
614 contained = ntohl (msg->contained_element_count);
615 required_size =
616 sizeof(struct BobCryptodataMultipartMessage)
617 + 2 * contained * sizeof(struct GNUNET_CRYPTO_PaillierCiphertext);
618 if ((required_size != msg_size) ||
620 {
621 GNUNET_break (0);
622 return GNUNET_SYSERR;
623 }
624 return GNUNET_OK;
625}
@ GNUNET_SYSERR
uint32_t cadet_received_element_count
Already transferred elements from Bob to us.
Multipart Message type passed between to supply additional elements for the peer.
uint16_t size
The length of the struct (in bytes, including the length field itself), in big-endian format.

References AliceServiceSession::cadet_received_element_count, GNUNET_break, GNUNET_OK, GNUNET_SYSERR, msg, AliceServiceSession::s, GNUNET_MessageHeader::size, and AliceServiceSession::used_element_count.

◆ handle_bobs_cryptodata_multipart()

static void handle_bobs_cryptodata_multipart ( void *  cls,
const struct BobCryptodataMultipartMessage msg 
)
static

Handle a multipart chunk of a response we got from another service we wanted to calculate a scalarproduct with.

Parameters
clsthe struct AliceServiceSession
msgthe actual message

Definition at line 636 of file gnunet-service-scalarproduct_alice.c.

639{
640 struct AliceServiceSession *s = cls;
642 size_t i;
643 uint32_t contained;
644
645 contained = ntohl (msg->contained_element_count);
647 "Received %u additional crypto values from Bob\n",
648 (unsigned int) contained);
649
650 payload = (const struct GNUNET_CRYPTO_PaillierCiphertext *) &msg[1];
651 /* Convert each k[][perm] to its MPI_value */
652 for (i = 0; i < contained; i++)
653 {
655 &payload[2 * i],
656 sizeof(struct GNUNET_CRYPTO_PaillierCiphertext));
658 &payload[2 * i],
659 sizeof(struct GNUNET_CRYPTO_PaillierCiphertext));
660 }
661 s->cadet_received_element_count += contained;
664 return; /* more to come */
665
668}
static unsigned long long payload
How much data are we currently storing in the database?
static gcry_mpi_t compute_scalar_product(struct AliceServiceSession *session)
Compute our scalar product, done by Alice.
static void transmit_client_response(struct AliceServiceSession *s)
Prepare the final (positive) response we will send to Alice's client.
void GNUNET_CADET_receive_done(struct GNUNET_CADET_Channel *channel)
Indicate readiness to receive the next message on a channel.
Definition: cadet_api.c:872

References AliceServiceSession::cadet_received_element_count, AliceServiceSession::channel, compute_scalar_product(), GNUNET_CADET_receive_done(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_log, GNUNET_memcpy, msg, payload, AliceServiceSession::product, AliceServiceSession::r, AliceServiceSession::r_prime, AliceServiceSession::s, transmit_client_response(), and AliceServiceSession::used_element_count.

Here is the call graph for this function:

◆ check_bobs_cryptodata_message()

static int check_bobs_cryptodata_message ( void *  cls,
const struct BobCryptodataMessage msg 
)
static

Check a response we got from another service we wanted to calculate a scalarproduct with.

Parameters
clsour struct AliceServiceSession
msgthe actual message
Returns
GNUNET_OK to keep the connection open, GNUNET_SYSERR to close it (we are done)

Definition at line 681 of file gnunet-service-scalarproduct_alice.c.

683{
684 struct AliceServiceSession *s = cls;
685 uint32_t contained;
686 uint16_t msg_size;
687 size_t required_size;
688
689 msg_size = ntohs (msg->header.size);
690 contained = ntohl (msg->contained_element_count);
691 required_size =
692 sizeof(struct BobCryptodataMessage)
693 + 2 * contained * sizeof(struct GNUNET_CRYPTO_PaillierCiphertext)
694 + 2 * sizeof(struct GNUNET_CRYPTO_PaillierCiphertext);
695 if ((msg_size != required_size) || (contained > UINT16_MAX) ||
696 (s->used_element_count < contained))
697 {
698 GNUNET_break_op (0);
699 return GNUNET_SYSERR;
700 }
701 if (NULL == s->sorted_elements)
702 {
703 /* we're not ready yet, how can Bob be? */
704 GNUNET_break_op (0);
705 return GNUNET_SYSERR;
706 }
708 {
709 /* we're not ready yet, how can Bob be? */
710 GNUNET_break_op (0);
711 return GNUNET_SYSERR;
712 }
713 return GNUNET_OK;
714}
#define GNUNET_break_op(cond)
Use this for assertion violations caused by other peers (i.e.
uint32_t total
How many elements we were supplied with from the client (total count before intersection).
uint32_t client_received_element_count
Already transferred elements from client to us.
Message type passed from responding service Bob to responding service Alice to complete a request and...

References AliceServiceSession::client_received_element_count, GNUNET_break_op, GNUNET_OK, GNUNET_SYSERR, msg, AliceServiceSession::s, GNUNET_MessageHeader::size, AliceServiceSession::sorted_elements, AliceServiceSession::total, and AliceServiceSession::used_element_count.

◆ handle_bobs_cryptodata_message()

static void handle_bobs_cryptodata_message ( void *  cls,
const struct BobCryptodataMessage msg 
)
static

Handle a response we got from another service we wanted to calculate a scalarproduct with.

Parameters
clsour struct AliceServiceSession
msgthe actual message

Definition at line 725 of file gnunet-service-scalarproduct_alice.c.

727{
728 struct AliceServiceSession *s = cls;
730 uint32_t i;
731 uint32_t contained;
732
733 contained = ntohl (msg->contained_element_count);
735 "Received %u crypto values from Bob\n",
736 (unsigned int) contained);
737 payload = (const struct GNUNET_CRYPTO_PaillierCiphertext *) &msg[1];
738 GNUNET_memcpy (&s->s,
739 &payload[0],
740 sizeof(struct GNUNET_CRYPTO_PaillierCiphertext));
742 &payload[1],
743 sizeof(struct GNUNET_CRYPTO_PaillierCiphertext));
744 payload = &payload[2];
745
750 for (i = 0; i < contained; i++)
751 {
752 GNUNET_memcpy (&s->r[i],
753 &payload[2 * i],
754 sizeof(struct GNUNET_CRYPTO_PaillierCiphertext));
755 GNUNET_memcpy (&s->r_prime[i],
756 &payload[2 * i + 1],
757 sizeof(struct GNUNET_CRYPTO_PaillierCiphertext));
758 }
759 s->cadet_received_element_count = contained;
761
763 {
764 /* More to come */
765 return;
766 }
769}
#define GNUNET_new_array(n, type)
Allocate a size n array with structs or unions of the given type.

References AliceServiceSession::cadet_received_element_count, AliceServiceSession::channel, compute_scalar_product(), GNUNET_CADET_receive_done(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_log, GNUNET_memcpy, GNUNET_new_array, msg, payload, AliceServiceSession::product, AliceServiceSession::r, AliceServiceSession::r_prime, AliceServiceSession::s, AliceServiceSession::s_prime, transmit_client_response(), and AliceServiceSession::used_element_count.

Here is the call 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 AliceServiceSession *
keythe key (unused)
valuethe struct GNUNET_SCALARPRODUCT_Element *

Definition at line 781 of file gnunet-service-scalarproduct_alice.c.

782{
783 struct AliceServiceSession *s = cls;
785 gcry_mpi_t mval;
786 int64_t val;
787
788 mval = gcry_mpi_new (0);
789 val = (int64_t) GNUNET_ntohll (e->value);
790 if (0 > val)
791 gcry_mpi_sub_ui (mval, mval, -val);
792 else
793 gcry_mpi_add_ui (mval, mval, val);
797 return GNUNET_OK;
798}
uint64_t GNUNET_ntohll(uint64_t n)
Convert unsigned 64-bit integer to host byte order.
Definition: common_endian.c:54
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.
const struct GNUNET_HashCode * key
Key used to identify matching pairs of values to multiply.

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

Referenced by send_alices_cryptodata_message().

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.

Definition at line 809 of file gnunet-service-scalarproduct_alice.c.

810{
811 const struct MpiElement *ma = a;
812 const struct MpiElement *mb = b;
813
814 return GNUNET_CRYPTO_hash_cmp (ma->key, mb->key);
815}
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:221
An encrypted element key-value pair.

References GNUNET_CRYPTO_hash_cmp(), and MpiElement::key.

Referenced by send_alices_cryptodata_message().

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

◆ send_alices_cryptodata_message()

static void send_alices_cryptodata_message ( struct AliceServiceSession s)
static

Send the cryptographic data from Alice to Bob.

Does nothing if we already transferred all elements.

Parameters
sthe associated service session

Definition at line 835 of file gnunet-service-scalarproduct_alice.c.

836{
838 struct GNUNET_MQ_Envelope *e;
840 unsigned int i;
841 uint32_t todo_count;
842 gcry_mpi_t a;
843 uint32_t off;
844
847 * sizeof(struct MpiElement));
848 s->used_element_count = 0;
851 s);
853 "Finished intersection, %d items remain\n",
855 qsort (s->sorted_elements,
857 sizeof(struct MpiElement),
858 &element_cmp);
859 off = 0;
860 while (off < s->used_element_count)
861 {
862 todo_count = s->used_element_count - off;
863 if (todo_count > ELEMENT_CAPACITY)
864 todo_count = ELEMENT_CAPACITY;
866 "Sending %u/%u crypto values to Bob\n",
867 (unsigned int) todo_count,
868 (unsigned int) s->used_element_count);
869
870 e =
872 todo_count
873 * sizeof(struct GNUNET_CRYPTO_PaillierCiphertext),
875 msg->contained_element_count = htonl (todo_count);
877 a = gcry_mpi_new (0);
878 for (i = off; i < off + todo_count; i++)
879 {
880 gcry_mpi_add (a, s->sorted_elements[i].value, my_offset);
882 3 ==
884 }
885 gcry_mpi_release (a);
886 off += todo_count;
887 GNUNET_MQ_send (s->cadet_mq, e);
888 }
889}
#define ELEMENT_CAPACITY
Maximum number of elements we can put into a single cryptodata message.
static int element_cmp(const void *a, const void *b)
Compare two struct MpiValues by key for sorting.
#define LOG(kind,...)
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.
unsigned int GNUNET_CONTAINER_multihashmap_size(const struct GNUNET_CONTAINER_MultiHashMap *map)
Get the number of key-value pairs in the map.
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.
#define GNUNET_malloc(size)
Wrapper around malloc.
#define GNUNET_MESSAGE_TYPE_SCALARPRODUCT_ALICE_CRYPTODATA
Alice -> Bob SP crypto-data (after intersection)
struct GNUNET_MQ_Handle * cadet_mq
The message queue for CADET.

References AliceServiceSession::cadet_mq, copy_element_cb(), ELEMENT_CAPACITY, element_cmp(), GNUNET_assert, GNUNET_CONTAINER_multihashmap_iterate(), GNUNET_CONTAINER_multihashmap_size(), GNUNET_CRYPTO_paillier_encrypt(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_log, GNUNET_malloc, GNUNET_MESSAGE_TYPE_SCALARPRODUCT_ALICE_CRYPTODATA, GNUNET_MQ_msg_extra, GNUNET_MQ_send(), AliceServiceSession::intersected_elements, LOG, msg, my_offset, my_pubkey, payload, AliceServiceSession::sorted_elements, AliceServiceSession::used_element_count, and MpiElement::value.

Referenced by cb_intersection_element_removed().

Here is the call graph for this function:
Here is the caller 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 should be removed from the result set, and then once to indicate that the set intersection operation is done.

Parameters
clsclosure with the struct AliceServiceSession
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 903 of file gnunet-service-scalarproduct_alice.c.

907{
908 struct AliceServiceSession *s = cls;
910
911 switch (status)
912 {
914 /* this element has been removed from the set */
916 element->data);
917 GNUNET_assert (NULL != se);
919 "Intersection removed element with key %s and value %lld\n",
920 GNUNET_h2s (&se->key),
921 (long long) GNUNET_ntohll (se->value));
923 GNUNET_YES ==
925 element->data,
926 se));
927 GNUNET_free (se);
928 return;
929
931 s->intersection_op = NULL;
932 if (NULL != s->intersection_set)
933 {
935 s->intersection_set = NULL;
936 }
938 return;
940 /* unhandled status code */
941 LOG (GNUNET_ERROR_TYPE_DEBUG, "Set intersection failed!\n");
942 if (NULL != s->intersection_listen)
943 {
945 s->intersection_listen = NULL;
946 }
947 s->intersection_op = NULL;
948 if (NULL != s->intersection_set)
949 {
951 s->intersection_set = NULL;
952 }
955 return;
956
957 default:
958 GNUNET_break (0);
959 return;
960 }
961}
static int status
The program status; 0 for success.
Definition: gnunet-nse.c:39
static void send_alices_cryptodata_message(struct AliceServiceSession *s)
Send the cryptographic data from Alice to Bob.
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.
@ 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.
const void * data
Actual data of the element.

References GNUNET_SETI_Element::data, GNUNET_assert, GNUNET_break, GNUNET_CONTAINER_multihashmap_get(), GNUNET_CONTAINER_multihashmap_remove(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_free, GNUNET_h2s(), GNUNET_ntohll(), GNUNET_SCALARPRODUCT_STATUS_FAILURE, GNUNET_SETI_destroy(), GNUNET_SETI_listen_cancel(), GNUNET_SETI_STATUS_DEL_LOCAL, GNUNET_SETI_STATUS_DONE, GNUNET_SETI_STATUS_FAILURE, GNUNET_YES, AliceServiceSession::intersected_elements, AliceServiceSession::intersection_listen, AliceServiceSession::intersection_op, AliceServiceSession::intersection_set, GNUNET_SCALARPRODUCT_Element::key, LOG, prepare_client_end_notification(), AliceServiceSession::s, send_alices_cryptodata_message(), status, AliceServiceSession::status, and GNUNET_SCALARPRODUCT_Element::value.

Referenced by cb_intersection_request_alice().

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

◆ cb_intersection_request_alice()

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 
)
static

Called when another peer wants to do a set operation with the local peer.

If a listen error occurs, the request is NULL.

Parameters
clsclosure with the struct AliceServiceSession *
other_peerthe other peer
context_msgmessage with application specific information from the other peer
requestrequest from the other peer (never NULL), use GNUNET_SETI_accept() to accept it, otherwise the request will be refused Note that we can't just return value from the listen callback, as it is also necessary to specify the set we want to do the operation with, which sometimes can be derived from the context message. It's necessary to specify the timeout.

Definition at line 980 of file gnunet-service-scalarproduct_alice.c.

984{
985 struct AliceServiceSession *s = cls;
986
987 if (0 != GNUNET_memcmp (other_peer, &s->peer))
988 {
989 GNUNET_break_op (0);
990 return;
991 }
992 s->intersection_op = GNUNET_SETI_accept (request,
993 (struct
994 GNUNET_SETI_Option[]){ { 0 } },
996 s);
997 if (NULL == s->intersection_op)
998 {
999 GNUNET_break (0);
1002 return;
1003 }
1004 if (GNUNET_OK != GNUNET_SETI_commit (s->intersection_op, s->intersection_set))
1005 {
1006 GNUNET_break (0);
1009 return;
1010 }
1011}
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_VPN_RedirectionRequest * request
Opaque redirection request handle.
Definition: gnunet-vpn.c:40
#define GNUNET_memcmp(a, b)
Compare memory in a and b, where both must be of the same pointer type.
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:754
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
Option for set operations.

References cb_intersection_element_removed(), GNUNET_break, GNUNET_break_op, GNUNET_memcmp, GNUNET_OK, GNUNET_SCALARPRODUCT_STATUS_FAILURE, GNUNET_SETI_accept(), GNUNET_SETI_commit(), prepare_client_end_notification(), request, and AliceServiceSession::s.

Referenced by client_request_complete_alice().

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

◆ client_request_complete_alice()

static void client_request_complete_alice ( struct AliceServiceSession s)
static

Our client has finished sending us its multipart message.

Parameters
sessionthe service session context

Definition at line 1020 of file gnunet-service-scalarproduct_alice.c.

1021{
1022 struct GNUNET_MQ_MessageHandler cadet_handlers[] =
1023 { GNUNET_MQ_hd_var_size (bobs_cryptodata_message,
1025 struct BobCryptodataMessage,
1026 s),
1028 bobs_cryptodata_multipart,
1031 s),
1033 struct ServiceRequestMessage *msg;
1034 struct GNUNET_MQ_Envelope *e;
1035
1037 "Creating new channel for session with key %s.\n",
1038 GNUNET_h2s (&s->session_id));
1040 s,
1041 &s->peer,
1042 &s->session_id,
1043 NULL,
1045 cadet_handlers);
1046 if (NULL == s->channel)
1047 {
1050 return;
1051 }
1054 &s->session_id,
1056 s);
1057 if (NULL == s->intersection_listen)
1058 {
1061 s->channel = NULL;
1063 return;
1064 }
1065
1066 e = GNUNET_MQ_msg (msg,
1068 msg->session_id = s->session_id;
1069 msg->public_key = my_pubkey;
1070 GNUNET_MQ_send (s->cadet_mq, e);
1071}
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.
static struct GNUNET_CADET_Handle * my_cadet
Handle to the CADET service.
static const struct GNUNET_CONFIGURATION_Handle * cfg
GNUnet configuration handle.
static void cb_channel_destruction(void *cls, const struct GNUNET_CADET_Channel *channel)
Function called whenever a channel is destroyed.
struct GNUNET_MQ_Handle * GNUNET_CADET_get_mq(const struct GNUNET_CADET_Channel *channel)
Obtain the message queue for a connected channel.
Definition: cadet_api.c:1066
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:1015
#define GNUNET_MQ_handler_end()
End-marker for the handlers array.
#define GNUNET_MQ_hd_var_size(name, code, str, ctx)
#define GNUNET_MESSAGE_TYPE_SCALARPRODUCT_BOB_CRYPTODATA
Bob -> Alice SP crypto-data.
#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.
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:702
struct GNUNET_PeerIdentity peer
Alice or Bob's peerID.
Message handler for a specific message type.
Message type passed from requesting service Alice to responding service Bob to initiate a request and...

References AliceServiceSession::cadet_mq, cb_channel_destruction(), cb_intersection_request_alice(), cfg, AliceServiceSession::channel, GNUNET_CADET_channel_create(), GNUNET_CADET_channel_destroy(), GNUNET_CADET_get_mq(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_h2s(), GNUNET_log, GNUNET_MESSAGE_TYPE_SCALARPRODUCT_BOB_CRYPTODATA, GNUNET_MESSAGE_TYPE_SCALARPRODUCT_BOB_CRYPTODATA_MULTIPART, GNUNET_MESSAGE_TYPE_SCALARPRODUCT_SESSION_INITIALIZATION, GNUNET_MQ_handler_end, GNUNET_MQ_hd_var_size, GNUNET_MQ_msg, GNUNET_MQ_send(), GNUNET_SCALARPRODUCT_STATUS_FAILURE, GNUNET_SETI_listen(), AliceServiceSession::intersection_listen, msg, my_cadet, my_pubkey, AliceServiceSession::peer, prepare_client_end_notification(), AliceServiceSession::session_id, and AliceServiceSession::status.

Referenced by handle_alice_client_message(), and handle_alice_client_message_multipart().

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

◆ check_alice_client_message_multipart()

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

We're receiving additional set data.

Check if msg is well-formed.

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

Definition at line 1083 of file gnunet-service-scalarproduct_alice.c.

1086{
1087 struct AliceServiceSession *s = cls;
1088 uint32_t contained_count;
1089 uint16_t msize;
1090
1091 msize = ntohs (msg->header.size);
1092 contained_count = ntohl (msg->element_count_contained);
1093 if ((msize !=
1095 + contained_count * sizeof(struct GNUNET_SCALARPRODUCT_Element))) ||
1096 (0 == contained_count) ||
1097 (s->total == s->client_received_element_count) ||
1098 (s->total < s->client_received_element_count + contained_count))
1099 {
1100 GNUNET_break_op (0);
1101 return GNUNET_SYSERR;
1102 }
1103 return GNUNET_OK;
1104}
multipart messages following struct ComputationMessage

References GNUNET_break_op, GNUNET_OK, GNUNET_SYSERR, msg, AliceServiceSession::s, and GNUNET_MessageHeader::size.

◆ handle_alice_client_message_multipart()

static void handle_alice_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
clsclient identification of the client
msgthe actual message

Definition at line 1115 of file gnunet-service-scalarproduct_alice.c.

1118{
1119 struct AliceServiceSession *s = cls;
1120 uint32_t contained_count;
1121 const struct GNUNET_SCALARPRODUCT_Element *elements;
1122 struct GNUNET_SETI_Element set_elem;
1123 struct GNUNET_SCALARPRODUCT_Element *elem;
1124
1125 contained_count = ntohl (msg->element_count_contained);
1126 s->client_received_element_count += contained_count;
1127 elements = (const struct GNUNET_SCALARPRODUCT_Element *) &msg[1];
1128 for (uint32_t i = 0; i < contained_count; i++)
1129 {
1131 GNUNET_memcpy (elem,
1132 &elements[i],
1133 sizeof(struct GNUNET_SCALARPRODUCT_Element));
1136 &elem->key,
1137 elem,
1139 {
1140 GNUNET_break (0);
1141 GNUNET_free (elem);
1142 continue;
1143 }
1144 set_elem.data = &elem->key;
1145 set_elem.size = sizeof(elem->key);
1146 set_elem.element_type = 0;
1147 GNUNET_SETI_add_element (s->intersection_set, &set_elem, NULL, NULL);
1148 s->used_element_count++;
1149 }
1152 {
1153 /* more to come */
1154 return;
1155 }
1157}
static void client_request_complete_alice(struct AliceServiceSession *s)
Our client has finished sending us its multipart message.
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.
@ 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_new(type)
Allocate a struct or union of the given type.
void GNUNET_SERVICE_client_continue(struct GNUNET_SERVICE_Client *c)
Continue receiving further messages from the given client.
Definition: service.c:2408
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
Element stored in a set.

References AliceServiceSession::client, AliceServiceSession::client_received_element_count, client_request_complete_alice(), 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, AliceServiceSession::intersected_elements, AliceServiceSession::intersection_set, GNUNET_SCALARPRODUCT_Element::key, msg, AliceServiceSession::s, GNUNET_SETI_Element::size, AliceServiceSession::total, and AliceServiceSession::used_element_count.

Here is the call graph for this function:

◆ check_alice_client_message()

static int check_alice_client_message ( void *  cls,
const struct AliceComputationMessage msg 
)
static

Handler for Alice's client request message.

Check that msg is well-formed.

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

Definition at line 1169 of file gnunet-service-scalarproduct_alice.c.

1171{
1172 struct AliceServiceSession *s = cls;
1173 uint16_t msize;
1174 uint32_t total_count;
1175 uint32_t contained_count;
1176
1177 if (NULL != s->intersected_elements)
1178 {
1179 /* only one concurrent session per client connection allowed,
1180 simplifies logic a lot... */
1181 GNUNET_break (0);
1182 return GNUNET_SYSERR;
1183 }
1184 msize = ntohs (msg->header.size);
1185 total_count = ntohl (msg->element_count_total);
1186 contained_count = ntohl (msg->element_count_contained);
1187 if ((0 == total_count) || (0 == contained_count) ||
1188 (msize !=
1189 (sizeof(struct AliceComputationMessage)
1190 + contained_count * sizeof(struct GNUNET_SCALARPRODUCT_Element))))
1191 {
1192 GNUNET_break_op (0);
1193 return GNUNET_SYSERR;
1194 }
1195 return GNUNET_OK;
1196}
Message type passed from client to service to initiate a request or responder role.
Definition: scalarproduct.h:46

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

◆ handle_alice_client_message()

static void handle_alice_client_message ( void *  cls,
const struct AliceComputationMessage msg 
)
static

Handler for Alice's client request message.

We are doing request-initiation to compute a scalar product with a peer.

Parameters
clsidentification of the client
msgthe actual message

Definition at line 1207 of file gnunet-service-scalarproduct_alice.c.

1209{
1210 struct AliceServiceSession *s = cls;
1211 uint32_t contained_count;
1212 uint32_t total_count;
1213 const struct GNUNET_SCALARPRODUCT_Element *elements;
1214 struct GNUNET_SETI_Element set_elem;
1215 struct GNUNET_SCALARPRODUCT_Element *elem;
1216
1217 total_count = ntohl (msg->element_count_total);
1218 contained_count = ntohl (msg->element_count_contained);
1219 s->peer = msg->peer;
1221 s->total = total_count;
1222 s->client_received_element_count = contained_count;
1223 s->session_id = msg->session_key;
1224 elements = (const struct GNUNET_SCALARPRODUCT_Element *) &msg[1];
1228
1229 for (uint32_t i = 0; i < contained_count; i++)
1230 {
1231 if (0 == GNUNET_ntohll (elements[i].value))
1232 continue;
1234 GNUNET_memcpy (elem,
1235 &elements[i],
1236 sizeof(struct GNUNET_SCALARPRODUCT_Element));
1239 &elem->key,
1240 elem,
1242 {
1243 /* element with same key encountered twice! */
1244 GNUNET_break (0);
1245 GNUNET_free (elem);
1246 continue;
1247 }
1248 set_elem.data = &elem->key;
1249 set_elem.size = sizeof(elem->key);
1250 set_elem.element_type = 0;
1252 &set_elem,
1253 NULL,
1254 NULL);
1255 s->used_element_count++;
1256 }
1259 {
1260 /* wait for multipart msg */
1261 return;
1262 }
1264}
struct GNUNET_CONTAINER_MultiHashMap * GNUNET_CONTAINER_multihashmap_create(unsigned int len, int do_not_copy_keys)
Create a multi hash map.
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

References cfg, AliceServiceSession::client, AliceServiceSession::client_received_element_count, client_request_complete_alice(), GNUNET_SETI_Element::data, GNUNET_SETI_Element::element_type, GNUNET_break, GNUNET_CONTAINER_multihashmap_create(), GNUNET_CONTAINER_multihashmap_put(), GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY, GNUNET_free, GNUNET_memcpy, GNUNET_new, GNUNET_ntohll(), GNUNET_SCALARPRODUCT_STATUS_ACTIVE, GNUNET_SERVICE_client_continue(), GNUNET_SETI_add_element(), GNUNET_SETI_create(), GNUNET_SYSERR, GNUNET_YES, AliceServiceSession::intersected_elements, AliceServiceSession::intersection_set, GNUNET_SCALARPRODUCT_Element::key, msg, AliceServiceSession::peer, AliceServiceSession::s, AliceServiceSession::session_id, GNUNET_SETI_Element::size, AliceServiceSession::status, AliceServiceSession::total, AliceServiceSession::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 1273 of file gnunet-service-scalarproduct_alice.c.

1274{
1275 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Shutting down, initiating cleanup.\n");
1276 // FIXME: we have to cut our connections to CADET first!
1277 if (NULL != my_cadet)
1278 {
1280 my_cadet = NULL;
1281 }
1282}
void GNUNET_CADET_disconnect(struct GNUNET_CADET_Handle *handle)
Disconnect from the cadet service.
Definition: cadet_api.c:774

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

Referenced by run().

Here is the call graph for this function:
Here is the caller 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 AliceServiceSession

Definition at line 1296 of file gnunet-service-scalarproduct_alice.c.

1299{
1300 struct AliceServiceSession *s;
1301
1302 s = GNUNET_new (struct AliceServiceSession);
1303 s->client = client;
1304 s->client_mq = mq;
1305 return s;
1306}
struct GNUNET_MQ_Handle * mq
Definition: 003.c:5

References AliceServiceSession::client, GNUNET_new, mq, and AliceServiceSession::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 AliceServiceSession

Definition at line 1320 of file gnunet-service-scalarproduct_alice.c.

1323{
1324 struct AliceServiceSession *s = app_cls;
1325
1327 "Client %p disconnected from us.\n",
1328 client);
1329 s->client = NULL;
1330 s->client_mq = NULL;
1332}
static void destroy_service_session(struct AliceServiceSession *s)
Destroy session state, we are done with it.

References AliceServiceSession::client, destroy_service_session(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_log, and AliceServiceSession::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 1343 of file gnunet-service-scalarproduct_alice.c.

1346{
1347 cfg = c;
1348 /*
1349 offset has to be sufficiently small to allow computation of:
1350 m1+m2 mod n == (S + a) + (S + b) mod n,
1351 if we have more complex operations, this factor needs to be lowered */
1352 my_offset = gcry_mpi_new (GNUNET_CRYPTO_PAILLIER_BITS / 3);
1353 gcry_mpi_set_bit (my_offset, GNUNET_CRYPTO_PAILLIER_BITS / 3);
1357 if (NULL == my_cadet)
1358 {
1359 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _ ("Connect to CADET failed\n"));
1361 return;
1362 }
1363}
static void shutdown_task(void *cls)
Task run during shutdown.
struct GNUNET_CADET_Handle * GNUNET_CADET_connect(const struct GNUNET_CONFIGURATION_Handle *cfg)
Connect to the MQ-based cadet service.
Definition: cadet_api.c:894
#define GNUNET_CRYPTO_PAILLIER_BITS
Size of paillier plain texts and public keys.
void GNUNET_CRYPTO_paillier_create(struct GNUNET_CRYPTO_PaillierPublicKey *public_key, struct GNUNET_CRYPTO_PaillierPrivateKey *private_key)
Create a freshly generated paillier public key.
void GNUNET_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:1340
#define _(String)
GNU gettext support macro.
Definition: platform.h:178

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 ( "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.

Variable Documentation

◆ cfg

const struct GNUNET_CONFIGURATION_Handle* cfg
static

GNUnet configuration handle.

Definition at line 195 of file gnunet-service-scalarproduct_alice.c.

Referenced by client_request_complete_alice(), handle_alice_client_message(), and run().

◆ my_pubkey

struct GNUNET_CRYPTO_PaillierPublicKey my_pubkey
static

◆ my_privkey

struct GNUNET_CRYPTO_PaillierPrivateKey my_privkey
static

Service's own private key.

Definition at line 205 of file gnunet-service-scalarproduct_alice.c.

Referenced by compute_scalar_product(), and 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 210 of file gnunet-service-scalarproduct_alice.c.

Referenced by compute_scalar_product(), run(), and send_alices_cryptodata_message().

◆ my_cadet

struct GNUNET_CADET_Handle* my_cadet
static

Handle to the CADET service.

Definition at line 215 of file gnunet-service-scalarproduct_alice.c.

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