X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=src%2Fscalarproduct%2Fgnunet-service-scalarproduct-ecc_bob.c;h=0b0333332a34b56e908fea8714c52671d28f35fb;hb=04a46ba5acf180be6f3a7d85cd6f6ce0ff13b1ba;hp=d08f5b8584b4f63506a60c614676443254f96e80;hpb=110973ebdd4f267cbaca4f793dae6c2ff325eeb9;p=oweals%2Fgnunet.git diff --git a/src/scalarproduct/gnunet-service-scalarproduct-ecc_bob.c b/src/scalarproduct/gnunet-service-scalarproduct-ecc_bob.c index d08f5b858..0b0333332 100644 --- a/src/scalarproduct/gnunet-service-scalarproduct-ecc_bob.c +++ b/src/scalarproduct/gnunet-service-scalarproduct-ecc_bob.c @@ -1,6 +1,6 @@ /* This file is part of GNUnet. - Copyright (C) 2013, 2014 Christian Grothoff (and other contributing authors) + Copyright (C) 2013-2017 GNUnet e.V. GNUnet is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published @@ -18,7 +18,7 @@ Boston, MA 02110-1301, USA. */ /** - * @file scalarproduct/gnunet-service-scalarproduct_bob.c + * @file scalarproduct/gnunet-service-scalarproduct-ecc_bob.c * @brief scalarproduct service implementation * @author Christian M. Fuchs * @author Christian Grothoff @@ -34,7 +34,7 @@ #include "gnunet_scalarproduct_service.h" #include "gnunet_set_service.h" #include "scalarproduct.h" -#include "gnunet-service-scalarproduct.h" +#include "gnunet-service-scalarproduct-ecc.h" #define LOG(kind,...) GNUNET_log_from (kind, "scalarproduct-bob", __VA_ARGS__) @@ -58,12 +58,6 @@ struct MpiElement }; -/** - * An incoming session from CADET. - */ -struct CadetIncomingSession; - - /** * A scalarproduct session which tracks an offer for a * multiplication service by a local client. @@ -71,15 +65,10 @@ struct CadetIncomingSession; struct BobServiceSession { - /** - * (hopefully) unique transaction ID - */ - struct GNUNET_HashCode session_id; - /** * The client this request is related to. */ - struct GNUNET_SERVER_Client *client; + struct GNUNET_SERVICE_Client *client; /** * Client message queue. @@ -104,45 +93,24 @@ struct BobServiceSession struct GNUNET_SET_OperationHandle *intersection_op; /** - * a(Alice) - */ - struct MpiElement *sorted_elements; - - /** - * E(ai)(Bob) after applying the mask + * Our open port. */ - struct GNUNET_CRYPTO_PaillierCiphertext *e_a; + struct GNUNET_CADET_Port *port; /** - * Bob's permutation p of R + * b(Bob) */ - struct GNUNET_CRYPTO_PaillierCiphertext *r; - - /** - * Bob's permutation q of R - */ - struct GNUNET_CRYPTO_PaillierCiphertext *r_prime; - - /** - * Bob's "s" - */ - struct GNUNET_CRYPTO_PaillierCiphertext s; - - /** - * Bob's "s'" - */ - struct GNUNET_CRYPTO_PaillierCiphertext s_prime; + struct MpiElement *sorted_elements; /** - * Handle for our associated incoming CADET session, or NULL - * if we have not gotten one yet. + * Product of the g_i^{b_i} */ - struct CadetIncomingSession *cadet; + gcry_mpi_point_t prod_g_i_b_i; /** - * The computed scalar + * Product of the h_i^{b_i} */ - gcry_mpi_t product; + gcry_mpi_point_t prod_h_i_b_i; /** * How many elements will be supplied in total from the client. @@ -168,12 +136,6 @@ struct BobServiceSession */ uint32_t cadet_received_element_count; - /** - * Counts the number of values transmitted from us to Alice. - * Always less than @e used_element_count. - */ - uint32_t cadet_transmitted_element_count; - /** * State of this session. In * #GNUNET_SCALARPRODUCT_STATUS_ACTIVE while operation is @@ -187,20 +149,6 @@ struct BobServiceSession */ int in_destroy; -}; - - -/** - * An incoming session from CADET. - */ -struct CadetIncomingSession -{ - - /** - * Associated client session, or NULL. - */ - struct BobServiceSession *s; - /** * The CADET channel. */ @@ -216,28 +164,11 @@ struct CadetIncomingSession */ struct GNUNET_HashCode session_id; - /** - * Public key of the remote service. - */ - struct GNUNET_CRYPTO_PaillierPublicKey remote_pubkey; - /** * The message queue for this channel. */ struct GNUNET_MQ_Handle *cadet_mq; - /** - * Has this CADET session been added to the map yet? - * #GNUNET_YES if so, in which case @e session_id is - * the key. - */ - int in_map; - - /** - * Are we already in #destroy_cadet_session()? - */ - int in_destroy; - }; @@ -246,65 +177,15 @@ struct CadetIncomingSession */ static const struct GNUNET_CONFIGURATION_Handle *cfg; -/** - * Service's own public key - */ -static struct GNUNET_CRYPTO_PaillierPublicKey my_pubkey; - -/** - * Service's own private key - */ -static struct GNUNET_CRYPTO_PaillierPrivateKey my_privkey; - -/** - * Service's offset for values that could possibly be negative but are plaintext for encryption. - */ -static gcry_mpi_t my_offset; - -/** - * Map of `struct BobServiceSession`, by session keys. - */ -static struct GNUNET_CONTAINER_MultiHashMap *client_sessions; - -/** - * Map of `struct CadetIncomingSession`, by session keys. - */ -static struct GNUNET_CONTAINER_MultiHashMap *cadet_sessions; - /** * Handle to the CADET service. */ static struct GNUNET_CADET_Handle *my_cadet; - - -/** - * Finds a not terminated client session in the respective map based on - * session key. - * - * @param key the session key we want to search for - * @return the matching session, or NULL for none - */ -static struct BobServiceSession * -find_matching_client_session (const struct GNUNET_HashCode *key) -{ - return GNUNET_CONTAINER_multihashmap_get (client_sessions, - key); -} - - /** - * Finds a CADET session in the respective map based on session key. - * - * @param key the session key we want to search for - * @return the matching session, or NULL for none + * Context for DLOG operations on a curve. */ -static struct CadetIncomingSession * -find_matching_cadet_session (const struct GNUNET_HashCode *key) -{ - return GNUNET_CONTAINER_multihashmap_get (cadet_sessions, - key); -} +static struct GNUNET_CRYPTO_EccDlogContext *edc; /** @@ -326,15 +207,6 @@ free_element_cb (void *cls, } -/** - * Destroy session state, we are done with it. - * - * @param session the session to free elements from - */ -static void -destroy_cadet_session (struct CadetIncomingSession *s); - - /** * Destroy session state, we are done with it. * @@ -343,31 +215,18 @@ destroy_cadet_session (struct CadetIncomingSession *s); static void destroy_service_session (struct BobServiceSession *s) { - struct CadetIncomingSession *in; unsigned int i; if (GNUNET_YES == s->in_destroy) return; s->in_destroy = GNUNET_YES; - if (NULL != (in = s->cadet)) - { - s->cadet = NULL; - destroy_cadet_session (in); - } - if (NULL != s->client_mq) - { - GNUNET_MQ_destroy (s->client_mq); - s->client_mq = NULL; - } if (NULL != s->client) { - GNUNET_SERVER_client_disconnect (s->client); + struct GNUNET_SERVICE_Client *c = s->client; + s->client = NULL; + GNUNET_SERVICE_client_drop (c); } - GNUNET_assert (GNUNET_YES == - GNUNET_CONTAINER_multihashmap_remove (client_sessions, - &s->session_id, - s)); if (NULL != s->intersected_elements) { GNUNET_CONTAINER_multihashmap_iterate (s->intersected_elements, @@ -386,11 +245,6 @@ destroy_service_session (struct BobServiceSession *s) GNUNET_SET_destroy (s->intersection_set); s->intersection_set = NULL; } - if (NULL != s->e_a) - { - GNUNET_free (s->e_a); - s->e_a = NULL; - } if (NULL != s->sorted_elements) { for (i=0;iused_element_count;i++) @@ -398,62 +252,27 @@ destroy_service_session (struct BobServiceSession *s) GNUNET_free (s->sorted_elements); s->sorted_elements = NULL; } - if (NULL != s->r) + if (NULL != s->prod_g_i_b_i) { - GNUNET_free (s->r); - s->r = NULL; + gcry_mpi_point_release (s->prod_g_i_b_i); + s->prod_g_i_b_i = NULL; } - if (NULL != s->r_prime) + if (NULL != s->prod_h_i_b_i) { - GNUNET_free (s->r_prime); - s->r_prime = NULL; + gcry_mpi_point_release (s->prod_h_i_b_i); + s->prod_h_i_b_i = NULL; } - if (NULL != s->product) + if (NULL != s->port) { - gcry_mpi_release (s->product); - s->product = NULL; + GNUNET_CADET_close_port (s->port); + s->port = NULL; } - GNUNET_free (s); -} - - -/** - * Destroy incoming CADET session state, we are done with it. - * - * @param in the session to free elements from - */ -static void -destroy_cadet_session (struct CadetIncomingSession *in) -{ - struct BobServiceSession *s; - - if (GNUNET_YES == in->in_destroy) - return; - in->in_destroy = GNUNET_YES; - if (NULL != (s = in->s)) - { - in->s = NULL; - destroy_service_session (s); - } - if (GNUNET_YES == in->in_map) - { - GNUNET_assert (GNUNET_YES == - GNUNET_CONTAINER_multihashmap_remove (cadet_sessions, - &in->session_id, - in)); - in->in_map = GNUNET_NO; - } - if (NULL != in->cadet_mq) + if (NULL != s->channel) { - GNUNET_MQ_destroy (in->cadet_mq); - in->cadet_mq = NULL; + GNUNET_CADET_channel_destroy (s->channel); + s->channel = NULL; } - if (NULL != in->channel) - { - GNUNET_CADET_channel_destroy (in->channel); - in->channel = NULL; - } - GNUNET_free (in); + GNUNET_free (s); } @@ -470,6 +289,8 @@ prepare_client_end_notification (struct BobServiceSession *session) struct ClientResponseMessage *msg; struct GNUNET_MQ_Envelope *e; + if (NULL == session->client_mq) + return; /* no client left to be notified */ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending session-end notification with status %d to client for session %s\n", session->status, @@ -490,38 +311,28 @@ prepare_client_end_notification (struct BobServiceSession *session) * * It must NOT call #GNUNET_CADET_channel_destroy() on the channel. * - * @param cls closure (set from #GNUNET_CADET_connect()) + * @param cls the `struct BobServiceSession` * @param channel connection to the other end (henceforth invalid) * @param channel_ctx place where local state associated * with the channel is stored */ static void cb_channel_destruction (void *cls, - const struct GNUNET_CADET_Channel *channel, - void *channel_ctx) + const struct GNUNET_CADET_Channel *channel) { - struct CadetIncomingSession *in = channel_ctx; - struct BobServiceSession *s; + struct BobServiceSession *s = cls; GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Peer disconnected, terminating session %s with peer %s\n", - GNUNET_h2s (&in->session_id), - GNUNET_i2s (&in->peer)); - if (NULL != in->cadet_mq) - { - GNUNET_MQ_destroy (in->cadet_mq); - in->cadet_mq = NULL; - } - in->channel = NULL; - if (NULL != (s = in->s)) + GNUNET_h2s (&s->session_id), + GNUNET_i2s (&s->peer)); + s->channel = NULL; + if (GNUNET_SCALARPRODUCT_STATUS_ACTIVE == s->status) { - if (GNUNET_SCALARPRODUCT_STATUS_ACTIVE == s->status) - { - s->status = GNUNET_SCALARPRODUCT_STATUS_FAILURE; - prepare_client_end_notification (s); - } + s->status = GNUNET_SCALARPRODUCT_STATUS_FAILURE; + prepare_client_end_notification (s); } - destroy_cadet_session (in); + destroy_service_session (s); } @@ -540,306 +351,34 @@ bob_cadet_done_cb (void *cls) /** - * Maximum count of elements we can put into a multipart message - */ -#define ELEMENT_CAPACITY ((GNUNET_CONSTANTS_MAX_CADET_MESSAGE_SIZE - 1 - sizeof (struct BobCryptodataMultipartMessage)) / sizeof (struct GNUNET_CRYPTO_PaillierCiphertext)) - - -/** - * Send a multipart chunk of a service response from Bob to Alice. - * This element only contains the two permutations of R, R'. - * - * @param s the associated service session - */ -static void -transmit_bobs_cryptodata_message_multipart (struct BobServiceSession *s) -{ - struct GNUNET_CRYPTO_PaillierCiphertext *payload; - struct BobCryptodataMultipartMessage *msg; - struct GNUNET_MQ_Envelope *e; - unsigned int i; - unsigned int j; - uint32_t todo_count; - - while (s->cadet_transmitted_element_count != s->used_element_count) - { - todo_count = s->used_element_count - s->cadet_transmitted_element_count; - if (todo_count > ELEMENT_CAPACITY / 2) - todo_count = ELEMENT_CAPACITY / 2; - - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Sending %u additional crypto values to Alice\n", - (unsigned int) todo_count); - e = GNUNET_MQ_msg_extra (msg, - todo_count * sizeof (struct GNUNET_CRYPTO_PaillierCiphertext) * 2, - GNUNET_MESSAGE_TYPE_SCALARPRODUCT_BOB_CRYPTODATA_MULTIPART); - msg->contained_element_count = htonl (todo_count); - payload = (struct GNUNET_CRYPTO_PaillierCiphertext *) &msg[1]; - for (i = s->cadet_transmitted_element_count, j = 0; i < s->cadet_transmitted_element_count + todo_count; i++) - { - //r[i][p] and r[i][q] - memcpy (&payload[j++], - &s->r[i], - sizeof (struct GNUNET_CRYPTO_PaillierCiphertext)); - memcpy (&payload[j++], - &s->r_prime[i], - sizeof (struct GNUNET_CRYPTO_PaillierCiphertext)); - } - s->cadet_transmitted_element_count += todo_count; - if (s->cadet_transmitted_element_count == s->used_element_count) - GNUNET_MQ_notify_sent (e, - &bob_cadet_done_cb, - s); - GNUNET_MQ_send (s->cadet->cadet_mq, - e); - } - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "All values queued for Alice, Bob is done\n"); -} - - -/** - * 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)$ + * Bob generates the response message to be sent to Alice. * * @param s the associated requesting session with Alice */ static void transmit_bobs_cryptodata_message (struct BobServiceSession *s) { - struct BobCryptodataMessage *msg; + struct EccBobCryptodataMessage *msg; struct GNUNET_MQ_Envelope *e; - struct GNUNET_CRYPTO_PaillierCiphertext *payload; - unsigned int i; - - s->cadet_transmitted_element_count - = ((GNUNET_CONSTANTS_MAX_CADET_MESSAGE_SIZE - 1 - sizeof (struct BobCryptodataMessage)) - / sizeof (struct GNUNET_CRYPTO_PaillierCiphertext) / 2) - 1; - if (s->cadet_transmitted_element_count > s->used_element_count) - s->cadet_transmitted_element_count = s->used_element_count; - - e = GNUNET_MQ_msg_extra (msg, - (2 + s->cadet_transmitted_element_count * 2) - * sizeof (struct GNUNET_CRYPTO_PaillierCiphertext), - GNUNET_MESSAGE_TYPE_SCALARPRODUCT_BOB_CRYPTODATA); - msg->contained_element_count = htonl (s->cadet_transmitted_element_count); GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Sending %u/%u crypto values to Alice\n", - (unsigned int) s->cadet_transmitted_element_count, - (unsigned int) s->used_element_count); - - payload = (struct GNUNET_CRYPTO_PaillierCiphertext *) &msg[1]; - memcpy (&payload[0], - &s->s, - sizeof (struct GNUNET_CRYPTO_PaillierCiphertext)); - memcpy (&payload[1], - &s->s_prime, - sizeof (struct GNUNET_CRYPTO_PaillierCiphertext)); - - payload = &payload[2]; - // convert k[][] - for (i = 0; i < s->cadet_transmitted_element_count; i++) - { - //k[i][p] and k[i][q] - memcpy (&payload[i * 2], - &s->r[i], - sizeof (struct GNUNET_CRYPTO_PaillierCiphertext)); - memcpy (&payload[i * 2 + 1], - &s->r_prime[i], - sizeof (struct GNUNET_CRYPTO_PaillierCiphertext)); - } - if (s->cadet_transmitted_element_count == s->used_element_count) - GNUNET_MQ_notify_sent (e, - &bob_cadet_done_cb, - s); - GNUNET_MQ_send (s->cadet->cadet_mq, + "Sending response to Alice\n"); + e = GNUNET_MQ_msg (msg, + GNUNET_MESSAGE_TYPE_SCALARPRODUCT_ECC_BOB_CRYPTODATA); + msg->contained_element_count = htonl (2); + if (NULL != s->prod_g_i_b_i) + GNUNET_CRYPTO_ecc_point_to_bin (edc, + s->prod_g_i_b_i, + &msg->prod_g_i_b_i); + if (NULL != s->prod_h_i_b_i) + GNUNET_CRYPTO_ecc_point_to_bin (edc, + s->prod_h_i_b_i, + &msg->prod_h_i_b_i); + GNUNET_MQ_notify_sent (e, + &bob_cadet_done_cb, + s); + GNUNET_MQ_send (s->cadet_mq, e); - transmit_bobs_cryptodata_message_multipart (s); -} -#undef ELEMENT_CAPACITY - - -/** - * Computes the square sum over a vector of a given length. - * - * @param vector the vector to compute over - * @param length the length of the vector - * @return an MPI value containing the calculated sum, never NULL - * TODO: code duplication with Alice! - */ -static gcry_mpi_t -compute_square_sum (const gcry_mpi_t *vector, - uint32_t length) -{ - gcry_mpi_t elem; - gcry_mpi_t sum; - uint32_t i; - - GNUNET_assert (NULL != (sum = gcry_mpi_new (0))); - GNUNET_assert (NULL != (elem = gcry_mpi_new (0))); - for (i = 0; i < length; i++) - { - gcry_mpi_mul (elem, vector[i], vector[i]); - gcry_mpi_add (sum, sum, elem); - } - gcry_mpi_release (elem); - return sum; -} - - -/** - * 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)$ - * - * @param request the requesting session + bob's requesting peer - * @return #GNUNET_OK on success - */ -static int -compute_service_response (struct BobServiceSession *session) -{ - uint32_t i; - unsigned int *p; - unsigned int *q; - uint32_t count; - gcry_mpi_t *rand; - gcry_mpi_t tmp; - const struct MpiElement *b; - struct GNUNET_CRYPTO_PaillierCiphertext *a; - struct GNUNET_CRYPTO_PaillierCiphertext *r; - struct GNUNET_CRYPTO_PaillierCiphertext *r_prime; - - count = session->used_element_count; - a = session->e_a; - b = session->sorted_elements; - q = GNUNET_CRYPTO_random_permute (GNUNET_CRYPTO_QUALITY_WEAK, - count); - p = GNUNET_CRYPTO_random_permute (GNUNET_CRYPTO_QUALITY_WEAK, - count); - rand = GNUNET_malloc (sizeof (gcry_mpi_t) * count); - for (i = 0; i < count; i++) - GNUNET_assert (NULL != (rand[i] = gcry_mpi_new (0))); - r = GNUNET_malloc (sizeof (struct GNUNET_CRYPTO_PaillierCiphertext) * count); - r_prime = GNUNET_malloc (sizeof (struct GNUNET_CRYPTO_PaillierCiphertext) * count); - - for (i = 0; i < count; i++) - { - int32_t svalue; - - svalue = (int32_t) GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK, - UINT32_MAX); - // long to gcry_mpi_t - if (svalue < 0) - gcry_mpi_sub_ui (rand[i], - rand[i], - - svalue); - else - rand[i] = gcry_mpi_set_ui (rand[i], svalue); - } - - tmp = gcry_mpi_new (0); - // encrypt the element - // for the sake of readability I decided to have dedicated permutation - // vectors, which get rid of all the lookups in p/q. - // however, ap/aq are not absolutely necessary but are just abstraction - // Calculate Kp = E(S + a_pi) (+) E(S - r_pi - b_pi) - for (i = 0; i < count; i++) - { - // E(S - r_pi - b_pi) - gcry_mpi_sub (tmp, my_offset, rand[p[i]]); - gcry_mpi_sub (tmp, tmp, b[p[i]].value); - GNUNET_assert (2 == - GNUNET_CRYPTO_paillier_encrypt (&session->cadet->remote_pubkey, - tmp, - 2, - &r[i])); - - // E(S - r_pi - b_pi) * E(S + a_pi) == E(2*S + a - r - b) - if (GNUNET_OK != - GNUNET_CRYPTO_paillier_hom_add (&session->cadet->remote_pubkey, - &r[i], - &a[p[i]], - &r[i])) - { - GNUNET_break_op (0); - goto error_cleanup; - } - } - - // Calculate Kq = E(S + a_qi) (+) E(S - r_qi) - for (i = 0; i < count; i++) - { - // E(S - r_qi) - gcry_mpi_sub (tmp, my_offset, rand[q[i]]); - GNUNET_assert (2 == - GNUNET_CRYPTO_paillier_encrypt (&session->cadet->remote_pubkey, - tmp, - 2, - &r_prime[i])); - - // E(S - r_qi) * E(S + a_qi) == E(2*S + a_qi - r_qi) - if (GNUNET_OK != - GNUNET_CRYPTO_paillier_hom_add (&session->cadet->remote_pubkey, - &r_prime[i], - &a[q[i]], - &r_prime[i])) - { - GNUNET_break_op (0); - goto error_cleanup; - } - } - gcry_mpi_release (tmp); - - // Calculate S' = E(SUM( r_i^2 )) - tmp = compute_square_sum (rand, count); - GNUNET_assert (1 == - GNUNET_CRYPTO_paillier_encrypt (&session->cadet->remote_pubkey, - tmp, - 1, - &session->s_prime)); - gcry_mpi_release (tmp); - - // Calculate S = E(SUM( (r_i + b_i)^2 )) - for (i = 0; i < count; i++) - gcry_mpi_add (rand[i], rand[i], b[i].value); - tmp = compute_square_sum (rand, count); - GNUNET_assert (1 == - GNUNET_CRYPTO_paillier_encrypt (&session->cadet->remote_pubkey, - tmp, - 1, - &session->s)); - gcry_mpi_release (tmp); - - session->r = r; - session->r_prime = r_prime; - - for (i = 0; i < count; i++) - gcry_mpi_release (rand[i]); - GNUNET_free (session->e_a); - session->e_a = NULL; - GNUNET_free (p); - GNUNET_free (q); - GNUNET_free (rand); - return GNUNET_OK; - - error_cleanup: - GNUNET_free (r); - GNUNET_free (r_prime); - gcry_mpi_release (tmp); - GNUNET_free (p); - GNUNET_free (q); - for (i = 0; i < count; i++) - gcry_mpi_release (rand[i]); - GNUNET_free (rand); - return GNUNET_SYSERR; } @@ -896,93 +435,36 @@ element_cmp (const void *a, /** - * Intersection operation and receiving data via CADET from - * Alice are both done, compute and transmit our reply via - * CADET. - * - * @param s session to transmit reply for. - */ -static void -transmit_cryptographic_reply (struct BobServiceSession *s) -{ - struct GNUNET_CADET_Channel *channel; - - /* TODO: code duplication with Alice! */ - LOG (GNUNET_ERROR_TYPE_DEBUG, - "Received everything, building reply for Alice\n"); - s->sorted_elements - = GNUNET_malloc (GNUNET_CONTAINER_multihashmap_size (s->intersected_elements) * - sizeof (struct MpiElement)); - s->used_element_count = 0; - GNUNET_CONTAINER_multihashmap_iterate (s->intersected_elements, - ©_element_cb, - s); - qsort (s->sorted_elements, - s->used_element_count, - sizeof (struct MpiElement), - &element_cmp); - if (GNUNET_OK != - compute_service_response (s)) - { - channel = s->cadet->channel; - s->cadet->channel = NULL; - GNUNET_CADET_channel_destroy (channel); - return; - } - transmit_bobs_cryptodata_message (s); -} - - -/** - * Handle a multipart-chunk of a request from another service to + * Check a multipart-chunk of a request from another service to * calculate a scalarproduct with us. * * @param cls closure (set from #GNUNET_CADET_connect) - * @param channel connection to the other end - * @param channel_ctx place to store local state associated with the @a channel - * @param message the actual message + * @param msg the actual message * @return #GNUNET_OK to keep the connection open, * #GNUNET_SYSERR to close it (signal serious error) */ static int -handle_alices_cryptodata_message (void *cls, - struct GNUNET_CADET_Channel *channel, - void **channel_ctx, - const struct GNUNET_MessageHeader *message) +check_alices_cryptodata_message (void *cls, + const struct EccAliceCryptodataMessage *msg) { - struct CadetIncomingSession *in = *channel_ctx; - struct BobServiceSession *s; - const struct AliceCryptodataMessage *msg; - const struct GNUNET_CRYPTO_PaillierCiphertext *payload; + struct BobServiceSession *s = cls; uint32_t contained_elements; size_t msg_length; uint16_t msize; unsigned int max; - if (NULL == in) + msize = ntohs (msg->header.size); + if (msize <= sizeof (struct EccAliceCryptodataMessage)) { GNUNET_break_op (0); return GNUNET_SYSERR; } - s = in->s; - if (NULL == s) - { - GNUNET_break_op (0); - return GNUNET_SYSERR; - } - msize = ntohs (message->size); - if (msize <= sizeof (struct AliceCryptodataMessage)) - { - GNUNET_break_op (0); - return GNUNET_SYSERR; - } - msg = (const struct AliceCryptodataMessage *) message; contained_elements = ntohl (msg->contained_element_count); /* Our intersection may still be ongoing, but this is nevertheless an upper bound on the required array size */ max = GNUNET_CONTAINER_multihashmap_size (s->intersected_elements); - msg_length = sizeof (struct AliceCryptodataMessage) - + contained_elements * sizeof (struct GNUNET_CRYPTO_PaillierCiphertext); + msg_length = sizeof (struct EccAliceCryptodataMessage) + + contained_elements * sizeof (struct GNUNET_CRYPTO_EccPoint) * 2; if ( (msize != msg_length) || (0 == contained_elements) || (contained_elements > UINT16_MAX) || @@ -991,29 +473,104 @@ handle_alices_cryptodata_message (void *cls, GNUNET_break_op (0); return GNUNET_SYSERR; } + return GNUNET_OK; +} + + +/** + * Handle a multipart-chunk of a request from another service to + * calculate a scalarproduct with us. + * + * @param cls closure (set from #GNUNET_CADET_connect) + * @param msg the actual message + */ +static void +handle_alices_cryptodata_message (void *cls, + const struct EccAliceCryptodataMessage *msg) +{ + struct BobServiceSession *s = cls; + const struct GNUNET_CRYPTO_EccPoint *payload; + uint32_t contained_elements; + unsigned int max; + unsigned int i; + const struct MpiElement *b_i; + gcry_mpi_point_t tmp; + gcry_mpi_point_t g_i; + gcry_mpi_point_t h_i; + gcry_mpi_point_t g_i_b_i; + gcry_mpi_point_t h_i_b_i; + + contained_elements = ntohl (msg->contained_element_count); + max = GNUNET_CONTAINER_multihashmap_size (s->intersected_elements); + /* sort our vector for the computation */ + if (NULL == s->sorted_elements) + { + s->sorted_elements + = GNUNET_new_array (GNUNET_CONTAINER_multihashmap_size (s->intersected_elements), + struct MpiElement); + s->used_element_count = 0; + GNUNET_CONTAINER_multihashmap_iterate (s->intersected_elements, + ©_element_cb, + s); + qsort (s->sorted_elements, + s->used_element_count, + sizeof (struct MpiElement), + &element_cmp); + } + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received %u crypto values from Alice\n", (unsigned int) contained_elements); + payload = (const struct GNUNET_CRYPTO_EccPoint *) &msg[1]; - payload = (const struct GNUNET_CRYPTO_PaillierCiphertext *) &msg[1]; - if (NULL == s->e_a) - s->e_a = GNUNET_malloc (sizeof (struct GNUNET_CRYPTO_PaillierCiphertext) * - max); - memcpy (&s->e_a[s->cadet_received_element_count], - payload, - sizeof (struct GNUNET_CRYPTO_PaillierCiphertext) * contained_elements); + for (i=0;isorted_elements[i + s->cadet_received_element_count]; + g_i = GNUNET_CRYPTO_ecc_bin_to_point (edc, + &payload[i * 2]); + g_i_b_i = GNUNET_CRYPTO_ecc_pmul_mpi (edc, + g_i, + b_i->value); + gcry_mpi_point_release (g_i); + h_i = GNUNET_CRYPTO_ecc_bin_to_point (edc, + &payload[i * 2 + 1]); + h_i_b_i = GNUNET_CRYPTO_ecc_pmul_mpi (edc, + h_i, + b_i->value); + gcry_mpi_point_release (h_i); + if (0 == i + s->cadet_received_element_count) + { + /* first iteration, nothing to add */ + s->prod_g_i_b_i = g_i_b_i; + s->prod_h_i_b_i = h_i_b_i; + } + else + { + /* further iterations, cummulate resulting value */ + tmp = GNUNET_CRYPTO_ecc_add (edc, + s->prod_g_i_b_i, + g_i_b_i); + gcry_mpi_point_release (s->prod_g_i_b_i); + gcry_mpi_point_release (g_i_b_i); + s->prod_g_i_b_i = tmp; + tmp = GNUNET_CRYPTO_ecc_add (edc, + s->prod_h_i_b_i, + h_i_b_i); + gcry_mpi_point_release (s->prod_h_i_b_i); + gcry_mpi_point_release (h_i_b_i); + s->prod_h_i_b_i = tmp; + } + } s->cadet_received_element_count += contained_elements; - if ( (s->cadet_received_element_count == max) && (NULL == s->intersection_op) ) { /* intersection has finished also on our side, and we got the full set, so we can proceed with the CADET response(s) */ - transmit_cryptographic_reply (s); + transmit_bobs_cryptodata_message (s); } - GNUNET_CADET_receive_done (s->cadet->channel); - return GNUNET_OK; + GNUNET_CADET_receive_done (s->channel); } @@ -1023,11 +580,13 @@ handle_alices_cryptodata_message (void *cls, * * @param cls closure with the `struct BobServiceSession` * @param element a result element, only valid if status is #GNUNET_SET_STATUS_OK + * @param current_size current set size * @param status what has happened with the set intersection? */ static void cb_intersection_element_removed (void *cls, const struct GNUNET_SET_Element *element, + uint64_t current_size, enum GNUNET_SET_Status status) { struct BobServiceSession *s = cls; @@ -1053,7 +612,7 @@ cb_intersection_element_removed (void *cls, case GNUNET_SET_STATUS_DONE: s->intersection_op = NULL; GNUNET_break (NULL == s->intersection_set); - GNUNET_CADET_receive_done (s->cadet->channel); + GNUNET_CADET_receive_done (s->channel); LOG (GNUNET_ERROR_TYPE_DEBUG, "Finished intersection, %d items remain\n", GNUNET_CONTAINER_multihashmap_size (s->intersected_elements)); @@ -1062,7 +621,7 @@ cb_intersection_element_removed (void *cls, { /* CADET transmission from Alice is also already done, start with our own reply */ - transmit_cryptographic_reply (s); + transmit_bobs_cryptodata_message (s); } return; case GNUNET_SET_STATUS_HALF_DONE: @@ -1098,16 +657,22 @@ cb_intersection_element_removed (void *cls, static void start_intersection (struct BobServiceSession *s) { + struct GNUNET_HashCode set_sid; + + GNUNET_CRYPTO_hash (&s->session_id, + sizeof (struct GNUNET_HashCode), + &set_sid); GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Got session with key %s and %u elements, starting intersection.\n", GNUNET_h2s (&s->session_id), (unsigned int) s->total); s->intersection_op - = GNUNET_SET_prepare (&s->cadet->peer, - &s->session_id, + = GNUNET_SET_prepare (&s->peer, + &set_sid, NULL, GNUNET_SET_RESULT_REMOVED, + (struct GNUNET_SET_Option[]) {{ 0 }}, &cb_intersection_element_removed, s); if (GNUNET_OK != @@ -1128,59 +693,24 @@ start_intersection (struct BobServiceSession *s) * Handle a request from Alice to calculate a scalarproduct with us (Bob). * * @param cls closure (set from #GNUNET_CADET_connect) - * @param channel connection to the other end - * @param channel_ctx place to store the `struct CadetIncomingSession *` - * @param message the actual message - * @return #GNUNET_OK to keep the connection open, - * #GNUNET_SYSERR to close it (signal serious error) + * @param msg the actual message */ -static int +static void handle_alices_computation_request (void *cls, - struct GNUNET_CADET_Channel *channel, - void **channel_ctx, - const struct GNUNET_MessageHeader *message) + const struct EccServiceRequestMessage *msg) { - struct CadetIncomingSession *in = *channel_ctx; - struct BobServiceSession *s; - const struct ServiceRequestMessage *msg; + struct BobServiceSession *s = cls; - if (ntohs (message->size) != sizeof (struct ServiceRequestMessage)) + s->session_id = msg->session_id; // ?? + if (s->client_received_element_count < s->total) { - GNUNET_break_op (0); - return GNUNET_SYSERR; - } - msg = (const struct ServiceRequestMessage *) message; - if (GNUNET_YES == in->in_map) - { - GNUNET_break_op (0); - return GNUNET_SYSERR; - } - if (NULL != find_matching_cadet_session (&msg->session_id)) - { - /* not unique, got one like this already */ - GNUNET_break_op (0); - return GNUNET_SYSERR; - } - in->session_id = msg->session_id; - in->remote_pubkey = msg->public_key; - GNUNET_assert (GNUNET_YES == - GNUNET_CONTAINER_multihashmap_put (cadet_sessions, - &in->session_id, - in, - GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY)); - s = find_matching_client_session (&in->session_id); - if (NULL == s) - { - /* no client waiting for this request, wait for client */ - return GNUNET_OK; + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Alice ready, still waiting for Bob client data!\n"); + return; } - GNUNET_assert (NULL == s->cadet); - /* pair them up */ - in->s = s; - s->cadet = in; - if (s->client_received_element_count == s->total) - start_intersection (s); - return GNUNET_OK; + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Both ready, launching intersection!\n"); + start_intersection (s); } @@ -1189,76 +719,47 @@ handle_alices_computation_request (void *cls, * preliminary initialization, more happens after we get Alice's first * message. * - * @param cls closure + * @param cls our `struct BobServiceSession` * @param channel new handle to the channel * @param initiator peer that started the channel - * @param port unused - * @param options unused * @return session associated with the channel */ static void * cb_channel_incoming (void *cls, struct GNUNET_CADET_Channel *channel, - const struct GNUNET_PeerIdentity *initiator, - uint32_t port, - enum GNUNET_CADET_ChannelOption options) + const struct GNUNET_PeerIdentity *initiator) { - struct CadetIncomingSession *in; + struct BobServiceSession *s = cls; GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "New incoming channel from peer %s.\n", GNUNET_i2s (initiator)); - in = GNUNET_new (struct CadetIncomingSession); - in->peer = *initiator; - in->channel = channel; - in->cadet_mq = GNUNET_CADET_mq_create (in->channel); - return in; + GNUNET_CADET_close_port (s->port); + s->port = NULL; + s->peer = *initiator; + s->channel = channel; + s->cadet_mq = GNUNET_CADET_get_mq (s->channel); + return s; } /** - * We're receiving additional set data. Add it to our - * set and if we are done, initiate the transaction. + * We're receiving additional set data. Check it is well-formed. * - * @param cls closure - * @param client identification of the client - * @param message the actual message + * @param cls identification of the client + * @param msg the actual message + * @return #GNUNET_OK if @a msg is well-formed */ -static void -GSS_handle_bob_client_message_multipart (void *cls, - struct GNUNET_SERVER_Client *client, - const struct GNUNET_MessageHeader *message) +static int +check_bob_client_message_multipart (void *cls, + const struct ComputationBobCryptodataMultipartMessage *msg) { - const struct ComputationBobCryptodataMultipartMessage * msg; - struct BobServiceSession *s; + struct BobServiceSession *s = cls; uint32_t contained_count; - const struct GNUNET_SCALARPRODUCT_Element *elements; - uint32_t i; uint16_t msize; - struct GNUNET_SET_Element set_elem; - struct GNUNET_SCALARPRODUCT_Element *elem; - s = GNUNET_SERVER_client_get_user_context (client, - struct BobServiceSession); - if (NULL == s) - { - /* session needs to already exist */ - GNUNET_break (0); - GNUNET_SERVER_receive_done (client, - GNUNET_SYSERR); - return; - } - msize = ntohs (message->size); - if (msize < sizeof (struct ComputationBobCryptodataMultipartMessage)) - { - GNUNET_break (0); - GNUNET_SERVER_receive_done (client, - GNUNET_SYSERR); - return; - } - msg = (const struct ComputationBobCryptodataMultipartMessage *) message; + msize = ntohs (msg->header.size); contained_count = ntohl (msg->element_count_contained); - if ( (msize != (sizeof (struct ComputationBobCryptodataMultipartMessage) + contained_count * sizeof (struct GNUNET_SCALARPRODUCT_Element))) || (0 == contained_count) || @@ -1266,18 +767,38 @@ GSS_handle_bob_client_message_multipart (void *cls, (s->total == s->client_received_element_count) || (s->total < s->client_received_element_count + contained_count) ) { - GNUNET_break_op (0); - GNUNET_SERVER_receive_done (client, - GNUNET_SYSERR); - return; + GNUNET_break (0); + return GNUNET_SYSERR; } + return GNUNET_OK; +} + + +/** + * We're receiving additional set data. Add it to our + * set and if we are done, initiate the transaction. + * + * @param cls identification of the client + * @param msg the actual message + */ +static void +handle_bob_client_message_multipart (void *cls, + const struct ComputationBobCryptodataMultipartMessage *msg) +{ + struct BobServiceSession *s = cls; + uint32_t contained_count; + const struct GNUNET_SCALARPRODUCT_Element *elements; + struct GNUNET_SET_Element set_elem; + struct GNUNET_SCALARPRODUCT_Element *elem; + + contained_count = ntohl (msg->element_count_contained); elements = (const struct GNUNET_SCALARPRODUCT_Element *) &msg[1]; - for (i = 0; i < contained_count; i++) + for (uint32_t i = 0; i < contained_count; i++) { elem = GNUNET_new (struct GNUNET_SCALARPRODUCT_Element); - memcpy (elem, - &elements[i], - sizeof (struct GNUNET_SCALARPRODUCT_Element)); + GNUNET_memcpy (elem, + &elements[i], + sizeof (struct GNUNET_SCALARPRODUCT_Element)); if (GNUNET_SYSERR == GNUNET_CONTAINER_multihashmap_put (s->intersected_elements, &elem->key, @@ -1296,67 +817,50 @@ GSS_handle_bob_client_message_multipart (void *cls, NULL, NULL); } s->client_received_element_count += contained_count; - GNUNET_SERVER_receive_done (client, - GNUNET_OK); + GNUNET_SERVICE_client_continue (s->client); if (s->total != s->client_received_element_count) { /* more to come */ + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Request still partial, waiting for more client data!\n"); return; } - if (NULL == s->cadet) + if (NULL == s->channel) { /* no Alice waiting for this request, wait for Alice */ + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Client ready, still waiting for Alice!\n"); return; } + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Both ready, launching intersection!\n"); start_intersection (s); } /** - * 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. + * Handler for Bob's a client request message. Check @a msg is + * well-formed. * - * @param cls closure - * @param client identification of the client - * @param message the actual message + * @param cls identification of the client + * @param msg the actual message + * @return #GNUNET_OK if @a msg is well-formed */ -static void -GSS_handle_bob_client_message (void *cls, - struct GNUNET_SERVER_Client *client, - const struct GNUNET_MessageHeader *message) +static int +check_bob_client_message (void *cls, + const struct BobComputationMessage *msg) { - const struct BobComputationMessage *msg; - struct BobServiceSession *s; - struct CadetIncomingSession *in; + struct BobServiceSession *s = cls; uint32_t contained_count; uint32_t total_count; - const struct GNUNET_SCALARPRODUCT_Element *elements; - uint32_t i; - struct GNUNET_SET_Element set_elem; - struct GNUNET_SCALARPRODUCT_Element *elem; uint16_t msize; - s = GNUNET_SERVER_client_get_user_context (client, - struct BobServiceSession); - if (NULL != s) - { - /* only one concurrent session per client connection allowed, - simplifies logic a lot... */ - GNUNET_break (0); - GNUNET_SERVER_receive_done (client, - GNUNET_SYSERR); - return; - } - msize = ntohs (message->size); - if (msize < sizeof (struct BobComputationMessage)) + if (GNUNET_SCALARPRODUCT_STATUS_INIT != s->status) { GNUNET_break (0); - GNUNET_SERVER_receive_done (client, - GNUNET_SYSERR); - return; + return GNUNET_SYSERR; } - msg = (const struct BobComputationMessage *) message; + msize = ntohs (msg->header.size); total_count = ntohl (msg->element_count_total); contained_count = ntohl (msg->element_count_contained); if ( (0 == total_count) || @@ -1366,41 +870,62 @@ GSS_handle_bob_client_message (void *cls, contained_count * sizeof (struct GNUNET_SCALARPRODUCT_Element))) ) { GNUNET_break_op (0); - GNUNET_SERVER_receive_done (client, - GNUNET_SYSERR); - return; - } - if (NULL != find_matching_client_session (&msg->session_key)) - { - GNUNET_break (0); - GNUNET_SERVER_receive_done (client, - GNUNET_SYSERR); - return; + return GNUNET_SYSERR; } + return GNUNET_OK; +} + + +/** + * 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. + * + * @param cls identification of the client + * @param msg the actual message + */ +static void +handle_bob_client_message (void *cls, + const struct BobComputationMessage *msg) +{ + struct BobServiceSession *s = cls; + struct GNUNET_MQ_MessageHandler cadet_handlers[] = { + GNUNET_MQ_hd_fixed_size (alices_computation_request, + GNUNET_MESSAGE_TYPE_SCALARPRODUCT_ECC_SESSION_INITIALIZATION, + struct EccServiceRequestMessage, + s), + GNUNET_MQ_hd_var_size (alices_cryptodata_message, + GNUNET_MESSAGE_TYPE_SCALARPRODUCT_ECC_ALICE_CRYPTODATA, + struct EccAliceCryptodataMessage, + s), + GNUNET_MQ_handler_end () + }; + uint32_t contained_count; + uint32_t total_count; + const struct GNUNET_SCALARPRODUCT_Element *elements; + struct GNUNET_SET_Element set_elem; + struct GNUNET_SCALARPRODUCT_Element *elem; + + total_count = ntohl (msg->element_count_total); + contained_count = ntohl (msg->element_count_contained); - s = GNUNET_new (struct BobServiceSession); s->status = GNUNET_SCALARPRODUCT_STATUS_ACTIVE; - s->client = client; - s->client_mq = GNUNET_MQ_queue_for_server_client (client); s->total = total_count; s->client_received_element_count = contained_count; s->session_id = msg->session_key; - GNUNET_break (GNUNET_YES == - GNUNET_CONTAINER_multihashmap_put (client_sessions, - &s->session_id, - s, - GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY)); elements = (const struct GNUNET_SCALARPRODUCT_Element *) &msg[1]; - s->intersected_elements = GNUNET_CONTAINER_multihashmap_create (s->total, - GNUNET_YES); - s->intersection_set = GNUNET_SET_create (cfg, - GNUNET_SET_OPERATION_INTERSECTION); - for (i = 0; i < contained_count; i++) + s->intersected_elements + = GNUNET_CONTAINER_multihashmap_create (s->total, + GNUNET_YES); + s->intersection_set + = GNUNET_SET_create (cfg, + GNUNET_SET_OPERATION_INTERSECTION); + for (uint32_t i = 0; i < contained_count; i++) { if (0 == GNUNET_ntohll (elements[i].value)) continue; elem = GNUNET_new (struct GNUNET_SCALARPRODUCT_Element); - memcpy (elem, + GNUNET_memcpy (elem, &elements[i], sizeof (struct GNUNET_SCALARPRODUCT_Element)); if (GNUNET_SYSERR == @@ -1421,26 +946,23 @@ GSS_handle_bob_client_message (void *cls, NULL, NULL); s->used_element_count++; } - GNUNET_SERVER_client_set_user_context (client, - s); - GNUNET_SERVER_receive_done (client, - GNUNET_YES); - if (s->total != s->client_received_element_count) - { - /* multipart msg */ - return; - } - in = find_matching_cadet_session (&s->session_id); - if (NULL == in) + GNUNET_SERVICE_client_continue (s->client); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Received client request, opening port %s!\n", + GNUNET_h2s (&msg->session_key)); + s->port = GNUNET_CADET_open_port (my_cadet, + &msg->session_key, + &cb_channel_incoming, + s, + NULL, + &cb_channel_destruction, + cadet_handlers); + if (NULL == s->port) { - /* nothing yet, wait for Alice */ + GNUNET_break (0); + GNUNET_SERVICE_client_drop (s->client); return; } - GNUNET_assert (NULL == in->s); - /* pair them up */ - in->s = s; - s->cadet = in; - start_intersection (s); } @@ -1448,11 +970,9 @@ GSS_handle_bob_client_message (void *cls, * Task run during shutdown. * * @param cls unused - * @param tc unused */ static void -shutdown_task (void *cls, - const struct GNUNET_SCHEDULER_TaskContext *tc) +shutdown_task (void *cls) { GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Shutting down, initiating cleanup.\n"); @@ -1462,10 +982,35 @@ shutdown_task (void *cls, GNUNET_CADET_disconnect (my_cadet); my_cadet = NULL; } - GNUNET_CONTAINER_multihashmap_destroy (client_sessions); - client_sessions = NULL; - GNUNET_CONTAINER_multihashmap_destroy (cadet_sessions); - cadet_sessions = NULL; + if (NULL != edc) + { + GNUNET_CRYPTO_ecc_dlog_release (edc); + edc = NULL; + } +} + + +/** + * A client connected. + * + * Setup the associated data structure. + * + * @param cls closure, NULL + * @param client identification of the client + * @param mq message queue to communicate with @a client + * @return our `struct BobServiceSession` + */ +static void * +client_connect_cb (void *cls, + struct GNUNET_SERVICE_Client *client, + struct GNUNET_MQ_Handle *mq) +{ + struct BobServiceSession *s; + + s = GNUNET_new (struct BobServiceSession); + s->client = client; + s->client_mq = mq; + return s; } @@ -1477,22 +1022,17 @@ shutdown_task (void *cls, * * @param cls closure, NULL * @param client identification of the client + * @param app_cls our `struct BobServiceSession` */ static void -handle_client_disconnect (void *cls, - struct GNUNET_SERVER_Client *client) +client_disconnect_cb (void *cls, + struct GNUNET_SERVICE_Client *client, + void *app_cls) { - struct BobServiceSession *s; + struct BobServiceSession *s = app_cls; - if (NULL == client) - return; GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Client disconnected from us.\n", - client); - s = GNUNET_SERVER_client_get_user_context (client, - struct BobServiceSession); - if (NULL == s) - return; + "Client disconnected from us.\n"); s->client = NULL; destroy_service_session (s); } @@ -1502,62 +1042,21 @@ handle_client_disconnect (void *cls, * Initialization of the program and message handlers * * @param cls closure - * @param server the initialized server * @param c configuration to use + * @param service the initialized service */ static void run (void *cls, - struct GNUNET_SERVER_Handle *server, - const struct GNUNET_CONFIGURATION_Handle *c) + const struct GNUNET_CONFIGURATION_Handle *c, + struct GNUNET_SERVICE_Handle *service) { - static const struct GNUNET_SERVER_MessageHandler server_handlers[] = { - { &GSS_handle_bob_client_message, NULL, - GNUNET_MESSAGE_TYPE_SCALARPRODUCT_CLIENT_TO_BOB, - 0}, - { &GSS_handle_bob_client_message_multipart, NULL, - GNUNET_MESSAGE_TYPE_SCALARPRODUCT_CLIENT_MUTLIPART_BOB, - 0}, - { NULL, NULL, 0, 0} - }; - static const struct GNUNET_CADET_MessageHandler cadet_handlers[] = { - { &handle_alices_computation_request, - GNUNET_MESSAGE_TYPE_SCALARPRODUCT_SESSION_INITIALIZATION, - sizeof (struct ServiceRequestMessage) }, - { &handle_alices_cryptodata_message, - GNUNET_MESSAGE_TYPE_SCALARPRODUCT_ALICE_CRYPTODATA, - 0}, - { NULL, 0, 0} - }; - static const uint32_t ports[] = { - GNUNET_APPLICATION_TYPE_SCALARPRODUCT, - 0 - }; - cfg = c; - /* - offset has to be sufficiently small to allow computation of: - m1+m2 mod n == (S + a) + (S + b) mod n, - if we have more complex operations, this factor needs to be lowered */ - my_offset = gcry_mpi_new (GNUNET_CRYPTO_PAILLIER_BITS / 3); - gcry_mpi_set_bit (my_offset, - GNUNET_CRYPTO_PAILLIER_BITS / 3); - - GNUNET_CRYPTO_paillier_create (&my_pubkey, - &my_privkey); - GNUNET_SERVER_add_handlers (server, - server_handlers); - GNUNET_SERVER_disconnect_notify (server, - &handle_client_disconnect, - NULL); - client_sessions = GNUNET_CONTAINER_multihashmap_create (128, - GNUNET_YES); - cadet_sessions = GNUNET_CONTAINER_multihashmap_create (128, - GNUNET_YES); - my_cadet = GNUNET_CADET_connect (cfg, NULL, - &cb_channel_incoming, - &cb_channel_destruction, - cadet_handlers, - ports); + /* We don't really do DLOG, so we can setup with very minimal resources */ + edc = GNUNET_CRYPTO_ecc_dlog_prepare (4 /* max value */, + 2 /* RAM */); + my_cadet = GNUNET_CADET_connect (cfg); + GNUNET_SCHEDULER_add_shutdown (&shutdown_task, + NULL); if (NULL == my_cadet) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, @@ -1565,28 +1064,28 @@ run (void *cls, GNUNET_SCHEDULER_shutdown (); return; } - GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL, - &shutdown_task, - NULL); } /** - * The main function for the scalarproduct service. - * - * @param argc number of arguments from the command line - * @param argv command line arguments - * @return 0 ok, 1 on error + * Define "main" method using service macro. */ -int -main (int argc, - char *const *argv) -{ - return (GNUNET_OK == - GNUNET_SERVICE_run (argc, argv, - "scalarproduct-bob", - GNUNET_SERVICE_OPTION_NONE, - &run, NULL)) ? 0 : 1; -} - -/* end of gnunet-service-scalarproduct_bob.c */ +GNUNET_SERVICE_MAIN +("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 ()); + + +/* end of gnunet-service-scalarproduct-ecc_bob.c */