From f0eb7ae79f54781bc00e51ff5e9630b2103e4df0 Mon Sep 17 00:00:00 2001 From: Nick Mathewson Date: Fri, 29 Aug 2014 09:24:27 -0400 Subject: [PATCH] More documentation for ed25519 stuff. --- src/common/crypto_ed25519.c | 43 +++++++++++++++++++++++++++++--- src/common/crypto_ed25519.h | 6 +++++ src/ext/ed25519/ref10/README.tor | 23 +++++++++++++++++ src/ext/ed25519/ref10/blinding.c | 2 +- 4 files changed, 69 insertions(+), 5 deletions(-) create mode 100644 src/ext/ed25519/ref10/README.tor diff --git a/src/common/crypto_ed25519.c b/src/common/crypto_ed25519.c index 15fc626fa2..a545cad9f5 100644 --- a/src/common/crypto_ed25519.c +++ b/src/common/crypto_ed25519.c @@ -19,6 +19,11 @@ #include +/** + * Initialize a new ed25519 secret key in seckey_out. If + * extra_strong, take the RNG inputs directly from the operating + * system. Return 0 on success, -1 on failure. + */ int ed25519_secret_key_generate(ed25519_secret_key_t *seckey_out, int extra_strong) @@ -34,6 +39,10 @@ ed25519_secret_key_generate(ed25519_secret_key_t *seckey_out, return r < 0 ? -1 : 0; } +/** + * Given a 32-byte random seed in seed, expand it into an ed25519 + * secret key in seckey_out. Return 0 on success, -1 on failure. + */ int ed25519_secret_key_from_seed(ed25519_secret_key_t *seckey_out, const uint8_t *seed) @@ -43,6 +52,10 @@ ed25519_secret_key_from_seed(ed25519_secret_key_t *seckey_out, return 0; } +/** + * Given a secret key in seckey, expand it into an + * ed25519 public key. Return 0 on success, -1 on failure. + */ int ed25519_public_key_generate(ed25519_public_key_t *pubkey_out, 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 out, blinded by the corresponding 32-byte input * 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 ed25519_keypair_blind(ed25519_keypair_t *out, @@ -245,6 +262,11 @@ ed25519_keypair_blind(ed25519_keypair_t *out, return 0; } +/** + * Given an ed25519 public key in inp, generate a corresponding blinded + * public key in out, blinded with the 32-byte parameter in + * param. Return 0 on sucess, -1 on railure. + */ int ed25519_public_blind(ed25519_public_key_t *out, const ed25519_public_key_t *inp, @@ -254,7 +276,10 @@ ed25519_public_blind(ed25519_public_key_t *out, return 0; } -/** DOCDOC */ +/** + * Store seckey unencrypted to filename, marking it with tag. + * Return 0 on success, -1 on failure. + */ int ed25519_seckey_write_to_file(const ed25519_secret_key_t *seckey, const char *filename, @@ -267,7 +292,11 @@ ed25519_seckey_write_to_file(const ed25519_secret_key_t *seckey, sizeof(seckey->seckey)); } -/** DOCDOC */ +/** + * Read seckey unencrypted from filename, storing it into + * seckey_out. Set *tag_out to the tag it was marked with. + * Return 0 on success, -1 on failure. + */ int ed25519_seckey_read_from_file(ed25519_secret_key_t *seckey_out, char **tag_out, @@ -284,7 +313,10 @@ ed25519_seckey_read_from_file(ed25519_secret_key_t *seckey_out, return 0; } -/** DOCDOC */ +/** + * Store pubkey unencrypted to filename, marking it with tag. + * Return 0 on success, -1 on failure. + */ int ed25519_pubkey_write_to_file(const ed25519_public_key_t *pubkey, const char *filename, @@ -297,7 +329,10 @@ ed25519_pubkey_write_to_file(const ed25519_public_key_t *pubkey, sizeof(pubkey->pubkey)); } -/** DOCDOC */ +/** + * Store pubkey unencrypted to filename, marking it with tag. + * Return 0 on success, -1 on failure. + */ int ed25519_pubkey_read_from_file(ed25519_public_key_t *pubkey_out, char **tag_out, diff --git a/src/common/crypto_ed25519.h b/src/common/crypto_ed25519.h index 1271312dfe..13b05c7c1e 100644 --- a/src/common/crypto_ed25519.h +++ b/src/common/crypto_ed25519.h @@ -24,6 +24,12 @@ typedef struct { /** An Ed25519 secret key */ 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]; } ed25519_secret_key_t; diff --git a/src/ext/ed25519/ref10/README.tor b/src/ext/ed25519/ref10/README.tor new file mode 100644 index 0000000000..38ed97ba05 --- /dev/null +++ b/src/ext/ed25519/ref10/README.tor @@ -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) + diff --git a/src/ext/ed25519/ref10/blinding.c b/src/ext/ed25519/ref10/blinding.c index a17dbcd3e3..f0154e098f 100644 --- a/src/ext/ed25519/ref10/blinding.c +++ b/src/ext/ed25519/ref10/blinding.c @@ -14,7 +14,7 @@ gettweak(unsigned char *out, const unsigned char *param) { const char str[] = "Derive temporary signing key"; 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] |= 64; }