aboutsummaryrefslogtreecommitdiff
path: root/src/secretsharing/gnunet-secretsharing-profiler.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/secretsharing/gnunet-secretsharing-profiler.c')
-rw-r--r--src/secretsharing/gnunet-secretsharing-profiler.c662
1 files changed, 0 insertions, 662 deletions
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 */
34static unsigned int num_peers = 3;
35
36/**
37 * What should the threshold for then key be?
38 */
39static unsigned int threshold = 2;
40
41/**
42 * Should we try to decrypt a value after the key generation?
43 */
44static int decrypt = GNUNET_NO;
45
46/**
47 * When would we like to see the operation finished?
48 */
49static struct GNUNET_TIME_Relative timeout;
50
51/**
52 * When should dkg communication start?
53 */
54static struct GNUNET_TIME_Relative delay;
55
56/**
57 * Handles for secretsharing sessions.
58 */
59static struct GNUNET_SECRETSHARING_Session **session_handles;
60
61static struct GNUNET_SECRETSHARING_DecryptionHandle **decrypt_handles;
62
63/**
64 * Shares we got from the distributed key generation.
65 */
66static struct GNUNET_SECRETSHARING_Share **shares;
67
68static struct GNUNET_SECRETSHARING_PublicKey common_pubkey;
69
70
71static unsigned int num_connected_sessions;
72
73static 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 */
79static struct GNUNET_TESTBED_Peer **peers;
80
81static struct GNUNET_PeerIdentity *peer_ids;
82
83static unsigned int num_retrieved_peer_ids;
84
85static unsigned int num_generated;
86
87static unsigned int num_decrypted;
88
89static struct GNUNET_HashCode session_id;
90
91static unsigned int verbose;
92
93static struct GNUNET_SECRETSHARING_Plaintext reference_plaintext;
94
95static struct GNUNET_SECRETSHARING_Ciphertext ciphertext;
96
97static struct GNUNET_TIME_Absolute dkg_start;
98
99static struct GNUNET_TIME_Absolute dkg_deadline;
100
101
102static struct GNUNET_TIME_Absolute decrypt_start;
103
104static struct GNUNET_TIME_Absolute decrypt_deadline;
105
106/**
107 * Connect operations, one for every peer.
108 */
109static struct GNUNET_TESTBED_Operation **connect_ops;
110
111/**
112 * Are we performing a shutdown right now?
113 */
114static 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 */
124static void
125controller_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 */
141static void
142session_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 */
177static void
178decrypt_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 */
210static void
211decrypt_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 */
258static void *
259decrypt_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 */
284static void
285decrypt_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
303static void
304secret_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 */
365static void *
366session_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 */
393static void
394session_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 */
455static void
456peer_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 */
495static void
496handle_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 */
530static void
531test_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
569static void
570run (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
617int
618main (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}