diff options
Diffstat (limited to 'src/secretsharing')
-rwxr-xr-x | src/secretsharing/gnunet-secretsharing-profiler.c | 265 | ||||
-rw-r--r-- | src/secretsharing/gnunet-service-secretsharing.c | 506 | ||||
-rw-r--r-- | src/secretsharing/secretsharing.h | 6 | ||||
-rw-r--r-- | src/secretsharing/secretsharing_api.c | 181 | ||||
-rw-r--r-- | src/secretsharing/secretsharing_common.c | 3 | ||||
-rw-r--r-- | src/secretsharing/test_secretsharing.conf | 2 |
6 files changed, 746 insertions, 217 deletions
diff --git a/src/secretsharing/gnunet-secretsharing-profiler.c b/src/secretsharing/gnunet-secretsharing-profiler.c index 01eb49a2d..b718e8a27 100755 --- a/src/secretsharing/gnunet-secretsharing-profiler.c +++ b/src/secretsharing/gnunet-secretsharing-profiler.c | |||
@@ -28,17 +28,48 @@ | |||
28 | #include "gnunet_secretsharing_service.h" | 28 | #include "gnunet_secretsharing_service.h" |
29 | #include "gnunet_testbed_service.h" | 29 | #include "gnunet_testbed_service.h" |
30 | 30 | ||
31 | /** | ||
32 | * How many peers should participate in the key generation? | ||
33 | */ | ||
31 | static unsigned int num_peers = 3; | 34 | static unsigned int num_peers = 3; |
32 | 35 | ||
36 | /** | ||
37 | * What should the threshold for then key be? | ||
38 | */ | ||
33 | static unsigned int threshold = 2; | 39 | static unsigned int threshold = 2; |
34 | 40 | ||
41 | /** | ||
42 | * Should we try to decrypt a value after the key generation? | ||
43 | */ | ||
44 | static unsigned int decrypt = GNUNET_NO; | ||
45 | |||
46 | /** | ||
47 | * When would we like to see the operation finished? | ||
48 | */ | ||
35 | static struct GNUNET_TIME_Relative timeout; | 49 | static struct GNUNET_TIME_Relative timeout; |
36 | 50 | ||
51 | /** | ||
52 | * Handles for secretsharing sessions. | ||
53 | */ | ||
37 | static struct GNUNET_SECRETSHARING_Session **session_handles; | 54 | static struct GNUNET_SECRETSHARING_Session **session_handles; |
38 | 55 | ||
56 | static struct GNUNET_SECRETSHARING_DecryptionHandle **decrypt_handles; | ||
57 | |||
58 | /** | ||
59 | * Shares we got from the distributed key generation. | ||
60 | */ | ||
61 | static struct GNUNET_SECRETSHARING_Share **shares; | ||
62 | |||
63 | static struct GNUNET_SECRETSHARING_PublicKey common_pubkey; | ||
64 | |||
65 | /** | ||
66 | * ??? | ||
67 | */ | ||
39 | static struct GNUNET_TESTBED_Operation **testbed_operations; | 68 | static struct GNUNET_TESTBED_Operation **testbed_operations; |
40 | 69 | ||
41 | static unsigned int num_connected_handles; | 70 | static unsigned int num_connected_sessions; |
71 | |||
72 | static unsigned int num_connected_decrypt; | ||
42 | 73 | ||
43 | static struct GNUNET_TESTBED_Peer **peers; | 74 | static struct GNUNET_TESTBED_Peer **peers; |
44 | 75 | ||
@@ -46,10 +77,18 @@ static struct GNUNET_PeerIdentity *peer_ids; | |||
46 | 77 | ||
47 | static unsigned int num_retrieved_peer_ids; | 78 | static unsigned int num_retrieved_peer_ids; |
48 | 79 | ||
80 | static unsigned int num_generated; | ||
81 | |||
82 | static unsigned int num_decrypted; | ||
83 | |||
49 | static struct GNUNET_HashCode session_id; | 84 | static struct GNUNET_HashCode session_id; |
50 | 85 | ||
51 | static int verbose; | 86 | static int verbose; |
52 | 87 | ||
88 | struct GNUNET_SECRETSHARING_Plaintext reference_plaintext; | ||
89 | |||
90 | struct GNUNET_SECRETSHARING_Ciphertext ciphertext; | ||
91 | |||
53 | 92 | ||
54 | /** | 93 | /** |
55 | * Signature of the event handler function called by the | 94 | * Signature of the event handler function called by the |
@@ -76,10 +115,47 @@ controller_cb (void *cls, | |||
76 | * operation has executed successfully. | 115 | * operation has executed successfully. |
77 | */ | 116 | */ |
78 | static void | 117 | static void |
79 | connect_complete (void *cls, | 118 | session_connect_complete (void *cls, |
80 | struct GNUNET_TESTBED_Operation *op, | 119 | struct GNUNET_TESTBED_Operation *op, |
81 | void *ca_result, | 120 | void *ca_result, |
82 | const char *emsg) | 121 | const char *emsg) |
122 | { | ||
123 | |||
124 | if (NULL != emsg) | ||
125 | { | ||
126 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
127 | "testbed connect emsg: %s\n", | ||
128 | emsg); | ||
129 | GNUNET_assert (0); | ||
130 | } | ||
131 | |||
132 | num_connected_sessions++; | ||
133 | |||
134 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, | ||
135 | "dkg: session connect complete\n"); | ||
136 | |||
137 | if (num_connected_sessions == num_peers) | ||
138 | { | ||
139 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, | ||
140 | "dkg: all peers connected\n"); | ||
141 | } | ||
142 | } | ||
143 | |||
144 | |||
145 | /** | ||
146 | * Callback to be called when a service connect operation is completed | ||
147 | * | ||
148 | * @param cls the callback closure from functions generating an operation | ||
149 | * @param op the operation that has been finished | ||
150 | * @param ca_result the service handle returned from GNUNET_TESTBED_ConnectAdapter() | ||
151 | * @param emsg error message in case the operation has failed; will be NULL if | ||
152 | * operation has executed successfully. | ||
153 | */ | ||
154 | static void | ||
155 | decrypt_connect_complete (void *cls, | ||
156 | struct GNUNET_TESTBED_Operation *op, | ||
157 | void *ca_result, | ||
158 | const char *emsg) | ||
83 | { | 159 | { |
84 | 160 | ||
85 | if (NULL != emsg) | 161 | if (NULL != emsg) |
@@ -90,35 +166,164 @@ connect_complete (void *cls, | |||
90 | GNUNET_assert (0); | 166 | GNUNET_assert (0); |
91 | } | 167 | } |
92 | 168 | ||
93 | num_connected_handles++; | 169 | num_connected_decrypt++; |
94 | 170 | ||
95 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, | 171 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, |
96 | "connect complete\n"); | 172 | "decrypt: session connect complete\n"); |
97 | 173 | ||
98 | if (num_connected_handles == num_peers) | 174 | if (num_connected_decrypt == num_peers) |
99 | { | 175 | { |
100 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, | 176 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, |
101 | "all peers connected\n"); | 177 | "decrypt: all peers connected\n"); |
178 | } | ||
179 | } | ||
180 | |||
181 | |||
182 | /** | ||
183 | * Called when a decryption has succeeded. | ||
184 | * | ||
185 | * @param cls Plaintext | ||
186 | * @param plaintext Plaintext | ||
187 | */ | ||
188 | static void decrypt_cb (void *cls, | ||
189 | const struct GNUNET_SECRETSHARING_Plaintext *plaintext) | ||
190 | { | ||
191 | struct GNUNET_SECRETSHARING_DecryptionHandle **dhp = cls; | ||
192 | unsigned int n = dhp - decrypt_handles; | ||
193 | num_decrypted++; | ||
194 | |||
195 | *dhp = NULL; | ||
196 | |||
197 | if (NULL == plaintext) | ||
198 | { | ||
199 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "decrypt failed for peer %u\n", n); | ||
200 | return; | ||
201 | } | ||
202 | else if (0 == memcmp (&reference_plaintext, plaintext, sizeof (struct GNUNET_SECRETSHARING_Plaintext))) | ||
203 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, "decrypt got correct result for peer %u\n", n); | ||
204 | else | ||
205 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "decrypt got wrong result for peer %u\n", n); | ||
206 | |||
207 | if (num_decrypted == num_peers) | ||
208 | { | ||
209 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, "every peer decrypted\n"); | ||
210 | GNUNET_SCHEDULER_shutdown (); | ||
211 | } | ||
212 | |||
213 | *dhp = NULL; | ||
214 | } | ||
215 | |||
216 | |||
217 | |||
218 | /** | ||
219 | * Adapter function called to establish a connection to | ||
220 | * a service. | ||
221 | * | ||
222 | * @param cls closure | ||
223 | * @param cfg configuration of the peer to connect to; will be available until | ||
224 | * GNUNET_TESTBED_operation_done() is called on the operation returned | ||
225 | * from GNUNET_TESTBED_service_connect() | ||
226 | * @return service handle to return in 'op_result', NULL on error | ||
227 | */ | ||
228 | static void * | ||
229 | decrypt_connect_adapter (void *cls, | ||
230 | const struct GNUNET_CONFIGURATION_Handle *cfg) | ||
231 | { | ||
232 | struct GNUNET_SECRETSHARING_DecryptionHandle **hp = cls; | ||
233 | unsigned int n = hp - decrypt_handles; | ||
234 | |||
235 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, | ||
236 | "decrypt connect adapter, %d peers\n", | ||
237 | num_peers); | ||
238 | *hp = GNUNET_SECRETSHARING_decrypt (cfg, shares[n], &ciphertext, | ||
239 | GNUNET_TIME_relative_to_absolute (GNUNET_TIME_UNIT_MINUTES), | ||
240 | decrypt_cb, | ||
241 | hp); | ||
242 | |||
243 | return *hp; | ||
244 | } | ||
245 | |||
246 | |||
247 | /** | ||
248 | * Adapter function called to destroy a connection to | ||
249 | * a service. | ||
250 | * | ||
251 | * @param cls closure | ||
252 | * @param op_result service handle returned from the connect adapter | ||
253 | */ | ||
254 | static void | ||
255 | decrypt_disconnect_adapter(void *cls, void *op_result) | ||
256 | { | ||
257 | struct GNUNET_SECRETSHARING_DecryptionHandle **dh = cls; | ||
258 | if (NULL != *dh) | ||
259 | { | ||
260 | GNUNET_SECRETSHARING_decrypt_cancel (*dh); | ||
261 | *dh = NULL; | ||
102 | } | 262 | } |
103 | } | 263 | } |
104 | 264 | ||
105 | 265 | ||
106 | static void | 266 | static void |
107 | secret_ready_cb (void *cls, | 267 | secret_ready_cb (void *cls, |
108 | const struct GNUNET_SECRETSHARING_Share *my_share, | 268 | struct GNUNET_SECRETSHARING_Share *my_share, |
109 | const struct GNUNET_SECRETSHARING_PublicKey *public_key, | 269 | struct GNUNET_SECRETSHARING_PublicKey *public_key, |
110 | unsigned int num_ready_peers, | 270 | unsigned int num_ready_peers, |
111 | const struct GNUNET_PeerIdentity *ready_peers) | 271 | struct GNUNET_PeerIdentity *ready_peers) |
112 | { | 272 | { |
113 | struct GNUNET_SECRETSHARING_Session **sp = cls; | 273 | struct GNUNET_SECRETSHARING_Session **sp = cls; |
114 | unsigned int n = sp - session_handles; | 274 | unsigned int n = sp - session_handles; |
115 | if (NULL == my_share || NULL == public_key) | 275 | char pubkey_str[1024]; |
276 | char *ret; | ||
277 | |||
278 | num_generated++; | ||
279 | *sp = NULL; | ||
280 | shares[n] = my_share; | ||
281 | if (NULL == my_share) | ||
116 | { | 282 | { |
117 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, "key generation failed for peer #%u\n", n); | 283 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, "key generation failed for peer #%u\n", n); |
118 | return; | ||
119 | } | 284 | } |
120 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, "secret ready for peer #%u\n", n); | 285 | else |
121 | // FIXME: end profiler or try decryption if all secrets are ready | 286 | { |
287 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, "secret ready for peer #%u\n", n); | ||
288 | /* we're the first to get the key -> store it */ | ||
289 | if (num_generated == 1) | ||
290 | { | ||
291 | common_pubkey = *public_key; | ||
292 | } | ||
293 | else if (0 != memcmp (public_key, &common_pubkey, sizeof (struct GNUNET_SECRETSHARING_PublicKey))) | ||
294 | { | ||
295 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "generated public keys do not match\n"); | ||
296 | GNUNET_SCHEDULER_shutdown (); | ||
297 | return; | ||
298 | } | ||
299 | } | ||
300 | |||
301 | ret = GNUNET_STRINGS_data_to_string (public_key, sizeof *public_key, pubkey_str, 1024); | ||
302 | GNUNET_assert (NULL != ret); | ||
303 | *ret = '\0'; | ||
304 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, "key generation successful for peer #%u, pubkey %s\n", n, | ||
305 | pubkey_str); | ||
306 | |||
307 | // FIXME: destroy testbed operation | ||
308 | |||
309 | if (num_generated == num_peers) | ||
310 | { | ||
311 | int i; | ||
312 | if (GNUNET_NO == decrypt) | ||
313 | { | ||
314 | GNUNET_SCHEDULER_shutdown (); | ||
315 | return; | ||
316 | } | ||
317 | |||
318 | // compute g^42 | ||
319 | GNUNET_SECRETSHARING_plaintext_generate_i (&reference_plaintext, 42); | ||
320 | GNUNET_SECRETSHARING_encrypt (&common_pubkey, &reference_plaintext, &ciphertext); | ||
321 | |||
322 | // FIXME: store the ops somewhere! | ||
323 | for (i = 0; i < num_peers; i++) | ||
324 | GNUNET_TESTBED_service_connect (NULL, peers[i], "secretsharing", &decrypt_connect_complete, NULL, | ||
325 | &decrypt_connect_adapter, &decrypt_disconnect_adapter, &decrypt_handles[i]); | ||
326 | } | ||
122 | } | 327 | } |
123 | 328 | ||
124 | 329 | ||
@@ -133,8 +338,8 @@ secret_ready_cb (void *cls, | |||
133 | * @return service handle to return in 'op_result', NULL on error | 338 | * @return service handle to return in 'op_result', NULL on error |
134 | */ | 339 | */ |
135 | static void * | 340 | static void * |
136 | connect_adapter (void *cls, | 341 | session_connect_adapter (void *cls, |
137 | const struct GNUNET_CONFIGURATION_Handle *cfg) | 342 | const struct GNUNET_CONFIGURATION_Handle *cfg) |
138 | { | 343 | { |
139 | struct GNUNET_SECRETSHARING_Session **sp = cls; | 344 | struct GNUNET_SECRETSHARING_Session **sp = cls; |
140 | 345 | ||
@@ -152,6 +357,7 @@ connect_adapter (void *cls, | |||
152 | } | 357 | } |
153 | 358 | ||
154 | 359 | ||
360 | |||
155 | /** | 361 | /** |
156 | * Adapter function called to destroy a connection to | 362 | * Adapter function called to destroy a connection to |
157 | * a service. | 363 | * a service. |
@@ -160,9 +366,14 @@ connect_adapter (void *cls, | |||
160 | * @param op_result service handle returned from the connect adapter | 366 | * @param op_result service handle returned from the connect adapter |
161 | */ | 367 | */ |
162 | static void | 368 | static void |
163 | disconnect_adapter(void *cls, void *op_result) | 369 | session_disconnect_adapter (void *cls, void *op_result) |
164 | { | 370 | { |
165 | /* FIXME: what to do here? */ | 371 | struct GNUNET_SECRETSHARING_Session **sp = cls; |
372 | if (NULL != *sp) | ||
373 | { | ||
374 | GNUNET_SECRETSHARING_session_destroy (*sp); | ||
375 | *sp = NULL; | ||
376 | } | ||
166 | } | 377 | } |
167 | 378 | ||
168 | 379 | ||
@@ -195,8 +406,8 @@ peer_info_cb (void *cb_cls, | |||
195 | if (num_retrieved_peer_ids == num_peers) | 406 | if (num_retrieved_peer_ids == num_peers) |
196 | for (i = 0; i < num_peers; i++) | 407 | for (i = 0; i < num_peers; i++) |
197 | testbed_operations[i] = | 408 | testbed_operations[i] = |
198 | GNUNET_TESTBED_service_connect (NULL, peers[i], "secretsharing", connect_complete, NULL, | 409 | GNUNET_TESTBED_service_connect (NULL, peers[i], "secretsharing", session_connect_complete, NULL, |
199 | connect_adapter, disconnect_adapter, &session_handles[i]); | 410 | session_connect_adapter, session_disconnect_adapter, &session_handles[i]); |
200 | } | 411 | } |
201 | else | 412 | else |
202 | { | 413 | { |
@@ -238,8 +449,11 @@ test_master (void *cls, | |||
238 | 449 | ||
239 | peer_ids = GNUNET_malloc (num_peers * sizeof (struct GNUNET_PeerIdentity)); | 450 | peer_ids = GNUNET_malloc (num_peers * sizeof (struct GNUNET_PeerIdentity)); |
240 | 451 | ||
241 | session_handles = GNUNET_malloc (num_peers * sizeof (struct GNUNET_SECRETSHARING_Session *)); | 452 | session_handles = GNUNET_new_array (num_peers, struct GNUNET_SECRETSHARING_Session *); |
242 | testbed_operations = GNUNET_malloc (num_peers * sizeof (struct GNUNET_TESTBED_Operation *)); | 453 | decrypt_handles = GNUNET_new_array (num_peers, struct GNUNET_SECRETSHARING_DecryptionHandle *); |
454 | testbed_operations = GNUNET_new_array (num_peers, struct GNUNET_TESTBED_Operation *); | ||
455 | shares = GNUNET_new_array (num_peers, struct GNUNET_SECRETSHARING_Share *); | ||
456 | |||
243 | 457 | ||
244 | for (i = 0; i < num_peers; i++) | 458 | for (i = 0; i < num_peers; i++) |
245 | GNUNET_TESTBED_peer_get_information (peers[i], | 459 | GNUNET_TESTBED_peer_get_information (peers[i], |
@@ -305,6 +519,9 @@ main (int argc, char **argv) | |||
305 | { 'k', "threshold", NULL, | 519 | { 'k', "threshold", NULL, |
306 | gettext_noop ("threshold"), | 520 | gettext_noop ("threshold"), |
307 | GNUNET_YES, &GNUNET_GETOPT_set_uint, &threshold }, | 521 | GNUNET_YES, &GNUNET_GETOPT_set_uint, &threshold }, |
522 | { 'd', "decrypt", NULL, | ||
523 | gettext_noop ("also profile decryption"), | ||
524 | GNUNET_NO, &GNUNET_GETOPT_set_one, &decrypt }, | ||
308 | { 'V', "verbose", NULL, | 525 | { 'V', "verbose", NULL, |
309 | gettext_noop ("be more verbose (print received values)"), | 526 | gettext_noop ("be more verbose (print received values)"), |
310 | GNUNET_NO, &GNUNET_GETOPT_set_one, &verbose }, | 527 | GNUNET_NO, &GNUNET_GETOPT_set_one, &verbose }, |
diff --git a/src/secretsharing/gnunet-service-secretsharing.c b/src/secretsharing/gnunet-service-secretsharing.c index 38dabc3a8..1fcc4e351 100644 --- a/src/secretsharing/gnunet-service-secretsharing.c +++ b/src/secretsharing/gnunet-service-secretsharing.c | |||
@@ -33,6 +33,9 @@ | |||
33 | #include <gcrypt.h> | 33 | #include <gcrypt.h> |
34 | 34 | ||
35 | 35 | ||
36 | #define EXTRA_CHECKS 1 | ||
37 | |||
38 | |||
36 | /** | 39 | /** |
37 | * Info about a peer in a key generation session. | 40 | * Info about a peer in a key generation session. |
38 | */ | 41 | */ |
@@ -45,6 +48,7 @@ struct KeygenPeerInfo | |||
45 | 48 | ||
46 | /** | 49 | /** |
47 | * The peer's paillier public key. | 50 | * The peer's paillier public key. |
51 | * Freshly generated for each keygen session. | ||
48 | */ | 52 | */ |
49 | gcry_mpi_t paillier_n; | 53 | gcry_mpi_t paillier_n; |
50 | 54 | ||
@@ -92,7 +96,7 @@ struct DecryptPeerInfo | |||
92 | * Original index in the key generation round. | 96 | * Original index in the key generation round. |
93 | * Necessary for computing the lagrange coefficients. | 97 | * Necessary for computing the lagrange coefficients. |
94 | */ | 98 | */ |
95 | unsigned int real_index; | 99 | unsigned int original_index; |
96 | 100 | ||
97 | /** | 101 | /** |
98 | * Set to the partial decryption of | 102 | * Set to the partial decryption of |
@@ -323,52 +327,11 @@ static struct GNUNET_SERVER_Handle *srv; | |||
323 | 327 | ||
324 | 328 | ||
325 | /** | 329 | /** |
326 | * If target != size, move @a target bytes to the end of the size-sized | ||
327 | * buffer and zero out the first @a target - @a size bytes. | ||
328 | * | ||
329 | * @param buf original buffer | ||
330 | * @param size number of bytes in @a buf | ||
331 | * @param target target size of the buffer | ||
332 | */ | ||
333 | static void | ||
334 | adjust (unsigned char *buf, | ||
335 | size_t size, | ||
336 | size_t target) | ||
337 | { | ||
338 | if (size < target) | ||
339 | { | ||
340 | memmove (&buf[target - size], buf, size); | ||
341 | memset (buf, 0, target - size); | ||
342 | } | ||
343 | } | ||
344 | |||
345 | |||
346 | /** | ||
347 | * Print an MPI to a buffer, so that is contains the MPI's | ||
348 | * the little endian representation of size @a size. | ||
349 | * | ||
350 | * @param buf buffer to write to | ||
351 | * @param x mpi to be written in the buffer | ||
352 | * @param size how many bytes should the little endian binary | ||
353 | * representation of @a x use? | ||
354 | */ | ||
355 | static void | ||
356 | print_mpi_fixed (void *buf, gcry_mpi_t x, size_t size) | ||
357 | { | ||
358 | size_t written; | ||
359 | GNUNET_assert (0 == gcry_mpi_print (GCRYMPI_FMT_USG, | ||
360 | buf, size, &written, | ||
361 | x)); | ||
362 | adjust (buf, written, size); | ||
363 | } | ||
364 | |||
365 | |||
366 | /** | ||
367 | * Get the peer info belonging to a peer identity in a keygen session. | 330 | * Get the peer info belonging to a peer identity in a keygen session. |
368 | * | 331 | * |
369 | * @param ks the keygen session | 332 | * @param ks The keygen session. |
370 | * @param peer the peer identity | 333 | * @param peer The peer identity. |
371 | * @return the keygen peer info, or NULL if the peer could not be found | 334 | * @return The Keygen peer info, or NULL if the peer could not be found. |
372 | */ | 335 | */ |
373 | static struct KeygenPeerInfo * | 336 | static struct KeygenPeerInfo * |
374 | get_keygen_peer_info (const struct KeygenSession *ks, | 337 | get_keygen_peer_info (const struct KeygenSession *ks, |
@@ -385,13 +348,13 @@ get_keygen_peer_info (const struct KeygenSession *ks, | |||
385 | /** | 348 | /** |
386 | * Get the peer info belonging to a peer identity in a decrypt session. | 349 | * Get the peer info belonging to a peer identity in a decrypt session. |
387 | * | 350 | * |
388 | * @param ks the decrypt session | 351 | * @param ks The decrypt session. |
389 | * @param peer the peer identity | 352 | * @param peer The peer identity. |
390 | * @return the decrypt peer info, or NULL if the peer could not be found | 353 | * @return The decrypt peer info, or NULL if the peer could not be found. |
391 | */ | 354 | */ |
392 | static struct DecryptPeerInfo * | 355 | static struct DecryptPeerInfo * |
393 | get_decrypt_peer_info (const struct DecryptSession *ds, | 356 | get_decrypt_peer_info (const struct DecryptSession *ds, |
394 | const struct GNUNET_PeerIdentity *peer) | 357 | const struct GNUNET_PeerIdentity *peer) |
395 | { | 358 | { |
396 | unsigned int i; | 359 | unsigned int i; |
397 | for (i = 0; i < ds->share->num_peers; i++) | 360 | for (i = 0; i < ds->share->num_peers; i++) |
@@ -428,8 +391,8 @@ time_between (struct GNUNET_TIME_Absolute start, | |||
428 | /** | 391 | /** |
429 | * Compare two peer identities. Indended to be used with qsort or bsearch. | 392 | * Compare two peer identities. Indended to be used with qsort or bsearch. |
430 | * | 393 | * |
431 | * @param p1 some peer identity | 394 | * @param p1 Some peer identity. |
432 | * @param p2 some peer identity | 395 | * @param p2 Some peer identity. |
433 | * @return 1 if p1 > p2, -1 if p1 < p2 and 0 if p1 == p2. | 396 | * @return 1 if p1 > p2, -1 if p1 < p2 and 0 if p1 == p2. |
434 | */ | 397 | */ |
435 | static int | 398 | static int |
@@ -442,10 +405,10 @@ peer_id_cmp (const void *p1, const void *p2) | |||
442 | /** | 405 | /** |
443 | * Get the index of a peer in an array of peers | 406 | * Get the index of a peer in an array of peers |
444 | * | 407 | * |
445 | * @param haystack array of peers | 408 | * @param haystack Array of peers. |
446 | * @param n size of @a haystack | 409 | * @param n Size of @a haystack. |
447 | * @param needle peer to find | 410 | * @param needle Peer to find |
448 | * @return index of @a needle in @a haystack, or -1 if peer | 411 | * @return Index of @a needle in @a haystack, or -1 if peer |
449 | * is not in the list. | 412 | * is not in the list. |
450 | */ | 413 | */ |
451 | static int | 414 | static int |
@@ -464,11 +427,11 @@ peer_find (const struct GNUNET_PeerIdentity *haystack, unsigned int n, | |||
464 | * Normalize the given list of peers, by including the local peer | 427 | * Normalize the given list of peers, by including the local peer |
465 | * (if it is missing) and sorting the peers by their identity. | 428 | * (if it is missing) and sorting the peers by their identity. |
466 | * | 429 | * |
467 | * @param listed peers in the unnormalized list | 430 | * @param listed Peers in the unnormalized list. |
468 | * @param num_listed peers in the un-normalized list | 431 | * @param num_listed Peers in the un-normalized list. |
469 | * @param[out] num_normalized number of peers in the normalized list | 432 | * @param[out] num_normalized Number of peers in the normalized list. |
470 | * @param[out] my_peer_idx index of the local peer in the normalized list | 433 | * @param[out] my_peer_idx Index of the local peer in the normalized list. |
471 | * @return normalized list, must be free'd by the caller | 434 | * @return Normalized list, must be free'd by the caller. |
472 | */ | 435 | */ |
473 | static struct GNUNET_PeerIdentity * | 436 | static struct GNUNET_PeerIdentity * |
474 | normalize_peers (struct GNUNET_PeerIdentity *listed, | 437 | normalize_peers (struct GNUNET_PeerIdentity *listed, |
@@ -477,6 +440,7 @@ normalize_peers (struct GNUNET_PeerIdentity *listed, | |||
477 | unsigned int *my_peer_idx) | 440 | unsigned int *my_peer_idx) |
478 | { | 441 | { |
479 | unsigned int local_peer_in_list; | 442 | unsigned int local_peer_in_list; |
443 | /* number of peers in the normalized list */ | ||
480 | unsigned int n; | 444 | unsigned int n; |
481 | struct GNUNET_PeerIdentity *normalized; | 445 | struct GNUNET_PeerIdentity *normalized; |
482 | 446 | ||
@@ -506,10 +470,10 @@ normalize_peers (struct GNUNET_PeerIdentity *listed, | |||
506 | 470 | ||
507 | 471 | ||
508 | /** | 472 | /** |
509 | * Get a the j-th lagrage coefficient for a set of indices. | 473 | * Get a the j-th lagrange coefficient for a set of indices. |
510 | * | 474 | * |
511 | * @param[out] coeff the lagrange coefficient | 475 | * @param[out] coeff the lagrange coefficient |
512 | * @param j lagrage coefficient we want to compute | 476 | * @param j lagrange coefficient we want to compute |
513 | * @param indices indices | 477 | * @param indices indices |
514 | * @param num number of indices in @a indices | 478 | * @param num number of indices in @a indices |
515 | */ | 479 | */ |
@@ -518,7 +482,7 @@ compute_lagrange_coefficient (gcry_mpi_t coeff, unsigned int j, | |||
518 | unsigned int *indices, | 482 | unsigned int *indices, |
519 | unsigned int num) | 483 | unsigned int num) |
520 | { | 484 | { |
521 | int i; | 485 | unsigned int i; |
522 | /* numerator */ | 486 | /* numerator */ |
523 | gcry_mpi_t n; | 487 | gcry_mpi_t n; |
524 | /* denominator */ | 488 | /* denominator */ |
@@ -535,22 +499,27 @@ compute_lagrange_coefficient (gcry_mpi_t coeff, unsigned int j, | |||
535 | gcry_mpi_set_ui (n, 1); | 499 | gcry_mpi_set_ui (n, 1); |
536 | gcry_mpi_set_ui (d, 1); | 500 | gcry_mpi_set_ui (d, 1); |
537 | 501 | ||
538 | gcry_mpi_set_ui (coeff, 0); | ||
539 | for (i = 0; i < num; i++) | 502 | for (i = 0; i < num; i++) |
540 | { | 503 | { |
541 | int l = indices[i]; | 504 | unsigned int l = indices[i]; |
542 | if (l == j) | 505 | if (l == j) |
543 | continue; | 506 | continue; |
544 | gcry_mpi_mul_ui (n, n, l); | 507 | gcry_mpi_mul_ui (n, n, l + 1); |
545 | // d <- d * (l-j) | 508 | // d <- d * (l-j) |
546 | gcry_mpi_set_ui (tmp, l); | 509 | gcry_mpi_set_ui (tmp, l + 1); |
547 | gcry_mpi_sub_ui (tmp, tmp, j); | 510 | gcry_mpi_sub_ui (tmp, tmp, j + 1); |
548 | gcry_mpi_mul (d, d, tmp); | 511 | gcry_mpi_mul (d, d, tmp); |
549 | } | 512 | } |
550 | 513 | ||
514 | // gcry_mpi_invm does not like negative numbers ... | ||
515 | gcry_mpi_mod (d, d, elgamal_q); | ||
516 | |||
517 | GNUNET_assert (gcry_mpi_cmp_ui (d, 0) > 0); | ||
518 | |||
551 | // now we do the actual division, with everything mod q, as we | 519 | // now we do the actual division, with everything mod q, as we |
552 | // are not operating on elemets from <g>, but on exponents | 520 | // are not operating on elements from <g>, but on exponents |
553 | GNUNET_assert (0 == gcry_mpi_invm (d, d, elgamal_q)); | 521 | GNUNET_assert (0 != gcry_mpi_invm (d, d, elgamal_q)); |
522 | |||
554 | gcry_mpi_mulm (coeff, n, d, elgamal_q); | 523 | gcry_mpi_mulm (coeff, n, d, elgamal_q); |
555 | 524 | ||
556 | gcry_mpi_release (n); | 525 | gcry_mpi_release (n); |
@@ -580,11 +549,22 @@ paillier_create (gcry_mpi_t n, gcry_mpi_t lambda, gcry_mpi_t mu) | |||
580 | GNUNET_assert (0 != (phi = gcry_mpi_new (PAILLIER_BITS))); | 549 | GNUNET_assert (0 != (phi = gcry_mpi_new (PAILLIER_BITS))); |
581 | GNUNET_assert (0 != (tmp = gcry_mpi_new (PAILLIER_BITS))); | 550 | GNUNET_assert (0 != (tmp = gcry_mpi_new (PAILLIER_BITS))); |
582 | 551 | ||
583 | // generate rsa modulus | 552 | p = q = NULL; |
584 | GNUNET_assert (0 == gcry_prime_generate (&p, PAILLIER_BITS / 2, 0, NULL, NULL, NULL, | 553 | |
585 | GCRY_WEAK_RANDOM, 0)); | 554 | // Generate two distinct primes. |
586 | GNUNET_assert (0 == gcry_prime_generate (&q, PAILLIER_BITS / 2, 0, NULL, NULL, NULL, | 555 | // The probability that the loop body |
556 | // is executed more than once is very low. | ||
557 | do { | ||
558 | if (NULL != p) | ||
559 | gcry_mpi_release (p); | ||
560 | if (NULL != q) | ||
561 | gcry_mpi_release (q); | ||
562 | // generate rsa modulus | ||
563 | GNUNET_assert (0 == gcry_prime_generate (&p, PAILLIER_BITS / 2, 0, NULL, NULL, NULL, | ||
564 | GCRY_WEAK_RANDOM, 0)); | ||
565 | GNUNET_assert (0 == gcry_prime_generate (&q, PAILLIER_BITS / 2, 0, NULL, NULL, NULL, | ||
587 | GCRY_WEAK_RANDOM, 0)); | 566 | GCRY_WEAK_RANDOM, 0)); |
567 | } while (0 == gcry_mpi_cmp (p, q)); | ||
588 | gcry_mpi_mul (n, p, q); | 568 | gcry_mpi_mul (n, p, q); |
589 | // compute phi(n) = (p-1)(q-1) | 569 | // compute phi(n) = (p-1)(q-1) |
590 | gcry_mpi_sub_ui (phi, p, 1); | 570 | gcry_mpi_sub_ui (phi, p, 1); |
@@ -604,7 +584,7 @@ paillier_create (gcry_mpi_t n, gcry_mpi_t lambda, gcry_mpi_t mu) | |||
604 | /** | 584 | /** |
605 | * Encrypt a value using Paillier's scheme. | 585 | * Encrypt a value using Paillier's scheme. |
606 | * | 586 | * |
607 | * @param c resulting ciphertext | 587 | * @param[out] c resulting ciphertext |
608 | * @param m plaintext to encrypt | 588 | * @param m plaintext to encrypt |
609 | * @param n n-component of public key | 589 | * @param n n-component of public key |
610 | */ | 590 | */ |
@@ -628,7 +608,7 @@ paillier_encrypt (gcry_mpi_t c, gcry_mpi_t m, gcry_mpi_t n) | |||
628 | { | 608 | { |
629 | gcry_mpi_randomize (r, PAILLIER_BITS, GCRY_WEAK_RANDOM); | 609 | gcry_mpi_randomize (r, PAILLIER_BITS, GCRY_WEAK_RANDOM); |
630 | } | 610 | } |
631 | while (gcry_mpi_cmp (r, n) > 0); | 611 | while (gcry_mpi_cmp (r, n) >= 0); |
632 | 612 | ||
633 | gcry_mpi_powm (c, g, m, n_square); | 613 | gcry_mpi_powm (c, g, m, n_square); |
634 | gcry_mpi_powm (r, r, n, n_square); | 614 | gcry_mpi_powm (r, r, n, n_square); |
@@ -636,6 +616,7 @@ paillier_encrypt (gcry_mpi_t c, gcry_mpi_t m, gcry_mpi_t n) | |||
636 | 616 | ||
637 | gcry_mpi_release (n_square); | 617 | gcry_mpi_release (n_square); |
638 | gcry_mpi_release (r); | 618 | gcry_mpi_release (r); |
619 | gcry_mpi_release (g); | ||
639 | } | 620 | } |
640 | 621 | ||
641 | 622 | ||
@@ -652,17 +633,69 @@ static void | |||
652 | paillier_decrypt (gcry_mpi_t m, gcry_mpi_t c, gcry_mpi_t mu, gcry_mpi_t lambda, gcry_mpi_t n) | 633 | paillier_decrypt (gcry_mpi_t m, gcry_mpi_t c, gcry_mpi_t mu, gcry_mpi_t lambda, gcry_mpi_t n) |
653 | { | 634 | { |
654 | gcry_mpi_t n_square; | 635 | gcry_mpi_t n_square; |
636 | |||
655 | GNUNET_assert (0 != (n_square = gcry_mpi_new (0))); | 637 | GNUNET_assert (0 != (n_square = gcry_mpi_new (0))); |
638 | |||
656 | gcry_mpi_mul (n_square, n, n); | 639 | gcry_mpi_mul (n_square, n, n); |
640 | // m = c^lambda mod n^2 | ||
657 | gcry_mpi_powm (m, c, lambda, n_square); | 641 | gcry_mpi_powm (m, c, lambda, n_square); |
642 | // m = m - 1 | ||
658 | gcry_mpi_sub_ui (m, m, 1); | 643 | gcry_mpi_sub_ui (m, m, 1); |
659 | // m = m/n | 644 | // m <- m/n |
660 | gcry_mpi_div (m, NULL, m, n, 0); | 645 | gcry_mpi_div (m, NULL, m, n, 0); |
661 | gcry_mpi_mulm (m, m, mu, n); | 646 | gcry_mpi_mulm (m, m, mu, n); |
662 | gcry_mpi_release (n_square); | 647 | gcry_mpi_release (n_square); |
663 | } | 648 | } |
664 | 649 | ||
665 | 650 | ||
651 | static void | ||
652 | decrypt_session_destroy (struct DecryptSession *ds) | ||
653 | { | ||
654 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "destroying decrypt session\n"); | ||
655 | |||
656 | GNUNET_CONTAINER_DLL_remove (decrypt_sessions_head, decrypt_sessions_tail, ds); | ||
657 | |||
658 | if (NULL != ds->client_mq) | ||
659 | { | ||
660 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "destroying decrypt MQ\n"); | ||
661 | GNUNET_MQ_destroy (ds->client_mq); | ||
662 | ds->client_mq = NULL; | ||
663 | } | ||
664 | |||
665 | if (NULL != ds->client) | ||
666 | { | ||
667 | GNUNET_SERVER_client_disconnect (ds->client); | ||
668 | ds->client = NULL; | ||
669 | } | ||
670 | |||
671 | GNUNET_free (ds); | ||
672 | } | ||
673 | |||
674 | |||
675 | static void | ||
676 | keygen_session_destroy (struct KeygenSession *ks) | ||
677 | { | ||
678 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "destroying keygen session\n"); | ||
679 | |||
680 | GNUNET_CONTAINER_DLL_remove (keygen_sessions_head, keygen_sessions_tail, ks); | ||
681 | |||
682 | if (NULL != ks->client_mq) | ||
683 | { | ||
684 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "destroying keygen MQ\n"); | ||
685 | GNUNET_MQ_destroy (ks->client_mq); | ||
686 | ks->client_mq = NULL; | ||
687 | } | ||
688 | |||
689 | if (NULL != ks->client) | ||
690 | { | ||
691 | GNUNET_SERVER_client_disconnect (ks->client); | ||
692 | ks->client = NULL; | ||
693 | } | ||
694 | |||
695 | GNUNET_free (ks); | ||
696 | } | ||
697 | |||
698 | |||
666 | /** | 699 | /** |
667 | * Task run during shutdown. | 700 | * Task run during shutdown. |
668 | * | 701 | * |
@@ -672,7 +705,11 @@ paillier_decrypt (gcry_mpi_t m, gcry_mpi_t c, gcry_mpi_t mu, gcry_mpi_t lambda, | |||
672 | static void | 705 | static void |
673 | cleanup_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | 706 | cleanup_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) |
674 | { | 707 | { |
675 | /* FIXME: do clean up here */ | 708 | while (NULL != decrypt_sessions_head) |
709 | decrypt_session_destroy (decrypt_sessions_head); | ||
710 | |||
711 | while (NULL != keygen_sessions_head) | ||
712 | keygen_session_destroy (keygen_sessions_head); | ||
676 | } | 713 | } |
677 | 714 | ||
678 | 715 | ||
@@ -685,23 +722,31 @@ static void | |||
685 | generate_presecret_polynomial (struct KeygenSession *ks) | 722 | generate_presecret_polynomial (struct KeygenSession *ks) |
686 | { | 723 | { |
687 | int i; | 724 | int i; |
725 | gcry_mpi_t v; | ||
726 | |||
688 | GNUNET_assert (NULL == ks->presecret_polynomial); | 727 | GNUNET_assert (NULL == ks->presecret_polynomial); |
689 | ks->presecret_polynomial = GNUNET_malloc (ks->threshold * sizeof (gcry_mpi_t)); | 728 | ks->presecret_polynomial = GNUNET_new_array (ks->threshold, gcry_mpi_t); |
690 | for (i = 0; i < ks->threshold; i++) | 729 | for (i = 0; i < ks->threshold; i++) |
691 | { | 730 | { |
692 | ks->presecret_polynomial[i] = gcry_mpi_new (GNUNET_SECRETSHARING_KEY_BITS); | 731 | v = ks->presecret_polynomial[i] = gcry_mpi_new (GNUNET_SECRETSHARING_ELGAMAL_BITS); |
693 | GNUNET_assert (0 != ks->presecret_polynomial[i]); | 732 | GNUNET_assert (NULL != v); |
694 | gcry_mpi_randomize (ks->presecret_polynomial[i], GNUNET_SECRETSHARING_KEY_BITS, | 733 | // Randomize v such that 0 < v < elgamal_q. |
695 | GCRY_WEAK_RANDOM); | 734 | // The '- 1' is necessary as bitlength(q) = bitlength(p) - 1. |
735 | do | ||
736 | { | ||
737 | gcry_mpi_randomize (v, GNUNET_SECRETSHARING_ELGAMAL_BITS - 1, GCRY_WEAK_RANDOM); | ||
738 | } while ((gcry_mpi_cmp_ui (v, 0) == 0) || (gcry_mpi_cmp (v, elgamal_q) >= 0)); | ||
696 | } | 739 | } |
697 | } | 740 | } |
698 | 741 | ||
699 | 742 | ||
700 | /** | 743 | /** |
701 | * Consensus element handler for round one. | 744 | * Consensus element handler for round one. |
745 | * We should get one ephemeral key for each peer. | ||
702 | * | 746 | * |
703 | * @param cls closure (keygen session) | 747 | * @param cls Closure (keygen session). |
704 | * @param element the element from consensus | 748 | * @param element The element from consensus, or |
749 | * NULL if consensus failed. | ||
705 | */ | 750 | */ |
706 | static void | 751 | static void |
707 | keygen_round1_new_element (void *cls, | 752 | keygen_round1_new_element (void *cls, |
@@ -717,6 +762,7 @@ keygen_round1_new_element (void *cls, | |||
717 | return; | 762 | return; |
718 | } | 763 | } |
719 | 764 | ||
765 | /* elements have fixed size */ | ||
720 | if (element->size != sizeof (struct GNUNET_SECRETSHARING_KeygenCommitData)) | 766 | if (element->size != sizeof (struct GNUNET_SECRETSHARING_KeygenCommitData)) |
721 | { | 767 | { |
722 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | 768 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, |
@@ -729,7 +775,6 @@ keygen_round1_new_element (void *cls, | |||
729 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, "got round1 element\n"); | 775 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, "got round1 element\n"); |
730 | 776 | ||
731 | d = element->data; | 777 | d = element->data; |
732 | |||
733 | info = get_keygen_peer_info (ks, &d->peer); | 778 | info = get_keygen_peer_info (ks, &d->peer); |
734 | 779 | ||
735 | if (NULL == info) | 780 | if (NULL == info) |
@@ -739,6 +784,7 @@ keygen_round1_new_element (void *cls, | |||
739 | return; | 784 | return; |
740 | } | 785 | } |
741 | 786 | ||
787 | /* Check that the right amount of data has been signed. */ | ||
742 | if (d->purpose.size != | 788 | if (d->purpose.size != |
743 | htonl (element->size - offsetof (struct GNUNET_SECRETSHARING_KeygenCommitData, purpose))) | 789 | htonl (element->size - offsetof (struct GNUNET_SECRETSHARING_KeygenCommitData, purpose))) |
744 | { | 790 | { |
@@ -752,11 +798,8 @@ keygen_round1_new_element (void *cls, | |||
752 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "keygen commit data with invalid signature in consensus\n"); | 798 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "keygen commit data with invalid signature in consensus\n"); |
753 | return; | 799 | return; |
754 | } | 800 | } |
755 | 801 | GNUNET_CRYPTO_mpi_scan_unsigned (&info->paillier_n, &d->pubkey.n, PAILLIER_BITS / 8); | |
756 | GNUNET_assert (0 == gcry_mpi_scan (&info->paillier_n, GCRYMPI_FMT_USG, | 802 | GNUNET_CRYPTO_mpi_scan_unsigned (&info->presecret_commitment, &d->pubkey.n, PAILLIER_BITS / 8); |
757 | &d->pubkey.n, sizeof d->pubkey.n, NULL)); | ||
758 | GNUNET_assert (0 == gcry_mpi_scan (&info->presecret_commitment, GCRYMPI_FMT_USG, | ||
759 | &d->commitment, sizeof d->commitment, NULL)); | ||
760 | info->round1_valid = GNUNET_YES; | 803 | info->round1_valid = GNUNET_YES; |
761 | } | 804 | } |
762 | 805 | ||
@@ -796,16 +839,20 @@ keygen_round2_conclude (void *cls) | |||
796 | unsigned int i; | 839 | unsigned int i; |
797 | unsigned int j; | 840 | unsigned int j; |
798 | struct GNUNET_SECRETSHARING_Share *share; | 841 | struct GNUNET_SECRETSHARING_Share *share; |
842 | /* our share */ | ||
799 | gcry_mpi_t s; | 843 | gcry_mpi_t s; |
844 | /* public key */ | ||
800 | gcry_mpi_t h; | 845 | gcry_mpi_t h; |
801 | 846 | ||
802 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, "round2 conclude\n"); | 847 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, "round2 conclude\n"); |
803 | 848 | ||
804 | GNUNET_assert (0 != (s = gcry_mpi_new (GNUNET_SECRETSHARING_KEY_BITS))); | 849 | GNUNET_assert (0 != (s = gcry_mpi_new (GNUNET_SECRETSHARING_ELGAMAL_BITS))); |
805 | GNUNET_assert (0 != (h = gcry_mpi_new (GNUNET_SECRETSHARING_KEY_BITS))); | 850 | GNUNET_assert (0 != (h = gcry_mpi_new (GNUNET_SECRETSHARING_ELGAMAL_BITS))); |
806 | 851 | ||
807 | // multiplicative identity | 852 | // multiplicative identity |
808 | gcry_mpi_set_ui (s, 1); | 853 | gcry_mpi_set_ui (h, 1); |
854 | // additive identity | ||
855 | gcry_mpi_set_ui (s, 0); | ||
809 | 856 | ||
810 | share = GNUNET_new (struct GNUNET_SECRETSHARING_Share); | 857 | share = GNUNET_new (struct GNUNET_SECRETSHARING_Share); |
811 | 858 | ||
@@ -820,6 +867,9 @@ keygen_round2_conclude (void *cls) | |||
820 | GNUNET_new_array (share->num_peers, struct GNUNET_SECRETSHARING_FieldElement); | 867 | GNUNET_new_array (share->num_peers, struct GNUNET_SECRETSHARING_FieldElement); |
821 | share->original_indices = GNUNET_new_array (share->num_peers, uint16_t); | 868 | share->original_indices = GNUNET_new_array (share->num_peers, uint16_t); |
822 | 869 | ||
870 | /* maybe we're not even in the list of peers? */ | ||
871 | share->my_peer = share->num_peers; | ||
872 | |||
823 | j = 0; | 873 | j = 0; |
824 | for (i = 0; i < ks->num_peers; i++) | 874 | for (i = 0; i < ks->num_peers; i++) |
825 | { | 875 | { |
@@ -829,13 +879,18 @@ keygen_round2_conclude (void *cls) | |||
829 | gcry_mpi_mulm (h, h, ks->info[i].public_key_share, elgamal_p); | 879 | gcry_mpi_mulm (h, h, ks->info[i].public_key_share, elgamal_p); |
830 | share->peers[i] = ks->info[i].peer; | 880 | share->peers[i] = ks->info[i].peer; |
831 | share->original_indices[i] = j++; | 881 | share->original_indices[i] = j++; |
882 | if (0 == memcmp (&share->peers[i], &my_peer, sizeof (struct GNUNET_PeerIdentity))) | ||
883 | share->my_peer = i; | ||
832 | } | 884 | } |
833 | } | 885 | } |
834 | 886 | ||
835 | print_mpi_fixed (&share->my_share, s, GNUNET_SECRETSHARING_KEY_BITS / 8); | 887 | GNUNET_CRYPTO_mpi_print_unsigned (&share->my_share, GNUNET_SECRETSHARING_ELGAMAL_BITS / 8, s); |
836 | print_mpi_fixed (&share->public_key, h, GNUNET_SECRETSHARING_KEY_BITS / 8); | 888 | GNUNET_CRYPTO_mpi_print_unsigned (&share->public_key, GNUNET_SECRETSHARING_ELGAMAL_BITS / 8, h); |
837 | 889 | ||
838 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, "keygen successful with %u peers\n", share->num_peers); | 890 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, "keygen completed with %u peers\n", share->num_peers); |
891 | |||
892 | /* Write the share. If 0 peers completed the dkg, an empty | ||
893 | * share will be sent. */ | ||
839 | 894 | ||
840 | m = GNUNET_malloc (sizeof (struct GNUNET_SECRETSHARING_SecretReadyMessage) + | 895 | m = GNUNET_malloc (sizeof (struct GNUNET_SECRETSHARING_SecretReadyMessage) + |
841 | ks->num_peers * sizeof (struct GNUNET_PeerIdentity)); | 896 | ks->num_peers * sizeof (struct GNUNET_PeerIdentity)); |
@@ -872,13 +927,19 @@ insert_round2_element (struct KeygenSession *ks) | |||
872 | unsigned int i; | 927 | unsigned int i; |
873 | gcry_mpi_t idx; | 928 | gcry_mpi_t idx; |
874 | gcry_mpi_t v; | 929 | gcry_mpi_t v; |
930 | gcry_mpi_t c; | ||
875 | 931 | ||
876 | GNUNET_assert (0 != (v = gcry_mpi_new (GNUNET_SECRETSHARING_KEY_BITS))); | 932 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "P%u: Inserting round2 element\n", |
877 | GNUNET_assert (0 != (idx = gcry_mpi_new (GNUNET_SECRETSHARING_KEY_BITS))); | 933 | ks->local_peer_idx); |
934 | |||
935 | GNUNET_assert (NULL != (v = gcry_mpi_new (GNUNET_SECRETSHARING_ELGAMAL_BITS))); | ||
936 | GNUNET_assert (NULL != (idx = gcry_mpi_new (GNUNET_SECRETSHARING_ELGAMAL_BITS))); | ||
937 | GNUNET_assert (NULL != (c = gcry_mpi_new (GNUNET_SECRETSHARING_ELGAMAL_BITS))); | ||
878 | 938 | ||
879 | element_size = (sizeof (struct GNUNET_SECRETSHARING_KeygenRevealData) + | 939 | element_size = (sizeof (struct GNUNET_SECRETSHARING_KeygenRevealData) + |
880 | 2 * GNUNET_SECRETSHARING_KEY_BITS / 8 * ks->num_peers + | 940 | GNUNET_SECRETSHARING_ELGAMAL_BITS / 8 * ks->num_peers + |
881 | 1 * GNUNET_SECRETSHARING_KEY_BITS / 8 * ks->threshold); | 941 | GNUNET_SECRETSHARING_ELGAMAL_BITS / 8 * ks->threshold + |
942 | PAILLIER_BITS * 2 / 8 * ks->num_peers); | ||
882 | 943 | ||
883 | element = GNUNET_malloc (sizeof (struct GNUNET_SET_Element) + element_size); | 944 | element = GNUNET_malloc (sizeof (struct GNUNET_SET_Element) + element_size); |
884 | element->size = element_size; | 945 | element->size = element_size; |
@@ -887,6 +948,8 @@ insert_round2_element (struct KeygenSession *ks) | |||
887 | d = (void *) element->data; | 948 | d = (void *) element->data; |
888 | d->peer = my_peer; | 949 | d->peer = my_peer; |
889 | 950 | ||
951 | // start inserting vector elements | ||
952 | // after the fixed part of the element's data | ||
890 | pos = (void *) &d[1]; | 953 | pos = (void *) &d[1]; |
891 | last_pos = pos + element_size; | 954 | last_pos = pos + element_size; |
892 | 955 | ||
@@ -895,38 +958,55 @@ insert_round2_element (struct KeygenSession *ks) | |||
895 | { | 958 | { |
896 | ptrdiff_t remaining = last_pos - pos; | 959 | ptrdiff_t remaining = last_pos - pos; |
897 | GNUNET_assert (remaining > 0); | 960 | GNUNET_assert (remaining > 0); |
898 | gcry_mpi_set_ui (idx, i); | 961 | gcry_mpi_set_ui (idx, i + 1); |
899 | // evaluate the polynomial | 962 | // evaluate the polynomial |
900 | horner_eval (v, ks->presecret_polynomial, ks->threshold, idx, elgamal_p); | 963 | horner_eval (v, ks->presecret_polynomial, ks->threshold, idx, elgamal_q); |
901 | // take g to the result | 964 | // take g to the result |
902 | gcry_mpi_powm (v, elgamal_g, v, elgamal_p); | 965 | gcry_mpi_powm (v, elgamal_g, v, elgamal_p); |
903 | print_mpi_fixed (pos, v, GNUNET_SECRETSHARING_KEY_BITS / 8); | 966 | GNUNET_CRYPTO_mpi_print_unsigned (pos, GNUNET_SECRETSHARING_ELGAMAL_BITS / 8, v); |
904 | pos += GNUNET_SECRETSHARING_KEY_BITS / 8; | 967 | pos += GNUNET_SECRETSHARING_ELGAMAL_BITS / 8; |
905 | } | 968 | } |
906 | 969 | ||
970 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "P%u: computed exp preshares\n", | ||
971 | ks->local_peer_idx); | ||
972 | |||
907 | // encrypted pre-shares | 973 | // encrypted pre-shares |
908 | for (i = 0; i < ks->num_peers; i++) | 974 | for (i = 0; i < ks->num_peers; i++) |
909 | { | 975 | { |
910 | ptrdiff_t remaining = last_pos - pos; | 976 | ptrdiff_t remaining = last_pos - pos; |
911 | GNUNET_assert (remaining > 0); | 977 | GNUNET_assert (remaining > 0); |
912 | if (GNUNET_NO == ks->info[i].round1_valid) | 978 | if (GNUNET_NO == ks->info[i].round1_valid) |
913 | gcry_mpi_set_ui (v, 0); | 979 | { |
980 | gcry_mpi_set_ui (c, 0); | ||
981 | } | ||
914 | else | 982 | else |
915 | paillier_encrypt (v, ks->presecret_polynomial[0], ks->info[i].paillier_n); | 983 | { |
916 | print_mpi_fixed (pos, v, GNUNET_SECRETSHARING_KEY_BITS / 8); | 984 | gcry_mpi_set_ui (idx, i + 1); |
917 | pos += GNUNET_SECRETSHARING_KEY_BITS / 8; | 985 | // evaluate the polynomial |
986 | horner_eval (v, ks->presecret_polynomial, ks->threshold, idx, elgamal_q); | ||
987 | // encrypt the result | ||
988 | paillier_encrypt (c, v, ks->info[i].paillier_n); | ||
989 | } | ||
990 | GNUNET_CRYPTO_mpi_print_unsigned (pos, PAILLIER_BITS * 2 / 8, c); | ||
991 | pos += PAILLIER_BITS * 2 / 8; | ||
918 | } | 992 | } |
919 | 993 | ||
994 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "P%u: computed enc preshares\n", | ||
995 | ks->local_peer_idx); | ||
996 | |||
920 | // exponentiated coefficients | 997 | // exponentiated coefficients |
921 | for (i = 0; i < ks->threshold; i++) | 998 | for (i = 0; i < ks->threshold; i++) |
922 | { | 999 | { |
923 | ptrdiff_t remaining = last_pos - pos; | 1000 | ptrdiff_t remaining = last_pos - pos; |
924 | GNUNET_assert (remaining > 0); | 1001 | GNUNET_assert (remaining > 0); |
925 | gcry_mpi_powm (v, elgamal_g, ks->presecret_polynomial[i], elgamal_p); | 1002 | gcry_mpi_powm (v, elgamal_g, ks->presecret_polynomial[i], elgamal_p); |
926 | print_mpi_fixed (pos, v, GNUNET_SECRETSHARING_KEY_BITS / 8); | 1003 | GNUNET_CRYPTO_mpi_print_unsigned (pos, GNUNET_SECRETSHARING_ELGAMAL_BITS / 8, v); |
927 | pos += GNUNET_SECRETSHARING_KEY_BITS / 8; | 1004 | pos += GNUNET_SECRETSHARING_ELGAMAL_BITS / 8; |
928 | } | 1005 | } |
929 | 1006 | ||
1007 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "P%u: computed exp coefficients\n", | ||
1008 | ks->local_peer_idx); | ||
1009 | |||
930 | d->purpose.size = htonl (element_size - offsetof (struct GNUNET_SECRETSHARING_KeygenRevealData, purpose)); | 1010 | d->purpose.size = htonl (element_size - offsetof (struct GNUNET_SECRETSHARING_KeygenRevealData, purpose)); |
931 | d->purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_SECRETSHARING_DKG2); | 1011 | d->purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_SECRETSHARING_DKG2); |
932 | GNUNET_CRYPTO_eddsa_sign (my_peer_private_key, &d->purpose, &d->signature); | 1012 | GNUNET_CRYPTO_eddsa_sign (my_peer_private_key, &d->purpose, &d->signature); |
@@ -957,8 +1037,9 @@ keygen_round2_new_element (void *cls, | |||
957 | } | 1037 | } |
958 | 1038 | ||
959 | expected_element_size = (sizeof (struct GNUNET_SECRETSHARING_KeygenRevealData) + | 1039 | expected_element_size = (sizeof (struct GNUNET_SECRETSHARING_KeygenRevealData) + |
960 | 2 * GNUNET_SECRETSHARING_KEY_BITS / 8 * ks->num_peers + | 1040 | GNUNET_SECRETSHARING_ELGAMAL_BITS / 8 * ks->num_peers + |
961 | 1 * GNUNET_SECRETSHARING_KEY_BITS / 8 * ks->threshold); | 1041 | PAILLIER_BITS / 8 * 2 * ks->num_peers + |
1042 | GNUNET_SECRETSHARING_ELGAMAL_BITS / 8 * ks->threshold); | ||
962 | 1043 | ||
963 | if (element->size != expected_element_size) | 1044 | if (element->size != expected_element_size) |
964 | { | 1045 | { |
@@ -1001,31 +1082,28 @@ keygen_round2_new_element (void *cls, | |||
1001 | 1082 | ||
1002 | pos = (void *) &d[1]; | 1083 | pos = (void *) &d[1]; |
1003 | // skip exponentiated pre-shares | 1084 | // skip exponentiated pre-shares |
1004 | pos += GNUNET_SECRETSHARING_KEY_BITS / 8 * ks->num_peers; | 1085 | pos += GNUNET_SECRETSHARING_ELGAMAL_BITS / 8 * ks->num_peers; |
1005 | // skip encrypted pre-shares | 1086 | // skip encrypted pre-shares |
1006 | pos += PAILLIER_BITS / 8 * ks->num_peers; | 1087 | pos += PAILLIER_BITS * 2 / 8 * ks->num_peers; |
1007 | // the first exponentiated coefficient is the public key share | 1088 | // the first exponentiated coefficient is the public key share |
1008 | GNUNET_assert (0 == gcry_mpi_scan (&info->public_key_share, GCRYMPI_FMT_USG, | 1089 | GNUNET_CRYPTO_mpi_scan_unsigned (&info->public_key_share, pos, GNUNET_SECRETSHARING_ELGAMAL_BITS / 8); |
1009 | pos, GNUNET_SECRETSHARING_KEY_BITS / 8, NULL)); | ||
1010 | 1090 | ||
1011 | pos = (void *) &d[1]; | 1091 | pos = (void *) &d[1]; |
1012 | // skip exp. pre-shares | 1092 | // skip exp. pre-shares |
1013 | pos += GNUNET_SECRETSHARING_KEY_BITS / 8 * ks->num_peers; | 1093 | pos += GNUNET_SECRETSHARING_ELGAMAL_BITS / 8 * ks->num_peers; |
1014 | // skip to the encrypted value for our peer | 1094 | // skip to the encrypted value for our peer |
1015 | pos += PAILLIER_BITS / 8 * ks->local_peer_idx; | 1095 | pos += PAILLIER_BITS * 2 / 8 * ks->local_peer_idx; |
1016 | 1096 | ||
1017 | GNUNET_assert (0 == gcry_mpi_scan (&c, GCRYMPI_FMT_USG, | 1097 | GNUNET_CRYPTO_mpi_scan_unsigned (&c, pos, PAILLIER_BITS * 2 / 8); |
1018 | pos, PAILLIER_BITS / 8, NULL)); | ||
1019 | 1098 | ||
1020 | GNUNET_assert (0 != (info->decrypted_preshare = mpi_new (0))); | 1099 | GNUNET_assert (0 != (info->decrypted_preshare = mpi_new (0))); |
1021 | 1100 | ||
1022 | paillier_decrypt (info->decrypted_preshare, c, ks->paillier_lambda, ks->paillier_mu, | 1101 | paillier_decrypt (info->decrypted_preshare, c, ks->paillier_mu, ks->paillier_lambda, |
1023 | ks->info[ks->local_peer_idx].paillier_n); | 1102 | ks->info[ks->local_peer_idx].paillier_n); |
1024 | |||
1025 | // TODO: validate zero knowledge proofs | 1103 | // TODO: validate zero knowledge proofs |
1026 | 1104 | ||
1027 | if (d->purpose.size != | 1105 | if (ntohl (d->purpose.size) != |
1028 | htons (element->size - offsetof (struct GNUNET_SECRETSHARING_KeygenRevealData, purpose))) | 1106 | element->size - offsetof (struct GNUNET_SECRETSHARING_KeygenRevealData, purpose)) |
1029 | { | 1107 | { |
1030 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "keygen reveal data with wrong signature purpose size in consensus\n"); | 1108 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "keygen reveal data with wrong signature purpose size in consensus\n"); |
1031 | return; | 1109 | return; |
@@ -1082,29 +1160,25 @@ insert_round1_element (struct KeygenSession *ks) | |||
1082 | // g^a_{i,0} | 1160 | // g^a_{i,0} |
1083 | gcry_mpi_t v; | 1161 | gcry_mpi_t v; |
1084 | // big-endian representation of 'v' | 1162 | // big-endian representation of 'v' |
1085 | unsigned char v_data[GNUNET_SECRETSHARING_KEY_BITS / 8]; | 1163 | unsigned char v_data[GNUNET_SECRETSHARING_ELGAMAL_BITS / 8]; |
1086 | 1164 | ||
1087 | element = GNUNET_malloc (sizeof *element + sizeof *d); | 1165 | element = GNUNET_malloc (sizeof *element + sizeof *d); |
1088 | d = (void *) &element[1]; | 1166 | d = (void *) &element[1]; |
1089 | element->data = d; | 1167 | element->data = d; |
1090 | element->size = sizeof *d; | 1168 | element->size = sizeof *d; |
1091 | 1169 | ||
1092 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, "alloc'd size %u\n", sizeof *element + sizeof *d); | ||
1093 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, "element size %u\n", element->size); | ||
1094 | |||
1095 | |||
1096 | d->peer = my_peer; | 1170 | d->peer = my_peer; |
1097 | 1171 | ||
1098 | GNUNET_assert (0 != (v = gcry_mpi_new (GNUNET_SECRETSHARING_KEY_BITS))); | 1172 | GNUNET_assert (0 != (v = gcry_mpi_new (GNUNET_SECRETSHARING_ELGAMAL_BITS))); |
1099 | 1173 | ||
1100 | gcry_mpi_powm (v, elgamal_g, ks->presecret_polynomial[0], elgamal_p); | 1174 | gcry_mpi_powm (v, elgamal_g, ks->presecret_polynomial[0], elgamal_p); |
1101 | 1175 | ||
1102 | print_mpi_fixed (v_data, v, GNUNET_SECRETSHARING_KEY_BITS); | 1176 | GNUNET_CRYPTO_mpi_print_unsigned (v_data, GNUNET_SECRETSHARING_ELGAMAL_BITS / 8, v); |
1103 | 1177 | ||
1104 | GNUNET_CRYPTO_hash (v_data, GNUNET_SECRETSHARING_KEY_BITS / 8, &d->commitment); | 1178 | GNUNET_CRYPTO_hash (v_data, GNUNET_SECRETSHARING_ELGAMAL_BITS / 8, &d->commitment); |
1105 | 1179 | ||
1106 | print_mpi_fixed (d->pubkey.n, ks->info[ks->local_peer_idx].paillier_n, | 1180 | GNUNET_CRYPTO_mpi_print_unsigned (d->pubkey.n, PAILLIER_BITS / 8, |
1107 | PAILLIER_BITS / 8); | 1181 | ks->info[ks->local_peer_idx].paillier_n); |
1108 | 1182 | ||
1109 | d->purpose.size = htonl ((sizeof *d) - offsetof (struct GNUNET_SECRETSHARING_KeygenCommitData, purpose)); | 1183 | d->purpose.size = htonl ((sizeof *d) - offsetof (struct GNUNET_SECRETSHARING_KeygenCommitData, purpose)); |
1110 | d->purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_SECRETSHARING_DKG1); | 1184 | d->purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_SECRETSHARING_DKG1); |
@@ -1158,7 +1232,7 @@ static void handle_client_keygen (void *cls, | |||
1158 | ks->consensus = GNUNET_CONSENSUS_create (cfg, ks->num_peers, ks->peers, &msg->session_id, | 1232 | ks->consensus = GNUNET_CONSENSUS_create (cfg, ks->num_peers, ks->peers, &msg->session_id, |
1159 | keygen_round1_new_element, ks); | 1233 | keygen_round1_new_element, ks); |
1160 | 1234 | ||
1161 | ks->info = GNUNET_malloc (ks->num_peers * sizeof (struct KeygenPeerInfo)); | 1235 | ks->info = GNUNET_new_array (ks->num_peers, struct KeygenPeerInfo); |
1162 | 1236 | ||
1163 | for (i = 0; i < ks->num_peers; i++) | 1237 | for (i = 0; i < ks->num_peers; i++) |
1164 | ks->info[i].peer = ks->peers[i]; | 1238 | ks->info[i].peer = ks->peers[i]; |
@@ -1171,12 +1245,15 @@ static void handle_client_keygen (void *cls, | |||
1171 | ks->paillier_lambda, | 1245 | ks->paillier_lambda, |
1172 | ks->paillier_mu); | 1246 | ks->paillier_mu); |
1173 | 1247 | ||
1248 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "P%u: Generated paillier key pair\n", ks->local_peer_idx); | ||
1174 | 1249 | ||
1175 | generate_presecret_polynomial (ks); | 1250 | generate_presecret_polynomial (ks); |
1176 | 1251 | ||
1252 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "P%u: Generated presecret polynomial\n", ks->local_peer_idx); | ||
1253 | |||
1177 | insert_round1_element (ks); | 1254 | insert_round1_element (ks); |
1178 | 1255 | ||
1179 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, "starting conclude of round 1\n"); | 1256 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "P%u: Concluding for round 1\n", ks->local_peer_idx); |
1180 | 1257 | ||
1181 | GNUNET_CONSENSUS_conclude (ks->consensus, | 1258 | GNUNET_CONSENSUS_conclude (ks->consensus, |
1182 | /* half the overall time */ | 1259 | /* half the overall time */ |
@@ -1185,6 +1262,8 @@ static void handle_client_keygen (void *cls, | |||
1185 | ks); | 1262 | ks); |
1186 | 1263 | ||
1187 | GNUNET_SERVER_receive_done (client, GNUNET_OK); | 1264 | GNUNET_SERVER_receive_done (client, GNUNET_OK); |
1265 | |||
1266 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "P%u: Waiting for round 1 elements ...\n", ks->local_peer_idx); | ||
1188 | } | 1267 | } |
1189 | 1268 | ||
1190 | 1269 | ||
@@ -1201,6 +1280,7 @@ decrypt_conclude (void *cls) | |||
1201 | gcry_mpi_t m; | 1280 | gcry_mpi_t m; |
1202 | gcry_mpi_t tmp; | 1281 | gcry_mpi_t tmp; |
1203 | gcry_mpi_t c_2; | 1282 | gcry_mpi_t c_2; |
1283 | gcry_mpi_t prod; | ||
1204 | unsigned int *indices; | 1284 | unsigned int *indices; |
1205 | unsigned int num; | 1285 | unsigned int num; |
1206 | unsigned int i; | 1286 | unsigned int i; |
@@ -1209,6 +1289,7 @@ decrypt_conclude (void *cls) | |||
1209 | GNUNET_assert (0 != (lagrange = gcry_mpi_new (0))); | 1289 | GNUNET_assert (0 != (lagrange = gcry_mpi_new (0))); |
1210 | GNUNET_assert (0 != (m = gcry_mpi_new (0))); | 1290 | GNUNET_assert (0 != (m = gcry_mpi_new (0))); |
1211 | GNUNET_assert (0 != (tmp = gcry_mpi_new (0))); | 1291 | GNUNET_assert (0 != (tmp = gcry_mpi_new (0))); |
1292 | GNUNET_assert (0 != (prod = gcry_mpi_new (0))); | ||
1212 | 1293 | ||
1213 | num = 0; | 1294 | num = 0; |
1214 | for (i = 0; i < ds->share->num_peers; i++) | 1295 | for (i = 0; i < ds->share->num_peers; i++) |
@@ -1219,30 +1300,36 @@ decrypt_conclude (void *cls) | |||
1219 | j = 0; | 1300 | j = 0; |
1220 | for (i = 0; i < ds->share->num_peers; i++) | 1301 | for (i = 0; i < ds->share->num_peers; i++) |
1221 | if (NULL != ds->info[i].partial_decryption) | 1302 | if (NULL != ds->info[i].partial_decryption) |
1222 | indices[j++] = ds->info[i].real_index; | 1303 | indices[j++] = ds->info[i].original_index; |
1223 | 1304 | ||
1224 | gcry_mpi_set_ui (m, 1); | 1305 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, "P%u: decrypt conclude, with %u peers\n", |
1306 | ds->share->my_peer, num); | ||
1225 | 1307 | ||
1308 | gcry_mpi_set_ui (prod, 1); | ||
1226 | for (i = 0; i < num; i++) | 1309 | for (i = 0; i < num; i++) |
1227 | { | 1310 | { |
1311 | |||
1312 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, "P%u: index of %u: %u\n", | ||
1313 | ds->share->my_peer, i, indices[i]); | ||
1228 | compute_lagrange_coefficient (lagrange, indices[i], indices, num); | 1314 | compute_lagrange_coefficient (lagrange, indices[i], indices, num); |
1229 | // w_j^{\lambda_j} | 1315 | // w_i^{\lambda_i} |
1230 | gcry_mpi_powm (tmp, ds->info[indices[i]].partial_decryption, lagrange, elgamal_p); | 1316 | gcry_mpi_powm (tmp, ds->info[indices[i]].partial_decryption, lagrange, elgamal_p); |
1231 | gcry_mpi_mulm (m, m, tmp, elgamal_p); | ||
1232 | } | ||
1233 | 1317 | ||
1234 | GNUNET_assert (0 == gcry_mpi_scan (&c_2, GCRYMPI_FMT_USG, ds->ciphertext.c2_bits, | 1318 | // product of all exponentiated partiel decryptions ... |
1235 | GNUNET_SECRETSHARING_KEY_BITS / 8, NULL)); | 1319 | gcry_mpi_mulm (prod, prod, tmp, elgamal_p); |
1320 | } | ||
1236 | 1321 | ||
1237 | // m <- c_2 / m | 1322 | GNUNET_CRYPTO_mpi_scan_unsigned (&c_2, ds->ciphertext.c2_bits, GNUNET_SECRETSHARING_ELGAMAL_BITS / 8); |
1238 | gcry_mpi_invm (m, m, elgamal_p); | ||
1239 | gcry_mpi_mulm (m, c_2, m, elgamal_p); | ||
1240 | 1323 | ||
1324 | GNUNET_assert (0 != gcry_mpi_invm (prod, prod, elgamal_p)); | ||
1325 | gcry_mpi_mulm (m, c_2, prod, elgamal_p); | ||
1241 | ev = GNUNET_MQ_msg (msg, GNUNET_MESSAGE_TYPE_SECRETSHARING_CLIENT_DECRYPT_DONE); | 1326 | ev = GNUNET_MQ_msg (msg, GNUNET_MESSAGE_TYPE_SECRETSHARING_CLIENT_DECRYPT_DONE); |
1242 | print_mpi_fixed (&msg->plaintext, m, GNUNET_SECRETSHARING_KEY_BITS / 8); | 1327 | GNUNET_CRYPTO_mpi_print_unsigned (&msg->plaintext, GNUNET_SECRETSHARING_ELGAMAL_BITS / 8, m); |
1243 | msg->success = htonl (1); | 1328 | msg->success = htonl (1); |
1244 | GNUNET_MQ_send (ds->client_mq, ev); | 1329 | GNUNET_MQ_send (ds->client_mq, ev); |
1245 | 1330 | ||
1331 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, "sent decrypt done to client\n"); | ||
1332 | |||
1246 | // FIXME: what if not enough peers participated? | 1333 | // FIXME: what if not enough peers participated? |
1247 | } | 1334 | } |
1248 | 1335 | ||
@@ -1291,8 +1378,8 @@ decrypt_new_element (void *cls, | |||
1291 | 1378 | ||
1292 | // FIXME: check NIZP first | 1379 | // FIXME: check NIZP first |
1293 | 1380 | ||
1294 | GNUNET_assert (0 == gcry_mpi_scan (&info->partial_decryption, | 1381 | GNUNET_CRYPTO_mpi_scan_unsigned (&info->partial_decryption, &d->partial_decryption, |
1295 | GCRYMPI_FMT_USG, &d->partial_decryption, GNUNET_SECRETSHARING_KEY_BITS / 8, NULL)); | 1382 | GNUNET_SECRETSHARING_ELGAMAL_BITS / 8); |
1296 | } | 1383 | } |
1297 | 1384 | ||
1298 | static void | 1385 | static void |
@@ -1303,22 +1390,37 @@ insert_decrypt_element (struct DecryptSession *ds) | |||
1303 | gcry_mpi_t x; | 1390 | gcry_mpi_t x; |
1304 | gcry_mpi_t s; | 1391 | gcry_mpi_t s; |
1305 | 1392 | ||
1306 | GNUNET_assert (0 == gcry_mpi_scan (&x, GCRYMPI_FMT_USG, ds->ciphertext.c1_bits, GNUNET_SECRETSHARING_KEY_BITS / 8, NULL)); | 1393 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "P%u: Inserting decrypt element\n", |
1307 | GNUNET_assert (0 == gcry_mpi_scan (&s, GCRYMPI_FMT_USG, &ds->share->my_share, GNUNET_SECRETSHARING_KEY_BITS / 8, NULL)); | 1394 | ds->share->my_peer); |
1395 | |||
1396 | GNUNET_CRYPTO_mpi_scan_unsigned (&x, &ds->ciphertext.c1_bits, | ||
1397 | GNUNET_SECRETSHARING_ELGAMAL_BITS / 8); | ||
1398 | GNUNET_CRYPTO_mpi_scan_unsigned (&s, &ds->share->my_share, | ||
1399 | GNUNET_SECRETSHARING_ELGAMAL_BITS / 8); | ||
1308 | 1400 | ||
1309 | gcry_mpi_powm (x, x, s, elgamal_p); | 1401 | gcry_mpi_powm (x, x, s, elgamal_p); |
1310 | 1402 | ||
1311 | element.data = (void *) &d; | 1403 | element.data = (void *) &d; |
1312 | element.size = sizeof (struct GNUNET_SECRETSHARING_DecryptData); | 1404 | element.size = sizeof (struct GNUNET_SECRETSHARING_DecryptData); |
1405 | element.type = 0; | ||
1313 | 1406 | ||
1407 | /* make vagrind happy until we implement the real deal ... */ | ||
1408 | memset (&d.nizk_commit1, 0, sizeof d.nizk_commit1); | ||
1409 | memset (&d.nizk_commit2, 0, sizeof d.nizk_commit2); | ||
1410 | memset (&d.nizk_response, 0, sizeof d.nizk_response); | ||
1411 | |||
1412 | d.ciphertext = ds->ciphertext; | ||
1314 | d.peer = my_peer; | 1413 | d.peer = my_peer; |
1315 | d.purpose.size = htonl (element.size - offsetof (struct GNUNET_SECRETSHARING_KeygenRevealData, purpose)); | 1414 | d.purpose.size = htonl (element.size - offsetof (struct GNUNET_SECRETSHARING_DecryptData, purpose)); |
1316 | d.purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_SECRETSHARING_DECRYPTION); | 1415 | d.purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_SECRETSHARING_DECRYPTION); |
1416 | |||
1317 | GNUNET_CRYPTO_eddsa_sign (my_peer_private_key, &d.purpose, &d.signature); | 1417 | GNUNET_CRYPTO_eddsa_sign (my_peer_private_key, &d.purpose, &d.signature); |
1318 | 1418 | ||
1319 | print_mpi_fixed (&d.partial_decryption, x, GNUNET_SECRETSHARING_KEY_BITS / 8); | 1419 | GNUNET_CRYPTO_mpi_print_unsigned (&d.partial_decryption, GNUNET_SECRETSHARING_ELGAMAL_BITS / 8, x); |
1320 | 1420 | ||
1321 | GNUNET_CONSENSUS_insert (ds->consensus, &element, NULL, NULL); | 1421 | GNUNET_CONSENSUS_insert (ds->consensus, &element, NULL, NULL); |
1422 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "P%u: Inserting decrypt element done!\n", | ||
1423 | ds->share->my_peer); | ||
1322 | } | 1424 | } |
1323 | 1425 | ||
1324 | 1426 | ||
@@ -1339,6 +1441,7 @@ static void handle_client_decrypt (void *cls, | |||
1339 | (const void *) message; | 1441 | (const void *) message; |
1340 | struct DecryptSession *ds; | 1442 | struct DecryptSession *ds; |
1341 | struct GNUNET_HashCode session_id; | 1443 | struct GNUNET_HashCode session_id; |
1444 | unsigned int i; | ||
1342 | 1445 | ||
1343 | ds = GNUNET_new (struct DecryptSession); | 1446 | ds = GNUNET_new (struct DecryptSession); |
1344 | // FIXME: check if session already exists | 1447 | // FIXME: check if session already exists |
@@ -1359,52 +1462,82 @@ static void handle_client_decrypt (void *cls, | |||
1359 | ds->share->num_peers, | 1462 | ds->share->num_peers, |
1360 | ds->share->peers, | 1463 | ds->share->peers, |
1361 | &session_id, | 1464 | &session_id, |
1362 | decrypt_new_element, | 1465 | &decrypt_new_element, |
1363 | ds); | 1466 | ds); |
1364 | 1467 | ||
1468 | |||
1469 | ds->info = GNUNET_new_array (ds->share->num_peers, struct DecryptPeerInfo); | ||
1470 | for (i = 0; i < ds->share->num_peers; i++) | ||
1471 | { | ||
1472 | ds->info[i].peer = ds->share->peers[i]; | ||
1473 | ds->info[i].original_index = ds->share->original_indices[i]; | ||
1474 | } | ||
1475 | |||
1365 | insert_decrypt_element (ds); | 1476 | insert_decrypt_element (ds); |
1366 | 1477 | ||
1367 | GNUNET_CONSENSUS_conclude (ds->consensus, ds->deadline, decrypt_conclude, ds); | 1478 | GNUNET_CONSENSUS_conclude (ds->consensus, ds->deadline, decrypt_conclude, ds); |
1479 | |||
1480 | GNUNET_SERVER_receive_done (client, GNUNET_OK); | ||
1481 | |||
1482 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, "decrypting with %u peers\n", | ||
1483 | ds->share->num_peers); | ||
1368 | } | 1484 | } |
1369 | 1485 | ||
1370 | 1486 | ||
1371 | static void | 1487 | static void |
1372 | init_crypto_constants (void) | 1488 | init_crypto_constants (void) |
1373 | { | 1489 | { |
1374 | /* 1024-bit safe prime */ | ||
1375 | const char *elgamal_p_hex = | ||
1376 | "0x08a347d3d69e8b2dd7d1b12a08dfbccbebf4ca" | ||
1377 | "6f4269a0814e158a34312964d946b3ef22882317" | ||
1378 | "2bcf30fc08f772774cb404f9bc002a6f66b09a79" | ||
1379 | "d810d67c4f8cb3bedc6060e3c8ef874b1b64df71" | ||
1380 | "6c7d2b002da880e269438d5a776e6b5f253c8df5" | ||
1381 | "6a16b1c7ce58def07c03db48238aadfc52a354a2" | ||
1382 | "7ed285b0c1675cad3f3"; | ||
1383 | /* 1023-bit Sophie Germain prime, q = (p-1)/2 */ | ||
1384 | const char *elgamal_q_hex = | ||
1385 | "0x0451a3e9eb4f4596ebe8d895046fde65f5fa65" | ||
1386 | "37a134d040a70ac51a1894b26ca359f79144118b" | ||
1387 | "95e7987e047bb93ba65a027cde001537b3584d3c" | ||
1388 | "ec086b3e27c659df6e303071e477c3a58db26fb8" | ||
1389 | "b63e958016d4407134a1c6ad3bb735af929e46fa" | ||
1390 | "b50b58e3e72c6f783e01eda411c556fe2951aa51" | ||
1391 | "3f6942d860b3ae569f9"; | ||
1392 | /* generator of the unique size q subgroup of Z_p^* */ | ||
1393 | const char *elgamal_g_hex = | ||
1394 | "0x05c00c36d2e822950087ef09d8252994adc4e4" | ||
1395 | "8fe3ec70269f035b46063aff0c99b633fd64df43" | ||
1396 | "02442e1914c829a41505a275438871f365e91c12" | ||
1397 | "3d5303ef9e90f4b8cb89bf86cc9b513e74a72634" | ||
1398 | "9cfd9f953674fab5d511e1c078fc72d72b34086f" | ||
1399 | "c82b4b951989eb85325cb203ff98df76bc366bba" | ||
1400 | "1d7024c3650f60d0da"; | ||
1401 | |||
1402 | GNUNET_assert (0 == gcry_mpi_scan (&elgamal_q, GCRYMPI_FMT_HEX, | 1490 | GNUNET_assert (0 == gcry_mpi_scan (&elgamal_q, GCRYMPI_FMT_HEX, |
1403 | elgamal_q_hex, 0, NULL)); | 1491 | GNUNET_SECRETSHARING_ELGAMAL_Q_HEX, 0, NULL)); |
1404 | GNUNET_assert (0 == gcry_mpi_scan (&elgamal_p, GCRYMPI_FMT_HEX, | 1492 | GNUNET_assert (0 == gcry_mpi_scan (&elgamal_p, GCRYMPI_FMT_HEX, |
1405 | elgamal_p_hex, 0, NULL)); | 1493 | GNUNET_SECRETSHARING_ELGAMAL_P_HEX, 0, NULL)); |
1406 | GNUNET_assert (0 == gcry_mpi_scan (&elgamal_g, GCRYMPI_FMT_HEX, | 1494 | GNUNET_assert (0 == gcry_mpi_scan (&elgamal_g, GCRYMPI_FMT_HEX, |
1407 | elgamal_g_hex, 0, NULL)); | 1495 | GNUNET_SECRETSHARING_ELGAMAL_G_HEX, 0, NULL)); |
1496 | } | ||
1497 | |||
1498 | |||
1499 | static struct KeygenSession * | ||
1500 | keygen_session_get (struct GNUNET_SERVER_Client *client) | ||
1501 | { | ||
1502 | struct KeygenSession *ks; | ||
1503 | for (ks = keygen_sessions_head; NULL != ks; ks = ks->next) | ||
1504 | if (ks->client == client) | ||
1505 | return ks; | ||
1506 | return NULL; | ||
1507 | } | ||
1508 | |||
1509 | static struct DecryptSession * | ||
1510 | decrypt_session_get (struct GNUNET_SERVER_Client *client) | ||
1511 | { | ||
1512 | struct DecryptSession *ds; | ||
1513 | for (ds = decrypt_sessions_head; NULL != ds; ds = ds->next) | ||
1514 | if (ds->client == client) | ||
1515 | return ds; | ||
1516 | return NULL; | ||
1517 | } | ||
1518 | |||
1519 | |||
1520 | /** | ||
1521 | * Clean up after a client has disconnected | ||
1522 | * | ||
1523 | * @param cls closure, unused | ||
1524 | * @param client the client to clean up after | ||
1525 | */ | ||
1526 | static void | ||
1527 | handle_client_disconnect (void *cls, struct GNUNET_SERVER_Client *client) | ||
1528 | { | ||
1529 | struct KeygenSession *ks; | ||
1530 | struct DecryptSession *ds; | ||
1531 | |||
1532 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "handling client disconnect\n"); | ||
1533 | |||
1534 | ks = keygen_session_get (client); | ||
1535 | if (NULL != ks) | ||
1536 | keygen_session_destroy (ks); | ||
1537 | |||
1538 | ds = decrypt_session_get (client); | ||
1539 | if (NULL != ds) | ||
1540 | decrypt_session_destroy (ds); | ||
1408 | } | 1541 | } |
1409 | 1542 | ||
1410 | 1543 | ||
@@ -1443,6 +1576,7 @@ run (void *cls, struct GNUNET_SERVER_Handle *server, | |||
1443 | return; | 1576 | return; |
1444 | } | 1577 | } |
1445 | GNUNET_SERVER_add_handlers (server, handlers); | 1578 | GNUNET_SERVER_add_handlers (server, handlers); |
1579 | GNUNET_SERVER_disconnect_notify (server, &handle_client_disconnect, NULL); | ||
1446 | GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL, &cleanup_task, | 1580 | GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL, &cleanup_task, |
1447 | NULL); | 1581 | NULL); |
1448 | } | 1582 | } |
diff --git a/src/secretsharing/secretsharing.h b/src/secretsharing/secretsharing.h index 232721410..e94ff46b7 100644 --- a/src/secretsharing/secretsharing.h +++ b/src/secretsharing/secretsharing.h | |||
@@ -40,7 +40,7 @@ struct GNUNET_SECRETSHARING_FieldElement | |||
40 | /** | 40 | /** |
41 | * Value of an element in <elgamal_g>. | 41 | * Value of an element in <elgamal_g>. |
42 | */ | 42 | */ |
43 | unsigned char bits[GNUNET_SECRETSHARING_KEY_BITS / 8]; | 43 | unsigned char bits[GNUNET_SECRETSHARING_ELGAMAL_BITS / 8]; |
44 | }; | 44 | }; |
45 | 45 | ||
46 | 46 | ||
@@ -107,6 +107,10 @@ struct GNUNET_SECRETSHARING_ShareHeaderNBO | |||
107 | }; | 107 | }; |
108 | 108 | ||
109 | 109 | ||
110 | /** | ||
111 | * Notify the client that then threshold secret has been | ||
112 | * established. | ||
113 | */ | ||
110 | struct GNUNET_SECRETSHARING_SecretReadyMessage | 114 | struct GNUNET_SECRETSHARING_SecretReadyMessage |
111 | { | 115 | { |
112 | /** | 116 | /** |
diff --git a/src/secretsharing/secretsharing_api.c b/src/secretsharing/secretsharing_api.c index d2b53acc7..1489a5c45 100644 --- a/src/secretsharing/secretsharing_api.c +++ b/src/secretsharing/secretsharing_api.c | |||
@@ -27,6 +27,7 @@ | |||
27 | #include "gnunet_util_lib.h" | 27 | #include "gnunet_util_lib.h" |
28 | #include "gnunet_secretsharing_service.h" | 28 | #include "gnunet_secretsharing_service.h" |
29 | #include "secretsharing.h" | 29 | #include "secretsharing.h" |
30 | #include <gcrypt.h> | ||
30 | 31 | ||
31 | 32 | ||
32 | #define LOG(kind,...) GNUNET_log_from (kind, "secretsharing-api",__VA_ARGS__) | 33 | #define LOG(kind,...) GNUNET_log_from (kind, "secretsharing-api",__VA_ARGS__) |
@@ -83,6 +84,40 @@ struct GNUNET_SECRETSHARING_DecryptionHandle | |||
83 | }; | 84 | }; |
84 | 85 | ||
85 | 86 | ||
87 | /** | ||
88 | * The ElGamal prime field order as libgcrypt mpi. | ||
89 | * Initialized in #init_crypto_constants. | ||
90 | */ | ||
91 | static gcry_mpi_t elgamal_q; | ||
92 | |||
93 | /** | ||
94 | * Modulus of the prime field used for ElGamal. | ||
95 | * Initialized in #init_crypto_constants. | ||
96 | */ | ||
97 | static gcry_mpi_t elgamal_p; | ||
98 | |||
99 | /** | ||
100 | * Generator for prime field of order 'elgamal_q'. | ||
101 | * Initialized in #init_crypto_constants. | ||
102 | */ | ||
103 | static gcry_mpi_t elgamal_g; | ||
104 | |||
105 | |||
106 | static void | ||
107 | ensure_elgamal_initialized (void) | ||
108 | { | ||
109 | if (NULL != elgamal_q) | ||
110 | return; /* looks like crypto is already initialized */ | ||
111 | |||
112 | GNUNET_assert (0 == gcry_mpi_scan (&elgamal_q, GCRYMPI_FMT_HEX, | ||
113 | GNUNET_SECRETSHARING_ELGAMAL_Q_HEX, 0, NULL)); | ||
114 | GNUNET_assert (0 == gcry_mpi_scan (&elgamal_p, GCRYMPI_FMT_HEX, | ||
115 | GNUNET_SECRETSHARING_ELGAMAL_P_HEX, 0, NULL)); | ||
116 | GNUNET_assert (0 == gcry_mpi_scan (&elgamal_g, GCRYMPI_FMT_HEX, | ||
117 | GNUNET_SECRETSHARING_ELGAMAL_G_HEX, 0, NULL)); | ||
118 | } | ||
119 | |||
120 | |||
86 | static void | 121 | static void |
87 | handle_session_client_error (void *cls, enum GNUNET_MQ_Error error) | 122 | handle_session_client_error (void *cls, enum GNUNET_MQ_Error error) |
88 | { | 123 | { |
@@ -95,9 +130,12 @@ handle_session_client_error (void *cls, enum GNUNET_MQ_Error error) | |||
95 | static void | 130 | static void |
96 | handle_decrypt_client_error (void *cls, enum GNUNET_MQ_Error error) | 131 | handle_decrypt_client_error (void *cls, enum GNUNET_MQ_Error error) |
97 | { | 132 | { |
98 | GNUNET_assert (0); | 133 | struct GNUNET_SECRETSHARING_DecryptionHandle *dh = cls; |
134 | |||
135 | dh->decrypt_cb (dh->decrypt_cls, NULL); | ||
99 | } | 136 | } |
100 | 137 | ||
138 | |||
101 | static void | 139 | static void |
102 | handle_secret_ready (void *cls, const struct GNUNET_MessageHeader *msg) | 140 | handle_secret_ready (void *cls, const struct GNUNET_MessageHeader *msg) |
103 | { | 141 | { |
@@ -116,6 +154,18 @@ handle_secret_ready (void *cls, const struct GNUNET_MessageHeader *msg) | |||
116 | share->num_peers, | 154 | share->num_peers, |
117 | (struct GNUNET_PeerIdentity *) &m[1]); | 155 | (struct GNUNET_PeerIdentity *) &m[1]); |
118 | 156 | ||
157 | GNUNET_SECRETSHARING_session_destroy (session); | ||
158 | } | ||
159 | |||
160 | |||
161 | void | ||
162 | GNUNET_SECRETSHARING_session_destroy (struct GNUNET_SECRETSHARING_Session *session) | ||
163 | { | ||
164 | GNUNET_MQ_destroy (session->mq); | ||
165 | session->mq = NULL; | ||
166 | GNUNET_CLIENT_disconnect (session->client); | ||
167 | session->client = NULL; | ||
168 | GNUNET_free (session); | ||
119 | } | 169 | } |
120 | 170 | ||
121 | 171 | ||
@@ -169,7 +219,20 @@ GNUNET_SECRETSHARING_create_session (const struct GNUNET_CONFIGURATION_Handle *c | |||
169 | static void | 219 | static void |
170 | handle_decrypt_done (void *cls, const struct GNUNET_MessageHeader *msg) | 220 | handle_decrypt_done (void *cls, const struct GNUNET_MessageHeader *msg) |
171 | { | 221 | { |
172 | GNUNET_assert (0); | 222 | struct GNUNET_SECRETSHARING_DecryptionHandle *dh = cls; |
223 | const struct GNUNET_SECRETSHARING_DecryptResponseMessage *m = | ||
224 | (const void *) msg; | ||
225 | |||
226 | const struct GNUNET_SECRETSHARING_Plaintext *plaintext; | ||
227 | |||
228 | if (m->success == 0) | ||
229 | plaintext = NULL; | ||
230 | else | ||
231 | plaintext = (void *) &m->plaintext; | ||
232 | |||
233 | dh->decrypt_cb (dh->decrypt_cls, plaintext); | ||
234 | |||
235 | GNUNET_SECRETSHARING_decrypt_cancel (dh); | ||
173 | } | 236 | } |
174 | 237 | ||
175 | 238 | ||
@@ -187,9 +250,9 @@ handle_decrypt_done (void *cls, const struct GNUNET_MessageHeader *msg) | |||
187 | * @return handle to cancel the operation | 250 | * @return handle to cancel the operation |
188 | */ | 251 | */ |
189 | struct GNUNET_SECRETSHARING_DecryptionHandle * | 252 | struct GNUNET_SECRETSHARING_DecryptionHandle * |
190 | GNUNET_SECRETSHARING_decrypt (struct GNUNET_CONFIGURATION_Handle *cfg, | 253 | GNUNET_SECRETSHARING_decrypt (const struct GNUNET_CONFIGURATION_Handle *cfg, |
191 | struct GNUNET_SECRETSHARING_Share *share, | 254 | struct GNUNET_SECRETSHARING_Share *share, |
192 | struct GNUNET_SECRETSHARING_Ciphertext *ciphertext, | 255 | const struct GNUNET_SECRETSHARING_Ciphertext *ciphertext, |
193 | struct GNUNET_TIME_Absolute deadline, | 256 | struct GNUNET_TIME_Absolute deadline, |
194 | GNUNET_SECRETSHARING_DecryptCallback decrypt_cb, | 257 | GNUNET_SECRETSHARING_DecryptCallback decrypt_cb, |
195 | void *decrypt_cb_cls) | 258 | void *decrypt_cb_cls) |
@@ -223,6 +286,7 @@ GNUNET_SECRETSHARING_decrypt (struct GNUNET_CONFIGURATION_Handle *cfg, | |||
223 | GNUNET_assert (GNUNET_OK == GNUNET_SECRETSHARING_share_write (share, &msg[1], share_size, NULL)); | 286 | GNUNET_assert (GNUNET_OK == GNUNET_SECRETSHARING_share_write (share, &msg[1], share_size, NULL)); |
224 | 287 | ||
225 | msg->deadline = GNUNET_TIME_absolute_hton (deadline); | 288 | msg->deadline = GNUNET_TIME_absolute_hton (deadline); |
289 | msg->ciphertext = *ciphertext; | ||
226 | 290 | ||
227 | GNUNET_MQ_send (s->mq, ev); | 291 | GNUNET_MQ_send (s->mq, ev); |
228 | 292 | ||
@@ -231,3 +295,112 @@ GNUNET_SECRETSHARING_decrypt (struct GNUNET_CONFIGURATION_Handle *cfg, | |||
231 | } | 295 | } |
232 | 296 | ||
233 | 297 | ||
298 | int | ||
299 | GNUNET_SECRETSHARING_plaintext_generate_i (struct GNUNET_SECRETSHARING_Plaintext *plaintext, | ||
300 | int64_t exponent) | ||
301 | { | ||
302 | int negative; | ||
303 | gcry_mpi_t x; | ||
304 | |||
305 | ensure_elgamal_initialized (); | ||
306 | |||
307 | GNUNET_assert (NULL != (x = gcry_mpi_new (0))); | ||
308 | |||
309 | negative = GNUNET_NO; | ||
310 | if (exponent < 0) | ||
311 | { | ||
312 | negative = GNUNET_YES; | ||
313 | exponent = -exponent; | ||
314 | } | ||
315 | |||
316 | gcry_mpi_set_ui (x, exponent); | ||
317 | |||
318 | gcry_mpi_powm (x, elgamal_g, x, elgamal_p); | ||
319 | |||
320 | if (GNUNET_YES == negative) | ||
321 | { | ||
322 | int res; | ||
323 | res = gcry_mpi_invm (x, x, elgamal_p); | ||
324 | if (0 == res) | ||
325 | return GNUNET_SYSERR; | ||
326 | } | ||
327 | |||
328 | GNUNET_CRYPTO_mpi_print_unsigned (plaintext, sizeof (struct GNUNET_SECRETSHARING_Plaintext), x); | ||
329 | |||
330 | return GNUNET_OK; | ||
331 | } | ||
332 | |||
333 | |||
334 | /** | ||
335 | * Encrypt a value. This operation is executed locally, no communication is | ||
336 | * necessary. | ||
337 | * | ||
338 | * This is a helper function, encryption can be done soley with a session's public key | ||
339 | * and the crypto system parameters. | ||
340 | * | ||
341 | * @param public_key public key to use for decryption | ||
342 | * @param message message to encrypt | ||
343 | * @param message_size number of bytes in @a message | ||
344 | * @param result_ciphertext pointer to store the resulting ciphertext | ||
345 | * @return #GNUNET_YES on succes, #GNUNET_SYSERR if the message is invalid (invalid range) | ||
346 | */ | ||
347 | int | ||
348 | GNUNET_SECRETSHARING_encrypt (const struct GNUNET_SECRETSHARING_PublicKey *public_key, | ||
349 | const struct GNUNET_SECRETSHARING_Plaintext *plaintext, | ||
350 | struct GNUNET_SECRETSHARING_Ciphertext *result_ciphertext) | ||
351 | { | ||
352 | /* pubkey */ | ||
353 | gcry_mpi_t h; | ||
354 | /* nonce */ | ||
355 | gcry_mpi_t y; | ||
356 | /* plaintext message */ | ||
357 | gcry_mpi_t m; | ||
358 | /* temp value */ | ||
359 | gcry_mpi_t tmp; | ||
360 | |||
361 | ensure_elgamal_initialized (); | ||
362 | |||
363 | GNUNET_assert (NULL != (h = gcry_mpi_new (0))); | ||
364 | GNUNET_assert (NULL != (y = gcry_mpi_new (0))); | ||
365 | GNUNET_assert (NULL != (tmp = gcry_mpi_new (0))); | ||
366 | |||
367 | GNUNET_CRYPTO_mpi_scan_unsigned (&h, public_key, sizeof *public_key); | ||
368 | GNUNET_CRYPTO_mpi_scan_unsigned (&m, plaintext, sizeof *plaintext); | ||
369 | |||
370 | // Randomize y such that 0 < y < elgamal_q. | ||
371 | // The '- 1' is necessary as bitlength(q) = bitlength(p) - 1. | ||
372 | do | ||
373 | { | ||
374 | gcry_mpi_randomize (y, GNUNET_SECRETSHARING_ELGAMAL_BITS - 1, GCRY_WEAK_RANDOM); | ||
375 | } while ((gcry_mpi_cmp_ui (y, 0) == 0) || (gcry_mpi_cmp (y, elgamal_q) >= 0)); | ||
376 | |||
377 | // tmp <- g^y | ||
378 | gcry_mpi_powm (tmp, elgamal_g, y, elgamal_p); | ||
379 | // write tmp to c1 | ||
380 | GNUNET_CRYPTO_mpi_print_unsigned (&result_ciphertext->c1_bits, | ||
381 | GNUNET_SECRETSHARING_ELGAMAL_BITS / 8, tmp); | ||
382 | |||
383 | // tmp <- h^y | ||
384 | gcry_mpi_powm (tmp, h, y, elgamal_p); | ||
385 | // tmp <- tmp * m | ||
386 | gcry_mpi_mulm (tmp, tmp, m, elgamal_p); | ||
387 | // write tmp to c2 | ||
388 | GNUNET_CRYPTO_mpi_print_unsigned (&result_ciphertext->c2_bits, | ||
389 | GNUNET_SECRETSHARING_ELGAMAL_BITS / 8, tmp); | ||
390 | |||
391 | return GNUNET_OK; | ||
392 | } | ||
393 | |||
394 | |||
395 | void | ||
396 | GNUNET_SECRETSHARING_decrypt_cancel (struct GNUNET_SECRETSHARING_DecryptionHandle *h) | ||
397 | { | ||
398 | GNUNET_MQ_destroy (h->mq); | ||
399 | h->mq = NULL; | ||
400 | GNUNET_CLIENT_disconnect (h->client); | ||
401 | h->client = NULL; | ||
402 | GNUNET_free (h); | ||
403 | } | ||
404 | |||
405 | |||
406 | |||
diff --git a/src/secretsharing/secretsharing_common.c b/src/secretsharing/secretsharing_common.c index 9f1e4900b..9f21a1102 100644 --- a/src/secretsharing/secretsharing_common.c +++ b/src/secretsharing/secretsharing_common.c | |||
@@ -94,7 +94,7 @@ GNUNET_SECRETSHARING_share_write (const struct GNUNET_SECRETSHARING_Share *share | |||
94 | char *p; | 94 | char *p; |
95 | int n; | 95 | int n; |
96 | 96 | ||
97 | payload_size = ntohs (sh->num_peers) * | 97 | payload_size = ntohs (share->num_peers) * |
98 | (sizeof (uint16_t) + sizeof (struct GNUNET_SECRETSHARING_FieldElement) + | 98 | (sizeof (uint16_t) + sizeof (struct GNUNET_SECRETSHARING_FieldElement) + |
99 | sizeof (struct GNUNET_PeerIdentity)); | 99 | sizeof (struct GNUNET_PeerIdentity)); |
100 | 100 | ||
@@ -134,3 +134,4 @@ GNUNET_SECRETSHARING_share_write (const struct GNUNET_SECRETSHARING_Share *share | |||
134 | return GNUNET_OK; | 134 | return GNUNET_OK; |
135 | } | 135 | } |
136 | 136 | ||
137 | |||
diff --git a/src/secretsharing/test_secretsharing.conf b/src/secretsharing/test_secretsharing.conf index 9cbb95608..6ce865e3a 100644 --- a/src/secretsharing/test_secretsharing.conf +++ b/src/secretsharing/test_secretsharing.conf | |||
@@ -1,6 +1,6 @@ | |||
1 | [secretsharing] | 1 | [secretsharing] |
2 | AUTOSTART = YES | 2 | AUTOSTART = YES |
3 | PREFIX = valgrind | 3 | #PREFIX = valgrind |
4 | 4 | ||
5 | [consensus] | 5 | [consensus] |
6 | AUTOSTART = YES | 6 | AUTOSTART = YES |