GNUnet  0.11.x
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 
26 #include "platform.h"
27 #include <gcrypt.h>
28 #include "gnunet_crypto_lib.h"
29 #include "gnunet_strings_lib.h"
30 #include "benchmark.h"
31 
32 #define EXTRA_CHECKS 0
33 
40 #define CURVE "Ed25519"
41 
42 #define LOG(kind, ...) GNUNET_log_from (kind, "util-crypto-ecc", __VA_ARGS__)
43 
44 #define LOG_STRERROR(kind, syscall) \
45  GNUNET_log_from_strerror (kind, "util-crypto-ecc", syscall)
46 
47 #define LOG_STRERROR_FILE(kind, syscall, filename) \
48  GNUNET_log_from_strerror_file (kind, "util-crypto-ecc", syscall, filename)
49 
55 #define LOG_GCRY(level, cmd, rc) \
56  do \
57  { \
58  LOG (level, \
59  _ ("`%s' failed at %s:%d with error: %s\n"), \
60  cmd, \
61  __FILE__, \
62  __LINE__, \
63  gcry_strerror (rc)); \
64  } while (0)
65 
66 
76 static int
77 key_from_sexp (gcry_mpi_t *array,
78  gcry_sexp_t sexp,
79  const char *topname,
80  const char *elems)
81 {
82  gcry_sexp_t list;
83  gcry_sexp_t l2;
84  unsigned int idx;
85 
86  list = gcry_sexp_find_token (sexp, topname, 0);
87  if (! list)
88  return 1;
89  l2 = gcry_sexp_cadr (list);
90  gcry_sexp_release (list);
91  list = l2;
92  if (! list)
93  return 2;
94 
95  idx = 0;
96  for (const char *s = elems; *s; s++, idx++)
97  {
98  l2 = gcry_sexp_find_token (list, s, 1);
99  if (! l2)
100  {
101  for (unsigned int i = 0; i < idx; i++)
102  {
103  gcry_free (array[i]);
104  array[i] = NULL;
105  }
106  gcry_sexp_release (list);
107  return 3; /* required parameter not found */
108  }
109  array[idx] = gcry_sexp_nth_mpi (l2, 1, GCRYMPI_FMT_USG);
110  gcry_sexp_release (l2);
111  if (! array[idx])
112  {
113  for (unsigned int i = 0; i < idx; i++)
114  {
115  gcry_free (array[i]);
116  array[i] = NULL;
117  }
118  gcry_sexp_release (list);
119  return 4; /* required parameter is invalid */
120  }
121  }
122  gcry_sexp_release (list);
123  return 0;
124 }
125 
126 
134 static gcry_sexp_t
136 {
137  gcry_sexp_t result;
138  int rc;
139 
140  rc = gcry_sexp_build (&result,
141  NULL,
142  "(private-key(ecc(curve \"" CURVE "\")"
143  "(d %b)))",
144  (int) sizeof(priv->d),
145  priv->d);
146  if (0 != rc)
147  {
148  LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_sexp_build", rc);
149  GNUNET_assert (0);
150  }
151 #if EXTRA_CHECKS
152  if (0 != (rc = gcry_pk_testkey (result)))
153  {
154  LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_pk_testkey", rc);
155  GNUNET_assert (0);
156  }
157 #endif
158  return result;
159 }
160 
161 
169 static gcry_sexp_t
171 {
172  gcry_sexp_t result;
173  int rc;
174 
175  rc = gcry_sexp_build (&result,
176  NULL,
177  "(private-key(ecc(curve \"" CURVE "\")"
178  "(flags eddsa)(d %b)))",
179  (int) sizeof(priv->d),
180  priv->d);
181  if (0 != rc)
182  {
183  LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_sexp_build", rc);
184  GNUNET_assert (0);
185  }
186 #if EXTRA_CHECKS
187  if (0 != (rc = gcry_pk_testkey (result)))
188  {
189  LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_pk_testkey", rc);
190  GNUNET_assert (0);
191  }
192 #endif
193  return result;
194 }
195 
196 
204 static gcry_sexp_t
206 {
207  gcry_sexp_t result;
208  int rc;
209 
210  rc = gcry_sexp_build (&result,
211  NULL,
212  "(private-key(ecc(curve \"" CURVE "\")"
213  "(d %b)))",
214  (int) sizeof(priv->d),
215  priv->d);
216  if (0 != rc)
217  {
218  LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_sexp_build", rc);
219  GNUNET_assert (0);
220  }
221 #if EXTRA_CHECKS
222  if (0 != (rc = gcry_pk_testkey (result)))
223  {
224  LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_pk_testkey", rc);
225  GNUNET_assert (0);
226  }
227 #endif
228  return result;
229 }
230 
231 
238 void
240  const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv,
242 {
243  gcry_sexp_t sexp;
244  gcry_ctx_t ctx;
245  gcry_mpi_t q;
246 
247  BENCHMARK_START (ecdsa_key_get_public);
248 
249  sexp = decode_private_ecdsa_key (priv);
250  GNUNET_assert (NULL != sexp);
251  GNUNET_assert (0 == gcry_mpi_ec_new (&ctx, sexp, NULL));
252  gcry_sexp_release (sexp);
253  q = gcry_mpi_ec_get_mpi ("q@eddsa", ctx, 0);
254  GNUNET_assert (NULL != q);
255  GNUNET_CRYPTO_mpi_print_unsigned (pub->q_y, sizeof(pub->q_y), q);
256  gcry_mpi_release (q);
257  gcry_ctx_release (ctx);
258 
259  BENCHMARK_END (ecdsa_key_get_public);
260 }
261 
262 
269 void
271  const struct GNUNET_CRYPTO_EddsaPrivateKey *priv,
273 {
274  gcry_sexp_t sexp;
275  gcry_ctx_t ctx;
276  gcry_mpi_t q;
277 
278  BENCHMARK_START (eddsa_key_get_public);
279 
280  sexp = decode_private_eddsa_key (priv);
281  GNUNET_assert (NULL != sexp);
282  GNUNET_assert (0 == gcry_mpi_ec_new (&ctx, sexp, NULL));
283  gcry_sexp_release (sexp);
284  q = gcry_mpi_ec_get_mpi ("q@eddsa", ctx, 0);
285  GNUNET_assert (q);
286  GNUNET_CRYPTO_mpi_print_unsigned (pub->q_y, sizeof(pub->q_y), q);
287  gcry_mpi_release (q);
288  gcry_ctx_release (ctx);
289 
290  BENCHMARK_END (eddsa_key_get_public);
291 }
292 
293 
300 void
302  const struct GNUNET_CRYPTO_EcdhePrivateKey *priv,
304 {
305  gcry_sexp_t sexp;
306  gcry_ctx_t ctx;
307  gcry_mpi_t q;
308 
309  BENCHMARK_START (ecdhe_key_get_public);
310 
311  sexp = decode_private_ecdhe_key (priv);
312  GNUNET_assert (NULL != sexp);
313  GNUNET_assert (0 == gcry_mpi_ec_new (&ctx, sexp, NULL));
314  gcry_sexp_release (sexp);
315  q = gcry_mpi_ec_get_mpi ("q@eddsa", ctx, 0);
316  GNUNET_assert (q);
317  GNUNET_CRYPTO_mpi_print_unsigned (pub->q_y, sizeof(pub->q_y), q);
318  gcry_mpi_release (q);
319  gcry_ctx_release (ctx);
320 
321  BENCHMARK_END (ecdhe_key_get_public);
322 }
323 
324 
331 char *
333  const struct GNUNET_CRYPTO_EcdsaPublicKey *pub)
334 {
335  char *pubkeybuf;
336  size_t keylen = (sizeof(struct GNUNET_CRYPTO_EcdsaPublicKey)) * 8;
337  char *end;
338 
339  if (keylen % 5 > 0)
340  keylen += 5 - keylen % 5;
341  keylen /= 5;
342  pubkeybuf = GNUNET_malloc (keylen + 1);
343  end =
344  GNUNET_STRINGS_data_to_string ((unsigned char *) pub,
345  sizeof(struct GNUNET_CRYPTO_EcdsaPublicKey),
346  pubkeybuf,
347  keylen);
348  if (NULL == end)
349  {
350  GNUNET_free (pubkeybuf);
351  return NULL;
352  }
353  *end = '\0';
354  return pubkeybuf;
355 }
356 
357 
364 char *
366  const struct GNUNET_CRYPTO_EddsaPublicKey *pub)
367 {
368  char *pubkeybuf;
369  size_t keylen = (sizeof(struct GNUNET_CRYPTO_EddsaPublicKey)) * 8;
370  char *end;
371 
372  if (keylen % 5 > 0)
373  keylen += 5 - keylen % 5;
374  keylen /= 5;
375  pubkeybuf = GNUNET_malloc (keylen + 1);
376  end =
377  GNUNET_STRINGS_data_to_string ((unsigned char *) pub,
378  sizeof(struct GNUNET_CRYPTO_EddsaPublicKey),
379  pubkeybuf,
380  keylen);
381  if (NULL == end)
382  {
383  GNUNET_free (pubkeybuf);
384  return NULL;
385  }
386  *end = '\0';
387  return pubkeybuf;
388 }
389 
390 
397 char *
399  const struct GNUNET_CRYPTO_EddsaPrivateKey *priv)
400 {
401  char *privkeybuf;
402  size_t keylen = (sizeof(struct GNUNET_CRYPTO_EddsaPrivateKey)) * 8;
403  char *end;
404 
405  if (keylen % 5 > 0)
406  keylen += 5 - keylen % 5;
407  keylen /= 5;
408  privkeybuf = GNUNET_malloc (keylen + 1);
409  end = GNUNET_STRINGS_data_to_string ((unsigned char *) priv,
410  sizeof(
412  privkeybuf,
413  keylen);
414  if (NULL == end)
415  {
416  GNUNET_free (privkeybuf);
417  return NULL;
418  }
419  *end = '\0';
420  return privkeybuf;
421 }
422 
423 
430 char *
432  const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv)
433 {
434  char *privkeybuf;
435  size_t keylen = (sizeof(struct GNUNET_CRYPTO_EcdsaPrivateKey)) * 8;
436  char *end;
437 
438  if (keylen % 5 > 0)
439  keylen += 5 - keylen % 5;
440  keylen /= 5;
441  privkeybuf = GNUNET_malloc (keylen + 1);
442  end = GNUNET_STRINGS_data_to_string ((unsigned char *) priv,
443  sizeof(
445  privkeybuf,
446  keylen);
447  if (NULL == end)
448  {
449  GNUNET_free (privkeybuf);
450  return NULL;
451  }
452  *end = '\0';
453  return privkeybuf;
454 }
455 
456 
465 int
467  const char *enc,
468  size_t enclen,
470 {
471  size_t keylen = (sizeof(struct GNUNET_CRYPTO_EcdsaPublicKey)) * 8;
472 
473  if (keylen % 5 > 0)
474  keylen += 5 - keylen % 5;
475  keylen /= 5;
476  if (enclen != keylen)
477  return GNUNET_SYSERR;
478 
479  if (GNUNET_OK !=
481  enclen,
482  pub,
483  sizeof(
485  return GNUNET_SYSERR;
486  return GNUNET_OK;
487 }
488 
489 
498 int
500  const char *enc,
501  size_t enclen,
503 {
504  size_t keylen = (sizeof(struct GNUNET_CRYPTO_EddsaPublicKey)) * 8;
505 
506  if (keylen % 5 > 0)
507  keylen += 5 - keylen % 5;
508  keylen /= 5;
509  if (enclen != keylen)
510  return GNUNET_SYSERR;
511 
512  if (GNUNET_OK !=
514  enclen,
515  pub,
516  sizeof(
518  return GNUNET_SYSERR;
519  return GNUNET_OK;
520 }
521 
522 
531 int
533  const char *enc,
534  size_t enclen,
535  struct GNUNET_CRYPTO_EddsaPrivateKey *priv)
536 {
537  size_t keylen = (sizeof(struct GNUNET_CRYPTO_EddsaPrivateKey)) * 8;
538 
539  if (keylen % 5 > 0)
540  keylen += 5 - keylen % 5;
541  keylen /= 5;
542  if (enclen != keylen)
543  return GNUNET_SYSERR;
544 
545  if (GNUNET_OK !=
547  enclen,
548  priv,
549  sizeof(
551  return GNUNET_SYSERR;
552 #if CRYPTO_BUG
553  if (GNUNET_OK != check_eddsa_key (priv))
554  {
555  GNUNET_break (0);
556  return GNUNET_OK;
557  }
558 #endif
559  return GNUNET_OK;
560 }
561 
562 
569 void
571 {
572  memset (pk, 0, sizeof(struct GNUNET_CRYPTO_EcdhePrivateKey));
573 }
574 
575 
582 void
584 {
585  memset (pk, 0, sizeof(struct GNUNET_CRYPTO_EcdsaPrivateKey));
586 }
587 
588 
595 void
597 {
598  memset (pk, 0, sizeof(struct GNUNET_CRYPTO_EddsaPrivateKey));
599 }
600 
601 
609 {
610  struct GNUNET_CRYPTO_EcdhePrivateKey *priv;
611 
614  {
615  GNUNET_free (priv);
616  return NULL;
617  }
618  return priv;
619 }
620 
621 
629 int
631 {
632  gcry_sexp_t priv_sexp;
633  gcry_sexp_t s_keyparam;
634  gcry_mpi_t d;
635  int rc;
636 
637  BENCHMARK_START (ecdhe_key_create);
638 
639  /* NOTE: For libgcrypt >= 1.7, we do not need the 'eddsa' flag here,
640  but should also be harmless. For libgcrypt < 1.7, using 'eddsa'
641  disables an expensive key testing routine. We do not want to run
642  the expensive check for ECDHE, as we generate TONS of keys to
643  use for a very short time. */if (0 != (rc = gcry_sexp_build (&s_keyparam,
644  NULL,
645  "(genkey(ecc(curve \"" CURVE "\")"
646  "(flags eddsa no-keytest)))")))
647  {
648  LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_sexp_build", rc);
649  return GNUNET_SYSERR;
650  }
651  if (0 != (rc = gcry_pk_genkey (&priv_sexp, s_keyparam)))
652  {
653  LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_pk_genkey", rc);
654  gcry_sexp_release (s_keyparam);
655  return GNUNET_SYSERR;
656  }
657  gcry_sexp_release (s_keyparam);
658 #if EXTRA_CHECKS
659  if (0 != (rc = gcry_pk_testkey (priv_sexp)))
660  {
661  LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_pk_testkey", rc);
662  gcry_sexp_release (priv_sexp);
663  return GNUNET_SYSERR;
664  }
665 #endif
666  if (0 != (rc = key_from_sexp (&d, priv_sexp, "private-key", "d")))
667  {
668  LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "key_from_sexp", rc);
669  gcry_sexp_release (priv_sexp);
670  return GNUNET_SYSERR;
671  }
672  gcry_sexp_release (priv_sexp);
673  GNUNET_CRYPTO_mpi_print_unsigned (pk->d, sizeof(pk->d), d);
674  gcry_mpi_release (d);
675 
676  BENCHMARK_END (ecdhe_key_create);
677 
678  return GNUNET_OK;
679 }
680 
681 
689 {
690  struct GNUNET_CRYPTO_EcdsaPrivateKey *priv;
691  gcry_sexp_t priv_sexp;
692  gcry_sexp_t s_keyparam;
693  gcry_mpi_t d;
694  int rc;
695 
696  BENCHMARK_START (ecdsa_key_create);
697 
698  if (0 != (rc = gcry_sexp_build (&s_keyparam,
699  NULL,
700  "(genkey(ecc(curve \"" CURVE "\")"
701  "(flags)))")))
702  {
703  LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_sexp_build", rc);
704  return NULL;
705  }
706  if (0 != (rc = gcry_pk_genkey (&priv_sexp, s_keyparam)))
707  {
708  LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_pk_genkey", rc);
709  gcry_sexp_release (s_keyparam);
710  return NULL;
711  }
712  gcry_sexp_release (s_keyparam);
713 #if EXTRA_CHECKS
714  if (0 != (rc = gcry_pk_testkey (priv_sexp)))
715  {
716  LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_pk_testkey", rc);
717  gcry_sexp_release (priv_sexp);
718  return NULL;
719  }
720 #endif
721  if (0 != (rc = key_from_sexp (&d, priv_sexp, "private-key", "d")))
722  {
723  LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "key_from_sexp", rc);
724  gcry_sexp_release (priv_sexp);
725  return NULL;
726  }
727  gcry_sexp_release (priv_sexp);
729  GNUNET_CRYPTO_mpi_print_unsigned (priv->d, sizeof(priv->d), d);
730  gcry_mpi_release (d);
731 
732  BENCHMARK_END (ecdsa_key_create);
733 
734  return priv;
735 }
736 
737 
745 {
746  struct GNUNET_CRYPTO_EddsaPrivateKey *priv;
747  gcry_sexp_t priv_sexp;
748  gcry_sexp_t s_keyparam;
749  gcry_mpi_t d;
750  int rc;
751 
752  BENCHMARK_START (eddsa_key_create);
753 
754 #if CRYPTO_BUG
755 again:
756 #endif
757  if (0 != (rc = gcry_sexp_build (&s_keyparam,
758  NULL,
759  "(genkey(ecc(curve \"" CURVE "\")"
760  "(flags eddsa)))")))
761  {
762  LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_sexp_build", rc);
763  return NULL;
764  }
765  if (0 != (rc = gcry_pk_genkey (&priv_sexp, s_keyparam)))
766  {
767  LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_pk_genkey", rc);
768  gcry_sexp_release (s_keyparam);
769  return NULL;
770  }
771  gcry_sexp_release (s_keyparam);
772 #if EXTRA_CHECKS
773  if (0 != (rc = gcry_pk_testkey (priv_sexp)))
774  {
775  LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_pk_testkey", rc);
776  gcry_sexp_release (priv_sexp);
777  return NULL;
778  }
779 #endif
780  if (0 != (rc = key_from_sexp (&d, priv_sexp, "private-key", "d")))
781  {
782  LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "key_from_sexp", rc);
783  gcry_sexp_release (priv_sexp);
784  return NULL;
785  }
786  gcry_sexp_release (priv_sexp);
788  GNUNET_CRYPTO_mpi_print_unsigned (priv->d, sizeof(priv->d), d);
789  gcry_mpi_release (d);
790 
791 #if CRYPTO_BUG
792  if (GNUNET_OK != check_eddsa_key (priv))
793  {
794  GNUNET_break (0);
795  GNUNET_free (priv);
796  goto again;
797  }
798 #endif
799 
800  BENCHMARK_END (eddsa_key_create);
801 
802  return priv;
803 }
804 
805 
811 const struct GNUNET_CRYPTO_EcdsaPrivateKey *
813 {
818  static struct GNUNET_CRYPTO_EcdsaPrivateKey anonymous;
819  static int once;
820 
821  if (once)
822  return &anonymous;
824  sizeof(anonymous.d),
825  GCRYMPI_CONST_ONE);
826  once = 1;
827  return &anonymous;
828 }
829 
830 
838 static gcry_sexp_t
840 {
841  gcry_sexp_t data;
842  int rc;
843 
844 /* SEE #5398 */
845 #if 1
846  struct GNUNET_HashCode hc;
847 
848  GNUNET_CRYPTO_hash (purpose, ntohl (purpose->size), &hc);
849  if (0 != (rc = gcry_sexp_build (&data,
850  NULL,
851  "(data(flags eddsa)(hash-algo %s)(value %b))",
852  "sha512",
853  (int) sizeof(hc),
854  &hc)))
855  {
856  LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_sexp_build", rc);
857  return NULL;
858  }
859 #else
860  if (0 != (rc = gcry_sexp_build (&data,
861  NULL,
862  "(data(flags eddsa)(hash-algo %s)(value %b))",
863  "sha512",
864  ntohl (purpose->size),
865  purpose)))
866  {
867  LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_sexp_build", rc);
868  return NULL;
869  }
870 #endif
871  return data;
872 }
873 
874 
882 static gcry_sexp_t
884 {
885  gcry_sexp_t data;
886  int rc;
887 
888 /* See #5398 */
889 #if 1
890  struct GNUNET_HashCode hc;
891 
892  GNUNET_CRYPTO_hash (purpose, ntohl (purpose->size), &hc);
893  if (0 != (rc = gcry_sexp_build (&data,
894  NULL,
895  "(data(flags rfc6979)(hash %s %b))",
896  "sha512",
897  (int) sizeof(hc),
898  &hc)))
899  {
900  LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_sexp_build", rc);
901  return NULL;
902  }
903 #else
904  if (0 != (rc = gcry_sexp_build (&data,
905  NULL,
906  "(data(flags rfc6979)(hash %s %b))",
907  "sha512",
908  ntohl (purpose->size),
909  purpose)))
910  {
911  LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_sexp_build", rc);
912  return NULL;
913  }
914 #endif
915  return data;
916 }
917 
918 
927 int
929  const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv,
930  const struct GNUNET_CRYPTO_EccSignaturePurpose *purpose,
931  struct GNUNET_CRYPTO_EcdsaSignature *sig)
932 {
933  gcry_sexp_t priv_sexp;
934  gcry_sexp_t sig_sexp;
935  gcry_sexp_t data;
936  int rc;
937  gcry_mpi_t rs[2];
938 
939  BENCHMARK_START (ecdsa_sign);
940 
941  priv_sexp = decode_private_ecdsa_key (priv);
942  data = data_to_ecdsa_value (purpose);
943  if (0 != (rc = gcry_pk_sign (&sig_sexp, data, priv_sexp)))
944  {
946  _ ("ECC signing failed at %s:%d: %s\n"),
947  __FILE__,
948  __LINE__,
949  gcry_strerror (rc));
950  gcry_sexp_release (data);
951  gcry_sexp_release (priv_sexp);
952  return GNUNET_SYSERR;
953  }
954  gcry_sexp_release (priv_sexp);
955  gcry_sexp_release (data);
956 
957  /* extract 'r' and 's' values from sexpression 'sig_sexp' and store in
958  'signature' */
959  if (0 != (rc = key_from_sexp (rs, sig_sexp, "sig-val", "rs")))
960  {
961  GNUNET_break (0);
962  gcry_sexp_release (sig_sexp);
963  return GNUNET_SYSERR;
964  }
965  gcry_sexp_release (sig_sexp);
966  GNUNET_CRYPTO_mpi_print_unsigned (sig->r, sizeof(sig->r), rs[0]);
967  GNUNET_CRYPTO_mpi_print_unsigned (sig->s, sizeof(sig->s), rs[1]);
968  gcry_mpi_release (rs[0]);
969  gcry_mpi_release (rs[1]);
970 
971  BENCHMARK_END (ecdsa_sign);
972 
973  return GNUNET_OK;
974 }
975 
976 
985 int
987  const struct GNUNET_CRYPTO_EddsaPrivateKey *priv,
988  const struct GNUNET_CRYPTO_EccSignaturePurpose *purpose,
989  struct GNUNET_CRYPTO_EddsaSignature *sig)
990 {
991  gcry_sexp_t priv_sexp;
992  gcry_sexp_t sig_sexp;
993  gcry_sexp_t data;
994  int rc;
995  gcry_mpi_t rs[2];
996 
997  BENCHMARK_START (eddsa_sign);
998 
999  priv_sexp = decode_private_eddsa_key (priv);
1000  data = data_to_eddsa_value (purpose);
1001  if (0 != (rc = gcry_pk_sign (&sig_sexp, data, priv_sexp)))
1002  {
1004  _ ("EdDSA signing failed at %s:%d: %s\n"),
1005  __FILE__,
1006  __LINE__,
1007  gcry_strerror (rc));
1008  gcry_sexp_release (data);
1009  gcry_sexp_release (priv_sexp);
1010  return GNUNET_SYSERR;
1011  }
1012  gcry_sexp_release (priv_sexp);
1013  gcry_sexp_release (data);
1014 
1015  /* extract 'r' and 's' values from sexpression 'sig_sexp' and store in
1016  'signature' */
1017  if (0 != (rc = key_from_sexp (rs, sig_sexp, "sig-val", "rs")))
1018  {
1019  GNUNET_break (0);
1020  gcry_sexp_release (sig_sexp);
1021  return GNUNET_SYSERR;
1022  }
1023  gcry_sexp_release (sig_sexp);
1024  GNUNET_CRYPTO_mpi_print_unsigned (sig->r, sizeof(sig->r), rs[0]);
1025  GNUNET_CRYPTO_mpi_print_unsigned (sig->s, sizeof(sig->s), rs[1]);
1026  gcry_mpi_release (rs[0]);
1027  gcry_mpi_release (rs[1]);
1028 
1029  BENCHMARK_END (eddsa_sign);
1030 
1031  return GNUNET_OK;
1032 }
1033 
1034 
1044 int
1046  uint32_t purpose,
1047  const struct GNUNET_CRYPTO_EccSignaturePurpose *validate,
1048  const struct GNUNET_CRYPTO_EcdsaSignature *sig,
1049  const struct GNUNET_CRYPTO_EcdsaPublicKey *pub)
1050 {
1051  gcry_sexp_t data;
1052  gcry_sexp_t sig_sexpr;
1053  gcry_sexp_t pub_sexpr;
1054  int rc;
1055 
1056  BENCHMARK_START (ecdsa_verify);
1057 
1058  if (purpose != ntohl (validate->purpose))
1059  return GNUNET_SYSERR; /* purpose mismatch */
1060 
1061  /* build s-expression for signature */
1062  if (0 != (rc = gcry_sexp_build (&sig_sexpr,
1063  NULL,
1064  "(sig-val(ecdsa(r %b)(s %b)))",
1065  (int) sizeof(sig->r),
1066  sig->r,
1067  (int) sizeof(sig->s),
1068  sig->s)))
1069  {
1070  LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_sexp_build", rc);
1071  return GNUNET_SYSERR;
1072  }
1073  data = data_to_ecdsa_value (validate);
1074  if (0 != (rc = gcry_sexp_build (&pub_sexpr,
1075  NULL,
1076  "(public-key(ecc(curve " CURVE ")(q %b)))",
1077  (int) sizeof(pub->q_y),
1078  pub->q_y)))
1079  {
1080  gcry_sexp_release (data);
1081  gcry_sexp_release (sig_sexpr);
1082  return GNUNET_SYSERR;
1083  }
1084  rc = gcry_pk_verify (sig_sexpr, data, pub_sexpr);
1085  gcry_sexp_release (pub_sexpr);
1086  gcry_sexp_release (data);
1087  gcry_sexp_release (sig_sexpr);
1088  if (0 != rc)
1089  {
1091  _ ("ECDSA signature verification failed at %s:%d: %s\n"),
1092  __FILE__,
1093  __LINE__,
1094  gcry_strerror (rc));
1095  BENCHMARK_END (ecdsa_verify);
1096  return GNUNET_SYSERR;
1097  }
1098  BENCHMARK_END (ecdsa_verify);
1099  return GNUNET_OK;
1100 }
1101 
1102 
1112 int
1114  uint32_t purpose,
1115  const struct GNUNET_CRYPTO_EccSignaturePurpose *validate,
1116  const struct GNUNET_CRYPTO_EddsaSignature *sig,
1117  const struct GNUNET_CRYPTO_EddsaPublicKey *pub)
1118 {
1119  gcry_sexp_t data;
1120  gcry_sexp_t sig_sexpr;
1121  gcry_sexp_t pub_sexpr;
1122  int rc;
1123 
1124  BENCHMARK_START (eddsa_verify);
1125 
1126  if (purpose != ntohl (validate->purpose))
1127  return GNUNET_SYSERR; /* purpose mismatch */
1128 
1129  /* build s-expression for signature */
1130  if (0 != (rc = gcry_sexp_build (&sig_sexpr,
1131  NULL,
1132  "(sig-val(eddsa(r %b)(s %b)))",
1133  (int) sizeof(sig->r),
1134  sig->r,
1135  (int) sizeof(sig->s),
1136  sig->s)))
1137  {
1138  LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_sexp_build", rc);
1139  return GNUNET_SYSERR;
1140  }
1141  data = data_to_eddsa_value (validate);
1142  if (0 != (rc = gcry_sexp_build (&pub_sexpr,
1143  NULL,
1144  "(public-key(ecc(curve " CURVE
1145  ")(flags eddsa)(q %b)))",
1146  (int) sizeof(pub->q_y),
1147  pub->q_y)))
1148  {
1149  gcry_sexp_release (data);
1150  gcry_sexp_release (sig_sexpr);
1151  return GNUNET_SYSERR;
1152  }
1153  rc = gcry_pk_verify (sig_sexpr, data, pub_sexpr);
1154  gcry_sexp_release (pub_sexpr);
1155  gcry_sexp_release (data);
1156  gcry_sexp_release (sig_sexpr);
1157  if (0 != rc)
1158  {
1160  _ ("EdDSA signature verification of type %u failed at %s:%d: %s\n"),
1161  (unsigned int) purpose,
1162  __FILE__,
1163  __LINE__,
1164  gcry_strerror (rc));
1165  BENCHMARK_END (eddsa_verify);
1166  return GNUNET_SYSERR;
1167  }
1168  BENCHMARK_END (eddsa_verify);
1169  return GNUNET_OK;
1170 }
1171 
1172 
1181 int
1183  const struct GNUNET_CRYPTO_EcdhePublicKey *pub,
1184  struct GNUNET_HashCode *key_material)
1185 {
1186  gcry_mpi_point_t result;
1187  gcry_mpi_point_t q;
1188  gcry_mpi_t d;
1189  gcry_ctx_t ctx;
1190  gcry_sexp_t pub_sexpr;
1191  gcry_mpi_t result_x;
1192  unsigned char xbuf[256 / 8];
1193  size_t rsize;
1194 
1195  BENCHMARK_START (ecc_ecdh);
1196 
1197  /* first, extract the q = dP value from the public key */
1198  if (0 != gcry_sexp_build (&pub_sexpr,
1199  NULL,
1200  "(public-key(ecc(curve " CURVE ")(q %b)))",
1201  (int) sizeof(pub->q_y),
1202  pub->q_y))
1203  return GNUNET_SYSERR;
1204  GNUNET_assert (0 == gcry_mpi_ec_new (&ctx, pub_sexpr, NULL));
1205  gcry_sexp_release (pub_sexpr);
1206  q = gcry_mpi_ec_get_point ("q", ctx, 0);
1207 
1208  /* second, extract the d value from our private key */
1209  GNUNET_CRYPTO_mpi_scan_unsigned (&d, priv->d, sizeof(priv->d));
1210 
1211  /* then call the 'multiply' function, to compute the product */
1212  result = gcry_mpi_point_new (0);
1213  gcry_mpi_ec_mul (result, d, q, ctx);
1214  gcry_mpi_point_release (q);
1215  gcry_mpi_release (d);
1216 
1217  /* finally, convert point to string for hashing */
1218  result_x = gcry_mpi_new (256);
1219  if (gcry_mpi_ec_get_affine (result_x, NULL, result, ctx))
1220  {
1221  LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "get_affine failed", 0);
1222  gcry_mpi_point_release (result);
1223  gcry_ctx_release (ctx);
1224  return GNUNET_SYSERR;
1225  }
1226  gcry_mpi_point_release (result);
1227  gcry_ctx_release (ctx);
1228 
1229  rsize = sizeof(xbuf);
1230  GNUNET_assert (! gcry_mpi_get_flag (result_x, GCRYMPI_FLAG_OPAQUE));
1231  /* result_x can be negative here, so we do not use 'GNUNET_CRYPTO_mpi_print_unsigned'
1232  as that does not include the sign bit; x should be a 255-bit
1233  value, so with the sign it should fit snugly into the 256-bit
1234  xbuf */
1235  GNUNET_assert (
1236  0 == gcry_mpi_print (GCRYMPI_FMT_STD, xbuf, rsize, &rsize, result_x));
1237  GNUNET_CRYPTO_hash (xbuf, rsize, key_material);
1238  gcry_mpi_release (result_x);
1239  BENCHMARK_END (ecc_ecdh);
1240  return GNUNET_OK;
1241 }
1242 
1243 
1254 static gcry_mpi_t
1256  const char *label,
1257  const char *context)
1258 {
1259  gcry_mpi_t h;
1260  struct GNUNET_HashCode hc;
1261  static const char *const salt = "key-derivation";
1262 
1263  GNUNET_CRYPTO_kdf (&hc,
1264  sizeof(hc),
1265  salt,
1266  strlen (salt),
1267  pub,
1268  sizeof(*pub),
1269  label,
1270  strlen (label),
1271  context,
1272  strlen (context),
1273  NULL,
1274  0);
1275  GNUNET_CRYPTO_mpi_scan_unsigned (&h, (unsigned char *) &hc, sizeof(hc));
1276  return h;
1277 }
1278 
1279 
1294  const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv,
1295  const char *label,
1296  const char *context)
1297 {
1298  struct GNUNET_CRYPTO_EcdsaPublicKey pub;
1300  gcry_mpi_t h;
1301  gcry_mpi_t x;
1302  gcry_mpi_t d;
1303  gcry_mpi_t n;
1304  gcry_ctx_t ctx;
1305 
1306  GNUNET_assert (0 == gcry_mpi_ec_new (&ctx, NULL, CURVE));
1307 
1308  n = gcry_mpi_ec_get_mpi ("n", ctx, 1);
1310 
1311  h = derive_h (&pub, label, context);
1312  GNUNET_CRYPTO_mpi_scan_unsigned (&x, priv->d, sizeof(priv->d));
1313  d = gcry_mpi_new (256);
1314  gcry_mpi_mulm (d, h, x, n);
1315  gcry_mpi_release (h);
1316  gcry_mpi_release (x);
1317  gcry_mpi_release (n);
1318  gcry_ctx_release (ctx);
1320  GNUNET_CRYPTO_mpi_print_unsigned (ret->d, sizeof(ret->d), d);
1321  gcry_mpi_release (d);
1322  return ret;
1323 }
1324 
1325 
1336 void
1338  const struct GNUNET_CRYPTO_EcdsaPublicKey *pub,
1339  const char *label,
1340  const char *context,
1342 {
1343  gcry_ctx_t ctx;
1344  gcry_mpi_t q_y;
1345  gcry_mpi_t h;
1346  gcry_mpi_t n;
1347  gcry_mpi_t h_mod_n;
1348  gcry_mpi_point_t q;
1349  gcry_mpi_point_t v;
1350 
1351  GNUNET_assert (0 == gcry_mpi_ec_new (&ctx, NULL, CURVE));
1352 
1353  /* obtain point 'q' from original public key. The provided 'q' is
1354  compressed thus we first store it in the context and then get it
1355  back as a (decompresssed) point. */
1356  q_y = gcry_mpi_set_opaque_copy (NULL, pub->q_y, 8 * sizeof(pub->q_y));
1357  GNUNET_assert (NULL != q_y);
1358  GNUNET_assert (0 == gcry_mpi_ec_set_mpi ("q", q_y, ctx));
1359  gcry_mpi_release (q_y);
1360  q = gcry_mpi_ec_get_point ("q", ctx, 0);
1361  GNUNET_assert (q);
1362 
1363  /* calculate h_mod_n = h % n */
1364  h = derive_h (pub, label, context);
1365  n = gcry_mpi_ec_get_mpi ("n", ctx, 1);
1366  h_mod_n = gcry_mpi_new (256);
1367  gcry_mpi_mod (h_mod_n, h, n);
1368  /* calculate v = h_mod_n * q */
1369  v = gcry_mpi_point_new (0);
1370  gcry_mpi_ec_mul (v, h_mod_n, q, ctx);
1371  gcry_mpi_release (h_mod_n);
1372  gcry_mpi_release (h);
1373  gcry_mpi_release (n);
1374  gcry_mpi_point_release (q);
1375 
1376  /* convert point 'v' to public key that we return */
1377  GNUNET_assert (0 == gcry_mpi_ec_set_point ("q", v, ctx));
1378  gcry_mpi_point_release (v);
1379  q_y = gcry_mpi_ec_get_mpi ("q@eddsa", ctx, 0);
1380  GNUNET_assert (q_y);
1381  GNUNET_CRYPTO_mpi_print_unsigned (result->q_y, sizeof(result->q_y), q_y);
1382  gcry_mpi_release (q_y);
1383  gcry_ctx_release (ctx);
1384 }
1385 
1386 
1393 static void
1394 reverse_buffer (unsigned char *buffer, size_t length)
1395 {
1396  unsigned char tmp;
1397  size_t i;
1398 
1399  for (i = 0; i < length / 2; i++)
1400  {
1401  tmp = buffer[i];
1402  buffer[i] = buffer[length - 1 - i];
1403  buffer[length - 1 - i] = tmp;
1404  }
1405 }
1406 
1407 
1415 static gcry_mpi_t
1416 eddsa_d_to_a (gcry_mpi_t d)
1417 {
1418  unsigned char rawmpi[32]; /* 256-bit value */
1419  size_t rawmpilen;
1420  unsigned char digest[64]; /* 512-bit hash value */
1421  gcry_buffer_t hvec[2];
1422  unsigned int b;
1423  gcry_mpi_t a;
1424 
1425  b = 256 / 8; /* number of bytes in `d` */
1426 
1427  /* Note that we clear DIGEST so we can use it as input to left pad
1428  the key with zeroes for hashing. */
1429  memset (digest, 0, sizeof digest);
1430  memset (hvec, 0, sizeof hvec);
1431  rawmpilen = sizeof(rawmpi);
1432  GNUNET_assert (
1433  0 == gcry_mpi_print (GCRYMPI_FMT_USG, rawmpi, rawmpilen, &rawmpilen, d));
1434  hvec[0].data = digest;
1435  hvec[0].off = 0;
1436  hvec[0].len = b > rawmpilen ? (b - rawmpilen) : 0;
1437  hvec[1].data = rawmpi;
1438  hvec[1].off = 0;
1439  hvec[1].len = rawmpilen;
1440  GNUNET_assert (
1441  0 == gcry_md_hash_buffers (GCRY_MD_SHA512, 0 /* flags */, digest, hvec, 2));
1442  /* Compute the A value. */
1443  reverse_buffer (digest, 32); /* Only the first half of the hash. */
1444  digest[0] = (digest[0] & 0x7f) | 0x40;
1445  digest[31] &= 0xf8;
1446 
1447  GNUNET_CRYPTO_mpi_scan_unsigned (&a, digest, 32);
1448  return a;
1449 }
1450 
1451 
1460 static int
1461 point_to_hash (gcry_mpi_point_t result,
1462  gcry_ctx_t ctx,
1463  struct GNUNET_HashCode *key_material)
1464 {
1465  gcry_mpi_t result_x;
1466  unsigned char xbuf[256 / 8];
1467  size_t rsize;
1468 
1469  /* finally, convert point to string for hashing */
1470  result_x = gcry_mpi_new (256);
1471  if (gcry_mpi_ec_get_affine (result_x, NULL, result, ctx))
1472  {
1473  LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "get_affine failed", 0);
1474  return GNUNET_SYSERR;
1475  }
1476 
1477  rsize = sizeof(xbuf);
1478  GNUNET_assert (! gcry_mpi_get_flag (result_x, GCRYMPI_FLAG_OPAQUE));
1479  /* result_x can be negative here, so we do not use 'GNUNET_CRYPTO_mpi_print_unsigned'
1480  as that does not include the sign bit; x should be a 255-bit
1481  value, so with the sign it should fit snugly into the 256-bit
1482  xbuf */
1483  GNUNET_assert (
1484  0 == gcry_mpi_print (GCRYMPI_FMT_STD, xbuf, rsize, &rsize, result_x));
1485  GNUNET_CRYPTO_hash (xbuf, rsize, key_material);
1486  gcry_mpi_release (result_x);
1487  return GNUNET_OK;
1488 }
1489 
1490 
1501 int
1503  const struct GNUNET_CRYPTO_EcdhePublicKey *pub,
1504  struct GNUNET_HashCode *key_material)
1505 {
1506  gcry_mpi_point_t result;
1507  gcry_mpi_point_t q;
1508  gcry_mpi_t d;
1509  gcry_mpi_t a;
1510  gcry_ctx_t ctx;
1511  gcry_sexp_t pub_sexpr;
1512  int ret;
1513 
1514  BENCHMARK_START (eddsa_ecdh);
1515 
1516  /* first, extract the q = dP value from the public key */
1517  if (0 != gcry_sexp_build (&pub_sexpr,
1518  NULL,
1519  "(public-key(ecc(curve " CURVE ")(q %b)))",
1520  (int) sizeof(pub->q_y),
1521  pub->q_y))
1522  return GNUNET_SYSERR;
1523  GNUNET_assert (0 == gcry_mpi_ec_new (&ctx, pub_sexpr, NULL));
1524  gcry_sexp_release (pub_sexpr);
1525  q = gcry_mpi_ec_get_point ("q", ctx, 0);
1526 
1527  /* second, extract the d value from our private key */
1528  GNUNET_CRYPTO_mpi_scan_unsigned (&d, priv->d, sizeof(priv->d));
1529 
1530  /* NOW, because this is EdDSA, HASH 'd' first! */
1531  a = eddsa_d_to_a (d);
1532  gcry_mpi_release (d);
1533 
1534  /* then call the 'multiply' function, to compute the product */
1535  result = gcry_mpi_point_new (0);
1536  gcry_mpi_ec_mul (result, a, q, ctx);
1537  gcry_mpi_point_release (q);
1538  gcry_mpi_release (a);
1539 
1540  ret = point_to_hash (result, ctx, key_material);
1541  gcry_mpi_point_release (result);
1542  gcry_ctx_release (ctx);
1543  BENCHMARK_END (eddsa_ecdh);
1544  return ret;
1545 }
1546 
1547 
1558 int
1560  const struct GNUNET_CRYPTO_EcdhePublicKey *pub,
1561  struct GNUNET_HashCode *key_material)
1562 {
1563  gcry_mpi_point_t result;
1564  gcry_mpi_point_t q;
1565  gcry_mpi_t d;
1566  gcry_ctx_t ctx;
1567  gcry_sexp_t pub_sexpr;
1568  int ret;
1569 
1570  BENCHMARK_START (ecdsa_ecdh);
1571 
1572  /* first, extract the q = dP value from the public key */
1573  if (0 != gcry_sexp_build (&pub_sexpr,
1574  NULL,
1575  "(public-key(ecc(curve " CURVE ")(q %b)))",
1576  (int) sizeof(pub->q_y),
1577  pub->q_y))
1578  return GNUNET_SYSERR;
1579  GNUNET_assert (0 == gcry_mpi_ec_new (&ctx, pub_sexpr, NULL));
1580  gcry_sexp_release (pub_sexpr);
1581  q = gcry_mpi_ec_get_point ("q", ctx, 0);
1582 
1583  /* second, extract the d value from our private key */
1584  GNUNET_CRYPTO_mpi_scan_unsigned (&d, priv->d, sizeof(priv->d));
1585 
1586  /* then call the 'multiply' function, to compute the product */
1587  result = gcry_mpi_point_new (0);
1588  gcry_mpi_ec_mul (result, d, q, ctx);
1589  gcry_mpi_point_release (q);
1590  gcry_mpi_release (d);
1591 
1592  /* finally, convert point to string for hashing */
1593  ret = point_to_hash (result, ctx, key_material);
1594  gcry_mpi_point_release (result);
1595  gcry_ctx_release (ctx);
1596  BENCHMARK_END (ecdsa_ecdh);
1597  return ret;
1598 }
1599 
1600 
1611 int
1613  const struct GNUNET_CRYPTO_EddsaPublicKey *pub,
1614  struct GNUNET_HashCode *key_material)
1615 {
1616  gcry_mpi_point_t result;
1617  gcry_mpi_point_t q;
1618  gcry_mpi_t d;
1619  gcry_ctx_t ctx;
1620  gcry_sexp_t pub_sexpr;
1621  int ret;
1622 
1623  BENCHMARK_START (ecdh_eddsa);
1624 
1625  /* first, extract the q = dP value from the public key */
1626  if (0 != gcry_sexp_build (&pub_sexpr,
1627  NULL,
1628  "(public-key(ecc(curve " CURVE ")(q %b)))",
1629  (int) sizeof(pub->q_y),
1630  pub->q_y))
1631  return GNUNET_SYSERR;
1632  GNUNET_assert (0 == gcry_mpi_ec_new (&ctx, pub_sexpr, NULL));
1633  gcry_sexp_release (pub_sexpr);
1634  q = gcry_mpi_ec_get_point ("q", ctx, 0);
1635 
1636  /* second, extract the d value from our private key */
1637  GNUNET_CRYPTO_mpi_scan_unsigned (&d, priv->d, sizeof(priv->d));
1638 
1639  /* then call the 'multiply' function, to compute the product */
1640  result = gcry_mpi_point_new (0);
1641  gcry_mpi_ec_mul (result, d, q, ctx);
1642  gcry_mpi_point_release (q);
1643  gcry_mpi_release (d);
1644 
1645  /* finally, convert point to string for hashing */
1646  ret = point_to_hash (result, ctx, key_material);
1647  gcry_mpi_point_release (result);
1648  gcry_ctx_release (ctx);
1649  BENCHMARK_END (ecdh_eddsa);
1650  return ret;
1651 }
1652 
1653 
1664 int
1666  const struct GNUNET_CRYPTO_EcdsaPublicKey *pub,
1667  struct GNUNET_HashCode *key_material)
1668 {
1669  return GNUNET_CRYPTO_ecdh_eddsa (priv,
1670  (const struct GNUNET_CRYPTO_EddsaPublicKey *)
1671  pub,
1672  key_material);
1673 }
1674 
1675 
1676 /* end of crypto_ecc.c */
int GNUNET_CRYPTO_ecdhe_key_create2(struct GNUNET_CRYPTO_EcdhePrivateKey *pk)
Create a new private key.
Definition: crypto_ecc.c:630
int 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:1559
int 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:532
unsigned char d[256/8]
d is a value mod n, where n has at most 256 bits.
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:812
unsigned char q_y[256/8]
Q consists of an x- and a y-value, each mod p (256 bits), given here in affine coordinates and Ed2551...
void GNUNET_CRYPTO_ecdsa_public_key_derive(const struct GNUNET_CRYPTO_EcdsaPublicKey *pub, const char *label, const char *context, struct GNUNET_CRYPTO_EcdsaPublicKey *result)
Derive a public key from a given public key and a label.
Definition: crypto_ecc.c:1337
static struct GNUNET_CRYPTO_EddsaPrivateKey * pk
Private key of this peer.
static int end
Set if we are to shutdown all services (including ARM).
Definition: gnunet-arm.c:34
int 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:1665
int 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 signature.
Definition: crypto_ecc.c:1045
unsigned char r[256/8]
R value.
#define BENCHMARK_START(opname)
Definition: benchmark.h:57
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:365
uint32_t purpose
What does this signature vouch for? This must contain a GNUNET_SIGNATURE_PURPOSE_XXX constant (from g...
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:570
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:583
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
unsigned char s[256/8]
S value.
struct GNUNET_CRYPTO_EcdsaPrivateKey * GNUNET_CRYPTO_ecdsa_key_create()
Create a new private key.
Definition: crypto_ecc.c:688
#define BENCHMARK_END(opname)
Definition: benchmark.h:58
int GNUNET_CRYPTO_eddsa_sign(const struct GNUNET_CRYPTO_EddsaPrivateKey *priv, const struct GNUNET_CRYPTO_EccSignaturePurpose *purpose, struct GNUNET_CRYPTO_EddsaSignature *sig)
Sign a given block.
Definition: crypto_ecc.c:986
unsigned char r[256/8]
R value.
unsigned char q_y[256/8]
Q consists of an x- and a y-value, each mod p (256 bits), given here in affine coordinates and Ed2551...
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:78
int 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 ECDHE key.
Definition: crypto_ecc.c:1182
static int ret
Return value of the commandline.
Definition: gnunet-abd.c:81
struct GNUNET_CRYPTO_EcdhePrivateKey * GNUNET_CRYPTO_ecdhe_key_create()
Create a new private key.
Definition: crypto_ecc.c:608
static int point_to_hash(gcry_mpi_point_t result, gcry_ctx_t ctx, struct GNUNET_HashCode *key_material)
Take point from ECDH and convert it to key material.
Definition: crypto_ecc.c:1461
static gcry_sexp_t decode_private_ecdhe_key(const struct GNUNET_CRYPTO_EcdhePrivateKey *priv)
Convert the given private key from the network format to the S-expression that can be used by libgcry...
Definition: crypto_ecc.c:205
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:75
#define GNUNET_new(type)
Allocate a struct or union of the given type.
Private ECC key encoded for transmission.
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur...
static struct GNUNET_ARM_Handle * h
Connection with ARM.
Definition: gnunet-arm.c:99
static struct GNUNET_DNSSTUB_Context * ctx
Context for DNS resolution.
static pa_context * context
Pulseaudio context.
#define _(String)
GNU gettext support macro.
Definition: platform.h:181
header of what an ECC signature signs this must be followed by "size - 8" bytes of the actual signed ...
int GNUNET_CRYPTO_ecdsa_sign(const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv, const struct GNUNET_CRYPTO_EccSignaturePurpose *purpose, struct GNUNET_CRYPTO_EcdsaSignature *sig)
Sign a given block.
Definition: crypto_ecc.c:928
cryptographic primitives for GNUnet
struct GNUNET_CRYPTO_EddsaPrivateKey * GNUNET_CRYPTO_eddsa_key_create()
Create a new private key.
Definition: crypto_ecc.c:744
int 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 signature.
Definition: crypto_ecc.c:1113
int 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:1502
void GNUNET_CRYPTO_hash(const void *block, size_t size, struct GNUNET_HashCode *ret)
Compute hash of a given block.
Definition: crypto_hash.c:48
unsigned char d[256/8]
d is a value mod n, where n has at most 256 bits.
static int once
Global to mark if we&#39;ve run the initialization.
Definition: gnsrecord.c:68
an ECC signature using ECDSA
static int result
Global testing status.
#define LOG(kind,...)
Definition: crypto_ecc.c:42
uint32_t size
How many bytes does this signature sign? (including this purpose header); in network byte order (!)...
A 512-bit hashcode.
static gcry_mpi_t eddsa_d_to_a(gcry_mpi_t d)
Convert the secret d of an EdDSA key to the value that is actually used in the EdDSA computation...
Definition: crypto_ecc.c:1416
int 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:1612
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:398
static void reverse_buffer(unsigned char *buffer, size_t length)
Reverse the sequence of the bytes in buffer.
Definition: crypto_ecc.c:1394
static struct GNUNET_REVOCATION_Query * q
Handle for revocation query.
void GNUNET_CRYPTO_mpi_scan_unsigned(gcry_mpi_t *result, const void *data, size_t size)
Convert data buffer into MPI value.
Definition: crypto_mpi.c:131
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:332
Private ECC key encoded for transmission.
#define GNUNET_SYSERR
Definition: gnunet_common.h:76
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:239
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:301
#define LOG_GCRY(level, cmd, rc)
Log an error message at log-level &#39;level&#39; that indicates a failure of the command &#39;cmd&#39; with the mess...
Definition: crypto_ecc.c:55
unsigned char q_y[256/8]
Point Q consists of a y-value mod p (256 bits); the x-value is always positive.
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:883
an ECC signature using EdDSA.
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:270
Private ECC key encoded for transmission.
static gcry_sexp_t decode_private_eddsa_key(const struct GNUNET_CRYPTO_EddsaPrivateKey *priv)
Convert the given private key from the network format to the S-expression that can be used by libgcry...
Definition: crypto_ecc.c:170
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:596
static struct GNUNET_CRYPTO_EddsaPublicKey pub
Definition: gnunet-scrypt.c:39
Public ECC key (always for Curve25519) encoded in a format suitable for network transmission and ECDS...
static OpusEncoder * enc
OPUS encoder.
Public ECC key (always for Curve25519) encoded in a format suitable for network transmission and encr...
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:431
unsigned char s[256/8]
S value.
static gcry_mpi_t derive_h(const struct GNUNET_CRYPTO_EcdsaPublicKey *pub, const char *label, const char *context)
Derive the &#39;h&#39; value for key derivation, where &#39;h = H(l,P)&#39;.
Definition: crypto_ecc.c:1255
#define CURVE
Name of the curve we are using.
Definition: crypto_ecc.c:40
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:77
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:135
benchmarking for various operations
static gcry_sexp_t data_to_eddsa_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:839
struct GNUNET_CRYPTO_EcdsaPrivateKey * GNUNET_CRYPTO_ecdsa_private_key_derive(const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv, const char *label, const char *context)
Derive a private key from a given private key and a label.
Definition: crypto_ecc.c:1293
uint32_t data
The data value.
int 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:499
int GNUNET_CRYPTO_kdf(void *result, size_t out_len, const void *xts, size_t xts_len, const void *skm, size_t skm_len,...)
Derive key.
Definition: crypto_kdf.c:89
static int list
Set if we should print a list of currently running services.
Definition: gnunet-arm.c:69
#define GNUNET_malloc(size)
Wrapper around malloc.
int 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:952
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:856
#define GNUNET_free(ptr)
Wrapper around free.
int 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:466
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...