diff options
Diffstat (limited to 'src/secretsharing/gnunet-service-secretsharing.c')
-rw-r--r-- | src/secretsharing/gnunet-service-secretsharing.c | 506 |
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 | */ | ||
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 | } |