* Bob's permutation q of R
*/
gcry_mpi_t * r_prime;
+
+ /**
+ * Bob's s
+ */
+ gcry_mpi_t s;
+
+ /**
+ * Bob's s'
+ */
+ gcry_mpi_t s_prime;
/**
* Bobs matching response session from the client
* @return product as MPI, never NULL
*/
static gcry_mpi_t
-compute_scalar_product (struct ServiceSession * session,
- gcry_mpi_t * r, gcry_mpi_t * r_prime, gcry_mpi_t s, gcry_mpi_t s_prime)
+compute_scalar_product (struct ServiceSession * session)
{
uint32_t count;
gcry_mpi_t t;
// 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 (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);
+ decrypt_element (session->r[i], session->r[i], my_mu, my_lambda, my_n, my_nsquare);
+ gcry_mpi_sub (session->r[i], session->r[i], my_offset);
+ gcry_mpi_sub (session->r[i], session->r[i], my_offset);
+ decrypt_element (session->r_prime[i], session->r_prime[i], my_mu, my_lambda, my_n, my_nsquare);
+ gcry_mpi_sub (session->r_prime[i], session->r_prime[i], my_offset);
+ gcry_mpi_sub (session->r_prime[i], session->r_prime[i], my_offset);
}
// calculate t = sum(ai)
// calculate U
u = gcry_mpi_new (0);
- tmp = compute_square_sum (r, count);
+ tmp = compute_square_sum (session->r, count);
gcry_mpi_sub (u, u, tmp);
gcry_mpi_release (tmp);
//calculate U'
utick = gcry_mpi_new (0);
- tmp = compute_square_sum (r_prime, count);
+ tmp = compute_square_sum (session->r_prime, count);
gcry_mpi_sub (utick, utick, 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);
+ decrypt_element (session->s, session->s, my_mu, my_lambda, my_n, my_nsquare);
+ decrypt_element (session->s_prime, session->s_prime, my_mu, my_lambda, my_n, my_nsquare);
// compute P
- gcry_mpi_add (p, s, t);
+ gcry_mpi_add (p, session->s, t);
gcry_mpi_add (p, p, u);
// compute P'
- gcry_mpi_add (ptick, s_prime, t);
+ gcry_mpi_add (ptick, session->s_prime, t);
gcry_mpi_add (ptick, ptick, utick);
gcry_mpi_release (t);
struct ServiceSession * session;
const struct GNUNET_SCALARPRODUCT_multipart_message * msg = (const struct GNUNET_SCALARPRODUCT_multipart_message *) message;
uint32_t used_elements;
- uint32_t contained_elements;
+ uint32_t contained_elements=0;
uint32_t msg_length;
unsigned char * current;
- struct ServiceSession * responder_session;
int32_t i = -1;
// are we in the correct state?
session = (struct ServiceSession *) * tunnel_ctx;
- if (BOB != session->role) {
- goto except;
- }
- if (WAITING_FOR_MULTIPART_TRANSMISSION != session->state) {
- goto except;
+ if ((BOB != session->role) || (WAITING_FOR_MULTIPART_TRANSMISSION != session->state)) {
+ GNUNET_break_op (0);
+ return GNUNET_OK;
}
// shorter than minimum?
if (ntohs (msg->header.size) <= sizeof (struct GNUNET_SCALARPRODUCT_multipart_message)) {
if (session->transferred_element_count == used_elements) {
// single part finished
session->state = SERVICE_REQUEST_RECEIVED;
- if (responder_session) {
+ if (session->response) {
GNUNET_log (GNUNET_ERROR_TYPE_INFO, _ ("Got session with key %s and a matching element set, processing.\n"), GNUNET_h2s (&session->key));
- if (GNUNET_OK != compute_service_response (session, responder_session)) {
+ if (GNUNET_OK != compute_service_response (session, session->response)) {
//something went wrong, remove it again...
GNUNET_CONTAINER_DLL_remove (from_service_head, from_service_tail, session);
goto except;
return GNUNET_OK;
except:
- for (i = 0; i < session->transferred_element_count; i++)
+ for (i = 0; i < session->transferred_element_count + contained_elements; i++)
if (session->a[i])
gcry_mpi_release (session->a[i]);
gcry_sexp_release (session->remote_pubkey);
enum SessionState needed_state;
session = (struct ServiceSession *) * tunnel_ctx;
- if (BOB != session->role) {
- GNUNET_break_op (0);
- return GNUNET_SYSERR;
- }
- // is this tunnel already in use?
- if ((session->next) || (from_service_head == session)) {
+ if (WAITING_FOR_SERVICE_REQUEST != session->state) {
GNUNET_break_op (0);
- return GNUNET_SYSERR;
+ return GNUNET_OK;
}
// Check if message was sent by me, which would be bad!
if (!memcmp (&session->peer, &me, sizeof (struct GNUNET_PeerIdentity))) {
void **tunnel_ctx,
const struct GNUNET_MessageHeader * message)
{
+ struct ServiceSession * session;
+ const struct GNUNET_SCALARPRODUCT_multipart_message * msg = (const struct GNUNET_SCALARPRODUCT_multipart_message *) message;
+ unsigned char * current;
+ size_t read;
+ size_t i;
+ uint32_t contained_element_count=0;
+ size_t msg_size;
+ int rc;
+
+ GNUNET_assert (NULL != message);
+ // are we in the correct state?
+ session = (struct ServiceSession *) * tunnel_ctx;
+ if ((ALICE != session->role) || (WAITING_FOR_MULTIPART_TRANSMISSION != session->state)) {
+ GNUNET_break_op (0);
+ return GNUNET_OK;
+ }
+ // shorter than minimum?
+ if (ntohs (msg->header.size) <= sizeof (struct GNUNET_SCALARPRODUCT_multipart_message)) {
+ goto except;
+ }
+ contained_element_count = ntohl (msg->multipart_element_count);
+ msg_size = sizeof (struct GNUNET_SCALARPRODUCT_multipart_message)
+ + 2 * contained_element_count * PAILLIER_ELEMENT_LENGTH;
+ //sanity check: is the message as long as the message_count fields suggests?
+ if ((ntohs (msg->header.size) != msg_size) || (session->used_element_count < contained_element_count)) {
+ goto except;
+ }
+ current = (unsigned char *) &msg[1];
+ // Convert each k[][perm] to its MPI_value
+ for (i = 0; i < contained_element_count; i++) {
+ if (0 != (rc = gcry_mpi_scan (&session->r[i], GCRYMPI_FMT_USG, current,
+ PAILLIER_ELEMENT_LENGTH, &read))) {
+ LOG_GCRY (GNUNET_ERROR_TYPE_DEBUG, "gcry_mpi_scan", rc);
+ GNUNET_break_op (0);
+ goto except;
+ }
+ current += PAILLIER_ELEMENT_LENGTH;
+ if (0 != (rc = gcry_mpi_scan (&session->r_prime[i], GCRYMPI_FMT_USG, current,
+ PAILLIER_ELEMENT_LENGTH, &read))) {
+ LOG_GCRY (GNUNET_ERROR_TYPE_DEBUG, "gcry_mpi_scan", rc);
+ GNUNET_break_op (0);
+ goto except;
+ }
+ current += PAILLIER_ELEMENT_LENGTH;
+ }
+ session->transferred_element_count += contained_element_count;
+ if (session->transferred_element_count != session->used_element_count)
+ return GNUNET_OK;
+ session->state = SERVICE_RESPONSE_RECEIVED;
+ session->product = compute_scalar_product (session);
+ return GNUNET_SYSERR; // terminate the tunnel right away, we are done here!
+except:
+ GNUNET_break_op (0);
+ if (session->s)
+ gcry_mpi_release (session->s);
+ if (session->s_prime)
+ gcry_mpi_release (session->s_prime);
+ for (i = 0; session->r && i < session->transferred_element_count; i++)
+ if (session->r[i]) gcry_mpi_release (session->r[i]);
+ for (i = 0; session->r_prime && i < session->transferred_element_count; i++)
+ if (session->r_prime[i]) gcry_mpi_release (session->r_prime[i]);
+ GNUNET_free_non_null (session->r);
+ GNUNET_free_non_null (session->r_prime);
+
+ session->tunnel = NULL;
+ // send message with product to client
+ session->client_notification_task =
+ GNUNET_SCHEDULER_add_now (&prepare_client_response,
+ session);
+ // 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
+ // just close the connection, as recommended by Christian
return GNUNET_SYSERR;
}
struct ServiceSession * session;
const struct GNUNET_SCALARPRODUCT_service_response * msg = (const struct GNUNET_SCALARPRODUCT_service_response *) message;
unsigned char * current;
- uint32_t count;
- gcry_mpi_t s = NULL;
- gcry_mpi_t s_prime = NULL;
size_t read;
size_t i;
- uint32_t contained_element_count;
+ uint32_t contained_element_count=0;
size_t msg_size;
- gcry_mpi_t * r = NULL;
- gcry_mpi_t * r_prime = NULL;
int rc;
GNUNET_assert (NULL != message);
session = (struct ServiceSession *) * tunnel_ctx;
- if (ALICE != session->role) {
+ if (session->state != WAITING_FOR_SERVICE_REQUEST) {
GNUNET_break_op (0);
- return GNUNET_SYSERR;
+ return GNUNET_OK;
}
-
- count = session->used_element_count;
- session->product = NULL;
- session->state = SERVICE_RESPONSE_RECEIVED;
-
- //we need at least a peer and one message id to compare
+ //we need at least a full message
if (sizeof (struct GNUNET_SCALARPRODUCT_service_response) > ntohs (msg->header.size)) {
GNUNET_break_op (0);
goto invalid_msg;
+ 2 * contained_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 != contained_element_count)) {
+ if ((ntohs (msg->header.size) != msg_size) || (session->used_element_count < contained_element_count)) {
GNUNET_break_op (0);
goto invalid_msg;
}
-
+ session->state = WAITING_FOR_MULTIPART_TRANSMISSION;
+ session->transferred_element_count = contained_element_count;
//convert s
current = (unsigned char *) &msg[1];
- if (0 != (rc = gcry_mpi_scan (&s, GCRYMPI_FMT_USG, current,
+ if (0 != (rc = gcry_mpi_scan (&session->s, GCRYMPI_FMT_USG, current,
PAILLIER_ELEMENT_LENGTH, &read))) {
LOG_GCRY (GNUNET_ERROR_TYPE_DEBUG, "gcry_mpi_scan", rc);
GNUNET_break_op (0);
}
current += PAILLIER_ELEMENT_LENGTH;
//convert stick
- if (0 != (rc = gcry_mpi_scan (&s_prime, GCRYMPI_FMT_USG, current,
+ if (0 != (rc = gcry_mpi_scan (&session->s_prime, GCRYMPI_FMT_USG, current,
PAILLIER_ELEMENT_LENGTH, &read))) {
LOG_GCRY (GNUNET_ERROR_TYPE_DEBUG, "gcry_mpi_scan", rc);
GNUNET_break_op (0);
goto invalid_msg;
}
current += PAILLIER_ELEMENT_LENGTH;
-
- r = GNUNET_malloc (sizeof (gcry_mpi_t) * count);
- // Convert each kp[] to its MPI_value
- for (i = 0; i < count; i++) {
- if (0 != (rc = gcry_mpi_scan (&r[i], GCRYMPI_FMT_USG, current,
+ session->r = GNUNET_malloc (sizeof (gcry_mpi_t) * session->used_element_count);
+ session->r_prime = GNUNET_malloc (sizeof (gcry_mpi_t) * session->used_element_count);
+ // Convert each k[][perm] to its MPI_value
+ for (i = 0; i < contained_element_count; i++) {
+ if (0 != (rc = gcry_mpi_scan (&session->r[i], GCRYMPI_FMT_USG, current,
PAILLIER_ELEMENT_LENGTH, &read))) {
LOG_GCRY (GNUNET_ERROR_TYPE_DEBUG, "gcry_mpi_scan", rc);
GNUNET_break_op (0);
goto invalid_msg;
}
current += PAILLIER_ELEMENT_LENGTH;
- }
-
-
- r_prime = GNUNET_malloc (sizeof (gcry_mpi_t) * count);
- // Convert each kq[] to its MPI_value
- for (i = 0; i < count; i++) {
- if (0 != (rc = gcry_mpi_scan (&r_prime[i], GCRYMPI_FMT_USG, current,
+ if (0 != (rc = gcry_mpi_scan (&session->r_prime[i], GCRYMPI_FMT_USG, current,
PAILLIER_ELEMENT_LENGTH, &read))) {
LOG_GCRY (GNUNET_ERROR_TYPE_DEBUG, "gcry_mpi_scan", rc);
GNUNET_break_op (0);
}
current += PAILLIER_ELEMENT_LENGTH;
}
- session->product = compute_scalar_product (session, r, r_prime, s, s_prime);
+ if (session->transferred_element_count != session->used_element_count)
+ return GNUNET_OK; //wait for the other multipart chunks
+
+ session->state = SERVICE_RESPONSE_RECEIVED;
+ session->product = compute_scalar_product (session);
+ return GNUNET_SYSERR; // terminate the tunnel right away, we are done here!
invalid_msg:
- if (s)
- gcry_mpi_release (s);
- 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);
+ if (session->s)
+ gcry_mpi_release (session->s);
+ if (session->s_prime)
+ gcry_mpi_release (session->s_prime);
+ for (i = 0; session->r && i < contained_element_count; i++)
+ if (session->r[i]) gcry_mpi_release (session->r[i]);
+ for (i = 0; session->r_prime && i < contained_element_count; i++)
+ if (session->r_prime[i]) gcry_mpi_release (session->r_prime[i]);
+ GNUNET_free_non_null (session->r);
+ GNUNET_free_non_null (session->r_prime);
session->tunnel = NULL;
// send message with product to client