GNUnet 0.21.0
crypto_ecc.c
Go to the documentation of this file.
1/*
2 This file is part of GNUnet.
3 Copyright (C) 2012, 2013, 2015 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
28#include "platform.h"
29#include <gcrypt.h>
30#include <sodium.h>
31#include "gnunet_util_lib.h"
32#include "benchmark.h"
33
34#define EXTRA_CHECKS 0
35
59#define CURVE "Ed25519"
60
61#define LOG(kind, ...) GNUNET_log_from (kind, "util-crypto-ecc", __VA_ARGS__)
62
63#define LOG_STRERROR(kind, syscall) \
64 GNUNET_log_from_strerror (kind, "util-crypto-ecc", syscall)
65
66#define LOG_STRERROR_FILE(kind, syscall, filename) \
67 GNUNET_log_from_strerror_file (kind, "util-crypto-ecc", syscall, \
68 filename)
69
75#define LOG_GCRY(level, cmd, rc) \
76 do \
77 { \
78 LOG (level, \
79 _ ("`%s' failed at %s:%d with error: %s\n"), \
80 cmd, \
81 __FILE__, \
82 __LINE__, \
83 gcry_strerror (rc)); \
84 } while (0)
85
86
96static int
97key_from_sexp (gcry_mpi_t *array,
98 gcry_sexp_t sexp,
99 const char *topname,
100 const char *elems)
101{
102 gcry_sexp_t list;
103 gcry_sexp_t l2;
104 unsigned int idx;
105
106 list = gcry_sexp_find_token (sexp, topname, 0);
107 if (! list)
108 return 1;
109 l2 = gcry_sexp_cadr (list);
110 gcry_sexp_release (list);
111 list = l2;
112 if (! list)
113 return 2;
114
115 idx = 0;
116 for (const char *s = elems; *s; s++, idx++)
117 {
118 l2 = gcry_sexp_find_token (list, s, 1);
119 if (! l2)
120 {
121 for (unsigned int i = 0; i < idx; i++)
122 {
123 gcry_free (array[i]);
124 array[i] = NULL;
125 }
126 gcry_sexp_release (list);
127 return 3; /* required parameter not found */
128 }
129 array[idx] = gcry_sexp_nth_mpi (l2, 1, GCRYMPI_FMT_USG);
130 gcry_sexp_release (l2);
131 if (! array[idx])
132 {
133 for (unsigned int i = 0; i < idx; i++)
134 {
135 gcry_free (array[i]);
136 array[i] = NULL;
137 }
138 gcry_sexp_release (list);
139 return 4; /* required parameter is invalid */
140 }
141 }
142 gcry_sexp_release (list);
143 return 0;
144}
145
146
154static gcry_sexp_t
156{
157 gcry_sexp_t result;
158 int rc;
159 uint8_t d[32];
160
161 for (size_t i = 0; i<32; i++)
162 d[i] = priv->d[31 - i];
163
164 rc = gcry_sexp_build (&result,
165 NULL,
166 "(private-key(ecc(curve \"" CURVE "\")"
167 "(d %b)))",
168 32,
169 d);
170 if (0 != rc)
171 {
172 LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_sexp_build", rc);
173 GNUNET_assert (0);
174 }
175#if EXTRA_CHECKS
176 if (0 != (rc = gcry_pk_testkey (result)))
177 {
178 LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_pk_testkey", rc);
179 GNUNET_assert (0);
180 }
181#endif
182 return result;
183}
184
185
186void
188 const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv,
190{
191 BENCHMARK_START (ecdsa_key_get_public);
192 crypto_scalarmult_ed25519_base_noclamp (pub->q_y, priv->d);
193 BENCHMARK_END (ecdsa_key_get_public);
194}
195
196
197void
199 const struct GNUNET_CRYPTO_EddsaPrivateKey *priv,
201{
202 unsigned char pk[crypto_sign_PUBLICKEYBYTES];
203 unsigned char sk[crypto_sign_SECRETKEYBYTES];
204
205 BENCHMARK_START (eddsa_key_get_public);
206 GNUNET_assert (0 == crypto_sign_seed_keypair (pk, sk, priv->d));
207 GNUNET_memcpy (pub->q_y, pk, crypto_sign_PUBLICKEYBYTES);
208 sodium_memzero (sk, crypto_sign_SECRETKEYBYTES);
209 BENCHMARK_END (eddsa_key_get_public);
210}
211
212
213void
215 const struct GNUNET_CRYPTO_EcdhePrivateKey *priv,
217{
218 BENCHMARK_START (ecdhe_key_get_public);
219 GNUNET_assert (0 == crypto_scalarmult_base (pub->q_y, priv->d));
220 BENCHMARK_END (ecdhe_key_get_public);
221}
222
223
224char *
226 const struct GNUNET_CRYPTO_EcdsaPublicKey *pub)
227{
228 char *pubkeybuf;
229 size_t keylen = (sizeof(struct GNUNET_CRYPTO_EcdsaPublicKey)) * 8;
230 char *end;
231
232 if (keylen % 5 > 0)
233 keylen += 5 - keylen % 5;
234 keylen /= 5;
235 pubkeybuf = GNUNET_malloc (keylen + 1);
236 end =
237 GNUNET_STRINGS_data_to_string ((unsigned char *) pub,
238 sizeof(struct GNUNET_CRYPTO_EcdsaPublicKey),
239 pubkeybuf,
240 keylen);
241 if (NULL == end)
242 {
243 GNUNET_free (pubkeybuf);
244 return NULL;
245 }
246 *end = '\0';
247 return pubkeybuf;
248}
249
250
251char *
253 const struct GNUNET_CRYPTO_EddsaPublicKey *pub)
254{
255 char *pubkeybuf;
256 size_t keylen = (sizeof(struct GNUNET_CRYPTO_EddsaPublicKey)) * 8;
257 char *end;
258
259 if (keylen % 5 > 0)
260 keylen += 5 - keylen % 5;
261 keylen /= 5;
262 pubkeybuf = GNUNET_malloc (keylen + 1);
263 end =
264 GNUNET_STRINGS_data_to_string ((unsigned char *) pub,
265 sizeof(struct GNUNET_CRYPTO_EddsaPublicKey),
266 pubkeybuf,
267 keylen);
268 if (NULL == end)
269 {
270 GNUNET_free (pubkeybuf);
271 return NULL;
272 }
273 *end = '\0';
274 return pubkeybuf;
275}
276
277
278char *
280 const struct GNUNET_CRYPTO_EddsaPrivateKey *priv)
281{
282 char *privkeybuf;
283 size_t keylen = (sizeof(struct GNUNET_CRYPTO_EddsaPrivateKey)) * 8;
284 char *end;
285
286 if (keylen % 5 > 0)
287 keylen += 5 - keylen % 5;
288 keylen /= 5;
289 privkeybuf = GNUNET_malloc (keylen + 1);
290 end = GNUNET_STRINGS_data_to_string ((unsigned char *) priv,
291 sizeof(
293 privkeybuf,
294 keylen);
295 if (NULL == end)
296 {
297 GNUNET_free (privkeybuf);
298 return NULL;
299 }
300 *end = '\0';
301 return privkeybuf;
302}
303
304
305char *
307 const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv)
308{
309 char *privkeybuf;
310 size_t keylen = (sizeof(struct GNUNET_CRYPTO_EcdsaPrivateKey)) * 8;
311 char *end;
312
313 if (keylen % 5 > 0)
314 keylen += 5 - keylen % 5;
315 keylen /= 5;
316 privkeybuf = GNUNET_malloc (keylen + 1);
317 end = GNUNET_STRINGS_data_to_string ((unsigned char *) priv,
318 sizeof(
320 privkeybuf,
321 keylen);
322 if (NULL == end)
323 {
324 GNUNET_free (privkeybuf);
325 return NULL;
326 }
327 *end = '\0';
328 return privkeybuf;
329}
330
331
334 const char *enc,
335 size_t enclen,
337{
338 size_t keylen = (sizeof(struct GNUNET_CRYPTO_EcdsaPublicKey)) * 8;
339
340 if (keylen % 5 > 0)
341 keylen += 5 - keylen % 5;
342 keylen /= 5;
343 if (enclen != keylen)
344 return GNUNET_SYSERR;
345
346 if (GNUNET_OK !=
348 enclen,
349 pub,
350 sizeof(
352 return GNUNET_SYSERR;
353 return GNUNET_OK;
354}
355
356
359 const char *enc,
360 size_t enclen,
362{
363 size_t keylen = (sizeof(struct GNUNET_CRYPTO_EddsaPublicKey)) * 8;
364
365 if (keylen % 5 > 0)
366 keylen += 5 - keylen % 5;
367 keylen /= 5;
368 if (enclen != keylen)
369 return GNUNET_SYSERR;
370
371 if (GNUNET_OK !=
373 enclen,
374 pub,
375 sizeof(
377 return GNUNET_SYSERR;
378 return GNUNET_OK;
379}
380
381
384 const char *enc,
385 size_t enclen,
387{
388 size_t keylen = (sizeof(struct GNUNET_CRYPTO_EddsaPrivateKey)) * 8;
389
390 if (keylen % 5 > 0)
391 keylen += 5 - keylen % 5;
392 keylen /= 5;
393 if (enclen != keylen)
394 return GNUNET_SYSERR;
395
396 if (GNUNET_OK !=
398 enclen,
399 priv,
400 sizeof(
402 return GNUNET_SYSERR;
403#if CRYPTO_BUG
404 if (GNUNET_OK != check_eddsa_key (priv))
405 {
406 GNUNET_break (0);
407 return GNUNET_OK;
408 }
409#endif
410 return GNUNET_OK;
411}
412
413
414void
416{
417 memset (pk, 0, sizeof(struct GNUNET_CRYPTO_EcdhePrivateKey));
418}
419
420
421void
423{
424 memset (pk, 0, sizeof(struct GNUNET_CRYPTO_EcdsaPrivateKey));
425}
426
427
428void
430{
431 memset (pk, 0, sizeof(struct GNUNET_CRYPTO_EddsaPrivateKey));
432}
433
434
435void
437{
438 BENCHMARK_START (ecdhe_key_create);
440 pk,
441 sizeof (struct GNUNET_CRYPTO_EcdhePrivateKey));
442 BENCHMARK_END (ecdhe_key_create);
443}
444
445
446void
448{
449 BENCHMARK_START (ecdsa_key_create);
451 pk,
452 sizeof (struct GNUNET_CRYPTO_EcdsaPrivateKey));
453 pk->d[0] &= 248;
454 pk->d[31] &= 127;
455 pk->d[31] |= 64;
456
457 BENCHMARK_END (ecdsa_key_create);
458}
459
460
461void
463{
464 BENCHMARK_START (eddsa_key_create);
465 /*
466 * We do not clamp for EdDSA, since all functions that use the private key do
467 * their own clamping (just like in libsodium). What we call "private key"
468 * here, actually corresponds to the seed in libsodium.
469 *
470 * (Contrast this to ECDSA, where functions using the private key can't clamp
471 * due to properties needed for GNS. That is a worse/unsafer API, but
472 * required for the GNS constructions to work.)
473 */
475 pk,
476 sizeof (struct GNUNET_CRYPTO_EddsaPrivateKey));
477 BENCHMARK_END (eddsa_key_create);
478}
479
480
483{
488 static struct GNUNET_CRYPTO_EcdsaPrivateKey anonymous;
489 static int once;
490
491 if (once)
492 return &anonymous;
494 sizeof(anonymous.d),
495 GCRYMPI_CONST_ONE);
496 anonymous.d[0] &= 248;
497 anonymous.d[31] &= 127;
498 anonymous.d[31] |= 64;
499
500 once = 1;
501 return &anonymous;
502}
503
504
512static gcry_sexp_t
514{
515 gcry_sexp_t data;
516 int rc;
517 /* Unlike EdDSA, libgcrypt expects a hash for ECDSA. */
518 struct GNUNET_HashCode hc;
519
520 GNUNET_CRYPTO_hash (purpose, ntohl (purpose->size), &hc);
521 if (0 != (rc = gcry_sexp_build (&data,
522 NULL,
523 "(data(flags rfc6979)(hash %s %b))",
524 "sha512",
525 (int) sizeof(hc),
526 &hc)))
527 {
528 LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_sexp_build", rc);
529 return NULL;
530 }
531 return data;
532}
533
534
537 const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv,
538 const struct GNUNET_CRYPTO_EccSignaturePurpose *purpose,
540{
541 gcry_sexp_t priv_sexp;
542 gcry_sexp_t sig_sexp;
543 gcry_sexp_t data;
544 int rc;
545 gcry_mpi_t rs[2];
546
547 BENCHMARK_START (ecdsa_sign);
548
549 priv_sexp = decode_private_ecdsa_key (priv);
550 data = data_to_ecdsa_value (purpose);
551 if (0 != (rc = gcry_pk_sign (&sig_sexp, data, priv_sexp)))
552 {
554 _ ("ECC signing failed at %s:%d: %s\n"),
555 __FILE__,
556 __LINE__,
557 gcry_strerror (rc));
558 gcry_sexp_release (data);
559 gcry_sexp_release (priv_sexp);
560 return GNUNET_SYSERR;
561 }
562 gcry_sexp_release (priv_sexp);
563 gcry_sexp_release (data);
564
565 /* extract 'r' and 's' values from sexpression 'sig_sexp' and store in
566 'signature' */
567 if (0 != (rc = key_from_sexp (rs, sig_sexp, "sig-val", "rs")))
568 {
569 GNUNET_break (0);
570 gcry_sexp_release (sig_sexp);
571 return GNUNET_SYSERR;
572 }
573 gcry_sexp_release (sig_sexp);
574 GNUNET_CRYPTO_mpi_print_unsigned (sig->r, sizeof(sig->r), rs[0]);
575 GNUNET_CRYPTO_mpi_print_unsigned (sig->s, sizeof(sig->s), rs[1]);
576 gcry_mpi_release (rs[0]);
577 gcry_mpi_release (rs[1]);
578
579 BENCHMARK_END (ecdsa_sign);
580
581 return GNUNET_OK;
582}
583
584
587 const struct GNUNET_CRYPTO_EddsaPrivateKey *priv,
588 void *data,
589 size_t size,
591{
592 unsigned char sk[crypto_sign_SECRETKEYBYTES];
593 unsigned char pk[crypto_sign_PUBLICKEYBYTES];
594 int res;
595
596 GNUNET_assert (0 == crypto_sign_seed_keypair (pk, sk, priv->d));
597 res = crypto_sign_detached ((uint8_t *) sig,
598 NULL,
599 (uint8_t *) data,
600 size,
601 sk);
602 return (res == 0) ? GNUNET_OK : GNUNET_SYSERR;
603}
604
605
608 const struct GNUNET_CRYPTO_EddsaPrivateKey *priv,
609 const struct GNUNET_CRYPTO_EccSignaturePurpose *purpose,
611{
612
613 size_t mlen = ntohl (purpose->size);
614 unsigned char sk[crypto_sign_SECRETKEYBYTES];
615 unsigned char pk[crypto_sign_PUBLICKEYBYTES];
616 int res;
617
618 BENCHMARK_START (eddsa_sign);
619 GNUNET_assert (0 == crypto_sign_seed_keypair (pk, sk, priv->d));
620 res = crypto_sign_detached ((uint8_t *) sig,
621 NULL,
622 (uint8_t *) purpose,
623 mlen,
624 sk);
625 BENCHMARK_END (eddsa_sign);
626 return (res == 0) ? GNUNET_OK : GNUNET_SYSERR;
627}
628
629
632 uint32_t purpose,
633 const struct GNUNET_CRYPTO_EccSignaturePurpose *validate,
634 const struct GNUNET_CRYPTO_EcdsaSignature *sig,
635 const struct GNUNET_CRYPTO_EcdsaPublicKey *pub)
636{
637 gcry_sexp_t data;
638 gcry_sexp_t sig_sexpr;
639 gcry_sexp_t pub_sexpr;
640 int rc;
641
642 BENCHMARK_START (ecdsa_verify);
643
644 if (purpose != ntohl (validate->purpose))
645 return GNUNET_SYSERR; /* purpose mismatch */
646
647 /* build s-expression for signature */
648 if (0 != (rc = gcry_sexp_build (&sig_sexpr,
649 NULL,
650 "(sig-val(ecdsa(r %b)(s %b)))",
651 (int) sizeof(sig->r),
652 sig->r,
653 (int) sizeof(sig->s),
654 sig->s)))
655 {
656 LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_sexp_build", rc);
657 return GNUNET_SYSERR;
658 }
659 data = data_to_ecdsa_value (validate);
660 if (0 != (rc = gcry_sexp_build (&pub_sexpr,
661 NULL,
662 "(public-key(ecc(curve " CURVE ")(q %b)))",
663 (int) sizeof(pub->q_y),
664 pub->q_y)))
665 {
666 gcry_sexp_release (data);
667 gcry_sexp_release (sig_sexpr);
668 return GNUNET_SYSERR;
669 }
670 rc = gcry_pk_verify (sig_sexpr, data, pub_sexpr);
671 gcry_sexp_release (pub_sexpr);
672 gcry_sexp_release (data);
673 gcry_sexp_release (sig_sexpr);
674 if (0 != rc)
675 {
677 _ ("ECDSA signature verification failed at %s:%d: %s\n"),
678 __FILE__,
679 __LINE__,
680 gcry_strerror (rc));
681 BENCHMARK_END (ecdsa_verify);
682 return GNUNET_SYSERR;
683 }
684 BENCHMARK_END (ecdsa_verify);
685 return GNUNET_OK;
686}
687
688
691 uint32_t purpose,
692 const struct GNUNET_CRYPTO_EccSignaturePurpose *validate,
693 const struct GNUNET_CRYPTO_EddsaSignature *sig,
694 const struct GNUNET_CRYPTO_EddsaPublicKey *pub)
695{
696 const unsigned char *m = (const void *) validate;
697 size_t mlen = ntohl (validate->size);
698 const unsigned char *s = (const void *) sig;
699
700 int res;
701
702 if (purpose != ntohl (validate->purpose))
703 return GNUNET_SYSERR; /* purpose mismatch */
704
705 BENCHMARK_START (eddsa_verify);
706
707 res = crypto_sign_verify_detached (s, m, mlen, pub->q_y);
708 BENCHMARK_END (eddsa_verify);
709 return (res == 0) ? GNUNET_OK : GNUNET_SYSERR;
710}
711
712
715 const struct GNUNET_CRYPTO_EcdhePublicKey *pub,
716 struct GNUNET_HashCode *key_material)
717{
718 uint8_t p[crypto_scalarmult_BYTES];
719 if (0 != crypto_scalarmult (p, priv->d, pub->q_y))
720 return GNUNET_SYSERR;
721 GNUNET_CRYPTO_hash (p, crypto_scalarmult_BYTES, key_material);
722 return GNUNET_OK;
723}
724
725
728 const struct GNUNET_CRYPTO_EcdhePublicKey *pub,
729 struct GNUNET_HashCode *key_material)
730{
731 struct GNUNET_HashCode hc;
732 uint8_t a[crypto_scalarmult_SCALARBYTES];
733 uint8_t p[crypto_scalarmult_BYTES];
734
735 GNUNET_CRYPTO_hash (priv,
736 sizeof (struct GNUNET_CRYPTO_EcdsaPrivateKey),
737 &hc);
738 memcpy (a, &hc, sizeof (struct GNUNET_CRYPTO_EcdhePrivateKey));
739 if (0 != crypto_scalarmult (p, a, pub->q_y))
740 return GNUNET_SYSERR;
742 crypto_scalarmult_BYTES,
743 key_material);
744 return GNUNET_OK;
745}
746
747
751 const struct GNUNET_CRYPTO_EcdhePublicKey *c,
752 struct GNUNET_HashCode *key_material)
753{
754 return GNUNET_CRYPTO_eddsa_ecdh (priv, c, key_material);
755}
756
757
760 const struct GNUNET_CRYPTO_EcdhePublicKey *pub,
761 struct GNUNET_HashCode *key_material)
762{
763 uint8_t p[crypto_scalarmult_BYTES];
764
765 BENCHMARK_START (ecdsa_ecdh);
766 if (0 != crypto_scalarmult (p, priv->d, pub->q_y))
767 return GNUNET_SYSERR;
769 crypto_scalarmult_BYTES,
770 key_material);
771 BENCHMARK_END (ecdsa_ecdh);
772 return GNUNET_OK;
773}
774
775
778 const struct GNUNET_CRYPTO_EddsaPublicKey *pub,
779 struct GNUNET_HashCode *key_material)
780{
781 uint8_t p[crypto_scalarmult_BYTES];
782 uint8_t curve25510_pk[crypto_scalarmult_BYTES];
783
784 if (0 != crypto_sign_ed25519_pk_to_curve25519 (curve25510_pk, pub->q_y))
785 return GNUNET_SYSERR;
786 if (0 != crypto_scalarmult (p, priv->d, curve25510_pk))
787 return GNUNET_SYSERR;
788 GNUNET_CRYPTO_hash (p, crypto_scalarmult_BYTES, key_material);
789 return GNUNET_OK;
790}
791
792
796 struct GNUNET_HashCode *key_material)
797{
799
802 return GNUNET_CRYPTO_ecdh_eddsa (&sk, pub, key_material);
803}
804
805
809 struct GNUNET_CRYPTO_FoKemC *c,
810 struct GNUNET_HashCode *key_material)
811{
812 struct GNUNET_HashCode x;
813 struct GNUNET_HashCode ux;
814 struct GNUNET_HashCode w;
816
817 // This is the input to the FO OWTF
819
820 // We build our OWTF using a FO-transformation of ElGamal:
821 // U(x)
822 GNUNET_CRYPTO_hash (&x, sizeof (x), &ux);
823 GNUNET_memcpy (&sk, &ux, sizeof (sk));
824
825 // B := g^U(x)
827
829 return -1;
830 // w xor x (one-time pad)
831 GNUNET_CRYPTO_hash_xor (&w, &x, &c->y);
832
833 // k := H(x) FIXME: U and H must be different?
834 GNUNET_memcpy (key_material, &ux, sizeof (ux));
835 return GNUNET_OK;
836}
837
838
842 struct GNUNET_CRYPTO_FoKemC *c,
843 struct GNUNET_HashCode *key_material)
844{
845 struct GNUNET_HashCode x;
846 struct GNUNET_HashCode ux;
847 struct GNUNET_HashCode w;
850
851 // This is the input to the FO OWTF
853
854 // We build our OWTF using a FO-transformation of ElGamal:
855 // U(x)
856 GNUNET_CRYPTO_hash (&x, sizeof (x), &ux);
857 GNUNET_memcpy (&sk, &ux, sizeof (sk));
858
859 // B := g^U(x)
861
862 ret = GNUNET_CRYPTO_ecdh_eddsa (&sk, pub, &w);
863 if (GNUNET_OK != ret)
864 return ret;
865 // w xor x (one-time pad)
866 GNUNET_CRYPTO_hash_xor (&w, &x, &c->y);
867
868 // k := H(x) FIXME: U and H must be different?
869 GNUNET_memcpy (key_material, &ux, sizeof (ux));
870 return GNUNET_OK;
871}
872
873
876 const struct GNUNET_CRYPTO_FoKemC *c,
877 struct GNUNET_HashCode *key_material)
878{
879 struct GNUNET_HashCode x;
880 struct GNUNET_HashCode ux;
882 struct GNUNET_CRYPTO_EcdhePublicKey pub_test;
883
884 // w xor x (one-time pad)
885 GNUNET_CRYPTO_hash_xor (w, &c->y, &x);
886
887 // We build our OWTF using a FO-transformation of ElGamal:
888 // U(x)
889 GNUNET_CRYPTO_hash (&x, sizeof (x), &ux);
890 GNUNET_memcpy (&sk, &ux, sizeof (sk));
891
892 // B := g^U(x)
893 GNUNET_CRYPTO_ecdhe_key_get_public (&sk, &pub_test);
894
895 if (0 != memcmp (&pub_test, &c->pub, sizeof (c->pub)))
896 return GNUNET_SYSERR; // Reject
897
898 // k := H(x) FIXME: U and H must be different?
899 GNUNET_memcpy (key_material, &ux, sizeof (ux));
900 return GNUNET_OK;
901}
902
903
910 const struct GNUNET_CRYPTO_FoKemC *c,
911 struct GNUNET_HashCode *key_material)
912{
913 struct GNUNET_HashCode w;
915
916 ret = GNUNET_CRYPTO_eddsa_ecdh (priv, &c->pub, &w);
917 if (GNUNET_OK != ret)
918 return ret;
919 return fo_kem_decaps (&w, c, key_material);
920}
921
922
926 struct GNUNET_CRYPTO_FoKemC *c,
927 struct GNUNET_HashCode *key_material)
928{
929 struct GNUNET_HashCode w;
931
932 ret = GNUNET_CRYPTO_ecdsa_ecdh (priv, &c->pub, &w);
933 if (GNUNET_OK != ret)
934 return ret;
935 return fo_kem_decaps (&w, c, key_material);
936}
937
938
941 const struct GNUNET_CRYPTO_EcdsaPublicKey *pub,
942 struct GNUNET_HashCode *key_material)
943{
944 uint8_t p[crypto_scalarmult_BYTES];
945 uint8_t curve25510_pk[crypto_scalarmult_BYTES];
946
947 if (0 != crypto_sign_ed25519_pk_to_curve25519 (curve25510_pk, pub->q_y))
948 return GNUNET_SYSERR;
949 if (0 != crypto_scalarmult (p, priv->d, curve25510_pk))
950 return GNUNET_SYSERR;
951 GNUNET_CRYPTO_hash (p, crypto_scalarmult_BYTES, key_material);
952 return GNUNET_OK;
953}
954
955
956/* end of crypto_ecc.c */
benchmarking for various operations
#define BENCHMARK_START(opname)
Definition: benchmark.h:57
#define BENCHMARK_END(opname)
Definition: benchmark.h:58
static int key_from_sexp(gcry_mpi_t *array, gcry_sexp_t sexp, const char *topname, const char *elems)
Extract values from an S-expression.
Definition: crypto_ecc.c:97
static gcry_sexp_t data_to_ecdsa_value(const struct GNUNET_CRYPTO_EccSignaturePurpose *purpose)
Convert the data specified in the given purpose argument to an S-expression suitable for signature op...
Definition: crypto_ecc.c:513
#define CURVE
IMPLEMENTATION NOTICE:
Definition: crypto_ecc.c:59
#define LOG_GCRY(level, cmd, rc)
Log an error message at log-level 'level' that indicates a failure of the command 'cmd' with the mess...
Definition: crypto_ecc.c:75
static enum GNUNET_GenericReturnValue fo_kem_decaps(const struct GNUNET_HashCode *w, const struct GNUNET_CRYPTO_FoKemC *c, struct GNUNET_HashCode *key_material)
Definition: crypto_ecc.c:875
#define LOG(kind,...)
Definition: crypto_ecc.c:61
static gcry_sexp_t decode_private_ecdsa_key(const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv)
Convert the given private key from the network format to the S-expression that can be used by libgcry...
Definition: crypto_ecc.c:155
static mp_limb_t d[(((256)+GMP_NUMB_BITS - 1)/GMP_NUMB_BITS)]
static int once
Global to mark if we've run the initialization.
Definition: gnsrecord.c:67
static struct GNUNET_ARM_MonitorHandle * m
Monitor connection with ARM.
Definition: gnunet-arm.c:104
static int list
Set if we should print a list of currently running services.
Definition: gnunet-arm.c:69
static int ret
Final status code.
Definition: gnunet-arm.c:94
static int end
Set if we are to shutdown all services (including ARM).
Definition: gnunet-arm.c:34
static char * data
The data to insert into the dht.
static OpusEncoder * enc
OPUS encoder.
struct GNUNET_CRYPTO_PrivateKey pk
Private key from command line option, or NULL.
static char * res
Currently read line or NULL on EOF.
static int result
Global testing status.
static struct GNUNET_CRYPTO_EddsaPublicKey pub
Definition: gnunet-scrypt.c:47
static struct GNUNET_OS_Process * p
Helper process we started.
Definition: gnunet-uri.c:38
enum GNUNET_GenericReturnValue GNUNET_CRYPTO_ecdsa_fo_kem_decaps(const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv, struct GNUNET_CRYPTO_FoKemC *c, struct GNUNET_HashCode *key_material)
Decapsulate key material using a CCA-secure KEM.
Definition: crypto_ecc.c:924
enum GNUNET_GenericReturnValue GNUNET_CRYPTO_ecc_ecdh(const struct GNUNET_CRYPTO_EcdhePrivateKey *priv, const struct GNUNET_CRYPTO_EcdhePublicKey *pub, struct GNUNET_HashCode *key_material)
Derive key material from a public and a private ECC key.
Definition: crypto_ecc.c:714
void GNUNET_CRYPTO_ecdhe_key_create(struct GNUNET_CRYPTO_EcdhePrivateKey *pk)
Create a new private key.
Definition: crypto_ecc.c:436
enum GNUNET_GenericReturnValue GNUNET_CRYPTO_eddsa_kem_decaps(const struct GNUNET_CRYPTO_EddsaPrivateKey *priv, const struct GNUNET_CRYPTO_EcdhePublicKey *c, struct GNUNET_HashCode *key_material)
Decapsulate a key for a private EdDSA key.
Definition: crypto_ecc.c:749
enum GNUNET_GenericReturnValue GNUNET_CRYPTO_eddsa_fo_kem_encaps(const struct GNUNET_CRYPTO_EddsaPublicKey *pub, struct GNUNET_CRYPTO_FoKemC *c, struct GNUNET_HashCode *key_material)
Encapsulate key material using a CCA-secure KEM.
Definition: crypto_ecc.c:840
void GNUNET_CRYPTO_random_block(enum GNUNET_CRYPTO_Quality mode, void *buffer, size_t length)
Fill block with a random values.
void GNUNET_CRYPTO_eddsa_key_get_public(const struct GNUNET_CRYPTO_EddsaPrivateKey *priv, struct GNUNET_CRYPTO_EddsaPublicKey *pub)
Extract the public key for the given private key.
Definition: crypto_ecc.c:198
enum GNUNET_GenericReturnValue GNUNET_CRYPTO_ecdsa_ecdh(const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv, const struct GNUNET_CRYPTO_EcdhePublicKey *pub, struct GNUNET_HashCode *key_material)
Derive key material from a ECDH public key and a private ECDSA key.
Definition: crypto_ecc.c:759
void GNUNET_CRYPTO_eddsa_key_clear(struct GNUNET_CRYPTO_EddsaPrivateKey *pk)
Clear memory that was used to store a private key.
Definition: crypto_ecc.c:429
enum GNUNET_GenericReturnValue GNUNET_CRYPTO_ecdsa_sign_(const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv, const struct GNUNET_CRYPTO_EccSignaturePurpose *purpose, struct GNUNET_CRYPTO_EcdsaSignature *sig)
ECDSA Sign a given block.
Definition: crypto_ecc.c:536
enum GNUNET_GenericReturnValue GNUNET_CRYPTO_ecdsa_fo_kem_encaps(const struct GNUNET_CRYPTO_EcdsaPublicKey *pub, struct GNUNET_CRYPTO_FoKemC *c, struct GNUNET_HashCode *key_material)
Encapsulate key material using a CCA-secure KEM.
Definition: crypto_ecc.c:807
enum GNUNET_GenericReturnValue GNUNET_CRYPTO_eddsa_kem_encaps(const struct GNUNET_CRYPTO_EddsaPublicKey *pub, struct GNUNET_CRYPTO_EcdhePublicKey *c, struct GNUNET_HashCode *key_material)
Encapsulate key material for a EdDSA public key.
Definition: crypto_ecc.c:794
enum GNUNET_GenericReturnValue GNUNET_CRYPTO_eddsa_ecdh(const struct GNUNET_CRYPTO_EddsaPrivateKey *priv, const struct GNUNET_CRYPTO_EcdhePublicKey *pub, struct GNUNET_HashCode *key_material)
Derive key material from a ECDH public key and a private EdDSA key.
Definition: crypto_ecc.c:727
enum GNUNET_GenericReturnValue GNUNET_CRYPTO_ecdh_ecdsa(const struct GNUNET_CRYPTO_EcdhePrivateKey *priv, const struct GNUNET_CRYPTO_EcdsaPublicKey *pub, struct GNUNET_HashCode *key_material)
Derive key material from a EcDSA public key and a private ECDH key.
Definition: crypto_ecc.c:940
void GNUNET_CRYPTO_eddsa_key_create(struct GNUNET_CRYPTO_EddsaPrivateKey *pk)
Create a new private key.
Definition: crypto_ecc.c:462
enum GNUNET_GenericReturnValue GNUNET_CRYPTO_ecdh_eddsa(const struct GNUNET_CRYPTO_EcdhePrivateKey *priv, const struct GNUNET_CRYPTO_EddsaPublicKey *pub, struct GNUNET_HashCode *key_material)
Derive key material from a EdDSA public key and a private ECDH key.
Definition: crypto_ecc.c:777
void GNUNET_CRYPTO_ecdsa_key_create(struct GNUNET_CRYPTO_EcdsaPrivateKey *pk)
Create a new private key.
Definition: crypto_ecc.c:447
enum GNUNET_GenericReturnValue GNUNET_CRYPTO_eddsa_sign_(const struct GNUNET_CRYPTO_EddsaPrivateKey *priv, const struct GNUNET_CRYPTO_EccSignaturePurpose *purpose, struct GNUNET_CRYPTO_EddsaSignature *sig)
EdDSA sign a given block.
Definition: crypto_ecc.c:607
void GNUNET_CRYPTO_ecdsa_key_clear(struct GNUNET_CRYPTO_EcdsaPrivateKey *pk)
Clear memory that was used to store a private key.
Definition: crypto_ecc.c:422
enum GNUNET_GenericReturnValue GNUNET_CRYPTO_ecdsa_verify_(uint32_t purpose, const struct GNUNET_CRYPTO_EccSignaturePurpose *validate, const struct GNUNET_CRYPTO_EcdsaSignature *sig, const struct GNUNET_CRYPTO_EcdsaPublicKey *pub)
Verify ECDSA signature.
Definition: crypto_ecc.c:631
enum GNUNET_GenericReturnValue GNUNET_CRYPTO_eddsa_fo_kem_decaps(const struct GNUNET_CRYPTO_EddsaPrivateKey *priv, const struct GNUNET_CRYPTO_FoKemC *c, struct GNUNET_HashCode *key_material)
This implementation is not testes/publicly exposed yet.
Definition: crypto_ecc.c:908
const struct GNUNET_CRYPTO_EcdsaPrivateKey * GNUNET_CRYPTO_ecdsa_key_get_anonymous()
Get the shared private key we use for anonymous users.
Definition: crypto_ecc.c:482
void GNUNET_CRYPTO_ecdsa_key_get_public(const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv, struct GNUNET_CRYPTO_EcdsaPublicKey *pub)
Extract the public key for the given private key.
Definition: crypto_ecc.c:187
enum GNUNET_GenericReturnValue GNUNET_CRYPTO_eddsa_verify_(uint32_t purpose, const struct GNUNET_CRYPTO_EccSignaturePurpose *validate, const struct GNUNET_CRYPTO_EddsaSignature *sig, const struct GNUNET_CRYPTO_EddsaPublicKey *pub)
Verify EdDSA signature.
Definition: crypto_ecc.c:690
void GNUNET_CRYPTO_ecdhe_key_clear(struct GNUNET_CRYPTO_EcdhePrivateKey *pk)
Clear memory that was used to store a private key.
Definition: crypto_ecc.c:415
void GNUNET_CRYPTO_ecdhe_key_get_public(const struct GNUNET_CRYPTO_EcdhePrivateKey *priv, struct GNUNET_CRYPTO_EcdhePublicKey *pub)
Extract the public key for the given private key.
Definition: crypto_ecc.c:214
@ GNUNET_CRYPTO_QUALITY_NONCE
Randomness for IVs etc.
void GNUNET_CRYPTO_hash(const void *block, size_t size, struct GNUNET_HashCode *ret)
Compute hash of a given block.
Definition: crypto_hash.c:41
void GNUNET_CRYPTO_hash_xor(const struct GNUNET_HashCode *a, const struct GNUNET_HashCode *b, struct GNUNET_HashCode *result)
compute result = a ^ b
Definition: crypto_hash.c:135
char * GNUNET_CRYPTO_eddsa_private_key_to_string(const struct GNUNET_CRYPTO_EddsaPrivateKey *priv)
Convert a private key to a string.
Definition: crypto_ecc.c:279
enum GNUNET_GenericReturnValue GNUNET_CRYPTO_eddsa_sign_raw(const struct GNUNET_CRYPTO_EddsaPrivateKey *priv, void *data, size_t size, struct GNUNET_CRYPTO_EddsaSignature *sig)
Definition: crypto_ecc.c:586
enum GNUNET_GenericReturnValue GNUNET_CRYPTO_ecdsa_public_key_from_string(const char *enc, size_t enclen, struct GNUNET_CRYPTO_EcdsaPublicKey *pub)
Convert a string representing a public key to a public key.
Definition: crypto_ecc.c:333
char * GNUNET_CRYPTO_eddsa_public_key_to_string(const struct GNUNET_CRYPTO_EddsaPublicKey *pub)
Convert a public key to a string.
Definition: crypto_ecc.c:252
enum GNUNET_GenericReturnValue GNUNET_CRYPTO_eddsa_public_key_from_string(const char *enc, size_t enclen, struct GNUNET_CRYPTO_EddsaPublicKey *pub)
Convert a string representing a public key to a public key.
Definition: crypto_ecc.c:358
void GNUNET_CRYPTO_mpi_print_unsigned(void *buf, size_t size, gcry_mpi_t val)
Output the given MPI value to the given buffer in network byte order.
Definition: crypto_mpi.c:79
char * GNUNET_CRYPTO_ecdsa_public_key_to_string(const struct GNUNET_CRYPTO_EcdsaPublicKey *pub)
Convert a public key to a string.
Definition: crypto_ecc.c:225
#define GNUNET_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
enum GNUNET_GenericReturnValue GNUNET_CRYPTO_eddsa_private_key_from_string(const char *enc, size_t enclen, struct GNUNET_CRYPTO_EddsaPrivateKey *priv)
Convert a string representing a private key to a private key.
Definition: crypto_ecc.c:383
char * GNUNET_CRYPTO_ecdsa_private_key_to_string(const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv)
Convert a private key to a string.
Definition: crypto_ecc.c:306
GNUNET_GenericReturnValue
Named constants for return values.
@ GNUNET_OK
@ GNUNET_SYSERR
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur.
@ GNUNET_ERROR_TYPE_WARNING
@ GNUNET_ERROR_TYPE_ERROR
@ GNUNET_ERROR_TYPE_INFO
#define GNUNET_malloc(size)
Wrapper around malloc.
#define GNUNET_free(ptr)
Wrapper around free.
char * GNUNET_STRINGS_data_to_string(const void *data, size_t size, char *out, size_t out_size)
Convert binary data to ASCII encoding using CrockfordBase32.
Definition: strings.c:709
enum GNUNET_GenericReturnValue GNUNET_STRINGS_string_to_data(const char *enc, size_t enclen, void *out, size_t out_size)
Convert CrockfordBase32 encoding back to data.
Definition: strings.c:789
static unsigned int size
Size of the "table".
Definition: peer.c:68
#define _(String)
GNU gettext support macro.
Definition: platform.h:178
header of what an ECC signature signs this must be followed by "size - 8" bytes of the actual signed ...
uint32_t size
How many bytes does this signature sign? (including this purpose header); in network byte order (!...
uint32_t purpose
What does this signature vouch for? This must contain a GNUNET_SIGNATURE_PURPOSE_XXX constant (from g...
Private ECC key encoded for transmission.
unsigned char d[256/8]
d is a value mod n, where n has at most 256 bits.
Public ECC key (always for Curve25519) encoded in a format suitable for network transmission and encr...
Private ECC key encoded for transmission.
unsigned char d[256/8]
d is a value mod n, where n has at most 256 bits.
Public ECC key (always for Curve25519) encoded in a format suitable for network transmission and ECDS...
an ECC signature using ECDSA
unsigned char s[256/8]
S value.
unsigned char r[256/8]
R value.
Private ECC key encoded for transmission.
unsigned char d[256/8]
d is a value mod n, where n has at most 256 bits.
Public ECC key (always for curve Ed25519) encoded in a format suitable for network transmission and E...
unsigned char q_y[256/8]
Point Q consists of a y-value mod p (256 bits); the x-value is always positive.
an ECC signature using EdDSA.
This is the encapsulated key of our FO-KEM.
struct GNUNET_CRYPTO_EcdhePublicKey pub
struct GNUNET_HashCode y
A 512-bit hashcode.