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.c771
1 files changed, 0 insertions, 771 deletions
diff --git a/src/revocation/revocation_api.c b/src/revocation/revocation_api.c
deleted file mode 100644
index 9080ab862..000000000
--- a/src/revocation/revocation_api.c
+++ /dev/null
@@ -1,771 +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 matching_bits how many bits must match (configuration)
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 unsigned int score = 0;
481 unsigned int tmp_score = 0;
482 unsigned int epochs;
483 uint64_t pow_val;
484 ssize_t pklen;
485 const struct GNUNET_IDENTITY_PublicKey *pk;
486
487 pk = (const struct GNUNET_IDENTITY_PublicKey *) &pow[1];
488
489 /**
490 * Check if signature valid
491 */
492 if (GNUNET_OK != check_signature (pow))
493 {
494 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
495 "Proof of work signature invalid!\n");
496 return GNUNET_SYSERR;
497 }
498
499 /**
500 * First, check if PoW set is strictly monotically increasing
501 */
502 for (unsigned int i = 0; i < POW_COUNT - 1; i++)
503 {
504 if (GNUNET_ntohll (pow->pow[i]) >= GNUNET_ntohll (pow->pow[i + 1]))
505 return GNUNET_NO;
506 }
507 GNUNET_memcpy (&buf[sizeof(uint64_t)],
508 &pow->timestamp,
509 sizeof (uint64_t));
510 pklen = GNUNET_IDENTITY_key_get_length (pk);
511 if (0 > pklen)
512 {
513 GNUNET_break (0);
514 return GNUNET_NO;
515 }
516 GNUNET_memcpy (&buf[sizeof(uint64_t) * 2],
517 pk,
518 pklen);
519 for (unsigned int i = 0; i < POW_COUNT; i++)
520 {
521 pow_val = GNUNET_ntohll (pow->pow[i]);
522 GNUNET_memcpy (buf, &pow->pow[i], sizeof(uint64_t));
523 GNUNET_CRYPTO_pow_hash (&salt,
524 buf,
525 sizeof(buf),
526 &result);
527 tmp_score = GNUNET_CRYPTO_hash_count_leading_zeros (&result);
528 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
529 "Score %u with %" PRIu64 " (#%u)\n",
530 tmp_score, pow_val, i);
531
532 score += tmp_score;
533
534 }
535 score = score / POW_COUNT;
536 if (score < difficulty)
537 return GNUNET_NO;
538 epochs = score - difficulty;
539
540 /**
541 * Check expiration
542 */
543 ts = GNUNET_TIME_absolute_ntoh (pow->timestamp);
544 ttl = GNUNET_TIME_relative_multiply (epoch_duration,
545 epochs);
546 /**
547 * Extend by 10% for unsynchronized clocks
548 */
549 buffer = GNUNET_TIME_relative_divide (epoch_duration,
550 10);
551 exp = GNUNET_TIME_absolute_add (ts, ttl);
552 exp = GNUNET_TIME_absolute_add (exp,
553 buffer);
554
555 if (0 != GNUNET_TIME_absolute_get_remaining (ts).rel_value_us)
556 return GNUNET_NO; /* Not yet valid. */
557 /* Revert to actual start time */
558 ts = GNUNET_TIME_absolute_add (ts,
559 buffer);
560
561 if (0 == GNUNET_TIME_absolute_get_remaining (exp).rel_value_us)
562 return GNUNET_NO; /* expired */
563 return GNUNET_YES;
564}
565
566
567enum GNUNET_GenericReturnValue
568sign_pow_identity (const struct GNUNET_IDENTITY_PrivateKey *key,
569 struct GNUNET_REVOCATION_PowP *pow)
570{
571 struct GNUNET_TIME_Absolute ts = GNUNET_TIME_absolute_get ();
572 struct GNUNET_REVOCATION_SignaturePurposePS *rp;
573 const struct GNUNET_IDENTITY_PublicKey *pk;
574 size_t ksize;
575 char *sig;
576
577 /**
578 * Predate the validity period to prevent rejections due to
579 * unsynchronized clocks
580 */
581 ts = GNUNET_TIME_absolute_subtract (ts,
582 GNUNET_TIME_UNIT_WEEKS);
583 pk = (const struct GNUNET_IDENTITY_PublicKey *) &pow[1];
584 ksize = GNUNET_IDENTITY_key_get_length (pk);
585 pow->timestamp = GNUNET_TIME_absolute_hton (ts);
586 rp = REV_create_signature_message (pow);
587 sig = ((char*) &pow[1]) + ksize;
588 int result = GNUNET_IDENTITY_sign_raw_ (key,
589 &rp->purpose,
590 (void*) sig);
591 if (result == GNUNET_SYSERR)
592 return GNUNET_NO;
593 else
594 return result;
595}
596
597
598enum GNUNET_GenericReturnValue
599sign_pow (const struct GNUNET_IDENTITY_PrivateKey *key,
600 struct GNUNET_REVOCATION_PowP *pow)
601{
602 struct GNUNET_IDENTITY_PublicKey *pk;
603
604 pk = (struct GNUNET_IDENTITY_PublicKey *) &pow[1];
605 GNUNET_IDENTITY_key_get_public (key, pk);
606 return sign_pow_identity (key, pow);
607}
608
609
610/**
611 * Initializes a fresh PoW computation.
612 *
613 * @param key the key to calculate the PoW for.
614 * @param[out] pow starting point for PoW calculation (not yet valid)
615 */
616void
617GNUNET_REVOCATION_pow_init (const struct GNUNET_IDENTITY_PrivateKey *key,
618 struct GNUNET_REVOCATION_PowP *pow)
619{
620 GNUNET_assert (GNUNET_OK == sign_pow (key, pow));
621}
622
623
624/**
625 * Starts a proof-of-work calculation given the pow object as well as
626 * target epochs and difficulty.
627 *
628 * @param pow the PoW to based calculations on.
629 * @param epochs the number of epochs for which the PoW must be valid.
630 * @param difficulty the base difficulty of the PoW.
631 * @return a handle for use in PoW rounds
632 */
633struct GNUNET_REVOCATION_PowCalculationHandle*
634GNUNET_REVOCATION_pow_start (struct GNUNET_REVOCATION_PowP *pow,
635 int epochs,
636 unsigned int difficulty)
637{
638 struct GNUNET_REVOCATION_PowCalculationHandle *pc;
639 struct GNUNET_TIME_Relative ttl;
640
641
642 pc = GNUNET_new (struct GNUNET_REVOCATION_PowCalculationHandle);
643 pc->pow = pow;
644 ttl = GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_YEARS,
645 epochs);
646 pc->pow->ttl = GNUNET_TIME_relative_hton (ttl);
647 pc->current_pow = GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_WEAK,
648 UINT64_MAX);
649 pc->difficulty = difficulty;
650 pc->epochs = epochs;
651 return pc;
652}
653
654
655/**
656 * Comparison function for quicksort
657 *
658 * @param a left element
659 * @param b right element
660 * @return a-b
661 */
662static int
663cmp_pow_value (const void *a, const void *b)
664{
665 return (GNUNET_ntohll (*(uint64_t*) a) - GNUNET_ntohll (*(uint64_t*) b));
666}
667
668
669/**
670 * Calculate a key revocation valid for broadcasting for a number
671 * of epochs.
672 *
673 * @param pc handle to the PoW, initially called with NULL.
674 * @param epochs number of epochs for which the revocation must be valid.
675 * @param pow current pow value to try
676 * @param difficulty current base difficulty to achieve
677 * @return #GNUNET_YES if the @a pow is acceptable, #GNUNET_NO if not
678 */
679enum GNUNET_GenericReturnValue
680GNUNET_REVOCATION_pow_round (struct GNUNET_REVOCATION_PowCalculationHandle *pc)
681{
682 char buf[sizeof(struct GNUNET_IDENTITY_PublicKey)
683 + sizeof (uint64_t)
684 + sizeof (uint64_t)] GNUNET_ALIGN;
685 struct GNUNET_HashCode result;
686 const struct GNUNET_IDENTITY_PublicKey *pk;
687 unsigned int zeros;
688 int ret;
689 uint64_t pow_nbo;
690 ssize_t ksize;
691
692 pc->current_pow++;
693 pk = (const struct GNUNET_IDENTITY_PublicKey *) &(pc->pow[1]);
694
695 /**
696 * Do not try duplicates
697 */
698 for (unsigned int i = 0; i < POW_COUNT; i++)
699 if (pc->current_pow == pc->best[i].pow)
700 return GNUNET_NO;
701 pow_nbo = GNUNET_htonll (pc->current_pow);
702 GNUNET_memcpy (buf, &pow_nbo, sizeof(uint64_t));
703 GNUNET_memcpy (&buf[sizeof(uint64_t)],
704 &pc->pow->timestamp,
705 sizeof (uint64_t));
706 ksize = GNUNET_IDENTITY_key_get_length (pk);
707 GNUNET_assert (0 < ksize);
708 GNUNET_memcpy (&buf[sizeof(uint64_t) * 2],
709 pk,
710 ksize);
711 GNUNET_CRYPTO_pow_hash (&salt,
712 buf,
713 sizeof(buf),
714 &result);
715 zeros = GNUNET_CRYPTO_hash_count_leading_zeros (&result);
716 for (unsigned int i = 0; i < POW_COUNT; i++)
717 {
718 if (pc->best[i].bits < zeros)
719 {
720 pc->best[i].bits = zeros;
721 pc->best[i].pow = pc->current_pow;
722 pc->pow->pow[i] = pow_nbo;
723 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
724 "New best score %u with %" PRIu64 " (#%u)\n",
725 zeros, pc->current_pow, i);
726
727 break;
728 }
729 }
730 ret = calculate_score (pc) >= pc->difficulty + pc->epochs ? GNUNET_YES :
731 GNUNET_NO;
732 if (GNUNET_YES == ret)
733 {
734 /* Sort POWs) */
735 qsort (pc->pow->pow, POW_COUNT, sizeof (uint64_t), &cmp_pow_value);
736 }
737 return ret;
738}
739
740
741/**
742 * Stop a PoW calculation
743 *
744 * @param pc the calculation to clean up
745 * @return #GNUNET_YES if pow valid, #GNUNET_NO if pow was set but is not
746 * valid
747 */
748void
749GNUNET_REVOCATION_pow_stop (struct GNUNET_REVOCATION_PowCalculationHandle *pc)
750{
751 GNUNET_free (pc);
752}
753
754
755size_t
756GNUNET_REVOCATION_proof_get_size (const struct GNUNET_REVOCATION_PowP *pow)
757{
758 size_t size;
759 size_t ksize;
760 const struct GNUNET_IDENTITY_PublicKey *pk;
761
762 size = sizeof (struct GNUNET_REVOCATION_PowP);
763 pk = (const struct GNUNET_IDENTITY_PublicKey *) &pow[1];
764 ksize = GNUNET_IDENTITY_key_get_length (pk);
765 size += ksize;
766 size += GNUNET_IDENTITY_signature_get_raw_length_by_type (pk->type);
767 return size;
768}
769
770
771/* end of revocation_api.c */