aboutsummaryrefslogtreecommitdiff
path: root/src/revocation/revocation_api.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/revocation/revocation_api.c')
-rw-r--r--src/revocation/revocation_api.c773
1 files changed, 0 insertions, 773 deletions
diff --git a/src/revocation/revocation_api.c b/src/revocation/revocation_api.c
deleted file mode 100644
index b8c458e4f..000000000
--- a/src/revocation/revocation_api.c
+++ /dev/null
@@ -1,773 +0,0 @@
1/*
2 This file is part of GNUnet
3 Copyright (C) 2013, 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 * @file revocation/revocation_api.c
22 * @brief API to perform and access key revocations
23 * @author Christian Grothoff
24 */
25#include "platform.h"
26#include "gnunet_revocation_service.h"
27#include "gnunet_signatures.h"
28#include "gnunet_protocols.h"
29#include "revocation.h"
30#include <inttypes.h>
31
32/**
33 * Handle for the key revocation query.
34 */
35struct GNUNET_REVOCATION_Query
36{
37 /**
38 * Message queue to the service.
39 */
40 struct GNUNET_MQ_Handle *mq;
41
42 /**
43 * Function to call with the result.
44 */
45 GNUNET_REVOCATION_Callback func;
46
47 /**
48 * Closure for @e func.
49 */
50 void *func_cls;
51};
52
53
54/**
55 * Helper struct that holds a found pow nonce
56 * and the corresponding number of leading zeros.
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_PowP *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
106static struct GNUNET_CRYPTO_PowSalt salt = { "GnsRevocationPow" };
107
108/**
109 * Generic error handler, called with the appropriate
110 * error code and the same closure specified at the creation of
111 * the message queue.
112 * Not every message queue implementation supports an error handler.
113 *
114 * @param cls closure with the `struct GNUNET_NSE_Handle *`
115 * @param error error code
116 */
117static void
118query_mq_error_handler (void *cls,
119 enum GNUNET_MQ_Error error)
120{
121 struct GNUNET_REVOCATION_Query *q = cls;
122
123 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
124 "Revocation query MQ error\n");
125 q->func (q->func_cls,
126 GNUNET_SYSERR);
127 GNUNET_REVOCATION_query_cancel (q);
128}
129
130
131/**
132 * Handle response to our revocation query.
133 *
134 * @param cls our `struct GNUNET_REVOCATION_Query` handle
135 * @param qrm response we got
136 */
137static void
138handle_revocation_query_response (void *cls,
139 const struct QueryResponseMessage *qrm)
140{
141 struct GNUNET_REVOCATION_Query *q = cls;
142
143 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
144 "Revocation query result: %d\n",
145 (uint32_t) ntohl (qrm->is_valid));
146 q->func (q->func_cls,
147 ntohl (qrm->is_valid));
148 GNUNET_REVOCATION_query_cancel (q);
149}
150
151
152/**
153 * Check if a key was revoked.
154 *
155 * @param cfg the configuration to use
156 * @param key key to check for revocation
157 * @param func function to call with the result of the check
158 * @param func_cls closure to pass to @a func
159 * @return handle to use in #GNUNET_REVOCATION_query_cancel to stop REVOCATION from invoking the callback
160 */
161struct GNUNET_REVOCATION_Query *
162GNUNET_REVOCATION_query (const struct GNUNET_CONFIGURATION_Handle *cfg,
163 const struct GNUNET_IDENTITY_PublicKey *key,
164 GNUNET_REVOCATION_Callback func,
165 void *func_cls)
166{
167 struct GNUNET_REVOCATION_Query *q
168 = GNUNET_new (struct GNUNET_REVOCATION_Query);
169 struct GNUNET_MQ_MessageHandler handlers[] = {
170 GNUNET_MQ_hd_fixed_size (revocation_query_response,
171 GNUNET_MESSAGE_TYPE_REVOCATION_QUERY_RESPONSE,
172 struct QueryResponseMessage,
173 q),
174 GNUNET_MQ_handler_end ()
175 };
176 struct QueryMessage *qm;
177 struct GNUNET_MQ_Envelope *env;
178
179 q->mq = GNUNET_CLIENT_connect (cfg,
180 "revocation",
181 handlers,
182 &query_mq_error_handler,
183 q);
184 if (NULL == q->mq)
185 {
186 GNUNET_free (q);
187 return NULL;
188 }
189 q->func = func;
190 q->func_cls = func_cls;
191 env = GNUNET_MQ_msg (qm,
192 GNUNET_MESSAGE_TYPE_REVOCATION_QUERY);
193 qm->reserved = htonl (0);
194 qm->key = *key;
195 GNUNET_MQ_send (q->mq,
196 env);
197 return q;
198}
199
200
201/**
202 * Cancel key revocation check.
203 *
204 * @param q query to cancel
205 */
206void
207GNUNET_REVOCATION_query_cancel (struct GNUNET_REVOCATION_Query *q)
208{
209 if (NULL != q->mq)
210 {
211 GNUNET_MQ_destroy (q->mq);
212 q->mq = NULL;
213 }
214 GNUNET_free (q);
215}
216
217
218/**
219 * Handle for the key revocation operation.
220 */
221struct GNUNET_REVOCATION_Handle
222{
223 /**
224 * Message queue to the service.
225 */
226 struct GNUNET_MQ_Handle *mq;
227
228 /**
229 * Function to call once we are done.
230 */
231 GNUNET_REVOCATION_Callback func;
232
233 /**
234 * Closure for @e func.
235 */
236 void *func_cls;
237};
238
239
240/**
241 * Generic error handler, called with the appropriate
242 * error code and the same closure specified at the creation of
243 * the message queue.
244 * Not every message queue implementation supports an error handler.
245 *
246 * @param cls closure with the `struct GNUNET_NSE_Handle *`
247 * @param error error code
248 */
249static void
250revocation_mq_error_handler (void *cls,
251 enum GNUNET_MQ_Error error)
252{
253 struct GNUNET_REVOCATION_Handle *h = cls;
254
255 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
256 "Revocation MQ error\n");
257 h->func (h->func_cls,
258 GNUNET_SYSERR);
259 GNUNET_REVOCATION_revoke_cancel (h);
260}
261
262
263/**
264 * Handle response to our revocation query.
265 *
266 * @param cls our `struct GNUNET_REVOCATION_Handle` handle
267 * @param rrm response we got
268 */
269static void
270handle_revocation_response (void *cls,
271 const struct RevocationResponseMessage *rrm)
272{
273 struct GNUNET_REVOCATION_Handle *h = cls;
274
275 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
276 "Revocation transmission result: %d\n",
277 (uint32_t) ntohl (rrm->is_valid));
278 h->func (h->func_cls,
279 ntohl (rrm->is_valid));
280 GNUNET_REVOCATION_revoke_cancel (h);
281}
282
283
284/**
285 * Perform key revocation.
286 *
287 * @param cfg the configuration to use
288 * @param key public key of the key to revoke
289 * @param sig signature to use on the revocation (should have been
290 * created using #GNUNET_REVOCATION_sign_revocation).
291 * @param ts revocation timestamp
292 * @param pow proof of work to use (should have been created by
293 * iteratively calling #GNUNET_REVOCATION_check_pow)
294 * @param func function to call with the result of the check
295 * (called with `is_valid` being #GNUNET_NO if
296 * the revocation worked).
297 * @param func_cls closure to pass to @a func
298 * @return handle to use in #GNUNET_REVOCATION_revoke_cancel to stop REVOCATION from invoking the callback
299 */
300struct GNUNET_REVOCATION_Handle *
301GNUNET_REVOCATION_revoke (const struct GNUNET_CONFIGURATION_Handle *cfg,
302 const struct GNUNET_REVOCATION_PowP *pow,
303 GNUNET_REVOCATION_Callback func,
304 void *func_cls)
305{
306 struct GNUNET_REVOCATION_Handle *h
307 = GNUNET_new (struct GNUNET_REVOCATION_Handle);
308 struct GNUNET_MQ_MessageHandler handlers[] = {
309 GNUNET_MQ_hd_fixed_size (revocation_response,
310 GNUNET_MESSAGE_TYPE_REVOCATION_REVOKE_RESPONSE,
311 struct RevocationResponseMessage,
312 h),
313 GNUNET_MQ_handler_end ()
314 };
315 unsigned long long matching_bits;
316 struct GNUNET_TIME_Relative epoch_duration;
317 struct RevokeMessage *rm;
318 struct GNUNET_MQ_Envelope *env;
319
320 if ((GNUNET_OK !=
321 GNUNET_CONFIGURATION_get_value_number (cfg,
322 "REVOCATION",
323 "WORKBITS",
324 &matching_bits)))
325 {
326 GNUNET_break (0);
327 GNUNET_free (h);
328 return NULL;
329 }
330 if ((GNUNET_OK !=
331 GNUNET_CONFIGURATION_get_value_time (cfg,
332 "REVOCATION",
333 "EPOCH_DURATION",
334 &epoch_duration)))
335 {
336 GNUNET_break (0);
337 GNUNET_free (h);
338 return NULL;
339 }
340 if (GNUNET_YES != GNUNET_REVOCATION_check_pow (pow,
341 (unsigned int) matching_bits,
342 epoch_duration))
343 {
344 GNUNET_break (0);
345 GNUNET_free (h);
346 return NULL;
347 }
348
349
350 h->mq = GNUNET_CLIENT_connect (cfg,
351 "revocation",
352 handlers,
353 &revocation_mq_error_handler,
354 h);
355 if (NULL == h->mq)
356 {
357 GNUNET_free (h);
358 return NULL;
359 }
360 h->func = func;
361 h->func_cls = func_cls;
362 size_t extra_len = GNUNET_REVOCATION_proof_get_size (pow);
363 env = GNUNET_MQ_msg_extra (rm,
364 extra_len,
365 GNUNET_MESSAGE_TYPE_REVOCATION_REVOKE);
366 rm->pow_size = htonl (extra_len);
367 memcpy (&rm[1], pow, extra_len);
368 GNUNET_MQ_send (h->mq,
369 env);
370 return h;
371}
372
373
374/**
375 * Cancel key revocation.
376 *
377 * @param h operation to cancel
378 */
379void
380GNUNET_REVOCATION_revoke_cancel (struct GNUNET_REVOCATION_Handle *h)
381{
382 if (NULL != h->mq)
383 {
384 GNUNET_MQ_destroy (h->mq);
385 h->mq = NULL;
386 }
387 GNUNET_free (h);
388}
389
390
391/**
392 * Calculate the average zeros in the pows.
393 *
394 * @param ph the PowHandle
395 * @return the average number of zeros.
396 */
397static unsigned int
398calculate_score (const struct GNUNET_REVOCATION_PowCalculationHandle *ph)
399{
400 double sum = 0.0;
401 for (unsigned int j = 0; j<POW_COUNT; j++)
402 sum += ph->best[j].bits;
403 double avg = sum / POW_COUNT;
404 return avg;
405}
406
407struct GNUNET_REVOCATION_SignaturePurposePS *
408REV_create_signature_message (const struct GNUNET_REVOCATION_PowP *pow)
409{
410 struct GNUNET_REVOCATION_SignaturePurposePS *spurp;
411 const struct GNUNET_IDENTITY_PublicKey *pk;
412 size_t ksize;
413
414 pk = (const struct GNUNET_IDENTITY_PublicKey *) &pow[1];
415 ksize = GNUNET_IDENTITY_key_get_length (pk);
416 spurp = GNUNET_malloc (sizeof (*spurp) + ksize);
417 spurp->timestamp = pow->timestamp;
418 spurp->purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_REVOCATION);
419 spurp->purpose.size = htonl (sizeof(*spurp) + ksize);
420 GNUNET_IDENTITY_write_key_to_buffer (pk,
421 (char*) &spurp[1],
422 ksize);
423 return spurp;
424}
425
426enum GNUNET_GenericReturnValue
427check_signature_identity (const struct GNUNET_REVOCATION_PowP *pow,
428 const struct GNUNET_IDENTITY_PublicKey *key)
429{
430 struct GNUNET_REVOCATION_SignaturePurposePS *spurp;
431 unsigned char *sig;
432 size_t ksize;
433
434 ksize = GNUNET_IDENTITY_key_get_length (key);
435 spurp = REV_create_signature_message (pow);
436 sig = ((unsigned char*) &pow[1] + ksize);
437 if (GNUNET_OK !=
438 GNUNET_IDENTITY_signature_verify_raw_ (GNUNET_SIGNATURE_PURPOSE_REVOCATION,
439 &spurp->purpose,
440 sig,
441 key))
442 {
443 return GNUNET_SYSERR;
444 }
445 return GNUNET_OK;
446}
447
448
449enum GNUNET_GenericReturnValue
450check_signature (const struct GNUNET_REVOCATION_PowP *pow)
451{
452 const struct GNUNET_IDENTITY_PublicKey *pk;
453
454 pk = (const struct GNUNET_IDENTITY_PublicKey *) &pow[1];
455 return check_signature_identity (pow, pk);
456}
457
458
459/**
460 * Check if the given proof-of-work is valid.
461 *
462 * @param pow proof of work
463 * @param difficulty how many bits must match (configuration) LSD0001: D
464 * @param epoch_duration length of single epoch in configuration
465 * @return #GNUNET_YES if the @a pow is acceptable, #GNUNET_NO if not
466 */
467enum GNUNET_GenericReturnValue
468GNUNET_REVOCATION_check_pow (const struct GNUNET_REVOCATION_PowP *pow,
469 unsigned int difficulty,
470 struct GNUNET_TIME_Relative epoch_duration)
471{
472 char buf[sizeof(struct GNUNET_IDENTITY_PublicKey)
473 + sizeof (struct GNUNET_TIME_AbsoluteNBO)
474 + sizeof (uint64_t)] GNUNET_ALIGN;
475 struct GNUNET_HashCode result;
476 struct GNUNET_TIME_Absolute ts;
477 struct GNUNET_TIME_Absolute exp;
478 struct GNUNET_TIME_Relative ttl;
479 struct GNUNET_TIME_Relative buffer;
480 /* LSD0001: D' */
481 unsigned int score = 0;
482 unsigned int tmp_score = 0;
483 unsigned int epochs;
484 uint64_t pow_val;
485 ssize_t pklen;
486 const struct GNUNET_IDENTITY_PublicKey *pk;
487
488 pk = (const struct GNUNET_IDENTITY_PublicKey *) &pow[1];
489
490 /**
491 * Check if signature valid
492 */
493 if (GNUNET_OK != check_signature (pow))
494 {
495 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
496 "Proof of work signature invalid!\n");
497 return GNUNET_SYSERR;
498 }
499
500 /**
501 * First, check if PoW set is strictly monotically increasing
502 */
503 for (unsigned int i = 0; i < POW_COUNT - 1; i++)
504 {
505 if (GNUNET_ntohll (pow->pow[i]) >= GNUNET_ntohll (pow->pow[i + 1]))
506 return GNUNET_NO;
507 }
508 GNUNET_memcpy (&buf[sizeof(uint64_t)],
509 &pow->timestamp,
510 sizeof (uint64_t));
511 pklen = GNUNET_IDENTITY_key_get_length (pk);
512 if (0 > pklen)
513 {
514 GNUNET_break (0);
515 return GNUNET_NO;
516 }
517 GNUNET_memcpy (&buf[sizeof(uint64_t) * 2],
518 pk,
519 pklen);
520 for (unsigned int i = 0; i < POW_COUNT; i++)
521 {
522 pow_val = GNUNET_ntohll (pow->pow[i]);
523 GNUNET_memcpy (buf, &pow->pow[i], sizeof(uint64_t));
524 GNUNET_CRYPTO_pow_hash (&salt,
525 buf,
526 sizeof(buf),
527 &result);
528 tmp_score = GNUNET_CRYPTO_hash_count_leading_zeros (&result);
529 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
530 "Score %u with %" PRIu64 " (#%u)\n",
531 tmp_score, pow_val, i);
532
533 score += tmp_score;
534
535 }
536 score = score / POW_COUNT;
537 if (score < difficulty)
538 return GNUNET_NO;
539 /* LSD0001: (D'-D+1) */
540 epochs = score - difficulty + 1;
541
542 /**
543 * Check expiration
544 */
545 ts = GNUNET_TIME_absolute_ntoh (pow->timestamp);
546 ttl = GNUNET_TIME_relative_multiply (epoch_duration,
547 epochs);
548 /**
549 * Extend by 10% for unsynchronized clocks
550 */
551 buffer = GNUNET_TIME_relative_divide (epoch_duration,
552 10);
553 exp = GNUNET_TIME_absolute_add (ts, ttl);
554 exp = GNUNET_TIME_absolute_add (exp,
555 buffer);
556
557 if (0 != GNUNET_TIME_absolute_get_remaining (ts).rel_value_us)
558 return GNUNET_NO; /* Not yet valid. */
559 /* Revert to actual start time */
560 ts = GNUNET_TIME_absolute_add (ts,
561 buffer);
562
563 if (0 == GNUNET_TIME_absolute_get_remaining (exp).rel_value_us)
564 return GNUNET_NO; /* expired */
565 return GNUNET_YES;
566}
567
568
569enum GNUNET_GenericReturnValue
570sign_pow_identity (const struct GNUNET_IDENTITY_PrivateKey *key,
571 struct GNUNET_REVOCATION_PowP *pow)
572{
573 struct GNUNET_TIME_Absolute ts = GNUNET_TIME_absolute_get ();
574 struct GNUNET_REVOCATION_SignaturePurposePS *rp;
575 const struct GNUNET_IDENTITY_PublicKey *pk;
576 size_t ksize;
577 char *sig;
578
579 /**
580 * Predate the validity period to prevent rejections due to
581 * unsynchronized clocks
582 */
583 ts = GNUNET_TIME_absolute_subtract (ts,
584 GNUNET_TIME_UNIT_WEEKS);
585 pk = (const struct GNUNET_IDENTITY_PublicKey *) &pow[1];
586 ksize = GNUNET_IDENTITY_key_get_length (pk);
587 pow->timestamp = GNUNET_TIME_absolute_hton (ts);
588 rp = REV_create_signature_message (pow);
589 sig = ((char*) &pow[1]) + ksize;
590 int result = GNUNET_IDENTITY_sign_raw_ (key,
591 &rp->purpose,
592 (void*) sig);
593 if (result == GNUNET_SYSERR)
594 return GNUNET_NO;
595 else
596 return result;
597}
598
599
600enum GNUNET_GenericReturnValue
601sign_pow (const struct GNUNET_IDENTITY_PrivateKey *key,
602 struct GNUNET_REVOCATION_PowP *pow)
603{
604 struct GNUNET_IDENTITY_PublicKey *pk;
605
606 pk = (struct GNUNET_IDENTITY_PublicKey *) &pow[1];
607 GNUNET_IDENTITY_key_get_public (key, pk);
608 return sign_pow_identity (key, pow);
609}
610
611
612/**
613 * Initializes a fresh PoW computation.
614 *
615 * @param key the key to calculate the PoW for.
616 * @param[out] pow starting point for PoW calculation (not yet valid)
617 */
618void
619GNUNET_REVOCATION_pow_init (const struct GNUNET_IDENTITY_PrivateKey *key,
620 struct GNUNET_REVOCATION_PowP *pow)
621{
622 GNUNET_assert (GNUNET_OK == sign_pow (key, pow));
623}
624
625
626/**
627 * Starts a proof-of-work calculation given the pow object as well as
628 * target epochs and difficulty.
629 *
630 * @param pow the PoW to based calculations on.
631 * @param epochs the number of epochs for which the PoW must be valid.
632 * @param difficulty the base difficulty of the PoW.
633 * @return a handle for use in PoW rounds
634 */
635struct GNUNET_REVOCATION_PowCalculationHandle*
636GNUNET_REVOCATION_pow_start (struct GNUNET_REVOCATION_PowP *pow,
637 int epochs,
638 unsigned int difficulty)
639{
640 struct GNUNET_REVOCATION_PowCalculationHandle *pc;
641 struct GNUNET_TIME_Relative ttl;
642
643
644 pc = GNUNET_new (struct GNUNET_REVOCATION_PowCalculationHandle);
645 pc->pow = pow;
646 ttl = GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_YEARS,
647 epochs);
648 pc->pow->ttl = GNUNET_TIME_relative_hton (ttl);
649 pc->current_pow = GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_WEAK,
650 UINT64_MAX);
651 pc->difficulty = difficulty;
652 pc->epochs = epochs;
653 return pc;
654}
655
656
657/**
658 * Comparison function for quicksort
659 *
660 * @param a left element
661 * @param b right element
662 * @return a-b
663 */
664static int
665cmp_pow_value (const void *a, const void *b)
666{
667 return (GNUNET_ntohll (*(uint64_t*) a) - GNUNET_ntohll (*(uint64_t*) b));
668}
669
670
671/**
672 * Calculate a key revocation valid for broadcasting for a number
673 * of epochs.
674 *
675 * @param pc handle to the PoW, initially called with NULL.
676 * @param epochs number of epochs for which the revocation must be valid.
677 * @param pow current pow value to try
678 * @param difficulty current base difficulty to achieve
679 * @return #GNUNET_YES if the @a pow is acceptable, #GNUNET_NO if not
680 */
681enum GNUNET_GenericReturnValue
682GNUNET_REVOCATION_pow_round (struct GNUNET_REVOCATION_PowCalculationHandle *pc)
683{
684 char buf[sizeof(struct GNUNET_IDENTITY_PublicKey)
685 + sizeof (uint64_t)
686 + sizeof (uint64_t)] GNUNET_ALIGN;
687 struct GNUNET_HashCode result;
688 const struct GNUNET_IDENTITY_PublicKey *pk;
689 unsigned int zeros;
690 int ret;
691 uint64_t pow_nbo;
692 ssize_t ksize;
693
694 pc->current_pow++;
695 pk = (const struct GNUNET_IDENTITY_PublicKey *) &(pc->pow[1]);
696
697 /**
698 * Do not try duplicates
699 */
700 for (unsigned int i = 0; i < POW_COUNT; i++)
701 if (pc->current_pow == pc->best[i].pow)
702 return GNUNET_NO;
703 pow_nbo = GNUNET_htonll (pc->current_pow);
704 GNUNET_memcpy (buf, &pow_nbo, sizeof(uint64_t));
705 GNUNET_memcpy (&buf[sizeof(uint64_t)],
706 &pc->pow->timestamp,
707 sizeof (uint64_t));
708 ksize = GNUNET_IDENTITY_key_get_length (pk);
709 GNUNET_assert (0 < ksize);
710 GNUNET_memcpy (&buf[sizeof(uint64_t) * 2],
711 pk,
712 ksize);
713 GNUNET_CRYPTO_pow_hash (&salt,
714 buf,
715 sizeof(buf),
716 &result);
717 zeros = GNUNET_CRYPTO_hash_count_leading_zeros (&result);
718 for (unsigned int i = 0; i < POW_COUNT; i++)
719 {
720 if (pc->best[i].bits < zeros)
721 {
722 pc->best[i].bits = zeros;
723 pc->best[i].pow = pc->current_pow;
724 pc->pow->pow[i] = pow_nbo;
725 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
726 "New best score %u with %" PRIu64 " (#%u)\n",
727 zeros, pc->current_pow, i);
728
729 break;
730 }
731 }
732 ret = calculate_score (pc) >= pc->difficulty + pc->epochs ? GNUNET_YES :
733 GNUNET_NO;
734 if (GNUNET_YES == ret)
735 {
736 /* Sort POWs) */
737 qsort (pc->pow->pow, POW_COUNT, sizeof (uint64_t), &cmp_pow_value);
738 }
739 return ret;
740}
741
742
743/**
744 * Stop a PoW calculation
745 *
746 * @param pc the calculation to clean up
747 * @return #GNUNET_YES if pow valid, #GNUNET_NO if pow was set but is not
748 * valid
749 */
750void
751GNUNET_REVOCATION_pow_stop (struct GNUNET_REVOCATION_PowCalculationHandle *pc)
752{
753 GNUNET_free (pc);
754}
755
756
757size_t
758GNUNET_REVOCATION_proof_get_size (const struct GNUNET_REVOCATION_PowP *pow)
759{
760 size_t size;
761 size_t ksize;
762 const struct GNUNET_IDENTITY_PublicKey *pk;
763
764 size = sizeof (struct GNUNET_REVOCATION_PowP);
765 pk = (const struct GNUNET_IDENTITY_PublicKey *) &pow[1];
766 ksize = GNUNET_IDENTITY_key_get_length (pk);
767 size += ksize;
768 size += GNUNET_IDENTITY_signature_get_raw_length_by_type (pk->type);
769 return size;
770}
771
772
773/* end of revocation_api.c */