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");