diff options
author | Florian Dold <florian.dold@gmail.com> | 2013-12-10 11:14:22 +0000 |
---|---|---|
committer | Florian Dold <florian.dold@gmail.com> | 2013-12-10 11:14:22 +0000 |
commit | f3a98e004caf91688887a01b5fe2ad3f11813238 (patch) | |
tree | 74fc500c7771e38e6cc2f71d18953cdf210a5f9f /src | |
parent | 119237806b48c9220abc1b96b860bb8f7af03417 (diff) | |
download | gnunet-f3a98e004caf91688887a01b5fe2ad3f11813238.tar.gz gnunet-f3a98e004caf91688887a01b5fe2ad3f11813238.zip |
- key generation for secretsharing
- gnunet-ecc -E also prints hex
Diffstat (limited to 'src')
-rw-r--r-- | src/include/gnunet_protocols.h | 2 | ||||
-rw-r--r-- | src/include/gnunet_secretsharing_service.h | 4 | ||||
-rw-r--r-- | src/secretsharing/Makefile.am | 15 | ||||
-rw-r--r-- | src/secretsharing/gnunet-service-secretsharing.c | 246 | ||||
-rw-r--r-- | src/secretsharing/secretsharing.h | 17 | ||||
-rw-r--r-- | src/secretsharing/secretsharing_api.c | 94 | ||||
-rw-r--r-- | src/secretsharing/secretsharing_protocol.h | 25 | ||||
-rw-r--r-- | src/util/gnunet-ecc.c | 17 |
8 files changed, 383 insertions, 37 deletions
diff --git a/src/include/gnunet_protocols.h b/src/include/gnunet_protocols.h index 8fc1cd6e6..ea150c52f 100644 --- a/src/include/gnunet_protocols.h +++ b/src/include/gnunet_protocols.h | |||
@@ -2289,7 +2289,7 @@ extern "C" | |||
2289 | * The cryptosystem has been established. | 2289 | * The cryptosystem has been established. |
2290 | * Contains the peer's share. | 2290 | * Contains the peer's share. |
2291 | */ | 2291 | */ |
2292 | #define GNUNET_MESSAGE_TYPE_SECRETSHARING_CLIENT_ESTABLISHED 783 | 2292 | #define GNUNET_MESSAGE_TYPE_SECRETSHARING_CLIENT_SECRET_READY 783 |
2293 | 2293 | ||
2294 | 2294 | ||
2295 | 2295 | ||
diff --git a/src/include/gnunet_secretsharing_service.h b/src/include/gnunet_secretsharing_service.h index 7752bb2d2..4479f0d80 100644 --- a/src/include/gnunet_secretsharing_service.h +++ b/src/include/gnunet_secretsharing_service.h | |||
@@ -119,7 +119,7 @@ struct GNUNET_SECRETSHARING_Message | |||
119 | */ | 119 | */ |
120 | typedef void (*GNUNET_SECRETSHARING_SecretReadyCallback) (void *cls, | 120 | typedef void (*GNUNET_SECRETSHARING_SecretReadyCallback) (void *cls, |
121 | const struct GNUNET_SECRETSHARING_Share *my_share, | 121 | const struct GNUNET_SECRETSHARING_Share *my_share, |
122 | const struct GNUNET_SECRETSHARING_PublicKey public_key, | 122 | const struct GNUNET_SECRETSHARING_PublicKey *public_key, |
123 | unsigned int num_ready_peers, | 123 | unsigned int num_ready_peers, |
124 | const struct GNUNET_PeerIdentity *ready_peers); | 124 | const struct GNUNET_PeerIdentity *ready_peers); |
125 | 125 | ||
@@ -157,7 +157,7 @@ GNUNET_SECRETSHARING_create_session (const struct GNUNET_CONFIGURATION_Handle *c | |||
157 | const struct GNUNET_HashCode *session_id, | 157 | const struct GNUNET_HashCode *session_id, |
158 | struct GNUNET_TIME_Absolute deadline, | 158 | struct GNUNET_TIME_Absolute deadline, |
159 | unsigned int threshold, | 159 | unsigned int threshold, |
160 | GNUNET_SECRETSHARING_SecretReadyCallback *cb, | 160 | GNUNET_SECRETSHARING_SecretReadyCallback cb, |
161 | void *cls); | 161 | void *cls); |
162 | 162 | ||
163 | 163 | ||
diff --git a/src/secretsharing/Makefile.am b/src/secretsharing/Makefile.am index 96af95a44..a94bf293c 100644 --- a/src/secretsharing/Makefile.am +++ b/src/secretsharing/Makefile.am | |||
@@ -15,12 +15,27 @@ if USE_COVERAGE | |||
15 | AM_CFLAGS = -fprofile-arcs -ftest-coverage | 15 | AM_CFLAGS = -fprofile-arcs -ftest-coverage |
16 | endif | 16 | endif |
17 | 17 | ||
18 | |||
19 | bin_PROGRAMS = \ | ||
20 | gnunet-secretsharing-profiler | ||
21 | |||
18 | libexec_PROGRAMS = \ | 22 | libexec_PROGRAMS = \ |
19 | gnunet-service-secretsharing | 23 | gnunet-service-secretsharing |
20 | 24 | ||
21 | lib_LTLIBRARIES = \ | 25 | lib_LTLIBRARIES = \ |
22 | libgnunetsecretsharing.la | 26 | libgnunetsecretsharing.la |
23 | 27 | ||
28 | |||
29 | gnunet_secretsharing_profiler_SOURCES = \ | ||
30 | gnunet-secretsharing-profiler.c | ||
31 | gnunet_secretsharing_profiler_LDADD = \ | ||
32 | $(top_builddir)/src/util/libgnunetutil.la \ | ||
33 | $(top_builddir)/src/secretsharing/libgnunetsecretsharing.la \ | ||
34 | $(top_builddir)/src/testbed/libgnunettestbed.la \ | ||
35 | $(GN_LIBINTL) | ||
36 | gnunet_secretsharing_profiler_DEPENDENCIES = \ | ||
37 | libgnunetsecretsharing.la | ||
38 | |||
24 | gnunet_service_secretsharing_SOURCES = \ | 39 | gnunet_service_secretsharing_SOURCES = \ |
25 | gnunet-service-secretsharing.c | 40 | gnunet-service-secretsharing.c |
26 | gnunet_service_secretsharing_LDADD = \ | 41 | gnunet_service_secretsharing_LDADD = \ |
diff --git a/src/secretsharing/gnunet-service-secretsharing.c b/src/secretsharing/gnunet-service-secretsharing.c index 4020a554a..6ca0d85f9 100644 --- a/src/secretsharing/gnunet-service-secretsharing.c +++ b/src/secretsharing/gnunet-service-secretsharing.c | |||
@@ -32,7 +32,6 @@ | |||
32 | #include <gcrypt.h> | 32 | #include <gcrypt.h> |
33 | 33 | ||
34 | 34 | ||
35 | |||
36 | /** | 35 | /** |
37 | * Info about a peer in a key generation session. | 36 | * Info about a peer in a key generation session. |
38 | */ | 37 | */ |
@@ -51,7 +50,7 @@ struct KeygenPeerInfo | |||
51 | /** | 50 | /** |
52 | * mu-component of the peer's paillier public key. | 51 | * mu-component of the peer's paillier public key. |
53 | */ | 52 | */ |
54 | gcry_mpi_t paillier_mu; | 53 | gcry_mpi_t paillier_n; |
55 | 54 | ||
56 | /** | 55 | /** |
57 | * The peer's commitment to his presecret. | 56 | * The peer's commitment to his presecret. |
@@ -59,6 +58,17 @@ struct KeygenPeerInfo | |||
59 | gcry_mpi_t presecret_commitment; | 58 | gcry_mpi_t presecret_commitment; |
60 | 59 | ||
61 | /** | 60 | /** |
61 | * The peer's preshare that we could decrypt | ||
62 | * with out private key. | ||
63 | */ | ||
64 | gcry_mpi_t decrypted_preshare; | ||
65 | |||
66 | /** | ||
67 | * Multiplicative share of the public key. | ||
68 | */ | ||
69 | gcry_mpi_t public_key_share; | ||
70 | |||
71 | /** | ||
62 | * GNUNET_YES if the peer has been disqualified, | 72 | * GNUNET_YES if the peer has been disqualified, |
63 | * GNUNET_NO otherwise. | 73 | * GNUNET_NO otherwise. |
64 | */ | 74 | */ |
@@ -93,6 +103,11 @@ struct KeygenSession | |||
93 | struct GNUNET_SERVER_Client *client; | 103 | struct GNUNET_SERVER_Client *client; |
94 | 104 | ||
95 | /** | 105 | /** |
106 | * Message queue for 'client' | ||
107 | */ | ||
108 | struct GNUNET_MQ_Handle *client_mq; | ||
109 | |||
110 | /** | ||
96 | * Randomly generated coefficients of the polynomial for sharing our | 111 | * Randomly generated coefficients of the polynomial for sharing our |
97 | * pre-secret, where 'preshares[0]' is our pre-secret. Contains 'threshold' | 112 | * pre-secret, where 'preshares[0]' is our pre-secret. Contains 'threshold' |
98 | * elements, thus represents a polynomial of degree 'threshold-1', which can | 113 | * elements, thus represents a polynomial of degree 'threshold-1', which can |
@@ -136,7 +151,7 @@ struct KeygenSession | |||
136 | /** | 151 | /** |
137 | * g-component of our peer's paillier private key. | 152 | * g-component of our peer's paillier private key. |
138 | */ | 153 | */ |
139 | gcry_mpi_t paillier_g; | 154 | gcry_mpi_t paillier_lambda; |
140 | 155 | ||
141 | /** | 156 | /** |
142 | * g-component of our peer's paillier private key. | 157 | * g-component of our peer's paillier private key. |
@@ -166,12 +181,12 @@ struct DecryptSession | |||
166 | /** | 181 | /** |
167 | * Decrypt sessions are held in a linked list. | 182 | * Decrypt sessions are held in a linked list. |
168 | */ | 183 | */ |
169 | static struct DecryptSession *decrypt_sessions_head; | 184 | //static struct DecryptSession *decrypt_sessions_head; |
170 | 185 | ||
171 | /** | 186 | /** |
172 | * Decrypt sessions are held in a linked list. | 187 | * Decrypt sessions are held in a linked list. |
173 | */ | 188 | */ |
174 | static struct DecryptSession *decrypt_sessions_tail; | 189 | //static struct DecryptSession *decrypt_sessions_tail; |
175 | 190 | ||
176 | /** | 191 | /** |
177 | * Decrypt sessions are held in a linked list. | 192 | * Decrypt sessions are held in a linked list. |
@@ -298,9 +313,14 @@ normalize_peers (struct GNUNET_PeerIdentity *listed, | |||
298 | * | 313 | * |
299 | * Uses the simplified key generation of Jonathan Katz, Yehuda Lindell, | 314 | * Uses the simplified key generation of Jonathan Katz, Yehuda Lindell, |
300 | * "Introduction to Modern Cryptography: Principles and Protocols". | 315 | * "Introduction to Modern Cryptography: Principles and Protocols". |
316 | * | ||
317 | * @param g g-component of public key | ||
318 | * @param n n-component of public key | ||
319 | * @param lambda lambda-component of private key | ||
320 | * @param mu mu-componenent of private key | ||
301 | */ | 321 | */ |
302 | static void | 322 | static void |
303 | paillier_create (unsigned int s, gcry_mpi_t n, gcry_mpi_t g, gcry_mpi_t lambda, gcry_mpi_t mu) | 323 | paillier_create (gcry_mpi_t g, gcry_mpi_t n, gcry_mpi_t lambda, gcry_mpi_t mu) |
304 | { | 324 | { |
305 | gcry_mpi_t p; | 325 | gcry_mpi_t p; |
306 | gcry_mpi_t q; | 326 | gcry_mpi_t q; |
@@ -311,9 +331,9 @@ paillier_create (unsigned int s, gcry_mpi_t n, gcry_mpi_t g, gcry_mpi_t lambda, | |||
311 | GNUNET_assert (0 != (tmp = gcry_mpi_new (PAILLIER_BITS))); | 331 | GNUNET_assert (0 != (tmp = gcry_mpi_new (PAILLIER_BITS))); |
312 | 332 | ||
313 | // generate rsa modulus | 333 | // generate rsa modulus |
314 | GNUNET_assert (0 == gcry_prime_generate (&p, s, 0, NULL, NULL, NULL, | 334 | GNUNET_assert (0 == gcry_prime_generate (&p, PAILLIER_BITS / 2, 0, NULL, NULL, NULL, |
315 | GCRY_WEAK_RANDOM, 0)); | 335 | GCRY_WEAK_RANDOM, 0)); |
316 | GNUNET_assert (0 == gcry_prime_generate (&q, s, 0, NULL, NULL, NULL, | 336 | GNUNET_assert (0 == gcry_prime_generate (&q, PAILLIER_BITS / 2, 0, NULL, NULL, NULL, |
317 | GCRY_WEAK_RANDOM, 0)); | 337 | GCRY_WEAK_RANDOM, 0)); |
318 | gcry_mpi_mul (n, p, q); | 338 | gcry_mpi_mul (n, p, q); |
319 | gcry_mpi_add_ui (g, n, 1); | 339 | gcry_mpi_add_ui (g, n, 1); |
@@ -332,6 +352,14 @@ paillier_create (unsigned int s, gcry_mpi_t n, gcry_mpi_t g, gcry_mpi_t lambda, | |||
332 | } | 352 | } |
333 | 353 | ||
334 | 354 | ||
355 | /** | ||
356 | * Encrypt a value using Paillier's scheme. | ||
357 | * | ||
358 | * @param c resulting ciphertext | ||
359 | * @param m plaintext to encrypt | ||
360 | * @param g g-component of public key | ||
361 | * @param n n-component of public key | ||
362 | */ | ||
335 | static void | 363 | static void |
336 | paillier_encrypt (gcry_mpi_t c, gcry_mpi_t m, gcry_mpi_t g, gcry_mpi_t n) | 364 | paillier_encrypt (gcry_mpi_t c, gcry_mpi_t m, gcry_mpi_t g, gcry_mpi_t n) |
337 | { | 365 | { |
@@ -359,6 +387,14 @@ paillier_encrypt (gcry_mpi_t c, gcry_mpi_t m, gcry_mpi_t g, gcry_mpi_t n) | |||
359 | } | 387 | } |
360 | 388 | ||
361 | 389 | ||
390 | /** | ||
391 | * Decrypt a ciphertext using Paillier's scheme. | ||
392 | * | ||
393 | * @param m[out] resulting plaintext | ||
394 | * @param c ciphertext to decrypt | ||
395 | * @param lambda lambda-component of private key | ||
396 | * @param mu mu-component of private key | ||
397 | */ | ||
362 | static void | 398 | static void |
363 | paillier_decrypt (gcry_mpi_t m, gcry_mpi_t c, gcry_mpi_t mu, gcry_mpi_t lambda, gcry_mpi_t n) | 399 | paillier_decrypt (gcry_mpi_t m, gcry_mpi_t c, gcry_mpi_t mu, gcry_mpi_t lambda, gcry_mpi_t n) |
364 | { | 400 | { |
@@ -422,13 +458,18 @@ keygen_round1_new_element (void *cls, | |||
422 | { | 458 | { |
423 | if (0 == memcmp (&d->peer, &ks->info[i].peer, sizeof (struct GNUNET_PeerIdentity))) | 459 | if (0 == memcmp (&d->peer, &ks->info[i].peer, sizeof (struct GNUNET_PeerIdentity))) |
424 | { | 460 | { |
425 | // TODO: check signature and store key data | 461 | // TODO: check signature |
462 | GNUNET_assert (0 == gcry_mpi_scan (&ks->info[i].paillier_g, GCRYMPI_FMT_USG, | ||
463 | &d->pubkey.g, sizeof d->pubkey.g, NULL)); | ||
464 | GNUNET_assert (0 == gcry_mpi_scan (&ks->info[i].paillier_n, GCRYMPI_FMT_USG, | ||
465 | &d->pubkey.n, sizeof d->pubkey.n, NULL)); | ||
466 | GNUNET_assert (0 == gcry_mpi_scan (&ks->info[i].presecret_commitment, GCRYMPI_FMT_USG, | ||
467 | &d->commitment, sizeof d->commitment, NULL)); | ||
426 | return; | 468 | return; |
427 | } | 469 | } |
428 | } | 470 | } |
429 | 471 | ||
430 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "keygen commit data with wrong peer identity in consensus\n"); | 472 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "keygen commit data with wrong peer identity in consensus\n"); |
431 | |||
432 | } | 473 | } |
433 | 474 | ||
434 | 475 | ||
@@ -460,39 +501,116 @@ horner_eval (gcry_mpi_t z, gcry_mpi_t *coeff, unsigned int num_coeff, gcry_mpi_t | |||
460 | static void | 501 | static void |
461 | keygen_round2_conclude (void *cls) | 502 | keygen_round2_conclude (void *cls) |
462 | { | 503 | { |
463 | // TODO: recombine shares and send to client | 504 | struct KeygenSession *ks = cls; |
464 | GNUNET_assert (0); | 505 | struct GNUNET_SECRETSHARING_SecretReadyMessage *m; |
506 | struct GNUNET_MQ_Envelope *ev; | ||
507 | unsigned int i; | ||
508 | gcry_mpi_t s; | ||
509 | gcry_mpi_t h; | ||
510 | struct GNUNET_PeerIdentity *pid; | ||
511 | |||
512 | GNUNET_assert (0 != (s = gcry_mpi_new (PAILLIER_BITS))); | ||
513 | GNUNET_assert (0 != (h = gcry_mpi_new (PAILLIER_BITS))); | ||
514 | |||
515 | // multiplicative identity | ||
516 | gcry_mpi_set_ui (s, 1); | ||
517 | |||
518 | pid = (void *) &m[1]; | ||
519 | |||
520 | for (i = 0; i < ks->num_peers; i++) | ||
521 | { | ||
522 | if (GNUNET_NO == ks->info[i].disqualified) | ||
523 | { | ||
524 | gcry_mpi_addm (s, s, ks->info[i].decrypted_preshare, elgamal_p); | ||
525 | gcry_mpi_mulm (h, h, ks->info[i].public_key_share, elgamal_p); | ||
526 | m->num_secret_peers++; | ||
527 | *pid = ks->info[i].peer; | ||
528 | pid++; | ||
529 | } | ||
530 | } | ||
531 | |||
532 | ev = GNUNET_MQ_msg (m, GNUNET_MESSAGE_TYPE_SECRETSHARING_CLIENT_SECRET_READY); | ||
533 | |||
534 | gcry_mpi_print (GCRYMPI_FMT_USG, (void *) &m->secret, PAILLIER_BITS / 8, NULL, s); | ||
535 | gcry_mpi_print (GCRYMPI_FMT_USG, (void *) &m->public_key, PAILLIER_BITS / 8, NULL, s); | ||
536 | |||
537 | GNUNET_MQ_send (ks->client_mq, ev); | ||
465 | } | 538 | } |
466 | 539 | ||
467 | 540 | ||
541 | /** | ||
542 | * Insert round 2 element in the consensus, consisting of | ||
543 | * (1) The exponentiated pre-share polynomial coefficients A_{i,l}=g^{a_{i,l}} | ||
544 | * (2) The exponentiated pre-shares y_{i,j}=g^{s_{i,j}} | ||
545 | * (3) The encrypted pre-shares Y_{i,j} | ||
546 | * (4) The zero knowledge proof for correctness of | ||
547 | * the encryption | ||
548 | * | ||
549 | * @param ks session to use | ||
550 | */ | ||
468 | static void | 551 | static void |
469 | insert_round2_element (struct KeygenSession *ks) | 552 | insert_round2_element (struct KeygenSession *ks) |
470 | { | 553 | { |
471 | struct GNUNET_SET_Element *element; | 554 | struct GNUNET_SET_Element *element; |
555 | struct GNUNET_SECRETSHARING_KeygenRevealData *msg; | ||
556 | unsigned char *pos; | ||
557 | unsigned char *last_pos; | ||
558 | size_t element_size; | ||
472 | unsigned int i; | 559 | unsigned int i; |
473 | uint16_t big_y_size; | ||
474 | gcry_mpi_t c; | 560 | gcry_mpi_t c; |
475 | gcry_mpi_t idx; | 561 | gcry_mpi_t idx; |
476 | gcry_mpi_t preshare; | 562 | gcry_mpi_t v; |
477 | 563 | ||
478 | GNUNET_assert (0 != (c = gcry_mpi_new (PAILLIER_BITS))); | 564 | GNUNET_assert (0 != (c = gcry_mpi_new (PAILLIER_BITS))); |
479 | GNUNET_assert (0 != (preshare = gcry_mpi_new (PAILLIER_BITS))); | 565 | GNUNET_assert (0 != (v = gcry_mpi_new (PAILLIER_BITS))); |
480 | GNUNET_assert (0 != (idx = gcry_mpi_new (PAILLIER_BITS))); | 566 | GNUNET_assert (0 != (idx = gcry_mpi_new (PAILLIER_BITS))); |
481 | 567 | ||
482 | big_y_size = PAILLIER_BITS / 8 * ks->num_peers; | 568 | element_size = (sizeof (struct GNUNET_SECRETSHARING_KeygenRevealData) + |
569 | 2 * PAILLIER_BITS / 8 * ks->num_peers + | ||
570 | 1 * PAILLIER_BITS / 8 * ks->threshold); | ||
571 | |||
572 | element = GNUNET_malloc (sizeof (struct GNUNET_SET_Element) + element_size); | ||
483 | 573 | ||
484 | element = GNUNET_malloc (sizeof (struct GNUNET_SET_Element) + big_y_size); | 574 | msg = (void *) element->data; |
575 | pos = (void *) &msg[1]; | ||
576 | last_pos = pos + element_size; | ||
485 | 577 | ||
578 | // exponentiated pre-shares | ||
579 | for (i = 0; i <= ks->threshold; i++) | ||
580 | { | ||
581 | ptrdiff_t remaining = last_pos - pos; | ||
582 | GNUNET_assert (remaining > 0); | ||
583 | gcry_mpi_set_ui (idx, i); | ||
584 | // evaluate the polynomial | ||
585 | horner_eval (v, ks->presecret_polynomial, ks->threshold, idx, elgamal_p); | ||
586 | // take g to the result | ||
587 | gcry_mpi_powm (v, elgamal_g, v, elgamal_p); | ||
588 | gcry_mpi_print (GCRYMPI_FMT_USG, pos, (size_t) remaining, NULL, v); | ||
589 | pos += PAILLIER_BITS / 8; | ||
590 | } | ||
591 | |||
592 | // exponentiated coefficients | ||
486 | for (i = 0; i < ks->num_peers; i++) | 593 | for (i = 0; i < ks->num_peers; i++) |
487 | { | 594 | { |
488 | gcry_mpi_set_ui (idx, i + 1); | 595 | ptrdiff_t remaining = last_pos - pos; |
489 | horner_eval (preshare, ks->presecret_polynomial, ks->threshold, idx, elgamal_p); | 596 | GNUNET_assert (remaining > 0); |
490 | // concat 'A', 'y' and 'Y' to the vector | 597 | gcry_mpi_powm (v, elgamal_g, ks->presecret_polynomial[0], elgamal_p); |
598 | gcry_mpi_print (GCRYMPI_FMT_USG, pos, (size_t) remaining, NULL, v); | ||
599 | pos += PAILLIER_BITS / 8; | ||
491 | } | 600 | } |
492 | 601 | ||
602 | // encrypted pre-shares | ||
493 | for (i = 0; i < ks->threshold; i++) | 603 | for (i = 0; i < ks->threshold; i++) |
494 | { | 604 | { |
495 | // concat 'a' to the vector | 605 | ptrdiff_t remaining = last_pos - pos; |
606 | GNUNET_assert (remaining > 0); | ||
607 | if (GNUNET_YES == ks->info[i].disqualified) | ||
608 | gcry_mpi_set_ui (v, 0); | ||
609 | else | ||
610 | paillier_encrypt (v, ks->presecret_polynomial[0], | ||
611 | ks->info[i].paillier_g, ks->info[i].paillier_g); | ||
612 | gcry_mpi_print (GCRYMPI_FMT_USG, pos, (size_t) remaining, NULL, v); | ||
613 | pos += PAILLIER_BITS / 8; | ||
496 | } | 614 | } |
497 | 615 | ||
498 | GNUNET_CONSENSUS_insert (ks->consensus, element, NULL, NULL); | 616 | GNUNET_CONSENSUS_insert (ks->consensus, element, NULL, NULL); |
@@ -500,15 +618,75 @@ insert_round2_element (struct KeygenSession *ks) | |||
500 | } | 618 | } |
501 | 619 | ||
502 | 620 | ||
621 | static struct KeygenPeerInfo * | ||
622 | get_keygen_peer_info (const struct KeygenSession *ks, | ||
623 | struct GNUNET_PeerIdentity *peer) | ||
624 | { | ||
625 | unsigned int i; | ||
626 | for (i = 0; i < ks->num_peers; i++) | ||
627 | if (0 == memcmp (peer, &ks->info[i].peer, sizeof (struct GNUNET_PeerIdentity))) | ||
628 | return &ks->info[i]; | ||
629 | return NULL; | ||
630 | } | ||
631 | |||
632 | |||
633 | static void | ||
634 | keygen_round2_new_element (void *cls, | ||
635 | const struct GNUNET_SET_Element *element) | ||
636 | { | ||
637 | struct KeygenSession *ks = cls; | ||
638 | struct GNUNET_SECRETSHARING_KeygenRevealData *msg; | ||
639 | struct KeygenPeerInfo *info; | ||
640 | unsigned char *pos; | ||
641 | unsigned char *last_pos; | ||
642 | gcry_mpi_t c; | ||
643 | |||
644 | msg = (void *) element->data; | ||
645 | pos = (void *) &msg[1]; | ||
646 | // skip exp. pre-shares | ||
647 | pos += PAILLIER_BITS / 8 * ks->num_peers; | ||
648 | // skip exp. coefficients | ||
649 | pos += PAILLIER_BITS / 8 * ks->threshold; | ||
650 | // skip to the value for our peer | ||
651 | pos += PAILLIER_BITS / 8 * ks->local_peer_idx; | ||
652 | |||
653 | last_pos = element->size + (unsigned char *) element->data; | ||
654 | |||
655 | if ((pos >= last_pos) || ((last_pos - pos) < (PAILLIER_BITS / 8))) | ||
656 | { | ||
657 | GNUNET_break_op (0); | ||
658 | return; | ||
659 | } | ||
660 | |||
661 | GNUNET_assert (0 == gcry_mpi_scan (&c, GCRYMPI_FMT_USG, | ||
662 | pos, PAILLIER_BITS / 8, NULL)); | ||
663 | |||
664 | info = get_keygen_peer_info (ks, &msg->peer); | ||
665 | |||
666 | if (NULL == info) | ||
667 | { | ||
668 | GNUNET_break_op (0); | ||
669 | return; | ||
670 | } | ||
671 | |||
672 | paillier_decrypt (info->decrypted_preshare, c, ks->paillier_lambda, ks->paillier_mu, | ||
673 | ks->info[ks->local_peer_idx].paillier_n); | ||
674 | |||
675 | // TODO: validate signature and proofs | ||
676 | |||
677 | } | ||
678 | |||
679 | |||
503 | static void | 680 | static void |
504 | keygen_round1_conclude (void *cls) | 681 | keygen_round1_conclude (void *cls) |
505 | { | 682 | { |
506 | struct KeygenSession *ks = cls; | 683 | struct KeygenSession *ks = cls; |
507 | 684 | ||
508 | // TODO: destroy old consensus | 685 | // TODO: destroy old consensus |
686 | // TODO: mark peers without keys as disqualified | ||
509 | 687 | ||
510 | ks->consensus = GNUNET_CONSENSUS_create (cfg, ks->num_peers, ks->peers, &ks->session_id, | 688 | ks->consensus = GNUNET_CONSENSUS_create (cfg, ks->num_peers, ks->peers, &ks->session_id, |
511 | keygen_round1_new_element, ks); | 689 | keygen_round2_new_element, ks); |
512 | 690 | ||
513 | insert_round2_element (ks); | 691 | insert_round2_element (ks); |
514 | 692 | ||
@@ -516,12 +694,20 @@ keygen_round1_conclude (void *cls) | |||
516 | } | 694 | } |
517 | 695 | ||
518 | 696 | ||
697 | /** | ||
698 | * Insert the ephemeral key and the presecret commitment | ||
699 | * of this peer in the consensus of the given session. | ||
700 | * | ||
701 | * @param ks session to use | ||
702 | */ | ||
519 | static void | 703 | static void |
520 | insert_round1_element (struct KeygenSession *ks) | 704 | insert_round1_element (struct KeygenSession *ks) |
521 | { | 705 | { |
522 | struct GNUNET_SET_Element *element; | 706 | struct GNUNET_SET_Element *element; |
523 | struct GNUNET_SECRETSHARING_KeygenCommitData *d; | 707 | struct GNUNET_SECRETSHARING_KeygenCommitData *d; |
708 | // g^a_{i,0} | ||
524 | gcry_mpi_t v; | 709 | gcry_mpi_t v; |
710 | // big-endian representation of 'v' | ||
525 | unsigned char v_data[PAILLIER_BITS / 8]; | 711 | unsigned char v_data[PAILLIER_BITS / 8]; |
526 | 712 | ||
527 | element = GNUNET_malloc (sizeof *element + sizeof *d); | 713 | element = GNUNET_malloc (sizeof *element + sizeof *d); |
@@ -541,11 +727,11 @@ insert_round1_element (struct KeygenSession *ks) | |||
541 | 727 | ||
542 | GNUNET_assert (0 == gcry_mpi_print (GCRYMPI_FMT_USG, | 728 | GNUNET_assert (0 == gcry_mpi_print (GCRYMPI_FMT_USG, |
543 | (unsigned char *) d->pubkey.g, PAILLIER_BITS / 8, NULL, | 729 | (unsigned char *) d->pubkey.g, PAILLIER_BITS / 8, NULL, |
544 | ks->paillier_g)); | 730 | ks->info[ks->local_peer_idx].paillier_g)); |
545 | 731 | ||
546 | GNUNET_assert (0 == gcry_mpi_print (GCRYMPI_FMT_USG, | 732 | GNUNET_assert (0 == gcry_mpi_print (GCRYMPI_FMT_USG, |
547 | (unsigned char *) d->pubkey.mu, PAILLIER_BITS / 8, NULL, | 733 | (unsigned char *) d->pubkey.n, PAILLIER_BITS / 8, NULL, |
548 | ks->paillier_mu)); | 734 | ks->info[ks->local_peer_idx].paillier_n)); |
549 | 735 | ||
550 | // FIXME: sign stuff | 736 | // FIXME: sign stuff |
551 | 737 | ||
@@ -572,6 +758,8 @@ static void handle_client_keygen (void *cls, | |||
572 | (const struct GNUNET_SECRETSHARING_CreateMessage *) message; | 758 | (const struct GNUNET_SECRETSHARING_CreateMessage *) message; |
573 | struct KeygenSession *ks; | 759 | struct KeygenSession *ks; |
574 | 760 | ||
761 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, "client requested key generation\n"); | ||
762 | |||
575 | ks = GNUNET_new (struct KeygenSession); | 763 | ks = GNUNET_new (struct KeygenSession); |
576 | 764 | ||
577 | GNUNET_CONTAINER_DLL_insert (keygen_sessions_head, keygen_sessions_tail, ks); | 765 | GNUNET_CONTAINER_DLL_insert (keygen_sessions_head, keygen_sessions_tail, ks); |
@@ -583,9 +771,17 @@ static void handle_client_keygen (void *cls, | |||
583 | ks->peers = normalize_peers ((struct GNUNET_PeerIdentity *) &msg[1], ks->num_peers, | 771 | ks->peers = normalize_peers ((struct GNUNET_PeerIdentity *) &msg[1], ks->num_peers, |
584 | &ks->num_peers, &ks->local_peer_idx); | 772 | &ks->num_peers, &ks->local_peer_idx); |
585 | 773 | ||
774 | // TODO: initialize MPIs in peer structure | ||
775 | |||
586 | ks->consensus = GNUNET_CONSENSUS_create (cfg, ks->num_peers, ks->peers, &msg->session_id, | 776 | ks->consensus = GNUNET_CONSENSUS_create (cfg, ks->num_peers, ks->peers, &msg->session_id, |
587 | keygen_round1_new_element, ks); | 777 | keygen_round1_new_element, ks); |
588 | 778 | ||
779 | paillier_create (ks->info[ks->local_peer_idx].paillier_g, | ||
780 | ks->info[ks->local_peer_idx].paillier_n, | ||
781 | ks->paillier_lambda, | ||
782 | ks->paillier_mu); | ||
783 | |||
784 | |||
589 | generate_presecret_polynomial (ks); | 785 | generate_presecret_polynomial (ks); |
590 | 786 | ||
591 | insert_round1_element (ks); | 787 | insert_round1_element (ks); |
diff --git a/src/secretsharing/secretsharing.h b/src/secretsharing/secretsharing.h index 7025fdfea..8bd1b05b5 100644 --- a/src/secretsharing/secretsharing.h +++ b/src/secretsharing/secretsharing.h | |||
@@ -67,10 +67,10 @@ struct GNUNET_SECRETSHARING_CreateMessage | |||
67 | }; | 67 | }; |
68 | 68 | ||
69 | 69 | ||
70 | struct GNUNET_SECRETSHARING_SecretEstablishedMessage | 70 | struct GNUNET_SECRETSHARING_SecretReadyMessage |
71 | { | 71 | { |
72 | /** | 72 | /** |
73 | * Type: GNUNET_MESSAGE_TYPE_SECRETSHARING_CLIENT_ESTABLISHED | 73 | * Type: GNUNET_MESSAGE_TYPE_SECRETSHARING_CLIENT_SECRET_READY |
74 | */ | 74 | */ |
75 | struct GNUNET_MessageHeader header; | 75 | struct GNUNET_MessageHeader header; |
76 | 76 | ||
@@ -80,6 +80,11 @@ struct GNUNET_SECRETSHARING_SecretEstablishedMessage | |||
80 | unsigned char secret[GNUNET_SECRETSHARING_KEY_BITS / 8]; | 80 | unsigned char secret[GNUNET_SECRETSHARING_KEY_BITS / 8]; |
81 | 81 | ||
82 | /** | 82 | /** |
83 | * Secret share in network byte order. | ||
84 | */ | ||
85 | struct GNUNET_SECRETSHARING_PublicKey public_key; | ||
86 | |||
87 | /** | ||
83 | * Number of peers at the end of this message. | 88 | * Number of peers at the end of this message. |
84 | * Includes peers that are part of the established | 89 | * Includes peers that are part of the established |
85 | * threshold crypto system. | 90 | * threshold crypto system. |
@@ -90,10 +95,10 @@ struct GNUNET_SECRETSHARING_SecretEstablishedMessage | |||
90 | }; | 95 | }; |
91 | 96 | ||
92 | 97 | ||
93 | struct GNUNET_SECRETSHARING_DecryptMessage | 98 | struct GNUNET_SECRETSHARING_DecryptRequestMessage |
94 | { | 99 | { |
95 | /** | 100 | /** |
96 | * Type: GNUNET_MESSAGE_TYPE_SECRETSHARING_CLIENT_DECRYPT | 101 | * Type: GNUNET_MESSAGE_TYPE_SECRETSHARING_CLIENT_DECRYPT_REQUEST |
97 | */ | 102 | */ |
98 | struct GNUNET_MessageHeader header; | 103 | struct GNUNET_MessageHeader header; |
99 | 104 | ||
@@ -113,10 +118,10 @@ struct GNUNET_SECRETSHARING_DecryptMessage | |||
113 | }; | 118 | }; |
114 | 119 | ||
115 | 120 | ||
116 | struct GNUNET_SECRETSHARING_DecryptDoneMessage | 121 | struct GNUNET_SECRETSHARING_DecryptResponseMessage |
117 | { | 122 | { |
118 | /** | 123 | /** |
119 | * Type: GNUNET_MESSAGE_TYPE_SECRETSHARING_CLIENT_DECRYPT_DONE | 124 | * Type: GNUNET_MESSAGE_TYPE_SECRETSHARING_CLIENT_DECRYPT_RESPONSE |
120 | */ | 125 | */ |
121 | struct GNUNET_MessageHeader header; | 126 | struct GNUNET_MessageHeader header; |
122 | 127 | ||
diff --git a/src/secretsharing/secretsharing_api.c b/src/secretsharing/secretsharing_api.c index 325e07f51..a44fa2a2f 100644 --- a/src/secretsharing/secretsharing_api.c +++ b/src/secretsharing/secretsharing_api.c | |||
@@ -25,8 +25,102 @@ | |||
25 | */ | 25 | */ |
26 | #include "platform.h" | 26 | #include "platform.h" |
27 | #include "gnunet_util_lib.h" | 27 | #include "gnunet_util_lib.h" |
28 | #include "gnunet_secretsharing_service.h" | ||
29 | #include "secretsharing.h" | ||
28 | 30 | ||
29 | 31 | ||
30 | #define LOG(kind,...) GNUNET_log_from (kind, "secretsharing-api",__VA_ARGS__) | 32 | #define LOG(kind,...) GNUNET_log_from (kind, "secretsharing-api",__VA_ARGS__) |
31 | 33 | ||
32 | 34 | ||
35 | |||
36 | /** | ||
37 | * Session that will eventually establish a shared secred between | ||
38 | * the involved peers and allow encryption and cooperative decryption. | ||
39 | */ | ||
40 | struct GNUNET_SECRETSHARING_Session | ||
41 | { | ||
42 | /** | ||
43 | * Client connected to the secretsharing service. | ||
44 | */ | ||
45 | struct GNUNET_CLIENT_Connection *client; | ||
46 | |||
47 | /** | ||
48 | * Message queue for 'client'. | ||
49 | */ | ||
50 | struct GNUNET_MQ_Handle *mq; | ||
51 | |||
52 | /** | ||
53 | * Called when the secret sharing is done. | ||
54 | */ | ||
55 | GNUNET_SECRETSHARING_SecretReadyCallback secret_ready_cb; | ||
56 | |||
57 | /** | ||
58 | * Closure for 'secret_ready_cb'. | ||
59 | */ | ||
60 | void *secret_ready_cls; | ||
61 | }; | ||
62 | |||
63 | |||
64 | static void | ||
65 | handle_session_client_error (void *cls, enum GNUNET_MQ_Error error) | ||
66 | { | ||
67 | struct GNUNET_SECRETSHARING_Session *s = cls; | ||
68 | |||
69 | s->secret_ready_cb (s->secret_ready_cls, NULL, NULL, 0, NULL); | ||
70 | } | ||
71 | |||
72 | static void | ||
73 | handle_secret_ready (void *cls, const struct GNUNET_MessageHeader *msg) | ||
74 | { | ||
75 | struct GNUNET_SECRETSHARING_Session *s = cls; | ||
76 | const struct GNUNET_SECRETSHARING_SecretReadyMessage *m = (const void *) msg; | ||
77 | |||
78 | s->secret_ready_cb (s->secret_ready_cls, | ||
79 | NULL, | ||
80 | &m->public_key, | ||
81 | ntohs (m->num_secret_peers), | ||
82 | (struct GNUNET_PeerIdentity *) &m[1]); | ||
83 | |||
84 | } | ||
85 | |||
86 | |||
87 | struct GNUNET_SECRETSHARING_Session * | ||
88 | GNUNET_SECRETSHARING_create_session (const struct GNUNET_CONFIGURATION_Handle *cfg, | ||
89 | unsigned int num_peers, | ||
90 | const struct GNUNET_PeerIdentity *peers, | ||
91 | const struct GNUNET_HashCode *session_id, | ||
92 | struct GNUNET_TIME_Absolute deadline, | ||
93 | unsigned int threshold, | ||
94 | GNUNET_SECRETSHARING_SecretReadyCallback cb, | ||
95 | void *cls) | ||
96 | { | ||
97 | struct GNUNET_SECRETSHARING_Session *s; | ||
98 | struct GNUNET_MQ_Envelope *ev; | ||
99 | struct GNUNET_SECRETSHARING_CreateMessage *msg; | ||
100 | static const struct GNUNET_MQ_MessageHandler mq_handlers[] = { | ||
101 | {handle_secret_ready, GNUNET_MESSAGE_TYPE_SECRETSHARING_CLIENT_SECRET_READY, 0}, | ||
102 | GNUNET_MQ_HANDLERS_END | ||
103 | }; | ||
104 | |||
105 | |||
106 | s = GNUNET_new (struct GNUNET_SECRETSHARING_Session); | ||
107 | s->client = GNUNET_CLIENT_connect ("secretsharing", cfg); | ||
108 | s->secret_ready_cb = cb; | ||
109 | s->secret_ready_cls = cls; | ||
110 | GNUNET_assert (NULL != s->client); | ||
111 | |||
112 | s->mq = GNUNET_MQ_queue_for_connection_client (s->client, mq_handlers, | ||
113 | handle_session_client_error, s); | ||
114 | GNUNET_assert (NULL != s->mq); | ||
115 | |||
116 | ev = GNUNET_MQ_msg (msg, GNUNET_MESSAGE_TYPE_SECRETSHARING_CLIENT_GENERATE); | ||
117 | msg->threshold = htons (threshold); | ||
118 | GNUNET_MQ_send (s->mq, ev); | ||
119 | |||
120 | LOG (GNUNET_ERROR_TYPE_DEBUG, "secretsharing session created\n"); | ||
121 | return s; | ||
122 | |||
123 | } | ||
124 | |||
125 | |||
126 | |||
diff --git a/src/secretsharing/secretsharing_protocol.h b/src/secretsharing/secretsharing_protocol.h index 71e6d50a9..470002f10 100644 --- a/src/secretsharing/secretsharing_protocol.h +++ b/src/secretsharing/secretsharing_protocol.h | |||
@@ -60,9 +60,9 @@ struct PaillierPublicKey | |||
60 | 60 | ||
61 | /** | 61 | /** |
62 | * Network order representation of the | 62 | * Network order representation of the |
63 | * g-component. | 63 | * n-component. |
64 | */ | 64 | */ |
65 | uint32_t mu[PAILLIER_BITS / 8 / sizeof (uint32_t)]; | 65 | uint32_t n[PAILLIER_BITS / 8 / sizeof (uint32_t)]; |
66 | }; | 66 | }; |
67 | 67 | ||
68 | 68 | ||
@@ -72,6 +72,10 @@ struct PaillierPublicKey | |||
72 | struct GNUNET_SECRETSHARING_KeygenCommitData | 72 | struct GNUNET_SECRETSHARING_KeygenCommitData |
73 | { | 73 | { |
74 | /** | 74 | /** |
75 | * Signature over the rest of the message. | ||
76 | */ | ||
77 | struct GNUNET_CRYPTO_EddsaSignature signature; | ||
78 | /** | ||
75 | * Signature purpose for signing the keygen commit data. | 79 | * Signature purpose for signing the keygen commit data. |
76 | */ | 80 | */ |
77 | struct GNUNET_CRYPTO_EccSignaturePurpose purpose; | 81 | struct GNUNET_CRYPTO_EccSignaturePurpose purpose; |
@@ -88,10 +92,25 @@ struct GNUNET_SECRETSHARING_KeygenCommitData | |||
88 | * Commitment of 'peer' to his presecret. | 92 | * Commitment of 'peer' to his presecret. |
89 | */ | 93 | */ |
90 | struct GNUNET_HashCode commitment GNUNET_PACKED; | 94 | struct GNUNET_HashCode commitment GNUNET_PACKED; |
95 | }; | ||
96 | |||
97 | |||
98 | struct GNUNET_SECRETSHARING_KeygenRevealData | ||
99 | { | ||
91 | /** | 100 | /** |
92 | * Signature over the previous values. | 101 | * Signature over rest of the message. |
93 | */ | 102 | */ |
94 | struct GNUNET_CRYPTO_EddsaSignature signature; | 103 | struct GNUNET_CRYPTO_EddsaSignature signature; |
104 | /* | ||
105 | * Signature purpose for signing the keygen commit data. | ||
106 | */ | ||
107 | struct GNUNET_CRYPTO_EccSignaturePurpose purpose; | ||
108 | /** | ||
109 | * Peer that inserts this element. | ||
110 | */ | ||
111 | struct GNUNET_PeerIdentity peer; | ||
112 | |||
113 | /* values follow */ | ||
95 | }; | 114 | }; |
96 | 115 | ||
97 | GNUNET_NETWORK_STRUCT_END | 116 | GNUNET_NETWORK_STRUCT_END |
diff --git a/src/util/gnunet-ecc.c b/src/util/gnunet-ecc.c index d4e0f2387..4af9f084d 100644 --- a/src/util/gnunet-ecc.c +++ b/src/util/gnunet-ecc.c | |||
@@ -113,6 +113,19 @@ create_keys (const char *fn) | |||
113 | 113 | ||
114 | 114 | ||
115 | static void | 115 | static void |
116 | print_hex (char *msg, void *buf, size_t size) | ||
117 | { | ||
118 | size_t i; | ||
119 | printf ("%s: ", msg); | ||
120 | for (i = 0; i < size; i++) | ||
121 | { | ||
122 | printf ("%02hhx", ((char *)buf)[i]); | ||
123 | } | ||
124 | printf ("\n"); | ||
125 | } | ||
126 | |||
127 | |||
128 | static void | ||
116 | print_examples_ecdh () | 129 | print_examples_ecdh () |
117 | { | 130 | { |
118 | struct GNUNET_CRYPTO_EcdhePrivateKey *dh_priv1; | 131 | struct GNUNET_CRYPTO_EcdhePrivateKey *dh_priv1; |
@@ -132,14 +145,18 @@ print_examples_ecdh () | |||
132 | GNUNET_assert (NULL != GNUNET_STRINGS_data_to_string (dh_priv1, 32, buf, 128)); | 145 | GNUNET_assert (NULL != GNUNET_STRINGS_data_to_string (dh_priv1, 32, buf, 128)); |
133 | printf ("ECDHE key 1:\n"); | 146 | printf ("ECDHE key 1:\n"); |
134 | printf ("private: %s\n", buf); | 147 | printf ("private: %s\n", buf); |
148 | print_hex ("private(hex)", dh_priv1, sizeof *dh_priv1); | ||
135 | GNUNET_assert (NULL != GNUNET_STRINGS_data_to_string (dh_pub1, 32, buf, 128)); | 149 | GNUNET_assert (NULL != GNUNET_STRINGS_data_to_string (dh_pub1, 32, buf, 128)); |
136 | printf ("public: %s\n", buf); | 150 | printf ("public: %s\n", buf); |
151 | print_hex ("public(hex)", dh_pub1, sizeof *dh_pub1); | ||
137 | 152 | ||
138 | GNUNET_assert (NULL != GNUNET_STRINGS_data_to_string (dh_priv2, 32, buf, 128)); | 153 | GNUNET_assert (NULL != GNUNET_STRINGS_data_to_string (dh_priv2, 32, buf, 128)); |
139 | printf ("ECDHE key 2:\n"); | 154 | printf ("ECDHE key 2:\n"); |
140 | printf ("private: %s\n", buf); | 155 | printf ("private: %s\n", buf); |
156 | print_hex ("private(hex)", dh_priv2, sizeof *dh_priv2); | ||
141 | GNUNET_assert (NULL != GNUNET_STRINGS_data_to_string (dh_pub2, 32, buf, 128)); | 157 | GNUNET_assert (NULL != GNUNET_STRINGS_data_to_string (dh_pub2, 32, buf, 128)); |
142 | printf ("public: %s\n", buf); | 158 | printf ("public: %s\n", buf); |
159 | print_hex ("public(hex)", dh_pub2, sizeof *dh_pub2); | ||
143 | 160 | ||
144 | GNUNET_assert (GNUNET_OK == GNUNET_CRYPTO_ecc_ecdh (dh_priv1, dh_pub2, &hash)); | 161 | GNUNET_assert (GNUNET_OK == GNUNET_CRYPTO_ecc_ecdh (dh_priv1, dh_pub2, &hash)); |
145 | GNUNET_assert (NULL != GNUNET_STRINGS_data_to_string (&hash, 64, buf, 128)); | 162 | GNUNET_assert (NULL != GNUNET_STRINGS_data_to_string (&hash, 64, buf, 128)); |