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 of type %u failed at %s:%d: %s\n"),
1164  (unsigned int)purpose,
1165  __FILE__,
1166  __LINE__,
1167  gcry_strerror(rc));
1168  BENCHMARK_END(eddsa_verify);
1169  return GNUNET_SYSERR;
1170  }
1171  BENCHMARK_END(eddsa_verify);
1172  return GNUNET_OK;
1173 }
1174 
1175 
1184 int
1186  const struct GNUNET_CRYPTO_EcdhePublicKey *pub,
1187  struct GNUNET_HashCode *key_material)
1188 {
1189  gcry_mpi_point_t result;
1190  gcry_mpi_point_t q;
1191  gcry_mpi_t d;
1192  gcry_ctx_t ctx;
1193  gcry_sexp_t pub_sexpr;
1194  gcry_mpi_t result_x;
1195  unsigned char xbuf[256 / 8];
1196  size_t rsize;
1197 
1198  BENCHMARK_START(ecc_ecdh);
1199 
1200  /* first, extract the q = dP value from the public key */
1201  if (0 != gcry_sexp_build(&pub_sexpr,
1202  NULL,
1203  "(public-key(ecc(curve " CURVE ")(q %b)))",
1204  (int)sizeof(pub->q_y),
1205  pub->q_y))
1206  return GNUNET_SYSERR;
1207  GNUNET_assert(0 == gcry_mpi_ec_new(&ctx, pub_sexpr, NULL));
1208  gcry_sexp_release(pub_sexpr);
1209  q = gcry_mpi_ec_get_point("q", ctx, 0);
1210 
1211  /* second, extract the d value from our private key */
1212  GNUNET_CRYPTO_mpi_scan_unsigned(&d, priv->d, sizeof(priv->d));
1213 
1214  /* then call the 'multiply' function, to compute the product */
1215  result = gcry_mpi_point_new(0);
1216  gcry_mpi_ec_mul(result, d, q, ctx);
1217  gcry_mpi_point_release(q);
1218  gcry_mpi_release(d);
1219 
1220  /* finally, convert point to string for hashing */
1221  result_x = gcry_mpi_new(256);
1222  if (gcry_mpi_ec_get_affine(result_x, NULL, result, ctx))
1223  {
1224  LOG_GCRY(GNUNET_ERROR_TYPE_ERROR, "get_affine failed", 0);
1225  gcry_mpi_point_release(result);
1226  gcry_ctx_release(ctx);
1227  return GNUNET_SYSERR;
1228  }
1229  gcry_mpi_point_release(result);
1230  gcry_ctx_release(ctx);
1231 
1232  rsize = sizeof(xbuf);
1233  GNUNET_assert(!gcry_mpi_get_flag(result_x, GCRYMPI_FLAG_OPAQUE));
1234  /* result_x can be negative here, so we do not use 'GNUNET_CRYPTO_mpi_print_unsigned'
1235  as that does not include the sign bit; x should be a 255-bit
1236  value, so with the sign it should fit snugly into the 256-bit
1237  xbuf */
1238  GNUNET_assert(
1239  0 == gcry_mpi_print(GCRYMPI_FMT_STD, xbuf, rsize, &rsize, result_x));
1240  GNUNET_CRYPTO_hash(xbuf, rsize, key_material);
1241  gcry_mpi_release(result_x);
1242  BENCHMARK_END(ecc_ecdh);
1243  return GNUNET_OK;
1244 }
1245 
1246 
1257 static gcry_mpi_t
1259  const char *label,
1260  const char *context)
1261 {
1262  gcry_mpi_t h;
1263  struct GNUNET_HashCode hc;
1264  static const char *const salt = "key-derivation";
1265 
1266  GNUNET_CRYPTO_kdf(&hc,
1267  sizeof(hc),
1268  salt,
1269  strlen(salt),
1270  pub,
1271  sizeof(*pub),
1272  label,
1273  strlen(label),
1274  context,
1275  strlen(context),
1276  NULL,
1277  0);
1278  GNUNET_CRYPTO_mpi_scan_unsigned(&h, (unsigned char *)&hc, sizeof(hc));
1279  return h;
1280 }
1281 
1282 
1297  const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv,
1298  const char *label,
1299  const char *context)
1300 {
1301  struct GNUNET_CRYPTO_EcdsaPublicKey pub;
1303  gcry_mpi_t h;
1304  gcry_mpi_t x;
1305  gcry_mpi_t d;
1306  gcry_mpi_t n;
1307  gcry_ctx_t ctx;
1308 
1309  GNUNET_assert(0 == gcry_mpi_ec_new(&ctx, NULL, CURVE));
1310 
1311  n = gcry_mpi_ec_get_mpi("n", ctx, 1);
1313 
1314  h = derive_h(&pub, label, context);
1315  GNUNET_CRYPTO_mpi_scan_unsigned(&x, priv->d, sizeof(priv->d));
1316  d = gcry_mpi_new(256);
1317  gcry_mpi_mulm(d, h, x, n);
1318  gcry_mpi_release(h);
1319  gcry_mpi_release(x);
1320  gcry_mpi_release(n);
1321  gcry_ctx_release(ctx);
1323  GNUNET_CRYPTO_mpi_print_unsigned(ret->d, sizeof(ret->d), d);
1324  gcry_mpi_release(d);
1325  return ret;
1326 }
1327 
1328 
1339 void
1341  const struct GNUNET_CRYPTO_EcdsaPublicKey *pub,
1342  const char *label,
1343  const char *context,
1345 {
1346  gcry_ctx_t ctx;
1347  gcry_mpi_t q_y;
1348  gcry_mpi_t h;
1349  gcry_mpi_t n;
1350  gcry_mpi_t h_mod_n;
1351  gcry_mpi_point_t q;
1352  gcry_mpi_point_t v;
1353 
1354  GNUNET_assert(0 == gcry_mpi_ec_new(&ctx, NULL, CURVE));
1355 
1356  /* obtain point 'q' from original public key. The provided 'q' is
1357  compressed thus we first store it in the context and then get it
1358  back as a (decompresssed) point. */
1359  q_y = gcry_mpi_set_opaque_copy(NULL, pub->q_y, 8 * sizeof(pub->q_y));
1360  GNUNET_assert(NULL != q_y);
1361  GNUNET_assert(0 == gcry_mpi_ec_set_mpi("q", q_y, ctx));
1362  gcry_mpi_release(q_y);
1363  q = gcry_mpi_ec_get_point("q", ctx, 0);
1364  GNUNET_assert(q);
1365 
1366  /* calculate h_mod_n = h % n */
1367  h = derive_h(pub, label, context);
1368  n = gcry_mpi_ec_get_mpi("n", ctx, 1);
1369  h_mod_n = gcry_mpi_new(256);
1370  gcry_mpi_mod(h_mod_n, h, n);
1371  /* calculate v = h_mod_n * q */
1372  v = gcry_mpi_point_new(0);
1373  gcry_mpi_ec_mul(v, h_mod_n, q, ctx);
1374  gcry_mpi_release(h_mod_n);
1375  gcry_mpi_release(h);
1376  gcry_mpi_release(n);
1377  gcry_mpi_point_release(q);
1378 
1379  /* convert point 'v' to public key that we return */
1380  GNUNET_assert(0 == gcry_mpi_ec_set_point("q", v, ctx));
1381  gcry_mpi_point_release(v);
1382  q_y = gcry_mpi_ec_get_mpi("q@eddsa", ctx, 0);
1383  GNUNET_assert(q_y);
1384  GNUNET_CRYPTO_mpi_print_unsigned(result->q_y, sizeof(result->q_y), q_y);
1385  gcry_mpi_release(q_y);
1386  gcry_ctx_release(ctx);
1387 }
1388 
1389 
1396 static void
1397 reverse_buffer(unsigned char *buffer, size_t length)
1398 {
1399  unsigned char tmp;
1400  size_t i;
1401 
1402  for (i = 0; i < length / 2; i++)
1403  {
1404  tmp = buffer[i];
1405  buffer[i] = buffer[length - 1 - i];
1406  buffer[length - 1 - i] = tmp;
1407  }
1408 }
1409 
1410 
1418 static gcry_mpi_t
1419 eddsa_d_to_a(gcry_mpi_t d)
1420 {
1421  unsigned char rawmpi[32]; /* 256-bit value */
1422  size_t rawmpilen;
1423  unsigned char digest[64]; /* 512-bit hash value */
1424  gcry_buffer_t hvec[2];
1425  unsigned int b;
1426  gcry_mpi_t a;
1427 
1428  b = 256 / 8; /* number of bytes in `d` */
1429 
1430  /* Note that we clear DIGEST so we can use it as input to left pad
1431  the key with zeroes for hashing. */
1432  memset(digest, 0, sizeof digest);
1433  memset(hvec, 0, sizeof hvec);
1434  rawmpilen = sizeof(rawmpi);
1435  GNUNET_assert(
1436  0 == gcry_mpi_print(GCRYMPI_FMT_USG, rawmpi, rawmpilen, &rawmpilen, d));
1437  hvec[0].data = digest;
1438  hvec[0].off = 0;
1439  hvec[0].len = b > rawmpilen ? (b - rawmpilen) : 0;
1440  hvec[1].data = rawmpi;
1441  hvec[1].off = 0;
1442  hvec[1].len = rawmpilen;
1443  GNUNET_assert(
1444  0 == gcry_md_hash_buffers(GCRY_MD_SHA512, 0 /* flags */, digest, hvec, 2));
1445  /* Compute the A value. */
1446  reverse_buffer(digest, 32); /* Only the first half of the hash. */
1447  digest[0] = (digest[0] & 0x7f) | 0x40;
1448  digest[31] &= 0xf8;
1449 
1450  GNUNET_CRYPTO_mpi_scan_unsigned(&a, digest, 32);
1451  return a;
1452 }
1453 
1454 
1463 static int
1464 point_to_hash(gcry_mpi_point_t result,
1465  gcry_ctx_t ctx,
1466  struct GNUNET_HashCode *key_material)
1467 {
1468  gcry_mpi_t result_x;
1469  unsigned char xbuf[256 / 8];
1470  size_t rsize;
1471 
1472  /* finally, convert point to string for hashing */
1473  result_x = gcry_mpi_new(256);
1474  if (gcry_mpi_ec_get_affine(result_x, NULL, result, ctx))
1475  {
1476  LOG_GCRY(GNUNET_ERROR_TYPE_ERROR, "get_affine failed", 0);
1477  return GNUNET_SYSERR;
1478  }
1479 
1480  rsize = sizeof(xbuf);
1481  GNUNET_assert(!gcry_mpi_get_flag(result_x, GCRYMPI_FLAG_OPAQUE));
1482  /* result_x can be negative here, so we do not use 'GNUNET_CRYPTO_mpi_print_unsigned'
1483  as that does not include the sign bit; x should be a 255-bit
1484  value, so with the sign it should fit snugly into the 256-bit
1485  xbuf */
1486  GNUNET_assert(
1487  0 == gcry_mpi_print(GCRYMPI_FMT_STD, xbuf, rsize, &rsize, result_x));
1488  GNUNET_CRYPTO_hash(xbuf, rsize, key_material);
1489  gcry_mpi_release(result_x);
1490  return GNUNET_OK;
1491 }
1492 
1493 
1504 int
1506  const struct GNUNET_CRYPTO_EcdhePublicKey *pub,
1507  struct GNUNET_HashCode *key_material)
1508 {
1509  gcry_mpi_point_t result;
1510  gcry_mpi_point_t q;
1511  gcry_mpi_t d;
1512  gcry_mpi_t a;
1513  gcry_ctx_t ctx;
1514  gcry_sexp_t pub_sexpr;
1515  int ret;
1516 
1517  BENCHMARK_START(eddsa_ecdh);
1518 
1519  /* first, extract the q = dP value from the public key */
1520  if (0 != gcry_sexp_build(&pub_sexpr,
1521  NULL,
1522  "(public-key(ecc(curve " CURVE ")(q %b)))",
1523  (int)sizeof(pub->q_y),
1524  pub->q_y))
1525  return GNUNET_SYSERR;
1526  GNUNET_assert(0 == gcry_mpi_ec_new(&ctx, pub_sexpr, NULL));
1527  gcry_sexp_release(pub_sexpr);
1528  q = gcry_mpi_ec_get_point("q", ctx, 0);
1529 
1530  /* second, extract the d value from our private key */
1531  GNUNET_CRYPTO_mpi_scan_unsigned(&d, priv->d, sizeof(priv->d));
1532 
1533  /* NOW, because this is EdDSA, HASH 'd' first! */
1534  a = eddsa_d_to_a(d);
1535  gcry_mpi_release(d);
1536 
1537  /* then call the 'multiply' function, to compute the product */
1538  result = gcry_mpi_point_new(0);
1539  gcry_mpi_ec_mul(result, a, q, ctx);
1540  gcry_mpi_point_release(q);
1541  gcry_mpi_release(a);
1542 
1543  ret = point_to_hash(result, ctx, key_material);
1544  gcry_mpi_point_release(result);
1545  gcry_ctx_release(ctx);
1546  BENCHMARK_END(eddsa_ecdh);
1547  return ret;
1548 }
1549 
1550 
1561 int
1563  const struct GNUNET_CRYPTO_EcdhePublicKey *pub,
1564  struct GNUNET_HashCode *key_material)
1565 {
1566  gcry_mpi_point_t result;
1567  gcry_mpi_point_t q;
1568  gcry_mpi_t d;
1569  gcry_ctx_t ctx;
1570  gcry_sexp_t pub_sexpr;
1571  int ret;
1572 
1573  BENCHMARK_START(ecdsa_ecdh);
1574 
1575  /* first, extract the q = dP value from the public key */
1576  if (0 != gcry_sexp_build(&pub_sexpr,
1577  NULL,
1578  "(public-key(ecc(curve " CURVE ")(q %b)))",
1579  (int)sizeof(pub->q_y),
1580  pub->q_y))
1581  return GNUNET_SYSERR;
1582  GNUNET_assert(0 == gcry_mpi_ec_new(&ctx, pub_sexpr, NULL));
1583  gcry_sexp_release(pub_sexpr);
1584  q = gcry_mpi_ec_get_point("q", ctx, 0);
1585 
1586  /* second, extract the d value from our private key */
1587  GNUNET_CRYPTO_mpi_scan_unsigned(&d, priv->d, sizeof(priv->d));
1588 
1589  /* then call the 'multiply' function, to compute the product */
1590  result = gcry_mpi_point_new(0);
1591  gcry_mpi_ec_mul(result, d, q, ctx);
1592  gcry_mpi_point_release(q);
1593  gcry_mpi_release(d);
1594 
1595  /* finally, convert point to string for hashing */
1596  ret = point_to_hash(result, ctx, key_material);
1597  gcry_mpi_point_release(result);
1598  gcry_ctx_release(ctx);
1599  BENCHMARK_END(ecdsa_ecdh);
1600  return ret;
1601 }
1602 
1603 
1614 int
1616  const struct GNUNET_CRYPTO_EddsaPublicKey *pub,
1617  struct GNUNET_HashCode *key_material)
1618 {
1619  gcry_mpi_point_t result;
1620  gcry_mpi_point_t q;
1621  gcry_mpi_t d;
1622  gcry_ctx_t ctx;
1623  gcry_sexp_t pub_sexpr;
1624  int ret;
1625 
1626  BENCHMARK_START(ecdh_eddsa);
1627 
1628  /* first, extract the q = dP value from the public key */
1629  if (0 != gcry_sexp_build(&pub_sexpr,
1630  NULL,
1631  "(public-key(ecc(curve " CURVE ")(q %b)))",
1632  (int)sizeof(pub->q_y),
1633  pub->q_y))
1634  return GNUNET_SYSERR;
1635  GNUNET_assert(0 == gcry_mpi_ec_new(&ctx, pub_sexpr, NULL));
1636  gcry_sexp_release(pub_sexpr);
1637  q = gcry_mpi_ec_get_point("q", ctx, 0);
1638 
1639  /* second, extract the d value from our private key */
1640  GNUNET_CRYPTO_mpi_scan_unsigned(&d, priv->d, sizeof(priv->d));
1641 
1642  /* then call the 'multiply' function, to compute the product */
1643  result = gcry_mpi_point_new(0);
1644  gcry_mpi_ec_mul(result, d, q, ctx);
1645  gcry_mpi_point_release(q);
1646  gcry_mpi_release(d);
1647 
1648  /* finally, convert point to string for hashing */
1649  ret = point_to_hash(result, ctx, key_material);
1650  gcry_mpi_point_release(result);
1651  gcry_ctx_release(ctx);
1652  BENCHMARK_END(ecdh_eddsa);
1653  return ret;
1654 }
1655 
1666 int
1668  const struct GNUNET_CRYPTO_EcdsaPublicKey *pub,
1669  struct GNUNET_HashCode *key_material)
1670 {
1671  return GNUNET_CRYPTO_ecdh_eddsa(priv,
1672  (const struct GNUNET_CRYPTO_EddsaPublicKey *)
1673  pub,
1674  key_material);
1675 }
1676 
1677 /* 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:1562
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:1340
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:1667
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:1185
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:1464
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:75
#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: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: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:1505
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:67
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:1419
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:1615
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:1397
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: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: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:1258
#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:1296
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:953
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:857
#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...