aboutsummaryrefslogtreecommitdiff
path: root/src/util/crypto_ecc.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/util/crypto_ecc.c')
-rw-r--r--src/util/crypto_ecc.c791
1 files changed, 0 insertions, 791 deletions
diff --git a/src/util/crypto_ecc.c b/src/util/crypto_ecc.c
deleted file mode 100644
index 5b1b579ec..000000000
--- a/src/util/crypto_ecc.c
+++ /dev/null
@@ -1,791 +0,0 @@
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
21/**
22 * @file util/crypto_ecc.c
23 * @brief public key cryptography (ECC) with libgcrypt
24 * @author Christian Grothoff
25 * @author Florian Dold
26 */
27#include "platform.h"
28#include <gcrypt.h>
29#include <sodium.h>
30#include "gnunet_crypto_lib.h"
31#include "gnunet_strings_lib.h"
32#include "benchmark.h"
33
34#define EXTRA_CHECKS 0
35
36/**
37 * IMPLEMENTATION NOTICE:
38 *
39 * ECDSA: We use a non-standard curve for ECDSA: Ed25519.
40 * For performance reasons, we use cryptographic operations from
41 * libsodium wherever we can get away with it, even though libsodium
42 * itself does not support ECDSA.
43 * This is why the sign and verifiy functionality from libgcrypt is
44 * required and used.
45 *
46 * EdDSA: We use a standard EdDSA construction.
47 * (We still use libgcrypt for hashing and RNG, but not EC)
48 *
49 * ECDHE: For both EdDSA and ECDSA keys, we use libsodium for
50 * ECDHE due to performance benefits over libgcrypt.
51 */
52
53/**
54 * Name of the curve we are using. Note that we have hard-coded
55 * structs that use 256 bits, so using a bigger curve will require
56 * changes that break stuff badly. The name of the curve given here
57 * must be agreed by all peers and be supported by libgcrypt.
58 */
59#define CURVE "Ed25519"
60
61#define LOG(kind, ...) GNUNET_log_from (kind, "util-crypto-ecc", __VA_ARGS__)
62
63#define LOG_STRERROR(kind, syscall) \
64 GNUNET_log_from_strerror (kind, "util-crypto-ecc", syscall)
65
66#define LOG_STRERROR_FILE(kind, syscall, filename) \
67 GNUNET_log_from_strerror_file (kind, "util-crypto-ecc", syscall, filename)
68
69/**
70 * Log an error message at log-level 'level' that indicates
71 * a failure of the command 'cmd' with the message given
72 * by gcry_strerror(rc).
73 */
74#define LOG_GCRY(level, cmd, rc) \
75 do \
76 { \
77 LOG (level, \
78 _ ("`%s' failed at %s:%d with error: %s\n"), \
79 cmd, \
80 __FILE__, \
81 __LINE__, \
82 gcry_strerror (rc)); \
83 } while (0)
84
85
86/**
87 * Extract values from an S-expression.
88 *
89 * @param array where to store the result(s)
90 * @param sexp S-expression to parse
91 * @param topname top-level name in the S-expression that is of interest
92 * @param elems names of the elements to extract
93 * @return 0 on success
94 */
95static int
96key_from_sexp (gcry_mpi_t *array,
97 gcry_sexp_t sexp,
98 const char *topname,
99 const char *elems)
100{
101 gcry_sexp_t list;
102 gcry_sexp_t l2;
103 unsigned int idx;
104
105 list = gcry_sexp_find_token (sexp, topname, 0);
106 if (! list)
107 return 1;
108 l2 = gcry_sexp_cadr (list);
109 gcry_sexp_release (list);
110 list = l2;
111 if (! list)
112 return 2;
113
114 idx = 0;
115 for (const char *s = elems; *s; s++, idx++)
116 {
117 l2 = gcry_sexp_find_token (list, s, 1);
118 if (! l2)
119 {
120 for (unsigned int i = 0; i < idx; i++)
121 {
122 gcry_free (array[i]);
123 array[i] = NULL;
124 }
125 gcry_sexp_release (list);
126 return 3; /* required parameter not found */
127 }
128 array[idx] = gcry_sexp_nth_mpi (l2, 1, GCRYMPI_FMT_USG);
129 gcry_sexp_release (l2);
130 if (! array[idx])
131 {
132 for (unsigned int i = 0; i < idx; i++)
133 {
134 gcry_free (array[i]);
135 array[i] = NULL;
136 }
137 gcry_sexp_release (list);
138 return 4; /* required parameter is invalid */
139 }
140 }
141 gcry_sexp_release (list);
142 return 0;
143}
144
145
146/**
147 * Convert the given private key from the network format to the
148 * S-expression that can be used by libgcrypt.
149 *
150 * @param priv private key to decode
151 * @return NULL on error
152 */
153static gcry_sexp_t
154decode_private_ecdsa_key (const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv)
155{
156 gcry_sexp_t result;
157 int rc;
158 uint8_t d[32];
159
160 for (size_t i = 0; i<32; i++)
161 d[i] = priv->d[31 - i];
162
163 rc = gcry_sexp_build (&result,
164 NULL,
165 "(private-key(ecc(curve \"" CURVE "\")"
166 "(d %b)))",
167 32,
168 d);
169 if (0 != rc)
170 {
171 LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_sexp_build", rc);
172 GNUNET_assert (0);
173 }
174#if EXTRA_CHECKS
175 if (0 != (rc = gcry_pk_testkey (result)))
176 {
177 LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_pk_testkey", rc);
178 GNUNET_assert (0);
179 }
180#endif
181 return result;
182}
183
184
185void
186GNUNET_CRYPTO_ecdsa_key_get_public (
187 const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv,
188 struct GNUNET_CRYPTO_EcdsaPublicKey *pub)
189{
190 BENCHMARK_START (ecdsa_key_get_public);
191 crypto_scalarmult_ed25519_base_noclamp (pub->q_y, priv->d);
192 BENCHMARK_END (ecdsa_key_get_public);
193}
194
195
196void
197GNUNET_CRYPTO_eddsa_key_get_public (
198 const struct GNUNET_CRYPTO_EddsaPrivateKey *priv,
199 struct GNUNET_CRYPTO_EddsaPublicKey *pub)
200{
201 unsigned char pk[crypto_sign_PUBLICKEYBYTES];
202 unsigned char sk[crypto_sign_SECRETKEYBYTES];
203
204 BENCHMARK_START (eddsa_key_get_public);
205 GNUNET_assert (0 == crypto_sign_seed_keypair (pk, sk, priv->d));
206 GNUNET_memcpy (pub->q_y, pk, crypto_sign_PUBLICKEYBYTES);
207 sodium_memzero (sk, crypto_sign_SECRETKEYBYTES);
208 BENCHMARK_END (eddsa_key_get_public);
209}
210
211
212void
213GNUNET_CRYPTO_ecdhe_key_get_public (
214 const struct GNUNET_CRYPTO_EcdhePrivateKey *priv,
215 struct GNUNET_CRYPTO_EcdhePublicKey *pub)
216{
217 BENCHMARK_START (ecdhe_key_get_public);
218 GNUNET_assert (0 == crypto_scalarmult_base (pub->q_y, priv->d));
219 BENCHMARK_END (ecdhe_key_get_public);
220}
221
222
223char *
224GNUNET_CRYPTO_ecdsa_public_key_to_string (
225 const struct GNUNET_CRYPTO_EcdsaPublicKey *pub)
226{
227 char *pubkeybuf;
228 size_t keylen = (sizeof(struct GNUNET_CRYPTO_EcdsaPublicKey)) * 8;
229 char *end;
230
231 if (keylen % 5 > 0)
232 keylen += 5 - keylen % 5;
233 keylen /= 5;
234 pubkeybuf = GNUNET_malloc (keylen + 1);
235 end =
236 GNUNET_STRINGS_data_to_string ((unsigned char *) pub,
237 sizeof(struct GNUNET_CRYPTO_EcdsaPublicKey),
238 pubkeybuf,
239 keylen);
240 if (NULL == end)
241 {
242 GNUNET_free (pubkeybuf);
243 return NULL;
244 }
245 *end = '\0';
246 return pubkeybuf;
247}
248
249
250char *
251GNUNET_CRYPTO_eddsa_public_key_to_string (
252 const struct GNUNET_CRYPTO_EddsaPublicKey *pub)
253{
254 char *pubkeybuf;
255 size_t keylen = (sizeof(struct GNUNET_CRYPTO_EddsaPublicKey)) * 8;
256 char *end;
257
258 if (keylen % 5 > 0)
259 keylen += 5 - keylen % 5;
260 keylen /= 5;
261 pubkeybuf = GNUNET_malloc (keylen + 1);
262 end =
263 GNUNET_STRINGS_data_to_string ((unsigned char *) pub,
264 sizeof(struct GNUNET_CRYPTO_EddsaPublicKey),
265 pubkeybuf,
266 keylen);
267 if (NULL == end)
268 {
269 GNUNET_free (pubkeybuf);
270 return NULL;
271 }
272 *end = '\0';
273 return pubkeybuf;
274}
275
276
277char *
278GNUNET_CRYPTO_eddsa_private_key_to_string (
279 const struct GNUNET_CRYPTO_EddsaPrivateKey *priv)
280{
281 char *privkeybuf;
282 size_t keylen = (sizeof(struct GNUNET_CRYPTO_EddsaPrivateKey)) * 8;
283 char *end;
284
285 if (keylen % 5 > 0)
286 keylen += 5 - keylen % 5;
287 keylen /= 5;
288 privkeybuf = GNUNET_malloc (keylen + 1);
289 end = GNUNET_STRINGS_data_to_string ((unsigned char *) priv,
290 sizeof(
291 struct GNUNET_CRYPTO_EddsaPrivateKey),
292 privkeybuf,
293 keylen);
294 if (NULL == end)
295 {
296 GNUNET_free (privkeybuf);
297 return NULL;
298 }
299 *end = '\0';
300 return privkeybuf;
301}
302
303
304char *
305GNUNET_CRYPTO_ecdsa_private_key_to_string (
306 const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv)
307{
308 char *privkeybuf;
309 size_t keylen = (sizeof(struct GNUNET_CRYPTO_EcdsaPrivateKey)) * 8;
310 char *end;
311
312 if (keylen % 5 > 0)
313 keylen += 5 - keylen % 5;
314 keylen /= 5;
315 privkeybuf = GNUNET_malloc (keylen + 1);
316 end = GNUNET_STRINGS_data_to_string ((unsigned char *) priv,
317 sizeof(
318 struct GNUNET_CRYPTO_EcdsaPrivateKey),
319 privkeybuf,
320 keylen);
321 if (NULL == end)
322 {
323 GNUNET_free (privkeybuf);
324 return NULL;
325 }
326 *end = '\0';
327 return privkeybuf;
328}
329
330
331enum GNUNET_GenericReturnValue
332GNUNET_CRYPTO_ecdsa_public_key_from_string (
333 const char *enc,
334 size_t enclen,
335 struct GNUNET_CRYPTO_EcdsaPublicKey *pub)
336{
337 size_t keylen = (sizeof(struct GNUNET_CRYPTO_EcdsaPublicKey)) * 8;
338
339 if (keylen % 5 > 0)
340 keylen += 5 - keylen % 5;
341 keylen /= 5;
342 if (enclen != keylen)
343 return GNUNET_SYSERR;
344
345 if (GNUNET_OK !=
346 GNUNET_STRINGS_string_to_data (enc,
347 enclen,
348 pub,
349 sizeof(
350 struct GNUNET_CRYPTO_EcdsaPublicKey)))
351 return GNUNET_SYSERR;
352 return GNUNET_OK;
353}
354
355
356enum GNUNET_GenericReturnValue
357GNUNET_CRYPTO_eddsa_public_key_from_string (
358 const char *enc,
359 size_t enclen,
360 struct GNUNET_CRYPTO_EddsaPublicKey *pub)
361{
362 size_t keylen = (sizeof(struct GNUNET_CRYPTO_EddsaPublicKey)) * 8;
363
364 if (keylen % 5 > 0)
365 keylen += 5 - keylen % 5;
366 keylen /= 5;
367 if (enclen != keylen)
368 return GNUNET_SYSERR;
369
370 if (GNUNET_OK !=
371 GNUNET_STRINGS_string_to_data (enc,
372 enclen,
373 pub,
374 sizeof(
375 struct GNUNET_CRYPTO_EddsaPublicKey)))
376 return GNUNET_SYSERR;
377 return GNUNET_OK;
378}
379
380
381enum GNUNET_GenericReturnValue
382GNUNET_CRYPTO_eddsa_private_key_from_string (
383 const char *enc,
384 size_t enclen,
385 struct GNUNET_CRYPTO_EddsaPrivateKey *priv)
386{
387 size_t keylen = (sizeof(struct GNUNET_CRYPTO_EddsaPrivateKey)) * 8;
388
389 if (keylen % 5 > 0)
390 keylen += 5 - keylen % 5;
391 keylen /= 5;
392 if (enclen != keylen)
393 return GNUNET_SYSERR;
394
395 if (GNUNET_OK !=
396 GNUNET_STRINGS_string_to_data (enc,
397 enclen,
398 priv,
399 sizeof(
400 struct GNUNET_CRYPTO_EddsaPrivateKey)))
401 return GNUNET_SYSERR;
402#if CRYPTO_BUG
403 if (GNUNET_OK != check_eddsa_key (priv))
404 {
405 GNUNET_break (0);
406 return GNUNET_OK;
407 }
408#endif
409 return GNUNET_OK;
410}
411
412
413void
414GNUNET_CRYPTO_ecdhe_key_clear (struct GNUNET_CRYPTO_EcdhePrivateKey *pk)
415{
416 memset (pk, 0, sizeof(struct GNUNET_CRYPTO_EcdhePrivateKey));
417}
418
419
420void
421GNUNET_CRYPTO_ecdsa_key_clear (struct GNUNET_CRYPTO_EcdsaPrivateKey *pk)
422{
423 memset (pk, 0, sizeof(struct GNUNET_CRYPTO_EcdsaPrivateKey));
424}
425
426
427void
428GNUNET_CRYPTO_eddsa_key_clear (struct GNUNET_CRYPTO_EddsaPrivateKey *pk)
429{
430 memset (pk, 0, sizeof(struct GNUNET_CRYPTO_EddsaPrivateKey));
431}
432
433
434void
435GNUNET_CRYPTO_ecdhe_key_create (struct GNUNET_CRYPTO_EcdhePrivateKey *pk)
436{
437 BENCHMARK_START (ecdhe_key_create);
438 GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_NONCE,
439 pk,
440 sizeof (struct GNUNET_CRYPTO_EcdhePrivateKey));
441 BENCHMARK_END (ecdhe_key_create);
442}
443
444
445void
446GNUNET_CRYPTO_ecdsa_key_create (struct GNUNET_CRYPTO_EcdsaPrivateKey *pk)
447{
448 BENCHMARK_START (ecdsa_key_create);
449 GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_NONCE,
450 pk,
451 sizeof (struct GNUNET_CRYPTO_EcdsaPrivateKey));
452 pk->d[0] &= 248;
453 pk->d[31] &= 127;
454 pk->d[31] |= 64;
455
456 BENCHMARK_END (ecdsa_key_create);
457}
458
459
460void
461GNUNET_CRYPTO_eddsa_key_create (struct GNUNET_CRYPTO_EddsaPrivateKey *pk)
462{
463 BENCHMARK_START (eddsa_key_create);
464 /*
465 * We do not clamp for EdDSA, since all functions that use the private key do
466 * their own clamping (just like in libsodium). What we call "private key"
467 * here, actually corresponds to the seed in libsodium.
468 *
469 * (Contrast this to ECDSA, where functions using the private key can't clamp
470 * due to properties needed for GNS. That is a worse/unsafer API, but
471 * required for the GNS constructions to work.)
472 */
473 GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_NONCE,
474 pk,
475 sizeof (struct GNUNET_CRYPTO_EddsaPrivateKey));
476 BENCHMARK_END (eddsa_key_create);
477}
478
479
480const struct GNUNET_CRYPTO_EcdsaPrivateKey *
481GNUNET_CRYPTO_ecdsa_key_get_anonymous ()
482{
483 /**
484 * 'anonymous' pseudonym (global static, d=1, public key = G
485 * (generator).
486 */
487 static struct GNUNET_CRYPTO_EcdsaPrivateKey anonymous;
488 static int once;
489
490 if (once)
491 return &anonymous;
492 GNUNET_CRYPTO_mpi_print_unsigned (anonymous.d,
493 sizeof(anonymous.d),
494 GCRYMPI_CONST_ONE);
495 anonymous.d[0] &= 248;
496 anonymous.d[31] &= 127;
497 anonymous.d[31] |= 64;
498
499 once = 1;
500 return &anonymous;
501}
502
503
504/**
505 * Convert the data specified in the given purpose argument to an
506 * S-expression suitable for signature operations.
507 *
508 * @param purpose data to convert
509 * @return converted s-expression
510 */
511static gcry_sexp_t
512data_to_ecdsa_value (const struct GNUNET_CRYPTO_EccSignaturePurpose *purpose)
513{
514 gcry_sexp_t data;
515 int rc;
516
517/* See #5398 */
518#if 1
519 struct GNUNET_HashCode hc;
520
521 GNUNET_CRYPTO_hash (purpose, ntohl (purpose->size), &hc);
522 if (0 != (rc = gcry_sexp_build (&data,
523 NULL,
524 "(data(flags rfc6979)(hash %s %b))",
525 "sha512",
526 (int) sizeof(hc),
527 &hc)))
528 {
529 LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_sexp_build", rc);
530 return NULL;
531 }
532#else
533 if (0 != (rc = gcry_sexp_build (&data,
534 NULL,
535 "(data(flags rfc6979)(hash %s %b))",
536 "sha512",
537 ntohl (purpose->size),
538 purpose)))
539 {
540 LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_sexp_build", rc);
541 return NULL;
542 }
543#endif
544 return data;
545}
546
547
548enum GNUNET_GenericReturnValue
549GNUNET_CRYPTO_ecdsa_sign_ (
550 const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv,
551 const struct GNUNET_CRYPTO_EccSignaturePurpose *purpose,
552 struct GNUNET_CRYPTO_EcdsaSignature *sig)
553{
554 gcry_sexp_t priv_sexp;
555 gcry_sexp_t sig_sexp;
556 gcry_sexp_t data;
557 int rc;
558 gcry_mpi_t rs[2];
559
560 BENCHMARK_START (ecdsa_sign);
561
562 priv_sexp = decode_private_ecdsa_key (priv);
563 data = data_to_ecdsa_value (purpose);
564 if (0 != (rc = gcry_pk_sign (&sig_sexp, data, priv_sexp)))
565 {
566 LOG (GNUNET_ERROR_TYPE_WARNING,
567 _ ("ECC signing failed at %s:%d: %s\n"),
568 __FILE__,
569 __LINE__,
570 gcry_strerror (rc));
571 gcry_sexp_release (data);
572 gcry_sexp_release (priv_sexp);
573 return GNUNET_SYSERR;
574 }
575 gcry_sexp_release (priv_sexp);
576 gcry_sexp_release (data);
577
578 /* extract 'r' and 's' values from sexpression 'sig_sexp' and store in
579 'signature' */
580 if (0 != (rc = key_from_sexp (rs, sig_sexp, "sig-val", "rs")))
581 {
582 GNUNET_break (0);
583 gcry_sexp_release (sig_sexp);
584 return GNUNET_SYSERR;
585 }
586 gcry_sexp_release (sig_sexp);
587 GNUNET_CRYPTO_mpi_print_unsigned (sig->r, sizeof(sig->r), rs[0]);
588 GNUNET_CRYPTO_mpi_print_unsigned (sig->s, sizeof(sig->s), rs[1]);
589 gcry_mpi_release (rs[0]);
590 gcry_mpi_release (rs[1]);
591
592 BENCHMARK_END (ecdsa_sign);
593
594 return GNUNET_OK;
595}
596
597
598enum GNUNET_GenericReturnValue
599GNUNET_CRYPTO_eddsa_sign_ (
600 const struct GNUNET_CRYPTO_EddsaPrivateKey *priv,
601 const struct GNUNET_CRYPTO_EccSignaturePurpose *purpose,
602 struct GNUNET_CRYPTO_EddsaSignature *sig)
603{
604
605 size_t mlen = ntohl (purpose->size);
606 unsigned char sk[crypto_sign_SECRETKEYBYTES];
607 unsigned char pk[crypto_sign_PUBLICKEYBYTES];
608 int res;
609
610 BENCHMARK_START (eddsa_sign);
611 GNUNET_assert (0 == crypto_sign_seed_keypair (pk, sk, priv->d));
612 res = crypto_sign_detached ((uint8_t *) sig,
613 NULL,
614 (uint8_t *) purpose,
615 mlen,
616 sk);
617 BENCHMARK_END (eddsa_sign);
618 return (res == 0) ? GNUNET_OK : GNUNET_SYSERR;
619}
620
621
622enum GNUNET_GenericReturnValue
623GNUNET_CRYPTO_ecdsa_verify_ (
624 uint32_t purpose,
625 const struct GNUNET_CRYPTO_EccSignaturePurpose *validate,
626 const struct GNUNET_CRYPTO_EcdsaSignature *sig,
627 const struct GNUNET_CRYPTO_EcdsaPublicKey *pub)
628{
629 gcry_sexp_t data;
630 gcry_sexp_t sig_sexpr;
631 gcry_sexp_t pub_sexpr;
632 int rc;
633
634 BENCHMARK_START (ecdsa_verify);
635
636 if (purpose != ntohl (validate->purpose))
637 return GNUNET_SYSERR; /* purpose mismatch */
638
639 /* build s-expression for signature */
640 if (0 != (rc = gcry_sexp_build (&sig_sexpr,
641 NULL,
642 "(sig-val(ecdsa(r %b)(s %b)))",
643 (int) sizeof(sig->r),
644 sig->r,
645 (int) sizeof(sig->s),
646 sig->s)))
647 {
648 LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_sexp_build", rc);
649 return GNUNET_SYSERR;
650 }
651 data = data_to_ecdsa_value (validate);
652 if (0 != (rc = gcry_sexp_build (&pub_sexpr,
653 NULL,
654 "(public-key(ecc(curve " CURVE ")(q %b)))",
655 (int) sizeof(pub->q_y),
656 pub->q_y)))
657 {
658 gcry_sexp_release (data);
659 gcry_sexp_release (sig_sexpr);
660 return GNUNET_SYSERR;
661 }
662 rc = gcry_pk_verify (sig_sexpr, data, pub_sexpr);
663 gcry_sexp_release (pub_sexpr);
664 gcry_sexp_release (data);
665 gcry_sexp_release (sig_sexpr);
666 if (0 != rc)
667 {
668 LOG (GNUNET_ERROR_TYPE_INFO,
669 _ ("ECDSA signature verification failed at %s:%d: %s\n"),
670 __FILE__,
671 __LINE__,
672 gcry_strerror (rc));
673 BENCHMARK_END (ecdsa_verify);
674 return GNUNET_SYSERR;
675 }
676 BENCHMARK_END (ecdsa_verify);
677 return GNUNET_OK;
678}
679
680
681enum GNUNET_GenericReturnValue
682GNUNET_CRYPTO_eddsa_verify_ (
683 uint32_t purpose,
684 const struct GNUNET_CRYPTO_EccSignaturePurpose *validate,
685 const struct GNUNET_CRYPTO_EddsaSignature *sig,
686 const struct GNUNET_CRYPTO_EddsaPublicKey *pub)
687{
688 const unsigned char *m = (const void *) validate;
689 size_t mlen = ntohl (validate->size);
690 const unsigned char *s = (const void *) sig;
691
692 int res;
693
694 if (purpose != ntohl (validate->purpose))
695 return GNUNET_SYSERR; /* purpose mismatch */
696
697 BENCHMARK_START (eddsa_verify);
698 res = crypto_sign_verify_detached (s, m, mlen, pub->q_y);
699 BENCHMARK_END (eddsa_verify);
700 return (res == 0) ? GNUNET_OK : GNUNET_SYSERR;
701}
702
703
704enum GNUNET_GenericReturnValue
705GNUNET_CRYPTO_ecc_ecdh (const struct GNUNET_CRYPTO_EcdhePrivateKey *priv,
706 const struct GNUNET_CRYPTO_EcdhePublicKey *pub,
707 struct GNUNET_HashCode *key_material)
708{
709 uint8_t p[crypto_scalarmult_BYTES];
710 if (0 != crypto_scalarmult (p, priv->d, pub->q_y))
711 return GNUNET_SYSERR;
712 GNUNET_CRYPTO_hash (p, crypto_scalarmult_BYTES, key_material);
713 return GNUNET_OK;
714}
715
716
717enum GNUNET_GenericReturnValue
718GNUNET_CRYPTO_eddsa_ecdh (const struct GNUNET_CRYPTO_EddsaPrivateKey *priv,
719 const struct GNUNET_CRYPTO_EcdhePublicKey *pub,
720 struct GNUNET_HashCode *key_material)
721{
722 struct GNUNET_HashCode hc;
723 uint8_t a[crypto_scalarmult_SCALARBYTES];
724 uint8_t p[crypto_scalarmult_BYTES];
725
726 GNUNET_CRYPTO_hash (priv,
727 sizeof (struct GNUNET_CRYPTO_EcdsaPrivateKey),
728 &hc);
729 memcpy (a, &hc, sizeof (struct GNUNET_CRYPTO_EcdhePrivateKey));
730 if (0 != crypto_scalarmult (p, a, pub->q_y))
731 return GNUNET_SYSERR;
732 GNUNET_CRYPTO_hash (p,
733 crypto_scalarmult_BYTES,
734 key_material);
735 return GNUNET_OK;
736}
737
738
739enum GNUNET_GenericReturnValue
740GNUNET_CRYPTO_ecdsa_ecdh (const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv,
741 const struct GNUNET_CRYPTO_EcdhePublicKey *pub,
742 struct GNUNET_HashCode *key_material)
743{
744 uint8_t p[crypto_scalarmult_BYTES];
745
746 BENCHMARK_START (ecdsa_ecdh);
747 if (0 != crypto_scalarmult (p, priv->d, pub->q_y))
748 return GNUNET_SYSERR;
749 GNUNET_CRYPTO_hash (p,
750 crypto_scalarmult_BYTES,
751 key_material);
752 BENCHMARK_END (ecdsa_ecdh);
753 return GNUNET_OK;
754}
755
756
757enum GNUNET_GenericReturnValue
758GNUNET_CRYPTO_ecdh_eddsa (const struct GNUNET_CRYPTO_EcdhePrivateKey *priv,
759 const struct GNUNET_CRYPTO_EddsaPublicKey *pub,
760 struct GNUNET_HashCode *key_material)
761{
762 uint8_t p[crypto_scalarmult_BYTES];
763 uint8_t curve25510_pk[crypto_scalarmult_BYTES];
764
765 if (0 != crypto_sign_ed25519_pk_to_curve25519 (curve25510_pk, pub->q_y))
766 return GNUNET_SYSERR;
767 if (0 != crypto_scalarmult (p, priv->d, curve25510_pk))
768 return GNUNET_SYSERR;
769 GNUNET_CRYPTO_hash (p, crypto_scalarmult_BYTES, key_material);
770 return GNUNET_OK;
771}
772
773
774enum GNUNET_GenericReturnValue
775GNUNET_CRYPTO_ecdh_ecdsa (const struct GNUNET_CRYPTO_EcdhePrivateKey *priv,
776 const struct GNUNET_CRYPTO_EcdsaPublicKey *pub,
777 struct GNUNET_HashCode *key_material)
778{
779 uint8_t p[crypto_scalarmult_BYTES];
780 uint8_t curve25510_pk[crypto_scalarmult_BYTES];
781
782 if (0 != crypto_sign_ed25519_pk_to_curve25519 (curve25510_pk, pub->q_y))
783 return GNUNET_SYSERR;
784 if (0 != crypto_scalarmult (p, priv->d, curve25510_pk))
785 return GNUNET_SYSERR;
786 GNUNET_CRYPTO_hash (p, crypto_scalarmult_BYTES, key_material);
787 return GNUNET_OK;
788}
789
790
791/* end of crypto_ecc.c */