*/
/**
- * @file vectorproduct/gnunet-service-vectorproduct.c
- * @brief vectorproduct service implementation
+ * @file scalarproduct/gnunet-service-scalarproduct.c
+ * @brief scalarproduct service implementation
* @author Christian M. Fuchs
*/
#include <limits.h>
#include "gnunet_mesh_service.h"
#include "gnunet_applications.h"
#include "gnunet_protocols.h"
-#include "gnunet_vectorproduct_service.h"
-#include "gnunet_vectorproduct.h"
+#include "gnunet_scalarproduct_service.h"
+#include "scalarproduct.h"
+
+#define LOG(kind,...) GNUNET_log_from (kind, "scalarproduct", __VA_ARGS__)
///////////////////////////////////////////////////////////////////////////////
-// Global Variables
+// Service Structure Definitions
///////////////////////////////////////////////////////////////////////////////
/**
- * Handle to the core service (NULL until we've connected to it).
+ * state a session can be in
*/
-static struct GNUNET_CORE_Handle *my_core;
+enum SessionState
+{
+ WAITING_FOR_BOBS_CONNECT,
+ MESSAGE_FROM_RESPONDING_CLIENT_RECEIVED,
+ WAITING_FOR_RESPONSE_FROM_SERVICE,
+ REQUEST_FROM_SERVICE_RECEIVED,
+ FINALIZED
+};
+
+/**
+ * role a peer in a session can assume
+ */
+enum PeerRole
+{
+ ALICE,
+ BOB
+};
+
+
+/**
+ * A scalarproduct session which tracks:
+ *
+ * a request form the client to our final response.
+ * or
+ * a request from a service to us(service).
+ */
+struct ServiceSession
+{
+ /**
+ * the role this peer has
+ */
+ enum PeerRole role;
+
+ /**
+ * session information is kept in a DLL
+ */
+ struct ServiceSession *next;
+
+ /**
+ * session information is kept in a DLL
+ */
+ struct ServiceSession *prev;
+
+ /**
+ * (hopefully) unique transaction ID
+ */
+ struct GNUNET_HashCode key;
+
+ /**
+ * state of the session
+ */
+ enum SessionState state;
+
+ /**
+ * Alice or Bob's peerID
+ */
+ struct GNUNET_PeerIdentity peer;
+
+ /**
+ * the client this request is related to
+ */
+ struct GNUNET_SERVER_Client * client;
+
+ /**
+ * how many elements we were supplied with from the client
+ */
+ uint16_t element_count;
+
+ /**
+ * how many elements actually are used after applying the mask
+ */
+ uint16_t used_element_count;
+
+ /**
+ * how many bytes the mask is long.
+ * just for convenience so we don't have to re-re-re calculate it each time
+ */
+ uint16_t mask_length;
+
+ /**
+ * all the vector elements we received
+ */
+ int32_t * vector;
+
+ /**
+ * mask of which elements to check
+ */
+ unsigned char * mask;
+
+ /**
+ * Public key of the remote service, only used by bob
+ */
+ gcry_sexp_t remote_pubkey;
+
+ /**
+ * E(ai)(Bob) or ai(Alice) after applying the mask
+ */
+ gcry_mpi_t * a;
+
+ /**
+ * The computed scalar
+ */
+ gcry_mpi_t product;
+
+ /**
+ * My transmit handle for the current message to a alice/bob
+ */
+ struct GNUNET_MESH_TransmitHandle * service_transmit_handle;
+
+ /**
+ * My transmit handle for the current message to the client
+ */
+ struct GNUNET_SERVER_TransmitHandle * client_transmit_handle;
+
+ /**
+ * tunnel-handle associated with our mesh handle
+ */
+ struct GNUNET_MESH_Tunnel * tunnel;
+
+};
+
+/**
+ * We need to do a minimum of bookkeeping to maintain track of our transmit handles.
+ * each msg is associated with a session and handle. using this information we can determine which msg was sent.
+ */
+struct MessageObject
+{
+ /**
+ * The handle used to transmit with this request
+ */
+ void ** transmit_handle;
+
+ /**
+ * The message to send
+ */
+ struct GNUNET_MessageHeader * msg;
+};
+
+///////////////////////////////////////////////////////////////////////////////
+// Global Variables
+///////////////////////////////////////////////////////////////////////////////
+
/**
* Handle to the core service (NULL until we've connected to it).
*/
static gcry_mpi_t my_lambda;
+/**
+ * Service's offset for values that could possibly be negative but are plaintext for encryption.
+ */
+static gcry_mpi_t my_offset;
+
/**
* Head of our double linked list for client-requests sent to us.
- * for all of these elements we calculate a vector product with a remote peer
+ * for all of these elements we calculate a scalar product with a remote peer
* split between service->service and client->service for simplicity
*/
static struct ServiceSession * from_client_head;
/**
* Tail of our double linked list for client-requests sent to us.
- * for all of these elements we calculate a vector product with a remote peer
+ * for all of these elements we calculate a scalar product with a remote peer
* split between service->service and client->service for simplicity
*/
static struct ServiceSession * from_client_tail;
/**
* Head of our double linked list for service-requests sent to us.
- * for all of these elements we help the requesting service in calculating a vector product
+ * for all of these elements we help the requesting service in calculating a scalar product
* split between service->service and client->service for simplicity
*/
static struct ServiceSession * from_service_head;
/**
* Tail of our double linked list for service-requests sent to us.
- * for all of these elements we help the requesting service in calculating a vector product
+ * for all of these elements we help the requesting service in calculating a scalar product
* split between service->service and client->service for simplicity
*/
static struct ServiceSession * from_service_tail;
my_pubkey_external_length);
gcry_sexp_release (key);
+
+ // 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(KEYBITS/3);
+ gcry_mpi_set_bit(my_offset, KEYBITS/3);
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, _ ("Generated key set with key length %d bits.\n"), KEYBITS);
}
* @param c ciphertext (output)
* @param m plaintext
* @param g the public base
- * @param r random base (optional) gets generated and if not NULL but uninitialized
* @param n the module from which which r is chosen (Z*_n)
* @param n_square the module for encryption, for performance reasons.
*/
static void
-encrypt_element (gcry_mpi_t c, gcry_mpi_t m, gcry_mpi_t g, gcry_mpi_t r, gcry_mpi_t n, gcry_mpi_t n_square)
+encrypt_element (gcry_mpi_t c, gcry_mpi_t m, gcry_mpi_t g, gcry_mpi_t n, gcry_mpi_t n_square)
{
-#ifndef DISABLE_CRYPTO
gcry_mpi_t tmp;
- int release_r = GNUNET_NO;
GNUNET_assert (tmp = gcry_mpi_new (0));
- if (NULL == r)
- {
- GNUNET_assert (r = gcry_mpi_new (0));
- release_r = GNUNET_YES;
- while (0 <= gcry_mpi_cmp (r, n) || 0 >= gcry_mpi_cmp_ui (r, 1))
- {
- gcry_mpi_randomize (r, KEYBITS, GCRY_WEAK_RANDOM);
- // r must be 1 < r < n
- }
+ while (0 >= gcry_mpi_cmp_ui (tmp, 1))
+ {
+ gcry_mpi_randomize (tmp, KEYBITS / 3, GCRY_WEAK_RANDOM);
+ // r must be 1 < r < n
}
-
gcry_mpi_powm (c, g, m, n_square);
- gcry_mpi_powm (tmp, r, n, n_square);
+ gcry_mpi_powm (tmp, tmp, n, n_square);
gcry_mpi_mulm (c, tmp, c, n_square);
gcry_mpi_release (tmp);
- if (GNUNET_YES == release_r)
- gcry_mpi_release (r);
-#else
- gcry_mpi_set (c, m);
-#endif
}
-
/**
* decrypts an element using the paillier crypto system
*
static void
decrypt_element (gcry_mpi_t m, gcry_mpi_t c, gcry_mpi_t mu, gcry_mpi_t lambda, gcry_mpi_t n, gcry_mpi_t n_square)
{
-#ifndef DISABLE_CRYPTO
gcry_mpi_powm (m, c, lambda, n_square);
gcry_mpi_sub_ui (m, m, 1);
gcry_mpi_div (m, NULL, m, n, 0);
gcry_mpi_mulm (m, m, mu, n);
-#else
- gcry_mpi_set (m, c);
-#endif
}
if (info->transmit_handle)
*info->transmit_handle = NULL;
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, _ ("Sent a message of type %hu.\n"), ntohs (msg->type));
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Sent a message of type %hu.\n",
+ ntohs (msg->type));
GNUNET_free(msg);
GNUNET_free(info);
return written;
*/
static struct ServiceSession *
find_matching_session (struct ServiceSession * tail,
- struct GNUNET_HashCode * key,
+ const struct GNUNET_HashCode * key,
uint16_t element_count,
enum SessionState * state,
const struct GNUNET_PeerIdentity * peerid)
static void
free_session (struct ServiceSession * session)
{
- int i;
+ unsigned int i;
if (FINALIZED != session->state)
{
const struct GNUNET_SCHEDULER_TaskContext * tc)
{
struct ServiceSession * session = cls;
- struct GNUNET_VECTORPRODUCT_client_response * msg;
+ struct GNUNET_SCALARPRODUCT_client_response * msg;
struct MessageObject * msg_obj;
- GNUNET_assert (NULL != session);
-
- msg = GNUNET_new (struct GNUNET_VECTORPRODUCT_client_response);
- msg->header.type = htons (GNUNET_MESSAGE_TYPE_VECTORPRODUCT_SERVICE_TO_CLIENT);
+ msg = GNUNET_new (struct GNUNET_SCALARPRODUCT_client_response);
+ msg->header.type = htons (GNUNET_MESSAGE_TYPE_SCALARPRODUCT_SERVICE_TO_CLIENT);
memcpy (&msg->key, &session->key, sizeof (struct GNUNET_HashCode));
memcpy (&msg->peer, &session->peer, sizeof ( struct GNUNET_PeerIdentity));
- msg->header.size = htons (sizeof (struct GNUNET_VECTORPRODUCT_client_response));
+ msg->header.size = htons (sizeof (struct GNUNET_SCALARPRODUCT_client_response));
// 0 size and the first char in the product is 0, which should never be zero if encoding is used.
msg->product_length = htonl (0);
- msg_obj = GNUNET_malloc (sizeof (struct MessageObject));
- msg_obj->msg = (struct GNUNET_MessageHeader *) msg;
+ msg_obj = GNUNET_new (struct MessageObject);
+ msg_obj->msg = &msg->header;
msg_obj->transmit_handle = NULL; // do not reset the transmit handle, please
//transmit this message to our client
session->client_transmit_handle =
GNUNET_SERVER_notify_transmit_ready (session->client,
- sizeof (struct GNUNET_VECTORPRODUCT_client_response),
+ sizeof (struct GNUNET_SCALARPRODUCT_client_response),
GNUNET_TIME_UNIT_FOREVER_REL,
&do_send_message,
msg_obj);
* S: $S := E_A(sum (r_i + b_i)^2)$
* S': $S' := E_A(sum r_i^2)$
*
- * @param kp (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)})$
- * @param kq (2)[]: $E_A(a_{pi'(i)}) times E_A(- r_{pi'(i)}) &= E_A(a_{pi'(i)} - r_{pi'(i)})$
+ * @param r (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)})$
+ * @param r_prime (2)[]: $E_A(a_{pi'(i)}) times E_A(- r_{pi'(i)}) &= E_A(a_{pi'(i)} - r_{pi'(i)})$
* @param s S: $S := E_A(sum (r_i + b_i)^2)$
- * @param stick S': $S' := E_A(sum r_i^2)$
+ * @param s_prime S': $S' := E_A(sum r_i^2)$
* @param request the associated requesting session with alice
* @param response the associated responder session with bob's client
* @return GNUNET_SYSERR if the function was called with NULL parameters or if there was an error
* GNUNET_OK if the operation succeeded
*/
static int
-prepare_service_response (gcry_mpi_t * kp,
- gcry_mpi_t * kq,
+prepare_service_response (gcry_mpi_t * r,
+ gcry_mpi_t * r_prime,
gcry_mpi_t s,
- gcry_mpi_t stick,
+ gcry_mpi_t s_prime,
struct ServiceSession * request,
struct ServiceSession * response)
{
- struct GNUNET_VECTORPRODUCT_service_response * msg;
+ struct GNUNET_SCALARPRODUCT_service_response * msg;
uint16_t msg_length = 0;
unsigned char * current = NULL;
unsigned char * element_exported = NULL;
size_t element_length = 0;
int i;
- GNUNET_assert (request);
-
- msg_length = sizeof (struct GNUNET_VECTORPRODUCT_service_response)
+ msg_length = sizeof (struct GNUNET_SCALARPRODUCT_service_response)
+ 2 * request->used_element_count * PAILLIER_ELEMENT_LENGTH // kp, kq
+ 2 * PAILLIER_ELEMENT_LENGTH; // s, stick
msg = GNUNET_malloc (msg_length);
- GNUNET_assert (msg);
- msg->header.type = htons (GNUNET_MESSAGE_TYPE_VECTORPRODUCT_BOB_TO_ALICE);
+ msg->header.type = htons (GNUNET_MESSAGE_TYPE_SCALARPRODUCT_BOB_TO_ALICE);
msg->header.size = htons (msg_length);
msg->element_count = htons (request->element_count);
msg->used_element_count = htons (request->used_element_count);
GNUNET_assert (0 == gcry_mpi_print (GCRYMPI_FMT_USG,
element_exported, PAILLIER_ELEMENT_LENGTH,
&element_length,
- stick));
+ s_prime));
adjust (element_exported, element_length, PAILLIER_ELEMENT_LENGTH);
memcpy (current, element_exported, PAILLIER_ELEMENT_LENGTH);
GNUNET_free (element_exported);
GNUNET_assert (0 == gcry_mpi_print (GCRYMPI_FMT_USG,
element_exported, PAILLIER_ELEMENT_LENGTH,
&element_length,
- kp[i]));
+ r[i]));
adjust (element_exported, element_length, PAILLIER_ELEMENT_LENGTH);
memcpy (current, element_exported, PAILLIER_ELEMENT_LENGTH);
GNUNET_free (element_exported);
GNUNET_assert (0 == gcry_mpi_print (GCRYMPI_FMT_USG,
element_exported, PAILLIER_ELEMENT_LENGTH,
&element_length,
- kq[i]));
+ r_prime[i]));
adjust (element_exported, element_length, PAILLIER_ELEMENT_LENGTH);
memcpy (current, element_exported, PAILLIER_ELEMENT_LENGTH);
GNUNET_free (element_exported);
/**
* executed by bob:
* compute the values
- * (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)$
+ * (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
* @param response the responding session + bob's client handle
compute_service_response (struct ServiceSession * request,
struct ServiceSession * response)
{
- int i, j, ret = GNUNET_SYSERR;
+ int i;
+ int j;
+ int ret = GNUNET_SYSERR;
unsigned int * p;
unsigned int * q;
uint16_t count;
+ gcry_mpi_t * rand = NULL;
gcry_mpi_t * r = NULL;
- gcry_mpi_t * kp = NULL;
- gcry_mpi_t * kq = NULL;
+ gcry_mpi_t * r_prime = NULL;
gcry_mpi_t * b;
- gcry_mpi_t * ap;
- gcry_mpi_t * aq;
- gcry_mpi_t * bp;
- gcry_mpi_t * bq;
- gcry_mpi_t * rp;
- gcry_mpi_t * rq;
+ gcry_mpi_t * a_pi;
+ gcry_mpi_t * a_pi_prime;
+ gcry_mpi_t * b_pi;
+ gcry_mpi_t * rand_pi;
+ gcry_mpi_t * rand_pi_prime;
gcry_mpi_t s = NULL;
- gcry_mpi_t stick = NULL;
+ gcry_mpi_t s_prime = NULL;
gcry_mpi_t remote_n = NULL;
gcry_mpi_t remote_nsquare;
gcry_mpi_t remote_g = NULL;
gcry_sexp_t tmp_exp;
uint32_t value;
- GNUNET_assert (request != NULL && response != NULL);
count = request->used_element_count;
b = GNUNET_malloc (sizeof (gcry_mpi_t) * count);
- ap = GNUNET_malloc (sizeof (gcry_mpi_t) * count);
- bp = GNUNET_malloc (sizeof (gcry_mpi_t) * count);
- aq = GNUNET_malloc (sizeof (gcry_mpi_t) * count);
- bq = GNUNET_malloc (sizeof (gcry_mpi_t) * count);
- rp = GNUNET_malloc (sizeof (gcry_mpi_t) * count);
- rq = GNUNET_malloc (sizeof (gcry_mpi_t) * count);
+ a_pi = GNUNET_malloc (sizeof (gcry_mpi_t) * count);
+ b_pi = GNUNET_malloc (sizeof (gcry_mpi_t) * count);
+ a_pi_prime = GNUNET_malloc (sizeof (gcry_mpi_t) * count);
+ rand_pi = GNUNET_malloc (sizeof (gcry_mpi_t) * count);
+ rand_pi_prime = GNUNET_malloc (sizeof (gcry_mpi_t) * count);
// convert responder session to from long to mpi
for (i = 0, j = 0; i < response->element_count && j < count; i++)
gcry_sexp_release (tmp_exp);
// generate r, p and q
- r = generate_random_vector (count);
+ rand = generate_random_vector (count);
p = GNUNET_CRYPTO_random_permute (GNUNET_CRYPTO_QUALITY_WEAK, count);
q = GNUNET_CRYPTO_random_permute (GNUNET_CRYPTO_QUALITY_WEAK, count);
//initialize the result vectors
- kp = initialize_mpi_vector (count);
- kq = initialize_mpi_vector (count);
+ r = initialize_mpi_vector (count);
+ r_prime = initialize_mpi_vector (count);
// copy the REFERNCES of a, b and r into aq and bq. we will not change
// those values, thus we can work with the references
- memcpy (ap, request->a, sizeof (gcry_mpi_t) * count);
- memcpy (aq, request->a, sizeof (gcry_mpi_t) * count);
- memcpy (bp, b, sizeof (gcry_mpi_t) * count);
- memcpy (bq, b, sizeof (gcry_mpi_t) * count);
- memcpy (rp, r, sizeof (gcry_mpi_t) * count);
- memcpy (rq, r, sizeof (gcry_mpi_t) * count);
+ memcpy (a_pi, request->a, sizeof (gcry_mpi_t) * count);
+ memcpy (a_pi_prime, request->a, sizeof (gcry_mpi_t) * count);
+ memcpy (b_pi, b, sizeof (gcry_mpi_t) * count);
+ memcpy (rand_pi, rand, sizeof (gcry_mpi_t) * count);
+ memcpy (rand_pi_prime, rand, sizeof (gcry_mpi_t) * count);
// generate p and q permutations for a, b and r
- GNUNET_assert (permute_vector (ap, p, count));
- GNUNET_assert (permute_vector (bp, p, count));
- GNUNET_assert (permute_vector (rp, p, count));
- GNUNET_assert (permute_vector (aq, q, count));
- GNUNET_assert (permute_vector (bq, q, count));
- GNUNET_assert (permute_vector (rq, q, count));
+ GNUNET_assert (permute_vector (a_pi, p, count));
+ GNUNET_assert (permute_vector (b_pi, p, count));
+ GNUNET_assert (permute_vector (rand_pi, p, count));
+ GNUNET_assert (permute_vector (a_pi_prime, q, count));
+ GNUNET_assert (permute_vector (rand_pi_prime, q, count));
// 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(a_pi) + E(-r_pi - b_pi)
+ // Calculate Kp = E(S + a_pi) (+) E(S - r_pi - b_pi)
for (i = 0; i < count; i++)
{
- // E(-r_pi - b_pi)
- gcry_mpi_sub (kp[i], kp[i], rp[i]);
- gcry_mpi_sub (kp[i], kp[i], bp[i]);
- encrypt_element (kp[i], kp[i], NULL, remote_g, remote_n, remote_nsquare);
-
- // E(-r_pi - b_pi) * E(a_pi) == E(a + (-r -b))
- //gcry_mpi_mulm (kp[i], kp[i], ap[i], remote_nsquare);
- gcry_mpi_add (kp[i], kp[i], ap[i]);
+ // E(S - r_pi - b_pi)
+ gcry_mpi_sub (r[i], my_offset, rand_pi[i]);
+ gcry_mpi_sub (r[i], r[i], b_pi[i]);
+ encrypt_element (r[i], r[i], remote_g, remote_n, remote_nsquare);
+
+ // E(S - r_pi - b_pi) * E(S + a_pi) == E(2*S + a - r - b)
+ gcry_mpi_mulm (r[i], r[i], a_pi[i], remote_nsquare);
}
- GNUNET_free (ap);
- GNUNET_free (bp);
- GNUNET_free (rp);
+ GNUNET_free (a_pi);
+ GNUNET_free (b_pi);
+ GNUNET_free (rand_pi);
- // Calculate Kq = E(a_qi) + E( -r_qi)
+ // Calculate Kq = E(S + a_qi) (+) E(S - r_qi)
for (i = 0; i < count; i++)
{
- // E(-r_qi)
- gcry_mpi_sub (kq[i], kq[i], rq[i]);
- encrypt_element (kq[i], kq[i], NULL, remote_g, remote_n, remote_nsquare);
+ // E(S - r_qi)
+ gcry_mpi_sub (r_prime[i], my_offset, rand_pi_prime[i]);
+ encrypt_element (r_prime[i], r_prime[i], remote_g, remote_n, remote_nsquare);
- // E(-r_qi) * E(a_qi) == E(aqi + (- rqi))
- //gcry_mpi_mulm (kq[i], kq[i], aq[i], remote_nsquare);
- gcry_mpi_add (kq[i], kq[i], aq[i]);
+ // E(S - r_qi) * E(S + a_qi) == E(2*S + a_qi - r_qi)
+ gcry_mpi_mulm (r_prime[i], r_prime[i], a_pi_prime[i], remote_nsquare);
}
- GNUNET_free (aq);
- GNUNET_free (bq);
- GNUNET_free (rq);
+ GNUNET_free (a_pi_prime);
+ GNUNET_free (rand_pi_prime);
// Calculate S' = E(SUM( r_i^2 ))
- stick = compute_square_sum (r, count);
- encrypt_element (stick, stick, NULL, remote_g, remote_n, remote_nsquare);
+ s_prime = compute_square_sum (rand, count);
+ encrypt_element (s_prime, s_prime, remote_g, remote_n, remote_nsquare);
// Calculate S = E(SUM( (r_i + b_i)^2 ))
for (i = 0; i < count; i++)
{
- gcry_mpi_add (r[i], r[i], b[i]);
+ gcry_mpi_add (rand[i], rand[i], b[i]);
}
- s = compute_square_sum (r, count);
- encrypt_element (s, s, NULL, remote_g, remote_n, remote_nsquare);
+ s = compute_square_sum (rand, count);
+ encrypt_element (s, s, remote_g, remote_n, remote_nsquare);
gcry_mpi_release (remote_n);
gcry_mpi_release (remote_g);
gcry_mpi_release (remote_nsquare);
// release r and tmp
for (i = 0; i < count; i++)
// rp, rq, aq, ap, bp, bq are released along with a, r, b respectively, (a and b are handled at except:)
- gcry_mpi_release (r[i]);
+ gcry_mpi_release (rand[i]);
// copy the Kp[], Kq[], S and Stick into a new message
- if (GNUNET_YES != prepare_service_response (kp, kq, s, stick, request, response))
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _ ("Computation of values for alice failed!\n"));
+ if (GNUNET_YES != prepare_service_response (r, r_prime, s, s_prime, request, response))
+ GNUNET_log (GNUNET_ERROR_TYPE_INFO, _("Failed to communicate with `%s', scalar product calculation aborted.\n"),
+ GNUNET_i2s (&request->peer));
else
ret = GNUNET_OK;
for (i = 0; i < count; i++)
{
- gcry_mpi_release (kq[i]);
- gcry_mpi_release (kp[i]);
+ gcry_mpi_release (r_prime[i]);
+ gcry_mpi_release (r[i]);
}
gcry_mpi_release (s);
- gcry_mpi_release (stick);
+ gcry_mpi_release (s_prime);
except:
for (i = 0; i < count; i++)
* Executed by Alice, fills in a service-request message and sends it to the given peer
*
* @param session the session associated with this request, then also holds the CORE-handle
- * @return GNUNET_SYSERR if we could not send the message
- * GNUNET_NO if the message was too large
- * GNUNET_OK if we sent it
+ * @return #GNUNET_SYSERR if we could not send the message
+ * #GNUNET_NO if the message was too large
+ * #GNUNET_OK if we sent it
*/
static void
prepare_service_request (void *cls,
{
struct ServiceSession * session = cls;
unsigned char * current;
- struct GNUNET_VECTORPRODUCT_service_request * msg;
+ struct GNUNET_SCALARPRODUCT_service_request * msg;
struct MessageObject * msg_obj;
unsigned int i;
unsigned int j;
uint16_t msg_length;
size_t element_length = 0; //gets initialized by gcry_mpi_print, but the compiler doesn't know that
gcry_mpi_t a;
- gcry_mpi_t r;
uint32_t value;
GNUNET_assert (NULL != cls);
GNUNET_assert (NULL != peer);
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, _ ("Successfully created new tunnel to peer (%s)!\n"), GNUNET_i2s (peer));
- msg_length = sizeof (struct GNUNET_VECTORPRODUCT_service_request)
+ msg_length = sizeof (struct GNUNET_SCALARPRODUCT_service_request)
+ session->used_element_count * PAILLIER_ELEMENT_LENGTH
+ session->mask_length
+ my_pubkey_external_length;
- if (GNUNET_SERVER_MAX_MESSAGE_SIZE < sizeof (struct GNUNET_VECTORPRODUCT_service_request)
+ if (GNUNET_SERVER_MAX_MESSAGE_SIZE < sizeof (struct GNUNET_SCALARPRODUCT_service_request)
+ session->used_element_count * PAILLIER_ELEMENT_LENGTH
+ session->mask_length
+ my_pubkey_external_length)
}
msg = GNUNET_malloc (msg_length);
- msg->header.type = htons (GNUNET_MESSAGE_TYPE_VECTORPRODUCT_ALICE_TO_BOB);
+ msg->header.type = htons (GNUNET_MESSAGE_TYPE_SCALARPRODUCT_ALICE_TO_BOB);
memcpy (&msg->key, &session->key, sizeof (struct GNUNET_HashCode));
msg->mask_length = htons (session->mask_length);
msg->pk_length = htons (my_pubkey_external_length);
// now copy over the element vector
session->a = GNUNET_malloc (sizeof (gcry_mpi_t) * session->used_element_count);
a = gcry_mpi_new (KEYBITS * 2);
- r = gcry_mpi_new (KEYBITS * 2);
// encrypt our vector and generate string representations
for (i = 0, j = 0; i < session->element_count; i++)
{
unsigned char * element_exported = GNUNET_malloc (PAILLIER_ELEMENT_LENGTH);
value = session->vector[i] >= 0 ? session->vector[i] : -session->vector[i];
+ a = gcry_mpi_set_ui (a, 0);
// long to gcry_mpi_t
if (session->vector[i] < 0)
- {
- a = gcry_mpi_set_ui (NULL, 0);
- gcry_mpi_sub_ui (a, a, value);
- }
+ gcry_mpi_sub_ui (a, a, value);
else
- a = gcry_mpi_set_ui (NULL, value);
+ gcry_mpi_add_ui (a, a, value);
- // multiply with a given factor to avoid disclosing 1
session->a[j++] = gcry_mpi_set (NULL, a);
- encrypt_element (a, a, r, my_g, my_n, my_nsquare);
+ gcry_mpi_add (a, a, my_offset);
+ encrypt_element (a, a, my_g, my_n, my_nsquare);
// get representation as string
// we always supply some value, so gcry_mpi_print fails only if it can't reserve memory
}
}
gcry_mpi_release (a);
- gcry_mpi_release (r);
- msg_obj = GNUNET_malloc (sizeof (struct MessageObject));
+ msg_obj = GNUNET_new (struct MessageObject);
msg_obj->msg = (struct GNUNET_MessageHeader *) msg;
msg_obj->transmit_handle = (void *) &session->service_transmit_handle; //and reset the transmit handle
GNUNET_log (GNUNET_ERROR_TYPE_INFO, _("Transmitting service request.\n"));
GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_SECONDS,
&prepare_client_end_notification,
session);
- return;
}
}
/**
* Method called whenever a peer has disconnected from the tunnel.
* Implementations of this callback must NOT call
- * GNUNET_MESH_tunnel_destroy immediately, but instead schedule those
+ * #GNUNET_MESH_tunnel_destroy immediately, but instead schedule those
* to run in some other task later. However, calling
- * "GNUNET_MESH_notify_transmit_ready_cancel" is allowed.
+ * #GNUNET_MESH_notify_transmit_ready_cancel is allowed.
*
* @param cls closure
* @param peer peer identity the tunnel stopped working with
// as we have only one peer connected in each session, just remove the session and say good bye
struct ServiceSession * session = cls;
struct ServiceSession * curr;
- GNUNET_assert(cls);
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, _ ("Peer (%s) disconnected from our tunnel!\n"), GNUNET_i2s (peer));
+
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Peer (%s) disconnected from our tunnel!\n",
+ GNUNET_i2s (peer));
if ((session->role == ALICE) && (FINALIZED != session->state) && ( ! do_shutdown))
{
GNUNET_CONTAINER_DLL_remove (from_client_head, from_client_tail, session);
break;
}
+ // FIXME: dangling tasks, code duplication, use-after-free, fun...
GNUNET_SCHEDULER_add_now (&destroy_tunnel,
session);
// if this happened before we received the answer, we must terminate the session
- GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_SECONDS,
- &prepare_client_end_notification,
- session);
+ GNUNET_SCHEDULER_add_now (&prepare_client_end_notification,
+ session);
}
}
struct GNUNET_SERVER_Client *client,
const struct GNUNET_MessageHeader *message)
{
- struct GNUNET_VECTORPRODUCT_client_request * msg = (struct GNUNET_VECTORPRODUCT_client_request *) message;
+ const struct GNUNET_SCALARPRODUCT_client_request * msg = (const struct GNUNET_SCALARPRODUCT_client_request *) message;
struct ServiceSession * session;
uint16_t element_count;
uint16_t mask_length;
GNUNET_assert (message);
//we need at least a peer and one message id to compare
- if (sizeof (struct GNUNET_VECTORPRODUCT_client_request) > ntohs (msg->header.size))
+ if (sizeof (struct GNUNET_SCALARPRODUCT_client_request) > ntohs (msg->header.size))
{
- GNUNET_log (GNUNET_ERROR_TYPE_WARNING, _ ("Too short message received from client!\n"));
+ GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
+ _ ("Too short message received from client!\n"));
GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
return;
}
mask_length = ntohs (msg->mask_length);
//sanity check: is the message as long as the message_count fields suggests?
- if (( ntohs (msg->header.size) != (sizeof (struct GNUNET_VECTORPRODUCT_client_request) + element_count * sizeof (int32_t) + mask_length))
+ if (( ntohs (msg->header.size) != (sizeof (struct GNUNET_SCALARPRODUCT_client_request) + element_count * sizeof (int32_t) + mask_length))
|| (0 == element_count))
{
- GNUNET_log (GNUNET_ERROR_TYPE_WARNING, _ ("Invalid message received from client, session information incorrect!\n"));
+ GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
+ _ ("Invalid message received from client, session information incorrect!\n"));
GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
return;
}
return;
}
- session = GNUNET_malloc (sizeof (struct ServiceSession));
+ session = GNUNET_new (struct ServiceSession);
session->client = client;
session->element_count = element_count;
session->mask_length = mask_length;
session->vector = GNUNET_malloc (sizeof (int32_t) * element_count);
vector = (int32_t *) & msg[1];
- if (GNUNET_MESSAGE_TYPE_VECTORPRODUCT_CLIENT_TO_ALICE == msg_type)
+ if (GNUNET_MESSAGE_TYPE_SCALARPRODUCT_CLIENT_TO_ALICE == msg_type)
{
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, _ ("Got client-request-session with key %s, preparing tunnel to remote service.\n"), GNUNET_h2s (&session->key));
* Function called whenever an inbound tunnel is destroyed. Should clean up
* any associated state.
*
- * @param cls closure (set from GNUNET_MESH_connect)
+ * @param cls closure (set from #GNUNET_MESH_connect)
* @param tunnel connection to the other end (henceforth invalid)
* @param tunnel_ctx place where local state associated
* with the tunnel is stored (our 'struct TunnelState')
*
* @param session - the session associated with this computation
* @param kp - (1) from the protocol definition:
- * $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)})$
+ * $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)})$
* @param kq - (2) from the protocol definition:
- * $E_A(a_{pi'(i)}) times E_A(- r_{pi'(i)}) &= E_A(a_{pi'(i)} - r_{pi'(i)})$
+ * $E_A(a_{\pi'(i)}) \otimes E_A(- r_{\pi'(i)}) &= E_A(a_{\pi'(i)} - r_{\pi'(i)})$
* @param s - S from the protocol definition:
- * $S := E_A(sum (r_i + b_i)^2)$
+ * $S := E_A(\sum (r_i + b_i)^2)$
* @param stick - S' from the protocol definition:
- * $S' := E_A(sum r_i^2)$
+ * $S' := E_A(\sum r_i^2)$
* @return product as MPI, never NULL
*/
static gcry_mpi_t
compute_scalar_product (struct ServiceSession * session,
- gcry_mpi_t * kp, gcry_mpi_t * kq, gcry_mpi_t s, gcry_mpi_t stick)
+ gcry_mpi_t * r, gcry_mpi_t * r_prime, gcry_mpi_t s, gcry_mpi_t s_prime)
{
uint16_t count;
- gcry_mpi_t divider;
gcry_mpi_t t;
gcry_mpi_t u;
gcry_mpi_t utick;
gcry_mpi_t p;
gcry_mpi_t ptick;
- gcry_mpi_t product;
gcry_mpi_t tmp;
unsigned int i;
count = session->used_element_count;
tmp = gcry_mpi_new (KEYBITS);
+ // 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++)
{
- decrypt_element (kp[i], kp[i], my_mu, my_lambda, my_n, my_nsquare);
- decrypt_element (kq[i], kq[i], my_mu, my_lambda, my_n, my_nsquare);
+ decrypt_element (r[i], r[i], my_mu, my_lambda, my_n, my_nsquare);
+ gcry_mpi_sub(r[i],r[i],my_offset);
+ gcry_mpi_sub(r[i],r[i],my_offset);
+ decrypt_element (r_prime[i], r_prime[i], my_mu, my_lambda, my_n, my_nsquare);
+ gcry_mpi_sub(r_prime[i],r_prime[i],my_offset);
+ gcry_mpi_sub(r_prime[i],r_prime[i],my_offset);
}
- // calculate t = E(sum(ai))
+ // calculate t = sum(ai)
t = compute_square_sum (session->a, count);
- encrypt_element (t, t, NULL, my_g, my_n, my_nsquare);
// calculate U
u = gcry_mpi_new (0);
- tmp = compute_square_sum (kp, count);
+ tmp = compute_square_sum (r, count);
gcry_mpi_sub (u, u, tmp);
- encrypt_element (u, u, NULL, my_g, my_n, my_nsquare);
gcry_mpi_release (tmp);
//calculate U'
utick = gcry_mpi_new (0);
- tmp = compute_square_sum (kq, count);
+ tmp = compute_square_sum (r_prime, count);
gcry_mpi_sub (utick, utick, tmp);
- encrypt_element (utick, utick, NULL, my_g, my_n, my_nsquare);
- gcry_mpi_release (tmp);
GNUNET_assert (p = gcry_mpi_new (0));
GNUNET_assert (ptick = gcry_mpi_new (0));
+ // compute P
+ decrypt_element (s, s, my_mu, my_lambda, my_n, my_nsquare);
+ decrypt_element (s_prime, s_prime, my_mu, my_lambda, my_n, my_nsquare);
+
// compute P
gcry_mpi_add (p, s, t);
- //gcry_mpi_mulm (p, p, u, my_nsquare);
gcry_mpi_add (p, p, u);
- decrypt_element (p, p, my_mu, my_lambda, my_n, my_nsquare);
// compute P'
- gcry_mpi_add (ptick, stick, t);
- //gcry_mpi_mulm (ptick, ptick, utick, my_nsquare);
+ gcry_mpi_add (ptick, s_prime, t);
gcry_mpi_add (ptick, ptick, utick);
- decrypt_element (ptick, ptick, my_mu, my_lambda, my_n, my_nsquare);
gcry_mpi_release (t);
gcry_mpi_release (u);
gcry_mpi_release (utick);
// compute product
- GNUNET_assert (product = gcry_mpi_new (0));
- gcry_mpi_sub (product, p, ptick);
- gcry_mpi_release (p);
+ gcry_mpi_sub (p, p, ptick);
gcry_mpi_release (ptick);
- divider = gcry_mpi_set_ui (NULL, 2);
- gcry_mpi_div (product, NULL, product, divider, 0);
+ tmp = gcry_mpi_set_ui (tmp, 2);
+ gcry_mpi_div (p, NULL, p, tmp, 0);
- gcry_mpi_release (divider);
+ gcry_mpi_release (tmp);
for (i = 0; i < count; i++)
gcry_mpi_release (session->a[i]);
GNUNET_free (session->a);
session->a = NULL;
- return product;
+ return p;
}
const struct GNUNET_SCHEDULER_TaskContext *tc)
{
struct ServiceSession * session = cls;
- struct GNUNET_VECTORPRODUCT_client_response * msg;
+ struct GNUNET_SCALARPRODUCT_client_response * msg;
unsigned char * product_exported = NULL;
size_t product_length = 0;
uint16_t msg_length = 0;
struct MessageObject * msg_obj;
+ int8_t range = 0;
+ int sign;
- GNUNET_assert (session);
-
if (session->product)
{
+ gcry_mpi_t value = gcry_mpi_new(0);
+
+ sign = gcry_mpi_cmp_ui(session->product, 0);
+ // libgcrypt can not handle a print of a negative number
+ if (0 > sign){
+ range = -1;
+ gcry_mpi_sub(value, value, session->product);
+ }
+ else if(0 < sign){
+ range = 1;
+ gcry_mpi_add(value, value, session->product);
+ }
+
// get representation as string
- GNUNET_assert ( ! gcry_mpi_aprint (GCRYMPI_FMT_USG,
- &product_exported,
- &product_length,
- session->product));
+ // unfortunately libgcrypt is too stupid to implement print-support in
+ // signed GCRYMPI_FMT_STD format, and simply asserts in that case.
+ // here is the associated sourcecode:
+ // if (a->sign) return gcry_error (GPG_ERR_INTERNAL); /* Can't handle it yet. */
+ if (range)
+ GNUNET_assert ( ! gcry_mpi_aprint (GCRYMPI_FMT_USG, // FIXME: just log (& survive!)
+ &product_exported,
+ &product_length,
+ session->product));
+
gcry_mpi_release (session->product);
session->product = NULL;
}
- msg_length = sizeof (struct GNUNET_VECTORPRODUCT_client_response) +product_length;
+ msg_length = sizeof (struct GNUNET_SCALARPRODUCT_client_response) + product_length;
msg = GNUNET_malloc (msg_length);
memcpy (&msg[1], product_exported, product_length);
GNUNET_free_non_null (product_exported);
- msg->header.type = htons (GNUNET_MESSAGE_TYPE_VECTORPRODUCT_SERVICE_TO_CLIENT);
+ msg->header.type = htons (GNUNET_MESSAGE_TYPE_SCALARPRODUCT_SERVICE_TO_CLIENT);
msg->header.size = htons (msg_length);
+ msg->range = range;
memcpy (&msg->key, &session->key, sizeof (struct GNUNET_HashCode));
memcpy (&msg->peer, &session->peer, sizeof ( struct GNUNET_PeerIdentity));
msg->product_length = htonl (product_length);
- msg_obj = GNUNET_malloc (sizeof (struct MessageObject));
+ msg_obj = GNUNET_new (struct MessageObject);
msg_obj->msg = (struct GNUNET_MessageHeader *) msg;
msg_obj->transmit_handle = NULL; // don't reset the transmit handle
//transmit this message to our client
- session->client_transmit_handle =
+ session->client_transmit_handle = // FIXME: use after free possibility during shutdown
GNUNET_SERVER_notify_transmit_ready (session->client,
msg_length,
GNUNET_TIME_UNIT_FOREVER_REL,
/**
- * Handle a request from another service to calculate a vectorproduct with us.
+ * Handle a request from another service to calculate a scalarproduct with us.
*
- * @param cls closure (set from GNUNET_MESH_connect)
+ * @param cls closure (set from #GNUNET_MESH_connect)
* @param tunnel connection to the other end
* @param tunnel_ctx place to store local state associated with the tunnel
* @param sender who sent the message
* @param message the actual message
* @param atsi performance data for the connection
- * @return GNUNET_OK to keep the connection open,
- * GNUNET_SYSERR to close it (signal serious error)
+ * @return #GNUNET_OK to keep the connection open,
+ * #GNUNET_SYSERR to close it (signal serious error)
*/
static int
handle_service_request (void *cls,
const struct GNUNET_ATS_Information * atsi)
{
struct ServiceSession * session;
- struct GNUNET_VECTORPRODUCT_service_request * msg = (struct GNUNET_VECTORPRODUCT_service_request *) message;
+ const struct GNUNET_SCALARPRODUCT_service_request * msg = (const struct GNUNET_SCALARPRODUCT_service_request *) message;
uint16_t mask_length;
uint16_t pk_length;
uint16_t used_elements;
int32_t i = -1;
enum SessionState needed_state;
- GNUNET_assert (NULL != message);
- GNUNET_assert (NULL != sender);
- GNUNET_assert (NULL != tunnel_ctx);
session = (struct ServiceSession *) * tunnel_ctx;
// is this tunnel already in use?
if ( (session->next) || (from_service_head == session))
}
//we need at least a peer and one message id to compare
- if (ntohs (msg->header.size) < sizeof (struct GNUNET_VECTORPRODUCT_service_request))
+ if (ntohs (msg->header.size) < sizeof (struct GNUNET_SCALARPRODUCT_service_request))
{
GNUNET_log (GNUNET_ERROR_TYPE_WARNING, _ ("Too short message received from peer!\n"));
GNUNET_free (session);
pk_length = ntohs (msg->pk_length);
used_elements = ntohs (msg->used_element_count);
element_count = ntohs (msg->element_count);
- msg_length = sizeof (struct GNUNET_VECTORPRODUCT_service_request)
+ msg_length = sizeof (struct GNUNET_SCALARPRODUCT_service_request)
+ mask_length + pk_length + used_elements * PAILLIER_ELEMENT_LENGTH;
//sanity check: is the message as long as the message_count fields suggests?
session->a = GNUNET_malloc (sizeof (gcry_mpi_t) * used_elements);
- if (GNUNET_SERVER_MAX_MESSAGE_SIZE >= sizeof (struct GNUNET_VECTORPRODUCT_service_request)
+ if (GNUNET_SERVER_MAX_MESSAGE_SIZE >= sizeof (struct GNUNET_SCALARPRODUCT_service_request)
+pk_length
+ mask_length
+ used_elements * PAILLIER_ELEMENT_LENGTH)
¤t[i * PAILLIER_ELEMENT_LENGTH],
PAILLIER_ELEMENT_LENGTH,
&read);
- if (ret) // read < GNUNET_CRYPTO_RSA_DATA_ENCODING_LENGTH
+ if (ret)
{
GNUNET_log (GNUNET_ERROR_TYPE_WARNING, _ ("Could not translate E[a%d] to MPI!\n%s/%s\n"),
i, gcry_strsource (ret), gcry_strerror (ret));
/**
- * Handle a response we got from another service we wanted to calculate a vectorproduct with.
+ * Handle a response we got from another service we wanted to calculate a scalarproduct with.
*
- * @param cls closure (set from GNUNET_MESH_connect)
+ * @param cls closure (set from #GNUNET_MESH_connect)
* @param tunnel connection to the other end
* @param tunnel_ctx place to store local state associated with the tunnel
* @param sender who sent the message
* @param message the actual message
* @param atsi performance data for the connection
- * @return GNUNET_OK to keep the connection open,
- * GNUNET_SYSERR to close it (signal serious error)
+ * @return #GNUNET_OK to keep the connection open,
+ * #GNUNET_SYSERR to close it (signal serious error)
*/
static int
handle_service_response (void *cls,
{
struct ServiceSession * session;
- struct GNUNET_VECTORPRODUCT_service_response * msg = (struct GNUNET_VECTORPRODUCT_service_response *) message;
+ struct GNUNET_SCALARPRODUCT_service_response * msg = (struct GNUNET_SCALARPRODUCT_service_response *) message;
unsigned char * current;
uint16_t count;
gcry_mpi_t s = NULL;
- gcry_mpi_t stick = NULL;
+ gcry_mpi_t s_prime = NULL;
size_t read;
size_t i;
uint16_t used_element_count;
size_t msg_size;
- gcry_mpi_t * kp = NULL;
- gcry_mpi_t * kq = NULL;
+ gcry_mpi_t * r = NULL;
+ gcry_mpi_t * r_prime = NULL;
+ int rc;
GNUNET_assert (NULL != message);
GNUNET_assert (NULL != sender);
goto invalid_msg;
}
//we need at least a peer and one message id to compare
- if (sizeof (struct GNUNET_VECTORPRODUCT_service_response) > ntohs (msg->header.size))
+ if (sizeof (struct GNUNET_SCALARPRODUCT_service_response) > ntohs (msg->header.size))
{
- GNUNET_log (GNUNET_ERROR_TYPE_WARNING, _ ("Too short message received from peer!\n"));
+ GNUNET_break_op (0);
goto invalid_msg;
}
used_element_count = ntohs (msg->used_element_count);
- msg_size = sizeof (struct GNUNET_VECTORPRODUCT_service_response)
+ msg_size = sizeof (struct GNUNET_SCALARPRODUCT_service_response)
+ 2 * used_element_count * PAILLIER_ELEMENT_LENGTH
+ 2 * PAILLIER_ELEMENT_LENGTH;
//sanity check: is the message as long as the message_count fields suggests?
if ((ntohs (msg->header.size) != msg_size) || (count != used_element_count))
{
- GNUNET_log (GNUNET_ERROR_TYPE_WARNING, _ ("Invalid message received from peer!\n"));
- goto invalid_msg;
- }
- if (GNUNET_SERVER_MAX_MESSAGE_SIZE < msg_size)
- {
- GNUNET_log (GNUNET_ERROR_TYPE_WARNING, _ ("Message too large, fragmentation is currently not supported!\n"));
+ GNUNET_break_op (0);
goto invalid_msg;
}
//convert s
current = (unsigned char *) &msg[1];
- if (gcry_mpi_scan (&s, GCRYMPI_FMT_USG, current,
- PAILLIER_ELEMENT_LENGTH, &read))
+ if (0 != (rc = gcry_mpi_scan (&s, GCRYMPI_FMT_USG, current,
+ PAILLIER_ELEMENT_LENGTH, &read)))
{
- GNUNET_log (GNUNET_ERROR_TYPE_WARNING, _ ("Could not translate s to an MPI value!\n"));
+ LOG_GCRY (GNUNET_ERROR_TYPE_DEBUG, "gcry_mpi_scan", rc);
+ GNUNET_break_op (0);
goto invalid_msg;
}
current += PAILLIER_ELEMENT_LENGTH;
//convert stick
- if (gcry_mpi_scan (&stick, GCRYMPI_FMT_USG, current,
- PAILLIER_ELEMENT_LENGTH, &read))
+ if (0 != (rc = gcry_mpi_scan (&s_prime, GCRYMPI_FMT_USG, current,
+ PAILLIER_ELEMENT_LENGTH, &read)))
{
- GNUNET_log (GNUNET_ERROR_TYPE_WARNING, _ ("Could not translate s' to an MPI value!\n"));
+ LOG_GCRY (GNUNET_ERROR_TYPE_DEBUG, "gcry_mpi_scan", rc);
+ GNUNET_break_op (0);
goto invalid_msg;
}
current += PAILLIER_ELEMENT_LENGTH;
- kp = GNUNET_malloc (sizeof (gcry_mpi_t) * count);
+ r = GNUNET_malloc (sizeof (gcry_mpi_t) * count);
// Convert each kp[] to its MPI_value
for (i = 0; i < count; i++)
{
- if (gcry_mpi_scan (&kp[i], GCRYMPI_FMT_USG, current,
- PAILLIER_ELEMENT_LENGTH, &read))
+ if (0 != (rc = gcry_mpi_scan (&r[i], GCRYMPI_FMT_USG, current,
+ PAILLIER_ELEMENT_LENGTH, &read)))
{
- GNUNET_log (GNUNET_ERROR_TYPE_WARNING, _ ("Could not translate Kp[%d]to an MPI value!\n"), i);
+ LOG_GCRY (GNUNET_ERROR_TYPE_DEBUG, "gcry_mpi_scan", rc);
+ GNUNET_break_op (0);
goto invalid_msg;
}
current += PAILLIER_ELEMENT_LENGTH;
}
- kq = GNUNET_malloc (sizeof (gcry_mpi_t) * count);
+ r_prime = GNUNET_malloc (sizeof (gcry_mpi_t) * count);
// Convert each kq[] to its MPI_value
for (i = 0; i < count; i++)
{
- if (gcry_mpi_scan (&kq[i], GCRYMPI_FMT_USG, current,
- PAILLIER_ELEMENT_LENGTH, &read))
+ if (0 != (rc = gcry_mpi_scan (&r_prime[i], GCRYMPI_FMT_USG, current,
+ PAILLIER_ELEMENT_LENGTH, &read)))
{
- GNUNET_log (GNUNET_ERROR_TYPE_WARNING, _ ("Could not translate Kq[%d]to an MPI value!\n"), i);
+ LOG_GCRY (GNUNET_ERROR_TYPE_DEBUG, "gcry_mpi_scan", rc);
+ GNUNET_break_op (0);
goto invalid_msg;
}
current += PAILLIER_ELEMENT_LENGTH;
}
- session->product = compute_scalar_product (session, kp, kq, s, stick);
+ session->product = compute_scalar_product (session, r, r_prime, s, s_prime);
invalid_msg:
if (s)
gcry_mpi_release (s);
- if (stick)
- gcry_mpi_release (stick);
- for (i = 0; kp && i < count; i++)
- if (kp[i]) gcry_mpi_release (kp[i]);
- for (i = 0; kq && i < count; i++)
- if (kq[i]) gcry_mpi_release (kq[i]);
- GNUNET_free_non_null (kp);
- GNUNET_free_non_null (kq);
+ if (s_prime)
+ gcry_mpi_release (s_prime);
+ for (i = 0; r && i < count; i++)
+ if (r[i]) gcry_mpi_release (r[i]);
+ for (i = 0; r_prime && i < count; i++)
+ if (r_prime[i]) gcry_mpi_release (r_prime[i]);
+ GNUNET_free_non_null (r);
+ GNUNET_free_non_null (r_prime);
session->state = FINALIZED;
// the tunnel has done its job, terminate our connection and the tunnel
// the peer will be notified that the tunnel was destroyed via tunnel_destruction_handler
GNUNET_CONTAINER_DLL_remove (from_client_head, from_client_tail, session);
- GNUNET_SCHEDULER_add_now (&destroy_tunnel, session);
+ GNUNET_SCHEDULER_add_now (&destroy_tunnel, session); // FIXME: use after free!
// send message with product to client
- GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_SECONDS,
- &prepare_client_response, session);
+ /* session->current_task = */ GNUNET_SCHEDULER_add_now (&prepare_client_response, session); // FIXME: dangling task!
return GNUNET_OK;
// if success: terminate the session gracefully, else terminate with error
}
curr->state = FINALIZED;
}
}
-
- if (my_core)
- {
- GNUNET_CORE_disconnect (my_core);
- my_core = NULL;
- }
-
if (my_mesh)
{
GNUNET_MESH_disconnect (my_mesh);
}
-/**
- * To be called on core init/fail.
- *
- * @param cls closure, NULL
- * @param server handle to the server for this service
- * @param my_identity the public identity of this peer
- */
-static void
-core_init (void *cls, struct GNUNET_CORE_Handle *server,
- const struct GNUNET_PeerIdentity *my_identity)
-{
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, _ ("Core initialized\n"));
- me = *my_identity;
-}
-
-
/**
* Initialization of the program and message handlers
*
const struct GNUNET_CONFIGURATION_Handle *c)
{
static const struct GNUNET_SERVER_MessageHandler server_handlers[] = {
- {&handle_client_request, NULL, GNUNET_MESSAGE_TYPE_VECTORPRODUCT_CLIENT_TO_ALICE, 0},
- {&handle_client_request, NULL, GNUNET_MESSAGE_TYPE_VECTORPRODUCT_CLIENT_TO_BOB, 0},
+ {&handle_client_request, NULL, GNUNET_MESSAGE_TYPE_SCALARPRODUCT_CLIENT_TO_ALICE, 0},
+ {&handle_client_request, NULL, GNUNET_MESSAGE_TYPE_SCALARPRODUCT_CLIENT_TO_BOB, 0},
{NULL, NULL, 0, 0}
};
static const struct GNUNET_MESH_MessageHandler mesh_handlers[] = {
- { &handle_service_request, GNUNET_MESSAGE_TYPE_VECTORPRODUCT_ALICE_TO_BOB, 0},
- { &handle_service_response, GNUNET_MESSAGE_TYPE_VECTORPRODUCT_BOB_TO_ALICE, 0},
- {NULL, 0, 0}
- };
- static const struct GNUNET_CORE_MessageHandler core_handlers[] = {
+ { &handle_service_request, GNUNET_MESSAGE_TYPE_SCALARPRODUCT_ALICE_TO_BOB, 0},
+ { &handle_service_response, GNUNET_MESSAGE_TYPE_SCALARPRODUCT_BOB_TO_ALICE, 0},
{NULL, 0, 0}
};
static GNUNET_MESH_ApplicationType mesh_types[] = {
- GNUNET_APPLICATION_TYPE_VECTORPRODUCT,
+ GNUNET_APPLICATION_TYPE_SCALARPRODUCT,
GNUNET_APPLICATION_TYPE_END
};
//generate private/public key set
- GNUNET_log (GNUNET_ERROR_TYPE_INFO, _ ("Generating rsa-key.\n"));
+ GNUNET_log (GNUNET_ERROR_TYPE_INFO, _ ("Generating Paillier-Keyset.\n"));
generate_keyset ();
// register server callbacks and disconnect handler
GNUNET_SERVER_add_handlers (server, server_handlers);
GNUNET_SERVER_disconnect_notify (server,
&handle_client_disconnect,
NULL);
-
- my_core = GNUNET_CORE_connect (c, NULL, &core_init, NULL, NULL, NULL,
- GNUNET_NO, NULL, GNUNET_NO, core_handlers);
- if (!my_core)
- {
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _ ("Connect to CORE failed\n"));
- return;
- }
+ GNUNET_break (GNUNET_OK ==
+ GNUNET_CRYPTO_get_host_identity (c,
+ &me));
my_mesh = GNUNET_MESH_connect (c, NULL,
&tunnel_incoming_handler,
&tunnel_destruction_handler,
/**
- * The main function for the vectorproduct service.
+ * The main function for the scalarproduct service.
*
* @param argc number of arguments from the command line
* @param argv command line arguments
{
return (GNUNET_OK ==
GNUNET_SERVICE_run (argc, argv,
- "vectorproduct",
+ "scalarproduct",
GNUNET_SERVICE_OPTION_NONE,
&run, NULL)) ? 0 : 1;
}