diff options
author | Nick Mathewson <nickm@torproject.org> | 2014-08-27 00:18:26 -0400 |
---|---|---|
committer | Nick Mathewson <nickm@torproject.org> | 2014-09-25 15:08:31 -0400 |
commit | 4caa6fad4c71391ab41e92a32aa58b10b6febe7f (patch) | |
tree | 5a4a92ea93940837470b28c52cbecb780687fd27 /src/common/crypto_ed25519.c | |
parent | ed48b0fe56df2f719cd7cd274c664f7037f98b75 (diff) | |
download | tor-4caa6fad4c71391ab41e92a32aa58b10b6febe7f.tar.gz tor-4caa6fad4c71391ab41e92a32aa58b10b6febe7f.zip |
Add curve25519->ed25519 key conversion per proposal 228
For proposal 228, we need to cross-certify our identity with our
curve25519 key, so that we can prove at descriptor-generation time
that we own that key. But how can we sign something with a key that
is only for doing Diffie-Hellman? By converting it to the
corresponding ed25519 point.
See the ALL-CAPS warning in the documentation. According to djb
(IIUC), it is safe to use these keys in the ways that ntor and prop228
are using them, but it might not be safe if we start providing crazy
oracle access.
(Unit tests included. What kind of a monster do you take me for?)
Diffstat (limited to 'src/common/crypto_ed25519.c')
-rw-r--r-- | src/common/crypto_ed25519.c | 58 |
1 files changed, 58 insertions, 0 deletions
diff --git a/src/common/crypto_ed25519.c b/src/common/crypto_ed25519.c index b465b69d03..4c10c5ca01 100644 --- a/src/common/crypto_ed25519.c +++ b/src/common/crypto_ed25519.c @@ -17,6 +17,8 @@ #include "ed25519/ref10/ed25519_ref10.h" +#include <openssl/sha.h> + int ed25519_secret_key_generate(ed25519_secret_key_t *seckey_out, int extra_strong) @@ -161,6 +163,62 @@ ed25519_checksig_batch(int *okay_out, return res; } +/** + * Given a curve25519 keypair in <b>inp</b>, generate a corresponding + * ed25519 keypair in <b>out</b>, and set <b>signbit_out</b> to the + * sign bit of the X coordinate of the ed25519 key. + * + * NOTE THAT IT IS PROBABLY NOT SAFE TO USE THE GENERATED KEY FOR ANYTHING + * OUTSIDE OF WHAT'S PRESENTED IN PROPOSAL 228. In particular, it's probably + * not a great idea to use it to sign attacker-supplied anything. + */ +int +ed25519_keypair_from_curve25519_keypair(ed25519_keypair_t *out, + int *signbit_out, + const curve25519_keypair_t *inp) +{ + const char string[] = "Derive high part of ed25519 key from curve25519 key"; + ed25519_public_key_t pubkey_check; + SHA512_CTX ctx; + uint8_t sha512_output[64]; + + memcpy(out->seckey.seckey, inp->seckey.secret_key, 32); + SHA512_Init(&ctx); + SHA512_Update(&ctx, out->seckey.seckey, 32); + SHA512_Update(&ctx, string, sizeof(string)); + SHA512_Final(sha512_output, &ctx); + memcpy(out->seckey.seckey + 32, sha512_output, 32); + + ed25519_public_key_generate(&out->pubkey, &out->seckey); + + *signbit_out = out->pubkey.pubkey[31] >> 7; + + ed25519_public_key_from_curve25519_public_key(&pubkey_check, &inp->pubkey, + *signbit_out); + + tor_assert(fast_memeq(pubkey_check.pubkey, out->pubkey.pubkey, 32)); + + memwipe(&pubkey_check, 0, sizeof(pubkey_check)); + memwipe(&ctx, 0, sizeof(ctx)); + memwipe(sha512_output, 0, sizeof(sha512_output)); + + return 0; +} + +/** + * Given a curve25519 public key and sign bit of X coordinate of the ed25519 + * public key, generate the corresponding ed25519 public key. + */ +int +ed25519_public_key_from_curve25519_public_key(ed25519_public_key_t *pubkey, + const curve25519_public_key_t *pubkey_in, + int signbit) +{ + return ed25519_ref10_pubkey_from_curve25519_pubkey(pubkey->pubkey, + pubkey_in->public_key, + signbit); +} + /** DOCDOC */ int ed25519_seckey_write_to_file(const ed25519_secret_key_t *seckey, |