aboutsummaryrefslogtreecommitdiff
path: root/src/revocation
diff options
context:
space:
mode:
Diffstat (limited to 'src/revocation')
-rw-r--r--src/revocation/gnunet-revocation.c210
-rw-r--r--src/revocation/gnunet-service-revocation.c39
-rw-r--r--src/revocation/plugin_block_revocation.c30
-rw-r--r--src/revocation/revocation.conf.in1
-rw-r--r--src/revocation/revocation.h19
-rw-r--r--src/revocation/revocation_api.c360
-rw-r--r--src/revocation/test_revocation.c27
-rw-r--r--src/revocation/test_revocation.conf1
8 files changed, 492 insertions, 195 deletions
diff --git a/src/revocation/gnunet-revocation.c b/src/revocation/gnunet-revocation.c
index 14e23b244..8b7cf33c6 100644
--- a/src/revocation/gnunet-revocation.c
+++ b/src/revocation/gnunet-revocation.c
@@ -28,6 +28,10 @@
28#include "gnunet_revocation_service.h" 28#include "gnunet_revocation_service.h"
29#include "gnunet_identity_service.h" 29#include "gnunet_identity_service.h"
30 30
31/**
32 * Pow passes
33 */
34static unsigned int pow_passes = 1;
31 35
32/** 36/**
33 * Final status code. 37 * Final status code.
@@ -55,6 +59,11 @@ static char *revoke_ego;
55static char *test_ego; 59static char *test_ego;
56 60
57/** 61/**
62 * -e option.
63 */
64static unsigned int epochs = 1;
65
66/**
58 * Handle for revocation query. 67 * Handle for revocation query.
59 */ 68 */
60static struct GNUNET_REVOCATION_Query *q; 69static struct GNUNET_REVOCATION_Query *q;
@@ -80,10 +89,19 @@ static const struct GNUNET_CONFIGURATION_Handle *cfg;
80static unsigned long long matching_bits; 89static unsigned long long matching_bits;
81 90
82/** 91/**
92 * Epoch length
93 */
94static struct GNUNET_TIME_Relative epoch_duration;
95
96/**
83 * Task used for proof-of-work calculation. 97 * Task used for proof-of-work calculation.
84 */ 98 */
85static struct GNUNET_SCHEDULER_Task *pow_task; 99static struct GNUNET_SCHEDULER_Task *pow_task;
86 100
101/**
102 * Proof-of-work object
103 */
104static struct GNUNET_REVOCATION_Pow proof_of_work;
87 105
88/** 106/**
89 * Function run if the user aborts with CTRL-C. 107 * Function run if the user aborts with CTRL-C.
@@ -93,6 +111,7 @@ static struct GNUNET_SCHEDULER_Task *pow_task;
93static void 111static void
94do_shutdown (void *cls) 112do_shutdown (void *cls)
95{ 113{
114 fprintf (stderr, "%s", _ ("Shutting down...\n"));
96 if (NULL != el) 115 if (NULL != el)
97 { 116 {
98 GNUNET_IDENTITY_ego_lookup_cancel (el); 117 GNUNET_IDENTITY_ego_lookup_cancel (el);
@@ -188,37 +207,13 @@ print_revocation_result (void *cls, int is_valid)
188 207
189 208
190/** 209/**
191 * Data needed to perform a revocation.
192 */
193struct RevocationData
194{
195 /**
196 * Public key.
197 */
198 struct GNUNET_CRYPTO_EcdsaPublicKey key;
199
200 /**
201 * Revocation signature data.
202 */
203 struct GNUNET_CRYPTO_EcdsaSignature sig;
204
205 /**
206 * Proof of work (in NBO).
207 */
208 uint64_t pow GNUNET_PACKED;
209};
210
211
212/**
213 * Perform the revocation. 210 * Perform the revocation.
214 */ 211 */
215static void 212static void
216perform_revocation (const struct RevocationData *rd) 213perform_revocation ()
217{ 214{
218 h = GNUNET_REVOCATION_revoke (cfg, 215 h = GNUNET_REVOCATION_revoke (cfg,
219 &rd->key, 216 &proof_of_work,
220 &rd->sig,
221 rd->pow,
222 &print_revocation_result, 217 &print_revocation_result,
223 NULL); 218 NULL);
224} 219}
@@ -231,13 +226,13 @@ perform_revocation (const struct RevocationData *rd)
231 * @param rd data to sync 226 * @param rd data to sync
232 */ 227 */
233static void 228static void
234sync_rd (const struct RevocationData *rd) 229sync_pow ()
235{ 230{
236 if ((NULL != filename) && 231 if ((NULL != filename) &&
237 (sizeof(struct RevocationData) == 232 (sizeof(struct GNUNET_REVOCATION_Pow) !=
238 GNUNET_DISK_fn_write (filename, 233 GNUNET_DISK_fn_write (filename,
239 &rd, 234 &proof_of_work,
240 sizeof(rd), 235 sizeof(struct GNUNET_REVOCATION_Pow),
241 GNUNET_DISK_PERM_USER_READ 236 GNUNET_DISK_PERM_USER_READ
242 | GNUNET_DISK_PERM_USER_WRITE))) 237 | GNUNET_DISK_PERM_USER_WRITE)))
243 GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR, "write", filename); 238 GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR, "write", filename);
@@ -252,15 +247,16 @@ sync_rd (const struct RevocationData *rd)
252static void 247static void
253calculate_pow_shutdown (void *cls) 248calculate_pow_shutdown (void *cls)
254{ 249{
255 struct RevocationData *rd = cls; 250 struct GNUNET_REVOCATION_PowCalculationHandle *ph = cls;
256 251 fprintf (stderr, "%s", _ ("Cancelling calculation.\n"));
252 sync_pow ();
257 if (NULL != pow_task) 253 if (NULL != pow_task)
258 { 254 {
259 GNUNET_SCHEDULER_cancel (pow_task); 255 GNUNET_SCHEDULER_cancel (pow_task);
260 pow_task = NULL; 256 pow_task = NULL;
261 } 257 }
262 sync_rd (rd); 258 if (NULL != ph)
263 GNUNET_free (rd); 259 GNUNET_REVOCATION_pow_stop (ph);
264} 260}
265 261
266 262
@@ -272,38 +268,26 @@ calculate_pow_shutdown (void *cls)
272static void 268static void
273calculate_pow (void *cls) 269calculate_pow (void *cls)
274{ 270{
275 struct RevocationData *rd = cls; 271 struct GNUNET_REVOCATION_PowCalculationHandle *ph = cls;
276 272
277 /* store temporary results */ 273 /* store temporary results */
278 pow_task = NULL; 274 pow_task = NULL;
279 if (0 == (rd->pow % 128)) 275 if (0 == (pow_passes % 128))
280 sync_rd (rd); 276 sync_pow ();
281 /* display progress estimate */
282 if ((0 == ((1 << matching_bits) / 100 / 50)) ||
283 (0 == (rd->pow % ((1 << matching_bits) / 100 / 50))))
284 fprintf (stderr, "%s", ".");
285 if ((0 != rd->pow) && ((0 == ((1 << matching_bits) / 100)) ||
286 (0 == (rd->pow % ((1 << matching_bits) / 100)))))
287 fprintf (stderr,
288 " - @ %3u%% (estimate)\n",
289 (unsigned int) (rd->pow * 100) / (1 << matching_bits));
290 /* actually do POW calculation */ 277 /* actually do POW calculation */
291 rd->pow++; 278 if (GNUNET_OK == GNUNET_REVOCATION_pow_round (ph))
292 if (GNUNET_OK == GNUNET_REVOCATION_check_pow (&rd->key,
293 rd->pow,
294 (unsigned int) matching_bits))
295 { 279 {
296 if ((NULL != filename) && 280 if ((NULL != filename) &&
297 (sizeof(struct RevocationData) != 281 (sizeof(struct GNUNET_REVOCATION_Pow) !=
298 GNUNET_DISK_fn_write (filename, 282 GNUNET_DISK_fn_write (filename,
299 rd, 283 &proof_of_work,
300 sizeof(struct RevocationData), 284 sizeof(struct GNUNET_REVOCATION_Pow),
301 GNUNET_DISK_PERM_USER_READ 285 GNUNET_DISK_PERM_USER_READ
302 | GNUNET_DISK_PERM_USER_WRITE))) 286 | GNUNET_DISK_PERM_USER_WRITE)))
303 GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR, "write", filename); 287 GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR, "write", filename);
304 if (perform) 288 if (perform)
305 { 289 {
306 perform_revocation (rd); 290 perform_revocation ();
307 } 291 }
308 else 292 else
309 { 293 {
@@ -316,7 +300,19 @@ calculate_pow (void *cls)
316 } 300 }
317 return; 301 return;
318 } 302 }
319 pow_task = GNUNET_SCHEDULER_add_now (&calculate_pow, rd); 303 pow_passes++;
304 /**
305 * Otherwise CTRL-C does not work
306 */
307 if (0 == pow_passes % 128)
308 pow_task = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_MILLISECONDS,
309 &calculate_pow,
310 ph);
311 else
312 pow_task = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_MILLISECONDS,
313 &calculate_pow,
314 ph);
315
320} 316}
321 317
322 318
@@ -329,8 +325,9 @@ calculate_pow (void *cls)
329static void 325static void
330ego_callback (void *cls, const struct GNUNET_IDENTITY_Ego *ego) 326ego_callback (void *cls, const struct GNUNET_IDENTITY_Ego *ego)
331{ 327{
332 struct RevocationData *rd;
333 struct GNUNET_CRYPTO_EcdsaPublicKey key; 328 struct GNUNET_CRYPTO_EcdsaPublicKey key;
329 const struct GNUNET_CRYPTO_EcdsaPrivateKey *privkey;
330 struct GNUNET_REVOCATION_PowCalculationHandle *ph = NULL;
334 331
335 el = NULL; 332 el = NULL;
336 if (NULL == ego) 333 if (NULL == ego)
@@ -340,44 +337,55 @@ ego_callback (void *cls, const struct GNUNET_IDENTITY_Ego *ego)
340 return; 337 return;
341 } 338 }
342 GNUNET_IDENTITY_ego_get_public_key (ego, &key); 339 GNUNET_IDENTITY_ego_get_public_key (ego, &key);
343 rd = GNUNET_new (struct RevocationData); 340 privkey = GNUNET_IDENTITY_ego_get_private_key (ego);
341 memset (&proof_of_work, 0, sizeof (proof_of_work));
344 if ((NULL != filename) && (GNUNET_YES == GNUNET_DISK_file_test (filename)) && 342 if ((NULL != filename) && (GNUNET_YES == GNUNET_DISK_file_test (filename)) &&
345 (sizeof(struct RevocationData) == 343 (sizeof(proof_of_work) ==
346 GNUNET_DISK_fn_read (filename, rd, sizeof(struct RevocationData)))) 344 GNUNET_DISK_fn_read (filename, &proof_of_work, sizeof(proof_of_work))))
347 { 345 {
348 if (0 != GNUNET_memcmp (&rd->key, &key)) 346 if (0 != GNUNET_memcmp (&proof_of_work.key, &key))
349 { 347 {
350 fprintf (stderr, 348 fprintf (stderr,
351 _ ("Error: revocation certificate in `%s' is not for `%s'\n"), 349 _ ("Error: revocation certificate in `%s' is not for `%s'\n"),
352 filename, 350 filename,
353 revoke_ego); 351 revoke_ego);
354 GNUNET_free (rd);
355 return; 352 return;
356 } 353 }
357 } 354 if (GNUNET_YES ==
358 else 355 GNUNET_REVOCATION_check_pow (&proof_of_work,
359 { 356 (unsigned int) matching_bits,
360 GNUNET_REVOCATION_sign_revocation (GNUNET_IDENTITY_ego_get_private_key ( 357 epoch_duration))
361 ego), 358 {
362 &rd->sig); 359 fprintf (stderr, "%s", _ ("Revocation certificate ready\n"));
363 rd->key = key; 360 if (perform)
364 } 361 perform_revocation ();
365 if (GNUNET_YES == 362 else
366 GNUNET_REVOCATION_check_pow (&key, rd->pow, (unsigned int) matching_bits)) 363 GNUNET_SCHEDULER_shutdown ();
367 { 364 return;
368 fprintf (stderr, "%s", _ ("Revocation certificate ready\n")); 365 }
369 if (perform) 366 /**
370 perform_revocation (rd); 367 * Certificate not yet ready
371 else 368 */
372 GNUNET_SCHEDULER_shutdown (); 369 fprintf (stderr,
373 GNUNET_free (rd); 370 "%s",
374 return; 371 _ ("Continuing calculation where left off...\n"));
372 ph = GNUNET_REVOCATION_pow_start (&proof_of_work,
373 epochs,
374 matching_bits);
375 } 375 }
376 fprintf (stderr, 376 fprintf (stderr,
377 "%s", 377 "%s",
378 _ ("Revocation certificate not ready, calculating proof of work\n")); 378 _ ("Revocation certificate not ready, calculating proof of work\n"));
379 pow_task = GNUNET_SCHEDULER_add_now (&calculate_pow, rd); 379 if (NULL == ph)
380 GNUNET_SCHEDULER_add_shutdown (&calculate_pow_shutdown, rd); 380 {
381 GNUNET_REVOCATION_pow_init (privkey,
382 &proof_of_work);
383 ph = GNUNET_REVOCATION_pow_start (&proof_of_work,
384 epochs, /* Epochs */
385 matching_bits);
386 }
387 pow_task = GNUNET_SCHEDULER_add_now (&calculate_pow, ph);
388 GNUNET_SCHEDULER_add_shutdown (&calculate_pow_shutdown, ph);
381} 389}
382 390
383 391
@@ -396,7 +404,6 @@ run (void *cls,
396 const struct GNUNET_CONFIGURATION_Handle *c) 404 const struct GNUNET_CONFIGURATION_Handle *c)
397{ 405{
398 struct GNUNET_CRYPTO_EcdsaPublicKey pk; 406 struct GNUNET_CRYPTO_EcdsaPublicKey pk;
399 struct RevocationData rd;
400 407
401 cfg = c; 408 cfg = c;
402 if (NULL != test_ego) 409 if (NULL != test_ego)
@@ -429,6 +436,17 @@ run (void *cls,
429 "WORKBITS"); 436 "WORKBITS");
430 return; 437 return;
431 } 438 }
439 if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_time (cfg,
440 "REVOCATION",
441 "EPOCH_DURATION",
442 &epoch_duration))
443 {
444 GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR,
445 "REVOCATION",
446 "EPOCH_DURATION");
447 return;
448 }
449
432 if (NULL != revoke_ego) 450 if (NULL != revoke_ego)
433 { 451 {
434 if (! perform && (NULL == filename)) 452 if (! perform && (NULL == filename))
@@ -445,7 +463,9 @@ run (void *cls,
445 } 463 }
446 if ((NULL != filename) && (perform)) 464 if ((NULL != filename) && (perform))
447 { 465 {
448 if (sizeof(rd) != GNUNET_DISK_fn_read (filename, &rd, sizeof(rd))) 466 if (sizeof(proof_of_work) != GNUNET_DISK_fn_read (filename,
467 &proof_of_work,
468 sizeof(proof_of_work)))
449 { 469 {
450 fprintf (stderr, 470 fprintf (stderr,
451 _ ("Failed to read revocation certificate from `%s'\n"), 471 _ ("Failed to read revocation certificate from `%s'\n"),
@@ -454,18 +474,20 @@ run (void *cls,
454 } 474 }
455 GNUNET_SCHEDULER_add_shutdown (&do_shutdown, NULL); 475 GNUNET_SCHEDULER_add_shutdown (&do_shutdown, NULL);
456 if (GNUNET_YES != 476 if (GNUNET_YES !=
457 GNUNET_REVOCATION_check_pow (&rd.key, 477 GNUNET_REVOCATION_check_pow (&proof_of_work,
458 rd.pow, 478 (unsigned int) matching_bits,
459 (unsigned int) matching_bits)) 479 epoch_duration))
460 { 480 {
461 struct RevocationData *cp = GNUNET_new (struct RevocationData); 481 struct GNUNET_REVOCATION_PowCalculationHandle *ph;
482 ph = GNUNET_REVOCATION_pow_start (&proof_of_work,
483 epochs, /* Epochs */
484 matching_bits);
462 485
463 *cp = rd; 486 pow_task = GNUNET_SCHEDULER_add_now (&calculate_pow, ph);
464 pow_task = GNUNET_SCHEDULER_add_now (&calculate_pow, cp); 487 GNUNET_SCHEDULER_add_shutdown (&calculate_pow_shutdown, ph);
465 GNUNET_SCHEDULER_add_shutdown (&calculate_pow_shutdown, cp);
466 return; 488 return;
467 } 489 }
468 perform_revocation (&rd); 490 perform_revocation ();
469 return; 491 return;
470 } 492 }
471 fprintf (stderr, "%s", _ ("No action specified. Nothing to do.\n")); 493 fprintf (stderr, "%s", _ ("No action specified. Nothing to do.\n"));
@@ -511,6 +533,12 @@ main (int argc, char *const *argv)
511 gettext_noop ( 533 gettext_noop (
512 "test if the public key KEY has been revoked"), 534 "test if the public key KEY has been revoked"),
513 &test_ego), 535 &test_ego),
536 GNUNET_GETOPT_option_uint ('e',
537 "epochs",
538 "EPOCHS",
539 gettext_noop (
540 "number of epochs to calculate for"),
541 &epochs),
514 542
515 GNUNET_GETOPT_OPTION_END 543 GNUNET_GETOPT_OPTION_END
516 }; 544 };
diff --git a/src/revocation/gnunet-service-revocation.c b/src/revocation/gnunet-service-revocation.c
index 3e811cd9a..3c08e8452 100644
--- a/src/revocation/gnunet-service-revocation.c
+++ b/src/revocation/gnunet-service-revocation.c
@@ -129,6 +129,11 @@ static struct GNUNET_SET_ListenHandle *revocation_union_listen_handle;
129static unsigned long long revocation_work_required; 129static unsigned long long revocation_work_required;
130 130
131/** 131/**
132 * Length of an expiration expoch
133 */
134static struct GNUNET_TIME_Relative epoch_duration;
135
136/**
132 * Our application ID for set union operations. Must be the 137 * Our application ID for set union operations. Must be the
133 * same for all (compatible) peers. 138 * same for all (compatible) peers.
134 */ 139 */
@@ -167,25 +172,15 @@ new_peer_entry (const struct GNUNET_PeerIdentity *peer)
167static int 172static int
168verify_revoke_message (const struct RevokeMessage *rm) 173verify_revoke_message (const struct RevokeMessage *rm)
169{ 174{
170 if (GNUNET_YES != 175 if (GNUNET_YES != GNUNET_REVOCATION_check_pow (&rm->proof_of_work,
171 GNUNET_REVOCATION_check_pow (&rm->public_key, 176 (unsigned int) revocation_work_required,
172 rm->proof_of_work, 177 epoch_duration))
173 (unsigned int) revocation_work_required))
174 { 178 {
175 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 179 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
176 "Proof of work invalid!\n"); 180 "Proof of work invalid!\n");
177 GNUNET_break_op (0); 181 GNUNET_break_op (0);
178 return GNUNET_NO; 182 return GNUNET_NO;
179 } 183 }
180 if (GNUNET_OK !=
181 GNUNET_CRYPTO_ecdsa_verify_ (GNUNET_SIGNATURE_PURPOSE_REVOCATION,
182 &rm->purpose,
183 &rm->signature,
184 &rm->public_key))
185 {
186 GNUNET_break_op (0);
187 return GNUNET_NO;
188 }
189 return GNUNET_YES; 184 return GNUNET_YES;
190} 185}
191 186
@@ -308,7 +303,7 @@ publicize_rm (const struct RevokeMessage *rm)
308 struct GNUNET_HashCode hc; 303 struct GNUNET_HashCode hc;
309 struct GNUNET_SET_Element e; 304 struct GNUNET_SET_Element e;
310 305
311 GNUNET_CRYPTO_hash (&rm->public_key, 306 GNUNET_CRYPTO_hash (&rm->proof_of_work.key,
312 sizeof(struct GNUNET_CRYPTO_EcdsaPublicKey), 307 sizeof(struct GNUNET_CRYPTO_EcdsaPublicKey),
313 &hc); 308 &hc);
314 if (GNUNET_YES == 309 if (GNUNET_YES ==
@@ -848,6 +843,20 @@ run (void *cls,
848 GNUNET_free (fn); 843 GNUNET_free (fn);
849 return; 844 return;
850 } 845 }
846 if (GNUNET_OK !=
847 GNUNET_CONFIGURATION_get_value_time (cfg,
848 "REVOCATION",
849 "EPOCH_DURATION",
850 &epoch_duration))
851 {
852 GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR,
853 "REVOCATION",
854 "EPOCH_DURATION");
855 GNUNET_SCHEDULER_shutdown ();
856 GNUNET_free (fn);
857 return;
858 }
859
851 revocation_set = GNUNET_SET_create (cfg, 860 revocation_set = GNUNET_SET_create (cfg,
852 GNUNET_SET_OPERATION_UNION); 861 GNUNET_SET_OPERATION_UNION);
853 revocation_union_listen_handle 862 revocation_union_listen_handle
@@ -893,7 +902,7 @@ run (void *cls,
893 return; 902 return;
894 } 903 }
895 GNUNET_break (0 == ntohl (rm->reserved)); 904 GNUNET_break (0 == ntohl (rm->reserved));
896 GNUNET_CRYPTO_hash (&rm->public_key, 905 GNUNET_CRYPTO_hash (&rm->proof_of_work.key,
897 sizeof(struct GNUNET_CRYPTO_EcdsaPublicKey), 906 sizeof(struct GNUNET_CRYPTO_EcdsaPublicKey),
898 &hc); 907 &hc);
899 GNUNET_break (GNUNET_OK == 908 GNUNET_break (GNUNET_OK ==
diff --git a/src/revocation/plugin_block_revocation.c b/src/revocation/plugin_block_revocation.c
index 8d16b8781..291c56f70 100644
--- a/src/revocation/plugin_block_revocation.c
+++ b/src/revocation/plugin_block_revocation.c
@@ -52,6 +52,7 @@
52struct InternalContext 52struct InternalContext
53{ 53{
54 unsigned int matching_bits; 54 unsigned int matching_bits;
55 struct GNUNET_TIME_Relative epoch_duration;
55}; 56};
56 57
57 58
@@ -142,24 +143,15 @@ block_plugin_revocation_evaluate (void *cls,
142 GNUNET_break_op (0); 143 GNUNET_break_op (0);
143 return GNUNET_BLOCK_EVALUATION_RESULT_INVALID; 144 return GNUNET_BLOCK_EVALUATION_RESULT_INVALID;
144 } 145 }
145 if (GNUNET_YES != 146 if (0 >=
146 GNUNET_REVOCATION_check_pow (&rm->public_key, 147 GNUNET_REVOCATION_check_pow (&rm->proof_of_work,
147 rm->proof_of_work, 148 ic->matching_bits,
148 ic->matching_bits)) 149 ic->epoch_duration))
149 { 150 {
150 GNUNET_break_op (0); 151 GNUNET_break_op (0);
151 return GNUNET_BLOCK_EVALUATION_RESULT_INVALID; 152 return GNUNET_BLOCK_EVALUATION_RESULT_INVALID;
152 } 153 }
153 if (GNUNET_OK != 154 GNUNET_CRYPTO_hash (&rm->proof_of_work.key,
154 GNUNET_CRYPTO_ecdsa_verify_ (GNUNET_SIGNATURE_PURPOSE_REVOCATION,
155 &rm->purpose,
156 &rm->signature,
157 &rm->public_key))
158 {
159 GNUNET_break_op (0);
160 return GNUNET_BLOCK_EVALUATION_RESULT_INVALID;
161 }
162 GNUNET_CRYPTO_hash (&rm->public_key,
163 sizeof(struct GNUNET_CRYPTO_EcdsaPublicKey), 155 sizeof(struct GNUNET_CRYPTO_EcdsaPublicKey),
164 &chash); 156 &chash);
165 if (GNUNET_YES == 157 if (GNUNET_YES ==
@@ -195,7 +187,7 @@ block_plugin_revocation_get_key (void *cls,
195 GNUNET_break_op (0); 187 GNUNET_break_op (0);
196 return GNUNET_SYSERR; 188 return GNUNET_SYSERR;
197 } 189 }
198 GNUNET_CRYPTO_hash (&rm->public_key, 190 GNUNET_CRYPTO_hash (&rm->proof_of_work.key,
199 sizeof(struct GNUNET_CRYPTO_EcdsaPublicKey), 191 sizeof(struct GNUNET_CRYPTO_EcdsaPublicKey),
200 key); 192 key);
201 return GNUNET_OK; 193 return GNUNET_OK;
@@ -218,6 +210,7 @@ libgnunet_plugin_block_revocation_init (void *cls)
218 struct GNUNET_BLOCK_PluginFunctions *api; 210 struct GNUNET_BLOCK_PluginFunctions *api;
219 struct InternalContext *ic; 211 struct InternalContext *ic;
220 unsigned long long matching_bits; 212 unsigned long long matching_bits;
213 struct GNUNET_TIME_Relative epoch_duration;
221 214
222 if (GNUNET_OK != 215 if (GNUNET_OK !=
223 GNUNET_CONFIGURATION_get_value_number (cfg, 216 GNUNET_CONFIGURATION_get_value_number (cfg,
@@ -225,6 +218,12 @@ libgnunet_plugin_block_revocation_init (void *cls)
225 "WORKBITS", 218 "WORKBITS",
226 &matching_bits)) 219 &matching_bits))
227 return NULL; 220 return NULL;
221 if (GNUNET_OK !=
222 GNUNET_CONFIGURATION_get_value_time (cfg,
223 "REVOCATION",
224 "EPOCH_DURATION",
225 &epoch_duration))
226 return NULL;
228 227
229 api = GNUNET_new (struct GNUNET_BLOCK_PluginFunctions); 228 api = GNUNET_new (struct GNUNET_BLOCK_PluginFunctions);
230 api->evaluate = &block_plugin_revocation_evaluate; 229 api->evaluate = &block_plugin_revocation_evaluate;
@@ -233,6 +232,7 @@ libgnunet_plugin_block_revocation_init (void *cls)
233 api->types = types; 232 api->types = types;
234 ic = GNUNET_new (struct InternalContext); 233 ic = GNUNET_new (struct InternalContext);
235 ic->matching_bits = (unsigned int) matching_bits; 234 ic->matching_bits = (unsigned int) matching_bits;
235 ic->epoch_duration = epoch_duration;
236 api->cls = ic; 236 api->cls = ic;
237 return api; 237 return api;
238} 238}
diff --git a/src/revocation/revocation.conf.in b/src/revocation/revocation.conf.in
index 5ad41cd49..346168785 100644
--- a/src/revocation/revocation.conf.in
+++ b/src/revocation/revocation.conf.in
@@ -14,5 +14,6 @@ UNIX_MATCH_GID = YES
14# (using only a single-core) with SCRYPT. 14# (using only a single-core) with SCRYPT.
15# DO NOT CHANGE THIS VALUE, doing so will break the protocol! 15# DO NOT CHANGE THIS VALUE, doing so will break the protocol!
16WORKBITS = 25 16WORKBITS = 25
17EPOCH_DURATION = 356 d
17 18
18DATABASE = $GNUNET_DATA_HOME/revocation.dat 19DATABASE = $GNUNET_DATA_HOME/revocation.dat
diff --git a/src/revocation/revocation.h b/src/revocation/revocation.h
index b6e7a07ec..868c2b853 100644
--- a/src/revocation/revocation.h
+++ b/src/revocation/revocation.h
@@ -27,6 +27,7 @@
27#define REVOCATION_H 27#define REVOCATION_H
28 28
29#include "gnunet_util_lib.h" 29#include "gnunet_util_lib.h"
30#include "gnunet_revocation_service.h"
30 31
31GNUNET_NETWORK_STRUCT_BEGIN 32GNUNET_NETWORK_STRUCT_BEGIN
32 33
@@ -91,23 +92,7 @@ struct RevokeMessage
91 /** 92 /**
92 * Number that causes a hash collision with the @e public_key. 93 * Number that causes a hash collision with the @e public_key.
93 */ 94 */
94 uint64_t proof_of_work GNUNET_PACKED; 95 struct GNUNET_REVOCATION_Pow proof_of_work;
95
96 /**
97 * Signature confirming revocation.
98 */
99 struct GNUNET_CRYPTO_EcdsaSignature signature;
100
101 /**
102 * Must have purpose #GNUNET_SIGNATURE_PURPOSE_REVOCATION,
103 * size expands over the public key. (@deprecated)
104 */
105 struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
106
107 /**
108 * Key to revoke.
109 */
110 struct GNUNET_CRYPTO_EcdsaPublicKey public_key;
111}; 96};
112 97
113 98
diff --git a/src/revocation/revocation_api.c b/src/revocation/revocation_api.c
index 4755d4816..18a312ab8 100644
--- a/src/revocation/revocation_api.c
+++ b/src/revocation/revocation_api.c
@@ -27,8 +27,7 @@
27#include "gnunet_signatures.h" 27#include "gnunet_signatures.h"
28#include "gnunet_protocols.h" 28#include "gnunet_protocols.h"
29#include "revocation.h" 29#include "revocation.h"
30#include <gcrypt.h> 30#include <inttypes.h>
31
32 31
33/** 32/**
34 * Handle for the key revocation query. 33 * Handle for the key revocation query.
@@ -53,6 +52,58 @@ struct GNUNET_REVOCATION_Query
53 52
54 53
55/** 54/**
55 * Helper struct that holds a found pow nonce
56 * and the corresponding number of leading zeroes.
57 */
58struct BestPow
59{
60 /**
61 * PoW nonce
62 */
63 uint64_t pow;
64
65 /**
66 * Corresponding zero bits in hash
67 */
68 unsigned int bits;
69};
70
71
72/**
73 * The handle to a PoW calculation.
74 * Used in iterative PoW rounds.
75 */
76struct GNUNET_REVOCATION_PowCalculationHandle
77{
78 /**
79 * Current set of found PoWs
80 */
81 struct BestPow best[POW_COUNT];
82
83 /**
84 * The final PoW result data structure.
85 */
86 struct GNUNET_REVOCATION_Pow *pow;
87
88 /**
89 * The current nonce to try
90 */
91 uint64_t current_pow;
92
93 /**
94 * Epochs how long the PoW should be valid.
95 * This is added on top of the difficulty in the PoW.
96 */
97 unsigned int epochs;
98
99 /**
100 * The difficulty (leading zeros) to achieve.
101 */
102 unsigned int difficulty;
103
104};
105
106/**
56 * Generic error handler, called with the appropriate 107 * Generic error handler, called with the appropriate
57 * error code and the same closure specified at the creation of 108 * error code and the same closure specified at the creation of
58 * the message queue. 109 * the message queue.
@@ -235,6 +286,7 @@ handle_revocation_response (void *cls,
235 * @param key public key of the key to revoke 286 * @param key public key of the key to revoke
236 * @param sig signature to use on the revocation (should have been 287 * @param sig signature to use on the revocation (should have been
237 * created using #GNUNET_REVOCATION_sign_revocation). 288 * created using #GNUNET_REVOCATION_sign_revocation).
289 * @param ts revocation timestamp
238 * @param pow proof of work to use (should have been created by 290 * @param pow proof of work to use (should have been created by
239 * iteratively calling #GNUNET_REVOCATION_check_pow) 291 * iteratively calling #GNUNET_REVOCATION_check_pow)
240 * @param func funtion to call with the result of the check 292 * @param func funtion to call with the result of the check
@@ -245,9 +297,7 @@ handle_revocation_response (void *cls,
245 */ 297 */
246struct GNUNET_REVOCATION_Handle * 298struct GNUNET_REVOCATION_Handle *
247GNUNET_REVOCATION_revoke (const struct GNUNET_CONFIGURATION_Handle *cfg, 299GNUNET_REVOCATION_revoke (const struct GNUNET_CONFIGURATION_Handle *cfg,
248 const struct GNUNET_CRYPTO_EcdsaPublicKey *key, 300 const struct GNUNET_REVOCATION_Pow *pow,
249 const struct GNUNET_CRYPTO_EcdsaSignature *sig,
250 uint64_t pow,
251 GNUNET_REVOCATION_Callback func, 301 GNUNET_REVOCATION_Callback func,
252 void *func_cls) 302 void *func_cls)
253{ 303{
@@ -261,23 +311,39 @@ GNUNET_REVOCATION_revoke (const struct GNUNET_CONFIGURATION_Handle *cfg,
261 GNUNET_MQ_handler_end () 311 GNUNET_MQ_handler_end ()
262 }; 312 };
263 unsigned long long matching_bits; 313 unsigned long long matching_bits;
314 struct GNUNET_TIME_Relative epoch_duration;
264 struct RevokeMessage *rm; 315 struct RevokeMessage *rm;
265 struct GNUNET_MQ_Envelope *env; 316 struct GNUNET_MQ_Envelope *env;
266 317
267 if ((GNUNET_OK == 318 if ((GNUNET_OK !=
268 GNUNET_CONFIGURATION_get_value_number (cfg, 319 GNUNET_CONFIGURATION_get_value_number (cfg,
269 "REVOCATION", 320 "REVOCATION",
270 "WORKBITS", 321 "WORKBITS",
271 &matching_bits)) && 322 &matching_bits)))
272 (GNUNET_YES != 323 {
273 GNUNET_REVOCATION_check_pow (key, 324 GNUNET_break (0);
274 pow, 325 GNUNET_free (h);
275 (unsigned int) matching_bits))) 326 return NULL;
327 }
328 if ((GNUNET_OK !=
329 GNUNET_CONFIGURATION_get_value_time (cfg,
330 "REVOCATION",
331 "EPOCH_DURATION",
332 &epoch_duration)))
276 { 333 {
277 GNUNET_break (0); 334 GNUNET_break (0);
278 GNUNET_free (h); 335 GNUNET_free (h);
279 return NULL; 336 return NULL;
280 } 337 }
338 if (GNUNET_YES != GNUNET_REVOCATION_check_pow (pow,
339 (unsigned int) matching_bits,
340 epoch_duration))
341 {
342 GNUNET_break (0);
343 GNUNET_free (h);
344 return NULL;
345 }
346
281 347
282 h->mq = GNUNET_CLIENT_connect (cfg, 348 h->mq = GNUNET_CLIENT_connect (cfg,
283 "revocation", 349 "revocation",
@@ -294,12 +360,7 @@ GNUNET_REVOCATION_revoke (const struct GNUNET_CONFIGURATION_Handle *cfg,
294 env = GNUNET_MQ_msg (rm, 360 env = GNUNET_MQ_msg (rm,
295 GNUNET_MESSAGE_TYPE_REVOCATION_REVOKE); 361 GNUNET_MESSAGE_TYPE_REVOCATION_REVOKE);
296 rm->reserved = htonl (0); 362 rm->reserved = htonl (0);
297 rm->proof_of_work = pow; 363 rm->proof_of_work = *pow;
298 rm->purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_REVOCATION);
299 rm->purpose.size = htonl (sizeof(struct GNUNET_CRYPTO_EccSignaturePurpose)
300 + sizeof(struct GNUNET_CRYPTO_EcdsaPublicKey));
301 rm->public_key = *key;
302 rm->signature = *sig;
303 GNUNET_MQ_send (h->mq, 364 GNUNET_MQ_send (h->mq,
304 env); 365 env);
305 return h; 366 return h;
@@ -342,56 +403,263 @@ count_leading_zeroes (const struct GNUNET_HashCode *hash)
342 403
343 404
344/** 405/**
345 * Check if the given proof-of-work value 406 * Calculate the average zeros in the pows.
346 * would be acceptable for revoking the given key.
347 * 407 *
348 * @param key key to check for 408 * @param ph the PowHandle
349 * @param pow proof of work value 409 * @return the average number of zeroes.
410 */
411static unsigned int
412calculate_score (const struct GNUNET_REVOCATION_PowCalculationHandle *ph)
413{
414 double sum = 0.0;
415 for (unsigned int j = 0; j<POW_COUNT; j++)
416 sum += ph->best[j].bits;
417 double avg = sum / POW_COUNT;
418 return avg;
419}
420
421
422/**
423 * Check if the given proof-of-work is valid.
424 *
425 * @param pow proof of work
350 * @param matching_bits how many bits must match (configuration) 426 * @param matching_bits how many bits must match (configuration)
427 * @param epoch_duration length of single epoch in configuration
428 * @return #GNUNET_YES if the @a pow is acceptable, #GNUNET_NO if not
429 */
430enum GNUNET_GenericReturnValue
431GNUNET_REVOCATION_check_pow (const struct GNUNET_REVOCATION_Pow *pow,
432 unsigned int difficulty,
433 struct GNUNET_TIME_Relative epoch_duration)
434{
435 char buf[sizeof(struct GNUNET_CRYPTO_EcdsaPublicKey)
436 + sizeof (struct GNUNET_TIME_AbsoluteNBO)
437 + sizeof (uint64_t)] GNUNET_ALIGN;
438 struct GNUNET_REVOCATION_SignaturePurpose spurp;
439 struct GNUNET_HashCode result;
440 struct GNUNET_TIME_Absolute ts;
441 struct GNUNET_TIME_Absolute exp;
442 struct GNUNET_TIME_Relative ttl;
443 struct GNUNET_TIME_Relative buffer;
444 unsigned int score = 0;
445 unsigned int tmp_score = 0;
446 unsigned int epochs;
447 uint64_t pow_val;
448
449 /**
450 * Check if signature valid
451 */
452 spurp.key = pow->key;
453 spurp.timestamp = pow->timestamp;
454 spurp.purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_REVOCATION);
455 spurp.purpose.size = htonl (sizeof(struct GNUNET_CRYPTO_EccSignaturePurpose)
456 + sizeof(struct GNUNET_CRYPTO_EcdsaPublicKey)
457 + sizeof (struct GNUNET_TIME_AbsoluteNBO));
458 if (GNUNET_OK !=
459 GNUNET_CRYPTO_ecdsa_verify_ (GNUNET_SIGNATURE_PURPOSE_REVOCATION,
460 &spurp.purpose,
461 &pow->signature,
462 &pow->key))
463 {
464 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
465 "Proof of work signature invalid!\n");
466 return GNUNET_NO;
467 }
468
469 /**
470 * First, check if any duplicates are in the PoW set
471 */
472 for (unsigned int i = 0; i < POW_COUNT; i++)
473 {
474 for (unsigned int j = i + 1; j < POW_COUNT; j++)
475 {
476 if (pow->pow[i] == pow->pow[j])
477 return GNUNET_NO;
478 }
479 }
480 GNUNET_memcpy (&buf[sizeof(uint64_t)],
481 &pow->timestamp,
482 sizeof (uint64_t));
483 GNUNET_memcpy (&buf[sizeof(uint64_t) * 2],
484 &pow->key,
485 sizeof(struct GNUNET_CRYPTO_EcdsaPublicKey));
486 for (unsigned int i = 0; i < POW_COUNT; i++)
487 {
488 pow_val = GNUNET_ntohll (pow->pow[i]);
489 GNUNET_memcpy (buf, &pow_val, sizeof(uint64_t));
490 GNUNET_CRYPTO_pow_hash ("gnunet-revocation-proof-of-work",
491 buf,
492 sizeof(buf),
493 &result);
494 tmp_score = count_leading_zeroes (&result);
495 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
496 "Score %u with %" PRIu64 " (#%u)\n",
497 tmp_score, pow_val, i);
498 score += tmp_score;
499
500 }
501 score = score / POW_COUNT;
502 if (score < difficulty)
503 return GNUNET_NO;
504 epochs = score - difficulty;
505
506 /**
507 * Check expiration
508 */
509 ts = GNUNET_TIME_absolute_ntoh (pow->timestamp);
510 ttl = GNUNET_TIME_relative_multiply (epoch_duration,
511 epochs);
512 /**
513 * Extend by 10% for unsynchronized clocks
514 */
515 buffer = GNUNET_TIME_relative_divide (epoch_duration,
516 10);
517 exp = GNUNET_TIME_absolute_add (ts, ttl);
518 exp = GNUNET_TIME_absolute_add (exp,
519 buffer);
520
521 if (0 != GNUNET_TIME_absolute_get_remaining (ts).rel_value_us)
522 return GNUNET_NO; /* Not yet valid. */
523 /* Revert to actual start time */
524 ts = GNUNET_TIME_absolute_add (ts,
525 buffer);
526
527 if (0 == GNUNET_TIME_absolute_get_remaining (exp).rel_value_us)
528 return GNUNET_NO; /* expired */
529 return GNUNET_YES;
530}
531
532
533/**
534 * Initializes a fresh PoW computation.
535 *
536 * @param key the key to calculate the PoW for.
537 * @param[out] pow starting point for PoW calculation (not yet valid)
538 */
539void
540GNUNET_REVOCATION_pow_init (const struct GNUNET_CRYPTO_EcdsaPrivateKey *key,
541 struct GNUNET_REVOCATION_Pow *pow)
542{
543 struct GNUNET_TIME_Absolute ts = GNUNET_TIME_absolute_get ();
544 struct GNUNET_REVOCATION_SignaturePurpose rp;
545
546 /**
547 * Predate the validity period to prevent rejections due to
548 * unsynchronized clocks
549 */
550 ts = GNUNET_TIME_absolute_subtract (ts,
551 GNUNET_TIME_UNIT_WEEKS);
552
553 pow->timestamp = GNUNET_TIME_absolute_hton (ts);
554 rp.timestamp = pow->timestamp;
555 rp.purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_REVOCATION);
556 rp.purpose.size = htonl (sizeof(struct GNUNET_CRYPTO_EccSignaturePurpose)
557 + sizeof(struct GNUNET_CRYPTO_EcdsaPublicKey)
558 + sizeof (struct GNUNET_TIME_AbsoluteNBO));
559 GNUNET_CRYPTO_ecdsa_key_get_public (key, &pow->key);
560 rp.key = pow->key;
561 GNUNET_assert (GNUNET_OK ==
562 GNUNET_CRYPTO_ecdsa_sign_ (key,
563 &rp.purpose,
564 &pow->signature));
565}
566
567
568/**
569 * Starts a proof-of-work calculation given the pow object as well as
570 * target epochs and difficulty.
571 *
572 * @param pow the PoW to based calculations on.
573 * @param epochs the number of epochs for which the PoW must be valid.
574 * @param difficulty the base difficulty of the PoW.
575 * @return a handle for use in PoW rounds
576 */
577struct GNUNET_REVOCATION_PowCalculationHandle*
578GNUNET_REVOCATION_pow_start (struct GNUNET_REVOCATION_Pow *pow,
579 int epochs,
580 unsigned int difficulty)
581{
582 struct GNUNET_REVOCATION_PowCalculationHandle *pc;
583
584 pc = GNUNET_new (struct GNUNET_REVOCATION_PowCalculationHandle);
585 pc->pow = pow;
586 pc->current_pow = GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_WEAK,
587 UINT64_MAX);
588 pc->difficulty = difficulty;
589 pc->epochs = epochs;
590 return pc;
591}
592
593
594/**
595 * Calculate a key revocation valid for broadcasting for a number
596 * of epochs.
597 *
598 * @param pc handle to the PoW, initially called with NULL.
599 * @param epochs number of epochs for which the revocation must be valid.
600 * @param pow current pow value to try
601 * @param difficulty current base difficulty to achieve
351 * @return #GNUNET_YES if the @a pow is acceptable, #GNUNET_NO if not 602 * @return #GNUNET_YES if the @a pow is acceptable, #GNUNET_NO if not
352 */ 603 */
353int 604enum GNUNET_GenericReturnValue
354GNUNET_REVOCATION_check_pow (const struct GNUNET_CRYPTO_EcdsaPublicKey *key, 605GNUNET_REVOCATION_pow_round (struct GNUNET_REVOCATION_PowCalculationHandle *pc)
355 uint64_t pow,
356 unsigned int matching_bits)
357{ 606{
358 char buf[sizeof(struct GNUNET_CRYPTO_EcdsaPublicKey) 607 char buf[sizeof(struct GNUNET_CRYPTO_EcdsaPublicKey)
359 + sizeof(pow)] GNUNET_ALIGN; 608 + sizeof (uint64_t)
609 + sizeof (uint64_t)] GNUNET_ALIGN;
360 struct GNUNET_HashCode result; 610 struct GNUNET_HashCode result;
611 unsigned int zeros;
612
613 pc->current_pow++;
361 614
362 GNUNET_memcpy (buf, &pow, sizeof(pow)); 615 /**
363 GNUNET_memcpy (&buf[sizeof(pow)], key, 616 * Do not try duplicates
617 */
618 for (unsigned int i = 0; i < POW_COUNT; i++)
619 if (pc->current_pow == pc->best[i].pow)
620 return GNUNET_NO;
621
622 GNUNET_memcpy (buf, &pc->current_pow, sizeof(uint64_t));
623 GNUNET_memcpy (&buf[sizeof(uint64_t)],
624 &pc->pow->timestamp,
625 sizeof (uint64_t));
626 GNUNET_memcpy (&buf[sizeof(uint64_t) * 2],
627 &pc->pow->key,
364 sizeof(struct GNUNET_CRYPTO_EcdsaPublicKey)); 628 sizeof(struct GNUNET_CRYPTO_EcdsaPublicKey));
365 GNUNET_CRYPTO_pow_hash ("gnunet-revocation-proof-of-work", 629 GNUNET_CRYPTO_pow_hash ("gnunet-revocation-proof-of-work",
366 buf, 630 buf,
367 sizeof(buf), 631 sizeof(buf),
368 &result); 632 &result);
369 return (count_leading_zeroes (&result) >= 633 zeros = count_leading_zeroes (&result);
370 matching_bits) ? GNUNET_YES : GNUNET_NO; 634 for (unsigned int i = 0; i < POW_COUNT; i++)
635 {
636 if (pc->best[i].bits < zeros)
637 {
638 pc->best[i].bits = zeros;
639 pc->best[i].pow = pc->current_pow;
640 pc->pow->pow[i] = GNUNET_htonll (pc->current_pow);
641 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
642 "New best score %u with %" PRIu64 " (#%u)\n",
643 zeros, pc->current_pow, i);
644 break;
645 }
646 }
647 return calculate_score (pc) >= pc->difficulty + pc->epochs ? GNUNET_YES :
648 GNUNET_NO;
371} 649}
372 650
373 651
374/** 652/**
375 * Create a revocation signature. 653 * Stop a PoW calculation
376 * 654 *
377 * @param key private key of the key to revoke 655 * @param pc the calculation to clean up
378 * @param sig where to write the revocation signature 656 * @return #GNUNET_YES if pow valid, #GNUNET_NO if pow was set but is not
657 * valid
379 */ 658 */
380void 659void
381GNUNET_REVOCATION_sign_revocation (const struct 660GNUNET_REVOCATION_pow_stop (struct GNUNET_REVOCATION_PowCalculationHandle *pc)
382 GNUNET_CRYPTO_EcdsaPrivateKey *key,
383 struct GNUNET_CRYPTO_EcdsaSignature *sig)
384{ 661{
385 struct RevokeMessage rm; 662 GNUNET_free (pc);
386
387 rm.purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_REVOCATION);
388 rm.purpose.size = htonl (sizeof(struct GNUNET_CRYPTO_EccSignaturePurpose)
389 + sizeof(struct GNUNET_CRYPTO_EcdsaPublicKey));
390 GNUNET_CRYPTO_ecdsa_key_get_public (key, &rm.public_key);
391 GNUNET_assert (GNUNET_OK ==
392 GNUNET_CRYPTO_ecdsa_sign_ (key,
393 &rm.purpose,
394 sig));
395} 663}
396 664
397 665
diff --git a/src/revocation/test_revocation.c b/src/revocation/test_revocation.c
index 012bac09e..f193d5f6c 100644
--- a/src/revocation/test_revocation.c
+++ b/src/revocation/test_revocation.c
@@ -45,7 +45,7 @@ struct TestPeer
45 struct GNUNET_IDENTITY_EgoLookup *ego_lookup; 45 struct GNUNET_IDENTITY_EgoLookup *ego_lookup;
46 struct GNUNET_REVOCATION_Handle *revok_handle; 46 struct GNUNET_REVOCATION_Handle *revok_handle;
47 struct GNUNET_CORE_Handle *ch; 47 struct GNUNET_CORE_Handle *ch;
48 uint64_t pow; 48 struct GNUNET_REVOCATION_PowCalculationHandle *pow;
49}; 49};
50 50
51static struct TestPeer testpeers[2]; 51static struct TestPeer testpeers[2];
@@ -131,7 +131,7 @@ check_revocation (void *cls)
131 131
132 132
133static void 133static void
134revocation_cb (void *cls, int is_valid) 134revocation_cb (void *cls, enum GNUNET_GenericReturnValue is_valid)
135{ 135{
136 testpeers[1].revok_handle = NULL; 136 testpeers[1].revok_handle = NULL;
137 if (GNUNET_NO == is_valid) 137 if (GNUNET_NO == is_valid)
@@ -141,11 +141,14 @@ revocation_cb (void *cls, int is_valid)
141 } 141 }
142} 142}
143 143
144struct GNUNET_REVOCATION_Pow proof_of_work;
145
144 146
145static void 147static void
146ego_cb (void *cls, const struct GNUNET_IDENTITY_Ego *ego) 148ego_cb (void *cls, const struct GNUNET_IDENTITY_Ego *ego)
147{ 149{
148 static int completed = 0; 150 static int completed = 0;
151 const struct GNUNET_CRYPTO_EcdsaPrivateKey *privkey;
149 152
150 if ((NULL != ego) && (cls == &testpeers[0])) 153 if ((NULL != ego) && (cls == &testpeers[0]))
151 { 154 {
@@ -159,17 +162,20 @@ ego_cb (void *cls, const struct GNUNET_IDENTITY_Ego *ego)
159 testpeers[1].ego_lookup = NULL; 162 testpeers[1].ego_lookup = NULL;
160 testpeers[1].privkey = GNUNET_IDENTITY_ego_get_private_key (ego); 163 testpeers[1].privkey = GNUNET_IDENTITY_ego_get_private_key (ego);
161 GNUNET_IDENTITY_ego_get_public_key (ego, &testpeers[1].pubkey); 164 GNUNET_IDENTITY_ego_get_public_key (ego, &testpeers[1].pubkey);
162 GNUNET_REVOCATION_sign_revocation (testpeers[1].privkey, &testpeers[1].sig);
163
164 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Calculating proof of work...\n"); 165 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Calculating proof of work...\n");
165 testpeers[1].pow = 0; 166 privkey = GNUNET_IDENTITY_ego_get_private_key (ego);
167 memset (&proof_of_work, 0, sizeof (proof_of_work));
168 GNUNET_REVOCATION_pow_init (privkey,
169 &proof_of_work);
170 testpeers[1].pow = GNUNET_REVOCATION_pow_start (&proof_of_work,
171 1,
172 5);
166 int res = 173 int res =
167 GNUNET_REVOCATION_check_pow (&testpeers[1].pubkey, testpeers[1].pow, 5); 174 GNUNET_REVOCATION_pow_round (testpeers[1].pow);
168 while (GNUNET_OK != res) 175 while (GNUNET_OK != res)
169 { 176 {
170 testpeers[1].pow++;
171 res = 177 res =
172 GNUNET_REVOCATION_check_pow (&testpeers[1].pubkey, testpeers[1].pow, 5); 178 GNUNET_REVOCATION_pow_round (testpeers[1].pow);
173 } 179 }
174 fprintf (stderr, "Done calculating proof of work\n"); 180 fprintf (stderr, "Done calculating proof of work\n");
175 completed++; 181 completed++;
@@ -178,11 +184,10 @@ ego_cb (void *cls, const struct GNUNET_IDENTITY_Ego *ego)
178 { 184 {
179 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Egos retrieved\n"); 185 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Egos retrieved\n");
180 testpeers[1].revok_handle = GNUNET_REVOCATION_revoke (testpeers[1].cfg, 186 testpeers[1].revok_handle = GNUNET_REVOCATION_revoke (testpeers[1].cfg,
181 &testpeers[1].pubkey, 187 &proof_of_work,
182 &testpeers[1].sig,
183 testpeers[1].pow,
184 &revocation_cb, 188 &revocation_cb,
185 NULL); 189 NULL);
190 GNUNET_REVOCATION_pow_stop (testpeers[1].pow);
186 } 191 }
187} 192}
188 193
diff --git a/src/revocation/test_revocation.conf b/src/revocation/test_revocation.conf
index 3b04150c1..66e2cdcc9 100644
--- a/src/revocation/test_revocation.conf
+++ b/src/revocation/test_revocation.conf
@@ -7,6 +7,7 @@ SERVICEHOME=$GNUNET_TMP/test-revocation-service
7[revocation] 7[revocation]
8WORKBITS = 3 8WORKBITS = 3
9IMMEDIATE_START = YES 9IMMEDIATE_START = YES
10EPOCH_DURATION = 365 d
10 11
11[identity] 12[identity]
12# Directory where we store information about our egos 13# Directory where we store information about our egos