diff --git a/ChangeLog b/ChangeLog index 0c77dda24d31297f9d7eafc39eba27a27101075c..51fe70970830b0dfb7917ce2d96b5d51e7d0a6ce 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,7 +1,27 @@ 2015-03-18 Niels Möller <nisse@diamant.hack.org> + EdDSA interface change, use plain strings to represent keys. + * eddsa.h (_ED25519_LIMB_SIZE): Deleted constant. + (struct ed25519_private_key, ed25519_public_key): Deleted. + * eddsa-expand.c (_eddsa_expand_key): Don't compute the public + key. + (_eddsa_expand_key_itch): Deleted function. * eddsa-pubkey.c (_eddsa_public_key, _eddsa_public_key_itch): New file, new functions. + * ed25519-sha512-pubkey.c (ed25519_sha512_public_key): New file + and function. + * ed25519-sha512-verify.c (ed25519_sha512_set_public_key): Deleted + function. + (ed25519_sha512_verify): Use a string to represent the public key. + * ed25519-sha512-sign.c (ed25519_sha512_set_private_key): Deleted + function. + (ed25519_sha512_sign): Use strings for the input key pair. + * Makefile.in (hogweed_SOURCES): Added eddsa-pubkey.c and + ed25519-sha512-pubkey.c. + * testsuite/eddsa-sign-test.c (test_eddsa_sign): Adapt to + _eddsa_expand_key changes, and use _eddsa_public_key. + * testsuite/ed25519-test.c (test_one): Test + ed25519_sha512_public_key, and adapt to new ed25519 interface. 2015-03-14 Niels Möller <nisse@diamant.hack.org> diff --git a/Makefile.in b/Makefile.in index 7362a02dc4f437e20a8dbe252513ba836ad116fc..dbe03f4d70f13a239eca57adc9f254702f76b022 100644 --- a/Makefile.in +++ b/Makefile.in @@ -180,6 +180,7 @@ hogweed_SOURCES = sexp.c sexp-format.c \ curve25519-mul-g.c curve25519-mul.c curve25519-eh-to-x.c \ eddsa-compress.c eddsa-decompress.c eddsa-expand.c \ eddsa-hash.c eddsa-pubkey.c eddsa-sign.c eddsa-verify.c \ + ed25519-sha512-pubkey.c \ ed25519-sha512-sign.c ed25519-sha512-verify.c \ $(OPT_HOGWEED_SOURCES) diff --git a/ed25519-sha512-pubkey.c b/ed25519-sha512-pubkey.c new file mode 100644 index 0000000000000000000000000000000000000000..8e4c52e82deed3a381b18ff2c07e5c272811d19b --- /dev/null +++ b/ed25519-sha512-pubkey.c @@ -0,0 +1,59 @@ +/* ed25519-sha512-pubkey.c + + Copyright (C) 2014, 2015 Niels Möller + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + or + + * the GNU General Public License as published by the Free + Software Foundation; either version 2 of the License, or (at your + option) any later version. + + or both in parallel, as here. + + GNU Nettle is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +*/ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include "eddsa.h" + +#include "ecc-internal.h" +#include "sha2.h" + +void +ed25519_sha512_public_key (uint8_t *pub, const uint8_t *priv) +{ + const struct ecc_curve *ecc = &nettle_curve25519; + struct sha512_ctx ctx; + uint8_t digest[ED25519_KEY_SIZE]; + mp_size_t itch = ecc->q.size + _eddsa_public_key_itch (ecc); + mp_limb_t *scratch = gmp_alloc_limbs (itch); + +#define k scratch +#define scratch_out (scratch + ecc->q.size) + + _eddsa_expand_key (ecc, &nettle_sha512, &ctx, priv, digest, k); + _eddsa_public_key (ecc, k, pub, scratch_out); + + gmp_free_limbs (scratch, itch); +#undef k +#undef scratch_out +} diff --git a/ed25519-sha512-sign.c b/ed25519-sha512-sign.c index bbcd133b371f243548a17bafe2fd0a729e66eacd..6adda23579dc0be347bc7bcabcf5ae9b7181fe42 100644 --- a/ed25519-sha512-sign.c +++ b/ed25519-sha512-sign.c @@ -1,6 +1,6 @@ /* ed25519-sha512-sign.c - Copyright (C) 2014 Niels Möller + Copyright (C) 2014, 2015 Niels Möller This file is part of GNU Nettle. @@ -39,32 +39,29 @@ #include "sha2.h" void -ed25519_sha512_set_private_key (struct ed25519_private_key *priv, - const uint8_t *key) -{ - mp_size_t itch = _eddsa_expand_key_itch (&nettle_curve25519); - mp_limb_t *scratch = gmp_alloc_limbs (itch); - struct sha512_ctx ctx; - - _eddsa_expand_key (&nettle_curve25519, &nettle_sha512, &ctx, - key, priv->pub, priv->k1, priv->k2, scratch); - gmp_free_limbs (scratch, itch); -} - -void -ed25519_sha512_sign (const struct ed25519_private_key *priv, +ed25519_sha512_sign (const uint8_t *pub, + const uint8_t *priv, size_t length, const uint8_t *msg, uint8_t *signature) { - mp_size_t itch = _eddsa_sign_itch (&nettle_curve25519); + const struct ecc_curve *ecc = &nettle_curve25519; + mp_size_t itch = ecc->q.size + _eddsa_sign_itch (&nettle_curve25519); mp_limb_t *scratch = gmp_alloc_limbs (itch); +#define k2 scratch +#define scratch_out (scratch + ecc->q.size) struct sha512_ctx ctx; + uint8_t digest[SHA512_DIGEST_SIZE]; +#define k1 (digest + ED25519_KEY_SIZE) + + _eddsa_expand_key (ecc, &nettle_sha512, &ctx, priv, digest, k2); - sha512_init (&ctx); - sha512_update (&ctx, ED25519_KEY_SIZE, priv->k1); - _eddsa_sign (&nettle_curve25519, &nettle_sha512, priv->pub, + sha512_update (&ctx, ED25519_KEY_SIZE, k1); + _eddsa_sign (&nettle_curve25519, &nettle_sha512, pub, &ctx, - priv->k2, length, msg, signature, scratch); + k2, length, msg, signature, scratch_out); gmp_free_limbs (scratch, itch); +#undef k1 +#undef k2 +#undef scratch_out } diff --git a/ed25519-sha512-verify.c b/ed25519-sha512-verify.c index 763a9b043f5b06ce455a020e92df1909e336f544..fc9cd01065e9869d5d8fe6e90b27fc9762d1e338 100644 --- a/ed25519-sha512-verify.c +++ b/ed25519-sha512-verify.c @@ -1,6 +1,6 @@ /* ed25519-sha512-verify.c - Copyright (C) 2014 Niels Möller + Copyright (C) 2014, 2015 Niels Möller This file is part of GNU Nettle. @@ -41,35 +41,25 @@ #include "sha2.h" int -ed25519_sha512_set_public_key (struct ed25519_public_key *pub, - const uint8_t *key) -{ - mp_size_t itch = _eddsa_decompress_itch (&nettle_curve25519); - mp_limb_t *scratch = gmp_alloc_limbs (itch); - int res; - - memcpy (pub->pub, key, sizeof(pub->pub)); - res = _eddsa_decompress (&nettle_curve25519, - pub->A, key, scratch); - - gmp_free_limbs (scratch, itch); - return res; -} - -int -ed25519_sha512_verify (const struct ed25519_public_key *pub, +ed25519_sha512_verify (const uint8_t *pub, size_t length, const uint8_t *msg, const uint8_t *signature) { - mp_size_t itch = _eddsa_verify_itch (&nettle_curve25519); + const struct ecc_curve *ecc = &nettle_curve25519; + mp_size_t itch = 3*ecc->p.size + _eddsa_verify_itch (&nettle_curve25519); mp_limb_t *scratch = gmp_alloc_limbs (itch); struct sha512_ctx ctx; int res; - - res = _eddsa_verify (&nettle_curve25519, &nettle_sha512, - pub->pub, pub->A, &ctx, - length, msg, signature, - scratch); +#define A scratch +#define scratch_out (scratch + 3*ecc->p.size) + res = (_eddsa_decompress (&nettle_curve25519, + A, pub, scratch_out) + && _eddsa_verify (ecc, &nettle_sha512, + pub, A, &ctx, + length, msg, signature, + scratch_out)); gmp_free_limbs (scratch, itch); return res; +#undef A +#undef scratch_out } diff --git a/eddsa-expand.c b/eddsa-expand.c index 9c0b0b239a7f53b489a58c615b08d8b31b3dd8cf..dc2bfaf199a031889b1fc2da54189fe5af637e48 100644 --- a/eddsa-expand.c +++ b/eddsa-expand.c @@ -42,38 +42,23 @@ #include "ecc-internal.h" #include "nettle-meta.h" -mp_size_t -_eddsa_expand_key_itch (const struct ecc_curve *ecc) -{ - assert (_eddsa_compress_itch (ecc) <= ecc->mul_g_itch); - return 3*ecc->p.size + ecc->mul_g_itch; -} - -/* Expands a private key, generating the key K1 for nonce generation, - the secret scalar K2, and, if PUB is non-NULL, the corresponding - public key (in compressed form). */ +/* Expands a private key, generating the secret scalar K2 and leaving + the key K1 for nonce generation, at the end of the digest. */ void _eddsa_expand_key (const struct ecc_curve *ecc, const struct nettle_hash *H, void *ctx, const uint8_t *key, - uint8_t *pub, - uint8_t *k1, - mp_limb_t *k2, - mp_limb_t *scratch) + uint8_t *digest, + mp_limb_t *k2) { size_t nbytes = 1 + ecc->p.bit_size / 8; - uint8_t *digest = (uint8_t *) scratch; - -#define P scratch -#define scratch_out (scratch + 3*ecc->p.size) assert (H->digest_size >= 2*nbytes); H->init (ctx); H->update (ctx, nbytes, key); H->digest (ctx, 2*nbytes, digest); - memcpy (k1, digest + nbytes, nbytes); mpn_set_base256_le (k2, ecc->p.size, digest, nbytes); /* Clear low 3 bits */ @@ -84,12 +69,4 @@ _eddsa_expand_key (const struct ecc_curve *ecc, /* Clear any higher bits. */ k2[ecc->p.size - 1] &= ~(mp_limb_t) 0 >> (GMP_NUMB_BITS * ecc->p.size - ecc->p.bit_size); - - if (pub) - { - ecc->mul_g (ecc, P, k2, scratch_out); - _eddsa_compress (ecc, pub, P, scratch_out); - } -#undef P -#undef scratch_out } diff --git a/eddsa.h b/eddsa.h index b052ef8294ce446842b86eebe05bf608217c705d..49f1a025c0007f3d50ad137b5edc64cdcb4e2768 100644 --- a/eddsa.h +++ b/eddsa.h @@ -42,8 +42,8 @@ extern "C" { /* Name mangling */ #define ed25519_sha512_set_private_key nettle_ed25519_sha512_set_private_key +#define ed25519_sha512_public_key nettle_ed25519_sha512_public_key #define ed25519_sha512_sign nettle_ed25519_sha512_sign -#define ed25519_sha512_set_public_key nettle_ed25519_sha512_set_public_key #define ed25519_sha512_verify nettle_ed25519_sha512_verify #define _eddsa_compress _nettle_eddsa_compress @@ -51,7 +51,6 @@ extern "C" { #define _eddsa_decompress _nettle_eddsa_decompress #define _eddsa_decompress_itch _nettle_eddsa_decompress_itch #define _eddsa_hash _nettle_eddsa_hash -#define _eddsa_expand_key_itch _nettle_eddsa_expand_key_itch #define _eddsa_expand_key _nettle_eddsa_expand_key #define _eddsa_sign _nettle_eddsa_sign #define _eddsa_sign_itch _nettle_eddsa_sign_itch @@ -63,38 +62,17 @@ extern "C" { #define ED25519_KEY_SIZE 32 #define ED25519_SIGNATURE_SIZE 64 -/* Number of limbs needed to represent a point coordinate, or a secret - exponent (note that exponents are 254 bits, larger than q). */ -#define _ED25519_LIMB_SIZE ((255 + (GMP_NUMB_BITS - 1)) / GMP_NUMB_BITS) - -struct ed25519_private_key -{ - uint8_t pub[ED25519_KEY_SIZE]; - uint8_t k1[ED25519_KEY_SIZE]; - mp_limb_t k2[_ED25519_LIMB_SIZE]; -}; - void -ed25519_sha512_set_private_key (struct ed25519_private_key *priv, - const uint8_t *key); +ed25519_sha512_public_key (uint8_t *pub, const uint8_t *priv); void -ed25519_sha512_sign (const struct ed25519_private_key *priv, +ed25519_sha512_sign (const uint8_t *pub, + const uint8_t *priv, size_t length, const uint8_t *msg, uint8_t *signature); -struct ed25519_public_key -{ - uint8_t pub[ED25519_KEY_SIZE]; - mp_limb_t A[2*_ED25519_LIMB_SIZE]; -}; - -int -ed25519_sha512_set_public_key (struct ed25519_public_key *pub, - const uint8_t *key); - int -ed25519_sha512_verify (const struct ed25519_public_key *pub, +ed25519_sha512_verify (const uint8_t *pub, size_t length, const uint8_t *msg, const uint8_t *signature); @@ -148,18 +126,13 @@ _eddsa_verify (const struct ecc_curve *ecc, const uint8_t *signature, mp_limb_t *scratch); -mp_size_t -_eddsa_expand_key_itch (const struct ecc_curve *ecc); - void _eddsa_expand_key (const struct ecc_curve *ecc, const struct nettle_hash *H, void *ctx, const uint8_t *key, - uint8_t *pub, - uint8_t *k1, - mp_limb_t *k2, - mp_limb_t *scratch); + uint8_t *digest, + mp_limb_t *k2); mp_size_t _eddsa_public_key_itch (const struct ecc_curve *ecc); diff --git a/testsuite/ed25519-test.c b/testsuite/ed25519-test.c index 924ecea6e0d4a74e2797a83569035ddda8478596..83b6b84eca6d64113c791f4fda0215729ba01541 100644 --- a/testsuite/ed25519-test.c +++ b/testsuite/ed25519-test.c @@ -63,13 +63,12 @@ test_one (const char *line) const char *mp; uint8_t sk[ED25519_KEY_SIZE]; uint8_t pk[ED25519_KEY_SIZE]; + uint8_t t[ED25519_KEY_SIZE]; uint8_t s[ED25519_SIGNATURE_SIZE]; uint8_t *msg; size_t msg_size; uint8_t s2[ED25519_SIGNATURE_SIZE]; - struct ed25519_public_key pub; - struct ed25519_private_key priv; decode_hex (ED25519_KEY_SIZE, sk, line); p = strchr (line, ':'); @@ -91,28 +90,27 @@ test_one (const char *line) decode_hex (msg_size, msg, mp); - ed25519_sha512_set_private_key (&priv, sk); - ASSERT (MEMEQ(ED25519_KEY_SIZE, priv.pub, pk)); + ed25519_sha512_public_key (t, sk); + ASSERT (MEMEQ(ED25519_KEY_SIZE, t, pk)); - ed25519_sha512_sign (&priv, msg_size, msg, s2); + ed25519_sha512_sign (pk, sk, msg_size, msg, s2); ASSERT (MEMEQ (ED25519_SIGNATURE_SIZE, s, s2)); - ASSERT (ed25519_sha512_set_public_key (&pub, pk)); - ASSERT (ed25519_sha512_verify (&pub, msg_size, msg, s)); + ASSERT (ed25519_sha512_verify (pk, msg_size, msg, s)); s2[ED25519_SIGNATURE_SIZE/3] ^= 0x40; - ASSERT (!ed25519_sha512_verify (&pub, msg_size, msg, s2)); + ASSERT (!ed25519_sha512_verify (pk, msg_size, msg, s2)); memcpy (s2, s, ED25519_SIGNATURE_SIZE); s2[2*ED25519_SIGNATURE_SIZE/3] ^= 0x40; - ASSERT (!ed25519_sha512_verify (&pub, msg_size, msg, s2)); + ASSERT (!ed25519_sha512_verify (pk, msg_size, msg, s2)); - ASSERT (!ed25519_sha512_verify (&pub, msg_size + 1, msg, s)); + ASSERT (!ed25519_sha512_verify (pk, msg_size + 1, msg, s)); if (msg_size > 0) { msg[msg_size-1] ^= 0x20; - ASSERT (!ed25519_sha512_verify (&pub, msg_size, msg, s)); + ASSERT (!ed25519_sha512_verify (pk, msg_size, msg, s)); } free (msg); } diff --git a/testsuite/eddsa-sign-test.c b/testsuite/eddsa-sign-test.c index 381601dbdbf08829b0225d62bf1ae42b91b93d04..b4d1ca98af75735e7252b41279ae832f39672f24 100644 --- a/testsuite/eddsa-sign-test.c +++ b/testsuite/eddsa-sign-test.c @@ -46,21 +46,21 @@ test_eddsa_sign (const struct ecc_curve *ecc, uint8_t *signature = xalloc (2*nbytes); void *ctx = xalloc (H->context_size); uint8_t *public_out = xalloc (nbytes); - uint8_t *k1 = xalloc (nbytes); + uint8_t *digest = xalloc (2*nbytes); + const uint8_t *k1 = digest + nbytes; mp_limb_t *k2 = xalloc_limbs (ecc->p.size); ASSERT (public->length == nbytes); ASSERT (private->length == nbytes); ASSERT (ref->length == 2*nbytes); - ASSERT (_eddsa_expand_key_itch (ecc) <= _eddsa_sign_itch (ecc)); _eddsa_expand_key (ecc, H, ctx, private->data, - public_out, - k1, k2, scratch); + digest, k2); + _eddsa_public_key (ecc, k2, public_out, scratch); if (!MEMEQ (nbytes, public_out, public->data)) { - fprintf (stderr, "Bad public key from _eddsa_expand_key.\n"); + fprintf (stderr, "Bad public key from _eddsa_expand_key + _eddsa_public_key.\n"); fprintf (stderr, "got:"); print_hex (nbytes, public_out); fprintf (stderr, "\nref:"); @@ -95,7 +95,7 @@ test_eddsa_sign (const struct ecc_curve *ecc, free (scratch); free (signature); free (ctx); - free (k1); + free (digest); free (k2); free (public_out); }