aboutsummaryrefslogtreecommitdiff
path: root/src/revocation
diff options
context:
space:
mode:
authorSchanzenbach, Martin <mschanzenbach@posteo.de>2020-04-19 20:05:26 +0200
committerSchanzenbach, Martin <mschanzenbach@posteo.de>2020-04-19 20:05:26 +0200
commit8f9a45e853d9759f04a5f4fe9aa0146ed3f3fb17 (patch)
treeb9ef6928b2fdb8647a8c7d3e0f6d316198b51d48 /src/revocation
parenteb6b547e243144f27749811c15b6cce90e03aaa7 (diff)
downloadgnunet-8f9a45e853d9759f04a5f4fe9aa0146ed3f3fb17.tar.gz
gnunet-8f9a45e853d9759f04a5f4fe9aa0146ed3f3fb17.zip
towards less variance
Diffstat (limited to 'src/revocation')
-rw-r--r--src/revocation/gnunet-revocation.c137
-rw-r--r--src/revocation/gnunet-service-revocation.c16
-rw-r--r--src/revocation/plugin_block_revocation.c16
-rw-r--r--src/revocation/revocation.h24
-rw-r--r--src/revocation/revocation_api.c198
5 files changed, 231 insertions, 160 deletions
diff --git a/src/revocation/gnunet-revocation.c b/src/revocation/gnunet-revocation.c
index 42ec71d16..2d83da8b6 100644
--- a/src/revocation/gnunet-revocation.c
+++ b/src/revocation/gnunet-revocation.c
@@ -218,16 +218,12 @@ struct RevocationData
218 * Perform the revocation. 218 * Perform the revocation.
219 */ 219 */
220static void 220static void
221perform_revocation (const struct RevocationData *rd) 221perform_revocation (const struct GNUNET_REVOCATION_Pow *pow)
222{ 222{
223 struct GNUNET_TIME_Absolute ts; 223 struct GNUNET_TIME_Absolute ts;
224 224
225 ts = GNUNET_TIME_absolute_ntoh (rd->ts);
226 h = GNUNET_REVOCATION_revoke (cfg, 225 h = GNUNET_REVOCATION_revoke (cfg,
227 &rd->key, 226 pow,
228 &rd->sig,
229 &ts,
230 rd->pow,
231 &print_revocation_result, 227 &print_revocation_result,
232 NULL); 228 NULL);
233} 229}
@@ -240,13 +236,13 @@ perform_revocation (const struct RevocationData *rd)
240 * @param rd data to sync 236 * @param rd data to sync
241 */ 237 */
242static void 238static void
243sync_rd (const struct RevocationData *rd) 239sync_pow (const struct GNUNET_REVOCATION_Pow *pow)
244{ 240{
245 if ((NULL != filename) && 241 if ((NULL != filename) &&
246 (sizeof(struct RevocationData) == 242 (sizeof(struct GNUNET_REVOCATION_Pow) ==
247 GNUNET_DISK_fn_write (filename, 243 GNUNET_DISK_fn_write (filename,
248 &rd, 244 &pow,
249 sizeof(rd), 245 sizeof(pow),
250 GNUNET_DISK_PERM_USER_READ 246 GNUNET_DISK_PERM_USER_READ
251 | GNUNET_DISK_PERM_USER_WRITE))) 247 | GNUNET_DISK_PERM_USER_WRITE)))
252 GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR, "write", filename); 248 GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR, "write", filename);
@@ -261,15 +257,14 @@ sync_rd (const struct RevocationData *rd)
261static void 257static void
262calculate_pow_shutdown (void *cls) 258calculate_pow_shutdown (void *cls)
263{ 259{
264 struct RevocationData *rd = cls; 260 struct GNUNET_REVOCATION_PowCalculationHandle *ph = cls;
265 261
266 if (NULL != pow_task) 262 if (NULL != pow_task)
267 { 263 {
268 GNUNET_SCHEDULER_cancel (pow_task); 264 GNUNET_SCHEDULER_cancel (pow_task);
269 pow_task = NULL; 265 pow_task = NULL;
270 } 266 }
271 sync_rd (rd); 267 GNUNET_REVOCATION_pow_cleanup (ph);
272 GNUNET_free (rd);
273} 268}
274 269
275 270
@@ -281,40 +276,27 @@ calculate_pow_shutdown (void *cls)
281static void 276static void
282calculate_pow (void *cls) 277calculate_pow (void *cls)
283{ 278{
284 struct RevocationData *rd = cls; 279 struct GNUNET_REVOCATION_PowCalculationHandle *ph = cls;
285 struct GNUNET_TIME_Absolute ts = GNUNET_TIME_absolute_ntoh (rd->ts);
286 280
287 /* store temporary results */ 281 /* store temporary results */
288 pow_task = NULL; 282 pow_task = NULL;
289 if (0 == (rd->pow % 128)) 283 //if (0 == (rd->pow % 128))
290 sync_rd (rd); 284 // sync_rd (rd);
291 /* display progress estimate */
292 if ((0 == ((1 << matching_bits) / 100 / 50)) ||
293 (0 == (rd->pow % ((1 << matching_bits) / 100 / 50))))
294 fprintf (stderr, "%s", ".");
295 if ((0 != rd->pow) && ((0 == ((1 << matching_bits) / 100)) ||
296 (0 == (rd->pow % ((1 << matching_bits) / 100)))))
297 fprintf (stderr,
298 " - @ %3u%% (estimate)\n",
299 (unsigned int) (rd->pow * 100) / (1 << matching_bits));
300 /* actually do POW calculation */ 285 /* actually do POW calculation */
301 rd->pow++; 286 if (GNUNET_OK == GNUNET_REVOCATION_pow_round (ph))
302 if (GNUNET_OK == GNUNET_REVOCATION_check_pow (&rd->key,
303 &ts,
304 rd->pow,
305 (unsigned int) matching_bits))
306 { 287 {
288 const struct GNUNET_REVOCATION_Pow *pow = GNUNET_REVOCATION_pow_get (ph);
307 if ((NULL != filename) && 289 if ((NULL != filename) &&
308 (sizeof(struct RevocationData) != 290 (sizeof(struct GNUNET_REVOCATION_Pow) !=
309 GNUNET_DISK_fn_write (filename, 291 GNUNET_DISK_fn_write (filename,
310 rd, 292 pow,
311 sizeof(struct RevocationData), 293 sizeof(struct GNUNET_REVOCATION_Pow),
312 GNUNET_DISK_PERM_USER_READ 294 GNUNET_DISK_PERM_USER_READ
313 | GNUNET_DISK_PERM_USER_WRITE))) 295 | GNUNET_DISK_PERM_USER_WRITE)))
314 GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR, "write", filename); 296 GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR, "write", filename);
315 if (perform) 297 if (perform)
316 { 298 {
317 perform_revocation (rd); 299 perform_revocation (pow);
318 } 300 }
319 else 301 else
320 { 302 {
@@ -327,7 +309,7 @@ calculate_pow (void *cls)
327 } 309 }
328 return; 310 return;
329 } 311 }
330 pow_task = GNUNET_SCHEDULER_add_now (&calculate_pow, rd); 312 pow_task = GNUNET_SCHEDULER_add_now (&calculate_pow, ph);
331} 313}
332 314
333 315
@@ -340,9 +322,8 @@ calculate_pow (void *cls)
340static void 322static void
341ego_callback (void *cls, const struct GNUNET_IDENTITY_Ego *ego) 323ego_callback (void *cls, const struct GNUNET_IDENTITY_Ego *ego)
342{ 324{
343 struct RevocationData *rd; 325 struct GNUNET_REVOCATION_Pow *pow;
344 struct GNUNET_CRYPTO_EcdsaPublicKey key; 326 struct GNUNET_CRYPTO_EcdsaPublicKey key;
345 struct GNUNET_TIME_Absolute ts;
346 327
347 el = NULL; 328 el = NULL;
348 if (NULL == ego) 329 if (NULL == ego)
@@ -352,49 +333,49 @@ ego_callback (void *cls, const struct GNUNET_IDENTITY_Ego *ego)
352 return; 333 return;
353 } 334 }
354 GNUNET_IDENTITY_ego_get_public_key (ego, &key); 335 GNUNET_IDENTITY_ego_get_public_key (ego, &key);
355 rd = GNUNET_new (struct RevocationData); 336 pow = GNUNET_new (struct GNUNET_REVOCATION_Pow);
356 if ((NULL != filename) && (GNUNET_YES == GNUNET_DISK_file_test (filename)) && 337 if ((NULL != filename) && (GNUNET_YES == GNUNET_DISK_file_test (filename)) &&
357 (sizeof(struct RevocationData) == 338 (sizeof(struct GNUNET_REVOCATION_Pow) ==
358 GNUNET_DISK_fn_read (filename, rd, sizeof(struct RevocationData)))) 339 GNUNET_DISK_fn_read (filename, pow, sizeof(struct
340 GNUNET_REVOCATION_Pow))))
359 { 341 {
360 if (0 != GNUNET_memcmp (&rd->key, &key)) 342 if (0 != GNUNET_memcmp (&pow->key, &key))
361 { 343 {
362 fprintf (stderr, 344 fprintf (stderr,
363 _ ("Error: revocation certificate in `%s' is not for `%s'\n"), 345 _ ("Error: revocation certificate in `%s' is not for `%s'\n"),
364 filename, 346 filename,
365 revoke_ego); 347 revoke_ego);
366 GNUNET_free (rd); 348 GNUNET_free (pow);
367 return; 349 return;
368 } 350 }
369 } 351 if (GNUNET_YES ==
370 else 352 GNUNET_REVOCATION_check_pow (pow,
371 { 353 (unsigned int) matching_bits))
372 GNUNET_REVOCATION_sign_revocation (GNUNET_IDENTITY_ego_get_private_key ( 354 {
373 ego), 355 fprintf (stderr, "%s", _ ("Revocation certificate ready\n"));
374 &rd->sig); 356 if (perform)
375 rd->key = key; 357 perform_revocation (pow);
376 rd->ts = GNUNET_TIME_absolute_hton (GNUNET_TIME_absolute_get ()); 358 else
377 } 359 GNUNET_SCHEDULER_shutdown ();
378 ts = GNUNET_TIME_absolute_ntoh (rd->ts); 360 GNUNET_free (pow);
379 if (GNUNET_YES == 361 return;
380 GNUNET_REVOCATION_check_pow (&key, 362 }
381 &ts, 363 fprintf (stderr,
382 rd->pow, 364 _ ("Error: revocation certificate in `%s' invalid\n"),
383 (unsigned int) matching_bits)) 365 filename);
384 { 366 GNUNET_free (pow);
385 fprintf (stderr, "%s", _ ("Revocation certificate ready\n"));
386 if (perform)
387 perform_revocation (rd);
388 else
389 GNUNET_SCHEDULER_shutdown ();
390 GNUNET_free (rd);
391 return; 367 return;
392 } 368 }
393 fprintf (stderr, 369 fprintf (stderr,
394 "%s", 370 "%s",
395 _ ("Revocation certificate not ready, calculating proof of work\n")); 371 _ ("Revocation certificate not ready, calculating proof of work\n"));
396 pow_task = GNUNET_SCHEDULER_add_now (&calculate_pow, rd); 372 GNUNET_free (pow);
397 GNUNET_SCHEDULER_add_shutdown (&calculate_pow_shutdown, rd); 373 struct GNUNET_REVOCATION_PowCalculationHandle *ph;
374 ph = GNUNET_REVOCATION_pow_init (&key,
375 1, /* Epochs */
376 matching_bits);
377 pow_task = GNUNET_SCHEDULER_add_now (&calculate_pow, ph);
378 GNUNET_SCHEDULER_add_shutdown (&calculate_pow_shutdown, ph);
398} 379}
399 380
400 381
@@ -413,8 +394,7 @@ run (void *cls,
413 const struct GNUNET_CONFIGURATION_Handle *c) 394 const struct GNUNET_CONFIGURATION_Handle *c)
414{ 395{
415 struct GNUNET_CRYPTO_EcdsaPublicKey pk; 396 struct GNUNET_CRYPTO_EcdsaPublicKey pk;
416 struct RevocationData rd; 397 struct GNUNET_REVOCATION_Pow pow;
417 struct GNUNET_TIME_Absolute ts;
418 398
419 cfg = c; 399 cfg = c;
420 if (NULL != test_ego) 400 if (NULL != test_ego)
@@ -463,7 +443,7 @@ run (void *cls,
463 } 443 }
464 if ((NULL != filename) && (perform)) 444 if ((NULL != filename) && (perform))
465 { 445 {
466 if (sizeof(rd) != GNUNET_DISK_fn_read (filename, &rd, sizeof(rd))) 446 if (sizeof(pow) != GNUNET_DISK_fn_read (filename, &pow, sizeof(pow)))
467 { 447 {
468 fprintf (stderr, 448 fprintf (stderr,
469 _ ("Failed to read revocation certificate from `%s'\n"), 449 _ ("Failed to read revocation certificate from `%s'\n"),
@@ -471,21 +451,20 @@ run (void *cls,
471 return; 451 return;
472 } 452 }
473 GNUNET_SCHEDULER_add_shutdown (&do_shutdown, NULL); 453 GNUNET_SCHEDULER_add_shutdown (&do_shutdown, NULL);
474 ts = GNUNET_TIME_absolute_ntoh (rd.ts);
475 if (GNUNET_YES != 454 if (GNUNET_YES !=
476 GNUNET_REVOCATION_check_pow (&rd.key, 455 GNUNET_REVOCATION_check_pow (&pow,
477 &ts,
478 rd.pow,
479 (unsigned int) matching_bits)) 456 (unsigned int) matching_bits))
480 { 457 {
481 struct RevocationData *cp = GNUNET_new (struct RevocationData); 458 struct GNUNET_REVOCATION_PowCalculationHandle *ph;
459 ph = GNUNET_REVOCATION_pow_init (&pk,
460 1, /* Epochs */
461 matching_bits);
482 462
483 *cp = rd; 463 pow_task = GNUNET_SCHEDULER_add_now (&calculate_pow, ph);
484 pow_task = GNUNET_SCHEDULER_add_now (&calculate_pow, cp); 464 GNUNET_SCHEDULER_add_shutdown (&calculate_pow_shutdown, ph);
485 GNUNET_SCHEDULER_add_shutdown (&calculate_pow_shutdown, cp);
486 return; 465 return;
487 } 466 }
488 perform_revocation (&rd); 467 perform_revocation (&pow);
489 return; 468 return;
490 } 469 }
491 fprintf (stderr, "%s", _ ("No action specified. Nothing to do.\n")); 470 fprintf (stderr, "%s", _ ("No action specified. Nothing to do.\n"));
diff --git a/src/revocation/gnunet-service-revocation.c b/src/revocation/gnunet-service-revocation.c
index ff75faa2c..420cb392f 100644
--- a/src/revocation/gnunet-service-revocation.c
+++ b/src/revocation/gnunet-service-revocation.c
@@ -167,12 +167,8 @@ new_peer_entry (const struct GNUNET_PeerIdentity *peer)
167static int 167static int
168verify_revoke_message (const struct RevokeMessage *rm) 168verify_revoke_message (const struct RevokeMessage *rm)
169{ 169{
170 struct GNUNET_TIME_Absolute ts;
171 ts = GNUNET_TIME_absolute_ntoh (rm->ts);
172 if (GNUNET_YES != 170 if (GNUNET_YES !=
173 GNUNET_REVOCATION_check_pow (&rm->public_key, 171 GNUNET_REVOCATION_check_pow (&rm->proof_of_work,
174 &ts,
175 rm->proof_of_work,
176 (unsigned int) revocation_work_required)) 172 (unsigned int) revocation_work_required))
177 { 173 {
178 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 174 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
@@ -182,9 +178,9 @@ verify_revoke_message (const struct RevokeMessage *rm)
182 } 178 }
183 if (GNUNET_OK != 179 if (GNUNET_OK !=
184 GNUNET_CRYPTO_ecdsa_verify_ (GNUNET_SIGNATURE_PURPOSE_REVOCATION, 180 GNUNET_CRYPTO_ecdsa_verify_ (GNUNET_SIGNATURE_PURPOSE_REVOCATION,
185 &rm->purpose, 181 &rm->proof_of_work.purpose,
186 &rm->signature, 182 &rm->proof_of_work.signature,
187 &rm->public_key)) 183 &rm->proof_of_work.key))
188 { 184 {
189 GNUNET_break_op (0); 185 GNUNET_break_op (0);
190 return GNUNET_NO; 186 return GNUNET_NO;
@@ -311,7 +307,7 @@ publicize_rm (const struct RevokeMessage *rm)
311 struct GNUNET_HashCode hc; 307 struct GNUNET_HashCode hc;
312 struct GNUNET_SET_Element e; 308 struct GNUNET_SET_Element e;
313 309
314 GNUNET_CRYPTO_hash (&rm->public_key, 310 GNUNET_CRYPTO_hash (&rm->proof_of_work.key,
315 sizeof(struct GNUNET_CRYPTO_EcdsaPublicKey), 311 sizeof(struct GNUNET_CRYPTO_EcdsaPublicKey),
316 &hc); 312 &hc);
317 if (GNUNET_YES == 313 if (GNUNET_YES ==
@@ -896,7 +892,7 @@ run (void *cls,
896 return; 892 return;
897 } 893 }
898 GNUNET_break (0 == ntohl (rm->reserved)); 894 GNUNET_break (0 == ntohl (rm->reserved));
899 GNUNET_CRYPTO_hash (&rm->public_key, 895 GNUNET_CRYPTO_hash (&rm->proof_of_work.key,
900 sizeof(struct GNUNET_CRYPTO_EcdsaPublicKey), 896 sizeof(struct GNUNET_CRYPTO_EcdsaPublicKey),
901 &hc); 897 &hc);
902 GNUNET_break (GNUNET_OK == 898 GNUNET_break (GNUNET_OK ==
diff --git a/src/revocation/plugin_block_revocation.c b/src/revocation/plugin_block_revocation.c
index 57234fa36..a57a933c3 100644
--- a/src/revocation/plugin_block_revocation.c
+++ b/src/revocation/plugin_block_revocation.c
@@ -134,7 +134,6 @@ block_plugin_revocation_evaluate (void *cls,
134 struct InternalContext *ic = cls; 134 struct InternalContext *ic = cls;
135 struct GNUNET_HashCode chash; 135 struct GNUNET_HashCode chash;
136 const struct RevokeMessage *rm = reply_block; 136 const struct RevokeMessage *rm = reply_block;
137 struct GNUNET_TIME_Absolute ts;
138 137
139 if (NULL == reply_block) 138 if (NULL == reply_block)
140 return GNUNET_BLOCK_EVALUATION_REQUEST_VALID; 139 return GNUNET_BLOCK_EVALUATION_REQUEST_VALID;
@@ -143,11 +142,8 @@ block_plugin_revocation_evaluate (void *cls,
143 GNUNET_break_op (0); 142 GNUNET_break_op (0);
144 return GNUNET_BLOCK_EVALUATION_RESULT_INVALID; 143 return GNUNET_BLOCK_EVALUATION_RESULT_INVALID;
145 } 144 }
146 ts = GNUNET_TIME_absolute_ntoh (rm->ts);
147 if (GNUNET_YES != 145 if (GNUNET_YES !=
148 GNUNET_REVOCATION_check_pow (&rm->public_key, 146 GNUNET_REVOCATION_check_pow (&rm->proof_of_work,
149 &ts,
150 rm->proof_of_work,
151 ic->matching_bits)) 147 ic->matching_bits))
152 { 148 {
153 GNUNET_break_op (0); 149 GNUNET_break_op (0);
@@ -155,14 +151,14 @@ block_plugin_revocation_evaluate (void *cls,
155 } 151 }
156 if (GNUNET_OK != 152 if (GNUNET_OK !=
157 GNUNET_CRYPTO_ecdsa_verify_ (GNUNET_SIGNATURE_PURPOSE_REVOCATION, 153 GNUNET_CRYPTO_ecdsa_verify_ (GNUNET_SIGNATURE_PURPOSE_REVOCATION,
158 &rm->purpose, 154 &rm->proof_of_work.purpose,
159 &rm->signature, 155 &rm->proof_of_work.signature,
160 &rm->public_key)) 156 &rm->proof_of_work.key))
161 { 157 {
162 GNUNET_break_op (0); 158 GNUNET_break_op (0);
163 return GNUNET_BLOCK_EVALUATION_RESULT_INVALID; 159 return GNUNET_BLOCK_EVALUATION_RESULT_INVALID;
164 } 160 }
165 GNUNET_CRYPTO_hash (&rm->public_key, 161 GNUNET_CRYPTO_hash (&rm->proof_of_work.key,
166 sizeof(struct GNUNET_CRYPTO_EcdsaPublicKey), 162 sizeof(struct GNUNET_CRYPTO_EcdsaPublicKey),
167 &chash); 163 &chash);
168 if (GNUNET_YES == 164 if (GNUNET_YES ==
@@ -198,7 +194,7 @@ block_plugin_revocation_get_key (void *cls,
198 GNUNET_break_op (0); 194 GNUNET_break_op (0);
199 return GNUNET_SYSERR; 195 return GNUNET_SYSERR;
200 } 196 }
201 GNUNET_CRYPTO_hash (&rm->public_key, 197 GNUNET_CRYPTO_hash (&rm->proof_of_work.key,
202 sizeof(struct GNUNET_CRYPTO_EcdsaPublicKey), 198 sizeof(struct GNUNET_CRYPTO_EcdsaPublicKey),
203 key); 199 key);
204 return GNUNET_OK; 200 return GNUNET_OK;
diff --git a/src/revocation/revocation.h b/src/revocation/revocation.h
index d7b9cc139..b2769da0e 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,28 +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 GNUNET_PACKED;
95
96 /**
97 * Timestamp
98 */
99 struct GNUNET_TIME_AbsoluteNBO ts;
100
101 /**
102 * Signature confirming revocation.
103 */
104 struct GNUNET_CRYPTO_EcdsaSignature signature;
105
106 /**
107 * Must have purpose #GNUNET_SIGNATURE_PURPOSE_REVOCATION,
108 * size expands over the public key. (@deprecated)
109 */
110 struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
111
112 /**
113 * Key to revoke.
114 */
115 struct GNUNET_CRYPTO_EcdsaPublicKey public_key;
116}; 96};
117 97
118 98
diff --git a/src/revocation/revocation_api.c b/src/revocation/revocation_api.c
index c9bb2543a..6510f9583 100644
--- a/src/revocation/revocation_api.c
+++ b/src/revocation/revocation_api.c
@@ -51,6 +51,21 @@ struct GNUNET_REVOCATION_Query
51 void *func_cls; 51 void *func_cls;
52}; 52};
53 53
54struct BestPow
55{
56 uint64_t pow;
57 unsigned int bits;
58};
59
60struct GNUNET_REVOCATION_PowCalculationHandle
61{
62 struct BestPow best[POW_COUNT];
63 struct GNUNET_REVOCATION_Pow pow;
64 uint64_t current_pow;
65 unsigned int epochs;
66 unsigned int difficulty;
67 int valid;
68};
54 69
55/** 70/**
56 * Generic error handler, called with the appropriate 71 * Generic error handler, called with the appropriate
@@ -246,10 +261,7 @@ handle_revocation_response (void *cls,
246 */ 261 */
247struct GNUNET_REVOCATION_Handle * 262struct GNUNET_REVOCATION_Handle *
248GNUNET_REVOCATION_revoke (const struct GNUNET_CONFIGURATION_Handle *cfg, 263GNUNET_REVOCATION_revoke (const struct GNUNET_CONFIGURATION_Handle *cfg,
249 const struct GNUNET_CRYPTO_EcdsaPublicKey *key, 264 const struct GNUNET_REVOCATION_Pow *pow,
250 const struct GNUNET_CRYPTO_EcdsaSignature *sig,
251 const struct GNUNET_TIME_Absolute *ts,
252 uint64_t pow,
253 GNUNET_REVOCATION_Callback func, 265 GNUNET_REVOCATION_Callback func,
254 void *func_cls) 266 void *func_cls)
255{ 267{
@@ -272,9 +284,7 @@ GNUNET_REVOCATION_revoke (const struct GNUNET_CONFIGURATION_Handle *cfg,
272 "WORKBITS", 284 "WORKBITS",
273 &matching_bits)) && 285 &matching_bits)) &&
274 (GNUNET_YES != 286 (GNUNET_YES !=
275 GNUNET_REVOCATION_check_pow (key, 287 GNUNET_REVOCATION_check_pow (pow,
276 ts,
277 pow,
278 (unsigned int) matching_bits))) 288 (unsigned int) matching_bits)))
279 { 289 {
280 GNUNET_break (0); 290 GNUNET_break (0);
@@ -297,12 +307,7 @@ GNUNET_REVOCATION_revoke (const struct GNUNET_CONFIGURATION_Handle *cfg,
297 env = GNUNET_MQ_msg (rm, 307 env = GNUNET_MQ_msg (rm,
298 GNUNET_MESSAGE_TYPE_REVOCATION_REVOKE); 308 GNUNET_MESSAGE_TYPE_REVOCATION_REVOKE);
299 rm->reserved = htonl (0); 309 rm->reserved = htonl (0);
300 rm->proof_of_work = pow; 310 rm->proof_of_work = *pow;
301 rm->purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_REVOCATION);
302 rm->purpose.size = htonl (sizeof(struct GNUNET_CRYPTO_EccSignaturePurpose)
303 + sizeof(struct GNUNET_CRYPTO_EcdsaPublicKey));
304 rm->public_key = *key;
305 rm->signature = *sig;
306 GNUNET_MQ_send (h->mq, 311 GNUNET_MQ_send (h->mq,
307 env); 312 env);
308 return h; 313 return h;
@@ -345,6 +350,23 @@ count_leading_zeroes (const struct GNUNET_HashCode *hash)
345 350
346 351
347/** 352/**
353 * Calculate the average zeros in the pows.
354 *
355 * @param ph the PowHandle
356 * @return the average number of zeroes.
357 */
358static unsigned int
359calculate_score (const struct GNUNET_REVOCATION_PowCalculationHandle *ph)
360{
361 double sum = 0.0;
362 for (unsigned int j = 0; j<POW_COUNT; j++)
363 sum += ph->best[j].bits;
364 double avg = sum / POW_COUNT;
365 return avg;
366}
367
368
369/**
348 * Check if the given proof-of-work value 370 * Check if the given proof-of-work value
349 * would be acceptable for revoking the given key. 371 * would be acceptable for revoking the given key.
350 * 372 *
@@ -355,32 +377,133 @@ count_leading_zeroes (const struct GNUNET_HashCode *hash)
355 * @return #GNUNET_YES if the @a pow is acceptable, #GNUNET_NO if not 377 * @return #GNUNET_YES if the @a pow is acceptable, #GNUNET_NO if not
356 */ 378 */
357int 379int
358GNUNET_REVOCATION_check_pow (const struct GNUNET_CRYPTO_EcdsaPublicKey *key, 380GNUNET_REVOCATION_check_pow (const struct GNUNET_REVOCATION_Pow *pow,
359 const struct GNUNET_TIME_Absolute *ts, 381 unsigned int difficulty)
360 uint64_t pow, 382{
361 unsigned int matching_bits) 383 char buf[sizeof(struct GNUNET_CRYPTO_EcdsaPublicKey)
384 + sizeof (uint64_t)
385 + sizeof (uint64_t)] GNUNET_ALIGN;
386 struct GNUNET_HashCode result;
387 unsigned int score = 0;
388 unsigned int tmp_score = 0;
389 unsigned int epochs;
390 uint64_t pow_val;
391
392 GNUNET_memcpy (&buf[sizeof(uint64_t)],
393 &pow->timestamp,
394 sizeof (uint64_t));
395 GNUNET_memcpy (&buf[sizeof(uint64_t) * 2],
396 &pow->key,
397 sizeof(struct GNUNET_CRYPTO_EcdsaPublicKey));
398 for (unsigned int i = 0; i < POW_COUNT; i++)
399 {
400 pow_val = GNUNET_ntohll (pow->pow[i]);
401 GNUNET_memcpy (buf, &pow_val, sizeof(uint64_t));
402 GNUNET_CRYPTO_pow_hash ("gnunet-revocation-proof-of-work",
403 buf,
404 sizeof(buf),
405 &result);
406 tmp_score = count_leading_zeroes (&result);
407 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
408 "Score %u (#%u)\n",
409 tmp_score, i);
410 score += tmp_score;
411
412 }
413 score = score / POW_COUNT;
414 if (score < difficulty)
415 return GNUNET_NO;
416 // TODO verfiy signature?
417 epochs = score - difficulty + 1;
418 // TODO verify expiration
419 return GNUNET_YES;
420}
421
422
423struct GNUNET_REVOCATION_PowCalculationHandle*
424GNUNET_REVOCATION_pow_init (const struct GNUNET_CRYPTO_EcdsaPublicKey *key,
425 int epochs,
426 unsigned int difficulty)
427{
428 struct GNUNET_REVOCATION_PowCalculationHandle*pc;
429 struct GNUNET_TIME_Absolute ts = GNUNET_TIME_absolute_get();
430
431 pc = GNUNET_new (struct GNUNET_REVOCATION_PowCalculationHandle);
432 pc->pow.key = *key;
433 pc->pow.timestamp = GNUNET_TIME_absolute_hton(ts);
434 pc->current_pow = GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_WEAK,
435 UINT64_MAX);
436 pc->difficulty = difficulty;
437 pc->epochs = epochs;
438 return pc;
439}
440
441
442/**
443 * Calculate a key revocation valid for broadcasting for a number
444 * of epochs.
445 *
446 * @param pc handle to the PoW, initially called with NULL.
447 * @param epochs number of epochs for which the revocation must be valid.
448 * @param pow current pow value to try
449 * @param difficulty current base difficulty to achieve
450 * @return #GNUNET_YES if the @a pow is acceptable, #GNUNET_NO if not
451 */
452int
453GNUNET_REVOCATION_pow_round (struct GNUNET_REVOCATION_PowCalculationHandle *pc)
362{ 454{
363 char buf[sizeof(struct GNUNET_CRYPTO_EcdsaPublicKey) 455 char buf[sizeof(struct GNUNET_CRYPTO_EcdsaPublicKey)
364 + sizeof(pow) 456 + sizeof (uint64_t)
365 + sizeof (struct GNUNET_TIME_AbsoluteNBO)] GNUNET_ALIGN; 457 + sizeof (uint64_t)] GNUNET_ALIGN;
366 struct GNUNET_HashCode result; 458 struct GNUNET_HashCode result;
367 struct GNUNET_TIME_AbsoluteNBO ts_nbo; 459 unsigned int zeros;
368 460
369 ts_nbo = GNUNET_TIME_absolute_hton (*ts); 461 pc->current_pow++;
370 462
371 GNUNET_memcpy (buf, &pow, sizeof(pow)); 463 GNUNET_memcpy (buf, &pc->current_pow, sizeof(uint64_t));
372 GNUNET_memcpy (&buf[sizeof(pow)], 464 GNUNET_memcpy (&buf[sizeof(uint64_t)],
373 &ts_nbo, 465 &pc->pow.timestamp,
374 sizeof (struct GNUNET_TIME_AbsoluteNBO)); 466 sizeof (uint64_t));
375 GNUNET_memcpy (&buf[sizeof(pow) + sizeof (struct GNUNET_TIME_AbsoluteNBO)], 467 GNUNET_memcpy (&buf[sizeof(uint64_t) * 2],
376 key, 468 &pc->pow.key,
377 sizeof(struct GNUNET_CRYPTO_EcdsaPublicKey)); 469 sizeof(struct GNUNET_CRYPTO_EcdsaPublicKey));
378 GNUNET_CRYPTO_pow_hash ("gnunet-revocation-proof-of-work", 470 GNUNET_CRYPTO_pow_hash ("gnunet-revocation-proof-of-work",
379 buf, 471 buf,
380 sizeof(buf), 472 sizeof(buf),
381 &result); 473 &result);
382 return (count_leading_zeroes (&result) >= 474 zeros = count_leading_zeroes (&result);
383 matching_bits) ? GNUNET_YES : GNUNET_NO; 475 for (unsigned int i = 0; i < POW_COUNT; i++)
476 {
477 if (pc->best[i].bits < zeros)
478 {
479 pc->best[i].bits = zeros;
480 pc->best[i].pow = pc->current_pow;
481 pc->pow.pow[i] = GNUNET_htonll (pc->current_pow);
482 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
483 "New best score %u (#%u)\n",
484 zeros, i);
485 break;
486 }
487 }
488 return calculate_score (pc) >= pc->difficulty + pc->epochs ? GNUNET_YES :
489 GNUNET_NO;
490}
491
492
493const struct GNUNET_REVOCATION_Pow*
494GNUNET_REVOCATION_pow_get (const struct
495 GNUNET_REVOCATION_PowCalculationHandle *pc)
496{
497 return calculate_score (pc) >= pc->difficulty + pc->epochs ? &pc->pow :
498 NULL;
499}
500
501
502void
503GNUNET_REVOCATION_pow_cleanup (struct
504 GNUNET_REVOCATION_PowCalculationHandle *pc)
505{
506 GNUNET_free (pc);
384} 507}
385 508
386 509
@@ -391,20 +514,17 @@ GNUNET_REVOCATION_check_pow (const struct GNUNET_CRYPTO_EcdsaPublicKey *key,
391 * @param sig where to write the revocation signature 514 * @param sig where to write the revocation signature
392 */ 515 */
393void 516void
394GNUNET_REVOCATION_sign_revocation (const struct 517GNUNET_REVOCATION_sign_revocation (struct GNUNET_REVOCATION_Pow *pow,
395 GNUNET_CRYPTO_EcdsaPrivateKey *key, 518 const struct GNUNET_CRYPTO_EcdsaPrivateKey *key)
396 struct GNUNET_CRYPTO_EcdsaSignature *sig)
397{ 519{
398 struct RevokeMessage rm; 520 pow->purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_REVOCATION);
399 521 pow->purpose.size = htonl (sizeof(struct GNUNET_CRYPTO_EccSignaturePurpose)
400 rm.purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_REVOCATION);
401 rm.purpose.size = htonl (sizeof(struct GNUNET_CRYPTO_EccSignaturePurpose)
402 + sizeof(struct GNUNET_CRYPTO_EcdsaPublicKey)); 522 + sizeof(struct GNUNET_CRYPTO_EcdsaPublicKey));
403 GNUNET_CRYPTO_ecdsa_key_get_public (key, &rm.public_key); 523 GNUNET_CRYPTO_ecdsa_key_get_public (key, &pow->key);
404 GNUNET_assert (GNUNET_OK == 524 GNUNET_assert (GNUNET_OK ==
405 GNUNET_CRYPTO_ecdsa_sign_ (key, 525 GNUNET_CRYPTO_ecdsa_sign_ (key,
406 &rm.purpose, 526 &pow->purpose,
407 sig)); 527 &pow->signature));
408} 528}
409 529
410 530