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.c506
1 files changed, 320 insertions, 186 deletions
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 */
333static void
334adjust (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 */
355static void
356print_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 */
373static struct KeygenPeerInfo * 336static struct KeygenPeerInfo *
374get_keygen_peer_info (const struct KeygenSession *ks, 337get_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 */
392static struct DecryptPeerInfo * 355static struct DecryptPeerInfo *
393get_decrypt_peer_info (const struct DecryptSession *ds, 356get_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 */
435static int 398static 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 */
451static int 414static 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 */
473static struct GNUNET_PeerIdentity * 436static struct GNUNET_PeerIdentity *
474normalize_peers (struct GNUNET_PeerIdentity *listed, 437normalize_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
652paillier_decrypt (gcry_mpi_t m, gcry_mpi_t c, gcry_mpi_t mu, gcry_mpi_t lambda, gcry_mpi_t n) 633paillier_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
651static void
652decrypt_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
675static void
676keygen_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,
672static void 705static void
673cleanup_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) 706cleanup_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
685generate_presecret_polynomial (struct KeygenSession *ks) 722generate_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 */
706static void 751static void
707keygen_round1_new_element (void *cls, 752keygen_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
1298static void 1385static 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
1371static void 1487static void
1372init_crypto_constants (void) 1488init_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
1499static struct KeygenSession *
1500keygen_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
1509static struct DecryptSession *
1510decrypt_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 */
1526static void
1527handle_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}