18 #define CRYPTO_ED25519_PRIVATE
20 #ifdef HAVE_SYS_STAT_H
36 #include "ed25519/ref10/ed25519_ref10.h"
37 #include "ed25519/donna/ed25519_donna_tor.h"
46 int (*selftest)(void);
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 *);
53 int (*open)(
const unsigned char *,
const unsigned char *, size_t,
const
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 *);
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 *);
65 int (*pubkey_from_curve25519_pubkey)(
unsigned char *,
const unsigned char *,
68 int (*ed25519_scalarmult_with_group_order)(
unsigned char *,
69 const unsigned char *);
78 ed25519_ref10_seckey_expand,
86 ed25519_ref10_blind_secret_key,
87 ed25519_ref10_blind_public_key,
89 ed25519_ref10_pubkey_from_curve25519_pubkey,
90 ed25519_ref10_scalarmult_with_group_order,
96 ed25519_donna_selftest,
99 ed25519_donna_seckey_expand,
100 ed25519_donna_pubkey,
101 ed25519_donna_keygen,
105 ed25519_sign_open_batch_donna,
107 ed25519_donna_blind_secret_key,
108 ed25519_donna_blind_public_key,
110 ed25519_donna_pubkey_from_curve25519_pubkey,
111 ed25519_donna_scalarmult_with_group_order,
132 #ifdef TOR_UNIT_TESTS
140 crypto_ed25519_testing_force_impl(
const char *
name)
144 if (! strcmp(
name,
"donna")) {
155 crypto_ed25519_testing_restore_impl(
void)
158 saved_ed25519_impl = NULL;
179 memwipe(seed, 0,
sizeof(seed));
181 return r < 0 ? -1 : 0;
219 &keypair_out->seckey)<0)
237 get_prefixed_msg(
const uint8_t *msg,
size_t msg_len,
238 const char *prefix_str,
239 size_t *final_msg_len_out)
241 size_t prefixed_msg_len, prefix_len;
242 uint8_t *prefixed_msg;
247 prefix_len = strlen(prefix_str);
254 prefixed_msg_len = msg_len + prefix_len;
255 prefixed_msg = tor_malloc_zero(prefixed_msg_len);
257 memcpy(prefixed_msg, prefix_str, prefix_len);
258 memcpy(prefixed_msg + prefix_len, msg, msg_len);
260 *final_msg_len_out = prefixed_msg_len;
272 const uint8_t *msg,
size_t len,
275 if (
get_ed_impl()->sign(signature_out->sig, msg, len,
277 keypair->pubkey.pubkey) < 0) {
290 const uint8_t *msg,
size_t msg_len,
291 const char *prefix_str,
295 size_t prefixed_msg_len;
296 uint8_t *prefixed_msg;
300 prefixed_msg = get_prefixed_msg(msg, msg_len, prefix_str,
302 if (BUG(!prefixed_msg)) {
305 log_warn(
LD_GENERAL,
"Failed to get prefixed msg.");
311 prefixed_msg, prefixed_msg_len,
326 const uint8_t *msg,
size_t len,
330 get_ed_impl()->open(signature->sig, msg, len, pubkey->pubkey) < 0 ? -1 : 0;
340 const uint8_t *msg,
size_t msg_len,
341 const char *prefix_str,
345 size_t prefixed_msg_len;
346 uint8_t *prefixed_msg;
348 prefixed_msg = get_prefixed_msg(msg, msg_len, prefix_str,
350 if (BUG(!prefixed_msg)) {
353 log_warn(
LD_GENERAL,
"Failed to get prefixed msg.");
359 prefixed_msg, prefixed_msg_len,
381 if (impl->open_batch == NULL) {
386 for (i = 0; i < n_checkable; ++i) {
392 okay_out[i] = (r == 0);
404 const uint8_t **sigs;
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));
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;
423 all_ok = impl->open_batch(ms, lens, pks, sigs, n_checkable, oks);
424 for (i = 0; i < n_checkable; ++i) {
432 tor_assert(((res == 0) && !all_ok) || ((res < 0) && all_ok));
459 const char string[] =
"Derive high part of ed25519 key from curve25519 key";
464 memcpy(out->seckey.
seckey, inp->seckey.secret_key, 32);
471 memcpy(out->seckey.
seckey + 32, sha512_output, 32);
475 *signbit_out = out->pubkey.pubkey[31] >> 7;
482 memwipe(&pubkey_check, 0,
sizeof(pubkey_check));
483 memwipe(sha512_output, 0,
sizeof(sha512_output));
497 return get_ed_impl()->pubkey_from_curve25519_pubkey(pubkey->pubkey,
498 pubkey_in->public_key,
516 const uint8_t *param)
521 inp->seckey.
seckey, param);
530 memwipe(&pubkey_check, 0,
sizeof(pubkey_check));
543 const uint8_t *param)
545 return get_ed_impl()->blind_public_key(out->pubkey, inp->pubkey, param);
554 const char *filename,
572 const char *filename)
577 tag_out, seckey_out->
seckey,
578 sizeof(seckey_out->
seckey));
579 if (len ==
sizeof(seckey_out->
seckey)) {
581 }
else if (len >= 0) {
595 const char *filename,
602 sizeof(pubkey->pubkey));
612 const char *filename)
617 tag_out, pubkey_out->pubkey,
618 sizeof(pubkey_out->pubkey));
619 if (len ==
sizeof(pubkey_out->pubkey)) {
621 }
else if (len >= 0) {
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
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
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
700 if (impl->selftest && impl->selftest() != 0)
712 if (impl->seckey_expand(sk, alicesk) < 0)
714 if (impl->pubkey(pk, sk) < 0)
720 if (impl->sign(sig, alicemsg,
sizeof(alicemsg), sk, pk) < 0)
724 if (impl->open(sig, alicemsg,
sizeof(alicemsg), pk) < 0)
765 log_warn(
LD_CRYPTO,
"The Ed25519-donna implementation seems broken; using "
766 "the ref10 implementation.");
781 ed25519_point_is_identity_element(
const uint8_t *point)
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 };
790 return tor_memeq(point, ed25519_identity,
sizeof(ed25519_identity));
798 uint8_t result[32] = {0};
801 if (ed25519_point_is_identity_element(pubkey->pubkey)) {
802 log_warn(
LD_CRYPTO,
"ed25519 pubkey is the identity");
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");
815 if (!ed25519_point_is_identity_element(result)) {
816 log_warn(
LD_CRYPTO,
"ed25519 validation failed");
Header for crypto_curve25519.c.
Headers for crypto_digest.c.
void crypto_digest_get_digest(crypto_digest_t *digest, char *out, size_t out_len)
#define crypto_digest_free(d)
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)
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 ed25519_pubkey_copy(ed25519_public_key_t *dest, const ed25519_public_key_t *src)
int ed25519_public_key_is_zero(const ed25519_public_key_t *pubkey)
int ed25519_public_key_generate(ed25519_public_key_t *pubkey_out, const ed25519_secret_key_t *seckey)
int ed25519_validate_pubkey(const ed25519_public_key_t *pubkey)
void ed25519_keypair_free_(ed25519_keypair_t *kp)
int ed25519_checksig_batch(int *okay_out, const ed25519_checkable_t *checkable, int n_checkable)
int ed25519_seckey_read_from_file(ed25519_secret_key_t *seckey_out, char **tag_out, const char *filename)
int ed25519_sign(ed25519_signature_t *signature_out, const uint8_t *msg, size_t len, const ed25519_keypair_t *keypair)
int ed25519_secret_key_generate(ed25519_secret_key_t *seckey_out, int extra_strong)
int ed25519_keypair_generate(ed25519_keypair_t *keypair_out, int extra_strong)
int ed25519_keypair_blind(ed25519_keypair_t *out, const ed25519_keypair_t *inp, const uint8_t *param)
int ed25519_checksig(const ed25519_signature_t *signature, const uint8_t *msg, size_t len, const ed25519_public_key_t *pubkey)
int ed25519_pubkey_write_to_file(const ed25519_public_key_t *pubkey, const char *filename, const char *tag)
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
int ed25519_public_key_from_curve25519_public_key(ed25519_public_key_t *pubkey, const curve25519_public_key_t *pubkey_in, int signbit)
int ed25519_seckey_write_to_file(const ed25519_secret_key_t *seckey, const char *filename, const char *tag)
int ed25519_public_blind(ed25519_public_key_t *out, const ed25519_public_key_t *inp, const uint8_t *param)
int ed25519_pubkey_read_from_file(ed25519_public_key_t *pubkey_out, char **tag_out, const char *filename)
static const ed25519_impl_t * get_ed_impl(void)
static const ed25519_impl_t impl_ref10
int ed25519_keypair_from_curve25519_keypair(ed25519_keypair_t *out, int *signbit_out, const curve25519_keypair_t *inp)
STATIC int ed25519_impl_spot_check(void)
void ed25519_set_impl_params(int use_donna)
int ed25519_secret_key_from_seed(ed25519_secret_key_t *seckey_out, const uint8_t *seed)
static const ed25519_impl_t * ed25519_impl
int ed25519_pubkey_eq(const ed25519_public_key_t *key1, const ed25519_public_key_t *key2)
static void pick_ed25519_impl(void)
Header for crypto_ed25519.c.
void crypto_rand(char *to, size_t n)
void crypto_strongest_rand(uint8_t *out, size_t out_len)
Common functions for using (pseudo-)random number generators.
void memwipe(void *mem, uint8_t byte, size_t sz)
Common functions for cryptographic routines.
int tor_memeq(const void *a, const void *b, size_t sz)
int safe_mem_is_zero(const void *mem, size_t sz)
#define fast_memeq(a, b, c)
#define fast_memneq(a, b, c)
const ed25519_public_key_t * pubkey
ed25519_signature_t signature
uint8_t seckey[ED25519_SECKEY_LEN]
#define MOCK_IMPL(rv, funcname, arglist)
Macros to manage assertions, fatal and non-fatal.
Header for util_string.c.
#define ED25519_SECKEY_LEN
#define ED25519_PUBKEY_LEN