diff --git a/ChangeLog b/ChangeLog index 7280e91b0a10dc90e61af1c85cc55d2988795a88..48e295bfa989c2144524716347039f17eca52c56 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,7 +1,12 @@ 2014-07-15 Niels Möller <nisse@lysator.liu.se> - * testsuite/curve25519-add-test.c (test_main): Additonal test for - g2+g2. Free allocated storage. + * ecc-add-eh.c (ecc_add_eh, ecc_add_eh_itch): New file, new + functions. + * ecc.h: Declare new functions. + * ecc-internal.h (ECC_ADD_EH_ITCH): New macro. + * Makefile.in (hogweed_SOURCES): Added ecc-add-eh.c. + * testsuite/curve25519-add-test.c (test_main): Test ecc_add_eh. + Additional test for g2+g2. Free allocated storage. 2014-07-14 Niels Möller <nisse@lysator.liu.se> diff --git a/Makefile.in b/Makefile.in index 6831cc4ad375b2216a189b7729648b71f74066a6..9a91aec3f8755891a9630147cc4280a54e891cfe 100644 --- a/Makefile.in +++ b/Makefile.in @@ -167,7 +167,7 @@ hogweed_SOURCES = sexp.c sexp-format.c \ ecc-25519.c \ ecc-size.c ecc-j-to-a.c ecc-a-to-j.c \ ecc-dup-jj.c ecc-add-jja.c ecc-add-jjj.c \ - ecc-dup-eh.c ecc-add-ehh.c ecc-eh-to-a.c \ + ecc-dup-eh.c ecc-add-eh.c ecc-add-ehh.c ecc-eh-to-a.c \ ecc-mul-g.c ecc-mul-a.c ecc-hash.c ecc-random.c \ ecc-point.c ecc-scalar.c ecc-point-mul.c ecc-point-mul-g.c \ ecc-ecdsa-sign.c ecdsa-sign.c \ diff --git a/ecc-add-eh.c b/ecc-add-eh.c new file mode 100644 index 0000000000000000000000000000000000000000..05c2188ef83c8bd817cf0433a78768696d48a4cb --- /dev/null +++ b/ecc-add-eh.c @@ -0,0 +1,111 @@ +/* ecc-add-eh.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 "ecc.h" +#include "ecc-internal.h" + +mp_size_t +ecc_add_eh_itch (const struct ecc_curve *ecc) +{ + return ECC_ADD_EH_ITCH (ecc->size); +} + +/* Add two points on an Edwards curve, with result and first point in + homogeneous coordinates. */ +void +ecc_add_eh (const struct ecc_curve *ecc, + mp_limb_t *r, const mp_limb_t *p, const mp_limb_t *q, + mp_limb_t *scratch) +{ +#define x1 p +#define y1 (p + ecc->size) +#define z1 (p + 2*ecc->size) + +#define x2 q +#define y2 (q + ecc->size) + +#define x3 r +#define y3 (r + ecc->size) +#define z3 (r + 2*ecc->size) + + /* Formulas (from djb, + http://www.hyperelliptic.org/EFD/g1p/auto-edwards-projective.html#doubling-dbl-2007-bl): + + Computation Operation Live variables + + B = z1^2 sqr B + C = x1*x2 mul B, C + D = y1*y2 mul B, C, D + E = b*C*D 2 mul B, C, D, E + F = B - E B, C, D, E, F + G = B + E C, D, F, G + x3 = z1*F*[(x1+y1)(x2+y2) - C - D] 3 mul C, D, G + y3 = z1*G*(D-C) 2 mul F, G + z3 = F*G mul + */ +#define B (scratch) +#define C (scratch + 1*ecc->size) +#define D (scratch + 2*ecc->size) +#define E (scratch + 3*ecc->size) +#define F (scratch + 4*ecc->size) +#define G (scratch + 5*ecc->size) +#define T (scratch + 6*ecc->size) + + ecc_modp_sqr (ecc, B, z1); + ecc_modp_mul (ecc, C, x1, x2); + ecc_modp_mul (ecc, D, y1, y2); + ecc_modp_mul (ecc, T, C, D); + ecc_modp_mul (ecc, E, T, ecc->b); + ecc_modp_sub (ecc, F, B, E); + ecc_modp_add (ecc, G, B, E); + + /* x3 */ + ecc_modp_add (ecc, B, x1, y1); + ecc_modp_add (ecc, E, x2, y2); + ecc_modp_mul (ecc, T, B, E); + ecc_modp_sub (ecc, T, T, C); + ecc_modp_sub (ecc, x3, T, D); + ecc_modp_mul (ecc, T, x3, z1); + ecc_modp_mul (ecc, x3, T, F); + + /* y3 */ + ecc_modp_sub (ecc, C, D, C); + ecc_modp_mul (ecc, T, z1, C); + ecc_modp_mul (ecc, y3, T, G); + + /* z3 */ + ecc_modp_mul (ecc, T, F, G); + mpn_copyi (z3, T, ecc->size); +} diff --git a/ecc-internal.h b/ecc-internal.h index 1fefd138b86aae6c87d503667991ab582b639d3e..f2b9927876cd4410e45b7d79c8a313f3eed4690f 100644 --- a/ecc-internal.h +++ b/ecc-internal.h @@ -242,6 +242,7 @@ sec_modinv (mp_limb_t *vp, mp_limb_t *ap, mp_size_t n, #define ECC_DUP_EH_ITCH(size) (5*(size)) #define ECC_ADD_JJA_ITCH(size) (6*(size)) #define ECC_ADD_JJJ_ITCH(size) (8*(size)) +#define ECC_ADD_EH_ITCH(size) (8*(size)) #define ECC_ADD_EHH_ITCH(size) (9*(size)) #define ECC_MUL_G_ITCH(size) (9*(size)) #if ECC_MUL_A_WBITS == 0 diff --git a/ecc.h b/ecc.h index f8cadf5e2ba4d275cfadd476deb3667d5ae324ac..df9013aaf60d180a3bb55f79c81b6e6c76de5908 100644 --- a/ecc.h +++ b/ecc.h @@ -71,6 +71,8 @@ extern "C" { #define ecc_add_jjj nettle_ecc_add_jjj #define ecc_dup_eh_itch nettle_ecc_dup_eh_itch #define ecc_dup_eh nettle_ecc_dup_eh +#define ecc_add_eh_itch nettle_ecc_add_eh_itch +#define ecc_add_eh nettle_ecc_add_eh #define ecc_add_ehh_itch nettle_ecc_add_ehh_itch #define ecc_add_ehh nettle_ecc_add_ehh #define ecc_mul_g_itch nettle_ecc_mul_g_itch @@ -245,6 +247,13 @@ ecc_dup_eh (const struct ecc_curve *ecc, mp_limb_t *r, const mp_limb_t *p, mp_limb_t *scratch); +mp_size_t +ecc_add_eh_itch (const struct ecc_curve *ecc); +void +ecc_add_eh (const struct ecc_curve *ecc, + mp_limb_t *r, const mp_limb_t *p, const mp_limb_t *q, + mp_limb_t *scratch); + mp_size_t ecc_add_ehh_itch (const struct ecc_curve *ecc); void diff --git a/testsuite/curve25519-add-test.c b/testsuite/curve25519-add-test.c index 6a0d3250c0b1c0ca455f3a8016084696d0d139e0..cee6b51df2ebed7a94be9c771128c72e57350284 100644 --- a/testsuite/curve25519-add-test.c +++ b/testsuite/curve25519-add-test.c @@ -85,28 +85,43 @@ test_main (void) if (!point_zero_p (ecc, pe)) die ("dup of zero point failed.\n"); + ecc_add_eh (ecc, pe, z, z, scratch); + if (!point_zero_p (ecc, pe)) + die ("dup of zero point failed.\n"); + ecc_add_ehh (ecc, pe, g, pe, scratch); + ecc_eh_to_a (ecc, 0, pa, pe, scratch); + test_ecc_point (ecc, &rg, pa); + ecc_add_eh (ecc, pe, z, g, scratch); ecc_eh_to_a (ecc, 0, pa, pe, scratch); test_ecc_point (ecc, &rg, pa); ecc_add_ehh (ecc, g2, g, pe, scratch); + ecc_eh_to_a (ecc, 0, pa, g2, scratch); + test_ecc_point (ecc, &rg2, pa); + ecc_add_eh (ecc, g2, g, g, scratch); ecc_eh_to_a (ecc, 0, pa, g2, scratch); test_ecc_point (ecc, &rg2, pa); ecc_add_ehh (ecc, g3, g, g2, scratch); + ecc_eh_to_a (ecc, 0, pa, g3, scratch); + test_ecc_point (ecc, &rg3, pa); + ecc_add_eh (ecc, g3, g2, g, scratch); ecc_eh_to_a (ecc, 0, pa, g3, scratch); test_ecc_point (ecc, &rg3, pa); ecc_add_ehh (ecc, g4, g, g3, scratch); + ecc_eh_to_a (ecc, 0, pa, g4, scratch); + test_ecc_point (ecc, &rg4, pa); + ecc_add_eh (ecc, g4, g3, g, scratch); ecc_eh_to_a (ecc, 0, pa, g4, scratch); test_ecc_point (ecc, &rg4, pa); ecc_add_ehh (ecc, g4, g2, g2, scratch); - ecc_eh_to_a (ecc, 0, pa, g4, scratch); test_ecc_point (ecc, &rg4, pa);