aboutsummaryrefslogtreecommitdiff
path: root/src/secretsharing/gnunet-service-secretsharing.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/secretsharing/gnunet-service-secretsharing.c')
-rw-r--r--src/secretsharing/gnunet-service-secretsharing.c772
1 files changed, 657 insertions, 115 deletions
diff --git a/src/secretsharing/gnunet-service-secretsharing.c b/src/secretsharing/gnunet-service-secretsharing.c
index 3af899352..6c91343d5 100644
--- a/src/secretsharing/gnunet-service-secretsharing.c
+++ b/src/secretsharing/gnunet-service-secretsharing.c
@@ -26,6 +26,7 @@
26#include "platform.h" 26#include "platform.h"
27#include "gnunet_util_lib.h" 27#include "gnunet_util_lib.h"
28#include "gnunet_time_lib.h" 28#include "gnunet_time_lib.h"
29#include "gnunet_signatures.h"
29#include "gnunet_consensus_service.h" 30#include "gnunet_consensus_service.h"
30#include "secretsharing.h" 31#include "secretsharing.h"
31#include "secretsharing_protocol.h" 32#include "secretsharing_protocol.h"
@@ -69,10 +70,39 @@ struct KeygenPeerInfo
69 gcry_mpi_t public_key_share; 70 gcry_mpi_t public_key_share;
70 71
71 /** 72 /**
72 * GNUNET_YES if the peer has been disqualified, 73 * Did we successfully receive the round1 element
73 * GNUNET_NO otherwise. 74 * of the peer?
74 */ 75 */
75 int disqualified; 76 int round1_valid;
77
78 /**
79 * Did we successfully receive the round1 element
80 * of the peer?
81 */
82 int round2_valid;
83};
84
85
86struct DecryptPeerInfo
87{
88 /**
89 * Identity of the peer.
90 */
91 struct GNUNET_PeerIdentity peer;
92
93 /**
94 * Original index in the key generation round.
95 * Necessary for computing the lagrange coefficients.
96 */
97 unsigned int real_index;
98
99 /**
100 * Set to the partial decryption of
101 * this peer, or NULL if we did not
102 * receive a partial decryption from this
103 * peer or the zero knowledge proof failed.
104 */
105 gcry_mpi_t partial_decryption;
76}; 106};
77 107
78 108
@@ -120,6 +150,8 @@ struct KeygenSession
120 150
121 /** 151 /**
122 * Minimum number of shares required to restore the secret. 152 * Minimum number of shares required to restore the secret.
153 * Also the number of coefficients for the polynomial representing
154 * the sharing. Obviously, the polynomial then has degree threshold-1.
123 */ 155 */
124 unsigned int threshold; 156 unsigned int threshold;
125 157
@@ -135,6 +167,7 @@ struct KeygenSession
135 167
136 /** 168 /**
137 * Information about all participating peers. 169 * Information about all participating peers.
170 * Array of size 'num_peers'.
138 */ 171 */
139 struct KeygenPeerInfo *info; 172 struct KeygenPeerInfo *info;
140 173
@@ -158,9 +191,18 @@ struct KeygenSession
158 */ 191 */
159 gcry_mpi_t paillier_mu; 192 gcry_mpi_t paillier_mu;
160 193
194 /**
195 * When would we like the key to be established?
196 */
161 struct GNUNET_TIME_Absolute deadline; 197 struct GNUNET_TIME_Absolute deadline;
162 198
163 /** 199 /**
200 * When does the DKG start? Necessary to compute fractions of the
201 * operation's desired time interval.
202 */
203 struct GNUNET_TIME_Absolute start_time;
204
205 /**
164 * Index of the local peer in the ordered list 206 * Index of the local peer in the ordered list
165 * of peers in the session. 207 * of peers in the session.
166 */ 208 */
@@ -170,23 +212,63 @@ struct KeygenSession
170 212
171struct DecryptSession 213struct DecryptSession
172{ 214{
215 /**
216 * Decrypt sessions are stored in a linked list.
217 */
173 struct DecryptSession *next; 218 struct DecryptSession *next;
219
220 /**
221 * Decrypt sessions are stored in a linked list.
222 */
174 struct DecryptSession *prev; 223 struct DecryptSession *prev;
175 224
225 /**
226 * Handle to the consensus over partial decryptions.
227 */
176 struct GNUNET_CONSENSUS_Handle *consensus; 228 struct GNUNET_CONSENSUS_Handle *consensus;
177 229
230 /**
231 * Client connected to us.
232 */
178 struct GNUNET_SERVER_Client *client; 233 struct GNUNET_SERVER_Client *client;
234
235 /**
236 * Message queue for 'client'.
237 */
238 struct GNUNET_MQ_Handle *client_mq;
239
240 /**
241 * When would we like the ciphertext to be
242 * decrypted?
243 */
244 struct GNUNET_TIME_Absolute deadline;
245
246 /**
247 * Ciphertext we want to decrypt.
248 */
249 struct GNUNET_SECRETSHARING_Ciphertext ciphertext;
250
251 /**
252 * Share of the local peer.
253 */
254 struct GNUNET_SECRETSHARING_Share *share;
255
256 /**
257 * State information about other peers.
258 */
259 struct DecryptPeerInfo *info;
179}; 260};
180 261
262
181/** 263/**
182 * Decrypt sessions are held in a linked list. 264 * Decrypt sessions are held in a linked list.
183 */ 265 */
184//static struct DecryptSession *decrypt_sessions_head; 266static struct DecryptSession *decrypt_sessions_head;
185 267
186/** 268/**
187 * Decrypt sessions are held in a linked list. 269 * Decrypt sessions are held in a linked list.
188 */ 270 */
189//static struct DecryptSession *decrypt_sessions_tail; 271static struct DecryptSession *decrypt_sessions_tail;
190 272
191/** 273/**
192 * Decrypt sessions are held in a linked list. 274 * Decrypt sessions are held in a linked list.
@@ -222,6 +304,11 @@ static gcry_mpi_t elgamal_g;
222static struct GNUNET_PeerIdentity my_peer; 304static struct GNUNET_PeerIdentity my_peer;
223 305
224/** 306/**
307 * Peer that runs this service.
308 */
309static struct GNUNET_CRYPTO_EddsaPrivateKey *my_peer_private_key;
310
311/**
225 * Configuration of this service. 312 * Configuration of this service.
226 */ 313 */
227static const struct GNUNET_CONFIGURATION_Handle *cfg; 314static const struct GNUNET_CONFIGURATION_Handle *cfg;
@@ -231,20 +318,79 @@ static const struct GNUNET_CONFIGURATION_Handle *cfg;
231 */ 318 */
232static struct GNUNET_SERVER_Handle *srv; 319static struct GNUNET_SERVER_Handle *srv;
233 320
321/**
322 * Print a field element in a fixed-size buffer.
323 */
324static void
325print_field_element (void *buf, gcry_mpi_t x)
326{
327 GNUNET_assert (0);
328}
329
330
331static struct KeygenPeerInfo *
332get_keygen_peer_info (const struct KeygenSession *ks,
333 const struct GNUNET_PeerIdentity *peer)
334{
335 unsigned int i;
336 for (i = 0; i < ks->num_peers; i++)
337 if (0 == memcmp (peer, &ks->info[i].peer, sizeof (struct GNUNET_PeerIdentity)))
338 return &ks->info[i];
339 return NULL;
340}
341
342
343static struct DecryptPeerInfo *
344get_decrypt_peer_info (const struct DecryptSession *ds,
345 const struct GNUNET_PeerIdentity *peer)
346{
347 unsigned int i;
348 for (i = 0; i < ds->share->num_peers; i++)
349 if (0 == memcmp (peer, &ds->info[i].peer, sizeof (struct GNUNET_PeerIdentity)))
350 return &ds->info[i];
351 return NULL;
352}
353
354
355static struct GNUNET_TIME_Absolute
356time_between (struct GNUNET_TIME_Absolute start,
357 struct GNUNET_TIME_Absolute end,
358 int num, int denum)
359{
360 struct GNUNET_TIME_Absolute result;
361 uint64_t diff;
362
363 GNUNET_assert (start.abs_value_us <= end.abs_value_us);
364 diff = end.abs_value_us - start.abs_value_us;
365 result.abs_value_us = start.abs_value_us + ((diff * num) / denum);
366
367 return result;
368}
369
234 370
235/** 371/**
236 * Although GNUNET_CRYPTO_hash_cmp exisits, it does not have 372 * Compare two peer identities. Indended to be used with qsort or bsearch.
237 * the correct signature to be used with e.g. qsort.
238 * We use this function instead.
239 * 373 *
240 * @param h1 some hash code 374 * @param p1 some peer identity
241 * @param h2 some hash code 375 * @param p2 some peer identity
242 * @return 1 if h1 > h2, -1 if h1 < h2 and 0 if h1 == h2. 376 * @return 1 if p1 > p2, -1 if p1 < p2 and 0 if p1 == p2.
243 */ 377 */
244static int 378static int
245hash_cmp (const void *h1, const void *h2) 379peer_id_cmp (const void *p1, const void *p2)
380{
381 return memcmp (p1, p2, sizeof (struct GNUNET_PeerIdentity));
382}
383
384
385int
386peer_find (const struct GNUNET_PeerIdentity *haystack, unsigned int n,
387 const struct GNUNET_PeerIdentity *needle)
246{ 388{
247 return GNUNET_CRYPTO_hash_cmp ((struct GNUNET_HashCode *) h1, (struct GNUNET_HashCode *) h2); 389 unsigned int i;
390 for (i = 0; i < n; i++)
391 if (0 == memcmp (&haystack[i], needle, sizeof (struct GNUNET_PeerIdentity)))
392 return i;
393 return -1;
248} 394}
249 395
250 396
@@ -266,45 +412,84 @@ normalize_peers (struct GNUNET_PeerIdentity *listed,
266{ 412{
267 unsigned int local_peer_in_list; 413 unsigned int local_peer_in_list;
268 unsigned int n; 414 unsigned int n;
269 unsigned int i;
270 struct GNUNET_PeerIdentity *normalized; 415 struct GNUNET_PeerIdentity *normalized;
271 416
272 local_peer_in_list = GNUNET_NO; 417 local_peer_in_list = GNUNET_YES;
273 for (i = 0; i < num_listed; i++) 418 n = num_listed;
419 if (peer_find (listed, num_listed, &my_peer) < 0)
274 { 420 {
275 if (0 == memcmp (&listed[i], &my_peer, sizeof (struct GNUNET_PeerIdentity))) 421 local_peer_in_list = GNUNET_NO;
276 { 422 n += 1;
277 local_peer_in_list = GNUNET_YES;
278 break;
279 }
280 } 423 }
281 424
282 n = num_listed; 425 normalized = GNUNET_new_array (n, struct GNUNET_PeerIdentity);
283 if (GNUNET_NO == local_peer_in_list)
284 n++;
285
286 normalized = GNUNET_malloc (n * sizeof (struct GNUNET_PeerIdentity));
287 426
288 if (GNUNET_NO == local_peer_in_list) 427 if (GNUNET_NO == local_peer_in_list)
289 normalized[n - 1] = my_peer; 428 normalized[n - 1] = my_peer;
290 429
291 memcpy (normalized, listed, num_listed * sizeof (struct GNUNET_PeerIdentity)); 430 memcpy (normalized, listed, num_listed * sizeof (struct GNUNET_PeerIdentity));
292 qsort (normalized, n, sizeof (struct GNUNET_PeerIdentity), &hash_cmp); 431 qsort (normalized, n, sizeof (struct GNUNET_PeerIdentity), &peer_id_cmp);
293 432
294 if (NULL != my_peer_idx) 433 if (NULL != my_peer_idx)
434 *my_peer_idx = peer_find (normalized, n, &my_peer);
435 if (NULL != num_normalized)
436 *num_normalized = n;
437
438 return normalized;
439}
440
441
442/**
443 * Get a the j-th lagrage coefficient for a set of indices.
444 *
445 * @param[out] coeff the lagrange coefficient
446 * @param j lagrage coefficient we want to compute
447 * @param indices indices
448 * @param num number of indices in @a indices
449 */
450static void
451compute_lagrange_coefficient (gcry_mpi_t coeff, unsigned int j,
452 unsigned int *indices,
453 unsigned int num)
454{
455 int i;
456 /* numerator */
457 gcry_mpi_t n;
458 /* denominator */
459 gcry_mpi_t d;
460 /* temp value for l-j */
461 gcry_mpi_t tmp;
462
463 GNUNET_assert (0 != coeff);
464
465 GNUNET_assert (0 != (n = gcry_mpi_new (0)));
466 GNUNET_assert (0 != (d = gcry_mpi_new (0)));
467 GNUNET_assert (0 != (tmp = gcry_mpi_new (0)));
468
469 gcry_mpi_set_ui (n, 1);
470 gcry_mpi_set_ui (d, 1);
471
472 gcry_mpi_set_ui (coeff, 0);
473 for (i = 0; i < num; i++)
295 { 474 {
296 for (i = 0; i < num_listed; i++) 475 int l = indices[i];
297 { 476 if (l == j)
298 if (0 == memcmp (&normalized[i], &my_peer, sizeof (struct GNUNET_PeerIdentity))) 477 continue;
299 { 478 gcry_mpi_mul_ui (n, n, l);
300 *my_peer_idx = i; 479 // d <- d * (l-j)
301 break; 480 gcry_mpi_set_ui (tmp, l);
302 } 481 gcry_mpi_sub_ui (tmp, tmp, j);
303 } 482 gcry_mpi_mul (d, d, tmp);
304 } 483 }
305 484
306 *num_normalized = n; 485 // now we do the actual division, with everything mod q, as we
307 return normalized; 486 // are not operating on elemets from <g>, but on exponents
487 GNUNET_assert (0 == gcry_mpi_invm (d, d, elgamal_q));
488 gcry_mpi_mulm (coeff, n, d, elgamal_q);
489
490 gcry_mpi_release (n);
491 gcry_mpi_release (d);
492 gcry_mpi_release (tmp);
308} 493}
309 494
310 495
@@ -433,44 +618,76 @@ generate_presecret_polynomial (struct KeygenSession *ks)
433 for (i = 0; i < ks->threshold; i++) 618 for (i = 0; i < ks->threshold; i++)
434 { 619 {
435 ks->presecret_polynomial[i] = gcry_mpi_new (PAILLIER_BITS); 620 ks->presecret_polynomial[i] = gcry_mpi_new (PAILLIER_BITS);
621 GNUNET_assert (0 != ks->presecret_polynomial[i]);
436 gcry_mpi_randomize (ks->presecret_polynomial[i], PAILLIER_BITS, 622 gcry_mpi_randomize (ks->presecret_polynomial[i], PAILLIER_BITS,
437 GCRY_WEAK_RANDOM); 623 GCRY_WEAK_RANDOM);
438 } 624 }
439} 625}
440 626
441 627
628/**
629 * Consensus element handler for round one.
630 *
631 * @param cls closure (keygen session)
632 * @param element the element from consensus
633 */
442static void 634static void
443keygen_round1_new_element (void *cls, 635keygen_round1_new_element (void *cls,
444 const struct GNUNET_SET_Element *element) 636 const struct GNUNET_SET_Element *element)
445{ 637{
446 const struct GNUNET_SECRETSHARING_KeygenCommitData *d; 638 const struct GNUNET_SECRETSHARING_KeygenCommitData *d;
447 struct KeygenSession *ks = cls; 639 struct KeygenSession *ks = cls;
448 unsigned int i; 640 struct KeygenPeerInfo *info;
641
642 if (NULL == element)
643 {
644 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "round1 consensus failed\n");
645 return;
646 }
449 647
450 if (element->size != sizeof (struct GNUNET_SECRETSHARING_KeygenCommitData)) 648 if (element->size != sizeof (struct GNUNET_SECRETSHARING_KeygenCommitData))
451 { 649 {
452 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "keygen commit data with wrong size in consensus\n"); 650 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
651 "keygen commit data with wrong size (%u) in consensus, "
652 " %u expected\n",
653 element->size, sizeof (struct GNUNET_SECRETSHARING_KeygenCommitData));
453 return; 654 return;
454 } 655 }
455 656
657 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "got round1 element\n");
658
456 d = element->data; 659 d = element->data;
457 660
458 for (i = 0; i < ks->num_peers; i++) 661 info = get_keygen_peer_info (ks, &d->peer);
662
663 if (NULL == info)
459 { 664 {
460 if (0 == memcmp (&d->peer, &ks->info[i].peer, sizeof (struct GNUNET_PeerIdentity))) 665 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "keygen commit data with wrong peer identity (%s) in consensus\n",
461 { 666 GNUNET_i2s (&d->peer));
462 // TODO: check signature 667 return;
463 GNUNET_assert (0 == gcry_mpi_scan (&ks->info[i].paillier_g, GCRYMPI_FMT_USG, 668 }
464 &d->pubkey.g, sizeof d->pubkey.g, NULL)); 669
465 GNUNET_assert (0 == gcry_mpi_scan (&ks->info[i].paillier_n, GCRYMPI_FMT_USG, 670 if (d->purpose.size !=
466 &d->pubkey.n, sizeof d->pubkey.n, NULL)); 671 htons (element->size - offsetof (struct GNUNET_SECRETSHARING_KeygenCommitData, purpose)))
467 GNUNET_assert (0 == gcry_mpi_scan (&ks->info[i].presecret_commitment, GCRYMPI_FMT_USG, 672 {
468 &d->commitment, sizeof d->commitment, NULL)); 673 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "keygen commit data with wrong signature purpose size in consensus\n");
469 return; 674 return;
470 }
471 } 675 }
472 676
473 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "keygen commit data with wrong peer identity in consensus\n"); 677 if (GNUNET_OK != GNUNET_CRYPTO_eddsa_verify (GNUNET_SIGNATURE_PURPOSE_SECRETSHARING_DKG1,
678 &d->purpose, &d->signature, &d->peer.public_key))
679 {
680 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "keygen commit data with invalid signature in consensus\n");
681 return;
682 }
683
684 GNUNET_assert (0 == gcry_mpi_scan (&info->paillier_g, GCRYMPI_FMT_USG,
685 &d->pubkey.g, sizeof d->pubkey.g, NULL));
686 GNUNET_assert (0 == gcry_mpi_scan (&info->paillier_n, GCRYMPI_FMT_USG,
687 &d->pubkey.n, sizeof d->pubkey.n, NULL));
688 GNUNET_assert (0 == gcry_mpi_scan (&info->presecret_commitment, GCRYMPI_FMT_USG,
689 &d->commitment, sizeof d->commitment, NULL));
690 info->round1_valid = GNUNET_YES;
474} 691}
475 692
476 693
@@ -505,30 +722,60 @@ keygen_round2_conclude (void *cls)
505 struct KeygenSession *ks = cls; 722 struct KeygenSession *ks = cls;
506 struct GNUNET_SECRETSHARING_SecretReadyMessage *m; 723 struct GNUNET_SECRETSHARING_SecretReadyMessage *m;
507 struct GNUNET_MQ_Envelope *ev; 724 struct GNUNET_MQ_Envelope *ev;
725 size_t share_size;
508 unsigned int i; 726 unsigned int i;
727 unsigned int j;
728 struct GNUNET_SECRETSHARING_Share *share;
509 gcry_mpi_t s; 729 gcry_mpi_t s;
510 gcry_mpi_t h; 730 gcry_mpi_t h;
511 731
732 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "round2 conclude\n");
733
512 GNUNET_assert (0 != (s = gcry_mpi_new (PAILLIER_BITS))); 734 GNUNET_assert (0 != (s = gcry_mpi_new (PAILLIER_BITS)));
513 GNUNET_assert (0 != (h = gcry_mpi_new (PAILLIER_BITS))); 735 GNUNET_assert (0 != (h = gcry_mpi_new (PAILLIER_BITS)));
514 736
515 // multiplicative identity 737 // multiplicative identity
516 gcry_mpi_set_ui (s, 1); 738 gcry_mpi_set_ui (s, 1);
517 739
740 share = GNUNET_new (struct GNUNET_SECRETSHARING_Share);
741
742 share->num_peers = 0;
743
744 for (i = 0; i < ks->num_peers; i++)
745 if (GNUNET_YES == ks->info[i].round2_valid)
746 share->num_peers++;
747
748 share->peers = GNUNET_new_array (share->num_peers, struct GNUNET_PeerIdentity);
749 share->hom_share_commitments =
750 GNUNET_new_array (share->num_peers, struct GNUNET_SECRETSHARING_FieldElement);
751 share->original_indices = GNUNET_new_array (share->num_peers, uint16_t);
752
753 j = 0;
518 for (i = 0; i < ks->num_peers; i++) 754 for (i = 0; i < ks->num_peers; i++)
519 { 755 {
520 if (GNUNET_NO == ks->info[i].disqualified) 756 if (GNUNET_YES == ks->info[i].round2_valid)
521 { 757 {
522 gcry_mpi_addm (s, s, ks->info[i].decrypted_preshare, elgamal_p); 758 gcry_mpi_addm (s, s, ks->info[i].decrypted_preshare, elgamal_p);
523 gcry_mpi_mulm (h, h, ks->info[i].public_key_share, elgamal_p); 759 gcry_mpi_mulm (h, h, ks->info[i].public_key_share, elgamal_p);
524 // m->num_secret_peers++; // FIXME: m not initialized here! 760 share->peers[i] = ks->info[i].peer;
761 share->original_indices[i] = j++;
525 } 762 }
526 } 763 }
527 764
528 ev = GNUNET_MQ_msg (m, GNUNET_MESSAGE_TYPE_SECRETSHARING_CLIENT_SECRET_READY); 765 gcry_mpi_print (GCRYMPI_FMT_USG, (void *) &share->my_share, PAILLIER_BITS / 8, NULL, s);
766 gcry_mpi_print (GCRYMPI_FMT_USG, (void *) &share->public_key, PAILLIER_BITS / 8, NULL, s);
767
768 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "keygen successful with %u peers\n", share->num_peers);
769
770 m = GNUNET_malloc (sizeof (struct GNUNET_SECRETSHARING_SecretReadyMessage) +
771 ks->num_peers * sizeof (struct GNUNET_PeerIdentity));
772
773 GNUNET_assert (GNUNET_OK == GNUNET_SECRETSHARING_share_write (share, NULL, 0, &share_size));
529 774
530 gcry_mpi_print (GCRYMPI_FMT_USG, (void *) &m->secret, PAILLIER_BITS / 8, NULL, s); 775 ev = GNUNET_MQ_msg_extra (m, share_size,
531 gcry_mpi_print (GCRYMPI_FMT_USG, (void *) &m->public_key, PAILLIER_BITS / 8, NULL, s); 776 GNUNET_MESSAGE_TYPE_SECRETSHARING_CLIENT_SECRET_READY);
777
778 GNUNET_assert (GNUNET_OK == GNUNET_SECRETSHARING_share_write (share, &m[1], share_size, NULL));
532 779
533 GNUNET_MQ_send (ks->client_mq, ev); 780 GNUNET_MQ_send (ks->client_mq, ev);
534} 781}
@@ -548,17 +795,14 @@ static void
548insert_round2_element (struct KeygenSession *ks) 795insert_round2_element (struct KeygenSession *ks)
549{ 796{
550 struct GNUNET_SET_Element *element; 797 struct GNUNET_SET_Element *element;
551 struct GNUNET_SECRETSHARING_KeygenRevealData *msg; 798 struct GNUNET_SECRETSHARING_KeygenRevealData *d;
552 unsigned char *pos; 799 unsigned char *pos;
553 unsigned char *last_pos; 800 unsigned char *last_pos;
554 size_t element_size; 801 size_t element_size;
555 unsigned int i; 802 unsigned int i;
556 gcry_mpi_t c;
557 gcry_mpi_t idx; 803 gcry_mpi_t idx;
558 gcry_mpi_t v; 804 gcry_mpi_t v;
559 805
560 GNUNET_assert (0 != (c = gcry_mpi_new (PAILLIER_BITS)));
561 // FIXME: c is never used...
562 GNUNET_assert (0 != (v = gcry_mpi_new (PAILLIER_BITS))); 806 GNUNET_assert (0 != (v = gcry_mpi_new (PAILLIER_BITS)));
563 GNUNET_assert (0 != (idx = gcry_mpi_new (PAILLIER_BITS))); 807 GNUNET_assert (0 != (idx = gcry_mpi_new (PAILLIER_BITS)));
564 808
@@ -567,13 +811,17 @@ insert_round2_element (struct KeygenSession *ks)
567 1 * PAILLIER_BITS / 8 * ks->threshold); 811 1 * PAILLIER_BITS / 8 * ks->threshold);
568 812
569 element = GNUNET_malloc (sizeof (struct GNUNET_SET_Element) + element_size); 813 element = GNUNET_malloc (sizeof (struct GNUNET_SET_Element) + element_size);
814 element->size = element_size;
815 element->data = (void *) &element[1];
570 816
571 msg = (void *) element->data; 817 d = (void *) element->data;
572 pos = (void *) &msg[1]; 818 d->peer = my_peer;
819
820 pos = (void *) &d[1];
573 last_pos = pos + element_size; 821 last_pos = pos + element_size;
574 822
575 // exponentiated pre-shares 823 // exponentiated pre-shares
576 for (i = 0; i <= ks->threshold; i++) 824 for (i = 0; i < ks->num_peers; i++)
577 { 825 {
578 ptrdiff_t remaining = last_pos - pos; 826 ptrdiff_t remaining = last_pos - pos;
579 GNUNET_assert (remaining > 0); 827 GNUNET_assert (remaining > 0);
@@ -586,112 +834,168 @@ insert_round2_element (struct KeygenSession *ks)
586 pos += PAILLIER_BITS / 8; 834 pos += PAILLIER_BITS / 8;
587 } 835 }
588 836
589 // exponentiated coefficients 837 // encrypted pre-shares
590 for (i = 0; i < ks->num_peers; i++) 838 for (i = 0; i < ks->num_peers; i++)
591 { 839 {
592 ptrdiff_t remaining = last_pos - pos; 840 ptrdiff_t remaining = last_pos - pos;
593 GNUNET_assert (remaining > 0); 841 GNUNET_assert (remaining > 0);
594 gcry_mpi_powm (v, elgamal_g, ks->presecret_polynomial[0], elgamal_p); 842 if (GNUNET_NO == ks->info[i].round1_valid)
843 gcry_mpi_set_ui (v, 0);
844 else
845 paillier_encrypt (v, ks->presecret_polynomial[0],
846 ks->info[i].paillier_g, ks->info[i].paillier_g);
595 gcry_mpi_print (GCRYMPI_FMT_USG, pos, (size_t) remaining, NULL, v); 847 gcry_mpi_print (GCRYMPI_FMT_USG, pos, (size_t) remaining, NULL, v);
596 pos += PAILLIER_BITS / 8; 848 pos += PAILLIER_BITS / 8;
597 } 849 }
598 850
599 // encrypted pre-shares 851 // exponentiated coefficients
600 for (i = 0; i < ks->threshold; i++) 852 for (i = 0; i < ks->threshold; i++)
601 { 853 {
602 ptrdiff_t remaining = last_pos - pos; 854 ptrdiff_t remaining = last_pos - pos;
603 GNUNET_assert (remaining > 0); 855 GNUNET_assert (remaining > 0);
604 if (GNUNET_YES == ks->info[i].disqualified) 856 gcry_mpi_powm (v, elgamal_g, ks->presecret_polynomial[i], elgamal_p);
605 gcry_mpi_set_ui (v, 0);
606 else
607 paillier_encrypt (v, ks->presecret_polynomial[0],
608 ks->info[i].paillier_g, ks->info[i].paillier_g);
609 gcry_mpi_print (GCRYMPI_FMT_USG, pos, (size_t) remaining, NULL, v); 857 gcry_mpi_print (GCRYMPI_FMT_USG, pos, (size_t) remaining, NULL, v);
610 pos += PAILLIER_BITS / 8; 858 pos += PAILLIER_BITS / 8;
611 } 859 }
612 860
861 d->purpose.size = htons (element_size - offsetof (struct GNUNET_SECRETSHARING_KeygenRevealData, purpose));
862 d->purpose.purpose = htons (GNUNET_SIGNATURE_PURPOSE_SECRETSHARING_DKG2);
863 GNUNET_CRYPTO_eddsa_sign (my_peer_private_key, &d->purpose, &d->signature);
864
613 GNUNET_CONSENSUS_insert (ks->consensus, element, NULL, NULL); 865 GNUNET_CONSENSUS_insert (ks->consensus, element, NULL, NULL);
614 GNUNET_free (element); /* FIXME: maybe stack-allocate instead? */ 866 GNUNET_free (element); /* FIXME: maybe stack-allocate instead? */
615 867
616 gcry_mpi_release (c);
617 gcry_mpi_release (v); 868 gcry_mpi_release (v);
618 gcry_mpi_release (idx); 869 gcry_mpi_release (idx);
619} 870}
620 871
621 872
622static struct KeygenPeerInfo *
623get_keygen_peer_info (const struct KeygenSession *ks,
624 struct GNUNET_PeerIdentity *peer)
625{
626 unsigned int i;
627 for (i = 0; i < ks->num_peers; i++)
628 if (0 == memcmp (peer, &ks->info[i].peer, sizeof (struct GNUNET_PeerIdentity)))
629 return &ks->info[i];
630 return NULL;
631}
632
633
634static void 873static void
635keygen_round2_new_element (void *cls, 874keygen_round2_new_element (void *cls,
636 const struct GNUNET_SET_Element *element) 875 const struct GNUNET_SET_Element *element)
637{ 876{
638 struct KeygenSession *ks = cls; 877 struct KeygenSession *ks = cls;
639 struct GNUNET_SECRETSHARING_KeygenRevealData *msg; 878 const struct GNUNET_SECRETSHARING_KeygenRevealData *d;
640 struct KeygenPeerInfo *info; 879 struct KeygenPeerInfo *info;
641 unsigned char *pos; 880 unsigned char *pos;
642 unsigned char *last_pos;
643 gcry_mpi_t c; 881 gcry_mpi_t c;
882 size_t expected_element_size;
644 883
645 msg = (void *) element->data; 884 if (NULL == element)
646 pos = (void *) &msg[1]; 885 {
647 // skip exp. pre-shares 886 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "round2 consensus failed\n");
648 pos += PAILLIER_BITS / 8 * ks->num_peers; 887 return;
649 // skip exp. coefficients 888 }
650 pos += PAILLIER_BITS / 8 * ks->threshold;
651 // skip to the value for our peer
652 pos += PAILLIER_BITS / 8 * ks->local_peer_idx;
653 889
654 last_pos = element->size + (unsigned char *) element->data; 890 expected_element_size = (sizeof (struct GNUNET_SECRETSHARING_KeygenRevealData) +
891 2 * PAILLIER_BITS / 8 * ks->num_peers +
892 1 * PAILLIER_BITS / 8 * ks->threshold);
655 893
656 if ((pos >= last_pos) || ((last_pos - pos) < (PAILLIER_BITS / 8))) 894 if (element->size != expected_element_size)
657 { 895 {
658 GNUNET_break_op (0); 896 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
897 "keygen round2 data with wrong size (%u) in consensus, "
898 " %u expected\n",
899 element->size, expected_element_size);
659 return; 900 return;
660 } 901 }
661 902
662 GNUNET_assert (0 == gcry_mpi_scan (&c, GCRYMPI_FMT_USG, 903 d = (const void *) element->data;
663 pos, PAILLIER_BITS / 8, NULL));
664 904
665 info = get_keygen_peer_info (ks, &msg->peer); 905 info = get_keygen_peer_info (ks, &d->peer);
666 906
667 if (NULL == info) 907 if (NULL == info)
668 { 908 {
669 GNUNET_break_op (0); 909 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "keygen commit data with wrong peer identity (%s) in consensus\n",
910 GNUNET_i2s (&d->peer));
911 return;
912 }
913
914 if (GNUNET_NO == info->round1_valid)
915 {
916 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
917 "ignoring round2 element from peer with invalid round1 element (%s)\n",
918 GNUNET_i2s (&d->peer));
670 return; 919 return;
671 } 920 }
672 921
922 if (GNUNET_YES == info->round2_valid)
923 {
924 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
925 "ignoring duplicate round2 element (%s)\n",
926 GNUNET_i2s (&d->peer));
927 return;
928 }
929
930 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "got round2 element\n");
931
932
933 pos = (void *) &d[1];
934 // skip exponentiated pre-shares
935 pos += PAILLIER_BITS / 8 * ks->num_peers;
936 // skip encrypted pre-shares
937 pos += PAILLIER_BITS / 8 * ks->num_peers;
938 // the first exponentiated coefficient is the public key share
939 GNUNET_assert (0 == gcry_mpi_scan (&info->public_key_share, GCRYMPI_FMT_USG,
940 pos, PAILLIER_BITS / 8, NULL));
941
942 pos = (void *) &d[1];
943 // skip exp. pre-shares
944 pos += PAILLIER_BITS / 8 * ks->num_peers;
945 // skip to the encrypted value for our peer
946 pos += PAILLIER_BITS / 8 * ks->local_peer_idx;
947
948 GNUNET_assert (0 == gcry_mpi_scan (&c, GCRYMPI_FMT_USG,
949 pos, PAILLIER_BITS / 8, NULL));
950
951 GNUNET_assert (0 != (info->decrypted_preshare = mpi_new (0)));
952
673 paillier_decrypt (info->decrypted_preshare, c, ks->paillier_lambda, ks->paillier_mu, 953 paillier_decrypt (info->decrypted_preshare, c, ks->paillier_lambda, ks->paillier_mu,
674 ks->info[ks->local_peer_idx].paillier_n); 954 ks->info[ks->local_peer_idx].paillier_n);
675 955
676 // TODO: validate signature and proofs 956 // TODO: validate zero knowledge proofs
957
958 if (d->purpose.size !=
959 htons (element->size - offsetof (struct GNUNET_SECRETSHARING_KeygenRevealData, purpose)))
960 {
961 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "keygen reveal data with wrong signature purpose size in consensus\n");
962 return;
963 }
677 964
965 if (GNUNET_OK != GNUNET_CRYPTO_eddsa_verify (GNUNET_SIGNATURE_PURPOSE_SECRETSHARING_DKG2,
966 &d->purpose, &d->signature, &d->peer.public_key))
967 {
968 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "keygen reveal data with invalid signature in consensus\n");
969 return;
970 }
971
972 info->round2_valid = GNUNET_YES;
678} 973}
679 974
680 975
976/**
977 * Called when the first consensus round has concluded.
978 * Will initiate the second round.
979 *
980 * @param cls closure
981 */
681static void 982static void
682keygen_round1_conclude (void *cls) 983keygen_round1_conclude (void *cls)
683{ 984{
684 struct KeygenSession *ks = cls; 985 struct KeygenSession *ks = cls;
685 986
686 // TODO: destroy old consensus 987 GNUNET_CONSENSUS_destroy (ks->consensus);
687 // TODO: mark peers without keys as disqualified
688 988
689 ks->consensus = GNUNET_CONSENSUS_create (cfg, ks->num_peers, ks->peers, &ks->session_id, 989 ks->consensus = GNUNET_CONSENSUS_create (cfg, ks->num_peers, ks->peers, &ks->session_id,
690 keygen_round2_new_element, ks); 990 keygen_round2_new_element, ks);
691 991
692 insert_round2_element (ks); 992 insert_round2_element (ks);
693 993
694 GNUNET_CONSENSUS_conclude (ks->consensus, GNUNET_TIME_UNIT_FOREVER_REL /* FIXME */, keygen_round2_conclude, ks); 994 GNUNET_CONSENSUS_conclude (ks->consensus,
995 /* last round, thus conclude at DKG deadline */
996 ks->deadline,
997 keygen_round2_conclude,
998 ks);
695} 999}
696 1000
697 1001
@@ -716,6 +1020,8 @@ insert_round1_element (struct KeygenSession *ks)
716 element->data = d; 1020 element->data = d;
717 element->size = sizeof *d; 1021 element->size = sizeof *d;
718 1022
1023 d->peer = my_peer;
1024
719 GNUNET_assert (0 != (v = gcry_mpi_new (PAILLIER_BITS))); 1025 GNUNET_assert (0 != (v = gcry_mpi_new (PAILLIER_BITS)));
720 1026
721 gcry_mpi_powm (v, elgamal_g, ks->presecret_polynomial[0], elgamal_p); 1027 gcry_mpi_powm (v, elgamal_g, ks->presecret_polynomial[0], elgamal_p);
@@ -734,9 +1040,9 @@ insert_round1_element (struct KeygenSession *ks)
734 (unsigned char *) d->pubkey.n, PAILLIER_BITS / 8, NULL, 1040 (unsigned char *) d->pubkey.n, PAILLIER_BITS / 8, NULL,
735 ks->info[ks->local_peer_idx].paillier_n)); 1041 ks->info[ks->local_peer_idx].paillier_n));
736 1042
737 // FIXME: sign stuff 1043 d->purpose.size = htons ((sizeof *d) - offsetof (struct GNUNET_SECRETSHARING_KeygenCommitData, purpose));
738 1044 d->purpose.purpose = htons (GNUNET_SIGNATURE_PURPOSE_SECRETSHARING_DKG1);
739 d->peer = my_peer; 1045 GNUNET_assert (GNUNET_OK == GNUNET_CRYPTO_eddsa_sign (my_peer_private_key, &d->purpose, &d->signature));
740 1046
741 GNUNET_CONSENSUS_insert (ks->consensus, element, NULL, NULL); 1047 GNUNET_CONSENSUS_insert (ks->consensus, element, NULL, NULL);
742} 1048}
@@ -758,13 +1064,19 @@ static void handle_client_keygen (void *cls,
758 const struct GNUNET_SECRETSHARING_CreateMessage *msg = 1064 const struct GNUNET_SECRETSHARING_CreateMessage *msg =
759 (const struct GNUNET_SECRETSHARING_CreateMessage *) message; 1065 (const struct GNUNET_SECRETSHARING_CreateMessage *) message;
760 struct KeygenSession *ks; 1066 struct KeygenSession *ks;
1067 unsigned int i;
761 1068
762 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "client requested key generation\n"); 1069 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "client requested key generation\n");
763 1070
764 ks = GNUNET_new (struct KeygenSession); 1071 ks = GNUNET_new (struct KeygenSession);
765 1072
1073 /* FIXME: check if client already has some session */
1074
766 GNUNET_CONTAINER_DLL_insert (keygen_sessions_head, keygen_sessions_tail, ks); 1075 GNUNET_CONTAINER_DLL_insert (keygen_sessions_head, keygen_sessions_tail, ks);
767 1076
1077 ks->client = client;
1078 ks->client_mq = GNUNET_MQ_queue_for_server_client (client);
1079
768 ks->deadline = GNUNET_TIME_absolute_ntoh (msg->deadline); 1080 ks->deadline = GNUNET_TIME_absolute_ntoh (msg->deadline);
769 ks->threshold = ntohs (msg->threshold); 1081 ks->threshold = ntohs (msg->threshold);
770 ks->num_peers = ntohs (msg->num_peers); 1082 ks->num_peers = ntohs (msg->num_peers);
@@ -772,11 +1084,21 @@ static void handle_client_keygen (void *cls,
772 ks->peers = normalize_peers ((struct GNUNET_PeerIdentity *) &msg[1], ks->num_peers, 1084 ks->peers = normalize_peers ((struct GNUNET_PeerIdentity *) &msg[1], ks->num_peers,
773 &ks->num_peers, &ks->local_peer_idx); 1085 &ks->num_peers, &ks->local_peer_idx);
774 1086
775 // TODO: initialize MPIs in peer structure
776 1087
1088 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "first round of consensus with %u peers\n", ks->num_peers);
777 ks->consensus = GNUNET_CONSENSUS_create (cfg, ks->num_peers, ks->peers, &msg->session_id, 1089 ks->consensus = GNUNET_CONSENSUS_create (cfg, ks->num_peers, ks->peers, &msg->session_id,
778 keygen_round1_new_element, ks); 1090 keygen_round1_new_element, ks);
779 1091
1092 ks->info = GNUNET_malloc (ks->num_peers * sizeof (struct KeygenPeerInfo));
1093
1094 for (i = 0; i < ks->num_peers; i++)
1095 ks->info[i].peer = ks->peers[i];
1096
1097 GNUNET_assert (0 != (ks->info[ks->local_peer_idx].paillier_g = mpi_new (0)));
1098 GNUNET_assert (0 != (ks->info[ks->local_peer_idx].paillier_n = mpi_new (0)));
1099 GNUNET_assert (0 != (ks->paillier_lambda = mpi_new (0)));
1100 GNUNET_assert (0 != (ks->paillier_mu = mpi_new (0)));
1101
780 paillier_create (ks->info[ks->local_peer_idx].paillier_g, 1102 paillier_create (ks->info[ks->local_peer_idx].paillier_g,
781 ks->info[ks->local_peer_idx].paillier_n, 1103 ks->info[ks->local_peer_idx].paillier_n,
782 ks->paillier_lambda, 1104 ks->paillier_lambda,
@@ -787,7 +1109,149 @@ static void handle_client_keygen (void *cls,
787 1109
788 insert_round1_element (ks); 1110 insert_round1_element (ks);
789 1111
790 GNUNET_CONSENSUS_conclude (ks->consensus, GNUNET_TIME_UNIT_FOREVER_REL /* FIXME */, keygen_round1_conclude, ks); 1112 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "starting conclude of round 1\n");
1113
1114 GNUNET_CONSENSUS_conclude (ks->consensus,
1115 /* half the overall time */
1116 time_between (ks->start_time, ks->deadline, 1, 2),
1117 keygen_round1_conclude,
1118 ks);
1119
1120 GNUNET_SERVER_receive_done (client, GNUNET_OK);
1121}
1122
1123
1124/**
1125 * Called when the partial decryption consensus concludes.
1126 */
1127static void
1128decrypt_conclude (void *cls)
1129{
1130 struct DecryptSession *ds = cls;
1131 struct GNUNET_SECRETSHARING_DecryptResponseMessage *msg;
1132 struct GNUNET_MQ_Envelope *ev;
1133 gcry_mpi_t lagrange;
1134 gcry_mpi_t m;
1135 gcry_mpi_t tmp;
1136 gcry_mpi_t c_2;
1137 unsigned int *indices;
1138 unsigned int num;
1139 unsigned int i;
1140 unsigned int j;
1141
1142 GNUNET_assert (0 != (lagrange = gcry_mpi_new (0)));
1143 GNUNET_assert (0 != (m = gcry_mpi_new (0)));
1144 GNUNET_assert (0 != (tmp = gcry_mpi_new (0)));
1145
1146 num = 0;
1147 for (i = 0; i < ds->share->num_peers; i++)
1148 if (NULL != ds->info[i].partial_decryption)
1149 num++;
1150
1151 indices = GNUNET_malloc (num * sizeof (unsigned int));
1152 j = 0;
1153 for (i = 0; i < ds->share->num_peers; i++)
1154 if (NULL != ds->info[i].partial_decryption)
1155 indices[j++] = ds->info[i].real_index;
1156
1157 gcry_mpi_set_ui (m, 1);
1158
1159 for (i = 0; i < num; i++)
1160 {
1161 compute_lagrange_coefficient (lagrange, indices[i], indices, num);
1162 // w_j^{\lambda_j}
1163 gcry_mpi_powm (tmp, ds->info[indices[i]].partial_decryption, lagrange, elgamal_p);
1164 gcry_mpi_mulm (m, m, tmp, elgamal_p);
1165 }
1166
1167 GNUNET_assert (0 == gcry_mpi_scan (&c_2, GCRYMPI_FMT_USG, ds->ciphertext.c2_bits,
1168 PAILLIER_BITS / 8, NULL));
1169
1170 // m <- c_2 / m
1171 gcry_mpi_invm (m, m, elgamal_p);
1172 gcry_mpi_mulm (m, c_2, m, elgamal_p);
1173
1174 ev = GNUNET_MQ_msg (msg, GNUNET_MESSAGE_TYPE_SECRETSHARING_CLIENT_DECRYPT_DONE);
1175 print_field_element (&msg->plaintext, m);
1176 msg->success = htonl (1);
1177 GNUNET_MQ_send (ds->client_mq, ev);
1178
1179 // FIXME: what if not enough peers participated?
1180}
1181
1182
1183/**
1184 * Called when a new partial decryption arrives.
1185 */
1186static void
1187decrypt_new_element (void *cls,
1188 const struct GNUNET_SET_Element *element)
1189{
1190 struct DecryptSession *session = cls;
1191 const struct GNUNET_SECRETSHARING_DecryptData *d;
1192 struct DecryptPeerInfo *info;
1193
1194 if (NULL == element)
1195 {
1196 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "decryption failed\n");
1197 /* FIXME: destroy */
1198 return;
1199 }
1200
1201 if (element->size != sizeof *d)
1202 {
1203 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "element of wrong size in decrypt consensus\n");
1204 return;
1205 }
1206
1207 d = element->data;
1208
1209 info = get_decrypt_peer_info (session, &d->peer);
1210
1211 if (NULL == info)
1212 {
1213 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "decrypt element from invalid peer (%s)\n",
1214 GNUNET_i2s (&d->peer));
1215 return;
1216 }
1217
1218 if (NULL != info->partial_decryption)
1219 {
1220 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "decrypt element duplicate\n",
1221 GNUNET_i2s (&d->peer));
1222 return;
1223 }
1224
1225 // FIXME: check NIZP first
1226
1227 GNUNET_assert (0 == gcry_mpi_scan (&info->partial_decryption,
1228 GCRYMPI_FMT_USG, &d->partial_decryption, PAILLIER_BITS / 8, NULL));
1229}
1230
1231static void
1232insert_decrypt_element (struct DecryptSession *ds)
1233{
1234 struct GNUNET_SECRETSHARING_DecryptData d;
1235 struct GNUNET_SET_Element element;
1236 gcry_mpi_t x;
1237 gcry_mpi_t s;
1238
1239 GNUNET_assert (0 == gcry_mpi_scan (&x, GCRYMPI_FMT_USG, ds->ciphertext.c1_bits, PAILLIER_BITS / 8, NULL));
1240 GNUNET_assert (0 == gcry_mpi_scan (&s, GCRYMPI_FMT_USG, &ds->share->my_share, PAILLIER_BITS / 8, NULL));
1241
1242 gcry_mpi_powm (x, x, s, elgamal_p);
1243
1244 element.data = (void *) &d;
1245 element.size = sizeof (struct GNUNET_SECRETSHARING_DecryptData);
1246
1247 d.peer = my_peer;
1248 d.purpose.size = htons (element.size - offsetof (struct GNUNET_SECRETSHARING_KeygenRevealData, purpose));
1249 d.purpose.purpose = htons (GNUNET_SIGNATURE_PURPOSE_SECRETSHARING_DECRYPTION);
1250 GNUNET_CRYPTO_eddsa_sign (my_peer_private_key, &d.purpose, &d.signature);
1251
1252 print_field_element (&d.partial_decryption, x);
1253
1254 GNUNET_CONSENSUS_insert (ds->consensus, &element, NULL, NULL);
791} 1255}
792 1256
793 1257
@@ -800,11 +1264,80 @@ static void handle_client_keygen (void *cls,
800 * @param message the actual message 1264 * @param message the actual message
801 */ 1265 */
802static void handle_client_decrypt (void *cls, 1266static void handle_client_decrypt (void *cls,
803 struct GNUNET_SERVER_Client *client, 1267 struct GNUNET_SERVER_Client *client,
804 const struct GNUNET_MessageHeader 1268 const struct GNUNET_MessageHeader
805 *message) 1269 *message)
806{ 1270{
807 GNUNET_assert (0); 1271 const struct GNUNET_SECRETSHARING_DecryptRequestMessage *msg =
1272 (const void *) message;
1273 struct DecryptSession *ds;
1274 struct GNUNET_HashCode session_id;
1275
1276 ds = GNUNET_new (struct DecryptSession);
1277 // FIXME: check if session already exists
1278 GNUNET_CONTAINER_DLL_insert (decrypt_sessions_head, decrypt_sessions_tail, ds);
1279 ds->client = client;
1280 ds->client_mq = GNUNET_MQ_queue_for_server_client (client);
1281 ds->deadline = GNUNET_TIME_absolute_ntoh (msg->deadline);
1282 ds->ciphertext = msg->ciphertext;
1283
1284 ds->share = GNUNET_SECRETSHARING_share_read (&msg[1], ntohs (msg->header.size) - sizeof *msg, NULL);
1285 // FIXME: probably should be break rather than assert
1286 GNUNET_assert (NULL != ds->share);
1287
1288 // FIXME: this is probably sufficient, but kdf/hash with all values would be nicer ...
1289 GNUNET_CRYPTO_hash (&msg->ciphertext, sizeof (struct GNUNET_SECRETSHARING_Ciphertext), &session_id);
1290
1291 ds->consensus = GNUNET_CONSENSUS_create (cfg,
1292 ds->share->num_peers,
1293 ds->share->peers,
1294 &session_id,
1295 decrypt_new_element,
1296 ds);
1297
1298 insert_decrypt_element (ds);
1299
1300 GNUNET_CONSENSUS_conclude (ds->consensus, ds->deadline, decrypt_conclude, ds);
1301}
1302
1303
1304static void
1305init_crypto_constants (void)
1306{
1307 /* 1024-bit safe prime */
1308 const char *elgamal_p_hex =
1309 "0x08a347d3d69e8b2dd7d1b12a08dfbccbebf4ca"
1310 "6f4269a0814e158a34312964d946b3ef22882317"
1311 "2bcf30fc08f772774cb404f9bc002a6f66b09a79"
1312 "d810d67c4f8cb3bedc6060e3c8ef874b1b64df71"
1313 "6c7d2b002da880e269438d5a776e6b5f253c8df5"
1314 "6a16b1c7ce58def07c03db48238aadfc52a354a2"
1315 "7ed285b0c1675cad3f3";
1316 /* 1023-bit Sophie Germain prime, q = (p-1)/2 */
1317 const char *elgamal_q_hex =
1318 "0x0451a3e9eb4f4596ebe8d895046fde65f5fa65"
1319 "37a134d040a70ac51a1894b26ca359f79144118b"
1320 "95e7987e047bb93ba65a027cde001537b3584d3c"
1321 "ec086b3e27c659df6e303071e477c3a58db26fb8"
1322 "b63e958016d4407134a1c6ad3bb735af929e46fa"
1323 "b50b58e3e72c6f783e01eda411c556fe2951aa51"
1324 "3f6942d860b3ae569f9";
1325 /* generator of the unique size q subgroup of Z_p^* */
1326 const char *elgamal_g_hex =
1327 "0x05c00c36d2e822950087ef09d8252994adc4e4"
1328 "8fe3ec70269f035b46063aff0c99b633fd64df43"
1329 "02442e1914c829a41505a275438871f365e91c12"
1330 "3d5303ef9e90f4b8cb89bf86cc9b513e74a72634"
1331 "9cfd9f953674fab5d511e1c078fc72d72b34086f"
1332 "c82b4b951989eb85325cb203ff98df76bc366bba"
1333 "1d7024c3650f60d0da";
1334
1335 GNUNET_assert (0 == gcry_mpi_scan (&elgamal_q, GCRYMPI_FMT_HEX,
1336 elgamal_q_hex, 0, NULL));
1337 GNUNET_assert (0 == gcry_mpi_scan (&elgamal_p, GCRYMPI_FMT_HEX,
1338 elgamal_p_hex, 0, NULL));
1339 GNUNET_assert (0 == gcry_mpi_scan (&elgamal_g, GCRYMPI_FMT_HEX,
1340 elgamal_g_hex, 0, NULL));
808} 1341}
809 1342
810 1343
@@ -826,6 +1359,15 @@ run (void *cls, struct GNUNET_SERVER_Handle *server,
826 }; 1359 };
827 cfg = c; 1360 cfg = c;
828 srv = server; 1361 srv = server;
1362 my_peer_private_key = GNUNET_CRYPTO_eddsa_key_create_from_configuration (c);
1363 if (NULL == my_peer_private_key)
1364 {
1365 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "could not access host private key\n");
1366 GNUNET_break (0);
1367 GNUNET_SCHEDULER_shutdown ();
1368 return;
1369 }
1370 init_crypto_constants ();
829 if (GNUNET_OK != GNUNET_CRYPTO_get_peer_identity (cfg, &my_peer)) 1371 if (GNUNET_OK != GNUNET_CRYPTO_get_peer_identity (cfg, &my_peer))
830 { 1372 {
831 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "could not retrieve host identity\n"); 1373 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "could not retrieve host identity\n");