2014-08-28 Niels Möller <nisse@lysator.liu.se>
+ * 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.
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 \
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,
#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,
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,
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
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,
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,
+++ /dev/null
-/* 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 <assert.h>
-
-#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);
- }
- }
-}
/* 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
/* 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;
--- /dev/null
+/* 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 <assert.h>
+
+#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);
+ }
+}
--- /dev/null
+/* 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 <assert.h>
+
+#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);
+ }
+}
}
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);