GNUnet  0.10.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  const char *s;
85  unsigned int i;
86  unsigned int idx;
87 
88  list = gcry_sexp_find_token (sexp, topname, 0);
89  if (! list)
90  return 1;
91  l2 = gcry_sexp_cadr (list);
92  gcry_sexp_release (list);
93  list = l2;
94  if (! list)
95  return 2;
96 
97  idx = 0;
98  for (s = elems; *s; s++, idx++)
99  {
100  l2 = gcry_sexp_find_token (list, s, 1);
101  if (! l2)
102  {
103  for (i = 0; i < idx; i++)
104  {
105  gcry_free (array[i]);
106  array[i] = NULL;
107  }
108  gcry_sexp_release (list);
109  return 3; /* required parameter not found */
110  }
111  array[idx] = gcry_sexp_nth_mpi (l2, 1, GCRYMPI_FMT_USG);
112  gcry_sexp_release (l2);
113  if (! array[idx])
114  {
115  for (i = 0; i < idx; i++)
116  {
117  gcry_free (array[i]);
118  array[i] = NULL;
119  }
120  gcry_sexp_release (list);
121  return 4; /* required parameter is invalid */
122  }
123  }
124  gcry_sexp_release (list);
125  return 0;
126 }
127 
128 
136 static gcry_sexp_t
138 {
139  gcry_sexp_t result;
140  int rc;
141 
142  rc = gcry_sexp_build (&result,
143  NULL,
144  "(private-key(ecc(curve \"" CURVE "\")"
145  "(d %b)))",
146  (int) sizeof (priv->d),
147  priv->d);
148  if (0 != rc)
149  {
150  LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_sexp_build", rc);
151  GNUNET_assert (0);
152  }
153 #if EXTRA_CHECKS
154  if (0 != (rc = gcry_pk_testkey (result)))
155  {
156  LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_pk_testkey", rc);
157  GNUNET_assert (0);
158  }
159 #endif
160  return result;
161 }
162 
163 
171 static gcry_sexp_t
173 {
174  gcry_sexp_t result;
175  int rc;
176 
177  rc = gcry_sexp_build (&result,
178  NULL,
179  "(private-key(ecc(curve \"" CURVE "\")"
180  "(flags eddsa)(d %b)))",
181  (int) sizeof (priv->d),
182  priv->d);
183  if (0 != rc)
184  {
185  LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_sexp_build", rc);
186  GNUNET_assert (0);
187  }
188 #if EXTRA_CHECKS
189  if (0 != (rc = gcry_pk_testkey (result)))
190  {
191  LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_pk_testkey", rc);
192  GNUNET_assert (0);
193  }
194 #endif
195  return result;
196 }
197 
198 
206 static gcry_sexp_t
208 {
209  gcry_sexp_t result;
210  int rc;
211 
212  rc = gcry_sexp_build (&result,
213  NULL,
214  "(private-key(ecc(curve \"" CURVE "\")"
215  "(d %b)))",
216  (int) sizeof (priv->d),
217  priv->d);
218  if (0 != rc)
219  {
220  LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_sexp_build", rc);
221  GNUNET_assert (0);
222  }
223 #if EXTRA_CHECKS
224  if (0 != (rc = gcry_pk_testkey (result)))
225  {
226  LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_pk_testkey", rc);
227  GNUNET_assert (0);
228  }
229 #endif
230  return result;
231 }
232 
233 
240 void
242  const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv,
244 {
245  gcry_sexp_t sexp;
246  gcry_ctx_t ctx;
247  gcry_mpi_t q;
248 
249  BENCHMARK_START (ecdsa_key_get_public);
250 
251  sexp = decode_private_ecdsa_key (priv);
252  GNUNET_assert (NULL != sexp);
253  GNUNET_assert (0 == gcry_mpi_ec_new (&ctx, sexp, NULL));
254  gcry_sexp_release (sexp);
255  q = gcry_mpi_ec_get_mpi ("q@eddsa", ctx, 0);
256  GNUNET_assert (NULL != q);
257  GNUNET_CRYPTO_mpi_print_unsigned (pub->q_y, sizeof (pub->q_y), q);
258  gcry_mpi_release (q);
259  gcry_ctx_release (ctx);
260 
261  BENCHMARK_END (ecdsa_key_get_public);
262 }
263 
264 
271 void
273  const struct GNUNET_CRYPTO_EddsaPrivateKey *priv,
275 {
276  gcry_sexp_t sexp;
277  gcry_ctx_t ctx;
278  gcry_mpi_t q;
279 
280  BENCHMARK_START (eddsa_key_get_public);
281 
282  sexp = decode_private_eddsa_key (priv);
283  GNUNET_assert (NULL != sexp);
284  GNUNET_assert (0 == gcry_mpi_ec_new (&ctx, sexp, NULL));
285  gcry_sexp_release (sexp);
286  q = gcry_mpi_ec_get_mpi ("q@eddsa", ctx, 0);
287  GNUNET_assert (q);
288  GNUNET_CRYPTO_mpi_print_unsigned (pub->q_y, sizeof (pub->q_y), q);
289  gcry_mpi_release (q);
290  gcry_ctx_release (ctx);
291 
292  BENCHMARK_END (eddsa_key_get_public);
293 }
294 
295 
302 void
304  const struct GNUNET_CRYPTO_EcdhePrivateKey *priv,
306 {
307  gcry_sexp_t sexp;
308  gcry_ctx_t ctx;
309  gcry_mpi_t q;
310 
311  BENCHMARK_START (ecdhe_key_get_public);
312 
313  sexp = decode_private_ecdhe_key (priv);
314  GNUNET_assert (NULL != sexp);
315  GNUNET_assert (0 == gcry_mpi_ec_new (&ctx, sexp, NULL));
316  gcry_sexp_release (sexp);
317  q = gcry_mpi_ec_get_mpi ("q@eddsa", ctx, 0);
318  GNUNET_assert (q);
319  GNUNET_CRYPTO_mpi_print_unsigned (pub->q_y, sizeof (pub->q_y), q);
320  gcry_mpi_release (q);
321  gcry_ctx_release (ctx);
322 
323  BENCHMARK_END (ecdhe_key_get_public);
324 }
325 
326 
333 char *
335  const struct GNUNET_CRYPTO_EcdsaPublicKey *pub)
336 {
337  char *pubkeybuf;
338  size_t keylen = (sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey)) * 8;
339  char *end;
340 
341  if (keylen % 5 > 0)
342  keylen += 5 - keylen % 5;
343  keylen /= 5;
344  pubkeybuf = GNUNET_malloc (keylen + 1);
345  end =
346  GNUNET_STRINGS_data_to_string ((unsigned char *) pub,
347  sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey),
348  pubkeybuf,
349  keylen);
350  if (NULL == end)
351  {
352  GNUNET_free (pubkeybuf);
353  return NULL;
354  }
355  *end = '\0';
356  return pubkeybuf;
357 }
358 
359 
366 char *
368  const struct GNUNET_CRYPTO_EddsaPublicKey *pub)
369 {
370  char *pubkeybuf;
371  size_t keylen = (sizeof (struct GNUNET_CRYPTO_EddsaPublicKey)) * 8;
372  char *end;
373 
374  if (keylen % 5 > 0)
375  keylen += 5 - keylen % 5;
376  keylen /= 5;
377  pubkeybuf = GNUNET_malloc (keylen + 1);
378  end =
379  GNUNET_STRINGS_data_to_string ((unsigned char *) pub,
380  sizeof (struct GNUNET_CRYPTO_EddsaPublicKey),
381  pubkeybuf,
382  keylen);
383  if (NULL == end)
384  {
385  GNUNET_free (pubkeybuf);
386  return NULL;
387  }
388  *end = '\0';
389  return pubkeybuf;
390 }
391 
392 
399 char *
401  const struct GNUNET_CRYPTO_EddsaPrivateKey *priv)
402 {
403  char *privkeybuf;
404  size_t keylen = (sizeof (struct GNUNET_CRYPTO_EddsaPrivateKey)) * 8;
405  char *end;
406 
407  if (keylen % 5 > 0)
408  keylen += 5 - keylen % 5;
409  keylen /= 5;
410  privkeybuf = GNUNET_malloc (keylen + 1);
411  end = GNUNET_STRINGS_data_to_string ((unsigned char *) priv,
412  sizeof (
414  privkeybuf,
415  keylen);
416  if (NULL == end)
417  {
418  GNUNET_free (privkeybuf);
419  return NULL;
420  }
421  *end = '\0';
422  return privkeybuf;
423 }
424 
425 
432 char *
434  const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv)
435 {
436  char *privkeybuf;
437  size_t keylen = (sizeof (struct GNUNET_CRYPTO_EcdsaPrivateKey)) * 8;
438  char *end;
439 
440  if (keylen % 5 > 0)
441  keylen += 5 - keylen % 5;
442  keylen /= 5;
443  privkeybuf = GNUNET_malloc (keylen + 1);
444  end = GNUNET_STRINGS_data_to_string ((unsigned char *) priv,
445  sizeof (
447  privkeybuf,
448  keylen);
449  if (NULL == end)
450  {
451  GNUNET_free (privkeybuf);
452  return NULL;
453  }
454  *end = '\0';
455  return privkeybuf;
456 }
457 
458 
467 int
469  const char *enc,
470  size_t enclen,
472 {
473  size_t keylen = (sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey)) * 8;
474 
475  if (keylen % 5 > 0)
476  keylen += 5 - keylen % 5;
477  keylen /= 5;
478  if (enclen != keylen)
479  return GNUNET_SYSERR;
480 
481  if (GNUNET_OK !=
483  enclen,
484  pub,
485  sizeof (
487  return GNUNET_SYSERR;
488  return GNUNET_OK;
489 }
490 
491 
500 int
502  const char *enc,
503  size_t enclen,
505 {
506  size_t keylen = (sizeof (struct GNUNET_CRYPTO_EddsaPublicKey)) * 8;
507 
508  if (keylen % 5 > 0)
509  keylen += 5 - keylen % 5;
510  keylen /= 5;
511  if (enclen != keylen)
512  return GNUNET_SYSERR;
513 
514  if (GNUNET_OK !=
516  enclen,
517  pub,
518  sizeof (
520  return GNUNET_SYSERR;
521  return GNUNET_OK;
522 }
523 
524 
533 int
535  const char *enc,
536  size_t enclen,
537  struct GNUNET_CRYPTO_EddsaPrivateKey *priv)
538 {
539  size_t keylen = (sizeof (struct GNUNET_CRYPTO_EddsaPrivateKey)) * 8;
540 
541  if (keylen % 5 > 0)
542  keylen += 5 - keylen % 5;
543  keylen /= 5;
544  if (enclen != keylen)
545  return GNUNET_SYSERR;
546 
547  if (GNUNET_OK !=
549  enclen,
550  priv,
551  sizeof (
553  return GNUNET_SYSERR;
554 #if CRYPTO_BUG
555  if (GNUNET_OK != check_eddsa_key (priv))
556  {
557  GNUNET_break (0);
558  return GNUNET_OK;
559  }
560 #endif
561  return GNUNET_OK;
562 }
563 
564 
571 void
573 {
574  memset (pk, 0, sizeof (struct GNUNET_CRYPTO_EcdhePrivateKey));
575 }
576 
577 
584 void
586 {
587  memset (pk, 0, sizeof (struct GNUNET_CRYPTO_EcdsaPrivateKey));
588 }
589 
590 
597 void
599 {
600  memset (pk, 0, sizeof (struct GNUNET_CRYPTO_EddsaPrivateKey));
601 }
602 
603 
611 {
612  struct GNUNET_CRYPTO_EcdhePrivateKey *priv;
613 
616  {
617  GNUNET_free (priv);
618  return NULL;
619  }
620  return priv;
621 }
622 
623 
631 int
633 {
634  gcry_sexp_t priv_sexp;
635  gcry_sexp_t s_keyparam;
636  gcry_mpi_t d;
637  int rc;
638 
639  BENCHMARK_START (ecdhe_key_create);
640 
641  /* NOTE: For libgcrypt >= 1.7, we do not need the 'eddsa' flag here,
642  but should also be harmless. For libgcrypt < 1.7, using 'eddsa'
643  disables an expensive key testing routine. We do not want to run
644  the expensive check for ECDHE, as we generate TONS of keys to
645  use for a very short time. */
646  if (0 != (rc = gcry_sexp_build (&s_keyparam,
647  NULL,
648  "(genkey(ecc(curve \"" CURVE "\")"
649  "(flags eddsa no-keytest)))")))
650  {
651  LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_sexp_build", rc);
652  return GNUNET_SYSERR;
653  }
654  if (0 != (rc = gcry_pk_genkey (&priv_sexp, s_keyparam)))
655  {
656  LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_pk_genkey", rc);
657  gcry_sexp_release (s_keyparam);
658  return GNUNET_SYSERR;
659  }
660  gcry_sexp_release (s_keyparam);
661 #if EXTRA_CHECKS
662  if (0 != (rc = gcry_pk_testkey (priv_sexp)))
663  {
664  LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_pk_testkey", rc);
665  gcry_sexp_release (priv_sexp);
666  return GNUNET_SYSERR;
667  }
668 #endif
669  if (0 != (rc = key_from_sexp (&d, priv_sexp, "private-key", "d")))
670  {
671  LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "key_from_sexp", rc);
672  gcry_sexp_release (priv_sexp);
673  return GNUNET_SYSERR;
674  }
675  gcry_sexp_release (priv_sexp);
676  GNUNET_CRYPTO_mpi_print_unsigned (pk->d, sizeof (pk->d), d);
677  gcry_mpi_release (d);
678 
679  BENCHMARK_END (ecdhe_key_create);
680 
681  return GNUNET_OK;
682 }
683 
684 
692 {
693  struct GNUNET_CRYPTO_EcdsaPrivateKey *priv;
694  gcry_sexp_t priv_sexp;
695  gcry_sexp_t s_keyparam;
696  gcry_mpi_t d;
697  int rc;
698 
699  BENCHMARK_START (ecdsa_key_create);
700 
701  if (0 != (rc = gcry_sexp_build (&s_keyparam,
702  NULL,
703  "(genkey(ecc(curve \"" CURVE "\")"
704  "(flags)))")))
705  {
706  LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_sexp_build", rc);
707  return NULL;
708  }
709  if (0 != (rc = gcry_pk_genkey (&priv_sexp, s_keyparam)))
710  {
711  LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_pk_genkey", rc);
712  gcry_sexp_release (s_keyparam);
713  return NULL;
714  }
715  gcry_sexp_release (s_keyparam);
716 #if EXTRA_CHECKS
717  if (0 != (rc = gcry_pk_testkey (priv_sexp)))
718  {
719  LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_pk_testkey", rc);
720  gcry_sexp_release (priv_sexp);
721  return NULL;
722  }
723 #endif
724  if (0 != (rc = key_from_sexp (&d, priv_sexp, "private-key", "d")))
725  {
726  LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "key_from_sexp", rc);
727  gcry_sexp_release (priv_sexp);
728  return NULL;
729  }
730  gcry_sexp_release (priv_sexp);
732  GNUNET_CRYPTO_mpi_print_unsigned (priv->d, sizeof (priv->d), d);
733  gcry_mpi_release (d);
734 
735  BENCHMARK_END (ecdsa_key_create);
736 
737  return priv;
738 }
739 
747 {
748  struct GNUNET_CRYPTO_EddsaPrivateKey *priv;
749  gcry_sexp_t priv_sexp;
750  gcry_sexp_t s_keyparam;
751  gcry_mpi_t d;
752  int rc;
753 
754  BENCHMARK_START (eddsa_key_create);
755 
756 #if CRYPTO_BUG
757 again:
758 #endif
759  if (0 != (rc = gcry_sexp_build (&s_keyparam,
760  NULL,
761  "(genkey(ecc(curve \"" CURVE "\")"
762  "(flags eddsa)))")))
763  {
764  LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_sexp_build", rc);
765  return NULL;
766  }
767  if (0 != (rc = gcry_pk_genkey (&priv_sexp, s_keyparam)))
768  {
769  LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_pk_genkey", rc);
770  gcry_sexp_release (s_keyparam);
771  return NULL;
772  }
773  gcry_sexp_release (s_keyparam);
774 #if EXTRA_CHECKS
775  if (0 != (rc = gcry_pk_testkey (priv_sexp)))
776  {
777  LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_pk_testkey", rc);
778  gcry_sexp_release (priv_sexp);
779  return NULL;
780  }
781 #endif
782  if (0 != (rc = key_from_sexp (&d, priv_sexp, "private-key", "d")))
783  {
784  LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "key_from_sexp", rc);
785  gcry_sexp_release (priv_sexp);
786  return NULL;
787  }
788  gcry_sexp_release (priv_sexp);
790  GNUNET_CRYPTO_mpi_print_unsigned (priv->d, sizeof (priv->d), d);
791  gcry_mpi_release (d);
792 
793 #if CRYPTO_BUG
794  if (GNUNET_OK != check_eddsa_key (priv))
795  {
796  GNUNET_break (0);
797  GNUNET_free (priv);
798  goto again;
799  }
800 #endif
801 
802  BENCHMARK_END (eddsa_key_create);
803 
804  return priv;
805 }
806 
807 
813 const struct GNUNET_CRYPTO_EcdsaPrivateKey *
815 {
820  static struct GNUNET_CRYPTO_EcdsaPrivateKey anonymous;
821  static int once;
822 
823  if (once)
824  return &anonymous;
826  sizeof (anonymous.d),
827  GCRYMPI_CONST_ONE);
828  once = 1;
829  return &anonymous;
830 }
831 
832 
840 static gcry_sexp_t
842 {
843  gcry_sexp_t data;
844  int rc;
845 
846 /* SEE #5398 */
847 #if 1
848  struct GNUNET_HashCode hc;
849 
850  GNUNET_CRYPTO_hash (purpose, ntohl (purpose->size), &hc);
851  if (0 != (rc = gcry_sexp_build (&data,
852  NULL,
853  "(data(flags eddsa)(hash-algo %s)(value %b))",
854  "sha512",
855  (int) sizeof (hc),
856  &hc)))
857  {
858  LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_sexp_build", rc);
859  return NULL;
860  }
861 #else
862  GNUNET_CRYPTO_hash (purpose, ntohl (purpose->size), &hc);
863  if (0 != (rc = gcry_sexp_build (&data,
864  NULL,
865  "(data(flags eddsa)(hash-algo %s)(value %b))",
866  "sha512",
867  ntohl (purpose->size),
868  purpose)))
869  {
870  LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_sexp_build", rc);
871  return NULL;
872  }
873 #endif
874  return data;
875 }
876 
877 
885 static gcry_sexp_t
887 {
888  gcry_sexp_t data;
889  int rc;
890 
891 /* See #5398 */
892 #if 1
893  struct GNUNET_HashCode hc;
894 
895  GNUNET_CRYPTO_hash (purpose, ntohl (purpose->size), &hc);
896  if (0 != (rc = gcry_sexp_build (&data,
897  NULL,
898  "(data(flags rfc6979)(hash %s %b))",
899  "sha512",
900  (int) sizeof (hc),
901  &hc)))
902  {
903  LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_sexp_build", rc);
904  return NULL;
905  }
906 #else
907  if (0 != (rc = gcry_sexp_build (&data,
908  NULL,
909  "(data(flags rfc6979)(hash %s %b))",
910  "sha512",
911  ntohl (purpose->size),
912  purpose)))
913  {
914  LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_sexp_build", rc);
915  return NULL;
916  }
917 #endif
918  return data;
919 }
920 
921 
930 int
932  const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv,
933  const struct GNUNET_CRYPTO_EccSignaturePurpose *purpose,
934  struct GNUNET_CRYPTO_EcdsaSignature *sig)
935 {
936  gcry_sexp_t priv_sexp;
937  gcry_sexp_t sig_sexp;
938  gcry_sexp_t data;
939  int rc;
940  gcry_mpi_t rs[2];
941 
942  BENCHMARK_START (ecdsa_sign);
943 
944  priv_sexp = decode_private_ecdsa_key (priv);
945  data = data_to_ecdsa_value (purpose);
946  if (0 != (rc = gcry_pk_sign (&sig_sexp, data, priv_sexp)))
947  {
949  _ ("ECC signing failed at %s:%d: %s\n"),
950  __FILE__,
951  __LINE__,
952  gcry_strerror (rc));
953  gcry_sexp_release (data);
954  gcry_sexp_release (priv_sexp);
955  return GNUNET_SYSERR;
956  }
957  gcry_sexp_release (priv_sexp);
958  gcry_sexp_release (data);
959 
960  /* extract 'r' and 's' values from sexpression 'sig_sexp' and store in
961  'signature' */
962  if (0 != (rc = key_from_sexp (rs, sig_sexp, "sig-val", "rs")))
963  {
964  GNUNET_break (0);
965  gcry_sexp_release (sig_sexp);
966  return GNUNET_SYSERR;
967  }
968  gcry_sexp_release (sig_sexp);
969  GNUNET_CRYPTO_mpi_print_unsigned (sig->r, sizeof (sig->r), rs[0]);
970  GNUNET_CRYPTO_mpi_print_unsigned (sig->s, sizeof (sig->s), rs[1]);
971  gcry_mpi_release (rs[0]);
972  gcry_mpi_release (rs[1]);
973 
974  BENCHMARK_END (ecdsa_sign);
975 
976  return GNUNET_OK;
977 }
978 
979 
988 int
990  const struct GNUNET_CRYPTO_EddsaPrivateKey *priv,
991  const struct GNUNET_CRYPTO_EccSignaturePurpose *purpose,
992  struct GNUNET_CRYPTO_EddsaSignature *sig)
993 {
994  gcry_sexp_t priv_sexp;
995  gcry_sexp_t sig_sexp;
996  gcry_sexp_t data;
997  int rc;
998  gcry_mpi_t rs[2];
999 
1000  BENCHMARK_START (eddsa_sign);
1001 
1002  priv_sexp = decode_private_eddsa_key (priv);
1003  data = data_to_eddsa_value (purpose);
1004  if (0 != (rc = gcry_pk_sign (&sig_sexp, data, priv_sexp)))
1005  {
1007  _ ("EdDSA signing failed at %s:%d: %s\n"),
1008  __FILE__,
1009  __LINE__,
1010  gcry_strerror (rc));
1011  gcry_sexp_release (data);
1012  gcry_sexp_release (priv_sexp);
1013  return GNUNET_SYSERR;
1014  }
1015  gcry_sexp_release (priv_sexp);
1016  gcry_sexp_release (data);
1017 
1018  /* extract 'r' and 's' values from sexpression 'sig_sexp' and store in
1019  'signature' */
1020  if (0 != (rc = key_from_sexp (rs, sig_sexp, "sig-val", "rs")))
1021  {
1022  GNUNET_break (0);
1023  gcry_sexp_release (sig_sexp);
1024  return GNUNET_SYSERR;
1025  }
1026  gcry_sexp_release (sig_sexp);
1027  GNUNET_CRYPTO_mpi_print_unsigned (sig->r, sizeof (sig->r), rs[0]);
1028  GNUNET_CRYPTO_mpi_print_unsigned (sig->s, sizeof (sig->s), rs[1]);
1029  gcry_mpi_release (rs[0]);
1030  gcry_mpi_release (rs[1]);
1031 
1032  BENCHMARK_END (eddsa_sign);
1033 
1034  return GNUNET_OK;
1035 }
1036 
1037 
1047 int
1049  uint32_t purpose,
1050  const struct GNUNET_CRYPTO_EccSignaturePurpose *validate,
1051  const struct GNUNET_CRYPTO_EcdsaSignature *sig,
1052  const struct GNUNET_CRYPTO_EcdsaPublicKey *pub)
1053 {
1054  gcry_sexp_t data;
1055  gcry_sexp_t sig_sexpr;
1056  gcry_sexp_t pub_sexpr;
1057  int rc;
1058 
1059  BENCHMARK_START (ecdsa_verify);
1060 
1061  if (purpose != ntohl (validate->purpose))
1062  return GNUNET_SYSERR; /* purpose mismatch */
1063 
1064  /* build s-expression for signature */
1065  if (0 != (rc = gcry_sexp_build (&sig_sexpr,
1066  NULL,
1067  "(sig-val(ecdsa(r %b)(s %b)))",
1068  (int) sizeof (sig->r),
1069  sig->r,
1070  (int) sizeof (sig->s),
1071  sig->s)))
1072  {
1073  LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_sexp_build", rc);
1074  return GNUNET_SYSERR;
1075  }
1076  data = data_to_ecdsa_value (validate);
1077  if (0 != (rc = gcry_sexp_build (&pub_sexpr,
1078  NULL,
1079  "(public-key(ecc(curve " CURVE ")(q %b)))",
1080  (int) sizeof (pub->q_y),
1081  pub->q_y)))
1082  {
1083  gcry_sexp_release (data);
1084  gcry_sexp_release (sig_sexpr);
1085  return GNUNET_SYSERR;
1086  }
1087  rc = gcry_pk_verify (sig_sexpr, data, pub_sexpr);
1088  gcry_sexp_release (pub_sexpr);
1089  gcry_sexp_release (data);
1090  gcry_sexp_release (sig_sexpr);
1091  if (0 != rc)
1092  {
1094  _ ("ECDSA signature verification failed at %s:%d: %s\n"),
1095  __FILE__,
1096  __LINE__,
1097  gcry_strerror (rc));
1098  BENCHMARK_END (ecdsa_verify);
1099  return GNUNET_SYSERR;
1100  }
1101  BENCHMARK_END (ecdsa_verify);
1102  return GNUNET_OK;
1103 }
1104 
1105 
1115 int
1117  uint32_t purpose,
1118  const struct GNUNET_CRYPTO_EccSignaturePurpose *validate,
1119  const struct GNUNET_CRYPTO_EddsaSignature *sig,
1120  const struct GNUNET_CRYPTO_EddsaPublicKey *pub)
1121 {
1122  gcry_sexp_t data;
1123  gcry_sexp_t sig_sexpr;
1124  gcry_sexp_t pub_sexpr;
1125  int rc;
1126 
1127  BENCHMARK_START (eddsa_verify);
1128 
1129  if (purpose != ntohl (validate->purpose))
1130  return GNUNET_SYSERR; /* purpose mismatch */
1131 
1132  /* build s-expression for signature */
1133  if (0 != (rc = gcry_sexp_build (&sig_sexpr,
1134  NULL,
1135  "(sig-val(eddsa(r %b)(s %b)))",
1136  (int) sizeof (sig->r),
1137  sig->r,
1138  (int) sizeof (sig->s),
1139  sig->s)))
1140  {
1141  LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_sexp_build", rc);
1142  return GNUNET_SYSERR;
1143  }
1144  data = data_to_eddsa_value (validate);
1145  if (0 != (rc = gcry_sexp_build (&pub_sexpr,
1146  NULL,
1147  "(public-key(ecc(curve " CURVE
1148  ")(flags eddsa)(q %b)))",
1149  (int) sizeof (pub->q_y),
1150  pub->q_y)))
1151  {
1152  gcry_sexp_release (data);
1153  gcry_sexp_release (sig_sexpr);
1154  return GNUNET_SYSERR;
1155  }
1156  rc = gcry_pk_verify (sig_sexpr, data, pub_sexpr);
1157  gcry_sexp_release (pub_sexpr);
1158  gcry_sexp_release (data);
1159  gcry_sexp_release (sig_sexpr);
1160  if (0 != rc)
1161  {
1163  _ ("EdDSA signature verification failed at %s:%d: %s\n"),
1164  __FILE__,
1165  __LINE__,
1166  gcry_strerror (rc));
1167  BENCHMARK_END (eddsa_verify);
1168  return GNUNET_SYSERR;
1169  }
1170  BENCHMARK_END (eddsa_verify);
1171  return GNUNET_OK;
1172 }
1173 
1174 
1183 int
1185  const struct GNUNET_CRYPTO_EcdhePublicKey *pub,
1186  struct GNUNET_HashCode *key_material)
1187 {
1188  gcry_mpi_point_t result;
1189  gcry_mpi_point_t q;
1190  gcry_mpi_t d;
1191  gcry_ctx_t ctx;
1192  gcry_sexp_t pub_sexpr;
1193  gcry_mpi_t result_x;
1194  unsigned char xbuf[256 / 8];
1195  size_t rsize;
1196 
1197  BENCHMARK_START (ecc_ecdh);
1198 
1199  /* first, extract the q = dP value from the public key */
1200  if (0 != gcry_sexp_build (&pub_sexpr,
1201  NULL,
1202  "(public-key(ecc(curve " CURVE ")(q %b)))",
1203  (int) sizeof (pub->q_y),
1204  pub->q_y))
1205  return GNUNET_SYSERR;
1206  GNUNET_assert (0 == gcry_mpi_ec_new (&ctx, pub_sexpr, NULL));
1207  gcry_sexp_release (pub_sexpr);
1208  q = gcry_mpi_ec_get_point ("q", ctx, 0);
1209 
1210  /* second, extract the d value from our private key */
1211  GNUNET_CRYPTO_mpi_scan_unsigned (&d, priv->d, sizeof (priv->d));
1212 
1213  /* then call the 'multiply' function, to compute the product */
1214  result = gcry_mpi_point_new (0);
1215  gcry_mpi_ec_mul (result, d, q, ctx);
1216  gcry_mpi_point_release (q);
1217  gcry_mpi_release (d);
1218 
1219  /* finally, convert point to string for hashing */
1220  result_x = gcry_mpi_new (256);
1221  if (gcry_mpi_ec_get_affine (result_x, NULL, result, ctx))
1222  {
1223  LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "get_affine failed", 0);
1224  gcry_mpi_point_release (result);
1225  gcry_ctx_release (ctx);
1226  return GNUNET_SYSERR;
1227  }
1228  gcry_mpi_point_release (result);
1229  gcry_ctx_release (ctx);
1230 
1231  rsize = sizeof (xbuf);
1232  GNUNET_assert (! gcry_mpi_get_flag (result_x, GCRYMPI_FLAG_OPAQUE));
1233  /* result_x can be negative here, so we do not use 'GNUNET_CRYPTO_mpi_print_unsigned'
1234  as that does not include the sign bit; x should be a 255-bit
1235  value, so with the sign it should fit snugly into the 256-bit
1236  xbuf */
1237  GNUNET_assert (
1238  0 == gcry_mpi_print (GCRYMPI_FMT_STD, xbuf, rsize, &rsize, result_x));
1239  GNUNET_CRYPTO_hash (xbuf, rsize, key_material);
1240  gcry_mpi_release (result_x);
1241  BENCHMARK_END (ecc_ecdh);
1242  return GNUNET_OK;
1243 }
1244 
1245 
1256 static gcry_mpi_t
1258  const char *label,
1259  const char *context)
1260 {
1261  gcry_mpi_t h;
1262  struct GNUNET_HashCode hc;
1263  static const char *const salt = "key-derivation";
1264 
1265  GNUNET_CRYPTO_kdf (&hc,
1266  sizeof (hc),
1267  salt,
1268  strlen (salt),
1269  pub,
1270  sizeof (*pub),
1271  label,
1272  strlen (label),
1273  context,
1274  strlen (context),
1275  NULL,
1276  0);
1277  GNUNET_CRYPTO_mpi_scan_unsigned (&h, (unsigned char *) &hc, sizeof (hc));
1278  return h;
1279 }
1280 
1281 
1296  const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv,
1297  const char *label,
1298  const char *context)
1299 {
1300  struct GNUNET_CRYPTO_EcdsaPublicKey pub;
1302  gcry_mpi_t h;
1303  gcry_mpi_t x;
1304  gcry_mpi_t d;
1305  gcry_mpi_t n;
1306  gcry_ctx_t ctx;
1307 
1308  GNUNET_assert (0 == gcry_mpi_ec_new (&ctx, NULL, CURVE));
1309 
1310  n = gcry_mpi_ec_get_mpi ("n", ctx, 1);
1312 
1313  h = derive_h (&pub, label, context);
1314  GNUNET_CRYPTO_mpi_scan_unsigned (&x, priv->d, sizeof (priv->d));
1315  d = gcry_mpi_new (256);
1316  gcry_mpi_mulm (d, h, x, n);
1317  gcry_mpi_release (h);
1318  gcry_mpi_release (x);
1319  gcry_mpi_release (n);
1320  gcry_ctx_release (ctx);
1322  GNUNET_CRYPTO_mpi_print_unsigned (ret->d, sizeof (ret->d), d);
1323  gcry_mpi_release (d);
1324  return ret;
1325 }
1326 
1327 
1338 void
1340  const struct GNUNET_CRYPTO_EcdsaPublicKey *pub,
1341  const char *label,
1342  const char *context,
1344 {
1345  gcry_ctx_t ctx;
1346  gcry_mpi_t q_y;
1347  gcry_mpi_t h;
1348  gcry_mpi_t n;
1349  gcry_mpi_t h_mod_n;
1350  gcry_mpi_point_t q;
1351  gcry_mpi_point_t v;
1352 
1353  GNUNET_assert (0 == gcry_mpi_ec_new (&ctx, NULL, CURVE));
1354 
1355  /* obtain point 'q' from original public key. The provided 'q' is
1356  compressed thus we first store it in the context and then get it
1357  back as a (decompresssed) point. */
1358  q_y = gcry_mpi_set_opaque_copy (NULL, pub->q_y, 8 * sizeof (pub->q_y));
1359  GNUNET_assert (NULL != q_y);
1360  GNUNET_assert (0 == gcry_mpi_ec_set_mpi ("q", q_y, ctx));
1361  gcry_mpi_release (q_y);
1362  q = gcry_mpi_ec_get_point ("q", ctx, 0);
1363  GNUNET_assert (q);
1364 
1365  /* calculate h_mod_n = h % n */
1366  h = derive_h (pub, label, context);
1367  n = gcry_mpi_ec_get_mpi ("n", ctx, 1);
1368  h_mod_n = gcry_mpi_new (256);
1369  gcry_mpi_mod (h_mod_n, h, n);
1370  /* calculate v = h_mod_n * q */
1371  v = gcry_mpi_point_new (0);
1372  gcry_mpi_ec_mul (v, h_mod_n, q, ctx);
1373  gcry_mpi_release (h_mod_n);
1374  gcry_mpi_release (h);
1375  gcry_mpi_release (n);
1376  gcry_mpi_point_release (q);
1377 
1378  /* convert point 'v' to public key that we return */
1379  GNUNET_assert (0 == gcry_mpi_ec_set_point ("q", v, ctx));
1380  gcry_mpi_point_release (v);
1381  q_y = gcry_mpi_ec_get_mpi ("q@eddsa", ctx, 0);
1382  GNUNET_assert (q_y);
1383  GNUNET_CRYPTO_mpi_print_unsigned (result->q_y, sizeof (result->q_y), q_y);
1384  gcry_mpi_release (q_y);
1385  gcry_ctx_release (ctx);
1386 }
1387 
1388 
1395 static void
1396 reverse_buffer (unsigned char *buffer, size_t length)
1397 {
1398  unsigned char tmp;
1399  size_t i;
1400 
1401  for (i = 0; i < length / 2; i++)
1402  {
1403  tmp = buffer[i];
1404  buffer[i] = buffer[length - 1 - i];
1405  buffer[length - 1 - i] = tmp;
1406  }
1407 }
1408 
1409 
1417 static gcry_mpi_t
1418 eddsa_d_to_a (gcry_mpi_t d)
1419 {
1420  unsigned char rawmpi[32]; /* 256-bit value */
1421  size_t rawmpilen;
1422  unsigned char digest[64]; /* 512-bit hash value */
1423  gcry_buffer_t hvec[2];
1424  unsigned int b;
1425  gcry_mpi_t a;
1426 
1427  b = 256 / 8; /* number of bytes in `d` */
1428 
1429  /* Note that we clear DIGEST so we can use it as input to left pad
1430  the key with zeroes for hashing. */
1431  memset (digest, 0, sizeof digest);
1432  memset (hvec, 0, sizeof hvec);
1433  rawmpilen = sizeof (rawmpi);
1434  GNUNET_assert (
1435  0 == gcry_mpi_print (GCRYMPI_FMT_USG, rawmpi, rawmpilen, &rawmpilen, d));
1436  hvec[0].data = digest;
1437  hvec[0].off = 0;
1438  hvec[0].len = b > rawmpilen ? (b - rawmpilen) : 0;
1439  hvec[1].data = rawmpi;
1440  hvec[1].off = 0;
1441  hvec[1].len = rawmpilen;
1442  GNUNET_assert (
1443  0 == gcry_md_hash_buffers (GCRY_MD_SHA512, 0 /* flags */, digest, hvec, 2));
1444  /* Compute the A value. */
1445  reverse_buffer (digest, 32); /* Only the first half of the hash. */
1446  digest[0] = (digest[0] & 0x7f) | 0x40;
1447  digest[31] &= 0xf8;
1448 
1449  GNUNET_CRYPTO_mpi_scan_unsigned (&a, digest, 32);
1450  return a;
1451 }
1452 
1453 
1462 static int
1463 point_to_hash (gcry_mpi_point_t result,
1464  gcry_ctx_t ctx,
1465  struct GNUNET_HashCode *key_material)
1466 {
1467  gcry_mpi_t result_x;
1468  unsigned char xbuf[256 / 8];
1469  size_t rsize;
1470 
1471  /* finally, convert point to string for hashing */
1472  result_x = gcry_mpi_new (256);
1473  if (gcry_mpi_ec_get_affine (result_x, NULL, result, ctx))
1474  {
1475  LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "get_affine failed", 0);
1476  return GNUNET_SYSERR;
1477  }
1478 
1479  rsize = sizeof (xbuf);
1480  GNUNET_assert (! gcry_mpi_get_flag (result_x, GCRYMPI_FLAG_OPAQUE));
1481  /* result_x can be negative here, so we do not use 'GNUNET_CRYPTO_mpi_print_unsigned'
1482  as that does not include the sign bit; x should be a 255-bit
1483  value, so with the sign it should fit snugly into the 256-bit
1484  xbuf */
1485  GNUNET_assert (
1486  0 == gcry_mpi_print (GCRYMPI_FMT_STD, xbuf, rsize, &rsize, result_x));
1487  GNUNET_CRYPTO_hash (xbuf, rsize, key_material);
1488  gcry_mpi_release (result_x);
1489  return GNUNET_OK;
1490 }
1491 
1492 
1503 int
1505  const struct GNUNET_CRYPTO_EcdhePublicKey *pub,
1506  struct GNUNET_HashCode *key_material)
1507 {
1508  gcry_mpi_point_t result;
1509  gcry_mpi_point_t q;
1510  gcry_mpi_t d;
1511  gcry_mpi_t a;
1512  gcry_ctx_t ctx;
1513  gcry_sexp_t pub_sexpr;
1514  int ret;
1515 
1516  BENCHMARK_START (eddsa_ecdh);
1517 
1518  /* first, extract the q = dP value from the public key */
1519  if (0 != gcry_sexp_build (&pub_sexpr,
1520  NULL,
1521  "(public-key(ecc(curve " CURVE ")(q %b)))",
1522  (int) sizeof (pub->q_y),
1523  pub->q_y))
1524  return GNUNET_SYSERR;
1525  GNUNET_assert (0 == gcry_mpi_ec_new (&ctx, pub_sexpr, NULL));
1526  gcry_sexp_release (pub_sexpr);
1527  q = gcry_mpi_ec_get_point ("q", ctx, 0);
1528 
1529  /* second, extract the d value from our private key */
1530  GNUNET_CRYPTO_mpi_scan_unsigned (&d, priv->d, sizeof (priv->d));
1531 
1532  /* NOW, because this is EdDSA, HASH 'd' first! */
1533  a = eddsa_d_to_a (d);
1534  gcry_mpi_release (d);
1535 
1536  /* then call the 'multiply' function, to compute the product */
1537  result = gcry_mpi_point_new (0);
1538  gcry_mpi_ec_mul (result, a, q, ctx);
1539  gcry_mpi_point_release (q);
1540  gcry_mpi_release (a);
1541 
1542  ret = point_to_hash (result, ctx, key_material);
1543  gcry_mpi_point_release (result);
1544  gcry_ctx_release (ctx);
1545  BENCHMARK_END (eddsa_ecdh);
1546  return ret;
1547 }
1548 
1549 
1560 int
1562  const struct GNUNET_CRYPTO_EcdhePublicKey *pub,
1563  struct GNUNET_HashCode *key_material)
1564 {
1565  gcry_mpi_point_t result;
1566  gcry_mpi_point_t q;
1567  gcry_mpi_t d;
1568  gcry_ctx_t ctx;
1569  gcry_sexp_t pub_sexpr;
1570  int ret;
1571 
1572  BENCHMARK_START (ecdsa_ecdh);
1573 
1574  /* first, extract the q = dP value from the public key */
1575  if (0 != gcry_sexp_build (&pub_sexpr,
1576  NULL,
1577  "(public-key(ecc(curve " CURVE ")(q %b)))",
1578  (int) sizeof (pub->q_y),
1579  pub->q_y))
1580  return GNUNET_SYSERR;
1581  GNUNET_assert (0 == gcry_mpi_ec_new (&ctx, pub_sexpr, NULL));
1582  gcry_sexp_release (pub_sexpr);
1583  q = gcry_mpi_ec_get_point ("q", ctx, 0);
1584 
1585  /* second, extract the d value from our private key */
1586  GNUNET_CRYPTO_mpi_scan_unsigned (&d, priv->d, sizeof (priv->d));
1587 
1588  /* then call the 'multiply' function, to compute the product */
1589  result = gcry_mpi_point_new (0);
1590  gcry_mpi_ec_mul (result, d, q, ctx);
1591  gcry_mpi_point_release (q);
1592  gcry_mpi_release (d);
1593 
1594  /* finally, convert point to string for hashing */
1595  ret = point_to_hash (result, ctx, key_material);
1596  gcry_mpi_point_release (result);
1597  gcry_ctx_release (ctx);
1598  BENCHMARK_END (ecdsa_ecdh);
1599  return ret;
1600 }
1601 
1602 
1613 int
1615  const struct GNUNET_CRYPTO_EddsaPublicKey *pub,
1616  struct GNUNET_HashCode *key_material)
1617 {
1618  gcry_mpi_point_t result;
1619  gcry_mpi_point_t q;
1620  gcry_mpi_t d;
1621  gcry_ctx_t ctx;
1622  gcry_sexp_t pub_sexpr;
1623  int ret;
1624 
1625  BENCHMARK_START (ecdh_eddsa);
1626 
1627  /* first, extract the q = dP value from the public key */
1628  if (0 != gcry_sexp_build (&pub_sexpr,
1629  NULL,
1630  "(public-key(ecc(curve " CURVE ")(q %b)))",
1631  (int) sizeof (pub->q_y),
1632  pub->q_y))
1633  return GNUNET_SYSERR;
1634  GNUNET_assert (0 == gcry_mpi_ec_new (&ctx, pub_sexpr, NULL));
1635  gcry_sexp_release (pub_sexpr);
1636  q = gcry_mpi_ec_get_point ("q", ctx, 0);
1637 
1638  /* second, extract the d value from our private key */
1639  GNUNET_CRYPTO_mpi_scan_unsigned (&d, priv->d, sizeof (priv->d));
1640 
1641  /* then call the 'multiply' function, to compute the product */
1642  result = gcry_mpi_point_new (0);
1643  gcry_mpi_ec_mul (result, d, q, ctx);
1644  gcry_mpi_point_release (q);
1645  gcry_mpi_release (d);
1646 
1647  /* finally, convert point to string for hashing */
1648  ret = point_to_hash (result, ctx, key_material);
1649  gcry_mpi_point_release (result);
1650  gcry_ctx_release (ctx);
1651  BENCHMARK_END (ecdh_eddsa);
1652  return ret;
1653 }
1654 
1665 int
1667  const struct GNUNET_CRYPTO_EcdsaPublicKey *pub,
1668  struct GNUNET_HashCode *key_material)
1669 {
1670  return GNUNET_CRYPTO_ecdh_eddsa (priv,
1671  (const struct GNUNET_CRYPTO_EddsaPublicKey *)
1672  pub,
1673  key_material);
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:632
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:1561
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:534
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:814
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:1339
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:1666
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:1048
unsigned char r[256/8]
R value.
#define BENCHMARK_START(opname)
Definition: benchmark.h:53
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:367
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:572
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:585
#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:691
#define BENCHMARK_END(opname)
Definition: benchmark.h:54
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:989
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:75
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:1184
struct GNUNET_CRYPTO_EcdhePrivateKey * GNUNET_CRYPTO_ecdhe_key_create()
Create a new private key.
Definition: crypto_ecc.c:610
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:1463
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:207
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:78
#define GNUNET_new(type)
Allocate a struct or union of the given type.
Private ECC key encoded for transmission.
static int ret
Final status code.
Definition: gnunet-arm.c:89
#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:94
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:208
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:931
cryptographic primitives for GNUnet
struct GNUNET_CRYPTO_EddsaPrivateKey * GNUNET_CRYPTO_eddsa_key_create()
Create a new private key.
Definition: crypto_ecc.c:746
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:1116
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:1504
void GNUNET_CRYPTO_hash(const void *block, size_t size, struct GNUNET_HashCode *ret)
Compute hash of a given block.
Definition: crypto_hash.c:44
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:1418
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:1614
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:400
static void reverse_buffer(unsigned char *buffer, size_t length)
Reverse the sequence of the bytes in buffer.
Definition: crypto_ecc.c:1396
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:128
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:334
Private ECC key encoded for transmission.
#define GNUNET_SYSERR
Definition: gnunet_common.h:79
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:241
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:303
#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:886
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:272
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:172
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:598
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:433
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:1257
#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:137
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:841
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:1295
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:501
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:91
static int list
Set if we should print a list of currently running services.
Definition: gnunet-arm.c:64
#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:1021
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:924
#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:468
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...