More documentation for ed25519 stuff.

This commit is contained in:
Nick Mathewson 2014-08-29 09:24:27 -04:00
parent 1d3b33e1ed
commit f0eb7ae79f
4 changed files with 69 additions and 5 deletions

View File

@ -19,6 +19,11 @@
#include <openssl/sha.h> #include <openssl/sha.h>
/**
* Initialize a new ed25519 secret key in <b>seckey_out</b>. If
* <b>extra_strong</b>, take the RNG inputs directly from the operating
* system. Return 0 on success, -1 on failure.
*/
int int
ed25519_secret_key_generate(ed25519_secret_key_t *seckey_out, ed25519_secret_key_generate(ed25519_secret_key_t *seckey_out,
int extra_strong) int extra_strong)
@ -34,6 +39,10 @@ ed25519_secret_key_generate(ed25519_secret_key_t *seckey_out,
return r < 0 ? -1 : 0; return r < 0 ? -1 : 0;
} }
/**
* Given a 32-byte random seed in <b>seed</b>, expand it into an ed25519
* secret key in <b>seckey_out</b>. Return 0 on success, -1 on failure.
*/
int int
ed25519_secret_key_from_seed(ed25519_secret_key_t *seckey_out, ed25519_secret_key_from_seed(ed25519_secret_key_t *seckey_out,
const uint8_t *seed) const uint8_t *seed)
@ -43,6 +52,10 @@ ed25519_secret_key_from_seed(ed25519_secret_key_t *seckey_out,
return 0; return 0;
} }
/**
* Given a secret key in <b>seckey</b>, expand it into an
* ed25519 public key. Return 0 on success, -1 on failure.
*/
int int
ed25519_public_key_generate(ed25519_public_key_t *pubkey_out, ed25519_public_key_generate(ed25519_public_key_t *pubkey_out,
const ed25519_secret_key_t *seckey) const ed25519_secret_key_t *seckey)
@ -224,6 +237,10 @@ ed25519_public_key_from_curve25519_public_key(ed25519_public_key_t *pubkey,
* ed25519 keypair in <b>out</b>, blinded by the corresponding 32-byte input * ed25519 keypair in <b>out</b>, blinded by the corresponding 32-byte input
* in 'param'. * in 'param'.
* *
* Tor uses key blinding for the "next-generation" hidden services design:
* service descriptors are encrypted with a key derived from the service's
* long-term public key, and then signed with (and stored at a position
* indexed by) a short-term key derived by blinding the long-term keys.
*/ */
int int
ed25519_keypair_blind(ed25519_keypair_t *out, ed25519_keypair_blind(ed25519_keypair_t *out,
@ -245,6 +262,11 @@ ed25519_keypair_blind(ed25519_keypair_t *out,
return 0; return 0;
} }
/**
* Given an ed25519 public key in <b>inp</b>, generate a corresponding blinded
* public key in <b>out</b>, blinded with the 32-byte parameter in
* <b>param</b>. Return 0 on sucess, -1 on railure.
*/
int int
ed25519_public_blind(ed25519_public_key_t *out, ed25519_public_blind(ed25519_public_key_t *out,
const ed25519_public_key_t *inp, const ed25519_public_key_t *inp,
@ -254,7 +276,10 @@ ed25519_public_blind(ed25519_public_key_t *out,
return 0; return 0;
} }
/** DOCDOC */ /**
* Store seckey unencrypted to <b>filename</b>, marking it with <b>tag</b>.
* Return 0 on success, -1 on failure.
*/
int int
ed25519_seckey_write_to_file(const ed25519_secret_key_t *seckey, ed25519_seckey_write_to_file(const ed25519_secret_key_t *seckey,
const char *filename, const char *filename,
@ -267,7 +292,11 @@ ed25519_seckey_write_to_file(const ed25519_secret_key_t *seckey,
sizeof(seckey->seckey)); sizeof(seckey->seckey));
} }
/** DOCDOC */ /**
* Read seckey unencrypted from <b>filename</b>, storing it into
* <b>seckey_out</b>. Set *<b>tag_out</> to the tag it was marked with.
* Return 0 on success, -1 on failure.
*/
int int
ed25519_seckey_read_from_file(ed25519_secret_key_t *seckey_out, ed25519_seckey_read_from_file(ed25519_secret_key_t *seckey_out,
char **tag_out, char **tag_out,
@ -284,7 +313,10 @@ ed25519_seckey_read_from_file(ed25519_secret_key_t *seckey_out,
return 0; return 0;
} }
/** DOCDOC */ /**
* Store pubkey unencrypted to <b>filename</b>, marking it with <b>tag</b>.
* Return 0 on success, -1 on failure.
*/
int int
ed25519_pubkey_write_to_file(const ed25519_public_key_t *pubkey, ed25519_pubkey_write_to_file(const ed25519_public_key_t *pubkey,
const char *filename, const char *filename,
@ -297,7 +329,10 @@ ed25519_pubkey_write_to_file(const ed25519_public_key_t *pubkey,
sizeof(pubkey->pubkey)); sizeof(pubkey->pubkey));
} }
/** DOCDOC */ /**
* Store pubkey unencrypted to <b>filename</b>, marking it with <b>tag</b>.
* Return 0 on success, -1 on failure.
*/
int int
ed25519_pubkey_read_from_file(ed25519_public_key_t *pubkey_out, ed25519_pubkey_read_from_file(ed25519_public_key_t *pubkey_out,
char **tag_out, char **tag_out,

View File

@ -24,6 +24,12 @@ typedef struct {
/** An Ed25519 secret key */ /** An Ed25519 secret key */
typedef struct { typedef struct {
/** Note that we store secret keys in an expanded format that doesn't match
* the format from standard ed25519. Ed25519 stores a 32-byte value k and
* expands it into a 64-byte H(k), using the first 32 bytes for a multiplier
* of the base point, and second 32 bytes as an input to a hash function
* for deriving r. But because we implement key blinding, we need to store
* keys in the 64-byte expanded form. */
uint8_t seckey[ED25519_SECKEY_LEN]; uint8_t seckey[ED25519_SECKEY_LEN];
} ed25519_secret_key_t; } ed25519_secret_key_t;

View File

@ -0,0 +1,23 @@
We've made the following changes to the stock ed25519_ref10 from
supercop-20140622:
* We added the necessary glue to provide integers of fixed bit
sizes, SHA512, and to compile without warnings everywhere we need
to build.
* Secret keys are stored in expanded format. There are functions
to expand them from the 32-byte seed.
* Signatures are made and processed detached from the messages that
they sign. (In other words, we support "make signature" and
"check signature", not "create signed message" and "check and
unpack signed message".)
* There's an implementation of 'convert a curve25519 key to an
ed25519 key' so we can do cross-certification with curve25519 keys.
(keyconv.c)
* There's an implementation of multiplicative key blinding so we
can use it for next-gen hidden srevice descriptors. (blinding.c)

View File

@ -14,7 +14,7 @@ gettweak(unsigned char *out, const unsigned char *param)
{ {
const char str[] = "Derive temporary signing key"; const char str[] = "Derive temporary signing key";
crypto_hash_sha512_2(out, (const unsigned char*)str, strlen(str), param, 32); crypto_hash_sha512_2(out, (const unsigned char*)str, strlen(str), param, 32);
out[0] &= 248; /* Necessary ? */ out[0] &= 248; /* Is this necessary necessary ? */
out[31] &= 63; out[31] &= 63;
out[31] |= 64; out[31] |= 64;
} }