diff options
-rw-r--r-- | src/scalarproduct/gnunet-service-scalarproduct.c | 90 | ||||
-rw-r--r-- | src/scalarproduct/scalarproduct.h | 5 |
2 files changed, 92 insertions, 3 deletions
diff --git a/src/scalarproduct/gnunet-service-scalarproduct.c b/src/scalarproduct/gnunet-service-scalarproduct.c index b2a84fdb6..dafcde3a4 100644 --- a/src/scalarproduct/gnunet-service-scalarproduct.c +++ b/src/scalarproduct/gnunet-service-scalarproduct.c | |||
@@ -127,6 +127,11 @@ struct ServiceSession | |||
127 | * already transferred elements (sent/received) for multipart messages, less or equal than used_element_count for | 127 | * already transferred elements (sent/received) for multipart messages, less or equal than used_element_count for |
128 | */ | 128 | */ |
129 | uint32_t transferred_element_count; | 129 | uint32_t transferred_element_count; |
130 | |||
131 | /** | ||
132 | * index of the last transferred element for multipart messages | ||
133 | */ | ||
134 | uint32_t last_processed_element; | ||
130 | 135 | ||
131 | /** | 136 | /** |
132 | * how many bytes the mask is long. | 137 | * how many bytes the mask is long. |
@@ -497,6 +502,13 @@ compute_square_sum (gcry_mpi_t * vector, uint32_t length) | |||
497 | } | 502 | } |
498 | 503 | ||
499 | 504 | ||
505 | static void | ||
506 | prepare_service_request_multipart (void *cls, | ||
507 | const struct GNUNET_SCHEDULER_TaskContext *tc); | ||
508 | static void | ||
509 | prepare_service_response_multipart (void *cls, | ||
510 | const struct GNUNET_SCHEDULER_TaskContext *tc); | ||
511 | |||
500 | /** | 512 | /** |
501 | * Primitive callback for copying over a message, as they | 513 | * Primitive callback for copying over a message, as they |
502 | * usually are too complex to be handled in the callback itself. | 514 | * usually are too complex to be handled in the callback itself. |
@@ -533,7 +545,7 @@ do_send_message (void *cls, size_t size, void *buf) | |||
533 | session->service_transmit_handle = NULL; | 545 | session->service_transmit_handle = NULL; |
534 | // reset flags for sending | 546 | // reset flags for sending |
535 | if ((session->state != WAITING_FOR_MULTIPART_TRANSMISSION) && (session->used_element_count != session->transferred_element_count)) | 547 | if ((session->state != WAITING_FOR_MULTIPART_TRANSMISSION) && (session->used_element_count != session->transferred_element_count)) |
536 | prepare_service_request_multipart(session); | 548 | prepare_service_request_multipart(session, NULL); |
537 | //TODO we have sent a message and now need to trigger trigger the next multipart message sending | 549 | //TODO we have sent a message and now need to trigger trigger the next multipart message sending |
538 | break; | 550 | break; |
539 | case GNUNET_MESSAGE_TYPE_SCALARPRODUCT_BOB_TO_ALICE: | 551 | case GNUNET_MESSAGE_TYPE_SCALARPRODUCT_BOB_TO_ALICE: |
@@ -541,7 +553,7 @@ do_send_message (void *cls, size_t size, void *buf) | |||
541 | //else | 553 | //else |
542 | session->service_transmit_handle = NULL; | 554 | session->service_transmit_handle = NULL; |
543 | if ((session->state != WAITING_FOR_MULTIPART_TRANSMISSION) && (session->used_element_count != session->transferred_element_count)) | 555 | if ((session->state != WAITING_FOR_MULTIPART_TRANSMISSION) && (session->used_element_count != session->transferred_element_count)) |
544 | prepare_service_response_multipart(session); | 556 | prepare_service_response_multipart(session, NULL); |
545 | break; | 557 | break; |
546 | default: | 558 | default: |
547 | session->service_transmit_handle = NULL; | 559 | session->service_transmit_handle = NULL; |
@@ -1154,7 +1166,77 @@ except: | |||
1154 | return ret; | 1166 | return ret; |
1155 | } | 1167 | } |
1156 | 1168 | ||
1169 | static void | ||
1170 | prepare_service_request_multipart (void *cls, | ||
1171 | const struct GNUNET_SCHEDULER_TaskContext *tc) | ||
1172 | { | ||
1173 | struct ServiceSession * session = cls; | ||
1174 | unsigned char * current; | ||
1175 | unsigned char * element_exported; | ||
1176 | struct GNUNET_SCALARPRODUCT_service_request * msg; | ||
1177 | unsigned int i; | ||
1178 | unsigned int j; | ||
1179 | uint32_t msg_length; | ||
1180 | uint32_t todo_count; | ||
1181 | size_t element_length = 0; // initialized by gcry_mpi_print, but the compiler doesn't know that | ||
1182 | gcry_mpi_t a; | ||
1183 | uint32_t value; | ||
1184 | |||
1185 | msg_length = sizeof (struct GNUNET_SCALARPRODUCT_multipart_message); | ||
1186 | todo_count = session->used_element_count - session->transferred_element_count; | ||
1157 | 1187 | ||
1188 | if (todo_count > MULTIPART_ELEMENT_CAPACITY){ | ||
1189 | // send the currently possible maximum chunk, else send all remaining | ||
1190 | todo_count = MULTIPART_ELEMENT_CAPACITY; | ||
1191 | } | ||
1192 | msg_length += todo_count * PAILLIER_ELEMENT_LENGTH; | ||
1193 | msg = GNUNET_malloc (msg_length); | ||
1194 | |||
1195 | element_exported = GNUNET_malloc (PAILLIER_ELEMENT_LENGTH); | ||
1196 | a = gcry_mpi_new (KEYBITS * 2); | ||
1197 | current = (unsigned char *) &msg[1]; | ||
1198 | // encrypt our vector and generate string representations | ||
1199 | for (i = session->last_processed_element, j = 0; i < session->element_count; i++) | ||
1200 | { | ||
1201 | // is this a used element? | ||
1202 | if (session->mask[i / 8] & 1 << (i % 8)) | ||
1203 | { | ||
1204 | if (todo_count <= j) | ||
1205 | break; //reached end of this message, can't include more | ||
1206 | |||
1207 | memset(element_exported, 0, PAILLIER_ELEMENT_LENGTH); | ||
1208 | value = session->vector[i] >= 0 ? session->vector[i] : -session->vector[i]; | ||
1209 | |||
1210 | a = gcry_mpi_set_ui (a, 0); | ||
1211 | // long to gcry_mpi_t | ||
1212 | if (session->vector[i] < 0) | ||
1213 | gcry_mpi_sub_ui (a, a, value); | ||
1214 | else | ||
1215 | gcry_mpi_add_ui (a, a, value); | ||
1216 | |||
1217 | session->a[session->transferred_element_count + j++] = gcry_mpi_set (NULL, a); | ||
1218 | gcry_mpi_add (a, a, my_offset); | ||
1219 | encrypt_element (a, a, my_g, my_n, my_nsquare); | ||
1220 | |||
1221 | // get representation as string | ||
1222 | // we always supply some value, so gcry_mpi_print fails only if it can't reserve memory | ||
1223 | GNUNET_assert (!gcry_mpi_print (GCRYMPI_FMT_USG, | ||
1224 | element_exported, PAILLIER_ELEMENT_LENGTH, | ||
1225 | &element_length, | ||
1226 | a)); | ||
1227 | |||
1228 | // move buffer content to the end of the buffer so it can easily be read by libgcrypt. also this now has fixed size | ||
1229 | adjust (element_exported, element_length, PAILLIER_ELEMENT_LENGTH); | ||
1230 | |||
1231 | // copy over to the message | ||
1232 | memcpy (current, element_exported, PAILLIER_ELEMENT_LENGTH); | ||
1233 | current += PAILLIER_ELEMENT_LENGTH; | ||
1234 | } | ||
1235 | } | ||
1236 | gcry_mpi_release (a); | ||
1237 | GNUNET_free(element_exported); | ||
1238 | |||
1239 | } | ||
1158 | /** | 1240 | /** |
1159 | * Executed by Alice, fills in a service-request message and sends it to the given peer | 1241 | * Executed by Alice, fills in a service-request message and sends it to the given peer |
1160 | * | 1242 | * |
@@ -1278,8 +1360,10 @@ prepare_service_request (void *cls, | |||
1278 | session); | 1360 | session); |
1279 | return; | 1361 | return; |
1280 | } | 1362 | } |
1281 | if (session->transferred_element_count != session->used_element_count) | 1363 | if (session->transferred_element_count != session->used_element_count){ |
1282 | session->state = WAITING_FOR_MULTIPART_TRANSMISSION; | 1364 | session->state = WAITING_FOR_MULTIPART_TRANSMISSION; |
1365 | session->last_processed_element = i; | ||
1366 | } | ||
1283 | else | 1367 | else |
1284 | //singlepart message | 1368 | //singlepart message |
1285 | session->state = WAITING_FOR_SERVICE_RESPONSE; | 1369 | session->state = WAITING_FOR_SERVICE_RESPONSE; |
diff --git a/src/scalarproduct/scalarproduct.h b/src/scalarproduct/scalarproduct.h index 18e782ac0..d476ae8ff 100644 --- a/src/scalarproduct/scalarproduct.h +++ b/src/scalarproduct/scalarproduct.h | |||
@@ -49,6 +49,11 @@ extern "C" | |||
49 | #define PAILLIER_ELEMENT_LENGTH (2*KEYBITS/8 +1) | 49 | #define PAILLIER_ELEMENT_LENGTH (2*KEYBITS/8 +1) |
50 | 50 | ||
51 | /** | 51 | /** |
52 | * Maximum count of elements we can put into a multipart message | ||
53 | */ | ||
54 | #define MULTIPART_ELEMENT_CAPACITY ((GNUNET_SERVER_MAX_MESSAGE_SIZE - 1 - sizeof (struct GNUNET_SCALARPRODUCT_multipart_message)) / PAILLIER_ELEMENT_LENGTH) | ||
55 | |||
56 | /** | ||
52 | * Log an error message at log-level 'level' that indicates | 57 | * Log an error message at log-level 'level' that indicates |
53 | * a failure of the command 'cmd' with the message given | 58 | * a failure of the command 'cmd' with the message given |
54 | * by gcry_strerror(rc). | 59 | * by gcry_strerror(rc). |