GNUnet  0.20.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 
96 static int
97 key_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 
154 static 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 
186 void
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 
197 void
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 
213 void
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 
224 char *
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 
251 char *
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 
278 char *
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 
305 char *
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,
386  struct GNUNET_CRYPTO_EddsaPrivateKey *priv)
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 
414 void
416 {
417  memset (pk, 0, sizeof(struct GNUNET_CRYPTO_EcdhePrivateKey));
418 }
419 
420 
421 void
423 {
424  memset (pk, 0, sizeof(struct GNUNET_CRYPTO_EcdsaPrivateKey));
425 }
426 
427 
428 void
430 {
431  memset (pk, 0, sizeof(struct GNUNET_CRYPTO_EddsaPrivateKey));
432 }
433 
434 
435 void
437 {
438  BENCHMARK_START (ecdhe_key_create);
440  pk,
441  sizeof (struct GNUNET_CRYPTO_EcdhePrivateKey));
442  BENCHMARK_END (ecdhe_key_create);
443 }
444 
445 
446 void
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 
461 void
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 
481 const struct GNUNET_CRYPTO_EcdsaPrivateKey *
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 
512 static 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,
539  struct GNUNET_CRYPTO_EcdsaSignature *sig)
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,
590  struct GNUNET_CRYPTO_EddsaSignature *sig)
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,
610  struct GNUNET_CRYPTO_EddsaSignature *sig)
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 
749 GNUNET_CRYPTO_eddsa_kem_decaps (const struct
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 
828  if (GNUNET_SYSERR == GNUNET_CRYPTO_ecdh_ecdsa (&sk, pub, &w))
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 
874 static enum GNUNET_GenericReturnValue
875 fo_kem_decaps (const struct GNUNET_HashCode *w,
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 int once
Global to mark if we've run the initialization.
Definition: gnsrecord.c:67
static int ret
Return value of the commandline.
Definition: gnunet-abd.c:81
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 end
Set if we are to shutdown all services (including ARM).
Definition: gnunet-arm.c:34
static int res
static OpusEncoder * enc
OPUS encoder.
uint32_t data
The data value.
struct GNUNET_IDENTITY_PrivateKey pk
Private key from command line option, or NULL.
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
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
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
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
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
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
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
#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
GNUNET_GenericReturnValue
Named constants for return values.
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
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
@ 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:708
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:788
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.