GNUnet 0.28.0-dev.3-17-g184ae026b
 
Loading...
Searching...
No Matches
crypto_hpke.c
Go to the documentation of this file.
1/*
2 This file is part of GNUnet.
3 Copyright (C) 2024 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 "gnunet_common.h"
28#include <sodium.h>
29#include <stdint.h>
30#include "gnunet_util_lib.h"
31#include "sodium/crypto_scalarmult.h"
32#include "sodium/crypto_scalarmult_curve25519.h"
33#include "sodium/utils.h"
34
51labeled_extract (const char *ctx_str,
52 const void *salt, size_t salt_len,
53 const void *label, size_t label_len,
54 const void *ikm, size_t ikm_len,
55 const uint8_t *suite_id, size_t suite_id_len,
56 struct GNUNET_ShortHashCode *prk)
57{
58 size_t labeled_ikm_len = strlen (ctx_str) + suite_id_len
59 + label_len + ikm_len;
60 uint8_t labeled_ikm[labeled_ikm_len];
61 uint8_t *tmp = labeled_ikm;
62
63 // labeled_ikm = concat("HPKE-v1", suite_id, label, ikm)
64 memcpy (tmp, ctx_str, strlen (ctx_str));
65 tmp += strlen (ctx_str);
66 memcpy (tmp, suite_id, suite_id_len);
67 tmp += suite_id_len;
68 memcpy (tmp, label, label_len);
69 tmp += label_len;
70 memcpy (tmp, ikm, ikm_len);
71 // return Extract(salt, labeled_ikm)
73 salt, salt_len,
74 labeled_ikm, labeled_ikm_len);
75}
76
77
94labeled_expand (const char *ctx_str,
95 const struct GNUNET_ShortHashCode *prk,
96 const char *label, size_t label_len,
97 const void *info, size_t info_len,
98 const uint8_t *suite_id, size_t suite_id_len,
99 void *out_buf,
100 uint16_t out_len)
101{
102 uint8_t labeled_info[2 + strlen (ctx_str) + suite_id_len + label_len
103 + info_len];
104 uint8_t *tmp = labeled_info;
105 uint16_t out_len_nbo = htons (out_len);
106
107 // labeled_info = concat(I2OSP(L, 2), "HPKE-v1", suite_id,
108 // label, info)
109 memcpy (tmp, &out_len_nbo, 2);
110 tmp += 2;
111 memcpy (tmp, ctx_str, strlen (ctx_str));
112 tmp += strlen (ctx_str);
113 memcpy (tmp, suite_id, suite_id_len);
114 tmp += suite_id_len;
115 memcpy (tmp, label, label_len);
116 tmp += label_len;
117 memcpy (tmp, info, info_len);
119 out_buf,
120 out_len,
121 prk,
122 GNUNET_CRYPTO_kdf_arg (labeled_info,
123 sizeof labeled_info));
124}
125
126
129 size_t dh_len,
130 const char *extract_ctx,
131 const char *expand_ctx,
132 const void*extract_lbl, size_t
133 extract_lbl_len,
134 const void*expand_lbl, size_t
135 expand_lbl_len,
136 const uint8_t *kem_context,
137 size_t kem_context_len,
138 const uint8_t *suite_id, size_t
139 suite_id_len,
140 struct GNUNET_ShortHashCode *
141 shared_secret)
142{
143 struct GNUNET_ShortHashCode prk;
144 // eae_prk = LabeledExtract("", "eae_prk", dh)
145 labeled_extract (extract_ctx,
146 NULL, 0,
147 extract_lbl, extract_lbl_len,
148 dh, dh_len,
149 suite_id, suite_id_len,
150 &prk);
151 return labeled_expand (expand_ctx,
152 &prk,
153 expand_lbl, expand_lbl_len,
154 kem_context, kem_context_len,
155 suite_id, suite_id_len,
156 shared_secret, sizeof *shared_secret);
157}
158
159
160// DHKEM(X25519, HKDF-256): kem_id = 32
161// concat("KEM", I2OSP(kem_id, 2))
162static uint8_t GNUNET_CRYPTO_HPKE_KEM_SUITE_ID[] = { 'K', 'E', 'M',
163 0x00, 0x20 };
164
165// DHKEM(X25519Elligator, HKDF-256): kem_id = 0x0022
166// concat("KEM", I2OSP(kem_id, 2))
167static uint8_t GNUNET_CRYPTO_HPKE_KEM_ELLIGATOR_SUITE_ID[] = { 'K', 'E', 'M',
168 0x00, 0x22 };
169
171kem_encaps_norand (uint8_t *suite_id, size_t suite_id_len,
172 const struct GNUNET_CRYPTO_HpkePublicKey *pkR,
173 const struct GNUNET_CRYPTO_HpkeEncapsulation *c,
174 const struct GNUNET_CRYPTO_HpkePrivateKey *skE,
175 struct GNUNET_ShortHashCode *shared_secret)
176{
178 uint8_t kem_context[sizeof *c + sizeof pkR->ecdhe_key];
179
180 // dh = DH(skE, pkR)
182 &skE->ecdhe_key,
183 &pkR->ecdhe_key,
184 &dh.ecdhe_key))
185 {
187 "HPKE KEM encaps: Validation error\n");
188 return GNUNET_SYSERR; // ValidationError
189 }
190 // enc = SerializePublicKey(pkE) is a NOP, see Section 7.1.1
191 // pkRm = SerializePublicKey(pkR) is a NOP, see Section 7.1.1
192 // kem_context = concat(enc, pkRm)
193 memcpy (kem_context, c, sizeof *c);
194 memcpy (kem_context + sizeof *c,
195 &pkR->ecdhe_key,
196 sizeof pkR->ecdhe_key);
197 // shared_secret = ExtractAndExpand(dh, kem_context)
199 &dh.ecdhe_key, sizeof dh.ecdhe_key,
200 "HPKE-v1",
201 "HPKE-v1",
202 "eae_prk", strlen ("eae_prk"),
203 "shared_secret", strlen ("shared_secret"),
204 kem_context, sizeof kem_context,
205 suite_id, suite_id_len,
206 shared_secret);
207}
208
209
212 const struct GNUNET_CRYPTO_HpkePublicKey *pkR,
214 const struct GNUNET_CRYPTO_HpkePrivateKey *skE,
215 struct GNUNET_ShortHashCode *shared_secret)
216{
217 struct GNUNET_CRYPTO_EcdhePublicKey ecdh_pk;
218 // enc = SerializePublicKey(pkE) is a NOP, see Section 7.1.1
220 &skE->ecdhe_key,
221 &ecdh_pk);
223 ecdh_pk.q_y,
224 sizeof ecdh_pk.q_y);
227 pkR, enc, skE, shared_secret);
228}
229
230
233 pub,
235 struct GNUNET_ShortHashCode *shared_secret)
236{
238 // skE, pkE = GenerateKeyPair()
240
241 return GNUNET_CRYPTO_hpke_kem_encaps_norand (pub, c, &skE, shared_secret);
242}
243
244
248 struct GNUNET_ShortHashCode *shared_secret)
249{
251
252 // This maps the ed25519 point to X25519
253 if (0 != crypto_sign_ed25519_pk_to_curve25519 (pkR.ecdhe_key.q_y,
254 pub->q_y))
255 return GNUNET_SYSERR;
256
257 return GNUNET_CRYPTO_hpke_kem_encaps (&pkR, c, shared_secret);
258}
259
260
263 skR,
264 const struct GNUNET_CRYPTO_HpkeEncapsulation *c,
265 struct GNUNET_ShortHashCode *shared_secret)
266{
268 uint8_t kem_context[sizeof *c + crypto_scalarmult_curve25519_BYTES];
269 uint8_t pkR[crypto_scalarmult_BYTES];
270
271 // pkE = DeserializePublicKey(enc) is a NOP, see Section 7.1.1
272 // dh = DH(skR, pkE)
273 if (GNUNET_OK !=
276 &dh.ecdhe_key))
277 return GNUNET_SYSERR; // ValidationError
278
279 // pkRm = DeserializePublicKey(pk(skR)) is a NOP, see Section 7.1.1
280 crypto_scalarmult_curve25519_base (pkR,
281 skR->ecdhe_key.d);
282 // kem_context = concat(enc, pkRm)
283 memcpy (kem_context, c, sizeof *c);
284 memcpy (kem_context + sizeof *c, pkR, sizeof pkR);
285 // shared_secret = ExtractAndExpand(dh, kem_context)
287 &dh.ecdhe_key, sizeof dh.ecdhe_key,
288 "HPKE-v1",
289 "HPKE-v1",
290 "eae_prk", strlen ("eae_prk"),
291 "shared_secret", strlen ("shared_secret"),
292 kem_context, sizeof kem_context,
295 shared_secret);
296}
297
298
299// FIXME use Ed -> Curve conversion???
303 const struct GNUNET_CRYPTO_HpkeEncapsulation *c,
304 struct GNUNET_ShortHashCode *shared_secret)
305{
307
308 // This maps the ed25519 point to X25519
309 if (0 != crypto_sign_ed25519_sk_to_curve25519 (skR.ecdhe_key.d,
310 priv->d))
311 return GNUNET_SYSERR;
312 return GNUNET_CRYPTO_hpke_kem_decaps (&skR, c, shared_secret);
313
314}
315
316
319 uint8_t random_tweak,
320 const struct GNUNET_CRYPTO_HpkePublicKey *pkR,
323 struct GNUNET_ShortHashCode *shared_secret)
324{
326 struct GNUNET_CRYPTO_HpkePrivateKey skE_hpke;
327 // skE, pkE = GenerateElligatorKeyPair()
328 // enc = SerializePublicKey(pkE) == c is the elligator representative
330 random_tweak,
331 skE,
332 &pkE.ecdhe_key,
334
335 GNUNET_memcpy (&skE_hpke.ecdhe_key,
336 skE,
337 sizeof *skE);
340 pkR,
341 c,
342 &skE_hpke,
343 shared_secret);
344}
345
346
349 const struct GNUNET_CRYPTO_HpkePublicKey *pkR,
351 struct GNUNET_ShortHashCode *shared_secret)
352{
353 uint8_t random_tweak;
355
356 GNUNET_CRYPTO_random_block (&random_tweak,
357 sizeof(uint8_t));
358
359 // skE, pkE = GenerateElligatorKeyPair()
361
362 return GNUNET_CRYPTO_hpke_elligator_kem_encaps_norand (random_tweak, pkR, c,
363 &skE, shared_secret);
364}
365
366
369 const struct GNUNET_CRYPTO_HpkePrivateKey *skR,
370 const struct GNUNET_CRYPTO_HpkeEncapsulation *c,
371 struct GNUNET_ShortHashCode *shared_secret)
372{
376 uint8_t kem_context[sizeof *r + crypto_scalarmult_curve25519_BYTES];
377 uint8_t pkR[crypto_scalarmult_BYTES];
378
380 // pkE = DeserializePublicKey(enc) Elligator deserialize!
382 &pkE.ecdhe_key,
383 NULL,
384 r);
385 // dh = DH(skR, pkE)
388 &skR->ecdhe_key,
389 &pkE.ecdhe_key,
390 &dh.ecdhe_key));
391 // pkRm = DeserializePublicKey(pk(skR)) is a NOP, see Section 7.1.1
392 crypto_scalarmult_curve25519_base (pkR,
393 skR->ecdhe_key.d);
394 memcpy (kem_context, r, sizeof *r);
395 memcpy (kem_context + sizeof *r, pkR, sizeof pkR);
396 // shared_secret = ExtractAndExpand(dh, kem_context)
398 &dh.ecdhe_key, sizeof dh.ecdhe_key,
399 "HPKE-v1",
400 "HPKE-v1",
401 "eae_prk", strlen ("eae_prk"),
402 "shared_secret", strlen ("shared_secret"),
403 kem_context, sizeof kem_context,
406 shared_secret);
407}
408
409
412 const uint8_t *psk, size_t psk_len,
413 const uint8_t *psk_id, size_t psk_id_len)
414{
415 bool got_psk;
416 bool got_psk_id;
417
418 got_psk = (0 != psk_len);
419 got_psk_id = (0 != psk_id_len);
420
421 if (got_psk != got_psk_id)
422 {
424 "Inconsistent PSK inputs\n");
425 return GNUNET_SYSERR;
426 }
427
428 if (got_psk &&
431 {
433 "PSK input provided when not needed\n");
434 return GNUNET_SYSERR;
435 }
436 if (! got_psk &&
439 {
441 "Missing required PSK input\n");
442 return GNUNET_SYSERR;
443 }
444 return GNUNET_OK;
445}
446
447
451 const struct GNUNET_ShortHashCode *shared_secret,
452 const uint8_t *info, size_t info_len,
453 const uint8_t *psk, size_t psk_len,
454 const uint8_t *psk_id, size_t psk_id_len,
456{
457 struct GNUNET_ShortHashCode psk_id_hash;
458 struct GNUNET_ShortHashCode info_hash;
459 struct GNUNET_ShortHashCode secret;
460 uint8_t key_schedule_context[1 + sizeof info_hash * 2];
461 uint8_t suite_id[4 + 3 * 2];
462 uint16_t kem_id = htons (32); // FIXME hardcode as constant
463 uint16_t kdf_id = htons (1); // HKDF-256 FIXME hardcode as constant
464 uint16_t aead_id = htons (3); // ChaCha20Poly1305 FIXME hardcode as constant
465
466 // DHKEM(X25519, HKDF-256): kem_id = 32
467 // concat("KEM", I2OSP(kem_id, 2))
468 memcpy (suite_id, "HPKE", 4);
469 memcpy (suite_id + 4, &kem_id, 2);
470 memcpy (suite_id + 6, &kdf_id, 2);
471 memcpy (suite_id + 8, &aead_id, 2);
472
473 if (GNUNET_OK != verify_psk_inputs (mode, psk, psk_len, psk_id, psk_id_len))
474 return GNUNET_SYSERR;
475
476 if (GNUNET_OK != labeled_extract ("HPKE-v1", NULL, 0,
477 "psk_id_hash", strlen ("psk_id_hash"),
478 psk_id, psk_id_len,
479 suite_id, sizeof suite_id, &psk_id_hash))
480 return GNUNET_SYSERR;
481 if (GNUNET_OK != labeled_extract ("HPKE-v1", NULL, 0,
482 "info_hash", strlen ("info_hash"),
483 info, info_len,
484 suite_id, sizeof suite_id, &info_hash))
485 return GNUNET_SYSERR;
486 memcpy (key_schedule_context, &mode, 1);
487 memcpy (key_schedule_context + 1, &psk_id_hash, sizeof psk_id_hash);
488 memcpy (key_schedule_context + 1 + sizeof psk_id_hash,
489 &info_hash, sizeof info_hash);
490 if (GNUNET_OK != labeled_extract ("HPKE-v1",
491 shared_secret, sizeof *shared_secret,
492 "secret", strlen ("secret"),
493 psk, psk_len,
494 suite_id, sizeof suite_id, &secret))
495 return GNUNET_SYSERR;
496 // key = LabeledExpand(secret, "key", key_schedule_context, Nk)
497 // Note: Nk == sizeof ctx->key
498 if (GNUNET_OK != labeled_expand ("HPKE-v1",
499 &secret,
500 "key", strlen ("key"),
501 &key_schedule_context,
502 sizeof key_schedule_context,
503 suite_id, sizeof suite_id,
504 ctx->key, sizeof ctx->key))
505 return GNUNET_SYSERR;
506 // base_nonce = LabeledExpand(secret, "base_nonce",
507 // key_schedule_context, Nn)
508 if (GNUNET_OK != labeled_expand ("HPKE-v1",
509 &secret,
510 "base_nonce", strlen ("base_nonce"),
511 &key_schedule_context,
512 sizeof key_schedule_context,
513 suite_id, sizeof suite_id,
514 ctx->base_nonce, sizeof ctx->base_nonce))
515 return GNUNET_SYSERR;
516 // exporter_secret = LabeledExpand(secret, "exp",
517 // key_schedule_context, Nh)
518 if (GNUNET_OK != labeled_expand ("HPKE-v1",
519 &secret,
520 "exp", strlen ("exp"),
521 &key_schedule_context,
522 sizeof key_schedule_context,
523 suite_id, sizeof suite_id,
524 &ctx->exporter_secret,
525 sizeof ctx->exporter_secret))
526 return GNUNET_SYSERR;
527 ctx->seq = 0;
528 ctx->role = role;
529 return GNUNET_OK;
530}
531
532
535 enum GNUNET_CRYPTO_HpkeKem kem,
539 const struct GNUNET_CRYPTO_HpkePublicKey *pkR,
540 const uint8_t *info, size_t info_len,
541 const uint8_t *psk, size_t psk_len,
542 const uint8_t *psk_id, size_t psk_id_len,
545{
546 struct GNUNET_ShortHashCode shared_secret;
547
548 switch (mode)
549 {
553 {
555 &shared_secret))
556 return GNUNET_SYSERR;
557 break;
558 }
559 else if (kem ==
561 {
562 uint8_t random_tweak;
563 GNUNET_CRYPTO_random_block (&random_tweak,
564 sizeof(uint8_t));
565 if (GNUNET_OK !=
567 pkR,
568 enc,
569 (struct
571 *) skE,
572 &shared_secret))
573 return GNUNET_SYSERR;
574 }
575 break;
576 default:
577 return GNUNET_SYSERR;
578 }
580 mode,
581 &shared_secret,
582 info, info_len,
583 psk, psk_len,
584 psk_id, psk_id_len,
585 ctx))
586 return GNUNET_SYSERR;
587 return GNUNET_OK;
588}
589
590
594 const uint8_t *info, size_t info_len,
597{
599 // skE, pkE = GenerateKeyPair()
601
605 &sk, NULL,
606 pkR, info, info_len,
607 NULL, 0,
608 NULL, 0,
609 enc,
610 ctx);
611}
612
613
616 enum GNUNET_CRYPTO_HpkeKem kem,
619 const struct GNUNET_CRYPTO_HpkePrivateKey *skR,
620 const struct GNUNET_CRYPTO_HpkePublicKey *pkS,
621 const uint8_t *info, size_t info_len,
622 const uint8_t *psk, size_t psk_len,
623 const uint8_t *psk_id, size_t psk_id_len,
625{
626 struct GNUNET_ShortHashCode shared_secret;
627
628 switch (mode)
629 {
633 {
635 &shared_secret))
636 return GNUNET_SYSERR;
637 }
638 else if (kem ==
640 {
642 enc,
643 &shared_secret))
644 return GNUNET_SYSERR;
645 }
646 break;
647 default:
648 return GNUNET_SYSERR;
649 }
651 mode,
652 &shared_secret,
653 info, info_len,
654 psk, psk_len,
655 psk_id, psk_id_len,
656 ctx))
657 return GNUNET_SYSERR;
658 return GNUNET_OK;
659}
660
661
665 const struct GNUNET_CRYPTO_HpkePrivateKey *skR,
666 const uint8_t *info, size_t info_len,
668{
672 enc, skR, NULL,
673 info, info_len,
674 NULL, 0, NULL, 0, ctx);
675}
676
677
680{
681 if (ctx->seq >= UINT64_MAX)
682 {
683 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "MessageLimitReached\n");
684 return GNUNET_SYSERR;
685 }
686 ctx->seq = GNUNET_htonll (GNUNET_ntohll (ctx->seq) + 1);
687 return GNUNET_OK;
688}
689
690
691static void
693 uint8_t *nonce)
694{
695 size_t offset = GNUNET_CRYPTO_HPKE_NONCE_LEN - sizeof ctx->seq;
696 int j = 0;
697 for (int i = 0; i < GNUNET_CRYPTO_HPKE_NONCE_LEN; i++)
698 {
699 // FIXME correct byte order?
700 if (i < offset)
701 memset (&nonce[i], ctx->base_nonce[i], 1);
702 else
703 nonce[i] = ctx->base_nonce[i] ^ ((uint8_t*) &ctx->seq)[j++];
704 }
705}
706
707
710 const uint8_t*aad, size_t aad_len,
711 const uint8_t *pt, size_t pt_len,
712 uint8_t *ct, unsigned long long *ct_len_p)
713{
714 uint8_t comp_nonce[GNUNET_CRYPTO_HPKE_NONCE_LEN];
715 if (ctx->role != GNUNET_CRYPTO_HPKE_ROLE_S)
716 {
718 "HPKE: Wrong role; called as receiver (%d)!\n",
719 ctx->role);
720 return GNUNET_SYSERR;
721 }
722 compute_nonce (ctx, comp_nonce);
723 crypto_aead_chacha20poly1305_ietf_encrypt (ct, ct_len_p,
724 pt, pt_len,
725 aad, aad_len,
726 NULL,
727 comp_nonce,
728 ctx->key);
729 if (GNUNET_OK != increment_seq (ctx))
730 {
732 "HPKE: Seq increment failed!\n");
733 return GNUNET_SYSERR;
734 }
735 return GNUNET_OK;
736}
737
738
741 const uint8_t*aad, size_t aad_len,
742 const uint8_t *ct, size_t ct_len,
743 uint8_t *pt, unsigned long long *pt_len)
744{
745 uint8_t comp_nonce[GNUNET_CRYPTO_HPKE_NONCE_LEN];
746 if (ctx->role != GNUNET_CRYPTO_HPKE_ROLE_R)
747 {
749 "HPKE: Wrong role; called as sender (%d)!\n",
750 ctx->role);
751 return GNUNET_SYSERR;
752 }
753 compute_nonce (ctx, comp_nonce);
754 if (0 != crypto_aead_chacha20poly1305_ietf_decrypt (pt, pt_len,
755 NULL,
756 ct, ct_len,
757 aad, aad_len,
758 comp_nonce,
759 ctx->key))
760 {
761 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "OpenError\n");
762 return GNUNET_SYSERR;
763 }
764 if (GNUNET_OK != increment_seq (ctx))
765 {
767 "HPKE: Seq increment failed!\n");
768 return GNUNET_SYSERR;
769 }
770 return GNUNET_OK;
771}
772
773
777 const uint8_t *info, size_t info_len,
778 const uint8_t*aad, size_t aad_len,
779 const uint8_t *pt, size_t pt_len,
780 uint8_t *ct, unsigned long long *ct_len_p)
781{
784 uint8_t *ct_off;
785
787 ct_off = (uint8_t*) &enc[1];
789 info, info_len,
790 enc, &ctx))
791 {
793 "HPKE: Sender setup failed!\n");
794 return GNUNET_SYSERR;
795 }
797 aad, aad_len,
798 pt, pt_len,
799 ct_off,
800 ct_len_p);
801}
802
803
806 const struct GNUNET_CRYPTO_HpkePrivateKey *skR,
807 const uint8_t *info, size_t info_len,
808 const uint8_t*aad, size_t aad_len,
809 const uint8_t *ct, size_t ct_len,
810 uint8_t *pt, unsigned long long *pt_len_p)
811{
814 uint8_t *ct_off;
815
817 ct_off = (uint8_t*) &enc[1];
819 info, info_len,
820 &ctx))
821 {
823 "HPKE: Receiver setup failed!\n");
824 return GNUNET_SYSERR;
825 }
827 aad, aad_len,
828 ct_off,
829 ct_len - sizeof *enc,
830 pt,
831 pt_len_p);
832}
833
834
837 pk,
839 x25519)
840{
841 switch (ntohl (pk->type))
842 {
844 if (0 != crypto_sign_ed25519_pk_to_curve25519 (x25519->ecdhe_key.q_y,
845 pk->ecdsa_key.q_y))
846 return GNUNET_SYSERR;
848 return GNUNET_OK;
850 if (0 != crypto_sign_ed25519_pk_to_curve25519 (x25519->ecdhe_key.q_y,
851 pk->eddsa_key.q_y))
852 return GNUNET_SYSERR;
854 return GNUNET_OK;
855 default:
856 return GNUNET_SYSERR;
857 }
858 return GNUNET_SYSERR;
859
860}
861
862
867 x25519)
868{
869 switch (ntohl (sk->type))
870 {
872 memcpy (x25519->ecdhe_key.d,
873 sk->ecdsa_key.d,
874 sizeof sk->ecdsa_key.d);
876 return GNUNET_OK;
878 if (0 != crypto_sign_ed25519_sk_to_curve25519 (x25519->ecdhe_key.d,
879 sk->eddsa_key.d))
880 return GNUNET_SYSERR;
882 return GNUNET_OK;
883 default:
884 return GNUNET_SYSERR;
885 }
886 return GNUNET_SYSERR;
887
888}
889
890
891ssize_t
893 const struct GNUNET_CRYPTO_HpkePublicKey *key)
894{
895 switch (ntohl (key->type))
896 {
898 return sizeof (key->type) + sizeof (key->ecdhe_key);
899 default:
900 GNUNET_break (0);
901 }
902 return -1;
903}
904
905
908 size_t len,
909 struct
911 size_t *read)
912{
913 ssize_t length;
914 if (len < sizeof (key->type))
915 return GNUNET_SYSERR;
916 GNUNET_memcpy (&key->type,
917 buffer,
918 sizeof (key->type));
920 if (len < length)
921 return GNUNET_SYSERR;
922 if (length < 0)
923 return GNUNET_SYSERR;
924 GNUNET_memcpy (&key->ecdhe_key,
925 buffer + sizeof (key->type),
926 length - sizeof (key->type));
927 *read = length;
928 return GNUNET_OK;
929}
930
931
932ssize_t
935 void*buffer,
936 size_t len)
937{
938 const ssize_t length = GNUNET_CRYPTO_hpke_pk_get_length (key);
939 if (len < length)
940 return -1;
941 if (length < 0)
942 return -2;
943 GNUNET_memcpy (buffer, &(key->type), sizeof (key->type));
944 GNUNET_memcpy (buffer + sizeof (key->type), &(key->ecdhe_key), length
945 - sizeof (key->type));
946 return length;
947}
948
949
950void
952{
953 switch (ntohl (key->type))
954 {
957 break;
958 default:
959 GNUNET_break (0);
960 }
961}
962
963
966 const char *ikm,
967 size_t ikm_len,
969{
970 struct GNUNET_ShortHashCode dkp_prk;
971
973 {
974 GNUNET_break (0);
975 return GNUNET_SYSERR;
976 }
977 sk->type = htonl (type);
978
979 labeled_extract ("HPKE-v1",
980 "",
981 0,
982 "dkp_prk",
983 strlen ("dkp_prk"),
984 ikm,
985 ikm_len,
988 &dkp_prk);
989 labeled_expand ("HPKE-v1",
990 &dkp_prk,
991 "sk",
992 strlen ("sk"),
993 "",
994 0,
997 &sk->ecdhe_key,
998 sizeof sk->ecdhe_key);
999 // RFC 9180 Section 7.1.2 states SerializePrivateKey() MUST clamp its output for X25519.
1000 // https://www.rfc-editor.org/errata/eid7121
1001 sk->ecdhe_key.d[0] &= 248;
1002 sk->ecdhe_key.d[31] &= 127;
1003 sk->ecdhe_key.d[31] |= 64;
1004
1005 return GNUNET_OK;
1006
1007}
1008
1009
1013{
1014 char ikm[64];
1015
1017 sizeof(ikm));
1018
1020 ikm,
1021 sizeof ikm,
1022 pk);
1023}
1024
1025
1026ssize_t
1029{
1030 switch (ntohl (key->type))
1031 {
1033 return sizeof (key->type) + sizeof (key->ecdhe_key);
1034 break;
1035 default:
1037 "Got key type %u\n", ntohl (key->type));
1038 GNUNET_break (0);
1039 }
1040 return -1;
1041}
1042
1043
1046 size_t len,
1047 struct
1049 key,
1050 size_t *read)
1051{
1052 ssize_t length;
1053 if (len < sizeof (key->type))
1054 return GNUNET_SYSERR;
1055 GNUNET_memcpy (&key->type,
1056 buffer,
1057 sizeof (key->type));
1059 if (len < length)
1060 return GNUNET_SYSERR;
1061 if (length < 0)
1062 return GNUNET_SYSERR;
1063 GNUNET_memcpy (&key->ecdhe_key,
1064 buffer + sizeof (key->type),
1065 length - sizeof (key->type));
1066 *read = length;
1067 return GNUNET_OK;
1068}
1069
1070
1071ssize_t
1074 key,
1075 void *buffer,
1076 size_t len)
1077{
1078 const ssize_t length = GNUNET_CRYPTO_hpke_sk_get_length (key);
1079 if (len < length)
1080 return -1;
1081 if (length < 0)
1082 return -2;
1083 GNUNET_memcpy (buffer, &(key->type), sizeof (key->type));
1084 GNUNET_memcpy (buffer + sizeof (key->type), &(key->ecdhe_key), length
1085 - sizeof (key->type));
1086 return length;
1087}
1088
1089
1093 privkey,
1095 *key)
1096{
1097 key->type = privkey->type;
1098 switch (ntohl (privkey->type))
1099 {
1102 &key->ecdhe_key);
1103 break;
1104 default:
1105 GNUNET_break (0);
1106 return GNUNET_SYSERR;
1107 }
1108 return GNUNET_OK;
1109}
static void compute_nonce(struct GNUNET_CRYPTO_HpkeContext *ctx, uint8_t *nonce)
static enum GNUNET_GenericReturnValue key_schedule(enum GNUNET_CRYPTO_HpkeRole role, enum GNUNET_CRYPTO_HpkeMode mode, const struct GNUNET_ShortHashCode *shared_secret, const uint8_t *info, size_t info_len, const uint8_t *psk, size_t psk_len, const uint8_t *psk_id, size_t psk_id_len, struct GNUNET_CRYPTO_HpkeContext *ctx)
static enum GNUNET_GenericReturnValue increment_seq(struct GNUNET_CRYPTO_HpkeContext *ctx)
static enum GNUNET_GenericReturnValue labeled_extract(const char *ctx_str, const void *salt, size_t salt_len, const void *label, size_t label_len, const void *ikm, size_t ikm_len, const uint8_t *suite_id, size_t suite_id_len, struct GNUNET_ShortHashCode *prk)
A RFC9180 inspired labeled extract.
Definition crypto_hpke.c:51
static enum GNUNET_GenericReturnValue verify_psk_inputs(enum GNUNET_CRYPTO_HpkeMode mode, const uint8_t *psk, size_t psk_len, const uint8_t *psk_id, size_t psk_id_len)
static uint8_t GNUNET_CRYPTO_HPKE_KEM_SUITE_ID[]
static enum GNUNET_GenericReturnValue GNUNET_CRYPTO_hpke_labeled_extract_and_expand(const void *dh, size_t dh_len, const char *extract_ctx, const char *expand_ctx, const void *extract_lbl, size_t extract_lbl_len, const void *expand_lbl, size_t expand_lbl_len, const uint8_t *kem_context, size_t kem_context_len, const uint8_t *suite_id, size_t suite_id_len, struct GNUNET_ShortHashCode *shared_secret)
static enum GNUNET_GenericReturnValue labeled_expand(const char *ctx_str, const struct GNUNET_ShortHashCode *prk, const char *label, size_t label_len, const void *info, size_t info_len, const uint8_t *suite_id, size_t suite_id_len, void *out_buf, uint16_t out_len)
A RFC9180 inspired labeled extract.
Definition crypto_hpke.c:94
static enum GNUNET_GenericReturnValue kem_encaps_norand(uint8_t *suite_id, size_t suite_id_len, const struct GNUNET_CRYPTO_HpkePublicKey *pkR, const struct GNUNET_CRYPTO_HpkeEncapsulation *c, const struct GNUNET_CRYPTO_HpkePrivateKey *skE, struct GNUNET_ShortHashCode *shared_secret)
static uint8_t GNUNET_CRYPTO_HPKE_KEM_ELLIGATOR_SUITE_ID[]
struct GNUNET_HashCode key
The key used in the DHT.
static struct GNUNET_FS_Handle * ctx
static OpusEncoder * enc
OPUS encoder.
struct GNUNET_CRYPTO_BlindablePrivateKey pk
Private key from command line option, or NULL.
static uint32_t type
Type string converted to DNS type value.
static struct GNUNET_CRYPTO_EddsaPublicKey pub
static struct GNUNET_CRYPTO_PowSalt salt
Salt for PoW calculations.
#define info
static unsigned char ikm[256/8]
The initial key material for the peer.
commonly used definitions; globals in this file are exempt from the rule that the module name ("commo...
static enum @52 mode
Should we do a PUT (mode = 0) or GET (mode = 1);.
void GNUNET_CRYPTO_ecdhe_key_create(struct GNUNET_CRYPTO_EcdhePrivateKey *pk)
Create a new private key.
Definition crypto_ecc.c:454
enum GNUNET_GenericReturnValue GNUNET_CRYPTO_eddsa_kem_decaps(const struct GNUNET_CRYPTO_EddsaPrivateKey *priv, const struct GNUNET_CRYPTO_HpkeEncapsulation *c, struct GNUNET_ShortHashCode *shared_secret)
Decapsulate a key for a private EdDSA key.
enum GNUNET_GenericReturnValue GNUNET_CRYPTO_x25519_ecdh(const struct GNUNET_CRYPTO_EcdhePrivateKey *sk, const struct GNUNET_CRYPTO_EcdhePublicKey *pk, struct GNUNET_CRYPTO_EcdhePublicKey *dh)
Derive key material from a ECDH public key and a private X25519 key.
Definition crypto_ecc.c:787
void GNUNET_CRYPTO_ecdhe_elligator_key_create(struct GNUNET_CRYPTO_ElligatorEcdhePrivateKey *sk)
Generates a private key for Curve25519.
enum GNUNET_GenericReturnValue GNUNET_CRYPTO_hpke_elligator_kem_encaps(const struct GNUNET_CRYPTO_HpkePublicKey *pkR, struct GNUNET_CRYPTO_HpkeEncapsulation *c, struct GNUNET_ShortHashCode *shared_secret)
Carries out ecdh encapsulation with given public key and the private key from a freshly created ephem...
enum GNUNET_GenericReturnValue GNUNET_CRYPTO_hpke_kem_decaps(const struct GNUNET_CRYPTO_HpkePrivateKey *skR, const struct GNUNET_CRYPTO_HpkeEncapsulation *c, struct GNUNET_ShortHashCode *shared_secret)
Decapsulate a key for a private X25519 key.
enum GNUNET_GenericReturnValue GNUNET_CRYPTO_hpke_kem_encaps_norand(const struct GNUNET_CRYPTO_HpkePublicKey *pkR, struct GNUNET_CRYPTO_HpkeEncapsulation *enc, const struct GNUNET_CRYPTO_HpkePrivateKey *skE, struct GNUNET_ShortHashCode *shared_secret)
Deterministic variant of GNUNET_CRYPTO_hpke_kem_encaps.
enum GNUNET_GenericReturnValue GNUNET_CRYPTO_hpke_elligator_kem_decaps(const struct GNUNET_CRYPTO_HpkePrivateKey *skR, const struct GNUNET_CRYPTO_HpkeEncapsulation *c, struct GNUNET_ShortHashCode *shared_secret)
Carries out ecdh decapsulation with own private key and the representative of the received public key...
void GNUNET_CRYPTO_ecdhe_elligator_decoding(struct GNUNET_CRYPTO_EcdhePublicKey *point, bool *high_y, const struct GNUNET_CRYPTO_ElligatorRepresentative *representative)
Clears the most significant bit and second most significant bit of the serialized representaive befor...
void GNUNET_CRYPTO_random_block(void *buffer, size_t length)
Fill block with a random values.
enum GNUNET_GenericReturnValue GNUNET_CRYPTO_ecdhe_elligator_key_get_public_norand(uint8_t random_tweak, const struct GNUNET_CRYPTO_ElligatorEcdhePrivateKey *sk, struct GNUNET_CRYPTO_EcdhePublicKey *pub, struct GNUNET_CRYPTO_ElligatorRepresentative *repr)
Generates a valid public key for elligator's inverse map by adding a lower order point to a prime ord...
enum GNUNET_GenericReturnValue GNUNET_CRYPTO_hpke_kem_encaps(const struct GNUNET_CRYPTO_HpkePublicKey *pub, struct GNUNET_CRYPTO_HpkeEncapsulation *c, struct GNUNET_ShortHashCode *shared_secret)
Encapsulate key material for a X25519 public key.
enum GNUNET_GenericReturnValue GNUNET_CRYPTO_ecdh_x25519(const struct GNUNET_CRYPTO_EcdhePrivateKey *priv, const struct GNUNET_CRYPTO_EcdhePublicKey *pub, struct GNUNET_CRYPTO_EcdhePublicKey *dh)
Derive key material from a EdDSA public key and a private ECDH key.
Definition crypto_ecc.c:803
enum GNUNET_GenericReturnValue GNUNET_CRYPTO_eddsa_kem_encaps(const struct GNUNET_CRYPTO_EddsaPublicKey *pub, struct GNUNET_CRYPTO_HpkeEncapsulation *c, struct GNUNET_ShortHashCode *shared_secret)
Encapsulate key material for a EdDSA public key.
enum GNUNET_GenericReturnValue GNUNET_CRYPTO_hpke_elligator_kem_encaps_norand(uint8_t random_tweak, const struct GNUNET_CRYPTO_HpkePublicKey *pkR, struct GNUNET_CRYPTO_HpkeEncapsulation *c, const struct GNUNET_CRYPTO_ElligatorEcdhePrivateKey *skE, struct GNUNET_ShortHashCode *shared_secret)
Carries out ecdh encapsulation with given public key and the private key from a freshly created ephem...
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:433
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:217
enum GNUNET_GenericReturnValue GNUNET_CRYPTO_hkdf_extract(struct GNUNET_ShortHashCode *prk, const void *salt, size_t salt_len, const void *ikm, size_t ikm_len)
HKDF-Extract using SHA256.
#define GNUNET_CRYPTO_hkdf_expand(result, out_len, prk,...)
HKDF-Expand using SHA256.
GNUNET_CRYPTO_HpkeKem
HPKE KEM identifier https://www.iana.org/assignments/hpke/hpke.xhtml.
ssize_t GNUNET_CRYPTO_write_hpke_pk_to_buffer(const struct GNUNET_CRYPTO_HpkePublicKey *key, void *buffer, size_t len)
Writes a GNUNET_CRYPTO_HpkePublicKey to a compact buffer.
#define GNUNET_log(kind,...)
ssize_t GNUNET_CRYPTO_hpke_sk_get_length(const struct GNUNET_CRYPTO_HpkePrivateKey *key)
Get the compacted length of a GNUNET_CRYPTO_HpkePrivateKey.
enum GNUNET_GenericReturnValue GNUNET_CRYPTO_read_hpke_pk_from_buffer(const void *buffer, size_t len, struct GNUNET_CRYPTO_HpkePublicKey *key, size_t *read)
Reads a GNUNET_CRYPTO_HpkePublicKey from a compact buffer.
enum GNUNET_GenericReturnValue GNUNET_CRYPTO_hpke_seal(struct GNUNET_CRYPTO_HpkeContext *ctx, const uint8_t *aad, size_t aad_len, const uint8_t *pt, size_t pt_len, uint8_t *ct, unsigned long long *ct_len_p)
RFC9180 HPKE encryption.
enum GNUNET_GenericReturnValue GNUNET_CRYPTO_hpke_sender_setup(const struct GNUNET_CRYPTO_HpkePublicKey *pkR, const uint8_t *info, size_t info_len, struct GNUNET_CRYPTO_HpkeEncapsulation *enc, struct GNUNET_CRYPTO_HpkeContext *ctx)
RFC9180 HPKE encryption.
ssize_t GNUNET_CRYPTO_hpke_pk_get_length(const struct GNUNET_CRYPTO_HpkePublicKey *key)
Get the compacted length of a GNUNET_CRYPTO_HpkePublicKey.
enum GNUNET_GenericReturnValue GNUNET_CRYPTO_hpke_seal_oneshot(const struct GNUNET_CRYPTO_HpkePublicKey *pkR, const uint8_t *info, size_t info_len, const uint8_t *aad, size_t aad_len, const uint8_t *pt, size_t pt_len, uint8_t *ct, unsigned long long *ct_len_p)
RFC9180 HPKE encryption.
uint64_t GNUNET_ntohll(uint64_t n)
Convert unsigned 64-bit integer to host byte order.
ssize_t GNUNET_CRYPTO_write_hpke_sk_to_buffer(const struct GNUNET_CRYPTO_HpkePrivateKey *key, void *buffer, size_t len)
Writes a GNUNET_CRYPTO_HpkePrivateKey to a compact buffer.
enum GNUNET_GenericReturnValue GNUNET_CRYPTO_hpke_sk_create(enum GNUNET_CRYPTO_HpkeKeyType type, struct GNUNET_CRYPTO_HpkePrivateKey *pk)
Create a new GNUNET_CRYPTO_HpkePrivateKey of specific type.
enum GNUNET_GenericReturnValue GNUNET_CRYPTO_hpke_sk_to_x25519(const struct GNUNET_CRYPTO_BlindablePrivateKey *sk, struct GNUNET_CRYPTO_HpkePrivateKey *x25519)
Convert a GNUnet identity key to a key sutiable for HPKE (X25519)
enum GNUNET_GenericReturnValue GNUNET_CRYPTO_hpke_open_oneshot(const struct GNUNET_CRYPTO_HpkePrivateKey *skR, const uint8_t *info, size_t info_len, const uint8_t *aad, size_t aad_len, const uint8_t *ct, size_t ct_len, uint8_t *pt, unsigned long long *pt_len_p)
RFC9180 HPKE encryption.
enum GNUNET_GenericReturnValue GNUNET_CRYPTO_hpke_open(struct GNUNET_CRYPTO_HpkeContext *ctx, const uint8_t *aad, size_t aad_len, const uint8_t *ct, size_t ct_len, uint8_t *pt, unsigned long long *pt_len)
RFC9180 HPKE encryption.
enum GNUNET_GenericReturnValue GNUNET_CRYPTO_hpke_sender_setup2(enum GNUNET_CRYPTO_HpkeKem kem, enum GNUNET_CRYPTO_HpkeMode mode, struct GNUNET_CRYPTO_HpkePrivateKey *skE, struct GNUNET_CRYPTO_HpkePrivateKey *skS, const struct GNUNET_CRYPTO_HpkePublicKey *pkR, const uint8_t *info, size_t info_len, const uint8_t *psk, size_t psk_len, const uint8_t *psk_id, size_t psk_id_len, struct GNUNET_CRYPTO_HpkeEncapsulation *enc, struct GNUNET_CRYPTO_HpkeContext *ctx)
RFC9180 HPKE encryption.
enum GNUNET_GenericReturnValue GNUNET_CRYPTO_hpke_receiver_setup2(enum GNUNET_CRYPTO_HpkeKem kem, enum GNUNET_CRYPTO_HpkeMode mode, const struct GNUNET_CRYPTO_HpkeEncapsulation *enc, const struct GNUNET_CRYPTO_HpkePrivateKey *skR, const struct GNUNET_CRYPTO_HpkePublicKey *pkS, const uint8_t *info, size_t info_len, const uint8_t *psk, size_t psk_len, const uint8_t *psk_id, size_t psk_id_len, struct GNUNET_CRYPTO_HpkeContext *ctx)
RFC9180 HPKE encryption.
enum GNUNET_GenericReturnValue GNUNET_CRYPTO_hpke_sk_get_public(const struct GNUNET_CRYPTO_HpkePrivateKey *privkey, struct GNUNET_CRYPTO_HpkePublicKey *key)
Retrieves the GNUNET_CRYPTO_HpkePublicKey representation of a GNUNET_CRYPTO_HpkePrivateKey.
uint64_t GNUNET_htonll(uint64_t n)
Convert unsigned 64-bit integer to network byte order.
#define GNUNET_CRYPTO_HPKE_NONCE_LEN
void GNUNET_CRYPTO_hpke_sk_clear(struct GNUNET_CRYPTO_HpkePrivateKey *key)
Clear memory that was used to store a GNUNET_CRYPTO_HpkePrivateKey.
#define GNUNET_CRYPTO_kdf_arg(d, s)
#define GNUNET_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
enum GNUNET_GenericReturnValue GNUNET_CRYPTO_hpke_receiver_setup(const struct GNUNET_CRYPTO_HpkeEncapsulation *enc, const struct GNUNET_CRYPTO_HpkePrivateKey *skR, const uint8_t *info, size_t info_len, struct GNUNET_CRYPTO_HpkeContext *ctx)
RFC9180 HPKE encryption.
GNUNET_CRYPTO_HpkeMode
HPKE RFC 9180.
enum GNUNET_GenericReturnValue GNUNET_CRYPTO_hpke_sk_create2(enum GNUNET_CRYPTO_HpkeKeyType type, const char *ikm, size_t ikm_len, struct GNUNET_CRYPTO_HpkePrivateKey *sk)
Create a new GNUNET_CRYPTO_HpkePrivateKey of specific type.
GNUNET_GenericReturnValue
Named constants for return values.
enum GNUNET_GenericReturnValue GNUNET_CRYPTO_hpke_pk_to_x25519(const struct GNUNET_CRYPTO_BlindablePublicKey *pk, struct GNUNET_CRYPTO_HpkePublicKey *x25519)
Convert a GNUnet identity key to a key sutiable for HPKE (X25519)
enum GNUNET_GenericReturnValue GNUNET_CRYPTO_read_hpke_sk_from_buffer(const void *buffer, size_t len, struct GNUNET_CRYPTO_HpkePrivateKey *key, size_t *read)
Reads a GNUNET_CRYPTO_HpkePrivateKey from a compact buffer.
GNUNET_CRYPTO_HpkeKeyType
Key type for the hpke public key union.
GNUNET_CRYPTO_HpkeRole
Role of the HPKE participant.
@ GNUNET_CRYPTO_HPKE_KEM_DH_X25519_HKDF256
@ GNUNET_CRYPTO_HPKE_KEM_DH_X25519ELLIGATOR_HKDF256
@ GNUNET_PUBLIC_KEY_TYPE_EDDSA
EDDSA identity.
@ GNUNET_PUBLIC_KEY_TYPE_ECDSA
The identity type.
@ GNUNET_CRYPTO_HPKE_MODE_PSK
@ GNUNET_CRYPTO_HPKE_MODE_AUTH_PSK
@ GNUNET_CRYPTO_HPKE_MODE_BASE
@ GNUNET_CRYPTO_HPKE_MODE_AUTH
@ GNUNET_OK
@ GNUNET_SYSERR
@ GNUNET_CRYPTO_HPKE_KEY_TYPE_X25519
Type for X25519 hybrid public key encryption.
@ GNUNET_CRYPTO_HPKE_ROLE_R
@ GNUNET_CRYPTO_HPKE_ROLE_S
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur.
@ GNUNET_ERROR_TYPE_ERROR
A private key for an identity as per LSD0001.
struct GNUNET_CRYPTO_EcdsaPrivateKey ecdsa_key
An ECDSA identity key.
uint32_t type
Type of public key.
struct GNUNET_CRYPTO_EddsaPrivateKey eddsa_key
AN EdDSA identtiy key.
An identity key as per LSD0001.
unsigned char d[256/8]
d is a value mod n, where n has at most 256 bits.
Public ECC key (always for Curve25519) encoded in a format suitable for network transmission and encr...
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...
unsigned char d[256/8]
d is a value mod n, where n has at most 256 bits.
Private ECC key encoded for transmission.
unsigned char d[256/8]
d is a value mod n, where n has at most 256 bits.
Public ECC key (always for curve Ed25519) encoded in a format suitable for network transmission and E...
unsigned char q_y[256/8]
Point Q consists of a y-value mod p (256 bits); the x-value is always positive.
Special private ECC key generated by GNUNET_CRYPTO_ecdhe_elligator_key_create.
Elligator representative (always for Curve25519)
uint8_t r[256/8]
Represents an element of Curve25519 finite field.
HPKE DHKEM encapsulation (X25519) See RFC 9180.
A public key used for decryption.
struct GNUNET_CRYPTO_EcdhePrivateKey ecdhe_key
An ECDHE/X25519 key.
A public key used for encryption.
struct GNUNET_CRYPTO_EcdhePublicKey ecdhe_key
An ECDHE/X25519 key.
A 256-bit hashcode.