tor  0.4.1.0-alpha-dev
crypto_ed25519.c
Go to the documentation of this file.
1 /* Copyright (c) 2013-2019, The Tor Project, Inc. */
2 /* See LICENSE for licensing information */
3 
18 #define CRYPTO_ED25519_PRIVATE
19 #include "orconfig.h"
20 #ifdef HAVE_SYS_STAT_H
21 #include <sys/stat.h>
22 #endif
23 
24 #include "lib/ctime/di_ops.h"
31 #include "lib/log/log.h"
32 #include "lib/log/util_bug.h"
33 #include "lib/encoding/binascii.h"
34 #include "lib/string/util_string.h"
35 
36 #include "ed25519/ref10/ed25519_ref10.h"
37 #include "ed25519/donna/ed25519_donna_tor.h"
38 
39 #include <string.h>
40 #include <errno.h>
41 
42 static void pick_ed25519_impl(void);
43 
45 typedef struct {
46  int (*selftest)(void);
47 
48  int (*seckey)(unsigned char *);
49  int (*seckey_expand)(unsigned char *, const unsigned char *);
50  int (*pubkey)(unsigned char *, const unsigned char *);
51  int (*keygen)(unsigned char *, unsigned char *);
52 
53  int (*open)(const unsigned char *, const unsigned char *, size_t, const
54  unsigned char *);
55  int (*sign)(unsigned char *, const unsigned char *, size_t,
56  const unsigned char *, const unsigned char *);
57  int (*open_batch)(const unsigned char **, size_t *, const unsigned char **,
58  const unsigned char **, size_t, int *);
59 
60  int (*blind_secret_key)(unsigned char *, const unsigned char *,
61  const unsigned char *);
62  int (*blind_public_key)(unsigned char *, const unsigned char *,
63  const unsigned char *);
64 
65  int (*pubkey_from_curve25519_pubkey)(unsigned char *, const unsigned char *,
66  int);
67 
68  int (*ed25519_scalarmult_with_group_order)(unsigned char *,
69  const unsigned char *);
71 
74 static const ed25519_impl_t impl_ref10 = {
75  NULL,
76 
77  ed25519_ref10_seckey,
78  ed25519_ref10_seckey_expand,
79  ed25519_ref10_pubkey,
80  ed25519_ref10_keygen,
81 
82  ed25519_ref10_open,
83  ed25519_ref10_sign,
84  NULL,
85 
86  ed25519_ref10_blind_secret_key,
87  ed25519_ref10_blind_public_key,
88 
89  ed25519_ref10_pubkey_from_curve25519_pubkey,
90  ed25519_ref10_scalarmult_with_group_order,
91 };
92 
95 static const ed25519_impl_t impl_donna = {
96  ed25519_donna_selftest,
97 
98  ed25519_donna_seckey,
99  ed25519_donna_seckey_expand,
100  ed25519_donna_pubkey,
101  ed25519_donna_keygen,
102 
103  ed25519_donna_open,
104  ed25519_donna_sign,
105  ed25519_sign_open_batch_donna,
106 
107  ed25519_donna_blind_secret_key,
108  ed25519_donna_blind_public_key,
109 
110  ed25519_donna_pubkey_from_curve25519_pubkey,
111  ed25519_donna_scalarmult_with_group_order,
112 };
113 
116 static const ed25519_impl_t *ed25519_impl = NULL;
117 
123 static inline const ed25519_impl_t *
125 {
126  if (BUG(ed25519_impl == NULL)) {
127  pick_ed25519_impl(); // LCOV_EXCL_LINE - We always call ed25519_init().
128  }
129  return ed25519_impl;
130 }
131 
132 #ifdef TOR_UNIT_TESTS
133 
135 static const ed25519_impl_t *saved_ed25519_impl = NULL;
139 void
140 crypto_ed25519_testing_force_impl(const char *name)
141 {
142  tor_assert(saved_ed25519_impl == NULL);
143  saved_ed25519_impl = ed25519_impl;
144  if (! strcmp(name, "donna")) {
146  } else {
147  tor_assert(!strcmp(name, "ref10"));
149  }
150 }
154 void
155 crypto_ed25519_testing_restore_impl(void)
156 {
157  ed25519_impl = saved_ed25519_impl;
158  saved_ed25519_impl = NULL;
159 }
160 #endif /* defined(TOR_UNIT_TESTS) */
161 
167 int
169  int extra_strong)
170 {
171  int r;
172  uint8_t seed[32];
173  if (extra_strong)
174  crypto_strongest_rand(seed, sizeof(seed));
175  else
176  crypto_rand((char*)seed, sizeof(seed));
177 
178  r = get_ed_impl()->seckey_expand(seckey_out->seckey, seed);
179  memwipe(seed, 0, sizeof(seed));
180 
181  return r < 0 ? -1 : 0;
182 }
183 
188 int
190  const uint8_t *seed)
191 {
192  if (get_ed_impl()->seckey_expand(seckey_out->seckey, seed) < 0)
193  return -1;
194  return 0;
195 }
196 
201 int
203  const ed25519_secret_key_t *seckey)
204 {
205  if (get_ed_impl()->pubkey(pubkey_out->pubkey, seckey->seckey) < 0)
206  return -1;
207  return 0;
208 }
209 
213 int
214 ed25519_keypair_generate(ed25519_keypair_t *keypair_out, int extra_strong)
215 {
216  if (ed25519_secret_key_generate(&keypair_out->seckey, extra_strong) < 0)
217  return -1;
218  if (ed25519_public_key_generate(&keypair_out->pubkey,
219  &keypair_out->seckey)<0)
220  return -1;
221  return 0;
222 }
223 
226 int
228 {
229  return tor_mem_is_zero((char*)pubkey->pubkey, ED25519_PUBKEY_LEN);
230 }
231 
232 /* Return a heap-allocated array that contains <b>msg</b> prefixed by the
233  * string <b>prefix_str</b>. Set <b>final_msg_len_out</b> to the size of the
234  * final array. If an error occurred, return NULL. It's the responsibility of
235  * the caller to free the returned array. */
236 static uint8_t *
237 get_prefixed_msg(const uint8_t *msg, size_t msg_len,
238  const char *prefix_str,
239  size_t *final_msg_len_out)
240 {
241  size_t prefixed_msg_len, prefix_len;
242  uint8_t *prefixed_msg;
243 
244  tor_assert(prefix_str);
245  tor_assert(final_msg_len_out);
246 
247  prefix_len = strlen(prefix_str);
248 
249  /* msg_len + strlen(prefix_str) must not overflow. */
250  if (msg_len > SIZE_T_CEILING - prefix_len) {
251  return NULL;
252  }
253 
254  prefixed_msg_len = msg_len + prefix_len;
255  prefixed_msg = tor_malloc_zero(prefixed_msg_len);
256 
257  memcpy(prefixed_msg, prefix_str, prefix_len);
258  memcpy(prefixed_msg + prefix_len, msg, msg_len);
259 
260  *final_msg_len_out = prefixed_msg_len;
261  return prefixed_msg;
262 }
263 
270 int
272  const uint8_t *msg, size_t len,
273  const ed25519_keypair_t *keypair)
274 {
275  if (get_ed_impl()->sign(signature_out->sig, msg, len,
276  keypair->seckey.seckey,
277  keypair->pubkey.pubkey) < 0) {
278  return -1;
279  }
280 
281  return 0;
282 }
283 
289 ed25519_sign_prefixed,(ed25519_signature_t *signature_out,
290  const uint8_t *msg, size_t msg_len,
291  const char *prefix_str,
292  const ed25519_keypair_t *keypair))
293 {
294  int retval;
295  size_t prefixed_msg_len;
296  uint8_t *prefixed_msg;
297 
298  tor_assert(prefix_str);
299 
300  prefixed_msg = get_prefixed_msg(msg, msg_len, prefix_str,
301  &prefixed_msg_len);
302  if (BUG(!prefixed_msg)) {
303  /* LCOV_EXCL_START -- only possible when the message and prefix are
304  * ridiculously huge */
305  log_warn(LD_GENERAL, "Failed to get prefixed msg.");
306  return -1;
307  /* LCOV_EXCL_STOP */
308  }
309 
310  retval = ed25519_sign(signature_out,
311  prefixed_msg, prefixed_msg_len,
312  keypair);
313  tor_free(prefixed_msg);
314 
315  return retval;
316 }
317 
325 ed25519_checksig,(const ed25519_signature_t *signature,
326  const uint8_t *msg, size_t len,
327  const ed25519_public_key_t *pubkey))
328 {
329  return
330  get_ed_impl()->open(signature->sig, msg, len, pubkey->pubkey) < 0 ? -1 : 0;
331 }
332 
338 int
340  const uint8_t *msg, size_t msg_len,
341  const char *prefix_str,
342  const ed25519_public_key_t *pubkey)
343 {
344  int retval;
345  size_t prefixed_msg_len;
346  uint8_t *prefixed_msg;
347 
348  prefixed_msg = get_prefixed_msg(msg, msg_len, prefix_str,
349  &prefixed_msg_len);
350  if (BUG(!prefixed_msg)) {
351  /* LCOV_EXCL_START -- only possible when the message and prefix are
352  * ridiculously huge */
353  log_warn(LD_GENERAL, "Failed to get prefixed msg.");
354  return -1;
355  /* LCOV_EXCL_STOP */
356  }
357 
358  retval = ed25519_checksig(signature,
359  prefixed_msg, prefixed_msg_len,
360  pubkey);
361  tor_free(prefixed_msg);
362 
363  return retval;
364 }
365 
374 ed25519_checksig_batch,(int *okay_out,
375  const ed25519_checkable_t *checkable,
376  int n_checkable))
377 {
378  int i, res;
379  const ed25519_impl_t *impl = get_ed_impl();
380 
381  if (impl->open_batch == NULL) {
382  /* No batch verification implementation available, fake it by checking the
383  * each signature individually.
384  */
385  res = 0;
386  for (i = 0; i < n_checkable; ++i) {
387  const ed25519_checkable_t *ch = &checkable[i];
388  int r = ed25519_checksig(&ch->signature, ch->msg, ch->len, ch->pubkey);
389  if (r < 0)
390  --res;
391  if (okay_out)
392  okay_out[i] = (r == 0);
393  }
394  } else {
395  /* ed25519-donna style batch verification available.
396  *
397  * Theoretically, this should only be called if n_checkable >= 3, since
398  * that's the threshold where the batch verification actually kicks in,
399  * but the only difference is a few mallocs/frees.
400  */
401  const uint8_t **ms;
402  size_t *lens;
403  const uint8_t **pks;
404  const uint8_t **sigs;
405  int *oks;
406  int all_ok;
407 
408  ms = tor_calloc(n_checkable, sizeof(uint8_t*));
409  lens = tor_calloc(n_checkable, sizeof(size_t));
410  pks = tor_calloc(n_checkable, sizeof(uint8_t*));
411  sigs = tor_calloc(n_checkable, sizeof(uint8_t*));
412  oks = okay_out ? okay_out : tor_calloc(n_checkable, sizeof(int));
413 
414  for (i = 0; i < n_checkable; ++i) {
415  ms[i] = checkable[i].msg;
416  lens[i] = checkable[i].len;
417  pks[i] = checkable[i].pubkey->pubkey;
418  sigs[i] = checkable[i].signature.sig;
419  oks[i] = 0;
420  }
421 
422  res = 0;
423  all_ok = impl->open_batch(ms, lens, pks, sigs, n_checkable, oks);
424  for (i = 0; i < n_checkable; ++i) {
425  if (!oks[i])
426  --res;
427  }
428  /* XXX: For now sanity check oks with the return value. Once we have
429  * more confidence in the code, if `all_ok == 0` we can skip iterating
430  * over oks since all the signatures were found to be valid.
431  */
432  tor_assert(((res == 0) && !all_ok) || ((res < 0) && all_ok));
433 
434  tor_free(ms);
435  tor_free(lens);
436  tor_free(pks);
437  tor_free(sigs);
438  if (! okay_out)
439  tor_free(oks);
440  }
441 
442  return res;
443 }
444 
454 int
456  int *signbit_out,
457  const curve25519_keypair_t *inp)
458 {
459  const char string[] = "Derive high part of ed25519 key from curve25519 key";
460  ed25519_public_key_t pubkey_check;
461  crypto_digest_t *ctx;
462  uint8_t sha512_output[DIGEST512_LEN];
463 
464  memcpy(out->seckey.seckey, inp->seckey.secret_key, 32);
465 
466  ctx = crypto_digest512_new(DIGEST_SHA512);
467  crypto_digest_add_bytes(ctx, (const char*)out->seckey.seckey, 32);
468  crypto_digest_add_bytes(ctx, (const char*)string, sizeof(string));
469  crypto_digest_get_digest(ctx, (char *)sha512_output, sizeof(sha512_output));
470  crypto_digest_free(ctx);
471  memcpy(out->seckey.seckey + 32, sha512_output, 32);
472 
473  ed25519_public_key_generate(&out->pubkey, &out->seckey);
474 
475  *signbit_out = out->pubkey.pubkey[31] >> 7;
476 
477  ed25519_public_key_from_curve25519_public_key(&pubkey_check, &inp->pubkey,
478  *signbit_out);
479 
480  tor_assert(fast_memeq(pubkey_check.pubkey, out->pubkey.pubkey, 32));
481 
482  memwipe(&pubkey_check, 0, sizeof(pubkey_check));
483  memwipe(sha512_output, 0, sizeof(sha512_output));
484 
485  return 0;
486 }
487 
492 int
494  const curve25519_public_key_t *pubkey_in,
495  int signbit)
496 {
497  return get_ed_impl()->pubkey_from_curve25519_pubkey(pubkey->pubkey,
498  pubkey_in->public_key,
499  signbit);
500 }
501 
513 int
515  const ed25519_keypair_t *inp,
516  const uint8_t *param)
517 {
518  ed25519_public_key_t pubkey_check;
519 
520  get_ed_impl()->blind_secret_key(out->seckey.seckey,
521  inp->seckey.seckey, param);
522 
523  if (ed25519_public_blind(&pubkey_check, &inp->pubkey, param) < 0) {
524  return -1;
525  }
526  ed25519_public_key_generate(&out->pubkey, &out->seckey);
527 
528  tor_assert(fast_memeq(pubkey_check.pubkey, out->pubkey.pubkey, 32));
529 
530  memwipe(&pubkey_check, 0, sizeof(pubkey_check));
531 
532  return 0;
533 }
534 
540 int
542  const ed25519_public_key_t *inp,
543  const uint8_t *param)
544 {
545  return get_ed_impl()->blind_public_key(out->pubkey, inp->pubkey, param);
546 }
547 
552 int
554  const char *filename,
555  const char *tag)
556 {
557  return crypto_write_tagged_contents_to_file(filename,
558  "ed25519v1-secret",
559  tag,
560  seckey->seckey,
561  sizeof(seckey->seckey));
562 }
563 
569 int
571  char **tag_out,
572  const char *filename)
573 {
574  ssize_t len;
575 
576  len = crypto_read_tagged_contents_from_file(filename, "ed25519v1-secret",
577  tag_out, seckey_out->seckey,
578  sizeof(seckey_out->seckey));
579  if (len == sizeof(seckey_out->seckey)) {
580  return 0;
581  } else if (len >= 0) {
582  errno = EINVAL;
583  }
584 
585  tor_free(*tag_out);
586  return -1;
587 }
588 
593 int
595  const char *filename,
596  const char *tag)
597 {
598  return crypto_write_tagged_contents_to_file(filename,
599  "ed25519v1-public",
600  tag,
601  pubkey->pubkey,
602  sizeof(pubkey->pubkey));
603 }
604 
609 int
611  char **tag_out,
612  const char *filename)
613 {
614  ssize_t len;
615 
616  len = crypto_read_tagged_contents_from_file(filename, "ed25519v1-public",
617  tag_out, pubkey_out->pubkey,
618  sizeof(pubkey_out->pubkey));
619  if (len == sizeof(pubkey_out->pubkey)) {
620  return 0;
621  } else if (len >= 0) {
622  errno = EINVAL;
623  }
624 
625  tor_free(*tag_out);
626  return -1;
627 }
628 
630 void
632 {
633  if (! kp)
634  return;
635 
636  memwipe(kp, 0, sizeof(*kp));
637  tor_free(kp);
638 }
639 
641 int
643  const ed25519_public_key_t *key2)
644 {
645  tor_assert(key1);
646  tor_assert(key2);
647  return tor_memeq(key1->pubkey, key2->pubkey, ED25519_PUBKEY_LEN);
648 }
649 
653 void
655  const ed25519_public_key_t *src)
656 {
657  tor_assert(dest);
658  tor_assert(src);
659  memcpy(dest, src, sizeof(ed25519_public_key_t));
660 }
661 
664 MOCK_IMPL(STATIC int,
665 ed25519_impl_spot_check,(void))
666 {
667  static const uint8_t alicesk[32] = {
668  0xc5,0xaa,0x8d,0xf4,0x3f,0x9f,0x83,0x7b,
669  0xed,0xb7,0x44,0x2f,0x31,0xdc,0xb7,0xb1,
670  0x66,0xd3,0x85,0x35,0x07,0x6f,0x09,0x4b,
671  0x85,0xce,0x3a,0x2e,0x0b,0x44,0x58,0xf7
672  };
673  static const uint8_t alicepk[32] = {
674  0xfc,0x51,0xcd,0x8e,0x62,0x18,0xa1,0xa3,
675  0x8d,0xa4,0x7e,0xd0,0x02,0x30,0xf0,0x58,
676  0x08,0x16,0xed,0x13,0xba,0x33,0x03,0xac,
677  0x5d,0xeb,0x91,0x15,0x48,0x90,0x80,0x25
678  };
679  static const uint8_t alicemsg[2] = { 0xaf, 0x82 };
680  static const uint8_t alicesig[64] = {
681  0x62,0x91,0xd6,0x57,0xde,0xec,0x24,0x02,
682  0x48,0x27,0xe6,0x9c,0x3a,0xbe,0x01,0xa3,
683  0x0c,0xe5,0x48,0xa2,0x84,0x74,0x3a,0x44,
684  0x5e,0x36,0x80,0xd7,0xdb,0x5a,0xc3,0xac,
685  0x18,0xff,0x9b,0x53,0x8d,0x16,0xf2,0x90,
686  0xae,0x67,0xf7,0x60,0x98,0x4d,0xc6,0x59,
687  0x4a,0x7c,0x15,0xe9,0x71,0x6e,0xd2,0x8d,
688  0xc0,0x27,0xbe,0xce,0xea,0x1e,0xc4,0x0a
689  };
690  const ed25519_impl_t *impl = get_ed_impl();
691  uint8_t sk[ED25519_SECKEY_LEN];
692  uint8_t pk[ED25519_PUBKEY_LEN];
693  uint8_t sig[ED25519_SIG_LEN];
694  int r = 0;
695 
696  /* Some implementations (eg: The modified Ed25519-donna) have handy self-test
697  * code that sanity-checks the internals. If present, use that to screen out
698  * catastrophic errors like massive compiler failure.
699  */
700  if (impl->selftest && impl->selftest() != 0)
701  goto fail;
702 
703  /* Validate results versus known answer tests. People really should be
704  * running "make test" instead of relying on this, but it's better than
705  * nothing.
706  *
707  * Test vectors taken from "EdDSA & Ed25519 - 6. Test Vectors for Ed25519
708  * (TEST3)" (draft-josefsson-eddsa-ed25519-03).
709  */
710 
711  /* Key expansion, public key derivation. */
712  if (impl->seckey_expand(sk, alicesk) < 0)
713  goto fail;
714  if (impl->pubkey(pk, sk) < 0)
715  goto fail;
716  if (fast_memneq(pk, alicepk, ED25519_PUBKEY_LEN))
717  goto fail;
718 
719  /* Signing, verification. */
720  if (impl->sign(sig, alicemsg, sizeof(alicemsg), sk, pk) < 0)
721  return -1;
722  if (fast_memneq(sig, alicesig, ED25519_SIG_LEN))
723  return -1;
724  if (impl->open(sig, alicemsg, sizeof(alicemsg), pk) < 0)
725  return -1;
726 
727  /* XXX/yawning: Someone that's more paranoid than I am, can write "Assume
728  * ref0 is canonical, and fuzz impl against it" if they want, but I doubt
729  * that will catch anything that the known answer tests won't.
730  */
731  goto end;
732 
733  // LCOV_EXCL_START -- We can only reach this if our ed25519 implementation is
734  // broken.
735  fail:
736  r = -1;
737  // LCOV_EXCL_STOP
738  end:
739  return r;
740 }
741 
745 void
747 {
748  if (use_donna)
750  else
752 }
753 
755 static void
757 {
759 
760  if (ed25519_impl_spot_check() == 0)
761  return;
762 
763  /* LCOV_EXCL_START
764  * unreachable unless ed25519_donna is broken */
765  log_warn(LD_CRYPTO, "The Ed25519-donna implementation seems broken; using "
766  "the ref10 implementation.");
768  /* LCOV_EXCL_STOP */
769 }
770 
771 /* Initialize the Ed25519 implementation. This is necessary if you're
772  * going to use them in a multithreaded setting, and not otherwise. */
773 void
774 ed25519_init(void)
775 {
777 }
778 
779 /* Return true if <b>point</b> is the identity element of the ed25519 group. */
780 static int
781 ed25519_point_is_identity_element(const uint8_t *point)
782 {
783  /* The identity element in ed25159 is the point with coordinates (0,1). */
784  static const uint8_t ed25519_identity[32] = {
785  0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
786  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
787  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
788  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
789  tor_assert(sizeof(ed25519_identity) == ED25519_PUBKEY_LEN);
790  return tor_memeq(point, ed25519_identity, sizeof(ed25519_identity));
791 }
792 
795 int
797 {
798  uint8_t result[32] = {9};
799 
800  /* First check that we were not given the identity element */
801  if (ed25519_point_is_identity_element(pubkey->pubkey)) {
802  log_warn(LD_CRYPTO, "ed25519 pubkey is the identity");
803  return -1;
804  }
805 
806  /* For any point on the curve, doing l*point should give the identity element
807  * (where l is the group order). Do the computation and check that the
808  * identity element is returned. */
809  if (get_ed_impl()->ed25519_scalarmult_with_group_order(result,
810  pubkey->pubkey) < 0) {
811  log_warn(LD_CRYPTO, "ed25519 group order scalarmult failed");
812  return -1;
813  }
814 
815  if (!ed25519_point_is_identity_element(result)) {
816  log_warn(LD_CRYPTO, "ed25519 validation failed");
817  return -1;
818  }
819 
820  return 0;
821 }
int ed25519_checksig_prefixed(const ed25519_signature_t *signature, const uint8_t *msg, size_t msg_len, const char *prefix_str, const ed25519_public_key_t *pubkey)
void crypto_digest_add_bytes(crypto_digest_t *digest, const char *data, size_t len)
crypto_digest_t * crypto_digest512_new(digest_algorithm_t algorithm)
Common functions for using (pseudo-)random number generators.
Headers for di_ops.c.
int ed25519_pubkey_read_from_file(ed25519_public_key_t *pubkey_out, char **tag_out, const char *filename)
#define DIGEST512_LEN
Definition: digest_sizes.h:25
const ed25519_public_key_t * pubkey
int ed25519_secret_key_generate(ed25519_secret_key_t *seckey_out, int extra_strong)
int tor_mem_is_zero(const char *mem, size_t len)
Definition: util_string.c:74
#define LD_GENERAL
Definition: log.h:58
int ed25519_public_key_generate(ed25519_public_key_t *pubkey_out, const ed25519_secret_key_t *seckey)
int ed25519_public_key_from_curve25519_public_key(ed25519_public_key_t *pubkey, const curve25519_public_key_t *pubkey_in, int signbit)
int ed25519_keypair_from_curve25519_keypair(ed25519_keypair_t *out, int *signbit_out, const curve25519_keypair_t *inp)
#define tor_free(p)
Definition: malloc.h:52
Header for util_string.c.
void memwipe(void *mem, uint8_t byte, size_t sz)
Definition: crypto_util.c:57
int ed25519_keypair_blind(ed25519_keypair_t *out, const ed25519_keypair_t *inp, const uint8_t *param)
int ed25519_pubkey_eq(const ed25519_public_key_t *key1, const ed25519_public_key_t *key2)
int crypto_write_tagged_contents_to_file(const char *fname, const char *typestring, const char *tag, const uint8_t *data, size_t datalen)
Definition: crypto_format.c:42
Common functions for cryptographic routines.
tor_assert(buffer)
ssize_t crypto_read_tagged_contents_from_file(const char *fname, const char *typestring, char **tag_out, uint8_t *data_out, ssize_t data_out_len)
Definition: crypto_format.c:77
void ed25519_set_impl_params(int use_donna)
Header for crypto_format.c.
uint8_t seckey[ED25519_SECKEY_LEN]
int tor_memeq(const void *a, const void *b, size_t sz)
Definition: di_ops.c:107
int ed25519_seckey_read_from_file(ed25519_secret_key_t *seckey_out, char **tag_out, const char *filename)
int ed25519_seckey_write_to_file(const ed25519_secret_key_t *seckey, const char *filename, const char *tag)
#define SIZE_T_CEILING
Definition: torint.h:126
int ed25519_public_key_is_zero(const ed25519_public_key_t *pubkey)
void ed25519_pubkey_copy(ed25519_public_key_t *dest, const ed25519_public_key_t *src)
void crypto_digest_get_digest(crypto_digest_t *digest, char *out, size_t out_len)
ed25519_signature_t signature
Header for binascii.c.
Header for crypto_ed25519.c.
static const ed25519_impl_t * get_ed_impl(void)
Headers for crypto_digest.c.
void ed25519_keypair_free_(ed25519_keypair_t *kp)
int ed25519_pubkey_write_to_file(const ed25519_public_key_t *pubkey, const char *filename, const char *tag)
MOCK_IMPL(int, ed25519_sign_prefixed,(ed25519_signature_t *signature_out, const uint8_t *msg, size_t msg_len, const char *prefix_str, const ed25519_keypair_t *keypair))
static const ed25519_impl_t impl_donna
void crypto_strongest_rand(uint8_t *out, size_t out_len)
Definition: crypto_rand.c:339
int ed25519_sign(ed25519_signature_t *signature_out, const uint8_t *msg, size_t len, const ed25519_keypair_t *keypair)
int ed25519_keypair_generate(ed25519_keypair_t *keypair_out, int extra_strong)
int ed25519_secret_key_from_seed(ed25519_secret_key_t *seckey_out, const uint8_t *seed)
Headers for log.c.
#define LD_CRYPTO
Definition: log.h:60
static const ed25519_impl_t impl_ref10
Macros to manage assertions, fatal and non-fatal.
static void pick_ed25519_impl(void)
Header for crypto_curve25519.c.
int ed25519_validate_pubkey(const ed25519_public_key_t *pubkey)
const uint8_t * msg
static const ed25519_impl_t * ed25519_impl
int ed25519_public_blind(ed25519_public_key_t *out, const ed25519_public_key_t *inp, const uint8_t *param)