From: Niels Möller Date: Thu, 28 Aug 2014 08:03:01 +0000 (+0200) Subject: Split ecc_generic_redc into two functions ecc_pp1_redc and ecc_pm1_redc. X-Git-Tag: nettle_3.1rc1~149 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=f064ef39b557eae53cfb30392d328adbe473d917;p=thirdparty%2Fnettle.git Split ecc_generic_redc into two functions ecc_pp1_redc and ecc_pm1_redc. --- diff --git a/ChangeLog b/ChangeLog index 3fa7b2e6..59965a00 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,20 @@ 2014-08-28 Niels Möller + * ecc-generic-redc.c (ecc_generic_redc): Deleted file and + function. Split into... + * ecc-pp1-redc.c (ecc_pp1_redc): New file and function. + * ecc-pm1-redc.c (ecc_pm1_redc): New file and function. + * ecc-internal.h: Updated declarations. + * Makefile.in (hogweed_SOURCES): Replace ecc-generic-redc.c by + ecc-pp1-redc.c and ecc-pm1-redc.c. + * ecc-192.c: Use ecc_pp1_redc (benchmarking only). + * ecc-224.c: Use ecc_pm1_redc when applicable. + * ecc-256.c: Use ecc_pp1_redc when applicable. + * ecc-384.c: Use ecc_pp1_redc (benchmarking only). + * ecc-521.c: Use ecc_pp1_redc (benchmarking only). + * testsuite/ecc-redc-test.c (test_main): Replace use of + ecc_generic_redc by ecc_pp1_redc and ecc_pm1_redc. + * eccdata.c (output_curve): Don't output ecc_redc_g. * ecc-internal.h (struct ecc_curve): Deleted unused field redc_g. Updated all instances. diff --git a/Makefile.in b/Makefile.in index d6370872..92ef8187 100644 --- a/Makefile.in +++ b/Makefile.in @@ -162,7 +162,7 @@ hogweed_SOURCES = sexp.c sexp-format.c \ sec-add-1.c sec-sub-1.c sec-modinv.c sec-tabselect.c \ gmp-glue.c cnd-copy.c \ ecc-mod.c ecc-generic-modp.c ecc-generic-modq.c \ - ecc-modp.c ecc-modq.c ecc-generic-redc.c \ + ecc-modp.c ecc-modq.c ecc-pp1-redc.c ecc-pm1-redc.c \ ecc-192.c ecc-224.c ecc-256.c ecc-384.c ecc-521.c \ ecc-25519.c \ ecc-size.c ecc-j-to-a.c ecc-a-to-j.c \ diff --git a/ecc-192.c b/ecc-192.c index f8ac522e..5253cc13 100644 --- a/ecc-192.c +++ b/ecc-192.c @@ -127,7 +127,7 @@ const struct ecc_curve nettle_secp_192r1 = ECC_J_TO_A_ITCH (ECC_LIMB_SIZE), ecc_192_modp, - ecc_generic_redc, + ECC_REDC_SIZE >= 1 ? ecc_pp1_redc : NULL, ecc_192_modp, ecc_generic_modq, diff --git a/ecc-224.c b/ecc-224.c index 6e48ddd0..2de193fe 100644 --- a/ecc-224.c +++ b/ecc-224.c @@ -54,6 +54,14 @@ ecc_224_modp (const struct ecc_curve *ecc, mp_limb_t *rp); #include "ecc-224.h" +#if ECC_REDC_SIZE < 0 +# define ecc_224_redc ecc_pm1_redc +#elif ECC_REDC_SIZE == 0 +# define ecc_224_redc NULL +#else +# error Configuration error +#endif + const struct ecc_curve nettle_secp_224r1 = { 224, @@ -71,8 +79,8 @@ const struct ecc_curve nettle_secp_224r1 = ECC_J_TO_A_ITCH (ECC_LIMB_SIZE), ecc_224_modp, - ecc_generic_redc, - USE_REDC ? ecc_generic_redc : ecc_224_modp, + ecc_224_redc, + USE_REDC ? ecc_224_redc : ecc_224_modp, ecc_generic_modq, ecc_mul_a, diff --git a/ecc-256.c b/ecc-256.c index 4de53008..6d413330 100644 --- a/ecc-256.c +++ b/ecc-256.c @@ -55,8 +55,14 @@ void ecc_256_redc (const struct ecc_curve *ecc, mp_limb_t *rp); #else /* !HAVE_NATIVE_ecc_256_redc */ -# define ecc_256_redc ecc_generic_redc -#endif +# if ECC_REDC_SIZE > 0 +# define ecc_256_redc ecc_pp1_redc +# elif ECC_REDC_SIZE == 0 +# define ecc_256_redc NULL +# else +# error Configuration error +# endif +#endif /* !HAVE_NATIVE_ecc_256_redc */ #if ECC_BMODP_SIZE < ECC_LIMB_SIZE #define ecc_256_modp ecc_generic_modp diff --git a/ecc-384.c b/ecc-384.c index 9d89fcb3..99f07266 100644 --- a/ecc-384.c +++ b/ecc-384.c @@ -164,7 +164,7 @@ const struct ecc_curve nettle_secp_384r1 = ECC_J_TO_A_ITCH (ECC_LIMB_SIZE), ecc_384_modp, - ECC_REDC_SIZE != 0 ? ecc_generic_redc : NULL, + ECC_REDC_SIZE > 0 ? ecc_pp1_redc : NULL, ecc_384_modp, ecc_generic_modq, diff --git a/ecc-521.c b/ecc-521.c index a38a25a7..cebf3e98 100644 --- a/ecc-521.c +++ b/ecc-521.c @@ -92,7 +92,7 @@ const struct ecc_curve nettle_secp_521r1 = ECC_J_TO_A_ITCH (ECC_LIMB_SIZE), ecc_521_modp, - ecc_generic_redc, + ECC_REDC_SIZE > 0 ? ecc_pp1_redc : NULL, ecc_521_modp, ecc_generic_modq, diff --git a/ecc-generic-redc.c b/ecc-generic-redc.c deleted file mode 100644 index cd264419..00000000 --- a/ecc-generic-redc.c +++ /dev/null @@ -1,94 +0,0 @@ -/* ecc-generic-redc.c - - Copyright (C) 2013 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/. -*/ - -/* Development of Nettle's ECC support was funded by the .SE Internet Fund. */ - -#if HAVE_CONFIG_H -# include "config.h" -#endif - -#include - -#include "ecc-internal.h" - -void -ecc_generic_redc (const struct ecc_curve *ecc, mp_limb_t *rp) -{ - unsigned i; - mp_limb_t hi, cy; - unsigned shift = ecc->size * GMP_NUMB_BITS - ecc->bit_size; - mp_size_t k = ecc->redc_size; - - assert (k != 0); - if (k > 0) - { - /* Use that 1 = p + 1, and that at least one low limb of p + 1 is zero. */ - for (i = 0; i < ecc->size; i++) - rp[i] = mpn_addmul_1 (rp + i + k, - ecc->redc_ppm1, ecc->size - k, rp[i]); - hi = mpn_add_n (rp, rp, rp + ecc->size, ecc->size); - if (shift > 0) - { - hi = (hi << shift) | (rp[ecc->size - 1] >> (GMP_NUMB_BITS - shift)); - rp[ecc->size - 1] = (rp[ecc->size - 1] - & (((mp_limb_t) 1 << (GMP_NUMB_BITS - shift)) - 1)) - + mpn_addmul_1 (rp, ecc->Bmodp_shifted, ecc->size-1, hi); - - } - else - { - cy = cnd_sub_n (hi, rp, ecc->p, ecc->size); - assert (cy == hi); - } - } - else - { - /* Use that 1 = - (p - 1), and that at least one low limb of p - - 1 is zero. */ - k = -k; - for (i = 0; i < ecc->size; i++) - rp[i] = mpn_submul_1 (rp + i + k, - ecc->redc_ppm1, ecc->size - k, rp[i]); - hi = mpn_sub_n (rp, rp + ecc->size, rp, ecc->size); - cy = cnd_add_n (hi, rp, ecc->p, ecc->size); - assert (cy == hi); - - if (shift > 0) - { - /* Result is always < 2p, provided that - 2^shift * Bmodp_shifted <= p */ - hi = (rp[ecc->size - 1] >> (GMP_NUMB_BITS - shift)); - rp[ecc->size - 1] = (rp[ecc->size - 1] - & (((mp_limb_t) 1 << (GMP_NUMB_BITS - shift)) - 1)) - + mpn_addmul_1 (rp, ecc->Bmodp_shifted, ecc->size-1, hi); - } - } -} diff --git a/ecc-internal.h b/ecc-internal.h index d7239e5d..1fa334aa 100644 --- a/ecc-internal.h +++ b/ecc-internal.h @@ -41,7 +41,8 @@ /* Name mangling */ #define ecc_generic_modp _nettle_ecc_generic_modp -#define ecc_generic_redc _nettle_ecc_generic_redc +#define ecc_pp1_redc _nettle_ecc_pp1_redc +#define ecc_pm1_redc _nettle_ecc_pm1_redc #define ecc_generic_modq _nettle_ecc_generic_modq #define ecc_modp_add _nettle_ecc_modp_add #define ecc_modp_sub _nettle_ecc_modp_sub @@ -174,7 +175,8 @@ struct ecc_curve /* In-place reduction. */ ecc_mod_func ecc_generic_modp; -ecc_mod_func ecc_generic_redc; +ecc_mod_func ecc_pp1_redc; +ecc_mod_func ecc_pm1_redc; ecc_mod_func ecc_generic_modq; diff --git a/ecc-pm1-redc.c b/ecc-pm1-redc.c new file mode 100644 index 00000000..02231f72 --- /dev/null +++ b/ecc-pm1-redc.c @@ -0,0 +1,70 @@ +/* ecc-pm1-redc.c + + Copyright (C) 2013, 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/. +*/ + +/* Development of Nettle's ECC support was funded by the .SE Internet Fund. */ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include + +#include "ecc-internal.h" + +/* Use that 1 = - (p - 1) (mod p), and that at least one low limb of p + - 1 is zero. */ +void +ecc_pm1_redc (const struct ecc_curve *ecc, mp_limb_t *rp) +{ + unsigned i; + mp_limb_t hi, cy; + unsigned shift = ecc->size * GMP_NUMB_BITS - ecc->bit_size; + mp_size_t k = -ecc->redc_size; + + assert (k > 0); + + for (i = 0; i < ecc->size; i++) + rp[i] = mpn_submul_1 (rp + i + k, + ecc->redc_ppm1, ecc->size - k, rp[i]); + hi = mpn_sub_n (rp, rp + ecc->size, rp, ecc->size); + cy = cnd_add_n (hi, rp, ecc->p, ecc->size); + assert (cy == hi); + + if (shift > 0) + { + /* Result is always < 2p, provided that + 2^shift * Bmodp_shifted <= p */ + hi = (rp[ecc->size - 1] >> (GMP_NUMB_BITS - shift)); + rp[ecc->size - 1] = (rp[ecc->size - 1] + & (((mp_limb_t) 1 << (GMP_NUMB_BITS - shift)) - 1)) + + mpn_addmul_1 (rp, ecc->Bmodp_shifted, ecc->size-1, hi); + } +} diff --git a/ecc-pp1-redc.c b/ecc-pp1-redc.c new file mode 100644 index 00000000..e2216119 --- /dev/null +++ b/ecc-pp1-redc.c @@ -0,0 +1,71 @@ +/* ecc-pp1-redc.c + + Copyright (C) 2013, 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/. +*/ + +/* Development of Nettle's ECC support was funded by the .SE Internet Fund. */ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include + +#include "ecc-internal.h" + +/* Use that 1 = p + 1 (mod p), and that at least one low limb of p + 1 + is zero. */ +void +ecc_pp1_redc (const struct ecc_curve *ecc, mp_limb_t *rp) +{ + unsigned i; + mp_limb_t hi, cy; + unsigned shift = ecc->size * GMP_NUMB_BITS - ecc->bit_size; + mp_size_t k = ecc->redc_size; + + assert (k > 0); + + for (i = 0; i < ecc->size; i++) + rp[i] = mpn_addmul_1 (rp + i + k, + ecc->redc_ppm1, ecc->size - k, rp[i]); + hi = mpn_add_n (rp, rp, rp + ecc->size, ecc->size); + if (shift > 0) + { + hi = (hi << shift) | (rp[ecc->size - 1] >> (GMP_NUMB_BITS - shift)); + rp[ecc->size - 1] = (rp[ecc->size - 1] + & (((mp_limb_t) 1 << (GMP_NUMB_BITS - shift)) - 1)) + + mpn_addmul_1 (rp, ecc->Bmodp_shifted, ecc->size-1, hi); + + } + else + { + cy = cnd_sub_n (hi, rp, ecc->p, ecc->size); + assert (cy == hi); + } +} diff --git a/testsuite/ecc-redc-test.c b/testsuite/ecc-redc-test.c index 1b0fe51d..538cd5f0 100644 --- a/testsuite/ecc-redc-test.c +++ b/testsuite/ecc-redc-test.c @@ -87,14 +87,18 @@ test_main (void) } mpn_copyi (m, a, 2*ecc->size); - ecc_generic_redc (ecc, m); + if (ecc->redc_size > 0) + ecc_pp1_redc (ecc, m); + else + ecc_pm1_redc (ecc, m); + if (mpn_cmp (m, ecc->p, ecc->size) >= 0) mpn_sub_n (m, m, ecc->p, ecc->size); if (mpn_cmp (m, ref, ecc->size)) { - fprintf (stderr, "ecc_generic_redc failed: bit_size = %u\n", - ecc->bit_size); + fprintf (stderr, "ecc_p%c1_redc failed: bit_size = %u\n", + ecc->redc_size > 0 ? 'p' : 'm', ecc->bit_size); gmp_fprintf (stderr, "a = %Nx\n", a, 2*ecc->size); gmp_fprintf (stderr, "m = %Nx (bad)\n", m, ecc->size); gmp_fprintf (stderr, "ref = %Nx\n", ref, ecc->size);