I've pushed some eddsa internal functions to the repo the last few weeks.
Now I have an initial implementation of some friendlier high-level functions for ed25519-sha512 signatures. Patch below, comments appreciated, in particular on the interface.
I have a test program that can process http://ed25519.cr.yp.to/python/sign.input successfully. But that input file is a bit large (2.4M, or 670K after lzip --best), so I hesitate before just including a copy of it in the testsuite directory.
Regards, /Niels
diff --git a/Makefile.in b/Makefile.in index 7006211..19269af 100644 --- a/Makefile.in +++ b/Makefile.in @@ -178,6 +178,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-sign.c eddsa-verify.c \ + ed25519-sha512-sign.c ed25519-sha512-verify.c \ $(OPT_HOGWEED_SOURCES)
HEADERS = aes.h arcfour.h arctwo.h asn1.h blowfish.h \ diff --git a/ed25519-sha512-sign.c b/ed25519-sha512-sign.c new file mode 100644 index 0000000..d401621 --- /dev/null +++ b/ed25519-sha512-sign.c @@ -0,0 +1,69 @@ +/* ed25519-sha512-sign.c + + Copyright (C) 2014 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" + +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, + size_t length, const uint8_t *msg, + uint8_t *signature) +{ + mp_size_t itch = _eddsa_sign_itch (&nettle_curve25519); + mp_limb_t *scratch = gmp_alloc_limbs (itch); + struct sha512_ctx ctx; + + sha512_init (&ctx); + sha512_update (&ctx, ED25519_KEY_SIZE, priv->k1); + _eddsa_sign (&nettle_curve25519, &nettle_sha512, priv->pub, + &ctx, + priv->k2, length, msg, signature, scratch); + + gmp_free_limbs (scratch, itch); +} diff --git a/ed25519-sha512-verify.c b/ed25519-sha512-verify.c new file mode 100644 index 0000000..f8d781a --- /dev/null +++ b/ed25519-sha512-verify.c @@ -0,0 +1,74 @@ +/* ed25519-sha512-sign.c + + Copyright (C) 2014 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 <string.h> + +#include "eddsa.h" + +#include "ecc-internal.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, + size_t length, const uint8_t *msg, + const uint8_t *signature) +{ + mp_size_t itch = _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); + gmp_free_limbs (scratch, itch); + return res; +} diff --git a/eddsa.h b/eddsa.h index 5021486..68a6b1c 100644 --- a/eddsa.h +++ b/eddsa.h @@ -35,12 +35,18 @@ #include "nettle-types.h"
#include "bignum.h" +#include "sha2.h"
#ifdef __cplusplus extern "C" { #endif
/* Name mangling */ +#define ed25519_sha512_set_private_key nettle_ed25519_sha512_set_private_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 #define _eddsa_compress_itch _nettle_eddsa_compress_itch #define _eddsa_decompress _nettle_eddsa_decompress @@ -54,6 +60,44 @@ extern "C" { #define _eddsa_verify_itch _nettle_eddsa_verify_itch
#define ED25519_KEY_SIZE 32 +#define ED25519_SIGNATURE_SIZE 64 + +/* Number of limbs needed to represent a point koordinate, 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); + +void +ed25519_sha512_sign (const struct ed25519_private_key *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, + size_t length, const uint8_t *msg, + const uint8_t *signature); + +/* Low-level internal functions */
struct ecc_curve; struct ecc_modulo;