From: Christian Grothoff Date: Sat, 5 Sep 2015 18:03:58 +0000 (+0000) Subject: -towards ECC variant of SP X-Git-Tag: initial-import-from-subversion-38251~1430 X-Git-Url: https://git.librecmc.org/?a=commitdiff_plain;h=14f9ba0d86025dfd2defb1635899c75da4815d16;p=oweals%2Fgnunet.git -towards ECC variant of SP --- diff --git a/src/scalarproduct/Makefile.am b/src/scalarproduct/Makefile.am index 13e1a00d2..c09e38393 100644 --- a/src/scalarproduct/Makefile.am +++ b/src/scalarproduct/Makefile.am @@ -60,7 +60,7 @@ gnunet_service_scalarproduct_bob_LDADD = \ $(GN_LIBINTL) gnunet_service_scalarproduct_ecc_alice_SOURCES = \ - gnunet-service-scalarproduct.h \ + gnunet-service-scalarproduct-ecc.h \ gnunet-service-scalarproduct-ecc_alice.c gnunet_service_scalarproduct_ecc_alice_LDADD = \ $(top_builddir)/src/util/libgnunetutil.la \ @@ -71,7 +71,7 @@ gnunet_service_scalarproduct_ecc_alice_LDADD = \ $(GN_LIBINTL) gnunet_service_scalarproduct_ecc_bob_SOURCES = \ - gnunet-service-scalarproduct.h \ + gnunet-service-scalarproduct-ecc.h \ gnunet-service-scalarproduct-ecc_bob.c gnunet_service_scalarproduct_ecc_bob_LDADD = \ $(top_builddir)/src/util/libgnunetutil.la \ diff --git a/src/scalarproduct/gnunet-service-scalarproduct-ecc.h b/src/scalarproduct/gnunet-service-scalarproduct-ecc.h new file mode 100644 index 000000000..0a222a208 --- /dev/null +++ b/src/scalarproduct/gnunet-service-scalarproduct-ecc.h @@ -0,0 +1,120 @@ +/* + This file is part of GNUnet. + Copyright (C) 2015 Christian Grothoff (and other contributing authors) + + GNUnet is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published + by the Free Software Foundation; either version 3, or (at your + option) any later version. + + GNUnet is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GNUnet; see the file COPYING. If not, write to the + Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. + */ +/** + * @file scalarproduct/gnunet-service-scalarproduct-ecc.h + * @brief scalarproduct service P2P messages + * @author Christian M. Fuchs + * @author Christian Grothoff + */ +#ifndef GNUNET_SERVICE_SCALARPRODUCT_ECC_H +#define GNUNET_SERVICE_SCALARPRODUCT_ECC_H + + +GNUNET_NETWORK_STRUCT_BEGIN + +/** + * Message type passed from requesting service Alice to responding + * service Bob to initiate a request and make Bob participate in our + * protocol. Afterwards, Bob is expected to perform the set + * intersection with Alice. Once that has succeeded, Alice will + * send a `struct AliceCryptodataMessage *`. Bob is not expected + * to respond via CADET in the meantime. + */ +struct EccServiceRequestMessage +{ + /** + * Type is #GNUNET_MESSAGE_TYPE_SCALARPRODUCT_ECC_SESSION_INITIALIZATION + */ + struct GNUNET_MessageHeader header; + + /** + * For alignment. Always zero. + */ + uint32_t reserved; + + /** + * The transaction/session key used to identify a session + */ + struct GNUNET_HashCode session_id; + +}; + + +/** + * Vector of ECC-encrypted values sent by Alice to Bob + * (after set intersection). Alice may send messages of this + * type repeatedly to transmit all values. + */ +struct EccAliceCryptodataMessage +{ + /** + * Type is #GNUNET_MESSAGE_TYPE_SCALARPRODUCT_ECC_ALICE_CRYPTODATA + */ + struct GNUNET_MessageHeader header; + + /** + * How many elements we appended to this message? In NBO. + */ + uint32_t contained_element_count GNUNET_PACKED; + + /** + * struct GNUNET_CRYPTO_EccPoint[contained_element_count] + */ +}; + + +/** + * Message type passed from responding service Bob to responding + * service Alice to complete a request and allow Alice to compute the + * result. If Bob's reply does not fit into this one message, the + * conversation may be continued with `struct BobCryptodataMultipartMessage` + * messages afterwards. + */ +struct EccBobCryptodataMessage +{ + /** + * GNUNET message header with type + * #GNUNET_MESSAGE_TYPE_SCALARPRODUCT_ECC_BOB_CRYPTODATA. + */ + struct GNUNET_MessageHeader header; + + /** + * How many elements this individual message delivers (in NBO), + * always TWO. + */ + uint32_t contained_element_count GNUNET_PACKED; + + /** + * The product of the g_i^{b_i} values. + */ + struct GNUNET_CRYPTO_EccPoint prod_g_i_b_i; + + /** + * The product of the h_i^{b_i} values. + */ + struct GNUNET_CRYPTO_EccPoint prod_h_i_b_i; + +}; + + +GNUNET_NETWORK_STRUCT_END + + +#endif diff --git a/src/scalarproduct/gnunet-service-scalarproduct-ecc_alice.c b/src/scalarproduct/gnunet-service-scalarproduct-ecc_alice.c index 565cc3104..773682234 100644 --- a/src/scalarproduct/gnunet-service-scalarproduct-ecc_alice.c +++ b/src/scalarproduct/gnunet-service-scalarproduct-ecc_alice.c @@ -1,6 +1,6 @@ /* This file is part of GNUnet. - Copyright (C) 2013, 2014 Christian Grothoff (and other contributing authors) + Copyright (C) 2013-2015 Christian Grothoff (and other contributing authors) 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_alice.c + * @file scalarproduct/gnunet-service-scalarproduct-ecc_alice.c * @brief scalarproduct service implementation * @author Christian M. Fuchs * @author Christian Grothoff @@ -34,10 +34,16 @@ #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-alice", __VA_ARGS__) +/** + * Maximum allowed result value for the scalarproduct computation. + * DLOG will fail if the result is bigger. + */ +#define MAX_RESULT (1024 * 1024) + /** * An encrypted element key-value pair. */ @@ -51,9 +57,15 @@ struct MpiElement const struct GNUNET_HashCode *key; /** - * Value represented (a). + * a_i value, not disclosed to Bob. */ gcry_mpi_t value; + + /** + * r_i value, chosen at random, not disclosed to Bob. + */ + gcry_mpi_t r_i; + }; @@ -122,26 +134,6 @@ struct AliceServiceSession */ struct MpiElement *sorted_elements; - /** - * Bob's permutation p of R - */ - 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; - /** * The computed scalar */ @@ -166,12 +158,6 @@ struct AliceServiceSession */ uint32_t client_received_element_count; - /** - * Already transferred elements from Bob to us. - * Less or equal than @e total. - */ - uint32_t cadet_received_element_count; - /** * State of this session. In * #GNUNET_SCALARPRODUCT_STATUS_ACTIVE while operation is @@ -195,19 +181,19 @@ struct AliceServiceSession static const struct GNUNET_CONFIGURATION_Handle *cfg; /** - * Service's own public key + * Context for DLOG operations on a curve. */ -static struct GNUNET_CRYPTO_PaillierPublicKey my_pubkey; +static struct GNUNET_CRYPTO_EccDlogContext *edc; /** - * Service's own private key + * Alice's private key ('a'). */ -static struct GNUNET_CRYPTO_PaillierPrivateKey my_privkey; +static gcry_mpi_t my_privkey; /** - * Service's offset for values that could possibly be negative but are plaintext for encryption. + * Inverse of Alice's private key ('a_inv'). */ -static gcry_mpi_t my_offset; +static gcry_mpi_t my_privkey_inv; /** * Handle to the CADET service. @@ -300,16 +286,6 @@ destroy_service_session (struct AliceServiceSession *s) GNUNET_free (s->sorted_elements); s->sorted_elements = NULL; } - if (NULL != s->r) - { - GNUNET_free (s->r); - s->r = NULL; - } - if (NULL != s->r_prime) - { - GNUNET_free (s->r_prime); - s->r_prime = NULL; - } if (NULL != s->product) { gcry_mpi_release (s->product); @@ -462,249 +438,42 @@ cb_channel_destruction (void *cls, } -/** - * 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 - */ -static gcry_mpi_t -compute_square_sum_mpi_elements (const struct MpiElement *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].value, vector[i].value); - gcry_mpi_add (sum, sum, elem); - } - gcry_mpi_release (elem); - return sum; -} - - -/** - * 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 - */ -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 our scalar product, done by Alice * * @param session the session associated with this computation + * @param prod_g_i_b_i value from Bob + * @param prod_h_i_b_i value from Bob * @return product as MPI, never NULL */ static gcry_mpi_t -compute_scalar_product (struct AliceServiceSession *session) +compute_scalar_product (struct AliceServiceSession *session, + gcry_mpi_point_t prod_g_i_b_i, + gcry_mpi_point_t prod_h_i_b_i) { - uint32_t count; - gcry_mpi_t t; - gcry_mpi_t u; - gcry_mpi_t u_prime; - gcry_mpi_t p; - gcry_mpi_t p_prime; - gcry_mpi_t tmp; - gcry_mpi_t r[session->used_element_count]; - gcry_mpi_t r_prime[session->used_element_count]; - gcry_mpi_t s; - gcry_mpi_t s_prime; - unsigned int i; - - count = session->used_element_count; - // due to the introduced static offset S, we now also have to remove this - // from the E(a_pi)(+)E(-b_pi-r_pi) and E(a_qi)(+)E(-r_qi) twice each, - // the result is E((S + a_pi) + (S -b_pi-r_pi)) and E(S + a_qi + S - r_qi) - for (i = 0; i < count; i++) + gcry_mpi_point_t g_i_b_i_a_inv; + gcry_mpi_point_t g_ai_bi; + int ai_bi; + gcry_mpi_t ret; + + g_i_b_i_a_inv = GNUNET_CRYPTO_ecc_pmul_mpi (edc, + prod_g_i_b_i, + my_privkey_inv); + g_ai_bi = GNUNET_CRYPTO_ecc_add (edc, + g_i_b_i_a_inv, + prod_h_i_b_i); + gcry_mpi_point_release (g_i_b_i_a_inv); + ai_bi = GNUNET_CRYPTO_ecc_dlog (edc, + g_ai_bi); + gcry_mpi_point_release (g_ai_bi); + if (MAX_RESULT == ai_bi) { - r[i] = gcry_mpi_new (0); - GNUNET_CRYPTO_paillier_decrypt (&my_privkey, - &my_pubkey, - &session->r[i], - r[i]); - gcry_mpi_sub (r[i], - r[i], - my_offset); - gcry_mpi_sub (r[i], - r[i], - my_offset); - r_prime[i] = gcry_mpi_new (0); - GNUNET_CRYPTO_paillier_decrypt (&my_privkey, - &my_pubkey, - &session->r_prime[i], - r_prime[i]); - gcry_mpi_sub (r_prime[i], - r_prime[i], - my_offset); - gcry_mpi_sub (r_prime[i], - r_prime[i], - my_offset); + /* result too big */ + return NULL; } - - // calculate t = sum(ai) - t = compute_square_sum_mpi_elements (session->sorted_elements, - count); - // calculate U - u = gcry_mpi_new (0); - tmp = compute_square_sum (r, count); - gcry_mpi_sub (u, u, tmp); - gcry_mpi_release (tmp); - - //calculate U' - u_prime = gcry_mpi_new (0); - tmp = compute_square_sum (r_prime, count); - gcry_mpi_sub (u_prime, u_prime, tmp); - - GNUNET_assert (p = gcry_mpi_new (0)); - GNUNET_assert (p_prime = gcry_mpi_new (0)); - GNUNET_assert (s = gcry_mpi_new (0)); - GNUNET_assert (s_prime = gcry_mpi_new (0)); - - // compute P - GNUNET_CRYPTO_paillier_decrypt (&my_privkey, - &my_pubkey, - &session->s, - s); - GNUNET_CRYPTO_paillier_decrypt (&my_privkey, - &my_pubkey, - &session->s_prime, - s_prime); - - // compute P - gcry_mpi_add (p, s, t); - gcry_mpi_add (p, p, u); - - // compute P' - gcry_mpi_add (p_prime, s_prime, t); - gcry_mpi_add (p_prime, p_prime, u_prime); - - gcry_mpi_release (t); - gcry_mpi_release (u); - gcry_mpi_release (u_prime); - gcry_mpi_release (s); - gcry_mpi_release (s_prime); - - // compute product - gcry_mpi_sub (p, p, p_prime); - gcry_mpi_release (p_prime); - tmp = gcry_mpi_set_ui (tmp, 2); - gcry_mpi_div (p, NULL, p, tmp, 0); - - gcry_mpi_release (tmp); - for (i = 0; i < count; i++) - { - gcry_mpi_release (session->sorted_elements[i].value); - gcry_mpi_release (r[i]); - gcry_mpi_release (r_prime[i]); - } - GNUNET_free (session->sorted_elements); - session->sorted_elements = NULL; - GNUNET_free (session->r); - session->r = NULL; - GNUNET_free (session->r_prime); - session->r_prime = NULL; - - return p; -} - - -/** - * Handle a multipart chunk of a response we got from another service - * we wanted to calculate a scalarproduct with. - * - * @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 - * @return #GNUNET_OK to keep the connection open, - * #GNUNET_SYSERR to close it (signal serious error) - */ -static int -handle_bobs_cryptodata_multipart (void *cls, - struct GNUNET_CADET_Channel *channel, - void **channel_ctx, - const struct GNUNET_MessageHeader *message) -{ - struct AliceServiceSession *s = *channel_ctx; - const struct BobCryptodataMultipartMessage *msg; - const struct GNUNET_CRYPTO_PaillierCiphertext *payload; - size_t i; - uint32_t contained; - size_t msg_size; - size_t required_size; - - if (NULL == s) - { - GNUNET_break_op (0); - return GNUNET_SYSERR; - } - msg_size = ntohs (message->size); - if (sizeof (struct BobCryptodataMultipartMessage) > msg_size) - { - GNUNET_break_op (0); - return GNUNET_SYSERR; - } - msg = (const struct BobCryptodataMultipartMessage *) message; - contained = ntohl (msg->contained_element_count); - required_size = sizeof (struct BobCryptodataMultipartMessage) - + 2 * contained * sizeof (struct GNUNET_CRYPTO_PaillierCiphertext); - if ( (required_size != msg_size) || - (s->cadet_received_element_count + contained > s->used_element_count) ) - { - GNUNET_break (0); - return GNUNET_SYSERR; - } - - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Received %u additional crypto values from Bob\n", - (unsigned int) contained); - - payload = (const struct GNUNET_CRYPTO_PaillierCiphertext *) &msg[1]; - /* Convert each k[][perm] to its MPI_value */ - for (i = 0; i < contained; i++) - { - memcpy (&s->r[s->cadet_received_element_count + i], - &payload[2 * i], - sizeof (struct GNUNET_CRYPTO_PaillierCiphertext)); - memcpy (&s->r_prime[s->cadet_received_element_count + i], - &payload[2 * i], - sizeof (struct GNUNET_CRYPTO_PaillierCiphertext)); - } - s->cadet_received_element_count += contained; - GNUNET_CADET_receive_done (s->channel); - if (s->cadet_received_element_count != s->used_element_count) - return GNUNET_OK; - - s->product = compute_scalar_product (s); - transmit_client_response (s); - return GNUNET_OK; + ret = gcry_mpi_new (0); + gcry_mpi_set_ui (ret, ai_bi); + return ret; } @@ -726,12 +495,11 @@ handle_bobs_cryptodata_message (void *cls, const struct GNUNET_MessageHeader *message) { struct AliceServiceSession *s = *channel_ctx; - const struct BobCryptodataMessage *msg; - const struct GNUNET_CRYPTO_PaillierCiphertext *payload; - uint32_t i; + const struct EccBobCryptodataMessage *msg; uint32_t contained; uint16_t msg_size; - size_t required_size; + gcry_mpi_point_t prod_g_i_b_i; + gcry_mpi_point_t prod_h_i_b_i; if (NULL == s) { @@ -739,19 +507,14 @@ handle_bobs_cryptodata_message (void *cls, return GNUNET_SYSERR; } msg_size = ntohs (message->size); - if (sizeof (struct BobCryptodataMessage) > msg_size) + if (sizeof (struct EccBobCryptodataMessage) > msg_size) { GNUNET_break_op (0); return GNUNET_SYSERR; } - msg = (const struct BobCryptodataMessage *) message; + msg = (const struct EccBobCryptodataMessage *) message; contained = ntohl (msg->contained_element_count); - required_size = sizeof (struct BobCryptodataMessage) - + 2 * contained * sizeof (struct GNUNET_CRYPTO_PaillierCiphertext) - + 2 * sizeof (struct GNUNET_CRYPTO_PaillierCiphertext); - if ( (msg_size != required_size) || - (contained > UINT16_MAX) || - (s->used_element_count < contained) ) + if (2 != contained) { GNUNET_break_op (0); return GNUNET_SYSERR; @@ -771,37 +534,16 @@ handle_bobs_cryptodata_message (void *cls, GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received %u crypto values from Bob\n", (unsigned int) contained); - - payload = (const struct GNUNET_CRYPTO_PaillierCiphertext *) &msg[1]; - memcpy (&s->s, - &payload[0], - sizeof (struct GNUNET_CRYPTO_PaillierCiphertext)); - memcpy (&s->s_prime, - &payload[1], - sizeof (struct GNUNET_CRYPTO_PaillierCiphertext)); - payload = &payload[2]; - - s->r = GNUNET_malloc (sizeof (struct GNUNET_CRYPTO_PaillierCiphertext) * s->used_element_count); - s->r_prime = GNUNET_malloc (sizeof (struct GNUNET_CRYPTO_PaillierCiphertext) * s->used_element_count); - for (i = 0; i < contained; i++) - { - memcpy (&s->r[i], - &payload[2 * i], - sizeof (struct GNUNET_CRYPTO_PaillierCiphertext)); - memcpy (&s->r_prime[i], - &payload[2 * i + 1], - sizeof (struct GNUNET_CRYPTO_PaillierCiphertext)); - } - s->cadet_received_element_count = contained; GNUNET_CADET_receive_done (s->channel); - - if (s->cadet_received_element_count != s->used_element_count) - { - /* More to come */ - return GNUNET_OK; - } - - s->product = compute_scalar_product (s); + prod_g_i_b_i = GNUNET_CRYPTO_ecc_bin_to_point (edc, + &msg->prod_g_i_b_i); + prod_h_i_b_i = GNUNET_CRYPTO_ecc_bin_to_point (edc, + &msg->prod_h_i_b_i); + s->product = compute_scalar_product (s, + prod_g_i_b_i, + prod_h_i_b_i); + gcry_mpi_point_release (prod_g_i_b_i); + gcry_mpi_point_release (prod_h_i_b_i); transmit_client_response (s); return GNUNET_OK; } @@ -832,6 +574,8 @@ copy_element_cb (void *cls, else gcry_mpi_add_ui (mval, mval, val); s->sorted_elements [s->used_element_count].value = mval; + s->sorted_elements [s->used_element_count].r_i + = GNUNET_CRYPTO_ecc_random_mod_n (edc); s->sorted_elements [s->used_element_count].key = &e->key; s->used_element_count++; return GNUNET_OK; @@ -861,7 +605,7 @@ element_cmp (const void *a, * Maximum number of elements we can put into a single cryptodata * message */ -#define ELEMENT_CAPACITY ((GNUNET_CONSTANTS_MAX_CADET_MESSAGE_SIZE - 1 - sizeof (struct AliceCryptodataMessage)) / sizeof (struct GNUNET_CRYPTO_PaillierCiphertext)) +#define ELEMENT_CAPACITY ((GNUNET_CONSTANTS_MAX_CADET_MESSAGE_SIZE - 1 - sizeof (struct EccAliceCryptodataMessage)) / sizeof (struct GNUNET_CRYPTO_EccPoint)) /** @@ -873,13 +617,16 @@ element_cmp (const void *a, static void send_alices_cryptodata_message (struct AliceServiceSession *s) { - struct AliceCryptodataMessage *msg; + struct EccAliceCryptodataMessage *msg; struct GNUNET_MQ_Envelope *e; - struct GNUNET_CRYPTO_PaillierCiphertext *payload; + struct GNUNET_CRYPTO_EccPoint *payload; + gcry_mpi_point_t g_i; + gcry_mpi_point_t h_i; + gcry_mpi_t r_ia; + gcry_mpi_t r_ia_ai; unsigned int i; - uint32_t todo_count; - gcry_mpi_t a; - uint32_t off; + unsigned int off; + unsigned int todo_count; s->sorted_elements = GNUNET_malloc (GNUNET_CONTAINER_multihashmap_size (s->intersected_elements) * @@ -907,23 +654,37 @@ send_alices_cryptodata_message (struct AliceServiceSession *s) (unsigned int) s->used_element_count); e = GNUNET_MQ_msg_extra (msg, - todo_count * sizeof (struct GNUNET_CRYPTO_PaillierCiphertext), - GNUNET_MESSAGE_TYPE_SCALARPRODUCT_ALICE_CRYPTODATA); + todo_count * 2 * sizeof (struct GNUNET_CRYPTO_EccPoint), + GNUNET_MESSAGE_TYPE_SCALARPRODUCT_ECC_ALICE_CRYPTODATA); msg->contained_element_count = htonl (todo_count); - payload = (struct GNUNET_CRYPTO_PaillierCiphertext *) &msg[1]; - a = gcry_mpi_new (0); + payload = (struct GNUNET_CRYPTO_EccPoint *) &msg[1]; + r_ia = gcry_mpi_new (0); + r_ia_ai = gcry_mpi_new (0); for (i = off; i < off + todo_count; i++) { - gcry_mpi_add (a, + g_i = GNUNET_CRYPTO_ecc_dexp_mpi (edc, + s->sorted_elements [i].r_i); + /* r_ia = r_i * a */ + gcry_mpi_mul (s->sorted_elements[i].r_i, + my_privkey, + r_ia); + /* r_ia_ai = r_ia + a_i */ + gcry_mpi_add (r_ia_ai, s->sorted_elements[i].value, - my_offset); - GNUNET_assert (3 == - GNUNET_CRYPTO_paillier_encrypt (&my_pubkey, - a, - 3, - &payload[i - off])); + r_ia); + h_i = GNUNET_CRYPTO_ecc_dexp_mpi (edc, + r_ia_ai); + GNUNET_CRYPTO_ecc_point_to_bin (edc, + g_i, + &payload[(i - off) * 2]); + GNUNET_CRYPTO_ecc_point_to_bin (edc, + h_i, + &payload[(i - off) * 2 + 1]); + gcry_mpi_point_release (g_i); + gcry_mpi_point_release (h_i); } - gcry_mpi_release (a); + gcry_mpi_release (r_ia); + gcry_mpi_release (r_ia_ai); off += todo_count; GNUNET_MQ_send (s->cadet_mq, e); @@ -1069,7 +830,7 @@ cb_intersection_request_alice (void *cls, static void client_request_complete_alice (struct AliceServiceSession *s) { - struct ServiceRequestMessage *msg; + struct EccServiceRequestMessage *msg; struct GNUNET_MQ_Envelope *e; GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, @@ -1079,7 +840,7 @@ client_request_complete_alice (struct AliceServiceSession *s) = GNUNET_CADET_channel_create (my_cadet, s, &s->peer, - GNUNET_APPLICATION_TYPE_SCALARPRODUCT, + GNUNET_APPLICATION_TYPE_SCALARPRODUCT_ECC, GNUNET_CADET_OPTION_RELIABLE); if (NULL == s->channel) { @@ -1104,9 +865,8 @@ client_request_complete_alice (struct AliceServiceSession *s) } e = GNUNET_MQ_msg (msg, - GNUNET_MESSAGE_TYPE_SCALARPRODUCT_SESSION_INITIALIZATION); + GNUNET_MESSAGE_TYPE_SCALARPRODUCT_ECC_SESSION_INITIALIZATION); msg->session_id = s->session_id; - msg->public_key = my_pubkey; GNUNET_MQ_send (s->cadet_mq, e); } @@ -1327,6 +1087,11 @@ shutdown_task (void *cls, GNUNET_CADET_disconnect (my_cadet); my_cadet = NULL; } + if (NULL != edc) + { + GNUNET_CRYPTO_ecc_dlog_release (edc); + edc = NULL; + } } @@ -1375,10 +1140,7 @@ run (void *cls, { static const struct GNUNET_CADET_MessageHandler cadet_handlers[] = { { &handle_bobs_cryptodata_message, - GNUNET_MESSAGE_TYPE_SCALARPRODUCT_BOB_CRYPTODATA, - 0}, - { &handle_bobs_cryptodata_multipart, - GNUNET_MESSAGE_TYPE_SCALARPRODUCT_BOB_CRYPTODATA_MULTIPART, + GNUNET_MESSAGE_TYPE_SCALARPRODUCT_ECC_BOB_CRYPTODATA, 0}, { NULL, 0, 0} }; @@ -1393,16 +1155,12 @@ run (void *cls, }; 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); + edc = GNUNET_CRYPTO_ecc_dlog_prepare (MAX_RESULT /* max value */, + 1024 /* RAM */); + /* Select a random 'a' value for Alice */ + GNUNET_CRYPTO_ecc_rnd_mpi (edc, + &my_privkey, + &my_privkey_inv); GNUNET_SERVER_add_handlers (server, server_handlers); GNUNET_SERVER_disconnect_notify (server, @@ -1445,4 +1203,4 @@ main (int argc, &run, NULL)) ? 0 : 1; } -/* end of gnunet-service-scalarproduct_alice.c */ +/* end of gnunet-service-scalarproduct-ecc_alice.c */ diff --git a/src/scalarproduct/gnunet-service-scalarproduct-ecc_bob.c b/src/scalarproduct/gnunet-service-scalarproduct-ecc_bob.c index d08f5b858..80a0dc941 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-2015 Christian Grothoff (and other contributing authors) 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__) @@ -104,34 +104,19 @@ struct BobServiceSession struct GNUNET_SET_OperationHandle *intersection_op; /** - * a(Alice) + * b(Bob) */ struct MpiElement *sorted_elements; /** - * E(ai)(Bob) after applying the mask + * Product of the g_i^{b_i} */ - struct GNUNET_CRYPTO_PaillierCiphertext *e_a; + gcry_mpi_point_t prod_g_i_b_i; /** - * Bob's permutation p of R + * Product of the h_i^{b_i} */ - 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; + gcry_mpi_point_t prod_h_i_b_i; /** * Handle for our associated incoming CADET session, or NULL @@ -139,11 +124,6 @@ struct BobServiceSession */ struct CadetIncomingSession *cadet; - /** - * The computed scalar - */ - gcry_mpi_t product; - /** * How many elements will be supplied in total from the client. */ @@ -168,12 +148,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 @@ -216,11 +190,6 @@ 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. */ @@ -246,21 +215,6 @@ 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. */ @@ -276,6 +230,11 @@ static struct GNUNET_CONTAINER_MultiHashMap *cadet_sessions; */ static struct GNUNET_CADET_Handle *my_cadet; +/** + * Context for DLOG operations on a curve. + */ +static struct GNUNET_CRYPTO_EccDlogContext *edc; + /** @@ -386,11 +345,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,20 +352,15 @@ 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_g_i_b_i) { - GNUNET_free (s->r_prime); - s->r_prime = NULL; - } - if (NULL != s->product) - { - gcry_mpi_release (s->product); - s->product = NULL; + gcry_mpi_point_release (s->prod_h_i_b_i); + s->prod_h_i_b_i = NULL; } GNUNET_free (s); } @@ -540,306 +489,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); + "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->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; } @@ -895,44 +572,6 @@ 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 * calculate a scalarproduct with us. @@ -952,13 +591,21 @@ handle_alices_cryptodata_message (void *cls, { struct CadetIncomingSession *in = *channel_ctx; struct BobServiceSession *s; - const struct AliceCryptodataMessage *msg; - const struct GNUNET_CRYPTO_PaillierCiphertext *payload; + const struct EccAliceCryptodataMessage *msg; + const struct GNUNET_CRYPTO_EccPoint *payload; uint32_t contained_elements; size_t msg_length; uint16_t msize; 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; + + /* sanity checks */ if (NULL == in) { GNUNET_break_op (0); @@ -970,19 +617,36 @@ handle_alices_cryptodata_message (void *cls, GNUNET_break_op (0); return GNUNET_SYSERR; } + /* sort our vector for the computation */ + if (NULL == s->sorted_elements) + { + 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); + } + + /* parse message */ msize = ntohs (message->size); - if (msize <= sizeof (struct AliceCryptodataMessage)) + if (msize <= sizeof (struct EccAliceCryptodataMessage)) { GNUNET_break_op (0); return GNUNET_SYSERR; } - msg = (const struct AliceCryptodataMessage *) message; + msg = (const struct EccAliceCryptodataMessage *) 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); if ( (msize != msg_length) || (0 == contained_elements) || (contained_elements > UINT16_MAX) || @@ -994,23 +658,54 @@ handle_alices_cryptodata_message (void *cls, 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; @@ -1062,7 +757,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: @@ -1142,14 +837,9 @@ handle_alices_computation_request (void *cls, { struct CadetIncomingSession *in = *channel_ctx; struct BobServiceSession *s; - const struct ServiceRequestMessage *msg; + const struct EccServiceRequestMessage *msg; - if (ntohs (message->size) != sizeof (struct ServiceRequestMessage)) - { - GNUNET_break_op (0); - return GNUNET_SYSERR; - } - msg = (const struct ServiceRequestMessage *) message; + msg = (const struct EccServiceRequestMessage *) message; if (GNUNET_YES == in->in_map) { GNUNET_break_op (0); @@ -1162,7 +852,6 @@ handle_alices_computation_request (void *cls, 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, @@ -1462,6 +1151,11 @@ shutdown_task (void *cls, GNUNET_CADET_disconnect (my_cadet); my_cadet = NULL; } + if (NULL != edc) + { + GNUNET_CRYPTO_ecc_dlog_release (edc); + edc = NULL; + } GNUNET_CONTAINER_multihashmap_destroy (client_sessions); client_sessions = NULL; GNUNET_CONTAINER_multihashmap_destroy (cadet_sessions); @@ -1521,29 +1215,23 @@ run (void *cls, }; static const struct GNUNET_CADET_MessageHandler cadet_handlers[] = { { &handle_alices_computation_request, - GNUNET_MESSAGE_TYPE_SCALARPRODUCT_SESSION_INITIALIZATION, - sizeof (struct ServiceRequestMessage) }, + GNUNET_MESSAGE_TYPE_SCALARPRODUCT_ECC_SESSION_INITIALIZATION, + sizeof (struct EccServiceRequestMessage) }, { &handle_alices_cryptodata_message, - GNUNET_MESSAGE_TYPE_SCALARPRODUCT_ALICE_CRYPTODATA, + GNUNET_MESSAGE_TYPE_SCALARPRODUCT_ECC_ALICE_CRYPTODATA, 0}, { NULL, 0, 0} }; static const uint32_t ports[] = { - GNUNET_APPLICATION_TYPE_SCALARPRODUCT, + GNUNET_APPLICATION_TYPE_SCALARPRODUCT_ECC, 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); + /* 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 */); + GNUNET_SERVER_add_handlers (server, server_handlers); GNUNET_SERVER_disconnect_notify (server, @@ -1589,4 +1277,4 @@ main (int argc, &run, NULL)) ? 0 : 1; } -/* end of gnunet-service-scalarproduct_bob.c */ +/* end of gnunet-service-scalarproduct-ecc_bob.c */