diff options
Diffstat (limited to 'src/secretsharing')
-rw-r--r-- | src/secretsharing/.gitignore | 3 | ||||
-rw-r--r-- | src/secretsharing/Makefile.am | 73 | ||||
-rw-r--r-- | src/secretsharing/gnunet-secretsharing-profiler.c | 662 | ||||
-rw-r--r-- | src/secretsharing/gnunet-service-secretsharing.c | 2415 | ||||
-rw-r--r-- | src/secretsharing/secretsharing.conf.in | 20 | ||||
-rw-r--r-- | src/secretsharing/secretsharing.h | 227 | ||||
-rw-r--r-- | src/secretsharing/secretsharing_api.c | 518 | ||||
-rw-r--r-- | src/secretsharing/secretsharing_common.c | 158 | ||||
-rw-r--r-- | src/secretsharing/secretsharing_protocol.h | 147 | ||||
-rw-r--r-- | src/secretsharing/test_secretsharing.conf | 40 | ||||
-rw-r--r-- | src/secretsharing/test_secretsharing_api.c | 102 |
11 files changed, 0 insertions, 4365 deletions
diff --git a/src/secretsharing/.gitignore b/src/secretsharing/.gitignore deleted file mode 100644 index fe9db53a4..000000000 --- a/src/secretsharing/.gitignore +++ /dev/null | |||
@@ -1,3 +0,0 @@ | |||
1 | gnunet-service-secretsharing | ||
2 | gnunet-secretsharing-profiler | ||
3 | test_secretsharing_api | ||
diff --git a/src/secretsharing/Makefile.am b/src/secretsharing/Makefile.am deleted file mode 100644 index 13dd0bd8d..000000000 --- a/src/secretsharing/Makefile.am +++ /dev/null | |||
@@ -1,73 +0,0 @@ | |||
1 | # This Makefile.am is in the public domain | ||
2 | AM_CPPFLAGS = -I$(top_srcdir)/src/include | ||
3 | |||
4 | pkgcfgdir= $(pkgdatadir)/config.d/ | ||
5 | |||
6 | libexecdir= $(pkglibdir)/libexec/ | ||
7 | |||
8 | pkgcfg_DATA = \ | ||
9 | secretsharing.conf | ||
10 | |||
11 | if USE_COVERAGE | ||
12 | AM_CFLAGS = -fprofile-arcs -ftest-coverage | ||
13 | endif | ||
14 | |||
15 | |||
16 | libexec_PROGRAMS = \ | ||
17 | gnunet-service-secretsharing | ||
18 | |||
19 | lib_LTLIBRARIES = \ | ||
20 | libgnunetsecretsharing.la | ||
21 | |||
22 | |||
23 | gnunet_secretsharing_profiler_SOURCES = \ | ||
24 | gnunet-secretsharing-profiler.c | ||
25 | gnunet_secretsharing_profiler_LDADD = \ | ||
26 | libgnunetsecretsharing.la \ | ||
27 | $(top_builddir)/src/testing/libgnunettesting.la \ | ||
28 | $(top_builddir)/src/testbed/libgnunettestbed.la \ | ||
29 | $(top_builddir)/src/util/libgnunetutil.la \ | ||
30 | $(GN_LIBINTL) | ||
31 | |||
32 | gnunet_service_secretsharing_SOURCES = \ | ||
33 | gnunet-service-secretsharing.c \ | ||
34 | secretsharing_common.c \ | ||
35 | secretsharing_protocol.h | ||
36 | gnunet_service_secretsharing_CFLAGS = $(AM_CFLAGS) | ||
37 | gnunet_service_secretsharing_LDADD = \ | ||
38 | $(top_builddir)/src/util/libgnunetutil.la \ | ||
39 | $(top_builddir)/src/consensus/libgnunetconsensus.la \ | ||
40 | $(LIBGCRYPT_LIBS) \ | ||
41 | $(GN_LIBINTL) | ||
42 | |||
43 | libgnunetsecretsharing_la_SOURCES = \ | ||
44 | secretsharing_api.c \ | ||
45 | secretsharing_common.c \ | ||
46 | secretsharing.h | ||
47 | libgnunetsecretsharing_la_LIBADD = \ | ||
48 | $(top_builddir)/src/util/libgnunetutil.la \ | ||
49 | $(LIBGCRYPT_LIBS) \ | ||
50 | $(LTLIBINTL) | ||
51 | libgnunetsecretsharing_la_LDFLAGS = \ | ||
52 | $(GN_LIB_LDFLAGS) | ||
53 | |||
54 | bin_PROGRAMS = \ | ||
55 | gnunet-secretsharing-profiler | ||
56 | |||
57 | check_PROGRAMS = \ | ||
58 | test_secretsharing_api | ||
59 | |||
60 | if ENABLE_TEST_RUN | ||
61 | AM_TESTS_ENVIRONMENT=export GNUNET_PREFIX=$${GNUNET_PREFIX:-@libdir@};export PATH=$${GNUNET_PREFIX:-@prefix@}/bin:$$PATH;unset XDG_DATA_HOME;unset XDG_CONFIG_HOME; | ||
62 | TESTS = $(check_PROGRAMS) | ||
63 | endif | ||
64 | |||
65 | test_secretsharing_api_SOURCES = \ | ||
66 | test_secretsharing_api.c | ||
67 | test_secretsharing_api_LDADD = \ | ||
68 | libgnunetsecretsharing.la \ | ||
69 | $(top_builddir)/src/testing/libgnunettesting.la \ | ||
70 | $(top_builddir)/src/util/libgnunetutil.la | ||
71 | |||
72 | EXTRA_DIST = \ | ||
73 | test_secretsharing.conf | ||
diff --git a/src/secretsharing/gnunet-secretsharing-profiler.c b/src/secretsharing/gnunet-secretsharing-profiler.c deleted file mode 100644 index 76bba0bc9..000000000 --- a/src/secretsharing/gnunet-secretsharing-profiler.c +++ /dev/null | |||
@@ -1,662 +0,0 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet | ||
3 | Copyright (C) 2014 GNUnet e.V. | ||
4 | |||
5 | GNUnet is free software: you can redistribute it and/or modify it | ||
6 | under the terms of the GNU Affero General Public License as published | ||
7 | by the Free Software Foundation, either version 3 of the License, | ||
8 | or (at your option) any later version. | ||
9 | |||
10 | GNUnet is distributed in the hope that it will be useful, but | ||
11 | WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
13 | Affero General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU Affero General Public License | ||
16 | along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
17 | |||
18 | SPDX-License-Identifier: AGPL3.0-or-later | ||
19 | */ | ||
20 | |||
21 | /** | ||
22 | * @file secretsharing/gnunet-secretsharing-profiler.c | ||
23 | * @brief profiling tool for distributed key generation and decryption | ||
24 | * @author Florian Dold | ||
25 | */ | ||
26 | #include "platform.h" | ||
27 | #include "gnunet_util_lib.h" | ||
28 | #include "gnunet_secretsharing_service.h" | ||
29 | #include "gnunet_testbed_service.h" | ||
30 | |||
31 | /** | ||
32 | * How many peers should participate in the key generation? | ||
33 | */ | ||
34 | static unsigned int num_peers = 3; | ||
35 | |||
36 | /** | ||
37 | * What should the threshold for then key be? | ||
38 | */ | ||
39 | static unsigned int threshold = 2; | ||
40 | |||
41 | /** | ||
42 | * Should we try to decrypt a value after the key generation? | ||
43 | */ | ||
44 | static int decrypt = GNUNET_NO; | ||
45 | |||
46 | /** | ||
47 | * When would we like to see the operation finished? | ||
48 | */ | ||
49 | static struct GNUNET_TIME_Relative timeout; | ||
50 | |||
51 | /** | ||
52 | * When should dkg communication start? | ||
53 | */ | ||
54 | static struct GNUNET_TIME_Relative delay; | ||
55 | |||
56 | /** | ||
57 | * Handles for secretsharing sessions. | ||
58 | */ | ||
59 | static struct GNUNET_SECRETSHARING_Session **session_handles; | ||
60 | |||
61 | static struct GNUNET_SECRETSHARING_DecryptionHandle **decrypt_handles; | ||
62 | |||
63 | /** | ||
64 | * Shares we got from the distributed key generation. | ||
65 | */ | ||
66 | static struct GNUNET_SECRETSHARING_Share **shares; | ||
67 | |||
68 | static struct GNUNET_SECRETSHARING_PublicKey common_pubkey; | ||
69 | |||
70 | |||
71 | static unsigned int num_connected_sessions; | ||
72 | |||
73 | static unsigned int num_connected_decrypt; | ||
74 | |||
75 | /** | ||
76 | * Handles to the running peers. | ||
77 | * When peers[i] is NULL, the i-th peer has stopped. | ||
78 | */ | ||
79 | static struct GNUNET_TESTBED_Peer **peers; | ||
80 | |||
81 | static struct GNUNET_PeerIdentity *peer_ids; | ||
82 | |||
83 | static unsigned int num_retrieved_peer_ids; | ||
84 | |||
85 | static unsigned int num_generated; | ||
86 | |||
87 | static unsigned int num_decrypted; | ||
88 | |||
89 | static struct GNUNET_HashCode session_id; | ||
90 | |||
91 | static unsigned int verbose; | ||
92 | |||
93 | static struct GNUNET_SECRETSHARING_Plaintext reference_plaintext; | ||
94 | |||
95 | static struct GNUNET_SECRETSHARING_Ciphertext ciphertext; | ||
96 | |||
97 | static struct GNUNET_TIME_Absolute dkg_start; | ||
98 | |||
99 | static struct GNUNET_TIME_Absolute dkg_deadline; | ||
100 | |||
101 | |||
102 | static struct GNUNET_TIME_Absolute decrypt_start; | ||
103 | |||
104 | static struct GNUNET_TIME_Absolute decrypt_deadline; | ||
105 | |||
106 | /** | ||
107 | * Connect operations, one for every peer. | ||
108 | */ | ||
109 | static struct GNUNET_TESTBED_Operation **connect_ops; | ||
110 | |||
111 | /** | ||
112 | * Are we performing a shutdown right now? | ||
113 | */ | ||
114 | static int in_shutdown; | ||
115 | |||
116 | |||
117 | /** | ||
118 | * Signature of the event handler function called by the | ||
119 | * respective event controller. | ||
120 | * | ||
121 | * @param cls closure | ||
122 | * @param event information about the event | ||
123 | */ | ||
124 | static void | ||
125 | controller_cb (void *cls, | ||
126 | const struct GNUNET_TESTBED_EventInformation *event) | ||
127 | { | ||
128 | GNUNET_assert (0); | ||
129 | } | ||
130 | |||
131 | |||
132 | /** | ||
133 | * Callback to be called when a service connect operation is completed | ||
134 | * | ||
135 | * @param cls the callback closure from functions generating an operation | ||
136 | * @param op the operation that has been finished | ||
137 | * @param ca_result the service handle returned from GNUNET_TESTBED_ConnectAdapter() | ||
138 | * @param emsg error message in case the operation has failed; will be NULL if | ||
139 | * operation has executed successfully. | ||
140 | */ | ||
141 | static void | ||
142 | session_connect_complete (void *cls, | ||
143 | struct GNUNET_TESTBED_Operation *op, | ||
144 | void *ca_result, | ||
145 | const char *emsg) | ||
146 | { | ||
147 | if (NULL != emsg) | ||
148 | { | ||
149 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
150 | "testbed connect emsg: %s\n", | ||
151 | emsg); | ||
152 | GNUNET_assert (0); | ||
153 | } | ||
154 | |||
155 | num_connected_sessions++; | ||
156 | |||
157 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, | ||
158 | "dkg: session connect complete\n"); | ||
159 | |||
160 | if (num_connected_sessions == num_peers) | ||
161 | { | ||
162 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, | ||
163 | "dkg: all peers connected\n"); | ||
164 | } | ||
165 | } | ||
166 | |||
167 | |||
168 | /** | ||
169 | * Callback to be called when a service connect operation is completed | ||
170 | * | ||
171 | * @param cls the callback closure from functions generating an operation | ||
172 | * @param op the operation that has been finished | ||
173 | * @param ca_result the service handle returned from GNUNET_TESTBED_ConnectAdapter() | ||
174 | * @param emsg error message in case the operation has failed; will be NULL if | ||
175 | * operation has executed successfully. | ||
176 | */ | ||
177 | static void | ||
178 | decrypt_connect_complete (void *cls, | ||
179 | struct GNUNET_TESTBED_Operation *op, | ||
180 | void *ca_result, | ||
181 | const char *emsg) | ||
182 | { | ||
183 | if (NULL != emsg) | ||
184 | { | ||
185 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
186 | "testbed connect emsg: %s\n", | ||
187 | emsg); | ||
188 | GNUNET_assert (0); | ||
189 | } | ||
190 | |||
191 | num_connected_decrypt++; | ||
192 | |||
193 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, | ||
194 | "decrypt: session connect complete\n"); | ||
195 | |||
196 | if (num_connected_decrypt == num_peers) | ||
197 | { | ||
198 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, | ||
199 | "decrypt: all peers connected\n"); | ||
200 | } | ||
201 | } | ||
202 | |||
203 | |||
204 | /** | ||
205 | * Called when a decryption has succeeded. | ||
206 | * | ||
207 | * @param cls Plaintext | ||
208 | * @param plaintext Plaintext | ||
209 | */ | ||
210 | static void | ||
211 | decrypt_cb (void *cls, | ||
212 | const struct GNUNET_SECRETSHARING_Plaintext *plaintext) | ||
213 | { | ||
214 | struct GNUNET_SECRETSHARING_DecryptionHandle **dhp = cls; | ||
215 | unsigned int n = dhp - decrypt_handles; | ||
216 | |||
217 | num_decrypted++; | ||
218 | |||
219 | *dhp = NULL; | ||
220 | |||
221 | // we should still be connected if this is called | ||
222 | GNUNET_assert (NULL != connect_ops[n]); | ||
223 | |||
224 | GNUNET_TESTBED_operation_done (connect_ops[n]); | ||
225 | |||
226 | if (NULL == plaintext) | ||
227 | { | ||
228 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "decrypt failed for peer %u\n", n); | ||
229 | return; | ||
230 | } | ||
231 | else if (0 == GNUNET_memcmp (&reference_plaintext, plaintext)) | ||
232 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, | ||
233 | "decrypt got correct result for peer %u\n", n); | ||
234 | else | ||
235 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
236 | "decrypt got wrong result for peer %u\n", n); | ||
237 | |||
238 | if (num_decrypted == num_peers) | ||
239 | { | ||
240 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, "every peer decrypted\n"); | ||
241 | GNUNET_SCHEDULER_shutdown (); | ||
242 | } | ||
243 | |||
244 | *dhp = NULL; | ||
245 | } | ||
246 | |||
247 | |||
248 | /** | ||
249 | * Adapter function called to establish a connection to | ||
250 | * a service. | ||
251 | * | ||
252 | * @param cls closure | ||
253 | * @param cfg configuration of the peer to connect to; will be available until | ||
254 | * GNUNET_TESTBED_operation_done() is called on the operation returned | ||
255 | * from GNUNET_TESTBED_service_connect() | ||
256 | * @return service handle to return in 'op_result', NULL on error | ||
257 | */ | ||
258 | static void * | ||
259 | decrypt_connect_adapter (void *cls, | ||
260 | const struct GNUNET_CONFIGURATION_Handle *cfg) | ||
261 | { | ||
262 | struct GNUNET_SECRETSHARING_DecryptionHandle **hp = cls; | ||
263 | unsigned int n = hp - decrypt_handles; | ||
264 | |||
265 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, | ||
266 | "decrypt connect adapter, %d peers\n", | ||
267 | num_peers); | ||
268 | *hp = GNUNET_SECRETSHARING_decrypt (cfg, shares[n], &ciphertext, | ||
269 | decrypt_start, decrypt_deadline, | ||
270 | decrypt_cb, | ||
271 | hp); | ||
272 | |||
273 | return *hp; | ||
274 | } | ||
275 | |||
276 | |||
277 | /** | ||
278 | * Adapter function called to destroy a connection to | ||
279 | * a service. | ||
280 | * | ||
281 | * @param cls closure | ||
282 | * @param op_result service handle returned from the connect adapter | ||
283 | */ | ||
284 | static void | ||
285 | decrypt_disconnect_adapter (void *cls, void *op_result) | ||
286 | { | ||
287 | struct GNUNET_SECRETSHARING_DecryptionHandle **dh = cls; | ||
288 | unsigned int n = dh - decrypt_handles; | ||
289 | |||
290 | GNUNET_assert (*dh == decrypt_handles[n]); | ||
291 | |||
292 | if (NULL != *dh) | ||
293 | { | ||
294 | GNUNET_SECRETSHARING_decrypt_cancel (*dh); | ||
295 | *dh = NULL; | ||
296 | } | ||
297 | |||
298 | GNUNET_assert (NULL != connect_ops[n]); | ||
299 | connect_ops[n] = NULL; | ||
300 | } | ||
301 | |||
302 | |||
303 | static void | ||
304 | secret_ready_cb (void *cls, | ||
305 | struct GNUNET_SECRETSHARING_Share *my_share, | ||
306 | struct GNUNET_SECRETSHARING_PublicKey *public_key, | ||
307 | unsigned int num_ready_peers, | ||
308 | const struct GNUNET_PeerIdentity *ready_peers) | ||
309 | { | ||
310 | struct GNUNET_SECRETSHARING_Session **sp = cls; | ||
311 | unsigned int n = sp - session_handles; | ||
312 | char pubkey_str[1024]; | ||
313 | char *ret; | ||
314 | |||
315 | num_generated++; | ||
316 | *sp = NULL; | ||
317 | shares[n] = my_share; | ||
318 | if (NULL == my_share) | ||
319 | { | ||
320 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, "key generation failed for peer #%u\n", | ||
321 | n); | ||
322 | } | ||
323 | else | ||
324 | { | ||
325 | ret = GNUNET_STRINGS_data_to_string (public_key, sizeof *public_key, | ||
326 | pubkey_str, 1024); | ||
327 | GNUNET_assert (NULL != ret); | ||
328 | *ret = '\0'; | ||
329 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, | ||
330 | "key generation successful for peer #%u, pubkey %s\n", n, | ||
331 | pubkey_str); | ||
332 | |||
333 | /* we're the first to get the key -> store it */ | ||
334 | if (num_generated == 1) | ||
335 | { | ||
336 | common_pubkey = *public_key; | ||
337 | } | ||
338 | else if (0 != GNUNET_memcmp (public_key, &common_pubkey)) | ||
339 | { | ||
340 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
341 | "generated public keys do not match\n"); | ||
342 | GNUNET_SCHEDULER_shutdown (); | ||
343 | return; | ||
344 | } | ||
345 | } | ||
346 | |||
347 | // we should still be connected | ||
348 | GNUNET_assert (NULL != connect_ops[n]); | ||
349 | |||
350 | // disconnect from the service, will call the disconnect callback | ||
351 | GNUNET_TESTBED_operation_done (connect_ops[n]); | ||
352 | } | ||
353 | |||
354 | |||
355 | /** | ||
356 | * Adapter function called to establish a connection to | ||
357 | * a service. | ||
358 | * | ||
359 | * @param cls closure | ||
360 | * @param cfg configuration of the peer to connect to; will be available until | ||
361 | * GNUNET_TESTBED_operation_done() is called on the operation returned | ||
362 | * from GNUNET_TESTBED_service_connect() | ||
363 | * @return service handle to return in 'op_result', NULL on error | ||
364 | */ | ||
365 | static void * | ||
366 | session_connect_adapter (void *cls, | ||
367 | const struct GNUNET_CONFIGURATION_Handle *cfg) | ||
368 | { | ||
369 | struct GNUNET_SECRETSHARING_Session **sp = cls; | ||
370 | |||
371 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, | ||
372 | "connect adapter, %d peers\n", | ||
373 | num_peers); | ||
374 | *sp = GNUNET_SECRETSHARING_create_session (cfg, | ||
375 | num_peers, | ||
376 | peer_ids, | ||
377 | &session_id, | ||
378 | dkg_start, | ||
379 | dkg_deadline, | ||
380 | threshold, | ||
381 | &secret_ready_cb, sp); | ||
382 | return *sp; | ||
383 | } | ||
384 | |||
385 | |||
386 | /** | ||
387 | * Adapter function called to destroy a connection to | ||
388 | * a service. | ||
389 | * | ||
390 | * @param cls closure | ||
391 | * @param op_result service handle returned from the connect adapter | ||
392 | */ | ||
393 | static void | ||
394 | session_disconnect_adapter (void *cls, void *op_result) | ||
395 | { | ||
396 | struct GNUNET_SECRETSHARING_Session **sp = cls; | ||
397 | unsigned int n = (sp - session_handles); | ||
398 | |||
399 | GNUNET_assert (*sp == session_handles[n]); | ||
400 | |||
401 | if (NULL != *sp) | ||
402 | { | ||
403 | GNUNET_SECRETSHARING_session_destroy (*sp); | ||
404 | *sp = NULL; | ||
405 | } | ||
406 | |||
407 | GNUNET_assert (NULL != connect_ops[n]); | ||
408 | connect_ops[n] = NULL; | ||
409 | |||
410 | if (GNUNET_YES == in_shutdown) | ||
411 | return; | ||
412 | |||
413 | // all peers received their secret | ||
414 | if (num_generated == num_peers) | ||
415 | { | ||
416 | int i; | ||
417 | |||
418 | // only do decryption if requested by the user | ||
419 | if (GNUNET_NO == decrypt) | ||
420 | { | ||
421 | GNUNET_SCHEDULER_shutdown (); | ||
422 | return; | ||
423 | } | ||
424 | |||
425 | decrypt_start = GNUNET_TIME_absolute_add (GNUNET_TIME_absolute_get (), | ||
426 | delay); | ||
427 | decrypt_deadline = GNUNET_TIME_absolute_add (decrypt_start, timeout); | ||
428 | |||
429 | // compute g^42 as the plaintext which we will decrypt and then | ||
430 | // cooperatively decrypt | ||
431 | GNUNET_SECRETSHARING_plaintext_generate_i (&reference_plaintext, 42); | ||
432 | GNUNET_SECRETSHARING_encrypt (&common_pubkey, &reference_plaintext, | ||
433 | &ciphertext); | ||
434 | |||
435 | for (i = 0; i < num_peers; i++) | ||
436 | connect_ops[i] = | ||
437 | GNUNET_TESTBED_service_connect (NULL, peers[i], "secretsharing", | ||
438 | &decrypt_connect_complete, NULL, | ||
439 | &decrypt_connect_adapter, | ||
440 | &decrypt_disconnect_adapter, | ||
441 | &decrypt_handles[i]); | ||
442 | } | ||
443 | } | ||
444 | |||
445 | |||
446 | /** | ||
447 | * Callback to be called when the requested peer information is available | ||
448 | * | ||
449 | * @param cb_cls the closure from GNUNET_TETSBED_peer_get_information() | ||
450 | * @param op the operation this callback corresponds to | ||
451 | * @param pinfo the result; will be NULL if the operation has failed | ||
452 | * @param emsg error message if the operation has failed; will be NULL if the | ||
453 | * operation is successful | ||
454 | */ | ||
455 | static void | ||
456 | peer_info_cb (void *cb_cls, | ||
457 | struct GNUNET_TESTBED_Operation *op, | ||
458 | const struct GNUNET_TESTBED_PeerInformation *pinfo, | ||
459 | const char *emsg) | ||
460 | { | ||
461 | struct GNUNET_PeerIdentity *p; | ||
462 | int i; | ||
463 | |||
464 | GNUNET_assert (NULL == emsg); | ||
465 | |||
466 | p = (struct GNUNET_PeerIdentity *) cb_cls; | ||
467 | |||
468 | if (pinfo->pit == GNUNET_TESTBED_PIT_IDENTITY) | ||
469 | { | ||
470 | *p = *pinfo->result.id; | ||
471 | num_retrieved_peer_ids++; | ||
472 | if (num_retrieved_peer_ids == num_peers) | ||
473 | for (i = 0; i < num_peers; i++) | ||
474 | connect_ops[i] = | ||
475 | GNUNET_TESTBED_service_connect (NULL, peers[i], "secretsharing", | ||
476 | session_connect_complete, NULL, | ||
477 | session_connect_adapter, | ||
478 | session_disconnect_adapter, | ||
479 | &session_handles[i]); | ||
480 | } | ||
481 | else | ||
482 | { | ||
483 | GNUNET_assert (0); | ||
484 | } | ||
485 | |||
486 | GNUNET_TESTBED_operation_done (op); | ||
487 | } | ||
488 | |||
489 | |||
490 | /** | ||
491 | * Signature of the main function of a task. | ||
492 | * | ||
493 | * @param cls closure | ||
494 | */ | ||
495 | static void | ||
496 | handle_shutdown (void *cls) | ||
497 | { | ||
498 | in_shutdown = GNUNET_YES; | ||
499 | |||
500 | if (NULL != connect_ops) | ||
501 | { | ||
502 | unsigned int i; | ||
503 | for (i = 0; i < num_peers; i++) | ||
504 | if (NULL != connect_ops[i]) | ||
505 | { | ||
506 | // the disconnect callback will set the op to NULL | ||
507 | GNUNET_TESTBED_operation_done (connect_ops[i]); | ||
508 | } | ||
509 | GNUNET_free (connect_ops); | ||
510 | } | ||
511 | |||
512 | // killing the testbed operation will take care of remaining | ||
513 | // service handles in the disconnect callback | ||
514 | } | ||
515 | |||
516 | |||
517 | /** | ||
518 | * Signature of a main function for a testcase. | ||
519 | * | ||
520 | * @param cls closure | ||
521 | * @param h the run handle | ||
522 | * @param num_peers number of peers in 'peers' | ||
523 | * @param started_peers handle to peers run in the testbed. NULL upon timeout (see | ||
524 | * GNUNET_TESTBED_test_run()). | ||
525 | * @param links_succeeded the number of overlay link connection attempts that | ||
526 | * succeeded | ||
527 | * @param links_failed the number of overlay link connection attempts that | ||
528 | * failed | ||
529 | */ | ||
530 | static void | ||
531 | test_master (void *cls, | ||
532 | struct GNUNET_TESTBED_RunHandle *h, | ||
533 | unsigned int num_peers, | ||
534 | struct GNUNET_TESTBED_Peer **started_peers, | ||
535 | unsigned int links_succeeded, | ||
536 | unsigned int links_failed) | ||
537 | { | ||
538 | int i; | ||
539 | |||
540 | GNUNET_log_setup ("gnunet-secretsharing-profiler", "INFO", NULL); | ||
541 | |||
542 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, "test master\n"); | ||
543 | |||
544 | GNUNET_SCHEDULER_add_shutdown (&handle_shutdown, NULL); | ||
545 | |||
546 | peers = started_peers; | ||
547 | |||
548 | peer_ids = GNUNET_malloc (num_peers * sizeof(struct GNUNET_PeerIdentity)); | ||
549 | |||
550 | session_handles = GNUNET_new_array (num_peers, struct | ||
551 | GNUNET_SECRETSHARING_Session *); | ||
552 | decrypt_handles = GNUNET_new_array (num_peers, struct | ||
553 | GNUNET_SECRETSHARING_DecryptionHandle *); | ||
554 | connect_ops = GNUNET_new_array (num_peers, struct GNUNET_TESTBED_Operation *); | ||
555 | shares = GNUNET_new_array (num_peers, struct GNUNET_SECRETSHARING_Share *); | ||
556 | |||
557 | for (i = 0; i < num_peers; i++) | ||
558 | { | ||
559 | // we do not store the returned operation, as peer_info_cb | ||
560 | // will receive it as a parameter and call GNUNET_TESTBED_operation_done. | ||
561 | GNUNET_TESTBED_peer_get_information (peers[i], | ||
562 | GNUNET_TESTBED_PIT_IDENTITY, | ||
563 | peer_info_cb, | ||
564 | &peer_ids[i]); | ||
565 | } | ||
566 | } | ||
567 | |||
568 | |||
569 | static void | ||
570 | run (void *cls, char *const *args, const char *cfgfile, | ||
571 | const struct GNUNET_CONFIGURATION_Handle *cfg) | ||
572 | { | ||
573 | static char *session_str = "gnunet-secretsharing/test"; | ||
574 | char *topology; | ||
575 | int topology_cmp_result; | ||
576 | |||
577 | dkg_start = GNUNET_TIME_absolute_add (GNUNET_TIME_absolute_get (), delay); | ||
578 | dkg_deadline = GNUNET_TIME_absolute_add (dkg_start, timeout); | ||
579 | |||
580 | if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_string (cfg, "testbed", | ||
581 | "OVERLAY_TOPOLOGY", | ||
582 | &topology)) | ||
583 | { | ||
584 | fprintf (stderr, | ||
585 | "'OVERLAY_TOPOLOGY' not found in 'testbed' config section, " | ||
586 | "seems like you passed the wrong configuration file\n"); | ||
587 | return; | ||
588 | } | ||
589 | |||
590 | topology_cmp_result = strcasecmp (topology, "NONE"); | ||
591 | GNUNET_free (topology); | ||
592 | |||
593 | if (0 == topology_cmp_result) | ||
594 | { | ||
595 | fprintf (stderr, | ||
596 | "'OVERLAY_TOPOLOGY' set to 'NONE', " | ||
597 | "seems like you passed the wrong configuration file\n"); | ||
598 | return; | ||
599 | } | ||
600 | |||
601 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, | ||
602 | "running gnunet-secretsharing-profiler\n"); | ||
603 | |||
604 | GNUNET_CRYPTO_hash (session_str, strlen (session_str), &session_id); | ||
605 | |||
606 | (void) GNUNET_TESTBED_test_run ("gnunet-secretsharing-profiler", | ||
607 | cfgfile, | ||
608 | num_peers, | ||
609 | 0, | ||
610 | controller_cb, | ||
611 | NULL, | ||
612 | test_master, | ||
613 | NULL); | ||
614 | } | ||
615 | |||
616 | |||
617 | int | ||
618 | main (int argc, char **argv) | ||
619 | { | ||
620 | struct GNUNET_GETOPT_CommandLineOption options[] = { | ||
621 | GNUNET_GETOPT_option_uint ('n', | ||
622 | "num-peers", | ||
623 | NULL, | ||
624 | gettext_noop ("number of peers in consensus"), | ||
625 | &num_peers), | ||
626 | |||
627 | GNUNET_GETOPT_option_relative_time ('D', | ||
628 | "delay", | ||
629 | NULL, | ||
630 | gettext_noop ("dkg start delay"), | ||
631 | &delay), | ||
632 | |||
633 | GNUNET_GETOPT_option_relative_time ('t', | ||
634 | "timeout", | ||
635 | NULL, | ||
636 | gettext_noop ("dkg timeout"), | ||
637 | &timeout), | ||
638 | |||
639 | GNUNET_GETOPT_option_uint ('k', | ||
640 | "threshold", | ||
641 | NULL, | ||
642 | gettext_noop ("threshold"), | ||
643 | &threshold), | ||
644 | |||
645 | GNUNET_GETOPT_option_flag ('d', | ||
646 | "descrypt", | ||
647 | gettext_noop ("also profile decryption"), | ||
648 | &decrypt), | ||
649 | |||
650 | |||
651 | GNUNET_GETOPT_option_verbose (&verbose), | ||
652 | |||
653 | GNUNET_GETOPT_OPTION_END | ||
654 | }; | ||
655 | |||
656 | delay = GNUNET_TIME_UNIT_ZERO; | ||
657 | timeout = GNUNET_TIME_UNIT_MINUTES; | ||
658 | GNUNET_PROGRAM_run2 (argc, argv, "gnunet-secretsharing-profiler", | ||
659 | "help", | ||
660 | options, &run, NULL, GNUNET_YES); | ||
661 | return 0; | ||
662 | } | ||
diff --git a/src/secretsharing/gnunet-service-secretsharing.c b/src/secretsharing/gnunet-service-secretsharing.c deleted file mode 100644 index 939b7827d..000000000 --- a/src/secretsharing/gnunet-service-secretsharing.c +++ /dev/null | |||
@@ -1,2415 +0,0 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet. | ||
3 | Copyright (C) 2013 GNUnet e.V. | ||
4 | |||
5 | GNUnet is free software: you can redistribute it and/or modify it | ||
6 | under the terms of the GNU Affero General Public License as published | ||
7 | by the Free Software Foundation, either version 3 of the License, | ||
8 | or (at your option) any later version. | ||
9 | |||
10 | GNUnet is distributed in the hope that it will be useful, but | ||
11 | WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
13 | Affero General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU Affero General Public License | ||
16 | along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
17 | |||
18 | SPDX-License-Identifier: AGPL3.0-or-later | ||
19 | */ | ||
20 | |||
21 | /** | ||
22 | * @file secretsharing/gnunet-service-secretsharing.c | ||
23 | * @brief secret sharing service | ||
24 | * @author Florian Dold | ||
25 | */ | ||
26 | #include "platform.h" | ||
27 | #include "gnunet_util_lib.h" | ||
28 | #include "gnunet_time_lib.h" | ||
29 | #include "gnunet_signatures.h" | ||
30 | #include "gnunet_consensus_service.h" | ||
31 | #include "secretsharing.h" | ||
32 | #include "secretsharing_protocol.h" | ||
33 | #include <gcrypt.h> | ||
34 | |||
35 | |||
36 | #define EXTRA_CHECKS 1 | ||
37 | |||
38 | |||
39 | /** | ||
40 | * Info about a peer in a key generation session. | ||
41 | */ | ||
42 | struct KeygenPeerInfo | ||
43 | { | ||
44 | /** | ||
45 | * Peer identity of the peer. | ||
46 | */ | ||
47 | struct GNUNET_PeerIdentity peer; | ||
48 | |||
49 | /** | ||
50 | * The peer's paillier public key. | ||
51 | * Freshly generated for each keygen session. | ||
52 | */ | ||
53 | struct GNUNET_CRYPTO_PaillierPublicKey paillier_public_key; | ||
54 | |||
55 | /** | ||
56 | * The peer's commitment to its presecret. | ||
57 | */ | ||
58 | gcry_mpi_t presecret_commitment; | ||
59 | |||
60 | /** | ||
61 | * Commitment to the preshare that is | ||
62 | * intended for our peer. | ||
63 | */ | ||
64 | gcry_mpi_t preshare_commitment; | ||
65 | |||
66 | /** | ||
67 | * Sigma (exponentiated share) for this peer. | ||
68 | */ | ||
69 | gcry_mpi_t sigma; | ||
70 | |||
71 | /** | ||
72 | * Did we successfully receive the round1 element | ||
73 | * of the peer? | ||
74 | */ | ||
75 | int round1_valid; | ||
76 | |||
77 | /** | ||
78 | * Did we successfully receive the round2 element | ||
79 | * of the peer? | ||
80 | */ | ||
81 | int round2_valid; | ||
82 | }; | ||
83 | |||
84 | |||
85 | /** | ||
86 | * Information about a peer in a decrypt session. | ||
87 | */ | ||
88 | struct DecryptPeerInfo | ||
89 | { | ||
90 | /** | ||
91 | * Identity of the peer. | ||
92 | */ | ||
93 | struct GNUNET_PeerIdentity peer; | ||
94 | |||
95 | /** | ||
96 | * Original index in the key generation round. | ||
97 | * Necessary for computing the lagrange coefficients. | ||
98 | */ | ||
99 | unsigned int original_index; | ||
100 | |||
101 | /** | ||
102 | * Set to the partial decryption of | ||
103 | * this peer, or NULL if we did not | ||
104 | * receive a partial decryption from this | ||
105 | * peer or the zero knowledge proof failed. | ||
106 | */ | ||
107 | gcry_mpi_t partial_decryption; | ||
108 | }; | ||
109 | |||
110 | |||
111 | /** | ||
112 | * State we keep per client. | ||
113 | */ | ||
114 | struct ClientState; | ||
115 | |||
116 | |||
117 | /** | ||
118 | * Session to establish a threshold-shared secret. | ||
119 | */ | ||
120 | struct KeygenSession | ||
121 | { | ||
122 | /** | ||
123 | * Current consensus, used for both DKG rounds. | ||
124 | */ | ||
125 | struct GNUNET_CONSENSUS_Handle *consensus; | ||
126 | |||
127 | /** | ||
128 | * Which client is this for? | ||
129 | */ | ||
130 | struct ClientState *cs; | ||
131 | |||
132 | /** | ||
133 | * Randomly generated coefficients of the polynomial for sharing our | ||
134 | * pre-secret, where 'preshares[0]' is our pre-secret. Contains 'threshold' | ||
135 | * elements, thus represents a polynomial of degree 'threshold-1', which can | ||
136 | * be interpolated with 'threshold' data points. | ||
137 | * | ||
138 | * The pre-secret-shares 'i=1,...,num_peers' are given by evaluating this | ||
139 | * polyomial at 'i' for share i. | ||
140 | */ | ||
141 | gcry_mpi_t *presecret_polynomial; | ||
142 | |||
143 | /** | ||
144 | * Minimum number of shares required to restore the secret. | ||
145 | * Also the number of coefficients for the polynomial representing | ||
146 | * the sharing. Obviously, the polynomial then has degree threshold-1. | ||
147 | */ | ||
148 | unsigned int threshold; | ||
149 | |||
150 | /** | ||
151 | * Total number of peers. | ||
152 | */ | ||
153 | unsigned int num_peers; | ||
154 | |||
155 | /** | ||
156 | * Index of the local peer. | ||
157 | */ | ||
158 | unsigned int local_peer; | ||
159 | |||
160 | /** | ||
161 | * Information about all participating peers. | ||
162 | * Array of size 'num_peers'. | ||
163 | */ | ||
164 | struct KeygenPeerInfo *info; | ||
165 | |||
166 | /** | ||
167 | * List of all peers involved in the secret sharing session. | ||
168 | */ | ||
169 | struct GNUNET_PeerIdentity *peers; | ||
170 | |||
171 | /** | ||
172 | * Identifier for this session. | ||
173 | */ | ||
174 | struct GNUNET_HashCode session_id; | ||
175 | |||
176 | /** | ||
177 | * Paillier private key of our peer. | ||
178 | */ | ||
179 | struct GNUNET_CRYPTO_PaillierPrivateKey paillier_private_key; | ||
180 | |||
181 | /** | ||
182 | * When would we like the key to be established? | ||
183 | */ | ||
184 | struct GNUNET_TIME_Absolute deadline; | ||
185 | |||
186 | /** | ||
187 | * When does the DKG start? Necessary to compute fractions of the | ||
188 | * operation's desired time interval. | ||
189 | */ | ||
190 | struct GNUNET_TIME_Absolute start_time; | ||
191 | |||
192 | /** | ||
193 | * Index of the local peer in the ordered list | ||
194 | * of peers in the session. | ||
195 | */ | ||
196 | unsigned int local_peer_idx; | ||
197 | |||
198 | /** | ||
199 | * Share of our peer. Once preshares from other peers are received, they | ||
200 | * will be added to 'my'share. | ||
201 | */ | ||
202 | gcry_mpi_t my_share; | ||
203 | |||
204 | /** | ||
205 | * Public key, will be updated when a round2 element arrives. | ||
206 | */ | ||
207 | gcry_mpi_t public_key; | ||
208 | }; | ||
209 | |||
210 | |||
211 | /** | ||
212 | * Session to cooperatively decrypt a value. | ||
213 | */ | ||
214 | struct DecryptSession | ||
215 | { | ||
216 | /** | ||
217 | * Handle to the consensus over partial decryptions. | ||
218 | */ | ||
219 | struct GNUNET_CONSENSUS_Handle *consensus; | ||
220 | |||
221 | /** | ||
222 | * Which client is this for? | ||
223 | */ | ||
224 | struct ClientState *cs; | ||
225 | |||
226 | /** | ||
227 | * When should we start communicating for decryption? | ||
228 | */ | ||
229 | struct GNUNET_TIME_Absolute start; | ||
230 | |||
231 | /** | ||
232 | * When would we like the ciphertext to be | ||
233 | * decrypted? | ||
234 | */ | ||
235 | struct GNUNET_TIME_Absolute deadline; | ||
236 | |||
237 | /** | ||
238 | * Ciphertext we want to decrypt. | ||
239 | */ | ||
240 | struct GNUNET_SECRETSHARING_Ciphertext ciphertext; | ||
241 | |||
242 | /** | ||
243 | * Share of the local peer. | ||
244 | * Contains other important information, such as | ||
245 | * the list of other peers. | ||
246 | */ | ||
247 | struct GNUNET_SECRETSHARING_Share *share; | ||
248 | |||
249 | /** | ||
250 | * State information about other peers. | ||
251 | */ | ||
252 | struct DecryptPeerInfo *info; | ||
253 | }; | ||
254 | |||
255 | |||
256 | /** | ||
257 | * State we keep per client. | ||
258 | */ | ||
259 | struct ClientState | ||
260 | { | ||
261 | /** | ||
262 | * Decrypt session of the client, if any. | ||
263 | */ | ||
264 | struct DecryptSession *decrypt_session; | ||
265 | |||
266 | /** | ||
267 | * Keygen session of the client, if any. | ||
268 | */ | ||
269 | struct KeygenSession *keygen_session; | ||
270 | |||
271 | /** | ||
272 | * Client this is about. | ||
273 | */ | ||
274 | struct GNUNET_SERVICE_Client *client; | ||
275 | |||
276 | /** | ||
277 | * MQ to talk to @a client. | ||
278 | */ | ||
279 | struct GNUNET_MQ_Handle *mq; | ||
280 | }; | ||
281 | |||
282 | |||
283 | /** | ||
284 | * The ElGamal prime field order as libgcrypt mpi. | ||
285 | * Initialized in #init_crypto_constants. | ||
286 | */ | ||
287 | static gcry_mpi_t elgamal_q; | ||
288 | |||
289 | /** | ||
290 | * Modulus of the prime field used for ElGamal. | ||
291 | * Initialized in #init_crypto_constants. | ||
292 | */ | ||
293 | static gcry_mpi_t elgamal_p; | ||
294 | |||
295 | /** | ||
296 | * Generator for prime field of order 'elgamal_q'. | ||
297 | * Initialized in #init_crypto_constants. | ||
298 | */ | ||
299 | static gcry_mpi_t elgamal_g; | ||
300 | |||
301 | /** | ||
302 | * Peer that runs this service. | ||
303 | */ | ||
304 | static struct GNUNET_PeerIdentity my_peer; | ||
305 | |||
306 | /** | ||
307 | * Peer that runs this service. | ||
308 | */ | ||
309 | static struct GNUNET_CRYPTO_EddsaPrivateKey *my_peer_private_key; | ||
310 | |||
311 | /** | ||
312 | * Configuration of this service. | ||
313 | */ | ||
314 | static const struct GNUNET_CONFIGURATION_Handle *cfg; | ||
315 | |||
316 | |||
317 | /** | ||
318 | * Get the peer info belonging to a peer identity in a keygen session. | ||
319 | * | ||
320 | * @param ks The keygen session. | ||
321 | * @param peer The peer identity. | ||
322 | * @return The Keygen peer info, or NULL if the peer could not be found. | ||
323 | */ | ||
324 | static struct KeygenPeerInfo * | ||
325 | get_keygen_peer_info (const struct KeygenSession *ks, | ||
326 | const struct GNUNET_PeerIdentity *peer) | ||
327 | { | ||
328 | unsigned int i; | ||
329 | |||
330 | for (i = 0; i < ks->num_peers; i++) | ||
331 | if (0 == GNUNET_memcmp (peer, &ks->info[i].peer)) | ||
332 | return &ks->info[i]; | ||
333 | return NULL; | ||
334 | } | ||
335 | |||
336 | |||
337 | /** | ||
338 | * Get the peer info belonging to a peer identity in a decrypt session. | ||
339 | * | ||
340 | * @param ds The decrypt session. | ||
341 | * @param peer The peer identity. | ||
342 | * @return The decrypt peer info, or NULL if the peer could not be found. | ||
343 | */ | ||
344 | static struct DecryptPeerInfo * | ||
345 | get_decrypt_peer_info (const struct DecryptSession *ds, | ||
346 | const struct GNUNET_PeerIdentity *peer) | ||
347 | { | ||
348 | unsigned int i; | ||
349 | |||
350 | for (i = 0; i < ds->share->num_peers; i++) | ||
351 | if (0 == GNUNET_memcmp (peer, &ds->info[i].peer)) | ||
352 | return &ds->info[i]; | ||
353 | return NULL; | ||
354 | } | ||
355 | |||
356 | |||
357 | /** | ||
358 | * Interpolate between two points in time. | ||
359 | * | ||
360 | * @param start start time | ||
361 | * @param end end time | ||
362 | * @param num numerator of the scale factor | ||
363 | * @param denum denumerator of the scale factor | ||
364 | */ | ||
365 | static struct GNUNET_TIME_Absolute | ||
366 | time_between (struct GNUNET_TIME_Absolute start, | ||
367 | struct GNUNET_TIME_Absolute end, | ||
368 | int num, int denum) | ||
369 | { | ||
370 | struct GNUNET_TIME_Absolute result; | ||
371 | uint64_t diff; | ||
372 | |||
373 | GNUNET_assert (start.abs_value_us <= end.abs_value_us); | ||
374 | diff = end.abs_value_us - start.abs_value_us; | ||
375 | result.abs_value_us = start.abs_value_us + ((diff * num) / denum); | ||
376 | |||
377 | return result; | ||
378 | } | ||
379 | |||
380 | |||
381 | /** | ||
382 | * Compare two peer identities. Intended to be used with qsort or bsearch. | ||
383 | * | ||
384 | * @param p1 Some peer identity. | ||
385 | * @param p2 Some peer identity. | ||
386 | * @return 1 if p1 > p2, -1 if p1 < p2 and 0 if p1 == p2. | ||
387 | */ | ||
388 | static int | ||
389 | peer_id_cmp (const void *p1, const void *p2) | ||
390 | { | ||
391 | return memcmp (p1, | ||
392 | p2, | ||
393 | sizeof(struct GNUNET_PeerIdentity)); | ||
394 | } | ||
395 | |||
396 | |||
397 | /** | ||
398 | * Get the index of a peer in an array of peers | ||
399 | * | ||
400 | * @param haystack Array of peers. | ||
401 | * @param n Size of @a haystack. | ||
402 | * @param needle Peer to find | ||
403 | * @return Index of @a needle in @a haystack, or -1 if peer | ||
404 | * is not in the list. | ||
405 | */ | ||
406 | static int | ||
407 | peer_find (const struct GNUNET_PeerIdentity *haystack, unsigned int n, | ||
408 | const struct GNUNET_PeerIdentity *needle) | ||
409 | { | ||
410 | unsigned int i; | ||
411 | |||
412 | for (i = 0; i < n; i++) | ||
413 | if (0 == GNUNET_memcmp (&haystack[i], | ||
414 | needle)) | ||
415 | return i; | ||
416 | return -1; | ||
417 | } | ||
418 | |||
419 | |||
420 | /** | ||
421 | * Normalize the given list of peers, by including the local peer | ||
422 | * (if it is missing) and sorting the peers by their identity. | ||
423 | * | ||
424 | * @param listed Peers in the unnormalized list. | ||
425 | * @param num_listed Peers in the un-normalized list. | ||
426 | * @param[out] num_normalized Number of peers in the normalized list. | ||
427 | * @param[out] my_peer_idx Index of the local peer in the normalized list. | ||
428 | * @return Normalized list, must be free'd by the caller. | ||
429 | */ | ||
430 | static struct GNUNET_PeerIdentity * | ||
431 | normalize_peers (struct GNUNET_PeerIdentity *listed, | ||
432 | unsigned int num_listed, | ||
433 | unsigned int *num_normalized, | ||
434 | unsigned int *my_peer_idx) | ||
435 | { | ||
436 | unsigned int local_peer_in_list; | ||
437 | /* number of peers in the normalized list */ | ||
438 | unsigned int n; | ||
439 | struct GNUNET_PeerIdentity *normalized; | ||
440 | |||
441 | local_peer_in_list = GNUNET_YES; | ||
442 | n = num_listed; | ||
443 | if (peer_find (listed, num_listed, &my_peer) < 0) | ||
444 | { | ||
445 | local_peer_in_list = GNUNET_NO; | ||
446 | n += 1; | ||
447 | } | ||
448 | |||
449 | normalized = GNUNET_new_array (n, | ||
450 | struct GNUNET_PeerIdentity); | ||
451 | |||
452 | if (GNUNET_NO == local_peer_in_list) | ||
453 | normalized[n - 1] = my_peer; | ||
454 | |||
455 | GNUNET_memcpy (normalized, | ||
456 | listed, | ||
457 | num_listed * sizeof(struct GNUNET_PeerIdentity)); | ||
458 | qsort (normalized, | ||
459 | n, | ||
460 | sizeof(struct GNUNET_PeerIdentity), | ||
461 | &peer_id_cmp); | ||
462 | |||
463 | if (NULL != my_peer_idx) | ||
464 | *my_peer_idx = peer_find (normalized, n, &my_peer); | ||
465 | if (NULL != num_normalized) | ||
466 | *num_normalized = n; | ||
467 | |||
468 | return normalized; | ||
469 | } | ||
470 | |||
471 | |||
472 | /** | ||
473 | * Get a the j-th lagrange coefficient for a set of indices. | ||
474 | * | ||
475 | * @param[out] coeff the lagrange coefficient | ||
476 | * @param j lagrange coefficient we want to compute | ||
477 | * @param indices indices | ||
478 | * @param num number of indices in @a indices | ||
479 | */ | ||
480 | static void | ||
481 | compute_lagrange_coefficient (gcry_mpi_t coeff, unsigned int j, | ||
482 | unsigned int *indices, | ||
483 | unsigned int num) | ||
484 | { | ||
485 | unsigned int i; | ||
486 | /* numerator */ | ||
487 | gcry_mpi_t n; | ||
488 | /* denominator */ | ||
489 | gcry_mpi_t d; | ||
490 | /* temp value for l-j */ | ||
491 | gcry_mpi_t tmp; | ||
492 | |||
493 | GNUNET_assert (0 != coeff); | ||
494 | |||
495 | GNUNET_assert (0 != (n = gcry_mpi_new (0))); | ||
496 | GNUNET_assert (0 != (d = gcry_mpi_new (0))); | ||
497 | GNUNET_assert (0 != (tmp = gcry_mpi_new (0))); | ||
498 | |||
499 | gcry_mpi_set_ui (n, 1); | ||
500 | gcry_mpi_set_ui (d, 1); | ||
501 | |||
502 | for (i = 0; i < num; i++) | ||
503 | { | ||
504 | unsigned int l = indices[i]; | ||
505 | if (l == j) | ||
506 | continue; | ||
507 | gcry_mpi_mul_ui (n, n, l + 1); | ||
508 | // d <- d * (l-j) | ||
509 | gcry_mpi_set_ui (tmp, l + 1); | ||
510 | gcry_mpi_sub_ui (tmp, tmp, j + 1); | ||
511 | gcry_mpi_mul (d, d, tmp); | ||
512 | } | ||
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 | |||
519 | // now we do the actual division, with everything mod q, as we | ||
520 | // are not operating on elements from <g>, but on exponents | ||
521 | GNUNET_assert (0 != gcry_mpi_invm (d, d, elgamal_q)); | ||
522 | |||
523 | gcry_mpi_mulm (coeff, n, d, elgamal_q); | ||
524 | |||
525 | gcry_mpi_release (n); | ||
526 | gcry_mpi_release (d); | ||
527 | gcry_mpi_release (tmp); | ||
528 | } | ||
529 | |||
530 | |||
531 | /** | ||
532 | * Destroy a decrypt session, removing it from | ||
533 | * the linked list of decrypt sessions. | ||
534 | * | ||
535 | * @param ds decrypt session to destroy | ||
536 | */ | ||
537 | static void | ||
538 | decrypt_session_destroy (struct DecryptSession *ds) | ||
539 | { | ||
540 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
541 | "destroying decrypt session\n"); | ||
542 | if (NULL != ds->cs) | ||
543 | { | ||
544 | ds->cs->decrypt_session = NULL; | ||
545 | ds->cs = NULL; | ||
546 | } | ||
547 | if (NULL != ds->consensus) | ||
548 | { | ||
549 | GNUNET_CONSENSUS_destroy (ds->consensus); | ||
550 | ds->consensus = NULL; | ||
551 | } | ||
552 | |||
553 | if (NULL != ds->info) | ||
554 | { | ||
555 | for (unsigned int i = 0; i < ds->share->num_peers; i++) | ||
556 | { | ||
557 | if (NULL != ds->info[i].partial_decryption) | ||
558 | { | ||
559 | gcry_mpi_release (ds->info[i].partial_decryption); | ||
560 | ds->info[i].partial_decryption = NULL; | ||
561 | } | ||
562 | } | ||
563 | GNUNET_free (ds->info); | ||
564 | ds->info = NULL; | ||
565 | } | ||
566 | if (NULL != ds->share) | ||
567 | { | ||
568 | GNUNET_SECRETSHARING_share_destroy (ds->share); | ||
569 | ds->share = NULL; | ||
570 | } | ||
571 | |||
572 | GNUNET_free (ds); | ||
573 | } | ||
574 | |||
575 | |||
576 | static void | ||
577 | keygen_info_destroy (struct KeygenPeerInfo *info) | ||
578 | { | ||
579 | if (NULL != info->sigma) | ||
580 | { | ||
581 | gcry_mpi_release (info->sigma); | ||
582 | info->sigma = NULL; | ||
583 | } | ||
584 | if (NULL != info->presecret_commitment) | ||
585 | { | ||
586 | gcry_mpi_release (info->presecret_commitment); | ||
587 | info->presecret_commitment = NULL; | ||
588 | } | ||
589 | if (NULL != info->preshare_commitment) | ||
590 | { | ||
591 | gcry_mpi_release (info->preshare_commitment); | ||
592 | info->preshare_commitment = NULL; | ||
593 | } | ||
594 | } | ||
595 | |||
596 | |||
597 | static void | ||
598 | keygen_session_destroy (struct KeygenSession *ks) | ||
599 | { | ||
600 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
601 | "destroying keygen session\n"); | ||
602 | |||
603 | if (NULL != ks->cs) | ||
604 | { | ||
605 | ks->cs->keygen_session = NULL; | ||
606 | ks->cs = NULL; | ||
607 | } | ||
608 | if (NULL != ks->info) | ||
609 | { | ||
610 | for (unsigned int i = 0; i < ks->num_peers; i++) | ||
611 | keygen_info_destroy (&ks->info[i]); | ||
612 | GNUNET_free (ks->info); | ||
613 | ks->info = NULL; | ||
614 | } | ||
615 | |||
616 | if (NULL != ks->consensus) | ||
617 | { | ||
618 | GNUNET_CONSENSUS_destroy (ks->consensus); | ||
619 | ks->consensus = NULL; | ||
620 | } | ||
621 | |||
622 | if (NULL != ks->presecret_polynomial) | ||
623 | { | ||
624 | for (unsigned int i = 0; i < ks->threshold; i++) | ||
625 | { | ||
626 | GNUNET_assert (NULL != ks->presecret_polynomial[i]); | ||
627 | gcry_mpi_release (ks->presecret_polynomial[i]); | ||
628 | ks->presecret_polynomial[i] = NULL; | ||
629 | } | ||
630 | GNUNET_free (ks->presecret_polynomial); | ||
631 | ks->presecret_polynomial = NULL; | ||
632 | } | ||
633 | if (NULL != ks->my_share) | ||
634 | { | ||
635 | gcry_mpi_release (ks->my_share); | ||
636 | ks->my_share = NULL; | ||
637 | } | ||
638 | if (NULL != ks->public_key) | ||
639 | { | ||
640 | gcry_mpi_release (ks->public_key); | ||
641 | ks->public_key = NULL; | ||
642 | } | ||
643 | if (NULL != ks->peers) | ||
644 | { | ||
645 | GNUNET_free (ks->peers); | ||
646 | ks->peers = NULL; | ||
647 | } | ||
648 | GNUNET_free (ks); | ||
649 | } | ||
650 | |||
651 | |||
652 | /** | ||
653 | * Task run during shutdown. | ||
654 | * | ||
655 | * @param cls unused | ||
656 | * @param tc unused | ||
657 | */ | ||
658 | static void | ||
659 | cleanup_task (void *cls) | ||
660 | { | ||
661 | /* Nothing to do! */ | ||
662 | } | ||
663 | |||
664 | |||
665 | /** | ||
666 | * Generate the random coefficients of our pre-secret polynomial | ||
667 | * | ||
668 | * @param ks the session | ||
669 | */ | ||
670 | static void | ||
671 | generate_presecret_polynomial (struct KeygenSession *ks) | ||
672 | { | ||
673 | int i; | ||
674 | gcry_mpi_t v; | ||
675 | |||
676 | GNUNET_assert (NULL == ks->presecret_polynomial); | ||
677 | ks->presecret_polynomial = GNUNET_new_array (ks->threshold, | ||
678 | gcry_mpi_t); | ||
679 | for (i = 0; i < ks->threshold; i++) | ||
680 | { | ||
681 | v = ks->presecret_polynomial[i] = gcry_mpi_new ( | ||
682 | GNUNET_SECRETSHARING_ELGAMAL_BITS); | ||
683 | GNUNET_assert (NULL != v); | ||
684 | // Randomize v such that 0 < v < elgamal_q. | ||
685 | // The '- 1' is necessary as bitlength(q) = bitlength(p) - 1. | ||
686 | do | ||
687 | { | ||
688 | gcry_mpi_randomize (v, GNUNET_SECRETSHARING_ELGAMAL_BITS - 1, | ||
689 | GCRY_WEAK_RANDOM); | ||
690 | } | ||
691 | while ((gcry_mpi_cmp_ui (v, 0) == 0) || (gcry_mpi_cmp (v, elgamal_q) >= 0)); | ||
692 | } | ||
693 | } | ||
694 | |||
695 | |||
696 | /** | ||
697 | * Consensus element handler for round one. | ||
698 | * We should get one ephemeral key for each peer. | ||
699 | * | ||
700 | * @param cls Closure (keygen session). | ||
701 | * @param element The element from consensus, or | ||
702 | * NULL if consensus failed. | ||
703 | */ | ||
704 | static void | ||
705 | keygen_round1_new_element (void *cls, | ||
706 | const struct GNUNET_SET_Element *element) | ||
707 | { | ||
708 | const struct GNUNET_SECRETSHARING_KeygenCommitData *d; | ||
709 | struct KeygenSession *ks = cls; | ||
710 | struct KeygenPeerInfo *info; | ||
711 | |||
712 | if (NULL == element) | ||
713 | { | ||
714 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "round1 consensus failed\n"); | ||
715 | return; | ||
716 | } | ||
717 | |||
718 | /* elements have fixed size */ | ||
719 | if (element->size != sizeof(struct GNUNET_SECRETSHARING_KeygenCommitData)) | ||
720 | { | ||
721 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | ||
722 | "keygen commit data with wrong size (%u) in consensus, %u expected\n", | ||
723 | (unsigned int) element->size, | ||
724 | (unsigned int) sizeof(struct | ||
725 | GNUNET_SECRETSHARING_KeygenCommitData)); | ||
726 | return; | ||
727 | } | ||
728 | |||
729 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, "got round1 element\n"); | ||
730 | |||
731 | d = element->data; | ||
732 | info = get_keygen_peer_info (ks, &d->peer); | ||
733 | |||
734 | if (NULL == info) | ||
735 | { | ||
736 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | ||
737 | "keygen commit data with wrong peer identity (%s) in consensus\n", | ||
738 | GNUNET_i2s (&d->peer)); | ||
739 | return; | ||
740 | } | ||
741 | |||
742 | /* Check that the right amount of data has been signed. */ | ||
743 | if (d->purpose.size != | ||
744 | htonl (element->size - offsetof (struct | ||
745 | GNUNET_SECRETSHARING_KeygenCommitData, | ||
746 | purpose))) | ||
747 | { | ||
748 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | ||
749 | "keygen commit data with wrong signature purpose size in consensus\n"); | ||
750 | return; | ||
751 | } | ||
752 | |||
753 | if (GNUNET_OK != GNUNET_CRYPTO_eddsa_verify_ ( | ||
754 | GNUNET_SIGNATURE_PURPOSE_SECRETSHARING_DKG1, | ||
755 | &d->purpose, &d->signature, | ||
756 | &d->peer.public_key)) | ||
757 | { | ||
758 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | ||
759 | "keygen commit data with invalid signature in consensus\n"); | ||
760 | return; | ||
761 | } | ||
762 | info->paillier_public_key = d->pubkey; | ||
763 | GNUNET_CRYPTO_mpi_scan_unsigned (&info->presecret_commitment, &d->commitment, | ||
764 | 512 / 8); | ||
765 | info->round1_valid = GNUNET_YES; | ||
766 | } | ||
767 | |||
768 | |||
769 | /** | ||
770 | * Evaluate the polynomial with coefficients @a coeff at @a x. | ||
771 | * The i-th element in @a coeff corresponds to the coefficient of x^i. | ||
772 | * | ||
773 | * @param[out] z result of the evaluation | ||
774 | * @param coeff array of coefficients | ||
775 | * @param num_coeff number of coefficients | ||
776 | * @param x where to evaluate the polynomial | ||
777 | * @param m what group are we operating in? | ||
778 | */ | ||
779 | static void | ||
780 | horner_eval (gcry_mpi_t z, gcry_mpi_t *coeff, unsigned int num_coeff, gcry_mpi_t | ||
781 | x, gcry_mpi_t m) | ||
782 | { | ||
783 | unsigned int i; | ||
784 | |||
785 | gcry_mpi_set_ui (z, 0); | ||
786 | for (i = 0; i < num_coeff; i++) | ||
787 | { | ||
788 | // z <- zx + c | ||
789 | gcry_mpi_mul (z, z, x); | ||
790 | gcry_mpi_addm (z, z, coeff[num_coeff - i - 1], m); | ||
791 | } | ||
792 | } | ||
793 | |||
794 | |||
795 | static void | ||
796 | keygen_round2_conclude (void *cls) | ||
797 | { | ||
798 | struct KeygenSession *ks = cls; | ||
799 | struct GNUNET_SECRETSHARING_SecretReadyMessage *m; | ||
800 | struct GNUNET_MQ_Envelope *ev; | ||
801 | size_t share_size; | ||
802 | unsigned int i; | ||
803 | unsigned int j; | ||
804 | struct GNUNET_SECRETSHARING_Share *share; | ||
805 | |||
806 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, "round2 conclude\n"); | ||
807 | |||
808 | GNUNET_CONSENSUS_destroy (ks->consensus); | ||
809 | ks->consensus = NULL; | ||
810 | |||
811 | share = GNUNET_new (struct GNUNET_SECRETSHARING_Share); | ||
812 | |||
813 | share->num_peers = 0; | ||
814 | |||
815 | for (i = 0; i < ks->num_peers; i++) | ||
816 | if (GNUNET_YES == ks->info[i].round2_valid) | ||
817 | share->num_peers++; | ||
818 | |||
819 | share->peers = GNUNET_new_array (share->num_peers, | ||
820 | struct GNUNET_PeerIdentity); | ||
821 | share->sigmas = | ||
822 | GNUNET_new_array (share->num_peers, | ||
823 | struct GNUNET_SECRETSHARING_FieldElement); | ||
824 | share->original_indices = GNUNET_new_array (share->num_peers, | ||
825 | uint16_t); | ||
826 | |||
827 | /* maybe we're not even in the list of peers? */ | ||
828 | share->my_peer = share->num_peers; | ||
829 | |||
830 | j = 0; /* running index of valid peers */ | ||
831 | for (i = 0; i < ks->num_peers; i++) | ||
832 | { | ||
833 | if (GNUNET_YES == ks->info[i].round2_valid) | ||
834 | { | ||
835 | share->peers[j] = ks->info[i].peer; | ||
836 | GNUNET_CRYPTO_mpi_print_unsigned (&share->sigmas[j], | ||
837 | GNUNET_SECRETSHARING_ELGAMAL_BITS / 8, | ||
838 | ks->info[i].sigma); | ||
839 | share->original_indices[i] = j; | ||
840 | if (0 == GNUNET_memcmp (&share->peers[i], &my_peer)) | ||
841 | share->my_peer = j; | ||
842 | j += 1; | ||
843 | } | ||
844 | } | ||
845 | |||
846 | if (share->my_peer == share->num_peers) | ||
847 | { | ||
848 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, "P%u: peer identity not in share\n", | ||
849 | ks->local_peer_idx); | ||
850 | } | ||
851 | |||
852 | GNUNET_CRYPTO_mpi_print_unsigned (&share->my_share, | ||
853 | GNUNET_SECRETSHARING_ELGAMAL_BITS / 8, | ||
854 | ks->my_share); | ||
855 | GNUNET_CRYPTO_mpi_print_unsigned (&share->public_key, | ||
856 | GNUNET_SECRETSHARING_ELGAMAL_BITS / 8, | ||
857 | ks->public_key); | ||
858 | |||
859 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, "keygen completed with %u peers\n", | ||
860 | share->num_peers); | ||
861 | |||
862 | /* Write the share. If 0 peers completed the dkg, an empty | ||
863 | * share will be sent. */ | ||
864 | |||
865 | GNUNET_assert (GNUNET_OK == GNUNET_SECRETSHARING_share_write (share, NULL, 0, | ||
866 | &share_size)); | ||
867 | |||
868 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "writing share of size %u\n", | ||
869 | (unsigned int) share_size); | ||
870 | |||
871 | ev = GNUNET_MQ_msg_extra (m, share_size, | ||
872 | GNUNET_MESSAGE_TYPE_SECRETSHARING_CLIENT_SECRET_READY); | ||
873 | |||
874 | GNUNET_assert (GNUNET_OK == GNUNET_SECRETSHARING_share_write (share, &m[1], | ||
875 | share_size, | ||
876 | NULL)); | ||
877 | |||
878 | GNUNET_SECRETSHARING_share_destroy (share); | ||
879 | share = NULL; | ||
880 | |||
881 | GNUNET_MQ_send (ks->cs->mq, | ||
882 | ev); | ||
883 | } | ||
884 | |||
885 | |||
886 | static void | ||
887 | restore_fair (const struct GNUNET_CRYPTO_PaillierPublicKey *ppub, | ||
888 | const struct GNUNET_SECRETSHARING_FairEncryption *fe, | ||
889 | gcry_mpi_t x, gcry_mpi_t xres) | ||
890 | { | ||
891 | gcry_mpi_t a_1; | ||
892 | gcry_mpi_t a_2; | ||
893 | gcry_mpi_t b_1; | ||
894 | gcry_mpi_t b_2; | ||
895 | gcry_mpi_t big_a; | ||
896 | gcry_mpi_t big_b; | ||
897 | gcry_mpi_t big_t; | ||
898 | gcry_mpi_t n; | ||
899 | gcry_mpi_t t_1; | ||
900 | gcry_mpi_t t_2; | ||
901 | gcry_mpi_t t; | ||
902 | gcry_mpi_t r; | ||
903 | gcry_mpi_t v; | ||
904 | |||
905 | |||
906 | GNUNET_assert (NULL != (n = gcry_mpi_new (0))); | ||
907 | GNUNET_assert (NULL != (t = gcry_mpi_new (0))); | ||
908 | GNUNET_assert (NULL != (t_1 = gcry_mpi_new (0))); | ||
909 | GNUNET_assert (NULL != (t_2 = gcry_mpi_new (0))); | ||
910 | GNUNET_assert (NULL != (r = gcry_mpi_new (0))); | ||
911 | GNUNET_assert (NULL != (big_t = gcry_mpi_new (0))); | ||
912 | GNUNET_assert (NULL != (v = gcry_mpi_new (0))); | ||
913 | GNUNET_assert (NULL != (big_a = gcry_mpi_new (0))); | ||
914 | GNUNET_assert (NULL != (big_b = gcry_mpi_new (0))); | ||
915 | |||
916 | // a = (N,0)^T | ||
917 | GNUNET_CRYPTO_mpi_scan_unsigned (&a_1, | ||
918 | ppub, | ||
919 | sizeof(struct | ||
920 | GNUNET_CRYPTO_PaillierPublicKey)); | ||
921 | GNUNET_assert (NULL != (a_2 = gcry_mpi_new (0))); | ||
922 | gcry_mpi_set_ui (a_2, 0); | ||
923 | // b = (x,1)^T | ||
924 | GNUNET_assert (NULL != (b_1 = gcry_mpi_new (0))); | ||
925 | gcry_mpi_set (b_1, x); | ||
926 | GNUNET_assert (NULL != (b_2 = gcry_mpi_new (0))); | ||
927 | gcry_mpi_set_ui (b_2, 1); | ||
928 | |||
929 | // A = a DOT a | ||
930 | gcry_mpi_mul (t, a_1, a_1); | ||
931 | gcry_mpi_mul (big_a, a_2, a_2); | ||
932 | gcry_mpi_add (big_a, big_a, t); | ||
933 | |||
934 | // B = b DOT b | ||
935 | gcry_mpi_mul (t, b_1, b_1); | ||
936 | gcry_mpi_mul (big_b, b_2, b_2); | ||
937 | gcry_mpi_add (big_b, big_b, t); | ||
938 | |||
939 | while (1) | ||
940 | { | ||
941 | // n = a DOT b | ||
942 | gcry_mpi_mul (t, a_1, b_1); | ||
943 | gcry_mpi_mul (n, a_2, b_2); | ||
944 | gcry_mpi_add (n, n, t); | ||
945 | |||
946 | // r = nearest(n/B) | ||
947 | gcry_mpi_div (r, NULL, n, big_b, 0); | ||
948 | |||
949 | // T := A - 2rn + rrB | ||
950 | gcry_mpi_mul (v, r, n); | ||
951 | gcry_mpi_mul_ui (v, v, 2); | ||
952 | gcry_mpi_sub (big_t, big_a, v); | ||
953 | gcry_mpi_mul (v, r, r); | ||
954 | gcry_mpi_mul (v, v, big_b); | ||
955 | gcry_mpi_add (big_t, big_t, v); | ||
956 | |||
957 | if (gcry_mpi_cmp (big_t, big_b) >= 0) | ||
958 | { | ||
959 | break; | ||
960 | } | ||
961 | |||
962 | // t = a - rb | ||
963 | gcry_mpi_mul (v, r, b_1); | ||
964 | gcry_mpi_sub (t_1, a_1, v); | ||
965 | gcry_mpi_mul (v, r, b_2); | ||
966 | gcry_mpi_sub (t_2, a_2, v); | ||
967 | |||
968 | // a = b | ||
969 | gcry_mpi_set (a_1, b_1); | ||
970 | gcry_mpi_set (a_2, b_2); | ||
971 | // b = t | ||
972 | gcry_mpi_set (b_1, t_1); | ||
973 | gcry_mpi_set (b_2, t_2); | ||
974 | |||
975 | gcry_mpi_set (big_a, big_b); | ||
976 | gcry_mpi_set (big_b, big_t); | ||
977 | } | ||
978 | |||
979 | gcry_mpi_set (xres, b_2); | ||
980 | gcry_mpi_invm (xres, xres, elgamal_q); | ||
981 | gcry_mpi_mulm (xres, xres, b_1, elgamal_q); | ||
982 | |||
983 | gcry_mpi_release (a_1); | ||
984 | gcry_mpi_release (a_2); | ||
985 | gcry_mpi_release (b_1); | ||
986 | gcry_mpi_release (b_2); | ||
987 | gcry_mpi_release (big_a); | ||
988 | gcry_mpi_release (big_b); | ||
989 | gcry_mpi_release (big_t); | ||
990 | gcry_mpi_release (n); | ||
991 | gcry_mpi_release (t_1); | ||
992 | gcry_mpi_release (t_2); | ||
993 | gcry_mpi_release (t); | ||
994 | gcry_mpi_release (r); | ||
995 | gcry_mpi_release (v); | ||
996 | } | ||
997 | |||
998 | |||
999 | static void | ||
1000 | get_fair_encryption_challenge (const struct | ||
1001 | GNUNET_SECRETSHARING_FairEncryption *fe, | ||
1002 | gcry_mpi_t *e) | ||
1003 | { | ||
1004 | struct | ||
1005 | { | ||
1006 | struct GNUNET_CRYPTO_PaillierCiphertext c; | ||
1007 | char h[GNUNET_SECRETSHARING_ELGAMAL_BITS / 8]; | ||
1008 | char t1[GNUNET_SECRETSHARING_ELGAMAL_BITS / 8]; | ||
1009 | char t2[GNUNET_CRYPTO_PAILLIER_BITS * 2 / 8]; | ||
1010 | } hash_data; | ||
1011 | struct GNUNET_HashCode e_hash; | ||
1012 | |||
1013 | memset (&hash_data, | ||
1014 | 0, | ||
1015 | sizeof(hash_data)); | ||
1016 | GNUNET_memcpy (&hash_data.c, &fe->c, sizeof(struct | ||
1017 | GNUNET_CRYPTO_PaillierCiphertext)); | ||
1018 | GNUNET_memcpy (&hash_data.h, &fe->h, GNUNET_SECRETSHARING_ELGAMAL_BITS / 8); | ||
1019 | GNUNET_memcpy (&hash_data.t1, &fe->t1, GNUNET_SECRETSHARING_ELGAMAL_BITS / 8); | ||
1020 | GNUNET_memcpy (&hash_data.t2, &fe->t2, GNUNET_CRYPTO_PAILLIER_BITS * 2 / 8); | ||
1021 | GNUNET_CRYPTO_hash (&hash_data, | ||
1022 | sizeof(hash_data), | ||
1023 | &e_hash); | ||
1024 | /* This allocates "e" */ | ||
1025 | GNUNET_CRYPTO_mpi_scan_unsigned (e, | ||
1026 | &e_hash, | ||
1027 | sizeof(struct GNUNET_HashCode)); | ||
1028 | gcry_mpi_mod (*e, *e, elgamal_q); | ||
1029 | } | ||
1030 | |||
1031 | |||
1032 | static int | ||
1033 | verify_fair (const struct GNUNET_CRYPTO_PaillierPublicKey *ppub, | ||
1034 | const struct GNUNET_SECRETSHARING_FairEncryption *fe) | ||
1035 | { | ||
1036 | gcry_mpi_t n; | ||
1037 | gcry_mpi_t n_sq; | ||
1038 | gcry_mpi_t z; | ||
1039 | gcry_mpi_t t1; | ||
1040 | gcry_mpi_t t2; | ||
1041 | gcry_mpi_t e; | ||
1042 | gcry_mpi_t w; | ||
1043 | gcry_mpi_t tmp1; | ||
1044 | gcry_mpi_t tmp2; | ||
1045 | gcry_mpi_t y; | ||
1046 | gcry_mpi_t big_y; | ||
1047 | int res; | ||
1048 | |||
1049 | GNUNET_assert (NULL != (n_sq = gcry_mpi_new (0))); | ||
1050 | GNUNET_assert (NULL != (tmp1 = gcry_mpi_new (0))); | ||
1051 | GNUNET_assert (NULL != (tmp2 = gcry_mpi_new (0))); | ||
1052 | |||
1053 | get_fair_encryption_challenge (fe, | ||
1054 | &e /* this allocates e */); | ||
1055 | |||
1056 | GNUNET_CRYPTO_mpi_scan_unsigned (&n, | ||
1057 | ppub, | ||
1058 | sizeof(struct | ||
1059 | GNUNET_CRYPTO_PaillierPublicKey)); | ||
1060 | GNUNET_CRYPTO_mpi_scan_unsigned (&t1, fe->t1, GNUNET_CRYPTO_PAILLIER_BITS | ||
1061 | / 8); | ||
1062 | GNUNET_CRYPTO_mpi_scan_unsigned (&z, fe->z, | ||
1063 | GNUNET_SECRETSHARING_ELGAMAL_BITS / 8); | ||
1064 | GNUNET_CRYPTO_mpi_scan_unsigned (&y, fe->h, | ||
1065 | GNUNET_SECRETSHARING_ELGAMAL_BITS / 8); | ||
1066 | GNUNET_CRYPTO_mpi_scan_unsigned (&w, fe->w, GNUNET_CRYPTO_PAILLIER_BITS / 8); | ||
1067 | GNUNET_CRYPTO_mpi_scan_unsigned (&big_y, fe->c.bits, | ||
1068 | GNUNET_CRYPTO_PAILLIER_BITS * 2 / 8); | ||
1069 | GNUNET_CRYPTO_mpi_scan_unsigned (&t2, fe->t2, GNUNET_CRYPTO_PAILLIER_BITS | ||
1070 | * 2 / 8); | ||
1071 | gcry_mpi_mul (n_sq, n, n); | ||
1072 | |||
1073 | // tmp1 = g^z | ||
1074 | gcry_mpi_powm (tmp1, elgamal_g, z, elgamal_p); | ||
1075 | // tmp2 = y^{-e} | ||
1076 | gcry_mpi_powm (tmp1, y, e, elgamal_p); | ||
1077 | gcry_mpi_invm (tmp1, tmp1, elgamal_p); | ||
1078 | // tmp1 = tmp1 * tmp2 | ||
1079 | gcry_mpi_mulm (tmp1, tmp1, tmp2, elgamal_p); | ||
1080 | |||
1081 | if (0 == gcry_mpi_cmp (t1, tmp1)) | ||
1082 | { | ||
1083 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "fair encryption invalid (t1)\n"); | ||
1084 | res = GNUNET_NO; | ||
1085 | goto cleanup; | ||
1086 | } | ||
1087 | |||
1088 | gcry_mpi_powm (big_y, big_y, e, n_sq); | ||
1089 | gcry_mpi_invm (big_y, big_y, n_sq); | ||
1090 | |||
1091 | gcry_mpi_add_ui (tmp1, n, 1); | ||
1092 | gcry_mpi_powm (tmp1, tmp1, z, n_sq); | ||
1093 | |||
1094 | gcry_mpi_powm (tmp2, w, n, n_sq); | ||
1095 | |||
1096 | gcry_mpi_mulm (tmp1, tmp1, tmp2, n_sq); | ||
1097 | gcry_mpi_mulm (tmp1, tmp1, big_y, n_sq); | ||
1098 | |||
1099 | |||
1100 | if (0 == gcry_mpi_cmp (t2, tmp1)) | ||
1101 | { | ||
1102 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "fair encryption invalid (t2)\n"); | ||
1103 | res = GNUNET_NO; | ||
1104 | goto cleanup; | ||
1105 | } | ||
1106 | |||
1107 | res = GNUNET_YES; | ||
1108 | |||
1109 | cleanup: | ||
1110 | |||
1111 | gcry_mpi_release (n); | ||
1112 | gcry_mpi_release (n_sq); | ||
1113 | gcry_mpi_release (z); | ||
1114 | gcry_mpi_release (t1); | ||
1115 | gcry_mpi_release (t2); | ||
1116 | gcry_mpi_release (e); | ||
1117 | gcry_mpi_release (w); | ||
1118 | gcry_mpi_release (tmp1); | ||
1119 | gcry_mpi_release (tmp2); | ||
1120 | gcry_mpi_release (y); | ||
1121 | gcry_mpi_release (big_y); | ||
1122 | return res; | ||
1123 | } | ||
1124 | |||
1125 | |||
1126 | /** | ||
1127 | * Create a fair Paillier encryption of then given ciphertext. | ||
1128 | * | ||
1129 | * @param v the ciphertext | ||
1130 | * @param[out] fe the fair encryption | ||
1131 | */ | ||
1132 | static void | ||
1133 | encrypt_fair (gcry_mpi_t v, | ||
1134 | const struct GNUNET_CRYPTO_PaillierPublicKey *ppub, | ||
1135 | struct GNUNET_SECRETSHARING_FairEncryption *fe) | ||
1136 | { | ||
1137 | gcry_mpi_t r; | ||
1138 | gcry_mpi_t s; | ||
1139 | gcry_mpi_t t1; | ||
1140 | gcry_mpi_t t2; | ||
1141 | gcry_mpi_t z; | ||
1142 | gcry_mpi_t w; | ||
1143 | gcry_mpi_t n; | ||
1144 | gcry_mpi_t e; | ||
1145 | gcry_mpi_t n_sq; | ||
1146 | gcry_mpi_t u; | ||
1147 | gcry_mpi_t Y; | ||
1148 | gcry_mpi_t G; | ||
1149 | gcry_mpi_t h; | ||
1150 | |||
1151 | GNUNET_assert (NULL != (r = gcry_mpi_new (0))); | ||
1152 | GNUNET_assert (NULL != (s = gcry_mpi_new (0))); | ||
1153 | GNUNET_assert (NULL != (t1 = gcry_mpi_new (0))); | ||
1154 | GNUNET_assert (NULL != (t2 = gcry_mpi_new (0))); | ||
1155 | GNUNET_assert (NULL != (z = gcry_mpi_new (0))); | ||
1156 | GNUNET_assert (NULL != (w = gcry_mpi_new (0))); | ||
1157 | GNUNET_assert (NULL != (n_sq = gcry_mpi_new (0))); | ||
1158 | GNUNET_assert (NULL != (u = gcry_mpi_new (0))); | ||
1159 | GNUNET_assert (NULL != (Y = gcry_mpi_new (0))); | ||
1160 | GNUNET_assert (NULL != (G = gcry_mpi_new (0))); | ||
1161 | GNUNET_assert (NULL != (h = gcry_mpi_new (0))); | ||
1162 | |||
1163 | GNUNET_CRYPTO_mpi_scan_unsigned (&n, | ||
1164 | ppub, | ||
1165 | sizeof(struct | ||
1166 | GNUNET_CRYPTO_PaillierPublicKey)); | ||
1167 | gcry_mpi_mul (n_sq, n, n); | ||
1168 | gcry_mpi_add_ui (G, n, 1); | ||
1169 | |||
1170 | do | ||
1171 | { | ||
1172 | gcry_mpi_randomize (u, GNUNET_CRYPTO_PAILLIER_BITS, GCRY_WEAK_RANDOM); | ||
1173 | } | ||
1174 | while (gcry_mpi_cmp (u, n) >= 0); | ||
1175 | |||
1176 | gcry_mpi_powm (t1, G, v, n_sq); | ||
1177 | gcry_mpi_powm (t2, u, n, n_sq); | ||
1178 | gcry_mpi_mulm (Y, t1, t2, n_sq); | ||
1179 | |||
1180 | GNUNET_CRYPTO_mpi_print_unsigned (fe->c.bits, | ||
1181 | sizeof fe->c.bits, | ||
1182 | Y); | ||
1183 | |||
1184 | |||
1185 | gcry_mpi_randomize (r, 2048, GCRY_WEAK_RANDOM); | ||
1186 | do | ||
1187 | { | ||
1188 | gcry_mpi_randomize (s, GNUNET_CRYPTO_PAILLIER_BITS, GCRY_WEAK_RANDOM); | ||
1189 | } | ||
1190 | while (gcry_mpi_cmp (s, n) >= 0); | ||
1191 | |||
1192 | // compute t1 | ||
1193 | gcry_mpi_mulm (t1, elgamal_g, r, elgamal_p); | ||
1194 | // compute t2 (use z and w as temp) | ||
1195 | gcry_mpi_powm (z, G, r, n_sq); | ||
1196 | gcry_mpi_powm (w, s, n, n_sq); | ||
1197 | gcry_mpi_mulm (t2, z, w, n_sq); | ||
1198 | |||
1199 | |||
1200 | gcry_mpi_powm (h, elgamal_g, v, elgamal_p); | ||
1201 | |||
1202 | GNUNET_CRYPTO_mpi_print_unsigned (fe->h, | ||
1203 | GNUNET_SECRETSHARING_ELGAMAL_BITS / 8, | ||
1204 | h); | ||
1205 | |||
1206 | GNUNET_CRYPTO_mpi_print_unsigned (fe->t1, | ||
1207 | GNUNET_SECRETSHARING_ELGAMAL_BITS / 8, | ||
1208 | t1); | ||
1209 | |||
1210 | GNUNET_CRYPTO_mpi_print_unsigned (fe->t2, | ||
1211 | GNUNET_CRYPTO_PAILLIER_BITS * 2 / 8, | ||
1212 | t2); | ||
1213 | |||
1214 | get_fair_encryption_challenge (fe, | ||
1215 | &e /* This allocates "e" */); | ||
1216 | |||
1217 | // compute z | ||
1218 | gcry_mpi_mul (z, e, v); | ||
1219 | gcry_mpi_addm (z, z, r, elgamal_q); | ||
1220 | // compute w | ||
1221 | gcry_mpi_powm (w, u, e, n); | ||
1222 | gcry_mpi_mulm (w, w, s, n); | ||
1223 | |||
1224 | GNUNET_CRYPTO_mpi_print_unsigned (fe->z, | ||
1225 | GNUNET_SECRETSHARING_ELGAMAL_BITS / 8, | ||
1226 | z); | ||
1227 | |||
1228 | GNUNET_CRYPTO_mpi_print_unsigned (fe->w, | ||
1229 | GNUNET_CRYPTO_PAILLIER_BITS / 8, | ||
1230 | w); | ||
1231 | |||
1232 | gcry_mpi_release (n); | ||
1233 | gcry_mpi_release (r); | ||
1234 | gcry_mpi_release (s); | ||
1235 | gcry_mpi_release (t1); | ||
1236 | gcry_mpi_release (t2); | ||
1237 | gcry_mpi_release (z); | ||
1238 | gcry_mpi_release (w); | ||
1239 | gcry_mpi_release (e); | ||
1240 | gcry_mpi_release (n_sq); | ||
1241 | gcry_mpi_release (u); | ||
1242 | gcry_mpi_release (Y); | ||
1243 | gcry_mpi_release (G); | ||
1244 | gcry_mpi_release (h); | ||
1245 | } | ||
1246 | |||
1247 | |||
1248 | /** | ||
1249 | * Insert round 2 element in the consensus, consisting of | ||
1250 | * (1) The exponentiated pre-share polynomial coefficients A_{i,l}=g^{a_{i,l}} | ||
1251 | * (2) The exponentiated pre-shares y_{i,j}=g^{s_{i,j}} | ||
1252 | * (3) The encrypted pre-shares Y_{i,j} | ||
1253 | * (4) The zero knowledge proof for fairness of | ||
1254 | * the encryption | ||
1255 | * | ||
1256 | * @param ks session to use | ||
1257 | */ | ||
1258 | static void | ||
1259 | insert_round2_element (struct KeygenSession *ks) | ||
1260 | { | ||
1261 | struct GNUNET_SET_Element *element; | ||
1262 | struct GNUNET_SECRETSHARING_KeygenRevealData *d; | ||
1263 | unsigned char *pos; | ||
1264 | unsigned char *last_pos; | ||
1265 | size_t element_size; | ||
1266 | unsigned int i; | ||
1267 | gcry_mpi_t idx; | ||
1268 | gcry_mpi_t v; | ||
1269 | |||
1270 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "P%u: Inserting round2 element\n", | ||
1271 | ks->local_peer_idx); | ||
1272 | |||
1273 | GNUNET_assert (NULL != (v = gcry_mpi_new ( | ||
1274 | GNUNET_SECRETSHARING_ELGAMAL_BITS))); | ||
1275 | GNUNET_assert (NULL != (idx = gcry_mpi_new ( | ||
1276 | GNUNET_SECRETSHARING_ELGAMAL_BITS))); | ||
1277 | |||
1278 | element_size = (sizeof(struct GNUNET_SECRETSHARING_KeygenRevealData) | ||
1279 | + sizeof(struct GNUNET_SECRETSHARING_FairEncryption) | ||
1280 | * ks->num_peers | ||
1281 | + GNUNET_SECRETSHARING_ELGAMAL_BITS / 8 * ks->threshold); | ||
1282 | |||
1283 | element = GNUNET_malloc (sizeof(struct GNUNET_SET_Element) + element_size); | ||
1284 | element->size = element_size; | ||
1285 | element->data = (void *) &element[1]; | ||
1286 | |||
1287 | d = (void *) element->data; | ||
1288 | d->peer = my_peer; | ||
1289 | |||
1290 | // start inserting vector elements | ||
1291 | // after the fixed part of the element's data | ||
1292 | pos = (void *) &d[1]; | ||
1293 | last_pos = pos + element_size; | ||
1294 | |||
1295 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "P%u: computed exp preshares\n", | ||
1296 | ks->local_peer_idx); | ||
1297 | |||
1298 | // encrypted pre-shares | ||
1299 | // and fair encryption proof | ||
1300 | { | ||
1301 | for (i = 0; i < ks->num_peers; i++) | ||
1302 | { | ||
1303 | ptrdiff_t remaining = last_pos - pos; | ||
1304 | struct GNUNET_SECRETSHARING_FairEncryption *fe = (void *) pos; | ||
1305 | |||
1306 | GNUNET_assert (remaining > 0); | ||
1307 | memset (fe, 0, sizeof *fe); | ||
1308 | if (GNUNET_YES == ks->info[i].round1_valid) | ||
1309 | { | ||
1310 | gcry_mpi_set_ui (idx, i + 1); | ||
1311 | // evaluate the polynomial | ||
1312 | horner_eval (v, ks->presecret_polynomial, ks->threshold, idx, | ||
1313 | elgamal_q); | ||
1314 | // encrypt the result | ||
1315 | encrypt_fair (v, &ks->info[i].paillier_public_key, fe); | ||
1316 | } | ||
1317 | pos += sizeof *fe; | ||
1318 | } | ||
1319 | } | ||
1320 | |||
1321 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "P%u: computed enc preshares\n", | ||
1322 | ks->local_peer_idx); | ||
1323 | |||
1324 | // exponentiated coefficients | ||
1325 | for (i = 0; i < ks->threshold; i++) | ||
1326 | { | ||
1327 | ptrdiff_t remaining = last_pos - pos; | ||
1328 | GNUNET_assert (remaining > 0); | ||
1329 | gcry_mpi_powm (v, elgamal_g, ks->presecret_polynomial[i], elgamal_p); | ||
1330 | GNUNET_CRYPTO_mpi_print_unsigned (pos, GNUNET_SECRETSHARING_ELGAMAL_BITS | ||
1331 | / 8, v); | ||
1332 | pos += GNUNET_SECRETSHARING_ELGAMAL_BITS / 8; | ||
1333 | } | ||
1334 | |||
1335 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "P%u: computed exp coefficients\n", | ||
1336 | ks->local_peer_idx); | ||
1337 | |||
1338 | |||
1339 | d->purpose.size = htonl (element_size - offsetof (struct | ||
1340 | GNUNET_SECRETSHARING_KeygenRevealData, | ||
1341 | purpose)); | ||
1342 | d->purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_SECRETSHARING_DKG2); | ||
1343 | GNUNET_assert (GNUNET_OK == | ||
1344 | GNUNET_CRYPTO_eddsa_sign_ (my_peer_private_key, | ||
1345 | &d->purpose, | ||
1346 | &d->signature)); | ||
1347 | |||
1348 | GNUNET_CONSENSUS_insert (ks->consensus, element, NULL, NULL); | ||
1349 | GNUNET_free (element); /* FIXME: maybe stack-allocate instead? */ | ||
1350 | |||
1351 | gcry_mpi_release (v); | ||
1352 | gcry_mpi_release (idx); | ||
1353 | } | ||
1354 | |||
1355 | |||
1356 | static gcry_mpi_t | ||
1357 | keygen_reveal_get_exp_coeff (struct KeygenSession *ks, | ||
1358 | const struct | ||
1359 | GNUNET_SECRETSHARING_KeygenRevealData *d, | ||
1360 | unsigned int idx) | ||
1361 | { | ||
1362 | unsigned char *pos; | ||
1363 | gcry_mpi_t exp_coeff; | ||
1364 | |||
1365 | GNUNET_assert (idx < ks->threshold); | ||
1366 | |||
1367 | pos = (void *) &d[1]; | ||
1368 | // skip encrypted pre-shares | ||
1369 | pos += sizeof(struct GNUNET_SECRETSHARING_FairEncryption) * ks->num_peers; | ||
1370 | // skip exp. coeffs we are not interested in | ||
1371 | pos += GNUNET_SECRETSHARING_ELGAMAL_BITS / 8 * idx; | ||
1372 | // the first exponentiated coefficient is the public key share | ||
1373 | GNUNET_CRYPTO_mpi_scan_unsigned (&exp_coeff, pos, | ||
1374 | GNUNET_SECRETSHARING_ELGAMAL_BITS / 8); | ||
1375 | return exp_coeff; | ||
1376 | } | ||
1377 | |||
1378 | |||
1379 | static struct GNUNET_SECRETSHARING_FairEncryption * | ||
1380 | keygen_reveal_get_enc_preshare (struct KeygenSession *ks, | ||
1381 | const struct | ||
1382 | GNUNET_SECRETSHARING_KeygenRevealData *d, | ||
1383 | unsigned int idx) | ||
1384 | { | ||
1385 | unsigned char *pos; | ||
1386 | |||
1387 | GNUNET_assert (idx < ks->num_peers); | ||
1388 | |||
1389 | pos = (void *) &d[1]; | ||
1390 | // skip encrypted pre-shares we're not interested in | ||
1391 | pos += sizeof(struct GNUNET_SECRETSHARING_FairEncryption) * idx; | ||
1392 | return (struct GNUNET_SECRETSHARING_FairEncryption *) pos; | ||
1393 | } | ||
1394 | |||
1395 | |||
1396 | static gcry_mpi_t | ||
1397 | keygen_reveal_get_exp_preshare (struct KeygenSession *ks, | ||
1398 | const struct | ||
1399 | GNUNET_SECRETSHARING_KeygenRevealData *d, | ||
1400 | unsigned int idx) | ||
1401 | { | ||
1402 | gcry_mpi_t exp_preshare; | ||
1403 | struct GNUNET_SECRETSHARING_FairEncryption *fe; | ||
1404 | |||
1405 | GNUNET_assert (idx < ks->num_peers); | ||
1406 | fe = keygen_reveal_get_enc_preshare (ks, d, idx); | ||
1407 | GNUNET_CRYPTO_mpi_scan_unsigned (&exp_preshare, fe->h, | ||
1408 | GNUNET_SECRETSHARING_ELGAMAL_BITS / 8); | ||
1409 | return exp_preshare; | ||
1410 | } | ||
1411 | |||
1412 | |||
1413 | static void | ||
1414 | keygen_round2_new_element (void *cls, | ||
1415 | const struct GNUNET_SET_Element *element) | ||
1416 | { | ||
1417 | struct KeygenSession *ks = cls; | ||
1418 | const struct GNUNET_SECRETSHARING_KeygenRevealData *d; | ||
1419 | struct KeygenPeerInfo *info; | ||
1420 | size_t expected_element_size; | ||
1421 | unsigned int j; | ||
1422 | int cmp_result; | ||
1423 | gcry_mpi_t tmp; | ||
1424 | gcry_mpi_t public_key_share; | ||
1425 | gcry_mpi_t preshare; | ||
1426 | |||
1427 | if (NULL == element) | ||
1428 | { | ||
1429 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "round2 consensus failed\n"); | ||
1430 | return; | ||
1431 | } | ||
1432 | |||
1433 | expected_element_size = (sizeof(struct GNUNET_SECRETSHARING_KeygenRevealData) | ||
1434 | + sizeof(struct | ||
1435 | GNUNET_SECRETSHARING_FairEncryption) | ||
1436 | * ks->num_peers | ||
1437 | + GNUNET_SECRETSHARING_ELGAMAL_BITS / 8 | ||
1438 | * ks->threshold); | ||
1439 | |||
1440 | if (element->size != expected_element_size) | ||
1441 | { | ||
1442 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | ||
1443 | "keygen round2 data with wrong size (%u) in consensus, %u expected\n", | ||
1444 | (unsigned int) element->size, | ||
1445 | (unsigned int) expected_element_size); | ||
1446 | return; | ||
1447 | } | ||
1448 | |||
1449 | d = (const void *) element->data; | ||
1450 | |||
1451 | info = get_keygen_peer_info (ks, &d->peer); | ||
1452 | |||
1453 | if (NULL == info) | ||
1454 | { | ||
1455 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | ||
1456 | "keygen commit data with wrong peer identity (%s) in consensus\n", | ||
1457 | GNUNET_i2s (&d->peer)); | ||
1458 | return; | ||
1459 | } | ||
1460 | |||
1461 | if (GNUNET_NO == info->round1_valid) | ||
1462 | { | ||
1463 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | ||
1464 | "ignoring round2 element from peer with invalid round1 element (%s)\n", | ||
1465 | GNUNET_i2s (&d->peer)); | ||
1466 | return; | ||
1467 | } | ||
1468 | |||
1469 | if (GNUNET_YES == info->round2_valid) | ||
1470 | { | ||
1471 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | ||
1472 | "ignoring duplicate round2 element (%s)\n", | ||
1473 | GNUNET_i2s (&d->peer)); | ||
1474 | return; | ||
1475 | } | ||
1476 | |||
1477 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, "got round2 element\n"); | ||
1478 | |||
1479 | if (ntohl (d->purpose.size) != | ||
1480 | element->size - offsetof (struct GNUNET_SECRETSHARING_KeygenRevealData, | ||
1481 | purpose)) | ||
1482 | { | ||
1483 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | ||
1484 | "keygen reveal data with wrong signature purpose size in consensus\n"); | ||
1485 | return; | ||
1486 | } | ||
1487 | |||
1488 | if (GNUNET_OK != GNUNET_CRYPTO_eddsa_verify_ ( | ||
1489 | GNUNET_SIGNATURE_PURPOSE_SECRETSHARING_DKG2, | ||
1490 | &d->purpose, &d->signature, | ||
1491 | &d->peer.public_key)) | ||
1492 | { | ||
1493 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | ||
1494 | "keygen reveal data with invalid signature in consensus\n"); | ||
1495 | return; | ||
1496 | } | ||
1497 | |||
1498 | public_key_share = keygen_reveal_get_exp_coeff (ks, d, 0); | ||
1499 | info->preshare_commitment = keygen_reveal_get_exp_preshare (ks, d, | ||
1500 | ks->local_peer_idx); | ||
1501 | |||
1502 | if (NULL == ks->public_key) | ||
1503 | { | ||
1504 | GNUNET_assert (NULL != (ks->public_key = gcry_mpi_new (0))); | ||
1505 | gcry_mpi_set_ui (ks->public_key, 1); | ||
1506 | } | ||
1507 | gcry_mpi_mulm (ks->public_key, ks->public_key, public_key_share, elgamal_p); | ||
1508 | |||
1509 | gcry_mpi_release (public_key_share); | ||
1510 | public_key_share = NULL; | ||
1511 | |||
1512 | { | ||
1513 | struct GNUNET_SECRETSHARING_FairEncryption *fe = | ||
1514 | keygen_reveal_get_enc_preshare (ks, d, ks->local_peer_idx); | ||
1515 | GNUNET_assert (NULL != (preshare = gcry_mpi_new (0))); | ||
1516 | GNUNET_CRYPTO_paillier_decrypt (&ks->paillier_private_key, | ||
1517 | &ks->info[ks->local_peer_idx]. | ||
1518 | paillier_public_key, | ||
1519 | &fe->c, | ||
1520 | preshare); | ||
1521 | |||
1522 | // FIXME: not doing the restoration is less expensive | ||
1523 | restore_fair (&ks->info[ks->local_peer_idx].paillier_public_key, | ||
1524 | fe, | ||
1525 | preshare, | ||
1526 | preshare); | ||
1527 | } | ||
1528 | |||
1529 | GNUNET_assert (NULL != (tmp = gcry_mpi_new (0))); | ||
1530 | gcry_mpi_powm (tmp, elgamal_g, preshare, elgamal_p); | ||
1531 | |||
1532 | cmp_result = gcry_mpi_cmp (tmp, info->preshare_commitment); | ||
1533 | gcry_mpi_release (tmp); | ||
1534 | tmp = NULL; | ||
1535 | if (0 != cmp_result) | ||
1536 | { | ||
1537 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | ||
1538 | "P%u: Got invalid presecret from P%u\n", | ||
1539 | (unsigned int) ks->local_peer_idx, (unsigned int) (info | ||
1540 | - ks->info)); | ||
1541 | return; | ||
1542 | } | ||
1543 | |||
1544 | if (NULL == ks->my_share) | ||
1545 | { | ||
1546 | GNUNET_assert (NULL != (ks->my_share = gcry_mpi_new (0))); | ||
1547 | } | ||
1548 | gcry_mpi_addm (ks->my_share, ks->my_share, preshare, elgamal_q); | ||
1549 | |||
1550 | for (j = 0; j < ks->num_peers; j++) | ||
1551 | { | ||
1552 | gcry_mpi_t presigma; | ||
1553 | if (NULL == ks->info[j].sigma) | ||
1554 | { | ||
1555 | GNUNET_assert (NULL != (ks->info[j].sigma = gcry_mpi_new (0))); | ||
1556 | gcry_mpi_set_ui (ks->info[j].sigma, 1); | ||
1557 | } | ||
1558 | presigma = keygen_reveal_get_exp_preshare (ks, d, j); | ||
1559 | gcry_mpi_mulm (ks->info[j].sigma, ks->info[j].sigma, presigma, elgamal_p); | ||
1560 | gcry_mpi_release (presigma); | ||
1561 | } | ||
1562 | |||
1563 | gcry_mpi_t prod; | ||
1564 | GNUNET_assert (NULL != (prod = gcry_mpi_new (0))); | ||
1565 | gcry_mpi_t j_to_k; | ||
1566 | GNUNET_assert (NULL != (j_to_k = gcry_mpi_new (0))); | ||
1567 | // validate that the polynomial sharing matches the additive sharing | ||
1568 | for (j = 0; j < ks->num_peers; j++) | ||
1569 | { | ||
1570 | unsigned int k; | ||
1571 | int cmp_result; | ||
1572 | gcry_mpi_t exp_preshare; | ||
1573 | gcry_mpi_set_ui (prod, 1); | ||
1574 | for (k = 0; k < ks->threshold; k++) | ||
1575 | { | ||
1576 | // Using pow(double,double) is a bit sketchy. | ||
1577 | // We count players from 1, but shares from 0. | ||
1578 | gcry_mpi_t tmp; | ||
1579 | gcry_mpi_set_ui (j_to_k, (unsigned int) pow (j + 1, k)); | ||
1580 | tmp = keygen_reveal_get_exp_coeff (ks, d, k); | ||
1581 | gcry_mpi_powm (tmp, tmp, j_to_k, elgamal_p); | ||
1582 | gcry_mpi_mulm (prod, prod, tmp, elgamal_p); | ||
1583 | gcry_mpi_release (tmp); | ||
1584 | } | ||
1585 | exp_preshare = keygen_reveal_get_exp_preshare (ks, d, j); | ||
1586 | gcry_mpi_mod (exp_preshare, exp_preshare, elgamal_p); | ||
1587 | cmp_result = gcry_mpi_cmp (prod, exp_preshare); | ||
1588 | gcry_mpi_release (exp_preshare); | ||
1589 | exp_preshare = NULL; | ||
1590 | if (0 != cmp_result) | ||
1591 | { | ||
1592 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | ||
1593 | "P%u: reveal data from P%u incorrect\n", | ||
1594 | ks->local_peer_idx, j); | ||
1595 | /* no need for further verification, round2 stays invalid ... */ | ||
1596 | return; | ||
1597 | } | ||
1598 | } | ||
1599 | |||
1600 | // TODO: verify proof of fair encryption (once implemented) | ||
1601 | for (j = 0; j < ks->num_peers; j++) | ||
1602 | { | ||
1603 | struct GNUNET_SECRETSHARING_FairEncryption *fe = | ||
1604 | keygen_reveal_get_enc_preshare (ks, d, j); | ||
1605 | if (GNUNET_YES != verify_fair (&ks->info[j].paillier_public_key, fe)) | ||
1606 | { | ||
1607 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | ||
1608 | "P%u: reveal data from P%u incorrect (fair encryption)\n", | ||
1609 | ks->local_peer_idx, j); | ||
1610 | return; | ||
1611 | } | ||
1612 | } | ||
1613 | |||
1614 | info->round2_valid = GNUNET_YES; | ||
1615 | |||
1616 | gcry_mpi_release (preshare); | ||
1617 | gcry_mpi_release (prod); | ||
1618 | gcry_mpi_release (j_to_k); | ||
1619 | } | ||
1620 | |||
1621 | |||
1622 | /** | ||
1623 | * Called when the first consensus round has concluded. | ||
1624 | * Will initiate the second round. | ||
1625 | * | ||
1626 | * @param cls closure | ||
1627 | */ | ||
1628 | static void | ||
1629 | keygen_round1_conclude (void *cls) | ||
1630 | { | ||
1631 | struct KeygenSession *ks = cls; | ||
1632 | |||
1633 | GNUNET_CONSENSUS_destroy (ks->consensus); | ||
1634 | |||
1635 | ks->consensus = GNUNET_CONSENSUS_create (cfg, ks->num_peers, ks->peers, | ||
1636 | &ks->session_id, | ||
1637 | time_between (ks->start_time, | ||
1638 | ks->deadline, 1, 2), | ||
1639 | ks->deadline, | ||
1640 | keygen_round2_new_element, ks); | ||
1641 | |||
1642 | insert_round2_element (ks); | ||
1643 | |||
1644 | GNUNET_CONSENSUS_conclude (ks->consensus, | ||
1645 | keygen_round2_conclude, | ||
1646 | ks); | ||
1647 | } | ||
1648 | |||
1649 | |||
1650 | /** | ||
1651 | * Insert the ephemeral key and the presecret commitment | ||
1652 | * of this peer in the consensus of the given session. | ||
1653 | * | ||
1654 | * @param ks session to use | ||
1655 | */ | ||
1656 | static void | ||
1657 | insert_round1_element (struct KeygenSession *ks) | ||
1658 | { | ||
1659 | struct GNUNET_SET_Element *element; | ||
1660 | struct GNUNET_SECRETSHARING_KeygenCommitData *d; | ||
1661 | // g^a_{i,0} | ||
1662 | gcry_mpi_t v; | ||
1663 | // big-endian representation of 'v' | ||
1664 | unsigned char v_data[GNUNET_SECRETSHARING_ELGAMAL_BITS / 8]; | ||
1665 | |||
1666 | element = GNUNET_malloc (sizeof *element + sizeof *d); | ||
1667 | d = (void *) &element[1]; | ||
1668 | element->data = d; | ||
1669 | element->size = sizeof *d; | ||
1670 | |||
1671 | d->peer = my_peer; | ||
1672 | |||
1673 | GNUNET_assert (0 != (v = gcry_mpi_new (GNUNET_SECRETSHARING_ELGAMAL_BITS))); | ||
1674 | |||
1675 | gcry_mpi_powm (v, elgamal_g, ks->presecret_polynomial[0], elgamal_p); | ||
1676 | |||
1677 | GNUNET_CRYPTO_mpi_print_unsigned (v_data, GNUNET_SECRETSHARING_ELGAMAL_BITS | ||
1678 | / 8, v); | ||
1679 | |||
1680 | GNUNET_CRYPTO_hash (v_data, GNUNET_SECRETSHARING_ELGAMAL_BITS / 8, | ||
1681 | &d->commitment); | ||
1682 | |||
1683 | d->pubkey = ks->info[ks->local_peer_idx].paillier_public_key; | ||
1684 | |||
1685 | d->purpose.size = htonl ((sizeof *d) - offsetof (struct | ||
1686 | GNUNET_SECRETSHARING_KeygenCommitData, | ||
1687 | purpose)); | ||
1688 | d->purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_SECRETSHARING_DKG1); | ||
1689 | GNUNET_assert (GNUNET_OK == | ||
1690 | GNUNET_CRYPTO_eddsa_sign_ (my_peer_private_key, | ||
1691 | &d->purpose, | ||
1692 | &d->signature)); | ||
1693 | |||
1694 | GNUNET_CONSENSUS_insert (ks->consensus, element, NULL, NULL); | ||
1695 | |||
1696 | gcry_mpi_release (v); | ||
1697 | GNUNET_free (element); | ||
1698 | } | ||
1699 | |||
1700 | |||
1701 | /** | ||
1702 | * Check that @a msg is well-formed. | ||
1703 | * | ||
1704 | * @param cls identification of the client | ||
1705 | * @param msg the actual message | ||
1706 | * @return #GNUNET_OK if @a msg is well-formed | ||
1707 | */ | ||
1708 | static int | ||
1709 | check_client_keygen (void *cls, | ||
1710 | const struct GNUNET_SECRETSHARING_CreateMessage *msg) | ||
1711 | { | ||
1712 | unsigned int num_peers = ntohs (msg->num_peers); | ||
1713 | |||
1714 | if (ntohs (msg->header.size) - sizeof(*msg) != | ||
1715 | num_peers * sizeof(struct GNUNET_PeerIdentity)) | ||
1716 | { | ||
1717 | GNUNET_break (0); | ||
1718 | return GNUNET_SYSERR; | ||
1719 | } | ||
1720 | return GNUNET_OK; | ||
1721 | } | ||
1722 | |||
1723 | |||
1724 | /** | ||
1725 | * Functions with this signature are called whenever a message is | ||
1726 | * received. | ||
1727 | * | ||
1728 | * @param cls identification of the client | ||
1729 | * @param msg the actual message | ||
1730 | */ | ||
1731 | static void | ||
1732 | handle_client_keygen (void *cls, | ||
1733 | const struct GNUNET_SECRETSHARING_CreateMessage *msg) | ||
1734 | { | ||
1735 | struct ClientState *cs = cls; | ||
1736 | struct KeygenSession *ks; | ||
1737 | |||
1738 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, | ||
1739 | "client requested key generation\n"); | ||
1740 | if (NULL != cs->keygen_session) | ||
1741 | { | ||
1742 | GNUNET_break (0); | ||
1743 | GNUNET_SERVICE_client_drop (cs->client); | ||
1744 | return; | ||
1745 | } | ||
1746 | ks = GNUNET_new (struct KeygenSession); | ||
1747 | ks->cs = cs; | ||
1748 | cs->keygen_session = ks; | ||
1749 | ks->deadline = GNUNET_TIME_absolute_ntoh (msg->deadline); | ||
1750 | ks->threshold = ntohs (msg->threshold); | ||
1751 | ks->num_peers = ntohs (msg->num_peers); | ||
1752 | |||
1753 | ks->peers = normalize_peers ((struct GNUNET_PeerIdentity *) &msg[1], | ||
1754 | ks->num_peers, | ||
1755 | &ks->num_peers, | ||
1756 | &ks->local_peer_idx); | ||
1757 | |||
1758 | |||
1759 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, | ||
1760 | "first round of consensus with %u peers\n", | ||
1761 | ks->num_peers); | ||
1762 | ks->consensus = GNUNET_CONSENSUS_create (cfg, | ||
1763 | ks->num_peers, | ||
1764 | ks->peers, | ||
1765 | &msg->session_id, | ||
1766 | GNUNET_TIME_absolute_ntoh ( | ||
1767 | msg->start), | ||
1768 | GNUNET_TIME_absolute_ntoh ( | ||
1769 | msg->deadline), | ||
1770 | keygen_round1_new_element, | ||
1771 | ks); | ||
1772 | |||
1773 | ks->info = GNUNET_new_array (ks->num_peers, | ||
1774 | struct KeygenPeerInfo); | ||
1775 | |||
1776 | for (unsigned int i = 0; i < ks->num_peers; i++) | ||
1777 | ks->info[i].peer = ks->peers[i]; | ||
1778 | |||
1779 | GNUNET_CRYPTO_paillier_create ( | ||
1780 | &ks->info[ks->local_peer_idx].paillier_public_key, | ||
1781 | &ks->paillier_private_key); | ||
1782 | |||
1783 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1784 | "P%u: Generated paillier key pair\n", | ||
1785 | ks->local_peer_idx); | ||
1786 | generate_presecret_polynomial (ks); | ||
1787 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1788 | "P%u: Generated presecret polynomial\n", | ||
1789 | ks->local_peer_idx); | ||
1790 | insert_round1_element (ks); | ||
1791 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1792 | "P%u: Concluding for round 1\n", | ||
1793 | ks->local_peer_idx); | ||
1794 | GNUNET_CONSENSUS_conclude (ks->consensus, | ||
1795 | keygen_round1_conclude, | ||
1796 | ks); | ||
1797 | GNUNET_SERVICE_client_continue (cs->client); | ||
1798 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1799 | "P%u: Waiting for round 1 elements ...\n", | ||
1800 | ks->local_peer_idx); | ||
1801 | } | ||
1802 | |||
1803 | |||
1804 | /** | ||
1805 | * Called when the partial decryption consensus concludes. | ||
1806 | */ | ||
1807 | static void | ||
1808 | decrypt_conclude (void *cls) | ||
1809 | { | ||
1810 | struct DecryptSession *ds = cls; | ||
1811 | struct GNUNET_SECRETSHARING_DecryptResponseMessage *msg; | ||
1812 | struct GNUNET_MQ_Envelope *ev; | ||
1813 | gcry_mpi_t lagrange; | ||
1814 | gcry_mpi_t m; | ||
1815 | gcry_mpi_t tmp; | ||
1816 | gcry_mpi_t c_2; | ||
1817 | gcry_mpi_t prod; | ||
1818 | unsigned int *indices; | ||
1819 | unsigned int num; | ||
1820 | unsigned int i; | ||
1821 | unsigned int j; | ||
1822 | |||
1823 | GNUNET_CONSENSUS_destroy (ds->consensus); | ||
1824 | ds->consensus = NULL; | ||
1825 | |||
1826 | GNUNET_assert (0 != (lagrange = gcry_mpi_new (0))); | ||
1827 | GNUNET_assert (0 != (m = gcry_mpi_new (0))); | ||
1828 | GNUNET_assert (0 != (tmp = gcry_mpi_new (0))); | ||
1829 | GNUNET_assert (0 != (prod = gcry_mpi_new (0))); | ||
1830 | |||
1831 | num = 0; | ||
1832 | for (i = 0; i < ds->share->num_peers; i++) | ||
1833 | if (NULL != ds->info[i].partial_decryption) | ||
1834 | num++; | ||
1835 | |||
1836 | indices = GNUNET_new_array (num, | ||
1837 | unsigned int); | ||
1838 | j = 0; | ||
1839 | for (i = 0; i < ds->share->num_peers; i++) | ||
1840 | if (NULL != ds->info[i].partial_decryption) | ||
1841 | indices[j++] = ds->info[i].original_index; | ||
1842 | |||
1843 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, | ||
1844 | "P%u: decrypt conclude, with %u peers\n", | ||
1845 | ds->share->my_peer, | ||
1846 | num); | ||
1847 | |||
1848 | gcry_mpi_set_ui (prod, 1); | ||
1849 | for (i = 0; i < num; i++) | ||
1850 | { | ||
1851 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, | ||
1852 | "P%u: index of %u: %u\n", | ||
1853 | ds->share->my_peer, i, indices[i]); | ||
1854 | compute_lagrange_coefficient (lagrange, indices[i], indices, num); | ||
1855 | // w_i^{\lambda_i} | ||
1856 | gcry_mpi_powm (tmp, ds->info[indices[i]].partial_decryption, lagrange, | ||
1857 | elgamal_p); | ||
1858 | |||
1859 | // product of all exponentiated partiel decryptions ... | ||
1860 | gcry_mpi_mulm (prod, prod, tmp, elgamal_p); | ||
1861 | } | ||
1862 | |||
1863 | GNUNET_CRYPTO_mpi_scan_unsigned (&c_2, ds->ciphertext.c2_bits, | ||
1864 | GNUNET_SECRETSHARING_ELGAMAL_BITS / 8); | ||
1865 | |||
1866 | GNUNET_assert (0 != gcry_mpi_invm (prod, prod, elgamal_p)); | ||
1867 | gcry_mpi_mulm (m, c_2, prod, elgamal_p); | ||
1868 | ev = GNUNET_MQ_msg (msg, | ||
1869 | GNUNET_MESSAGE_TYPE_SECRETSHARING_CLIENT_DECRYPT_DONE); | ||
1870 | GNUNET_CRYPTO_mpi_print_unsigned (&msg->plaintext, | ||
1871 | GNUNET_SECRETSHARING_ELGAMAL_BITS / 8, m); | ||
1872 | msg->success = htonl (1); | ||
1873 | GNUNET_MQ_send (ds->cs->mq, | ||
1874 | ev); | ||
1875 | |||
1876 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, "sent decrypt done to client\n"); | ||
1877 | |||
1878 | GNUNET_free (indices); | ||
1879 | |||
1880 | gcry_mpi_release (lagrange); | ||
1881 | gcry_mpi_release (m); | ||
1882 | gcry_mpi_release (tmp); | ||
1883 | gcry_mpi_release (prod); | ||
1884 | gcry_mpi_release (c_2); | ||
1885 | |||
1886 | // FIXME: what if not enough peers participated? | ||
1887 | } | ||
1888 | |||
1889 | |||
1890 | /** | ||
1891 | * Get a string representation of an MPI. | ||
1892 | * The caller must free the returned string. | ||
1893 | * | ||
1894 | * @param mpi mpi to convert to a string | ||
1895 | * @return string representation of @a mpi, must be free'd by the caller | ||
1896 | */ | ||
1897 | static char * | ||
1898 | mpi_to_str (gcry_mpi_t mpi) | ||
1899 | { | ||
1900 | unsigned char *buf; | ||
1901 | |||
1902 | GNUNET_assert (0 == gcry_mpi_aprint (GCRYMPI_FMT_HEX, &buf, NULL, mpi)); | ||
1903 | return (char *) buf; | ||
1904 | } | ||
1905 | |||
1906 | |||
1907 | /** | ||
1908 | * Called when a new partial decryption arrives. | ||
1909 | */ | ||
1910 | static void | ||
1911 | decrypt_new_element (void *cls, | ||
1912 | const struct GNUNET_SET_Element *element) | ||
1913 | { | ||
1914 | struct DecryptSession *session = cls; | ||
1915 | const struct GNUNET_SECRETSHARING_DecryptData *d; | ||
1916 | struct DecryptPeerInfo *info; | ||
1917 | struct GNUNET_HashCode challenge_hash; | ||
1918 | |||
1919 | /* nizk response */ | ||
1920 | gcry_mpi_t r; | ||
1921 | /* nizk challenge */ | ||
1922 | gcry_mpi_t challenge; | ||
1923 | /* nizk commit1, g^\beta */ | ||
1924 | gcry_mpi_t commit1; | ||
1925 | /* nizk commit2, c_1^\beta */ | ||
1926 | gcry_mpi_t commit2; | ||
1927 | /* homomorphic commitment to the peer's share, | ||
1928 | * public key share */ | ||
1929 | gcry_mpi_t sigma; | ||
1930 | /* partial decryption we received */ | ||
1931 | gcry_mpi_t w; | ||
1932 | /* ciphertext component #1 */ | ||
1933 | gcry_mpi_t c1; | ||
1934 | /* temporary variable (for comparison) #1 */ | ||
1935 | gcry_mpi_t tmp1; | ||
1936 | /* temporary variable (for comparison) #2 */ | ||
1937 | gcry_mpi_t tmp2; | ||
1938 | |||
1939 | if (NULL == element) | ||
1940 | { | ||
1941 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "decryption failed\n"); | ||
1942 | /* FIXME: destroy */ | ||
1943 | return; | ||
1944 | } | ||
1945 | |||
1946 | if (element->size != sizeof *d) | ||
1947 | { | ||
1948 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
1949 | "element of wrong size in decrypt consensus\n"); | ||
1950 | return; | ||
1951 | } | ||
1952 | |||
1953 | d = element->data; | ||
1954 | |||
1955 | info = get_decrypt_peer_info (session, &d->peer); | ||
1956 | |||
1957 | if (NULL == info) | ||
1958 | { | ||
1959 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
1960 | "decrypt element from invalid peer (%s)\n", | ||
1961 | GNUNET_i2s (&d->peer)); | ||
1962 | return; | ||
1963 | } | ||
1964 | |||
1965 | if (NULL != info->partial_decryption) | ||
1966 | { | ||
1967 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "decrypt element duplicate\n"); | ||
1968 | return; | ||
1969 | } | ||
1970 | |||
1971 | if (0 != GNUNET_memcmp (&d->ciphertext, &session->ciphertext)) | ||
1972 | { | ||
1973 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | ||
1974 | "P%u: got decrypt element with non-matching ciphertext from P%u\n", | ||
1975 | (unsigned int) session->share->my_peer, (unsigned int) (info | ||
1976 | - | ||
1977 | session | ||
1978 | ->info)); | ||
1979 | |||
1980 | return; | ||
1981 | } | ||
1982 | |||
1983 | |||
1984 | GNUNET_CRYPTO_hash (offsetof (struct GNUNET_SECRETSHARING_DecryptData, | ||
1985 | ciphertext) + (char *) d, | ||
1986 | offsetof (struct GNUNET_SECRETSHARING_DecryptData, | ||
1987 | nizk_response) | ||
1988 | - offsetof (struct GNUNET_SECRETSHARING_DecryptData, | ||
1989 | ciphertext), | ||
1990 | &challenge_hash); | ||
1991 | |||
1992 | GNUNET_CRYPTO_mpi_scan_unsigned (&challenge, &challenge_hash, | ||
1993 | sizeof(struct GNUNET_HashCode)); | ||
1994 | |||
1995 | GNUNET_CRYPTO_mpi_scan_unsigned (&sigma, &session->share->sigmas[info | ||
1996 | - session-> | ||
1997 | info], | ||
1998 | sizeof(struct | ||
1999 | GNUNET_SECRETSHARING_FieldElement)); | ||
2000 | |||
2001 | GNUNET_CRYPTO_mpi_scan_unsigned (&c1, session->ciphertext.c1_bits, | ||
2002 | sizeof(struct | ||
2003 | GNUNET_SECRETSHARING_FieldElement)); | ||
2004 | |||
2005 | GNUNET_CRYPTO_mpi_scan_unsigned (&commit1, &d->nizk_commit1, | ||
2006 | sizeof(struct | ||
2007 | GNUNET_SECRETSHARING_FieldElement)); | ||
2008 | |||
2009 | GNUNET_CRYPTO_mpi_scan_unsigned (&commit2, &d->nizk_commit2, | ||
2010 | sizeof(struct | ||
2011 | GNUNET_SECRETSHARING_FieldElement)); | ||
2012 | |||
2013 | GNUNET_CRYPTO_mpi_scan_unsigned (&r, &d->nizk_response, | ||
2014 | sizeof(struct | ||
2015 | GNUNET_SECRETSHARING_FieldElement)); | ||
2016 | |||
2017 | GNUNET_CRYPTO_mpi_scan_unsigned (&w, &d->partial_decryption, | ||
2018 | sizeof(struct | ||
2019 | GNUNET_SECRETSHARING_FieldElement)); | ||
2020 | |||
2021 | GNUNET_assert (NULL != (tmp1 = gcry_mpi_new (0))); | ||
2022 | GNUNET_assert (NULL != (tmp2 = gcry_mpi_new (0))); | ||
2023 | |||
2024 | // tmp1 = g^r | ||
2025 | gcry_mpi_powm (tmp1, elgamal_g, r, elgamal_p); | ||
2026 | |||
2027 | // tmp2 = g^\beta * \sigma^challenge | ||
2028 | gcry_mpi_powm (tmp2, sigma, challenge, elgamal_p); | ||
2029 | gcry_mpi_mulm (tmp2, tmp2, commit1, elgamal_p); | ||
2030 | |||
2031 | if (0 != gcry_mpi_cmp (tmp1, tmp2)) | ||
2032 | { | ||
2033 | char *tmp1_str; | ||
2034 | char *tmp2_str; | ||
2035 | |||
2036 | tmp1_str = mpi_to_str (tmp1); | ||
2037 | tmp2_str = mpi_to_str (tmp2); | ||
2038 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | ||
2039 | "P%u: Received invalid partial decryption from P%u (eqn 1), expected %s got %s\n", | ||
2040 | session->share->my_peer, | ||
2041 | (unsigned int) (info - session->info), | ||
2042 | tmp1_str, | ||
2043 | tmp2_str); | ||
2044 | GNUNET_free (tmp1_str); | ||
2045 | GNUNET_free (tmp2_str); | ||
2046 | goto cleanup; | ||
2047 | } | ||
2048 | |||
2049 | |||
2050 | gcry_mpi_powm (tmp1, c1, r, elgamal_p); | ||
2051 | |||
2052 | gcry_mpi_powm (tmp2, w, challenge, elgamal_p); | ||
2053 | gcry_mpi_mulm (tmp2, tmp2, commit2, elgamal_p); | ||
2054 | |||
2055 | |||
2056 | if (0 != gcry_mpi_cmp (tmp1, tmp2)) | ||
2057 | { | ||
2058 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | ||
2059 | "P%u: Received invalid partial decryption from P%u (eqn 2)\n", | ||
2060 | session->share->my_peer, | ||
2061 | (unsigned int) (info - session->info)); | ||
2062 | goto cleanup; | ||
2063 | } | ||
2064 | |||
2065 | |||
2066 | GNUNET_CRYPTO_mpi_scan_unsigned (&info->partial_decryption, | ||
2067 | &d->partial_decryption, | ||
2068 | GNUNET_SECRETSHARING_ELGAMAL_BITS / 8); | ||
2069 | cleanup: | ||
2070 | gcry_mpi_release (tmp1); | ||
2071 | gcry_mpi_release (tmp2); | ||
2072 | gcry_mpi_release (sigma); | ||
2073 | gcry_mpi_release (commit1); | ||
2074 | gcry_mpi_release (commit2); | ||
2075 | gcry_mpi_release (r); | ||
2076 | gcry_mpi_release (w); | ||
2077 | gcry_mpi_release (challenge); | ||
2078 | gcry_mpi_release (c1); | ||
2079 | } | ||
2080 | |||
2081 | |||
2082 | static void | ||
2083 | insert_decrypt_element (struct DecryptSession *ds) | ||
2084 | { | ||
2085 | struct GNUNET_SECRETSHARING_DecryptData d; | ||
2086 | struct GNUNET_SET_Element element; | ||
2087 | /* our share */ | ||
2088 | gcry_mpi_t s; | ||
2089 | /* partial decryption with our share */ | ||
2090 | gcry_mpi_t w; | ||
2091 | /* first component of the elgamal ciphertext */ | ||
2092 | gcry_mpi_t c1; | ||
2093 | /* nonce for dlog zkp */ | ||
2094 | gcry_mpi_t beta; | ||
2095 | gcry_mpi_t tmp; | ||
2096 | gcry_mpi_t challenge; | ||
2097 | gcry_mpi_t sigma; | ||
2098 | struct GNUNET_HashCode challenge_hash; | ||
2099 | |||
2100 | /* make vagrind happy until we implement the real deal ... */ | ||
2101 | memset (&d, 0, sizeof d); | ||
2102 | |||
2103 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "P%u: Inserting decrypt element\n", | ||
2104 | ds->share->my_peer); | ||
2105 | |||
2106 | GNUNET_assert (ds->share->my_peer < ds->share->num_peers); | ||
2107 | |||
2108 | GNUNET_CRYPTO_mpi_scan_unsigned (&c1, &ds->ciphertext.c1_bits, | ||
2109 | GNUNET_SECRETSHARING_ELGAMAL_BITS / 8); | ||
2110 | GNUNET_CRYPTO_mpi_scan_unsigned (&s, &ds->share->my_share, | ||
2111 | GNUNET_SECRETSHARING_ELGAMAL_BITS / 8); | ||
2112 | GNUNET_CRYPTO_mpi_scan_unsigned (&sigma, | ||
2113 | &ds->share->sigmas[ds->share->my_peer], | ||
2114 | GNUNET_SECRETSHARING_ELGAMAL_BITS / 8); | ||
2115 | |||
2116 | GNUNET_assert (NULL != (w = gcry_mpi_new (0))); | ||
2117 | GNUNET_assert (NULL != (beta = gcry_mpi_new (0))); | ||
2118 | GNUNET_assert (NULL != (tmp = gcry_mpi_new (0))); | ||
2119 | |||
2120 | // FIXME: unnecessary, remove once crypto works | ||
2121 | gcry_mpi_powm (tmp, elgamal_g, s, elgamal_p); | ||
2122 | if (0 != gcry_mpi_cmp (tmp, sigma)) | ||
2123 | { | ||
2124 | char *sigma_str = mpi_to_str (sigma); | ||
2125 | char *tmp_str = mpi_to_str (tmp); | ||
2126 | char *s_str = mpi_to_str (s); | ||
2127 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
2128 | "Share of P%u is invalid, ref sigma %s, " | ||
2129 | "computed sigma %s, s %s\n", | ||
2130 | ds->share->my_peer, | ||
2131 | sigma_str, tmp_str, s_str); | ||
2132 | GNUNET_free (sigma_str); | ||
2133 | GNUNET_free (tmp_str); | ||
2134 | GNUNET_free (s_str); | ||
2135 | } | ||
2136 | |||
2137 | gcry_mpi_powm (w, c1, s, elgamal_p); | ||
2138 | |||
2139 | element.data = (void *) &d; | ||
2140 | element.size = sizeof(struct GNUNET_SECRETSHARING_DecryptData); | ||
2141 | element.element_type = 0; | ||
2142 | |||
2143 | d.ciphertext = ds->ciphertext; | ||
2144 | d.peer = my_peer; | ||
2145 | GNUNET_CRYPTO_mpi_print_unsigned (&d.partial_decryption, | ||
2146 | GNUNET_SECRETSHARING_ELGAMAL_BITS / 8, w); | ||
2147 | |||
2148 | // create the zero knowledge proof | ||
2149 | // randomly choose beta such that 0 < beta < q | ||
2150 | do | ||
2151 | { | ||
2152 | gcry_mpi_randomize (beta, GNUNET_SECRETSHARING_ELGAMAL_BITS - 1, | ||
2153 | GCRY_WEAK_RANDOM); | ||
2154 | } | ||
2155 | while ((gcry_mpi_cmp_ui (beta, 0) == 0) || (gcry_mpi_cmp (beta, elgamal_q) >= | ||
2156 | 0)); | ||
2157 | // tmp = g^beta | ||
2158 | gcry_mpi_powm (tmp, elgamal_g, beta, elgamal_p); | ||
2159 | GNUNET_CRYPTO_mpi_print_unsigned (&d.nizk_commit1, | ||
2160 | GNUNET_SECRETSHARING_ELGAMAL_BITS / 8, tmp); | ||
2161 | // tmp = (c_1)^beta | ||
2162 | gcry_mpi_powm (tmp, c1, beta, elgamal_p); | ||
2163 | GNUNET_CRYPTO_mpi_print_unsigned (&d.nizk_commit2, | ||
2164 | GNUNET_SECRETSHARING_ELGAMAL_BITS / 8, tmp); | ||
2165 | |||
2166 | // the challenge is the hash of everything up to the response | ||
2167 | GNUNET_CRYPTO_hash (offsetof (struct GNUNET_SECRETSHARING_DecryptData, | ||
2168 | ciphertext) + (char *) &d, | ||
2169 | offsetof (struct GNUNET_SECRETSHARING_DecryptData, | ||
2170 | nizk_response) | ||
2171 | - offsetof (struct GNUNET_SECRETSHARING_DecryptData, | ||
2172 | ciphertext), | ||
2173 | &challenge_hash); | ||
2174 | |||
2175 | GNUNET_CRYPTO_mpi_scan_unsigned (&challenge, &challenge_hash, | ||
2176 | sizeof(struct GNUNET_HashCode)); | ||
2177 | |||
2178 | // compute the response in tmp, | ||
2179 | // tmp = (c * s + beta) mod q | ||
2180 | gcry_mpi_mulm (tmp, challenge, s, elgamal_q); | ||
2181 | gcry_mpi_addm (tmp, tmp, beta, elgamal_q); | ||
2182 | |||
2183 | GNUNET_CRYPTO_mpi_print_unsigned (&d.nizk_response, | ||
2184 | GNUNET_SECRETSHARING_ELGAMAL_BITS / 8, tmp); | ||
2185 | |||
2186 | d.purpose.size = htonl (element.size - offsetof (struct | ||
2187 | GNUNET_SECRETSHARING_DecryptData, | ||
2188 | purpose)); | ||
2189 | d.purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_SECRETSHARING_DECRYPTION); | ||
2190 | |||
2191 | GNUNET_assert (GNUNET_OK == | ||
2192 | GNUNET_CRYPTO_eddsa_sign_ (my_peer_private_key, | ||
2193 | &d.purpose, | ||
2194 | &d.signature)); | ||
2195 | |||
2196 | GNUNET_CONSENSUS_insert (ds->consensus, &element, NULL, NULL); | ||
2197 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
2198 | "P%u: Inserting decrypt element done!\n", | ||
2199 | ds->share->my_peer); | ||
2200 | |||
2201 | gcry_mpi_release (s); | ||
2202 | gcry_mpi_release (w); | ||
2203 | gcry_mpi_release (c1); | ||
2204 | gcry_mpi_release (beta); | ||
2205 | gcry_mpi_release (tmp); | ||
2206 | gcry_mpi_release (challenge); | ||
2207 | gcry_mpi_release (sigma); | ||
2208 | } | ||
2209 | |||
2210 | |||
2211 | /** | ||
2212 | * Check that @a msg is well-formed. | ||
2213 | * | ||
2214 | * @param cls identification of the client | ||
2215 | * @param msg the actual message | ||
2216 | * @return #GNUNET_OK (check deferred a bit) | ||
2217 | */ | ||
2218 | static int | ||
2219 | check_client_decrypt (void *cls, | ||
2220 | const struct | ||
2221 | GNUNET_SECRETSHARING_DecryptRequestMessage *msg) | ||
2222 | { | ||
2223 | /* we check later, it's complicated */ | ||
2224 | return GNUNET_OK; | ||
2225 | } | ||
2226 | |||
2227 | |||
2228 | /** | ||
2229 | * Functions with this signature are called whenever a message is | ||
2230 | * received. | ||
2231 | * | ||
2232 | * @param cls identification of the client | ||
2233 | * @param msg the actual message | ||
2234 | */ | ||
2235 | static void | ||
2236 | handle_client_decrypt (void *cls, | ||
2237 | const struct | ||
2238 | GNUNET_SECRETSHARING_DecryptRequestMessage *msg) | ||
2239 | { | ||
2240 | struct ClientState *cs = cls; | ||
2241 | struct DecryptSession *ds; | ||
2242 | struct GNUNET_HashCode session_id; | ||
2243 | |||
2244 | if (NULL != cs->decrypt_session) | ||
2245 | { | ||
2246 | GNUNET_break (0); | ||
2247 | GNUNET_SERVICE_client_drop (cs->client); | ||
2248 | return; | ||
2249 | } | ||
2250 | ds = GNUNET_new (struct DecryptSession); | ||
2251 | cs->decrypt_session = ds; | ||
2252 | ds->cs = cs; | ||
2253 | ds->start = GNUNET_TIME_absolute_ntoh (msg->start); | ||
2254 | ds->deadline = GNUNET_TIME_absolute_ntoh (msg->deadline); | ||
2255 | ds->ciphertext = msg->ciphertext; | ||
2256 | |||
2257 | ds->share = GNUNET_SECRETSHARING_share_read (&msg[1], | ||
2258 | ntohs (msg->header.size) | ||
2259 | - sizeof(*msg), | ||
2260 | NULL); | ||
2261 | if (NULL == ds->share) | ||
2262 | { | ||
2263 | GNUNET_break (0); | ||
2264 | GNUNET_SERVICE_client_drop (cs->client); | ||
2265 | return; | ||
2266 | } | ||
2267 | |||
2268 | /* FIXME: this is probably sufficient, but kdf/hash with all values would be nicer ... */ | ||
2269 | GNUNET_CRYPTO_hash (&msg->ciphertext, | ||
2270 | sizeof(struct GNUNET_SECRETSHARING_Ciphertext), | ||
2271 | &session_id); | ||
2272 | ds->consensus = GNUNET_CONSENSUS_create (cfg, | ||
2273 | ds->share->num_peers, | ||
2274 | ds->share->peers, | ||
2275 | &session_id, | ||
2276 | ds->start, | ||
2277 | ds->deadline, | ||
2278 | &decrypt_new_element, | ||
2279 | ds); | ||
2280 | |||
2281 | |||
2282 | ds->info = GNUNET_new_array (ds->share->num_peers, | ||
2283 | struct DecryptPeerInfo); | ||
2284 | for (unsigned int i = 0; i < ds->share->num_peers; i++) | ||
2285 | { | ||
2286 | ds->info[i].peer = ds->share->peers[i]; | ||
2287 | ds->info[i].original_index = ds->share->original_indices[i]; | ||
2288 | } | ||
2289 | insert_decrypt_element (ds); | ||
2290 | GNUNET_CONSENSUS_conclude (ds->consensus, | ||
2291 | decrypt_conclude, | ||
2292 | ds); | ||
2293 | GNUNET_SERVICE_client_continue (cs->client); | ||
2294 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, | ||
2295 | "decrypting with %u peers\n", | ||
2296 | ds->share->num_peers); | ||
2297 | } | ||
2298 | |||
2299 | |||
2300 | static void | ||
2301 | init_crypto_constants (void) | ||
2302 | { | ||
2303 | GNUNET_assert (0 == gcry_mpi_scan (&elgamal_q, GCRYMPI_FMT_HEX, | ||
2304 | GNUNET_SECRETSHARING_ELGAMAL_Q_HEX, 0, | ||
2305 | NULL)); | ||
2306 | GNUNET_assert (0 == gcry_mpi_scan (&elgamal_p, GCRYMPI_FMT_HEX, | ||
2307 | GNUNET_SECRETSHARING_ELGAMAL_P_HEX, 0, | ||
2308 | NULL)); | ||
2309 | GNUNET_assert (0 == gcry_mpi_scan (&elgamal_g, GCRYMPI_FMT_HEX, | ||
2310 | GNUNET_SECRETSHARING_ELGAMAL_G_HEX, 0, | ||
2311 | NULL)); | ||
2312 | } | ||
2313 | |||
2314 | |||
2315 | /** | ||
2316 | * Initialize secretsharing service. | ||
2317 | * | ||
2318 | * @param cls closure | ||
2319 | * @param c configuration to use | ||
2320 | * @param service the initialized service | ||
2321 | */ | ||
2322 | static void | ||
2323 | run (void *cls, | ||
2324 | const struct GNUNET_CONFIGURATION_Handle *c, | ||
2325 | struct GNUNET_SERVICE_Handle *service) | ||
2326 | { | ||
2327 | cfg = c; | ||
2328 | my_peer_private_key = GNUNET_CRYPTO_eddsa_key_create_from_configuration (c); | ||
2329 | if (NULL == my_peer_private_key) | ||
2330 | { | ||
2331 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
2332 | "could not access host private key\n"); | ||
2333 | GNUNET_break (0); | ||
2334 | GNUNET_SCHEDULER_shutdown (); | ||
2335 | return; | ||
2336 | } | ||
2337 | init_crypto_constants (); | ||
2338 | if (GNUNET_OK != | ||
2339 | GNUNET_CRYPTO_get_peer_identity (cfg, | ||
2340 | &my_peer)) | ||
2341 | { | ||
2342 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
2343 | "could not retrieve host identity\n"); | ||
2344 | GNUNET_break (0); | ||
2345 | GNUNET_SCHEDULER_shutdown (); | ||
2346 | return; | ||
2347 | } | ||
2348 | GNUNET_SCHEDULER_add_shutdown (&cleanup_task, | ||
2349 | NULL); | ||
2350 | } | ||
2351 | |||
2352 | |||
2353 | /** | ||
2354 | * Callback called when a client connects to the service. | ||
2355 | * | ||
2356 | * @param cls closure for the service | ||
2357 | * @param c the new client that connected to the service | ||
2358 | * @param mq the message queue used to send messages to the client | ||
2359 | * @return @a c | ||
2360 | */ | ||
2361 | static void * | ||
2362 | client_connect_cb (void *cls, | ||
2363 | struct GNUNET_SERVICE_Client *c, | ||
2364 | struct GNUNET_MQ_Handle *mq) | ||
2365 | { | ||
2366 | struct ClientState *cs = GNUNET_new (struct ClientState);; | ||
2367 | |||
2368 | cs->client = c; | ||
2369 | cs->mq = mq; | ||
2370 | return cs; | ||
2371 | } | ||
2372 | |||
2373 | |||
2374 | /** | ||
2375 | * Callback called when a client disconnected from the service | ||
2376 | * | ||
2377 | * @param cls closure for the service | ||
2378 | * @param c the client that disconnected | ||
2379 | * @param internal_cls should be equal to @a c | ||
2380 | */ | ||
2381 | static void | ||
2382 | client_disconnect_cb (void *cls, | ||
2383 | struct GNUNET_SERVICE_Client *c, | ||
2384 | void *internal_cls) | ||
2385 | { | ||
2386 | struct ClientState *cs = internal_cls; | ||
2387 | |||
2388 | if (NULL != cs->keygen_session) | ||
2389 | keygen_session_destroy (cs->keygen_session); | ||
2390 | |||
2391 | if (NULL != cs->decrypt_session) | ||
2392 | decrypt_session_destroy (cs->decrypt_session); | ||
2393 | GNUNET_free (cs); | ||
2394 | } | ||
2395 | |||
2396 | |||
2397 | /** | ||
2398 | * Define "main" method using service macro. | ||
2399 | */ | ||
2400 | GNUNET_SERVICE_MAIN | ||
2401 | ("secretsharing", | ||
2402 | GNUNET_SERVICE_OPTION_NONE, | ||
2403 | &run, | ||
2404 | &client_connect_cb, | ||
2405 | &client_disconnect_cb, | ||
2406 | NULL, | ||
2407 | GNUNET_MQ_hd_var_size (client_keygen, | ||
2408 | GNUNET_MESSAGE_TYPE_SECRETSHARING_CLIENT_GENERATE, | ||
2409 | struct GNUNET_SECRETSHARING_CreateMessage, | ||
2410 | NULL), | ||
2411 | GNUNET_MQ_hd_var_size (client_decrypt, | ||
2412 | GNUNET_MESSAGE_TYPE_SECRETSHARING_CLIENT_DECRYPT, | ||
2413 | struct GNUNET_SECRETSHARING_DecryptRequestMessage, | ||
2414 | NULL), | ||
2415 | GNUNET_MQ_handler_end ()); | ||
diff --git a/src/secretsharing/secretsharing.conf.in b/src/secretsharing/secretsharing.conf.in deleted file mode 100644 index df8566abd..000000000 --- a/src/secretsharing/secretsharing.conf.in +++ /dev/null | |||
@@ -1,20 +0,0 @@ | |||
1 | [secretsharing] | ||
2 | START_ON_DEMAND = NO | ||
3 | @JAVAPORT@PORT = 2114 | ||
4 | HOSTNAME = localhost | ||
5 | BINARY = gnunet-service-secretsharing | ||
6 | ACCEPT_FROM = 127.0.0.1; | ||
7 | ACCEPT_FROM6 = ::1; | ||
8 | UNIXPATH = $GNUNET_RUNTIME_DIR/gnunet-service-secretsharing.sock | ||
9 | UNIX_MATCH_UID = YES | ||
10 | UNIX_MATCH_GID = YES | ||
11 | # PREFIX = valgrind --leak-check=yes | ||
12 | # DISABLE_SOCKET_FORWARDING = NO | ||
13 | # USERNAME = | ||
14 | # MAXBUF = | ||
15 | # TIMEOUT = | ||
16 | # DISABLEV6 = | ||
17 | # BINDTO = | ||
18 | # REJECT_FROM = | ||
19 | # REJECT_FROM6 = | ||
20 | # PREFIX = | ||
diff --git a/src/secretsharing/secretsharing.h b/src/secretsharing/secretsharing.h deleted file mode 100644 index 6e104ebfa..000000000 --- a/src/secretsharing/secretsharing.h +++ /dev/null | |||
@@ -1,227 +0,0 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet. | ||
3 | Copyright (C) 2013 GNUnet e.V. | ||
4 | |||
5 | GNUnet is free software: you can redistribute it and/or modify it | ||
6 | under the terms of the GNU Affero General Public License as published | ||
7 | by the Free Software Foundation, either version 3 of the License, | ||
8 | or (at your option) any later version. | ||
9 | |||
10 | GNUnet is distributed in the hope that it will be useful, but | ||
11 | WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
13 | Affero General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU Affero General Public License | ||
16 | along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
17 | |||
18 | SPDX-License-Identifier: AGPL3.0-or-later | ||
19 | */ | ||
20 | |||
21 | /** | ||
22 | * @author Florian Dold | ||
23 | * @file secretsharing/secretsharing.h | ||
24 | * @brief messages used for the secretsharing api | ||
25 | */ | ||
26 | #ifndef SECRETSHARING_H | ||
27 | #define SECRETSHARING_H | ||
28 | |||
29 | #include "platform.h" | ||
30 | #include "gnunet_util_lib.h" | ||
31 | #include "gnunet_time_lib.h" | ||
32 | #include "gnunet_common.h" | ||
33 | #include "gnunet_secretsharing_service.h" | ||
34 | |||
35 | |||
36 | GNUNET_NETWORK_STRUCT_BEGIN | ||
37 | |||
38 | struct GNUNET_SECRETSHARING_FieldElement | ||
39 | { | ||
40 | /** | ||
41 | * Value of an element in <elgamal_g>. | ||
42 | */ | ||
43 | unsigned char bits[GNUNET_SECRETSHARING_ELGAMAL_BITS / 8]; | ||
44 | }; | ||
45 | |||
46 | |||
47 | struct GNUNET_SECRETSHARING_CreateMessage | ||
48 | { | ||
49 | /** | ||
50 | * Type: GNUNET_MESSAGE_TYPE_SECRETSHARING_CLIENT_GENERATE | ||
51 | */ | ||
52 | struct GNUNET_MessageHeader header; | ||
53 | |||
54 | /** | ||
55 | * Session ID, will be used for consensus. | ||
56 | */ | ||
57 | struct GNUNET_HashCode session_id GNUNET_PACKED; | ||
58 | |||
59 | /** | ||
60 | * Start time for communication with the other peers. | ||
61 | */ | ||
62 | struct GNUNET_TIME_AbsoluteNBO start; | ||
63 | |||
64 | /** | ||
65 | * Deadline for the establishment of the crypto system. | ||
66 | */ | ||
67 | struct GNUNET_TIME_AbsoluteNBO deadline; | ||
68 | |||
69 | /** | ||
70 | * Minimum number of cooperating peers to decrypt a | ||
71 | * value. | ||
72 | */ | ||
73 | uint16_t threshold GNUNET_PACKED; | ||
74 | |||
75 | /** | ||
76 | * Number of peers at the end of this message. | ||
77 | */ | ||
78 | uint16_t num_peers GNUNET_PACKED; | ||
79 | |||
80 | /* struct GNUNET_PeerIdentity[num_peers]; */ | ||
81 | }; | ||
82 | |||
83 | |||
84 | struct GNUNET_SECRETSHARING_ShareHeaderNBO | ||
85 | { | ||
86 | /** | ||
87 | * Threshold for the key this share belongs to. | ||
88 | */ | ||
89 | uint16_t threshold; | ||
90 | |||
91 | /** | ||
92 | * Peers that have the share. | ||
93 | */ | ||
94 | uint16_t num_peers; | ||
95 | |||
96 | /** | ||
97 | * Index of our peer in the list. | ||
98 | */ | ||
99 | uint16_t my_peer; | ||
100 | |||
101 | /** | ||
102 | * Public key. Must correspond to the product of | ||
103 | * the homomorphic share commitments. | ||
104 | */ | ||
105 | struct GNUNET_SECRETSHARING_PublicKey public_key; | ||
106 | |||
107 | /** | ||
108 | * Share of 'my_peer' | ||
109 | */ | ||
110 | struct GNUNET_SECRETSHARING_FieldElement my_share; | ||
111 | }; | ||
112 | |||
113 | |||
114 | /** | ||
115 | * Notify the client that then threshold secret has been | ||
116 | * established. | ||
117 | */ | ||
118 | struct GNUNET_SECRETSHARING_SecretReadyMessage | ||
119 | { | ||
120 | /** | ||
121 | * Type: GNUNET_MESSAGE_TYPE_SECRETSHARING_CLIENT_SECRET_READY | ||
122 | */ | ||
123 | struct GNUNET_MessageHeader header; | ||
124 | |||
125 | /* rest: the serialized share */ | ||
126 | }; | ||
127 | |||
128 | |||
129 | struct GNUNET_SECRETSHARING_DecryptRequestMessage | ||
130 | { | ||
131 | /** | ||
132 | * Type: GNUNET_MESSAGE_TYPE_SECRETSHARING_CLIENT_DECRYPT_REQUEST | ||
133 | */ | ||
134 | struct GNUNET_MessageHeader header; | ||
135 | |||
136 | /** | ||
137 | * Until when should the decryption start? | ||
138 | */ | ||
139 | struct GNUNET_TIME_AbsoluteNBO start; | ||
140 | |||
141 | /** | ||
142 | * Until when should the decryption be finished? | ||
143 | */ | ||
144 | struct GNUNET_TIME_AbsoluteNBO deadline; | ||
145 | |||
146 | /** | ||
147 | * Ciphertext we want to decrypt. | ||
148 | */ | ||
149 | struct GNUNET_SECRETSHARING_Ciphertext ciphertext; | ||
150 | |||
151 | /* the share with payload */ | ||
152 | }; | ||
153 | |||
154 | |||
155 | struct GNUNET_SECRETSHARING_DecryptResponseMessage | ||
156 | { | ||
157 | /** | ||
158 | * Type: #GNUNET_MESSAGE_TYPE_SECRETSHARING_CLIENT_DECRYPT_DONE | ||
159 | */ | ||
160 | struct GNUNET_MessageHeader header; | ||
161 | |||
162 | /** | ||
163 | * Zero if decryption failed, non-zero if decryption succeeded. | ||
164 | * If the decryption failed, plaintext is also zero. | ||
165 | */ | ||
166 | uint32_t success GNUNET_PACKED; | ||
167 | |||
168 | /** | ||
169 | * Decrypted plaintext. | ||
170 | */ | ||
171 | struct GNUNET_SECRETSHARING_FieldElement plaintext; | ||
172 | }; | ||
173 | |||
174 | |||
175 | GNUNET_NETWORK_STRUCT_END | ||
176 | |||
177 | |||
178 | /** | ||
179 | * A share, with all values in in host byte order. | ||
180 | */ | ||
181 | struct GNUNET_SECRETSHARING_Share | ||
182 | { | ||
183 | /** | ||
184 | * Threshold for the key this share belongs to. | ||
185 | */ | ||
186 | uint16_t threshold; | ||
187 | |||
188 | /** | ||
189 | * Peers that have the share. | ||
190 | */ | ||
191 | uint16_t num_peers; | ||
192 | |||
193 | /** | ||
194 | * Index of our peer in the list. | ||
195 | */ | ||
196 | uint16_t my_peer; | ||
197 | |||
198 | /** | ||
199 | * Public key. Computed from the | ||
200 | * exponentiated coefficients. | ||
201 | */ | ||
202 | struct GNUNET_SECRETSHARING_PublicKey public_key; | ||
203 | |||
204 | /** | ||
205 | * Share of 'my_peer' | ||
206 | */ | ||
207 | struct GNUNET_SECRETSHARING_FieldElement my_share; | ||
208 | |||
209 | /** | ||
210 | * Peer identities (includes 'my_peer') | ||
211 | */ | ||
212 | struct GNUNET_PeerIdentity *peers; | ||
213 | |||
214 | /* | ||
215 | * For each peer, store elgamal_g to the peer's | ||
216 | * share. | ||
217 | */ | ||
218 | struct GNUNET_SECRETSHARING_FieldElement *sigmas; | ||
219 | |||
220 | /* | ||
221 | * Original indices of peers from the DKG round. | ||
222 | */ | ||
223 | uint16_t *original_indices; | ||
224 | }; | ||
225 | |||
226 | |||
227 | #endif | ||
diff --git a/src/secretsharing/secretsharing_api.c b/src/secretsharing/secretsharing_api.c deleted file mode 100644 index 98f800c95..000000000 --- a/src/secretsharing/secretsharing_api.c +++ /dev/null | |||
@@ -1,518 +0,0 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet. | ||
3 | Copyright (C) 2012, 2016 GNUnet e.V. | ||
4 | |||
5 | GNUnet is free software: you can redistribute it and/or modify it | ||
6 | under the terms of the GNU Affero General Public License as published | ||
7 | by the Free Software Foundation, either version 3 of the License, | ||
8 | or (at your option) any later version. | ||
9 | |||
10 | GNUnet is distributed in the hope that it will be useful, but | ||
11 | WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
13 | Affero General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU Affero General Public License | ||
16 | along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
17 | |||
18 | SPDX-License-Identifier: AGPL3.0-or-later | ||
19 | */ | ||
20 | |||
21 | /** | ||
22 | * @file secretsharing/secretsharing_api.c | ||
23 | * @brief | ||
24 | * @author Florian Dold | ||
25 | */ | ||
26 | #include "platform.h" | ||
27 | #include "gnunet_util_lib.h" | ||
28 | #include "gnunet_secretsharing_service.h" | ||
29 | #include "secretsharing.h" | ||
30 | #include <gcrypt.h> | ||
31 | |||
32 | |||
33 | #define LOG(kind, ...) GNUNET_log_from (kind, "secretsharing-api", __VA_ARGS__) | ||
34 | |||
35 | /** | ||
36 | * Session that will eventually establish a shared secred between | ||
37 | * the involved peers and allow encryption and cooperative decryption. | ||
38 | */ | ||
39 | struct GNUNET_SECRETSHARING_Session | ||
40 | { | ||
41 | /** | ||
42 | * Message queue for @e client. | ||
43 | */ | ||
44 | struct GNUNET_MQ_Handle *mq; | ||
45 | |||
46 | /** | ||
47 | * Called when the secret sharing is done. | ||
48 | */ | ||
49 | GNUNET_SECRETSHARING_SecretReadyCallback secret_ready_cb; | ||
50 | |||
51 | /** | ||
52 | * Closure for @e secret_ready_cb. | ||
53 | */ | ||
54 | void *secret_ready_cls; | ||
55 | }; | ||
56 | |||
57 | |||
58 | /** | ||
59 | * Handle to cancel a cooperative decryption operation. | ||
60 | */ | ||
61 | struct GNUNET_SECRETSHARING_DecryptionHandle | ||
62 | { | ||
63 | /** | ||
64 | * Message queue for @e client. | ||
65 | */ | ||
66 | struct GNUNET_MQ_Handle *mq; | ||
67 | |||
68 | /** | ||
69 | * Called when the secret sharing is done. | ||
70 | */ | ||
71 | GNUNET_SECRETSHARING_DecryptCallback decrypt_cb; | ||
72 | |||
73 | /** | ||
74 | * Closure for @e decrypt_cb. | ||
75 | */ | ||
76 | void *decrypt_cls; | ||
77 | }; | ||
78 | |||
79 | |||
80 | /** | ||
81 | * The ElGamal prime field order as libgcrypt mpi. | ||
82 | * Initialized in #init_crypto_constants. | ||
83 | */ | ||
84 | static gcry_mpi_t elgamal_q; | ||
85 | |||
86 | /** | ||
87 | * Modulus of the prime field used for ElGamal. | ||
88 | * Initialized in #init_crypto_constants. | ||
89 | */ | ||
90 | static gcry_mpi_t elgamal_p; | ||
91 | |||
92 | /** | ||
93 | * Generator for prime field of order 'elgamal_q'. | ||
94 | * Initialized in #init_crypto_constants. | ||
95 | */ | ||
96 | static gcry_mpi_t elgamal_g; | ||
97 | |||
98 | |||
99 | /** | ||
100 | * Function to initialize #elgamal_q, #elgamal_p and #elgamal_g. | ||
101 | */ | ||
102 | static void | ||
103 | ensure_elgamal_initialized (void) | ||
104 | { | ||
105 | if (NULL != elgamal_q) | ||
106 | return; /* looks like crypto is already initialized */ | ||
107 | |||
108 | GNUNET_assert (0 == gcry_mpi_scan (&elgamal_q, GCRYMPI_FMT_HEX, | ||
109 | GNUNET_SECRETSHARING_ELGAMAL_Q_HEX, 0, | ||
110 | NULL)); | ||
111 | GNUNET_assert (0 == gcry_mpi_scan (&elgamal_p, GCRYMPI_FMT_HEX, | ||
112 | GNUNET_SECRETSHARING_ELGAMAL_P_HEX, 0, | ||
113 | NULL)); | ||
114 | GNUNET_assert (0 == gcry_mpi_scan (&elgamal_g, GCRYMPI_FMT_HEX, | ||
115 | GNUNET_SECRETSHARING_ELGAMAL_G_HEX, 0, | ||
116 | NULL)); | ||
117 | } | ||
118 | |||
119 | |||
120 | /** | ||
121 | * Callback invoked when there is an error communicating with | ||
122 | * the service. Notifies the application about the error. | ||
123 | * | ||
124 | * @param cls the `struct GNUNET_SECRETSHARING_Session` | ||
125 | * @param error error code | ||
126 | */ | ||
127 | static void | ||
128 | handle_session_client_error (void *cls, | ||
129 | enum GNUNET_MQ_Error error) | ||
130 | { | ||
131 | struct GNUNET_SECRETSHARING_Session *s = cls; | ||
132 | |||
133 | s->secret_ready_cb (s->secret_ready_cls, NULL, NULL, 0, NULL); | ||
134 | GNUNET_SECRETSHARING_session_destroy (s); | ||
135 | } | ||
136 | |||
137 | |||
138 | /** | ||
139 | * Callback invoked when there is an error communicating with | ||
140 | * the service. Notifies the application about the error. | ||
141 | * | ||
142 | * @param cls the `struct GNUNET_SECRETSHARING_DecryptionHandle` | ||
143 | * @param error error code | ||
144 | */ | ||
145 | static void | ||
146 | handle_decrypt_client_error (void *cls, | ||
147 | enum GNUNET_MQ_Error error) | ||
148 | { | ||
149 | struct GNUNET_SECRETSHARING_DecryptionHandle *dh = cls; | ||
150 | |||
151 | dh->decrypt_cb (dh->decrypt_cls, NULL); | ||
152 | GNUNET_SECRETSHARING_decrypt_cancel (dh); | ||
153 | } | ||
154 | |||
155 | |||
156 | /** | ||
157 | * Handler invoked with the final result message from | ||
158 | * secret sharing. Decodes the message and passes the | ||
159 | * result to the application. | ||
160 | * | ||
161 | * @param cls the `struct GNUNET_SECRETSHARING_Session` | ||
162 | * @param m message with the result | ||
163 | */ | ||
164 | static int | ||
165 | check_secret_ready (void *cls, | ||
166 | const struct GNUNET_SECRETSHARING_SecretReadyMessage *m) | ||
167 | { | ||
168 | /* FIXME: actually check m is well-formed here! */ | ||
169 | return GNUNET_OK; | ||
170 | } | ||
171 | |||
172 | |||
173 | /** | ||
174 | * Handler invoked with the final result message from | ||
175 | * secret sharing. Decodes the message and passes the | ||
176 | * result to the application. | ||
177 | * | ||
178 | * @param cls the `struct GNUNET_SECRETSHARING_Session` | ||
179 | * @param m message with the result | ||
180 | */ | ||
181 | static void | ||
182 | handle_secret_ready (void *cls, | ||
183 | const struct GNUNET_SECRETSHARING_SecretReadyMessage *m) | ||
184 | { | ||
185 | struct GNUNET_SECRETSHARING_Session *s = cls; | ||
186 | struct GNUNET_SECRETSHARING_Share *share; | ||
187 | size_t share_size; | ||
188 | |||
189 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
190 | "Got secret ready message of size %u\n", | ||
191 | ntohs (m->header.size)); | ||
192 | share_size = ntohs (m->header.size) - sizeof(struct | ||
193 | GNUNET_SECRETSHARING_SecretReadyMessage); | ||
194 | |||
195 | share = GNUNET_SECRETSHARING_share_read (&m[1], | ||
196 | share_size, | ||
197 | NULL); | ||
198 | GNUNET_assert (NULL != share); // FIXME: this can fail! | ||
199 | // should have been checked in #check_secret_ready! | ||
200 | // FIXME: below we never check &m[1] is valid! | ||
201 | // FIXME: do we leak 'share' here? | ||
202 | s->secret_ready_cb (s->secret_ready_cls, | ||
203 | share, /* FIXME */ | ||
204 | &share->public_key, | ||
205 | share->num_peers, | ||
206 | (const struct GNUNET_PeerIdentity *) &m[1]); | ||
207 | |||
208 | GNUNET_SECRETSHARING_session_destroy (s); | ||
209 | } | ||
210 | |||
211 | |||
212 | /** | ||
213 | * Destroy a secret sharing session. | ||
214 | * The secret ready callback will not be called. | ||
215 | * | ||
216 | * @param s session to destroy | ||
217 | */ | ||
218 | void | ||
219 | GNUNET_SECRETSHARING_session_destroy (struct GNUNET_SECRETSHARING_Session *s) | ||
220 | { | ||
221 | GNUNET_MQ_destroy (s->mq); | ||
222 | s->mq = NULL; | ||
223 | GNUNET_free (s); | ||
224 | } | ||
225 | |||
226 | |||
227 | /** | ||
228 | * Create a session that will eventually establish a shared secret | ||
229 | * with the other peers. | ||
230 | * | ||
231 | * @param cfg configuration to use | ||
232 | * @param num_peers number of peers in @a peers | ||
233 | * @param peers array of peers that we will share secrets with, can optionally contain the local peer | ||
234 | * @param session_id unique session id | ||
235 | * @param start When should all peers be available for sharing the secret? | ||
236 | * Random number generation can take place before the start time. | ||
237 | * @param deadline point in time where the session must be established; taken as hint | ||
238 | * by underlying consensus sessions | ||
239 | * @param threshold minimum number of peers that must cooperate to decrypt a value | ||
240 | * @param cb called when the secret has been established | ||
241 | * @param cls closure for @a cb | ||
242 | */ | ||
243 | struct GNUNET_SECRETSHARING_Session * | ||
244 | GNUNET_SECRETSHARING_create_session (const struct | ||
245 | GNUNET_CONFIGURATION_Handle *cfg, | ||
246 | unsigned int num_peers, | ||
247 | const struct GNUNET_PeerIdentity *peers, | ||
248 | const struct GNUNET_HashCode *session_id, | ||
249 | struct GNUNET_TIME_Absolute start, | ||
250 | struct GNUNET_TIME_Absolute deadline, | ||
251 | unsigned int threshold, | ||
252 | GNUNET_SECRETSHARING_SecretReadyCallback cb, | ||
253 | void *cls) | ||
254 | { | ||
255 | struct GNUNET_SECRETSHARING_Session *s | ||
256 | = GNUNET_new (struct GNUNET_SECRETSHARING_Session); | ||
257 | struct GNUNET_MQ_MessageHandler mq_handlers[] = { | ||
258 | GNUNET_MQ_hd_var_size (secret_ready, | ||
259 | GNUNET_MESSAGE_TYPE_SECRETSHARING_CLIENT_SECRET_READY, | ||
260 | struct GNUNET_SECRETSHARING_SecretReadyMessage, | ||
261 | s), | ||
262 | GNUNET_MQ_handler_end () | ||
263 | }; | ||
264 | struct GNUNET_MQ_Envelope *ev; | ||
265 | struct GNUNET_SECRETSHARING_CreateMessage *msg; | ||
266 | |||
267 | s->mq = GNUNET_CLIENT_connect (cfg, | ||
268 | "secretsharing", | ||
269 | mq_handlers, | ||
270 | &handle_session_client_error, | ||
271 | s); | ||
272 | if (NULL == s->mq) | ||
273 | { | ||
274 | /* secretsharing not configured correctly */ | ||
275 | GNUNET_break (0); | ||
276 | GNUNET_free (s); | ||
277 | return NULL; | ||
278 | } | ||
279 | s->secret_ready_cb = cb; | ||
280 | s->secret_ready_cls = cls; | ||
281 | ev = GNUNET_MQ_msg_extra (msg, | ||
282 | num_peers * sizeof(struct GNUNET_PeerIdentity), | ||
283 | GNUNET_MESSAGE_TYPE_SECRETSHARING_CLIENT_GENERATE); | ||
284 | |||
285 | msg->threshold = htons (threshold); | ||
286 | msg->num_peers = htons (num_peers); | ||
287 | msg->session_id = *session_id; | ||
288 | msg->start = GNUNET_TIME_absolute_hton (start); | ||
289 | msg->deadline = GNUNET_TIME_absolute_hton (deadline); | ||
290 | GNUNET_memcpy (&msg[1], peers, num_peers * sizeof(struct | ||
291 | GNUNET_PeerIdentity)); | ||
292 | |||
293 | GNUNET_MQ_send (s->mq, ev); | ||
294 | |||
295 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
296 | "Secretsharing session created with %u peers\n", | ||
297 | num_peers); | ||
298 | return s; | ||
299 | } | ||
300 | |||
301 | |||
302 | static void | ||
303 | handle_decrypt_done (void *cls, | ||
304 | const struct | ||
305 | GNUNET_SECRETSHARING_DecryptResponseMessage *m) | ||
306 | { | ||
307 | struct GNUNET_SECRETSHARING_DecryptionHandle *dh = cls; | ||
308 | const struct GNUNET_SECRETSHARING_Plaintext *plaintext; | ||
309 | |||
310 | if (m->success == 0) | ||
311 | plaintext = NULL; | ||
312 | else | ||
313 | plaintext = (void *) &m->plaintext; | ||
314 | dh->decrypt_cb (dh->decrypt_cls, plaintext); | ||
315 | GNUNET_SECRETSHARING_decrypt_cancel (dh); | ||
316 | } | ||
317 | |||
318 | |||
319 | /** | ||
320 | * Publish the given ciphertext for decryption. Once a sufficient (>=k) number of peers has | ||
321 | * published the same value, it will be decrypted. | ||
322 | * | ||
323 | * When the operation is canceled, the decrypt_cb is not called anymore, but the calling | ||
324 | * peer may already have irrevocably contributed its share for the decryption of the value. | ||
325 | * | ||
326 | * @param share our secret share to use for decryption | ||
327 | * @param ciphertext ciphertext to publish in order to decrypt it (if enough peers agree) | ||
328 | * @param decrypt_cb callback called once the decryption succeeded | ||
329 | * @param decrypt_cb_cls closure for @a decrypt_cb | ||
330 | * @return handle to cancel the operation | ||
331 | */ | ||
332 | struct GNUNET_SECRETSHARING_DecryptionHandle * | ||
333 | GNUNET_SECRETSHARING_decrypt (const struct GNUNET_CONFIGURATION_Handle *cfg, | ||
334 | struct GNUNET_SECRETSHARING_Share *share, | ||
335 | const struct | ||
336 | GNUNET_SECRETSHARING_Ciphertext *ciphertext, | ||
337 | struct GNUNET_TIME_Absolute start, | ||
338 | struct GNUNET_TIME_Absolute deadline, | ||
339 | GNUNET_SECRETSHARING_DecryptCallback decrypt_cb, | ||
340 | void *decrypt_cb_cls) | ||
341 | { | ||
342 | struct GNUNET_SECRETSHARING_DecryptionHandle *s | ||
343 | = GNUNET_new (struct GNUNET_SECRETSHARING_DecryptionHandle); | ||
344 | struct GNUNET_MQ_MessageHandler mq_handlers[] = { | ||
345 | GNUNET_MQ_hd_fixed_size (decrypt_done, | ||
346 | GNUNET_MESSAGE_TYPE_SECRETSHARING_CLIENT_DECRYPT_DONE, | ||
347 | struct GNUNET_SECRETSHARING_DecryptResponseMessage, | ||
348 | s), | ||
349 | GNUNET_MQ_handler_end () | ||
350 | }; | ||
351 | struct GNUNET_MQ_Envelope *ev; | ||
352 | struct GNUNET_SECRETSHARING_DecryptRequestMessage *msg; | ||
353 | size_t share_size; | ||
354 | |||
355 | s->decrypt_cb = decrypt_cb; | ||
356 | s->decrypt_cls = decrypt_cb_cls; | ||
357 | s->mq = GNUNET_CLIENT_connect (cfg, | ||
358 | "secretsharing", | ||
359 | mq_handlers, | ||
360 | &handle_decrypt_client_error, | ||
361 | s); | ||
362 | if (NULL == s->mq) | ||
363 | { | ||
364 | GNUNET_free (s); | ||
365 | return NULL; | ||
366 | } | ||
367 | GNUNET_assert (GNUNET_OK == | ||
368 | GNUNET_SECRETSHARING_share_write (share, NULL, 0, | ||
369 | &share_size)); | ||
370 | |||
371 | ev = GNUNET_MQ_msg_extra (msg, | ||
372 | share_size, | ||
373 | GNUNET_MESSAGE_TYPE_SECRETSHARING_CLIENT_DECRYPT); | ||
374 | |||
375 | GNUNET_assert (GNUNET_OK == | ||
376 | GNUNET_SECRETSHARING_share_write (share, | ||
377 | &msg[1], | ||
378 | share_size, | ||
379 | NULL)); | ||
380 | |||
381 | msg->start = GNUNET_TIME_absolute_hton (start); | ||
382 | msg->deadline = GNUNET_TIME_absolute_hton (deadline); | ||
383 | msg->ciphertext = *ciphertext; | ||
384 | |||
385 | GNUNET_MQ_send (s->mq, ev); | ||
386 | |||
387 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
388 | "decrypt session created\n"); | ||
389 | return s; | ||
390 | } | ||
391 | |||
392 | |||
393 | int | ||
394 | GNUNET_SECRETSHARING_plaintext_generate_i (struct | ||
395 | GNUNET_SECRETSHARING_Plaintext * | ||
396 | plaintext, | ||
397 | int64_t exponent) | ||
398 | { | ||
399 | int negative; | ||
400 | gcry_mpi_t x; | ||
401 | |||
402 | ensure_elgamal_initialized (); | ||
403 | |||
404 | GNUNET_assert (NULL != (x = gcry_mpi_new (0))); | ||
405 | |||
406 | negative = GNUNET_NO; | ||
407 | if (exponent < 0) | ||
408 | { | ||
409 | negative = GNUNET_YES; | ||
410 | exponent = -exponent; | ||
411 | } | ||
412 | |||
413 | gcry_mpi_set_ui (x, exponent); | ||
414 | |||
415 | gcry_mpi_powm (x, elgamal_g, x, elgamal_p); | ||
416 | |||
417 | if (GNUNET_YES == negative) | ||
418 | { | ||
419 | int res; | ||
420 | res = gcry_mpi_invm (x, x, elgamal_p); | ||
421 | if (0 == res) | ||
422 | return GNUNET_SYSERR; | ||
423 | } | ||
424 | |||
425 | GNUNET_CRYPTO_mpi_print_unsigned (plaintext, | ||
426 | sizeof(struct | ||
427 | GNUNET_SECRETSHARING_Plaintext), | ||
428 | x); | ||
429 | |||
430 | return GNUNET_OK; | ||
431 | } | ||
432 | |||
433 | |||
434 | /** | ||
435 | * Encrypt a value. This operation is executed locally, no communication is | ||
436 | * necessary. | ||
437 | * | ||
438 | * This is a helper function, encryption can be done solely with a session's public key | ||
439 | * and the crypto system parameters. | ||
440 | * | ||
441 | * @param public_key public key to use for decryption | ||
442 | * @param message message to encrypt | ||
443 | * @param message_size number of bytes in @a message | ||
444 | * @param result_ciphertext pointer to store the resulting ciphertext | ||
445 | * @return #GNUNET_YES on success, #GNUNET_SYSERR if the message is invalid (invalid range) | ||
446 | */ | ||
447 | int | ||
448 | GNUNET_SECRETSHARING_encrypt (const struct | ||
449 | GNUNET_SECRETSHARING_PublicKey *public_key, | ||
450 | const struct | ||
451 | GNUNET_SECRETSHARING_Plaintext *plaintext, | ||
452 | struct GNUNET_SECRETSHARING_Ciphertext * | ||
453 | result_ciphertext) | ||
454 | { | ||
455 | /* pubkey */ | ||
456 | gcry_mpi_t h; | ||
457 | /* nonce */ | ||
458 | gcry_mpi_t y; | ||
459 | /* plaintext message */ | ||
460 | gcry_mpi_t m; | ||
461 | /* temp value */ | ||
462 | gcry_mpi_t tmp; | ||
463 | |||
464 | ensure_elgamal_initialized (); | ||
465 | |||
466 | GNUNET_assert (NULL != (h = gcry_mpi_new (0))); | ||
467 | GNUNET_assert (NULL != (y = gcry_mpi_new (0))); | ||
468 | GNUNET_assert (NULL != (tmp = gcry_mpi_new (0))); | ||
469 | |||
470 | GNUNET_CRYPTO_mpi_scan_unsigned (&h, public_key, sizeof *public_key); | ||
471 | GNUNET_CRYPTO_mpi_scan_unsigned (&m, plaintext, sizeof *plaintext); | ||
472 | |||
473 | // Randomize y such that 0 < y < elgamal_q. | ||
474 | // The '- 1' is necessary as bitlength(q) = bitlength(p) - 1. | ||
475 | do | ||
476 | { | ||
477 | gcry_mpi_randomize (y, GNUNET_SECRETSHARING_ELGAMAL_BITS - 1, | ||
478 | GCRY_WEAK_RANDOM); | ||
479 | } | ||
480 | while ((gcry_mpi_cmp_ui (y, 0) == 0) || (gcry_mpi_cmp (y, elgamal_q) >= 0)); | ||
481 | |||
482 | // tmp <- g^y | ||
483 | gcry_mpi_powm (tmp, elgamal_g, y, elgamal_p); | ||
484 | // write tmp to c1 | ||
485 | GNUNET_CRYPTO_mpi_print_unsigned (&result_ciphertext->c1_bits, | ||
486 | GNUNET_SECRETSHARING_ELGAMAL_BITS / 8, tmp); | ||
487 | |||
488 | // tmp <- h^y | ||
489 | gcry_mpi_powm (tmp, h, y, elgamal_p); | ||
490 | // tmp <- tmp * m | ||
491 | gcry_mpi_mulm (tmp, tmp, m, elgamal_p); | ||
492 | // write tmp to c2 | ||
493 | GNUNET_CRYPTO_mpi_print_unsigned (&result_ciphertext->c2_bits, | ||
494 | GNUNET_SECRETSHARING_ELGAMAL_BITS / 8, tmp); | ||
495 | |||
496 | return GNUNET_OK; | ||
497 | } | ||
498 | |||
499 | |||
500 | /** | ||
501 | * Cancel a decryption. | ||
502 | * | ||
503 | * The decrypt_cb is not called anymore, but the calling | ||
504 | * peer may already have irrevocably contributed its share for the decryption of the value. | ||
505 | * | ||
506 | * @param dh to cancel | ||
507 | */ | ||
508 | void | ||
509 | GNUNET_SECRETSHARING_decrypt_cancel (struct | ||
510 | GNUNET_SECRETSHARING_DecryptionHandle *dh) | ||
511 | { | ||
512 | GNUNET_MQ_destroy (dh->mq); | ||
513 | dh->mq = NULL; | ||
514 | GNUNET_free (dh); | ||
515 | } | ||
516 | |||
517 | |||
518 | /* end of secretsharing_api.c */ | ||
diff --git a/src/secretsharing/secretsharing_common.c b/src/secretsharing/secretsharing_common.c deleted file mode 100644 index 3003109a4..000000000 --- a/src/secretsharing/secretsharing_common.c +++ /dev/null | |||
@@ -1,158 +0,0 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet. | ||
3 | Copyright (C) 2014 GNUnet e.V. | ||
4 | |||
5 | GNUnet is free software: you can redistribute it and/or modify it | ||
6 | under the terms of the GNU Affero General Public License as published | ||
7 | by the Free Software Foundation, either version 3 of the License, | ||
8 | or (at your option) any later version. | ||
9 | |||
10 | GNUnet is distributed in the hope that it will be useful, but | ||
11 | WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
13 | Affero General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU Affero General Public License | ||
16 | along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
17 | |||
18 | SPDX-License-Identifier: AGPL3.0-or-later | ||
19 | */ | ||
20 | |||
21 | #include "secretsharing.h" | ||
22 | |||
23 | /** | ||
24 | * Read a share from its binary representation. | ||
25 | * | ||
26 | * @param data Binary representation of the share. | ||
27 | * @param len Length of @a data. | ||
28 | * @param[out] readlen Number of bytes read, | ||
29 | * ignored if NULL. | ||
30 | * @return The share, or NULL on error. | ||
31 | */ | ||
32 | struct GNUNET_SECRETSHARING_Share * | ||
33 | GNUNET_SECRETSHARING_share_read (const void *data, | ||
34 | size_t len, | ||
35 | size_t *readlen) | ||
36 | { | ||
37 | struct GNUNET_SECRETSHARING_Share *share; | ||
38 | const struct GNUNET_SECRETSHARING_ShareHeaderNBO *sh = data; | ||
39 | const char *p; | ||
40 | size_t n; | ||
41 | uint16_t payload_size; | ||
42 | |||
43 | payload_size = ntohs (sh->num_peers) | ||
44 | * (sizeof(uint16_t) + sizeof(struct | ||
45 | GNUNET_SECRETSHARING_FieldElement) | ||
46 | + sizeof(struct GNUNET_PeerIdentity)); | ||
47 | |||
48 | if (NULL != readlen) | ||
49 | *readlen = payload_size + sizeof *sh; | ||
50 | |||
51 | share = GNUNET_new (struct GNUNET_SECRETSHARING_Share); | ||
52 | |||
53 | share->threshold = ntohs (sh->threshold); | ||
54 | share->num_peers = ntohs (sh->num_peers); | ||
55 | share->my_peer = ntohs (sh->my_peer); | ||
56 | |||
57 | share->my_share = sh->my_share; | ||
58 | share->public_key = sh->public_key; | ||
59 | |||
60 | p = (const char *) &sh[1]; | ||
61 | |||
62 | n = share->num_peers * sizeof(struct GNUNET_PeerIdentity); | ||
63 | share->peers = GNUNET_new_array (share->num_peers, | ||
64 | struct GNUNET_PeerIdentity); | ||
65 | GNUNET_memcpy (share->peers, p, n); | ||
66 | p += n; | ||
67 | |||
68 | n = share->num_peers * sizeof(struct GNUNET_SECRETSHARING_FieldElement); | ||
69 | share->sigmas = GNUNET_new_array (share->num_peers, | ||
70 | struct GNUNET_SECRETSHARING_FieldElement); | ||
71 | GNUNET_memcpy (share->sigmas, p, n); | ||
72 | p += n; | ||
73 | |||
74 | n = share->num_peers * sizeof(uint16_t); | ||
75 | share->original_indices = GNUNET_new_array (share->num_peers, | ||
76 | uint16_t); | ||
77 | GNUNET_memcpy (share->original_indices, p, n); | ||
78 | |||
79 | return share; | ||
80 | } | ||
81 | |||
82 | |||
83 | /** | ||
84 | * Convert a share to its binary representation. | ||
85 | * Can be called with a NULL @a buf to get the size of the share. | ||
86 | * | ||
87 | * @param share Share to write. | ||
88 | * @param buf Buffer to write to. | ||
89 | * @param buflen Number of writable bytes in @a buf. | ||
90 | * @param[out] writelen Pointer to store number of bytes written, | ||
91 | * ignored if NULL. | ||
92 | * @return #GNUNET_OK on success, #GNUNET_SYSERR on failure. | ||
93 | */ | ||
94 | int | ||
95 | GNUNET_SECRETSHARING_share_write (const struct | ||
96 | GNUNET_SECRETSHARING_Share *share, | ||
97 | void *buf, size_t buflen, size_t *writelen) | ||
98 | { | ||
99 | uint16_t payload_size; | ||
100 | struct GNUNET_SECRETSHARING_ShareHeaderNBO *sh; | ||
101 | char *p; | ||
102 | int n; | ||
103 | |||
104 | payload_size = share->num_peers | ||
105 | * (sizeof(uint16_t) + sizeof(struct | ||
106 | GNUNET_SECRETSHARING_FieldElement) | ||
107 | + sizeof(struct GNUNET_PeerIdentity)); | ||
108 | |||
109 | if (NULL != writelen) | ||
110 | *writelen = payload_size + sizeof(struct | ||
111 | GNUNET_SECRETSHARING_ShareHeaderNBO); | ||
112 | |||
113 | /* just a query for the writelen */ | ||
114 | if (buf == NULL) | ||
115 | return GNUNET_OK; | ||
116 | |||
117 | /* wrong buffer size */ | ||
118 | if (buflen < payload_size + sizeof(struct | ||
119 | GNUNET_SECRETSHARING_ShareHeaderNBO)) | ||
120 | return GNUNET_SYSERR; | ||
121 | |||
122 | sh = buf; | ||
123 | |||
124 | sh->threshold = htons (share->threshold); | ||
125 | sh->num_peers = htons (share->num_peers); | ||
126 | sh->my_peer = htons (share->my_peer); | ||
127 | |||
128 | sh->my_share = share->my_share; | ||
129 | sh->public_key = share->public_key; | ||
130 | |||
131 | p = (void *) &sh[1]; | ||
132 | |||
133 | n = share->num_peers * sizeof(struct GNUNET_PeerIdentity); | ||
134 | GNUNET_memcpy (p, share->peers, n); | ||
135 | p += n; | ||
136 | |||
137 | n = share->num_peers * sizeof(struct GNUNET_SECRETSHARING_FieldElement); | ||
138 | GNUNET_memcpy (p, share->sigmas, n); | ||
139 | p += n; | ||
140 | |||
141 | n = share->num_peers * sizeof(uint16_t); | ||
142 | GNUNET_memcpy (p, share->original_indices, n); | ||
143 | |||
144 | return GNUNET_OK; | ||
145 | } | ||
146 | |||
147 | |||
148 | void | ||
149 | GNUNET_SECRETSHARING_share_destroy (struct GNUNET_SECRETSHARING_Share *share) | ||
150 | { | ||
151 | GNUNET_free (share->original_indices); | ||
152 | share->original_indices = NULL; | ||
153 | GNUNET_free (share->sigmas); | ||
154 | share->sigmas = NULL; | ||
155 | GNUNET_free (share->peers); | ||
156 | share->peers = NULL; | ||
157 | GNUNET_free (share); | ||
158 | } | ||
diff --git a/src/secretsharing/secretsharing_protocol.h b/src/secretsharing/secretsharing_protocol.h deleted file mode 100644 index d4aaecb6c..000000000 --- a/src/secretsharing/secretsharing_protocol.h +++ /dev/null | |||
@@ -1,147 +0,0 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet | ||
3 | Copyright (C) 2012 GNUnet e.V. | ||
4 | |||
5 | GNUnet is free software: you can redistribute it and/or modify it | ||
6 | under the terms of the GNU Affero General Public License as published | ||
7 | by the Free Software Foundation, either version 3 of the License, | ||
8 | or (at your option) any later version. | ||
9 | |||
10 | GNUnet is distributed in the hope that it will be useful, but | ||
11 | WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
13 | Affero General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU Affero General Public License | ||
16 | along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
17 | |||
18 | SPDX-License-Identifier: AGPL3.0-or-later | ||
19 | */ | ||
20 | |||
21 | |||
22 | /** | ||
23 | * @file secretsharing/secretsharing_protocol.h | ||
24 | * @brief p2p message definitions for secretsharing | ||
25 | * @author Florian Dold | ||
26 | */ | ||
27 | |||
28 | #ifndef GNUNET_SECRETSHARING_PROTOCOL_H | ||
29 | #define GNUNET_SECRETSHARING_PROTOCOL_H | ||
30 | |||
31 | #include "platform.h" | ||
32 | #include "gnunet_common.h" | ||
33 | #include "gnunet_protocols.h" | ||
34 | #include "secretsharing.h" | ||
35 | |||
36 | |||
37 | GNUNET_NETWORK_STRUCT_BEGIN | ||
38 | |||
39 | |||
40 | /** | ||
41 | * Consensus element data used in the first round of key generation. | ||
42 | */ | ||
43 | struct GNUNET_SECRETSHARING_KeygenCommitData | ||
44 | { | ||
45 | /** | ||
46 | * Signature over the rest of the message. | ||
47 | */ | ||
48 | struct GNUNET_CRYPTO_EddsaSignature signature; | ||
49 | /** | ||
50 | * Signature purpose for signing the keygen commit data. | ||
51 | */ | ||
52 | struct GNUNET_CRYPTO_EccSignaturePurpose purpose; | ||
53 | /** | ||
54 | * Peer that inserts this element. | ||
55 | */ | ||
56 | struct GNUNET_PeerIdentity peer; | ||
57 | /** | ||
58 | * Ephemeral paillier public key used by 'peer' for | ||
59 | * this session. | ||
60 | */ | ||
61 | struct GNUNET_CRYPTO_PaillierPublicKey pubkey; | ||
62 | /** | ||
63 | * Commitment of 'peer' to its presecret. | ||
64 | */ | ||
65 | struct GNUNET_HashCode commitment GNUNET_PACKED; | ||
66 | }; | ||
67 | |||
68 | |||
69 | struct GNUNET_SECRETSHARING_KeygenRevealData | ||
70 | { | ||
71 | /** | ||
72 | * Signature over rest of the message. | ||
73 | */ | ||
74 | struct GNUNET_CRYPTO_EddsaSignature signature; | ||
75 | /* | ||
76 | * Signature purpose for signing the keygen commit data. | ||
77 | */ | ||
78 | struct GNUNET_CRYPTO_EccSignaturePurpose purpose; | ||
79 | /** | ||
80 | * Peer that inserts this element. | ||
81 | */ | ||
82 | struct GNUNET_PeerIdentity peer; | ||
83 | |||
84 | /* values follow */ | ||
85 | }; | ||
86 | |||
87 | |||
88 | /** | ||
89 | * Data of then element put in consensus | ||
90 | * for decrypting a value. | ||
91 | */ | ||
92 | struct GNUNET_SECRETSHARING_DecryptData | ||
93 | { | ||
94 | /* | ||
95 | * Signature over rest of the message. | ||
96 | */ | ||
97 | struct GNUNET_CRYPTO_EddsaSignature signature; | ||
98 | /* | ||
99 | * Signature purpose for signing the keygen commit data. | ||
100 | */ | ||
101 | struct GNUNET_CRYPTO_EccSignaturePurpose purpose; | ||
102 | /** | ||
103 | * Ciphertext we want to decrypt. | ||
104 | */ | ||
105 | struct GNUNET_SECRETSHARING_Ciphertext ciphertext; | ||
106 | /** | ||
107 | * Peer that inserts this element. | ||
108 | */ | ||
109 | struct GNUNET_PeerIdentity peer; | ||
110 | /** | ||
111 | * Partial decryption, computed as c_1^{s_i} | ||
112 | */ | ||
113 | struct GNUNET_SECRETSHARING_FieldElement partial_decryption; | ||
114 | /** | ||
115 | * Commitment for the non-interactive zero knowledge proof. | ||
116 | * g^\beta, with \beta < q | ||
117 | */ | ||
118 | struct GNUNET_SECRETSHARING_FieldElement nizk_commit1; | ||
119 | /** | ||
120 | * Commitment for the non-interactive zero knowledge proof. | ||
121 | * c_1^\beta, with \beta < q | ||
122 | */ | ||
123 | struct GNUNET_SECRETSHARING_FieldElement nizk_commit2; | ||
124 | /** | ||
125 | * Response to the challenge computed from the protocol transcript. | ||
126 | * r = \beta + challenge \cdot share_i | ||
127 | */ | ||
128 | struct GNUNET_SECRETSHARING_FieldElement nizk_response; | ||
129 | }; | ||
130 | |||
131 | |||
132 | struct GNUNET_SECRETSHARING_FairEncryption | ||
133 | { | ||
134 | struct GNUNET_CRYPTO_PaillierCiphertext c; | ||
135 | /** | ||
136 | * h = g^x, where x is the fairly encrypted secret. | ||
137 | */ | ||
138 | char h[GNUNET_SECRETSHARING_ELGAMAL_BITS / 8]; | ||
139 | char t1[GNUNET_SECRETSHARING_ELGAMAL_BITS / 8]; | ||
140 | char t2[GNUNET_CRYPTO_PAILLIER_BITS * 2 / 8]; | ||
141 | char z[GNUNET_SECRETSHARING_ELGAMAL_BITS / 8]; | ||
142 | char w[GNUNET_CRYPTO_PAILLIER_BITS / 8]; | ||
143 | }; | ||
144 | |||
145 | GNUNET_NETWORK_STRUCT_END | ||
146 | |||
147 | #endif | ||
diff --git a/src/secretsharing/test_secretsharing.conf b/src/secretsharing/test_secretsharing.conf deleted file mode 100644 index 9cbe3ebb1..000000000 --- a/src/secretsharing/test_secretsharing.conf +++ /dev/null | |||
@@ -1,40 +0,0 @@ | |||
1 | [secretsharing] | ||
2 | START_ON_DEMAND = YES | ||
3 | #PREFIX = valgrind --leak-check=full | ||
4 | OPTIONS = -LINFO | ||
5 | |||
6 | [consensus] | ||
7 | START_ON_DEMAND = YES | ||
8 | |||
9 | [transport] | ||
10 | OPTIONS = -LERROR | ||
11 | PLUGINS = unix | ||
12 | |||
13 | [set] | ||
14 | OPTIONS = -L INFO | ||
15 | START_ON_DEMAND = YES | ||
16 | #PREFIX = valgrind --leak-check=full | ||
17 | |||
18 | [testbed] | ||
19 | OVERLAY_TOPOLOGY = CLIQUE | ||
20 | |||
21 | [hostlist] | ||
22 | SERVERS = | ||
23 | |||
24 | [nat] | ||
25 | # Use addresses from the local network interfaces (including loopback, but also others) | ||
26 | USE_LOCALADDR = YES | ||
27 | |||
28 | # Disable IPv6 support | ||
29 | DISABLEV6 = NO | ||
30 | |||
31 | # Do we use addresses from localhost address ranges? (::1, 127.0.0.0/8) | ||
32 | RETURN_LOCAL_ADDRESSES = YES | ||
33 | |||
34 | [nse] | ||
35 | START_ON_DEMAND = NO | ||
36 | |||
37 | |||
38 | [rps] | ||
39 | START_ON_DEMAND = NO | ||
40 | IMMEDIATE_START = NO | ||
diff --git a/src/secretsharing/test_secretsharing_api.c b/src/secretsharing/test_secretsharing_api.c deleted file mode 100644 index 227af1c3e..000000000 --- a/src/secretsharing/test_secretsharing_api.c +++ /dev/null | |||
@@ -1,102 +0,0 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet. | ||
3 | Copyright (C) 2014 GNUnet e.V. | ||
4 | |||
5 | GNUnet is free software: you can redistribute it and/or modify it | ||
6 | under the terms of the GNU Affero General Public License as published | ||
7 | by the Free Software Foundation, either version 3 of the License, | ||
8 | or (at your option) any later version. | ||
9 | |||
10 | GNUnet is distributed in the hope that it will be useful, but | ||
11 | WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
13 | Affero General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU Affero General Public License | ||
16 | along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
17 | |||
18 | SPDX-License-Identifier: AGPL3.0-or-later | ||
19 | */ | ||
20 | |||
21 | /** | ||
22 | * @file secretsharing/test_secretsharing_api.c | ||
23 | * @brief testcase for the secretsharing api | ||
24 | */ | ||
25 | #include "platform.h" | ||
26 | #include "gnunet_util_lib.h" | ||
27 | #include "gnunet_testing_lib.h" | ||
28 | #include "gnunet_secretsharing_service.h" | ||
29 | |||
30 | |||
31 | static int success; | ||
32 | |||
33 | static struct GNUNET_SECRETSHARING_Session *keygen; | ||
34 | |||
35 | |||
36 | static void | ||
37 | secret_ready_cb (void *cls, | ||
38 | struct GNUNET_SECRETSHARING_Share *my_share, | ||
39 | struct GNUNET_SECRETSHARING_PublicKey *public_key, | ||
40 | unsigned int num_ready_peers, | ||
41 | const struct GNUNET_PeerIdentity *ready_peers) | ||
42 | { | ||
43 | keygen = NULL; | ||
44 | if (num_ready_peers == 1) | ||
45 | success = 1; | ||
46 | // FIXME: check that our share is valid, which we can do as there's only | ||
47 | // one peer. | ||
48 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, "secret ready, shutting down\n"); | ||
49 | GNUNET_SCHEDULER_shutdown (); | ||
50 | } | ||
51 | |||
52 | |||
53 | static void | ||
54 | handle_shutdown (void *cls) | ||
55 | { | ||
56 | if (NULL != keygen) | ||
57 | { | ||
58 | GNUNET_SECRETSHARING_session_destroy (keygen); | ||
59 | keygen = NULL; | ||
60 | } | ||
61 | } | ||
62 | |||
63 | |||
64 | static void | ||
65 | run (void *cls, | ||
66 | const struct GNUNET_CONFIGURATION_Handle *cfg, | ||
67 | struct GNUNET_TESTING_Peer *peer) | ||
68 | { | ||
69 | struct GNUNET_HashCode session_id; | ||
70 | struct GNUNET_TIME_Absolute start; | ||
71 | struct GNUNET_TIME_Absolute deadline; | ||
72 | |||
73 | GNUNET_SCHEDULER_add_shutdown (&handle_shutdown, NULL); | ||
74 | |||
75 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, "testing secretsharing api\n"); | ||
76 | |||
77 | GNUNET_CRYPTO_hash_create_random (GNUNET_CRYPTO_QUALITY_WEAK, &session_id); | ||
78 | |||
79 | start = GNUNET_TIME_absolute_get (); | ||
80 | deadline = GNUNET_TIME_absolute_add (start, GNUNET_TIME_UNIT_SECONDS); | ||
81 | |||
82 | keygen = GNUNET_SECRETSHARING_create_session (cfg, | ||
83 | 0, NULL, /* only the local peer */ | ||
84 | &session_id, | ||
85 | start, deadline, | ||
86 | 1, | ||
87 | secret_ready_cb, NULL); | ||
88 | } | ||
89 | |||
90 | |||
91 | int | ||
92 | main (int argc, char **argv) | ||
93 | { | ||
94 | int ret; | ||
95 | |||
96 | ret = GNUNET_TESTING_peer_run ("test_secretsharing_api", | ||
97 | "test_secretsharing.conf", | ||
98 | &run, NULL); | ||
99 | if (0 != ret) | ||
100 | return ret; | ||
101 | return (GNUNET_YES == success) ? 0 : 1; | ||
102 | } | ||