diff --git a/ChangeLog b/ChangeLog index 5dab6273a452b2a9372a3b94a1fa5bf93e45efcb..82ad092d47584148a86f0f311176b33585704762 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,12 @@ +2014-10-04 Niels Möller <nisse@lysator.liu.se> + + * eddsa-sign.c (_eddsa_sign, _eddsa_sign_itch): New file, new + functions. + * eddsa-hash.c (_eddsa_hash): New file and function. + * eddsa.h: Declare new functions. + * Makefile.in (hogweed_SOURCES): Added eddsa-hash.c and + eddsa-sign.c. + 2014-10-03 Niels Möller <nisse@lysator.liu.se> * testsuite/ecc-redc-test.c [NETTLE_USE_MINI_GMP]: Enable test. diff --git a/Makefile.in b/Makefile.in index 1cc423dfac8c7dc9fe2ca8127bb0bfaecc3f1350..666155149f7d1095f3a90afa9361546c4544e403 100644 --- a/Makefile.in +++ b/Makefile.in @@ -176,7 +176,8 @@ hogweed_SOURCES = sexp.c sexp-format.c \ ecc-ecdsa-sign.c ecdsa-sign.c \ ecc-ecdsa-verify.c ecdsa-verify.c ecdsa-keygen.c \ curve25519-mul-g.c curve25519-mul.c curve25519-eh-to-x.c \ - eddsa-compress.c eddsa-decompress.c \ + eddsa-compress.c eddsa-decompress.c eddsa-hash.c \ + eddsa-sign.c \ $(OPT_HOGWEED_SOURCES) HEADERS = aes.h arcfour.h arctwo.h asn1.h blowfish.h \ diff --git a/eddsa-hash.c b/eddsa-hash.c new file mode 100644 index 0000000000000000000000000000000000000000..4fb79f1b389e38f73f779743e4a08ea199afc2ee --- /dev/null +++ b/eddsa-hash.c @@ -0,0 +1,51 @@ +/* eddsa-hash.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 <assert.h> + +#include "eddsa.h" + +#include "ecc.h" +#include "ecc-internal.h" +#include "nettle-internal.h" + +void +_eddsa_hash (const struct ecc_modulo *m, + mp_limb_t *rp, const uint8_t *digest) +{ + size_t nbytes = 1 + m->bit_size / 8; + mpn_set_base256_le (rp, 2*m->size, digest, 2*nbytes); + m->mod (m, rp); +} diff --git a/eddsa-sign.c b/eddsa-sign.c new file mode 100644 index 0000000000000000000000000000000000000000..9b0c9d59e2f7a5f35fb7f3055617b1dd53888395 --- /dev/null +++ b/eddsa-sign.c @@ -0,0 +1,108 @@ +/* eddsa-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 <assert.h> + +#include "eddsa.h" + +#include "ecc.h" +#include "ecc-internal.h" +#include "nettle-internal.h" +#include "nettle-meta.h" + +mp_size_t +_eddsa_sign_itch (const struct ecc_curve *ecc) +{ + return 5*ecc->p.size + ecc->mul_g_itch; +} + +void +_eddsa_sign (const struct ecc_curve *ecc, + const struct nettle_hash *H, + const uint8_t *pub, + void *ctx, + const mp_limb_t *k2, + size_t length, + const uint8_t *msg, + uint8_t *signature, + mp_limb_t *scratch) +{ + mp_size_t size; + size_t nbytes; +#define rp scratch +#define hp (scratch + size) +#define P (scratch + 2*size) +#define sp (scratch + 2*size) +#define hash ((uint8_t *) (scratch + 3*size)) +#define scratch_out (scratch + 5*size) + + size = ecc->p.size; + nbytes = 1 + ecc->p.bit_size / 8; + + assert (H->digest_size >= 2 * nbytes); + + H->update (ctx, length, msg); + H->digest (ctx, 2*nbytes, hash); + _eddsa_hash (&ecc->q, rp, hash); + ecc->mul_g (ecc, P, rp, scratch_out); + _eddsa_compress (ecc, signature, P, scratch_out); + + H->update (ctx, nbytes, signature); + H->update (ctx, nbytes, pub); + H->update (ctx, length, msg); + H->digest (ctx, 2*nbytes, hash); + _eddsa_hash (&ecc->q, hp, hash); + + ecc_modq_mul (ecc, sp, hp, k2); + ecc_modq_add (ecc, sp, sp, rp); /* FIXME: Can be plain add */ + /* FIXME: Special code duplicated in ecc_25519_modq and ecc_eh_to_a. + Define a suitable method? */ + { + unsigned shift; + mp_limb_t cy; + assert (ecc->p.bit_size == 255); + shift = 252 - GMP_NUMB_BITS * (ecc->p.size - 1); + cy = mpn_submul_1 (sp, ecc->q.m, ecc->p.size, + sp[ecc->p.size-1] >> shift); + assert (cy < 2); + cnd_add_n (cy, sp, ecc->q.m, ecc->p.size); + } + mpn_get_base256_le (signature + nbytes, nbytes, sp, ecc->q.size); +#undef rp +#undef hp +#undef P +#undef sp +#undef hash +} diff --git a/eddsa.h b/eddsa.h index 7152b0773ff41b3c1316fbf6248f308bdcb85432..551c73554150d3b9f21d3267fba634c358bd2b44 100644 --- a/eddsa.h +++ b/eddsa.h @@ -45,10 +45,14 @@ extern "C" { #define _eddsa_compress_itch _nettle_eddsa_compress_itch #define _eddsa_decompress _nettle_eddsa_decompress #define _eddsa_decompress_itch _nettle_eddsa_decompress_itch +#define _eddsa_hash _nettle_eddsa_hash +#define _eddsa_sign _nettle_eddsa_sign +#define _eddsa_sign_itch _nettle_eddsa_sign_itch #define ED25519_KEY_SIZE 32 struct ecc_curve; +struct ecc_modulo; mp_size_t _eddsa_compress_itch (const struct ecc_curve *ecc); @@ -63,6 +67,24 @@ _eddsa_decompress (const struct ecc_curve *ecc, mp_limb_t *p, const uint8_t *cp, mp_limb_t *scratch); +void +_eddsa_hash (const struct ecc_modulo *m, + mp_limb_t *rp, const uint8_t *digest); + +mp_size_t +_eddsa_sign_itch (const struct ecc_curve *ecc); + +void +_eddsa_sign (const struct ecc_curve *ecc, + const struct nettle_hash *H, + const uint8_t *pub, + void *ctx, + const mp_limb_t *k2, + size_t length, + const uint8_t *msg, + uint8_t *signature, + mp_limb_t *scratch); + #ifdef __cplusplus } #endif