GNUnet 0.21.2
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
27#include "platform.h"
28#include "gnunet_common.h"
29#include <gcrypt.h>
30#include <sodium.h>
31#include "gnunet_util_lib.h"
32#include "benchmark.h"
33#include "sodium/crypto_scalarmult.h"
34#include "sodium/utils.h"
35
36#define EXTRA_CHECKS 0
37
61#define CURVE "Ed25519"
62
63#define LOG(kind, ...) GNUNET_log_from (kind, "util-crypto-ecc", __VA_ARGS__)
64
65#define LOG_STRERROR(kind, syscall) \
66 GNUNET_log_from_strerror (kind, "util-crypto-ecc", syscall)
67
68#define LOG_STRERROR_FILE(kind, syscall, filename) \
69 GNUNET_log_from_strerror_file (kind, "util-crypto-ecc", syscall, \
70 filename)
71
77#define LOG_GCRY(level, cmd, rc) \
78 do \
79 { \
80 LOG (level, \
81 _ ("`%s' failed at %s:%d with error: %s\n"), \
82 cmd, \
83 __FILE__, \
84 __LINE__, \
85 gcry_strerror (rc)); \
86 } while (0)
87
88
98static int
99key_from_sexp (gcry_mpi_t *array,
100 gcry_sexp_t sexp,
101 const char *topname,
102 const char *elems)
103{
104 gcry_sexp_t list;
105 gcry_sexp_t l2;
106 unsigned int idx;
107
108 list = gcry_sexp_find_token (sexp, topname, 0);
109 if (! list)
110 return 1;
111 l2 = gcry_sexp_cadr (list);
112 gcry_sexp_release (list);
113 list = l2;
114 if (! list)
115 return 2;
116
117 idx = 0;
118 for (const char *s = elems; *s; s++, idx++)
119 {
120 l2 = gcry_sexp_find_token (list, s, 1);
121 if (! l2)
122 {
123 for (unsigned int i = 0; i < idx; i++)
124 {
125 gcry_free (array[i]);
126 array[i] = NULL;
127 }
128 gcry_sexp_release (list);
129 return 3; /* required parameter not found */
130 }
131 array[idx] = gcry_sexp_nth_mpi (l2, 1, GCRYMPI_FMT_USG);
132 gcry_sexp_release (l2);
133 if (! array[idx])
134 {
135 for (unsigned int i = 0; i < idx; i++)
136 {
137 gcry_free (array[i]);
138 array[i] = NULL;
139 }
140 gcry_sexp_release (list);
141 return 4; /* required parameter is invalid */
142 }
143 }
144 gcry_sexp_release (list);
145 return 0;
146}
147
148
156static gcry_sexp_t
158{
159 gcry_sexp_t result;
160 int rc;
161 uint8_t d[32];
162
163 for (size_t i = 0; i<32; i++)
164 d[i] = priv->d[31 - i];
165
166 rc = gcry_sexp_build (&result,
167 NULL,
168 "(private-key(ecc(curve \"" CURVE "\")"
169 "(d %b)))",
170 32,
171 d);
172 if (0 != rc)
173 {
174 LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_sexp_build", rc);
175 GNUNET_assert (0);
176 }
177#if EXTRA_CHECKS
178 if (0 != (rc = gcry_pk_testkey (result)))
179 {
180 LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_pk_testkey", rc);
181 GNUNET_assert (0);
182 }
183#endif
184 return result;
185}
186
187
188void
190 const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv,
192{
193 BENCHMARK_START (ecdsa_key_get_public);
194 crypto_scalarmult_ed25519_base_noclamp (pub->q_y, priv->d);
195 BENCHMARK_END (ecdsa_key_get_public);
196}
197
198
199void
201 const struct GNUNET_CRYPTO_EddsaPrivateKey *priv,
203{
204 unsigned char pk[crypto_sign_PUBLICKEYBYTES];
205 unsigned char sk[crypto_sign_SECRETKEYBYTES];
206
207 BENCHMARK_START (eddsa_key_get_public);
208 GNUNET_assert (0 == crypto_sign_seed_keypair (pk, sk, priv->d));
209 GNUNET_memcpy (pub->q_y, pk, crypto_sign_PUBLICKEYBYTES);
210 sodium_memzero (sk, crypto_sign_SECRETKEYBYTES);
211 BENCHMARK_END (eddsa_key_get_public);
212}
213
214
215void
217 const struct GNUNET_CRYPTO_EcdhePrivateKey *priv,
219{
220 BENCHMARK_START (ecdhe_key_get_public);
221 GNUNET_assert (0 == crypto_scalarmult_base (pub->q_y, priv->d));
222 BENCHMARK_END (ecdhe_key_get_public);
223}
224
225
226char *
228 const struct GNUNET_CRYPTO_EcdsaPublicKey *pub)
229{
230 char *pubkeybuf;
231 size_t keylen = (sizeof(struct GNUNET_CRYPTO_EcdsaPublicKey)) * 8;
232 char *end;
233
234 if (keylen % 5 > 0)
235 keylen += 5 - keylen % 5;
236 keylen /= 5;
237 pubkeybuf = GNUNET_malloc (keylen + 1);
238 end =
239 GNUNET_STRINGS_data_to_string ((unsigned char *) pub,
240 sizeof(struct GNUNET_CRYPTO_EcdsaPublicKey),
241 pubkeybuf,
242 keylen);
243 if (NULL == end)
244 {
245 GNUNET_free (pubkeybuf);
246 return NULL;
247 }
248 *end = '\0';
249 return pubkeybuf;
250}
251
252
253char *
255 const struct GNUNET_CRYPTO_EddsaPublicKey *pub)
256{
257 char *pubkeybuf;
258 size_t keylen = (sizeof(struct GNUNET_CRYPTO_EddsaPublicKey)) * 8;
259 char *end;
260
261 if (keylen % 5 > 0)
262 keylen += 5 - keylen % 5;
263 keylen /= 5;
264 pubkeybuf = GNUNET_malloc (keylen + 1);
265 end =
266 GNUNET_STRINGS_data_to_string ((unsigned char *) pub,
267 sizeof(struct GNUNET_CRYPTO_EddsaPublicKey),
268 pubkeybuf,
269 keylen);
270 if (NULL == end)
271 {
272 GNUNET_free (pubkeybuf);
273 return NULL;
274 }
275 *end = '\0';
276 return pubkeybuf;
277}
278
279
280char *
282 const struct GNUNET_CRYPTO_EddsaPrivateKey *priv)
283{
284 char *privkeybuf;
285 size_t keylen = (sizeof(struct GNUNET_CRYPTO_EddsaPrivateKey)) * 8;
286 char *end;
287
288 if (keylen % 5 > 0)
289 keylen += 5 - keylen % 5;
290 keylen /= 5;
291 privkeybuf = GNUNET_malloc (keylen + 1);
292 end = GNUNET_STRINGS_data_to_string ((unsigned char *) priv,
293 sizeof(
295 privkeybuf,
296 keylen);
297 if (NULL == end)
298 {
299 GNUNET_free (privkeybuf);
300 return NULL;
301 }
302 *end = '\0';
303 return privkeybuf;
304}
305
306
307char *
309 const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv)
310{
311 char *privkeybuf;
312 size_t keylen = (sizeof(struct GNUNET_CRYPTO_EcdsaPrivateKey)) * 8;
313 char *end;
314
315 if (keylen % 5 > 0)
316 keylen += 5 - keylen % 5;
317 keylen /= 5;
318 privkeybuf = GNUNET_malloc (keylen + 1);
319 end = GNUNET_STRINGS_data_to_string ((unsigned char *) priv,
320 sizeof(
322 privkeybuf,
323 keylen);
324 if (NULL == end)
325 {
326 GNUNET_free (privkeybuf);
327 return NULL;
328 }
329 *end = '\0';
330 return privkeybuf;
331}
332
333
336 const char *enc,
337 size_t enclen,
339{
340 size_t keylen = (sizeof(struct GNUNET_CRYPTO_EcdsaPublicKey)) * 8;
341
342 if (keylen % 5 > 0)
343 keylen += 5 - keylen % 5;
344 keylen /= 5;
345 if (enclen != keylen)
346 return GNUNET_SYSERR;
347
348 if (GNUNET_OK !=
350 enclen,
351 pub,
352 sizeof(
354 return GNUNET_SYSERR;
355 return GNUNET_OK;
356}
357
358
361 const char *enc,
362 size_t enclen,
364{
365 size_t keylen = (sizeof(struct GNUNET_CRYPTO_EddsaPublicKey)) * 8;
366
367 if (keylen % 5 > 0)
368 keylen += 5 - keylen % 5;
369 keylen /= 5;
370 if (enclen != keylen)
371 return GNUNET_SYSERR;
372
373 if (GNUNET_OK !=
375 enclen,
376 pub,
377 sizeof(
379 return GNUNET_SYSERR;
380 return GNUNET_OK;
381}
382
383
386 const char *enc,
387 size_t enclen,
389{
390 size_t keylen = (sizeof(struct GNUNET_CRYPTO_EddsaPrivateKey)) * 8;
391
392 if (keylen % 5 > 0)
393 keylen += 5 - keylen % 5;
394 keylen /= 5;
395 if (enclen != keylen)
396 return GNUNET_SYSERR;
397
398 if (GNUNET_OK !=
400 enclen,
401 priv,
402 sizeof(
404 return GNUNET_SYSERR;
405#if CRYPTO_BUG
406 if (GNUNET_OK != check_eddsa_key (priv))
407 {
408 GNUNET_break (0);
409 return GNUNET_OK;
410 }
411#endif
412 return GNUNET_OK;
413}
414
415
416static void
417buffer_clear (void *buf, size_t len)
418{
419#if HAVE_MEMSET_S
420 memset_s (buf, len, 0, len);
421#elif HAVE_EXPLICIT_BZERO
422 explicit_bzero (buf, len);
423#else
424 volatile unsigned char *p = buf;
425 while (len--)
426 *p++ = 0;
427#endif
428}
429
430
431void
433{
435}
436
437
438void
440{
442}
443
444
445void
447{
449}
450
451
452void
454{
455 BENCHMARK_START (ecdhe_key_create);
457 pk,
458 sizeof (struct GNUNET_CRYPTO_EcdhePrivateKey));
459 BENCHMARK_END (ecdhe_key_create);
460}
461
462
463void
465{
466 BENCHMARK_START (ecdsa_key_create);
468 pk,
469 sizeof (struct GNUNET_CRYPTO_EcdsaPrivateKey));
470 pk->d[0] &= 248;
471 pk->d[31] &= 127;
472 pk->d[31] |= 64;
473
474 BENCHMARK_END (ecdsa_key_create);
475}
476
477
478void
480{
481 BENCHMARK_START (eddsa_key_create);
482 /*
483 * We do not clamp for EdDSA, since all functions that use the private key do
484 * their own clamping (just like in libsodium). What we call "private key"
485 * here, actually corresponds to the seed in libsodium.
486 *
487 * (Contrast this to ECDSA, where functions using the private key can't clamp
488 * due to properties needed for GNS. That is a worse/unsafer API, but
489 * required for the GNS constructions to work.)
490 */
492 pk,
493 sizeof (struct GNUNET_CRYPTO_EddsaPrivateKey));
494 BENCHMARK_END (eddsa_key_create);
495}
496
497
500{
505 static struct GNUNET_CRYPTO_EcdsaPrivateKey anonymous;
506 static int once;
507
508 if (once)
509 return &anonymous;
511 sizeof(anonymous.d),
512 GCRYMPI_CONST_ONE);
513 anonymous.d[0] &= 248;
514 anonymous.d[31] &= 127;
515 anonymous.d[31] |= 64;
516
517 once = 1;
518 return &anonymous;
519}
520
521
529static gcry_sexp_t
531{
532 gcry_sexp_t data;
533 int rc;
534 /* Unlike EdDSA, libgcrypt expects a hash for ECDSA. */
535 struct GNUNET_HashCode hc;
536
537 GNUNET_CRYPTO_hash (purpose, ntohl (purpose->size), &hc);
538 if (0 != (rc = gcry_sexp_build (&data,
539 NULL,
540 "(data(flags rfc6979)(hash %s %b))",
541 "sha512",
542 (int) sizeof(hc),
543 &hc)))
544 {
545 LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_sexp_build", rc);
546 return NULL;
547 }
548 return data;
549}
550
551
554 const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv,
555 const struct GNUNET_CRYPTO_EccSignaturePurpose *purpose,
557{
558 gcry_sexp_t priv_sexp;
559 gcry_sexp_t sig_sexp;
560 gcry_sexp_t data;
561 int rc;
562 gcry_mpi_t rs[2];
563
564 BENCHMARK_START (ecdsa_sign);
565
566 priv_sexp = decode_private_ecdsa_key (priv);
567 data = data_to_ecdsa_value (purpose);
568 if (0 != (rc = gcry_pk_sign (&sig_sexp, data, priv_sexp)))
569 {
571 _ ("ECC signing failed at %s:%d: %s\n"),
572 __FILE__,
573 __LINE__,
574 gcry_strerror (rc));
575 gcry_sexp_release (data);
576 gcry_sexp_release (priv_sexp);
577 return GNUNET_SYSERR;
578 }
579 gcry_sexp_release (priv_sexp);
580 gcry_sexp_release (data);
581
582 /* extract 'r' and 's' values from sexpression 'sig_sexp' and store in
583 'signature' */
584 if (0 != (rc = key_from_sexp (rs, sig_sexp, "sig-val", "rs")))
585 {
586 GNUNET_break (0);
587 gcry_sexp_release (sig_sexp);
588 return GNUNET_SYSERR;
589 }
590 gcry_sexp_release (sig_sexp);
591 GNUNET_CRYPTO_mpi_print_unsigned (sig->r, sizeof(sig->r), rs[0]);
592 GNUNET_CRYPTO_mpi_print_unsigned (sig->s, sizeof(sig->s), rs[1]);
593 gcry_mpi_release (rs[0]);
594 gcry_mpi_release (rs[1]);
595
596 BENCHMARK_END (ecdsa_sign);
597
598 return GNUNET_OK;
599}
600
601
604 const struct GNUNET_CRYPTO_EddsaPrivateKey *priv,
605 void *data,
606 size_t size,
608{
609 unsigned char sk[crypto_sign_SECRETKEYBYTES];
610 unsigned char pk[crypto_sign_PUBLICKEYBYTES];
611 int res;
612
613 GNUNET_assert (0 == crypto_sign_seed_keypair (pk, sk, priv->d));
614 res = crypto_sign_detached ((uint8_t *) sig,
615 NULL,
616 (uint8_t *) data,
617 size,
618 sk);
619 return (res == 0) ? GNUNET_OK : GNUNET_SYSERR;
620}
621
622
625 const struct GNUNET_CRYPTO_EddsaPrivateKey *priv,
626 const struct GNUNET_CRYPTO_EccSignaturePurpose *purpose,
628{
629
630 size_t mlen = ntohl (purpose->size);
631 unsigned char sk[crypto_sign_SECRETKEYBYTES];
632 unsigned char pk[crypto_sign_PUBLICKEYBYTES];
633 int res;
634
635 BENCHMARK_START (eddsa_sign);
636 GNUNET_assert (0 == crypto_sign_seed_keypair (pk, sk, priv->d));
637 res = crypto_sign_detached ((uint8_t *) sig,
638 NULL,
639 (uint8_t *) purpose,
640 mlen,
641 sk);
642 BENCHMARK_END (eddsa_sign);
643 return (res == 0) ? GNUNET_OK : GNUNET_SYSERR;
644}
645
646
649 uint32_t purpose,
650 const struct GNUNET_CRYPTO_EccSignaturePurpose *validate,
651 const struct GNUNET_CRYPTO_EcdsaSignature *sig,
652 const struct GNUNET_CRYPTO_EcdsaPublicKey *pub)
653{
654 gcry_sexp_t data;
655 gcry_sexp_t sig_sexpr;
656 gcry_sexp_t pub_sexpr;
657 int rc;
658
659 BENCHMARK_START (ecdsa_verify);
660
661 if (purpose != ntohl (validate->purpose))
662 return GNUNET_SYSERR; /* purpose mismatch */
663
664 /* build s-expression for signature */
665 if (0 != (rc = gcry_sexp_build (&sig_sexpr,
666 NULL,
667 "(sig-val(ecdsa(r %b)(s %b)))",
668 (int) sizeof(sig->r),
669 sig->r,
670 (int) sizeof(sig->s),
671 sig->s)))
672 {
673 LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_sexp_build", rc);
674 return GNUNET_SYSERR;
675 }
676 data = data_to_ecdsa_value (validate);
677 if (0 != (rc = gcry_sexp_build (&pub_sexpr,
678 NULL,
679 "(public-key(ecc(curve " CURVE ")(q %b)))",
680 (int) sizeof(pub->q_y),
681 pub->q_y)))
682 {
683 gcry_sexp_release (data);
684 gcry_sexp_release (sig_sexpr);
685 return GNUNET_SYSERR;
686 }
687 rc = gcry_pk_verify (sig_sexpr, data, pub_sexpr);
688 gcry_sexp_release (pub_sexpr);
689 gcry_sexp_release (data);
690 gcry_sexp_release (sig_sexpr);
691 if (0 != rc)
692 {
694 _ ("ECDSA signature verification failed at %s:%d: %s\n"),
695 __FILE__,
696 __LINE__,
697 gcry_strerror (rc));
698 BENCHMARK_END (ecdsa_verify);
699 return GNUNET_SYSERR;
700 }
701 BENCHMARK_END (ecdsa_verify);
702 return GNUNET_OK;
703}
704
705
708 uint32_t purpose,
709 const struct GNUNET_CRYPTO_EccSignaturePurpose *validate,
710 const struct GNUNET_CRYPTO_EddsaSignature *sig,
711 const struct GNUNET_CRYPTO_EddsaPublicKey *pub)
712{
713 const unsigned char *m = (const void *) validate;
714 size_t mlen = ntohl (validate->size);
715 const unsigned char *s = (const void *) sig;
716
717 int res;
718
719 if (purpose != ntohl (validate->purpose))
720 return GNUNET_SYSERR; /* purpose mismatch */
721
722 BENCHMARK_START (eddsa_verify);
723
724 res = crypto_sign_verify_detached (s, m, mlen, pub->q_y);
725 BENCHMARK_END (eddsa_verify);
726 return (res == 0) ? GNUNET_OK : GNUNET_SYSERR;
727}
728
729
732 const struct GNUNET_CRYPTO_EcdhePublicKey *pub,
733 struct GNUNET_HashCode *key_material)
734{
735 uint8_t p[crypto_scalarmult_BYTES];
736 if (0 != crypto_scalarmult (p, priv->d, pub->q_y))
737 return GNUNET_SYSERR;
738 GNUNET_CRYPTO_hash (p, crypto_scalarmult_BYTES, key_material);
739 return GNUNET_OK;
740}
741
742
745 const struct GNUNET_CRYPTO_EcdhePublicKey *pub,
746 struct GNUNET_HashCode *key_material)
747{
748 struct GNUNET_HashCode hc;
749 uint8_t a[crypto_scalarmult_SCALARBYTES];
750 uint8_t p[crypto_scalarmult_BYTES];
751
752 GNUNET_CRYPTO_hash (priv,
753 sizeof (struct GNUNET_CRYPTO_EcdsaPrivateKey),
754 &hc);
755 memcpy (a, &hc, sizeof (struct GNUNET_CRYPTO_EcdhePrivateKey));
756 if (0 != crypto_scalarmult (p, a, pub->q_y))
757 return GNUNET_SYSERR;
759 crypto_scalarmult_BYTES,
760 key_material);
761 return GNUNET_OK;
762}
763
764
767 const struct GNUNET_CRYPTO_EcdhePublicKey *pub,
768 struct GNUNET_HashCode *key_material)
769{
770 struct GNUNET_HashCode hc;
771 struct GNUNET_ShortHashCode prk;
772 uint8_t a[crypto_scalarmult_SCALARBYTES];
773 uint8_t p[crypto_scalarmult_BYTES];
774 uint8_t ikm[crypto_scalarmult_BYTES * 2];
775
776 GNUNET_CRYPTO_hash (priv,
777 sizeof (struct GNUNET_CRYPTO_EcdsaPrivateKey),
778 &hc);
779 memcpy (a, &hc, sizeof (struct GNUNET_CRYPTO_EcdhePrivateKey));
780 // Z := X25519(x,A) with x = p
781 if (0 != crypto_scalarmult (p, a, pub->q_y))
782 return GNUNET_SYSERR;
783 memcpy (ikm, pub->q_y, crypto_scalarmult_BYTES);
784 memcpy (ikm + crypto_scalarmult_BYTES, p, crypto_scalarmult_BYTES);
785 // KDF(A, X25519(a,X))
786 GNUNET_CRYPTO_hkdf_extract (&prk, NULL, 0, ikm, sizeof ikm);
787
788 // to get 512 bits, we call expand once
789 GNUNET_CRYPTO_hkdf_expand(&key_material, sizeof *key_material, &prk,
790 "gnunet-ed25519-x25519-ecdh",
791 strlen ("gnunet-ed25519-x25519-ecdh"),
792 NULL, 0);
793 return GNUNET_OK;
794}
795
796
799 const struct GNUNET_CRYPTO_EddsaPublicKey *pub,
800 struct GNUNET_HashCode *key_material)
801{
803 struct GNUNET_ShortHashCode prk;
804 uint8_t p[crypto_scalarmult_BYTES];
805 uint8_t curve25510_pk[crypto_scalarmult_BYTES];
806 uint8_t ikm[crypto_scalarmult_BYTES * 2];
807
808 // A := a * G
810 // This maps the ed25519 point to X25519
811 if (0 != crypto_sign_ed25519_pk_to_curve25519 (curve25510_pk, pub->q_y))
812 return GNUNET_SYSERR;
813 // Z := X25519(a,X)
814 if (0 != crypto_scalarmult (p, priv->d, curve25510_pk))
815 return GNUNET_SYSERR;
816 // From https://eprint.iacr.org/2021/509.pdf:
817 // To avoid potential malleability and preserve IND-CCA security, the original untranslated
818 // encapsulation A should be put into the KDF during decapsulation (and encapsulation).
819 memcpy (ikm, &A, crypto_scalarmult_BYTES);
820 memcpy (ikm + crypto_scalarmult_BYTES, p, crypto_scalarmult_BYTES);
821 // KDF(A, Z)
822 GNUNET_CRYPTO_hkdf_extract (&prk, NULL, 0, ikm, sizeof ikm);
823
824 // to get 512 bits, we call expand once
825 GNUNET_CRYPTO_hkdf_expand(&key_material, sizeof *key_material, &prk,
826 "gnunet-ed25519-x25519-ecdh",
827 strlen ("gnunet-ed25519-x25519-ecdh"),
828 NULL, 0);
829 return GNUNET_OK;
830}
831
832
836 const struct GNUNET_CRYPTO_EcdhePublicKey *c,
837 struct GNUNET_HashCode *key_material)
838{
839 return GNUNET_CRYPTO_eddsa_ecdh_kdf (priv, c, key_material);
840}
841
842
845 const struct GNUNET_CRYPTO_EcdhePublicKey *pub,
846 struct GNUNET_HashCode *key_material)
847{
848 uint8_t p[crypto_scalarmult_BYTES];
849
850 BENCHMARK_START (ecdsa_ecdh);
851 if (0 != crypto_scalarmult (p, priv->d, pub->q_y))
852 return GNUNET_SYSERR;
854 crypto_scalarmult_BYTES,
855 key_material);
856 BENCHMARK_END (ecdsa_ecdh);
857 return GNUNET_OK;
858}
859
860
863 const struct GNUNET_CRYPTO_EddsaPublicKey *pub,
864 struct GNUNET_HashCode *key_material)
865{
866 uint8_t p[crypto_scalarmult_BYTES];
867 uint8_t curve25510_pk[crypto_scalarmult_BYTES];
868
869 if (0 != crypto_sign_ed25519_pk_to_curve25519 (curve25510_pk, pub->q_y))
870 return GNUNET_SYSERR;
871 if (0 != crypto_scalarmult (p, priv->d, curve25510_pk))
872 return GNUNET_SYSERR;
873 GNUNET_CRYPTO_hash (p, crypto_scalarmult_BYTES, key_material);
874 return GNUNET_OK;
875}
876
877
881 struct GNUNET_HashCode *key_material)
882{
884
887 return GNUNET_CRYPTO_ecdh_eddsa_kdf (&sk, pub, key_material);
888}
889
890
894 struct GNUNET_CRYPTO_FoKemC *c,
895 struct GNUNET_HashCode *key_material)
896{
897 struct GNUNET_HashCode x;
898 struct GNUNET_HashCode ux;
899 struct GNUNET_HashCode w;
901
902 // This is the input to the FO OWTF
904
905 // We build our OWTF using a FO-transformation of ElGamal:
906 // U(x)
907 GNUNET_CRYPTO_hash (&x, sizeof (x), &ux);
908 GNUNET_memcpy (&sk, &ux, sizeof (sk));
909
910 // B := g^U(x)
912
914 return -1;
915 // w xor x (one-time pad)
916 GNUNET_CRYPTO_hash_xor (&w, &x, &c->y);
917
918 // k := H(x) FIXME: U and H must be different?
919 GNUNET_memcpy (key_material, &ux, sizeof (ux));
920 return GNUNET_OK;
921}
922
923
927 struct GNUNET_CRYPTO_FoKemC *c,
928 struct GNUNET_HashCode *key_material)
929{
930 struct GNUNET_HashCode x;
931 struct GNUNET_HashCode ux;
932 struct GNUNET_HashCode w;
935
936 // This is the input to the FO OWTF
938
939 // We build our OWTF using a FO-transformation of ElGamal:
940 // U(x)
941 GNUNET_CRYPTO_hash (&x, sizeof (x), &ux);
942 GNUNET_memcpy (&sk, &ux, sizeof (sk));
943
944 // B := g^U(x)
946
947 ret = GNUNET_CRYPTO_ecdh_eddsa (&sk, pub, &w);
948 if (GNUNET_OK != ret)
949 return ret;
950 // w xor x (one-time pad)
951 GNUNET_CRYPTO_hash_xor (&w, &x, &c->y);
952
953 // k := H(x) FIXME: U and H must be different?
954 GNUNET_memcpy (key_material, &ux, sizeof (ux));
955 return GNUNET_OK;
956}
957
958
961 const struct GNUNET_CRYPTO_FoKemC *c,
962 struct GNUNET_HashCode *key_material)
963{
964 struct GNUNET_HashCode x;
965 struct GNUNET_HashCode ux;
967 struct GNUNET_CRYPTO_EcdhePublicKey pub_test;
968
969 // w xor x (one-time pad)
970 GNUNET_CRYPTO_hash_xor (w, &c->y, &x);
971
972 // We build our OWTF using a FO-transformation of ElGamal:
973 // U(x)
974 GNUNET_CRYPTO_hash (&x, sizeof (x), &ux);
975 GNUNET_memcpy (&sk, &ux, sizeof (sk));
976
977 // B := g^U(x)
978 GNUNET_CRYPTO_ecdhe_key_get_public (&sk, &pub_test);
979
980 if (0 != memcmp (&pub_test, &c->pub, sizeof (c->pub)))
981 return GNUNET_SYSERR; // Reject
982
983 // k := H(x) FIXME: U and H must be different?
984 GNUNET_memcpy (key_material, &ux, sizeof (ux));
985 return GNUNET_OK;
986}
987
988
995 const struct GNUNET_CRYPTO_FoKemC *c,
996 struct GNUNET_HashCode *key_material)
997{
998 struct GNUNET_HashCode w;
1000
1001 ret = GNUNET_CRYPTO_eddsa_ecdh (priv, &c->pub, &w);
1002 if (GNUNET_OK != ret)
1003 return ret;
1004 return fo_kem_decaps (&w, c, key_material);
1005}
1006
1007
1011 struct GNUNET_CRYPTO_FoKemC *c,
1012 struct GNUNET_HashCode *key_material)
1013{
1014 struct GNUNET_HashCode w;
1016
1017 ret = GNUNET_CRYPTO_ecdsa_ecdh (priv, &c->pub, &w);
1018 if (GNUNET_OK != ret)
1019 return ret;
1020 return fo_kem_decaps (&w, c, key_material);
1021}
1022
1023
1026 const struct GNUNET_CRYPTO_EcdsaPublicKey *pub,
1027 struct GNUNET_HashCode *key_material)
1028{
1029 uint8_t p[crypto_scalarmult_BYTES];
1030 uint8_t curve25510_pk[crypto_scalarmult_BYTES];
1031
1032 if (0 != crypto_sign_ed25519_pk_to_curve25519 (curve25510_pk, pub->q_y))
1033 return GNUNET_SYSERR;
1034 if (0 != crypto_scalarmult (p, priv->d, curve25510_pk))
1035 return GNUNET_SYSERR;
1036 GNUNET_CRYPTO_hash (p, crypto_scalarmult_BYTES, key_material);
1037 return GNUNET_OK;
1038}
1039
1040
1041/* 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:99
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:530
#define CURVE
IMPLEMENTATION NOTICE:
Definition: crypto_ecc.c:61
static void buffer_clear(void *buf, size_t len)
Definition: crypto_ecc.c:417
#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:77
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:960
#define LOG(kind,...)
Definition: crypto_ecc.c:63
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:157
static mp_limb_t d[(((256)+GMP_NUMB_BITS - 1)/GMP_NUMB_BITS)]
static mp_limb_t A[(((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
commonly used definitions; globals in this file are exempt from the rule that the module name ("commo...
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:1009
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:731
void GNUNET_CRYPTO_ecdhe_key_create(struct GNUNET_CRYPTO_EcdhePrivateKey *pk)
Create a new private key.
Definition: crypto_ecc.c:453
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:834
enum GNUNET_GenericReturnValue GNUNET_CRYPTO_eddsa_ecdh_kdf(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:766
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:925
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:200
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:844
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:446
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:553
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:892
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:879
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:744
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:1025
void GNUNET_CRYPTO_eddsa_key_create(struct GNUNET_CRYPTO_EddsaPrivateKey *pk)
Create a new private key.
Definition: crypto_ecc.c:479
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:862
void GNUNET_CRYPTO_ecdsa_key_create(struct GNUNET_CRYPTO_EcdsaPrivateKey *pk)
Create a new private key.
Definition: crypto_ecc.c:464
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:624
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:439
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:648
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:993
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:499
enum GNUNET_GenericReturnValue GNUNET_CRYPTO_ecdh_eddsa_kdf(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:798
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:189
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:707
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:432
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:216
@ GNUNET_CRYPTO_QUALITY_NONCE
Randomness for IVs etc.
enum GNUNET_GenericReturnValue GNUNET_CRYPTO_hkdf_extract(struct GNUNET_ShortHashCode *prk, const void *salt, size_t salt_len, const void *ikm, size_t ikm_len)
HKDF-Extract using SHA256.
Definition: crypto_hkdf.c:224
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
enum GNUNET_GenericReturnValue GNUNET_CRYPTO_hkdf_expand(void *result, size_t out_len, const struct GNUNET_ShortHashCode *prk,...)
HKDF-Expand using SHA256.
Definition: crypto_hkdf.c:156
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:281
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:603
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:335
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:254
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:360
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:227
#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:385
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:308
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.
A 256-bit hashcode.