diff options
author | Nick Mathewson <nickm@torproject.org> | 2012-12-03 15:44:21 -0500 |
---|---|---|
committer | Nick Mathewson <nickm@torproject.org> | 2013-01-02 14:10:48 -0500 |
commit | 89ec584805bfba76609a1191eb6789fc0e24bdae (patch) | |
tree | 4b05bf749b0388d35cf52bce3eca37b2ebbd9b03 /src/common/crypto_curve25519.c | |
parent | f06966023a4000de24feebaa2ca8438abb10c16c (diff) | |
download | tor-89ec584805bfba76609a1191eb6789fc0e24bdae.tar.gz tor-89ec584805bfba76609a1191eb6789fc0e24bdae.zip |
Add a wrapper around, and test and build support for, curve25519.
We want to use donna-c64 when we have a GCC with support for
64x64->uint128_t multiplying. If not, we want to use libnacl if we
can, unless it's giving us the unsafe "ref" implementation. And if
that isn't going to work, we'd like to use the
portable-and-safe-but-slow 32-bit "donna" implementation.
We might need more library searching for the correct libnacl,
especially once the next libnacl release is out -- it's likely to have
bunches of better curve25519 implementations.
I also define a set of curve25519 wrapper functions, though it really
shouldn't be necessary.
We should eventually make the -donna*.c files get build with
-fomit-frame-pointer, since that can make a difference.
Diffstat (limited to 'src/common/crypto_curve25519.c')
-rw-r--r-- | src/common/crypto_curve25519.c | 88 |
1 files changed, 88 insertions, 0 deletions
diff --git a/src/common/crypto_curve25519.c b/src/common/crypto_curve25519.c new file mode 100644 index 0000000000..1985e8af2d --- /dev/null +++ b/src/common/crypto_curve25519.c @@ -0,0 +1,88 @@ +/* Copyright (c) 2012, The Tor Project, Inc. */ +/* See LICENSE for licensing information */ + +/* Wrapper code for a curve25519 implementation. */ + +#define CRYPTO_CURVE25519_PRIVATE +#include "orconfig.h" +#include "crypto.h" +#include "crypto_curve25519.h" +#include "util.h" + +/* ============================== + Part 1: wrap a suitable curve25519 implementation as curve25519_impl + ============================== */ + +#ifdef USE_CURVE25519_DONNA +int curve25519_donna(uint8_t *mypublic, + const uint8_t *secret, const uint8_t *basepoint); +#endif +#ifdef USE_CURVE25519_NACL +#include <crypto_scalarmult_curve25519.h> +#endif + +int +curve25519_impl(uint8_t *output, const uint8_t *secret, + const uint8_t *basepoint) +{ +#ifdef USE_CURVE25519_DONNA + return curve25519_donna(output, secret, basepoint); +#elif defined(USE_CURVE25519_NACL) + return crypto_scalarmult_curve25519(output, secret, basepoint); +#else +#error "No implementation of curve25519 is available." +#endif +} + +/* ============================== + Part 2: Wrap curve25519_impl with some convenience types and functions. + ============================== */ + +/** + * Return true iff a curve25519_public_key_t seems valid. (It's not necessary + * to see if the point is on the curve, since the twist is also secure, but we + * do need to make sure that it isn't the point at infinity.) */ +int +curve25519_public_key_is_ok(const curve25519_public_key_t *key) +{ + static const uint8_t zero[] = + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"; + + return tor_memneq(key->public_key, zero, CURVE25519_PUBKEY_LEN); +} + +/** Generate a new keypair and return the secret key. If <b>extra_strong</b> + * is true, this key is possibly going to get used more than once, so + * use a better-than-usual RNG. */ +void +curve25519_secret_key_generate(curve25519_secret_key_t *key_out, + int extra_strong) +{ + (void)extra_strong; + + crypto_rand((char*)key_out->secret_key, 32); + key_out->secret_key[0] &= 248; + key_out->secret_key[31] &= 127; + key_out->secret_key[31] |= 64; +} + +void +curve25519_public_key_generate(curve25519_public_key_t *key_out, + const curve25519_secret_key_t *seckey) +{ + static const uint8_t basepoint[32] = {9}; + + curve25519_impl(key_out->public_key, seckey->secret_key, basepoint); +} + +/** Perform the curve25519 ECDH handshake with <b>skey</b> and <b>pkey</b>, + * writing CURVE25519_OUTPUT_LEN bytes of output into <b>output</b>. */ +void +curve25519_handshake(uint8_t *output, + const curve25519_secret_key_t *skey, + const curve25519_public_key_t *pkey) +{ + curve25519_impl(output, skey->secret_key, pkey->public_key); +} + |