From 0b511c919436d21d14280b2c6ed9f1131de71de4 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Niels=20M=C3=B6ller?= <nisse@lysator.liu.se>
Date: Mon, 22 Sep 2014 13:47:43 +0200
Subject: [PATCH] Use struct ecc_modulo for all mod and redc functions.

---
 ChangeLog                 | 14 ++++++++++++
 Makefile.in               |  2 +-
 ecc-192.c                 | 10 ++++----
 ecc-224.c                 |  6 ++---
 ecc-25519.c               | 12 +++++-----
 ecc-256.c                 | 30 ++++++++++++------------
 ecc-384.c                 | 12 +++++-----
 ecc-521.c                 |  4 ++--
 ecc-a-to-j.c              |  4 ++--
 ecc-generic-modp.c        | 48 ---------------------------------------
 ecc-generic-modq.c        | 48 ---------------------------------------
 ecc-internal.h            | 11 ++-------
 ecc-j-to-a.c              |  6 ++---
 ecc-mod.c                 |  5 ++--
 ecc-modp.c                |  4 ++--
 ecc-modq.c                |  2 +-
 ecc-pm1-redc.c            | 20 ++++++++--------
 ecc-pp1-redc.c            | 20 ++++++++--------
 examples/ecc-benchmark.c  |  6 ++---
 testsuite/ecc-mod-test.c  |  8 +++----
 testsuite/ecc-redc-test.c |  6 ++---
 21 files changed, 95 insertions(+), 183 deletions(-)
 delete mode 100644 ecc-generic-modp.c
 delete mode 100644 ecc-generic-modq.c

diff --git a/ChangeLog b/ChangeLog
index e1abab9b..21aaca66 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,19 @@
 2014-09-22  Niels Möller  <nisse@lysator.liu.se>
 
+	* ecc-generic-modp.c (ecc_generic_modp): Deleted file and
+	function. We no longer need a wrapper around ecc_mod.
+	* ecc-generic-modq.c (ecc_generic_modq): Likewise deleted.
+	* Makefile.in (hogweed_SOURCES): Removed ecc-generic-modp.c and
+	ecc-generic-modq.c.
+
+	* ecc-internal.h (typedef ecc_mod_func): Take a const struct
+	ecc_modulo * argument, not const struct ecc_curve *. Updated all
+	implementations and all callers.
+
+	* ecc-mod.c (ecc_mod): Use struct ecc_modulo to specify the
+	modulo. Drop input size argument, always reduce from 2*size to
+	size.
+
 	* ecc-internal.h (struct ecc_modulo): New struct, collecting
 	constants needed for modulo arithmetic.
 	(struct ecc_curve): Use struct ecc_modulo for p and q arithmetic.
diff --git a/Makefile.in b/Makefile.in
index 770d55f7..8b04b101 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -162,7 +162,7 @@ hogweed_SOURCES = sexp.c sexp-format.c \
 		  der-iterator.c der2rsa.c der2dsa.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-mod.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 \
diff --git a/ecc-192.c b/ecc-192.c
index 227bdd21..c9bcf8fe 100644
--- a/ecc-192.c
+++ b/ecc-192.c
@@ -52,14 +52,14 @@
 
 #define ecc_192_modp nettle_ecc_192_modp
 void
-ecc_192_modp (const struct ecc_curve *ecc, mp_limb_t *rp);
+ecc_192_modp (const struct ecc_modulo *m, mp_limb_t *rp);
 
 /* Use that p = 2^{192} - 2^64 - 1, to eliminate 128 bits at a time. */
 
 #elif GMP_NUMB_BITS == 32
 /* p is 6 limbs, p = B^6 - B^2 - 1 */
 static void
-ecc_192_modp (const struct ecc_curve *ecc UNUSED, mp_limb_t *rp)
+ecc_192_modp (const struct ecc_modulo *m UNUSED, mp_limb_t *rp)
 {
   mp_limb_t cy;
 
@@ -84,7 +84,7 @@ ecc_192_modp (const struct ecc_curve *ecc UNUSED, mp_limb_t *rp)
 #elif GMP_NUMB_BITS == 64
 /* p is 3 limbs, p = B^3 - B - 1 */
 static void
-ecc_192_modp (const struct ecc_curve *ecc UNUSED, mp_limb_t *rp)
+ecc_192_modp (const struct ecc_modulo *m UNUSED, mp_limb_t *rp)
 {
   mp_limb_t cy;
 
@@ -107,7 +107,7 @@ ecc_192_modp (const struct ecc_curve *ecc UNUSED, mp_limb_t *rp)
 }
   
 #else
-#define ecc_192_modp ecc_generic_modp
+#define ecc_192_modp ecc_mod
 #endif
 
 const struct ecc_curve nettle_secp_192r1 =
@@ -145,7 +145,7 @@ const struct ecc_curve nettle_secp_192r1 =
   ecc_192_modp,
   ECC_REDC_SIZE >= 1 ? ecc_pp1_redc : NULL,
   ecc_192_modp,
-  ecc_generic_modq,
+  ecc_mod,
 
   ecc_add_jjj,
   ecc_mul_a,
diff --git a/ecc-224.c b/ecc-224.c
index 5b4e58d4..72f9fc7b 100644
--- a/ecc-224.c
+++ b/ecc-224.c
@@ -45,11 +45,11 @@
 #define USE_REDC 0
 #define ecc_224_modp nettle_ecc_224_modp
 void
-ecc_224_modp (const struct ecc_curve *ecc, mp_limb_t *rp);
+ecc_224_modp (const struct ecc_modulo *m, mp_limb_t *rp);
 
 #else
 #define USE_REDC (ECC_REDC_SIZE != 0)
-#define ecc_224_modp ecc_generic_modp
+#define ecc_224_modp ecc_mod
 #endif
 
 #include "ecc-224.h"
@@ -97,7 +97,7 @@ const struct ecc_curve nettle_secp_224r1 =
   ecc_224_modp,
   ecc_224_redc,
   USE_REDC ? ecc_224_redc : ecc_224_modp,
-  ecc_generic_modq,
+  ecc_mod,
 
   ecc_add_jjj,
   ecc_mul_a,
diff --git a/ecc-25519.c b/ecc-25519.c
index c8ffba44..55083b88 100644
--- a/ecc-25519.c
+++ b/ecc-25519.c
@@ -58,7 +58,7 @@ ecc_25519_modp (const struct ecc_curve *ecc, mp_limb_t *rp);
 #endif
 
 static void
-ecc_25519_modp(const struct ecc_curve *ecc UNUSED, mp_limb_t *rp)
+ecc_25519_modp(const struct ecc_modulo *m UNUSED, mp_limb_t *rp)
 {
   mp_limb_t hi, cy;
 
@@ -78,7 +78,7 @@ ecc_25519_modp(const struct ecc_curve *ecc UNUSED, mp_limb_t *rp)
 #endif
 
 static void
-ecc_25519_modq (const struct ecc_curve *ecc, mp_limb_t *rp)
+ecc_25519_modq (const struct ecc_modulo *q, mp_limb_t *rp)
 {
   mp_size_t n;
   mp_limb_t cy;
@@ -87,17 +87,17 @@ ecc_25519_modq (const struct ecc_curve *ecc, mp_limb_t *rp)
   for (n = ECC_LIMB_SIZE; n-- > 0;)
     {
       cy = mpn_submul_1 (rp + n,
-			 ecc->q.B_shifted, ECC_LIMB_SIZE,
+			 q->B_shifted, ECC_LIMB_SIZE,
 			 rp[n + ECC_LIMB_SIZE]);
       /* Top limb of mBmodq_shifted is zero, so we get cy == 0 or 1 */
       assert (cy < 2);
-      cnd_add_n (cy, rp+n, ecc->q.m, ECC_LIMB_SIZE);
+      cnd_add_n (cy, rp+n, q->m, ECC_LIMB_SIZE);
     }
 
-  cy = mpn_submul_1 (rp, ecc->q.m, ECC_LIMB_SIZE,
+  cy = mpn_submul_1 (rp, q->m, ECC_LIMB_SIZE,
 		     rp[ECC_LIMB_SIZE-1] >> (GMP_NUMB_BITS - QHIGH_BITS));
   assert (cy < 2);
-  cnd_add_n (cy, rp, ecc->q.m, ECC_LIMB_SIZE);
+  cnd_add_n (cy, rp, q->m, ECC_LIMB_SIZE);
 }
 
 /* Needs 2*ecc->size limbs at rp, and 2*ecc->size additional limbs of
diff --git a/ecc-256.c b/ecc-256.c
index 3e51304f..a6ac4b6c 100644
--- a/ecc-256.c
+++ b/ecc-256.c
@@ -65,22 +65,22 @@ ecc_256_redc (const struct ecc_curve *ecc, mp_limb_t *rp);
 #endif /* !HAVE_NATIVE_ecc_256_redc */
 
 #if ECC_BMODP_SIZE < ECC_LIMB_SIZE
-#define ecc_256_modp ecc_generic_modp
-#define ecc_256_modq ecc_generic_modq
+#define ecc_256_modp ecc_mod
+#define ecc_256_modq ecc_mod
 #elif GMP_NUMB_BITS == 64
 
 static void
-ecc_256_modp (const struct ecc_curve *ecc, mp_limb_t *rp)
+ecc_256_modp (const struct ecc_modulo *p, mp_limb_t *rp)
 {
   mp_limb_t u1, u0;
   mp_size_t n;
 
-  n = 2*ecc->p.size;
+  n = 2*p->size;
   u1 = rp[--n];
   u0 = rp[n-1];
 
   /* This is not particularly fast, but should work well with assembly implementation. */
-  for (; n >= ecc->p.size; n--)
+  for (; n >= p->size; n--)
     {
       mp_limb_t q2, q1, q0, t, cy;
 
@@ -115,8 +115,8 @@ ecc_256_modp (const struct ecc_curve *ecc, mp_limb_t *rp)
 
       /* We multiply by two low limbs of p, 2^96 - 1, so we could use
 	 shifts rather than mul. */
-      t = mpn_submul_1 (rp + n - 4, ecc->p.m, 2, q1);
-      t += cnd_sub_n (q2, rp + n - 3, ecc->p.m, 1);
+      t = mpn_submul_1 (rp + n - 4, p->m, 2, q1);
+      t += cnd_sub_n (q2, rp + n - 3, p->m, 1);
       t += (-q2) & 0xffffffff;
 
       u0 = rp[n-2];
@@ -124,7 +124,7 @@ ecc_256_modp (const struct ecc_curve *ecc, mp_limb_t *rp)
       u0 -= t;
       t = (u1 < cy);
       u1 -= cy;
-      u1 += cnd_add_n (t, rp + n - 4, ecc->p.m, 3);
+      u1 += cnd_add_n (t, rp + n - 4, p->m, 3);
       u1 -= (-t) & 0xffffffff;
     }
   rp[2] = u0;
@@ -132,17 +132,17 @@ ecc_256_modp (const struct ecc_curve *ecc, mp_limb_t *rp)
 }
 
 static void
-ecc_256_modq (const struct ecc_curve *ecc, mp_limb_t *rp)
+ecc_256_modq (const struct ecc_modulo *q, mp_limb_t *rp)
 {
   mp_limb_t u2, u1, u0;
   mp_size_t n;
 
-  n = 2*ecc->q.size;
+  n = 2*q->size;
   u2 = rp[--n];
   u1 = rp[n-1];
 
   /* This is not particularly fast, but should work well with assembly implementation. */
-  for (; n >= ecc->q.size; n--)
+  for (; n >= q->size; n--)
     {
       mp_limb_t q2, q1, q0, t, c1, c0;
 
@@ -196,9 +196,9 @@ ecc_256_modq (const struct ecc_curve *ecc, mp_limb_t *rp)
 
       assert (q2 < 2);
 
-      c0 = cnd_sub_n (q2, rp + n - 3, ecc->q.m, 1);
-      c0 += (-q2) & ecc->q.m[1];
-      t = mpn_submul_1 (rp + n - 4, ecc->q.m, 2, q1);
+      c0 = cnd_sub_n (q2, rp + n - 3, q->m, 1);
+      c0 += (-q2) & q->m[1];
+      t = mpn_submul_1 (rp + n - 4, q->m, 2, q1);
       c0 += t;
       c1 = c0 < t;
       
@@ -213,7 +213,7 @@ ecc_256_modq (const struct ecc_curve *ecc, mp_limb_t *rp)
       u1 += t;
       u2 += (t<<32) + (u0 < t);
 
-      t = cnd_add_n (t, rp + n - 4, ecc->q.m, 2);
+      t = cnd_add_n (t, rp + n - 4, q->m, 2);
       u1 += t;
       u2 += (u1 < t);
     }
diff --git a/ecc-384.c b/ecc-384.c
index 7ef9b1b3..cd53f3d7 100644
--- a/ecc-384.c
+++ b/ecc-384.c
@@ -62,7 +62,7 @@ ecc_384_modp (const struct ecc_curve *ecc, mp_limb_t *rp);
    almost 8 at a time. Do only 7, to avoid additional carry
    propagation, followed by 5. */
 static void
-ecc_384_modp (const struct ecc_curve *ecc, mp_limb_t *rp)
+ecc_384_modp (const struct ecc_modulo *p, mp_limb_t *rp)
 {
   mp_limb_t cy, bw;
 
@@ -99,14 +99,14 @@ ecc_384_modp (const struct ecc_curve *ecc, mp_limb_t *rp)
   assert (cy >= bw);
   cy -= bw;
   assert (cy <= 1);
-  cy = cnd_add_n (cy, rp, ecc->Bmodp, ECC_LIMB_SIZE);
+  cy = cnd_add_n (cy, rp, p->B, ECC_LIMB_SIZE);
   assert (cy == 0);
 }
 #elif GMP_NUMB_BITS == 64
 /* p is 6 limbs, and B^6 - p = B^2 + 2^32 (B - 1) + 1. Eliminate 3
    (almost 4) limbs at a time. */
 static void
-ecc_384_modp (const struct ecc_curve *ecc, mp_limb_t *rp)
+ecc_384_modp (const struct ecc_modulo *p, mp_limb_t *rp)
 {
   mp_limb_t tp[6];
   mp_limb_t cy;
@@ -140,11 +140,11 @@ ecc_384_modp (const struct ecc_curve *ecc, mp_limb_t *rp)
   cy = sec_add_1 (rp + 5, rp + 5, 1, cy);
   assert (cy <= 1);
 
-  cy = cnd_add_n (cy, rp, ecc->p.B, ECC_LIMB_SIZE);
+  cy = cnd_add_n (cy, rp, p->B, ECC_LIMB_SIZE);
   assert (cy == 0);  
 }
 #else
-#define ecc_384_modp ecc_generic_modp
+#define ecc_384_modp ecc_mod
 #endif
   
 const struct ecc_curve nettle_secp_384r1 =
@@ -182,7 +182,7 @@ const struct ecc_curve nettle_secp_384r1 =
   ecc_384_modp,
   ECC_REDC_SIZE > 0 ? ecc_pp1_redc : NULL,
   ecc_384_modp,
-  ecc_generic_modq,
+  ecc_mod,
 
   ecc_add_jjj,
   ecc_mul_a,
diff --git a/ecc-521.c b/ecc-521.c
index c3fed94f..505f6e25 100644
--- a/ecc-521.c
+++ b/ecc-521.c
@@ -57,7 +57,7 @@ ecc_521_modp (const struct ecc_curve *ecc, mp_limb_t *rp);
 
 /* Result may be *slightly* larger than 2^521 */
 static void
-ecc_521_modp (const struct ecc_curve *ecc UNUSED, mp_limb_t *rp)
+ecc_521_modp (const struct ecc_modulo *m UNUSED, mp_limb_t *rp)
 {
   /* FIXME: Should use mpn_addlsh_n_ip1 */
   mp_limb_t hi;
@@ -110,7 +110,7 @@ const struct ecc_curve nettle_secp_521r1 =
   ecc_521_modp,
   ECC_REDC_SIZE > 0 ? ecc_pp1_redc : NULL,
   ecc_521_modp,
-  ecc_generic_modq,
+  ecc_mod,
 
   ecc_add_jjj,
   ecc_mul_a,
diff --git a/ecc-a-to-j.c b/ecc-a-to-j.c
index 7852e14a..ea0fa68c 100644
--- a/ecc-a-to-j.c
+++ b/ecc-a-to-j.c
@@ -47,10 +47,10 @@ ecc_a_to_j (const struct ecc_curve *ecc,
       mpn_copyd (r + ecc->p.size, p, 2*ecc->p.size);
 
       mpn_zero (r, ecc->p.size);
-      ecc->modp (ecc, r);
+      ecc->modp (&ecc->p, r);
 
       mpn_zero (r + ecc->p.size, ecc->p.size);
-      ecc->modp (ecc, r + ecc->p.size);
+      ecc->modp (&ecc->p, r + ecc->p.size);
     }
   else if (r != p)
     mpn_copyi (r, p, 2*ecc->p.size);
diff --git a/ecc-generic-modp.c b/ecc-generic-modp.c
deleted file mode 100644
index 5bd4eece..00000000
--- a/ecc-generic-modp.c
+++ /dev/null
@@ -1,48 +0,0 @@
-/* ecc-generic-modp.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_modp (const struct ecc_curve *ecc, mp_limb_t *rp)
-{
-  assert (ecc->p.B_size < ecc->p.size);
-  
-  ecc_mod (&ecc->p, rp, 2*ecc->p.size);
-}
diff --git a/ecc-generic-modq.c b/ecc-generic-modq.c
deleted file mode 100644
index c66113d6..00000000
--- a/ecc-generic-modq.c
+++ /dev/null
@@ -1,48 +0,0 @@
-/* ecc-generic-modq.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_modq (const struct ecc_curve *ecc, mp_limb_t *rp)
-{
-  assert (ecc->q.B_size < ecc->q.size);
-
-  ecc_mod (&ecc->q, rp, 2*ecc->q.size);
-}
diff --git a/ecc-internal.h b/ecc-internal.h
index b81da1f3..22ff181c 100644
--- a/ecc-internal.h
+++ b/ecc-internal.h
@@ -40,10 +40,8 @@
 #include "gmp-glue.h"
 
 /* Name mangling */
-#define ecc_generic_modp _nettle_ecc_generic_modp
 #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
 #define ecc_modp_mul_1 _nettle_ecc_modp_mul_1
@@ -97,7 +95,7 @@ struct ecc_modulo
 /* Reduces from 2*ecc->size to ecc->size. */
 /* Required to return a result < 2q. This property is inherited by
    modp_mul and modp_sqr. */
-typedef void ecc_mod_func (const struct ecc_curve *ecc, mp_limb_t *rp);
+typedef void ecc_mod_func (const struct ecc_modulo *m, mp_limb_t *rp);
 
 typedef void ecc_add_func (const struct ecc_curve *ecc,
 			   mp_limb_t *r,
@@ -180,11 +178,9 @@ struct ecc_curve
 };
 
 /* In-place reduction. */
-ecc_mod_func ecc_generic_modp;
+ecc_mod_func ecc_mod;
 ecc_mod_func ecc_pp1_redc;
 ecc_mod_func ecc_pm1_redc;
-ecc_mod_func ecc_generic_modq;
-
 
 void
 ecc_modp_add (const struct ecc_curve *ecc, mp_limb_t *rp,
@@ -233,9 +229,6 @@ void
 ecc_modq_random (const struct ecc_curve *ecc, mp_limb_t *xp,
 		 void *ctx, nettle_random_func *random, mp_limb_t *scratch);
 
-void
-ecc_mod (const struct ecc_modulo *m, mp_limb_t *rp, mp_size_t rn);
-
 void
 ecc_hash (const struct ecc_curve *ecc,
 	  mp_limb_t *hp,
diff --git a/ecc-j-to-a.c b/ecc-j-to-a.c
index eb22ecab..874da294 100644
--- a/ecc-j-to-a.c
+++ b/ecc-j-to-a.c
@@ -73,16 +73,16 @@ ecc_j_to_a (const struct ecc_curve *ecc,
 
       mpn_copyi (up, p + 2*ecc->p.size, ecc->p.size);
       mpn_zero (up + ecc->p.size, ecc->p.size);
-      ecc->redc (ecc, up);
+      ecc->redc (&ecc->p, up);
       mpn_zero (up + ecc->p.size, ecc->p.size);
-      ecc->redc (ecc, up);
+      ecc->redc (&ecc->p, up);
 
       ecc_modp_inv (ecc, izp, up, up + ecc->p.size);
 
       /* Divide this common factor by B */
       mpn_copyi (izBp, izp, ecc->p.size);
       mpn_zero (izBp + ecc->p.size, ecc->p.size);
-      ecc->redc (ecc, izBp);
+      ecc->redc (&ecc->p, izBp);
 
       ecc_modp_mul (ecc, iz2p, izp, izBp);
     }
diff --git a/ecc-mod.c b/ecc-mod.c
index 68576a8b..5fee4c68 100644
--- a/ecc-mod.c
+++ b/ecc-mod.c
@@ -39,14 +39,15 @@
 
 #include "ecc-internal.h"
 
-/* Computes r mod m. */
+/* Computes r mod m, input 2*m->size, output m->size. */
 void
-ecc_mod (const struct ecc_modulo *m, mp_limb_t *rp, mp_size_t rn)
+ecc_mod (const struct ecc_modulo *m, mp_limb_t *rp)
 {
   mp_limb_t hi;
   mp_size_t mn = m->size;
   mp_size_t bn = m->B_size;
   mp_size_t sn = mn - bn;
+  mp_size_t rn = 2*mn;
   mp_size_t i;
   unsigned shift;
 
diff --git a/ecc-modp.c b/ecc-modp.c
index fe6c54a4..6f305aea 100644
--- a/ecc-modp.c
+++ b/ecc-modp.c
@@ -115,7 +115,7 @@ ecc_modp_mul (const struct ecc_curve *ecc, mp_limb_t *rp,
 	      const mp_limb_t *ap, const mp_limb_t *bp)
 {
   mpn_mul_n (rp, ap, bp, ecc->p.size);
-  ecc->reduce (ecc, rp);
+  ecc->reduce (&ecc->p, rp);
 }
 
 void
@@ -123,7 +123,7 @@ ecc_modp_sqr (const struct ecc_curve *ecc, mp_limb_t *rp,
 	      const mp_limb_t *ap)
 {
   mpn_sqr (rp, ap, ecc->p.size);
-  ecc->reduce (ecc, rp);
+  ecc->reduce (&ecc->p, rp);
 }
 
 void
diff --git a/ecc-modq.c b/ecc-modq.c
index 850290a2..54533bde 100644
--- a/ecc-modq.c
+++ b/ecc-modq.c
@@ -57,7 +57,7 @@ ecc_modq_mul (const struct ecc_curve *ecc, mp_limb_t *rp,
 	      const mp_limb_t *ap, const mp_limb_t *bp)
 {
   mpn_mul_n (rp, ap, bp, ecc->q.size);
-  ecc->modq (ecc, rp);
+  ecc->modq (&ecc->q, rp);
 }
 
 void
diff --git a/ecc-pm1-redc.c b/ecc-pm1-redc.c
index 6e742e9e..2ed50ca5 100644
--- a/ecc-pm1-redc.c
+++ b/ecc-pm1-redc.c
@@ -42,27 +42,27 @@
 /* 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)
+ecc_pm1_redc (const struct ecc_modulo *m, mp_limb_t *rp)
 {
   unsigned i;
   mp_limb_t hi, cy;
-  unsigned shift = ecc->p.size * GMP_NUMB_BITS - ecc->p.bit_size;
-  mp_size_t k = ecc->p.redc_size;
+  unsigned shift = m->size * GMP_NUMB_BITS - m->bit_size;
+  mp_size_t k = m->redc_size;
   
-  for (i = 0; i < ecc->p.size; i++)
+  for (i = 0; i < m->size; i++)
     rp[i] = mpn_submul_1 (rp + i + k,
-			  ecc->p.redc_mpm1, ecc->p.size - k, rp[i]);
-  hi = mpn_sub_n (rp, rp + ecc->p.size, rp, ecc->p.size);
-  cy = cnd_add_n (hi, rp, ecc->p.m, ecc->p.size);
+			  m->redc_mpm1, m->size - k, rp[i]);
+  hi = mpn_sub_n (rp, rp + m->size, rp, m->size);
+  cy = cnd_add_n (hi, rp, m->m, m->size);
   assert (cy == hi);
 
   if (shift > 0)
     {
       /* Result is always < 2p, provided that
 	 2^shift * Bmodp_shifted <= p */
-      hi = (rp[ecc->p.size - 1] >> (GMP_NUMB_BITS - shift));
-      rp[ecc->p.size - 1] = (rp[ecc->p.size - 1]
+      hi = (rp[m->size - 1] >> (GMP_NUMB_BITS - shift));
+      rp[m->size - 1] = (rp[m->size - 1]
 			   & (((mp_limb_t) 1 << (GMP_NUMB_BITS - shift)) - 1))
-	+ mpn_addmul_1 (rp, ecc->p.B_shifted, ecc->p.size-1, hi);
+	+ mpn_addmul_1 (rp, m->B_shifted, m->size-1, hi);
     }
 }
diff --git a/ecc-pp1-redc.c b/ecc-pp1-redc.c
index f631f094..ae5b9669 100644
--- a/ecc-pp1-redc.c
+++ b/ecc-pp1-redc.c
@@ -42,28 +42,28 @@
 /* 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)
+ecc_pp1_redc (const struct ecc_modulo *m, mp_limb_t *rp)
 {
   unsigned i;
   mp_limb_t hi, cy;
-  unsigned shift = ecc->p.size * GMP_NUMB_BITS - ecc->p.bit_size;
-  mp_size_t k = ecc->p.redc_size;
+  unsigned shift = m->size * GMP_NUMB_BITS - m->bit_size;
+  mp_size_t k = m->redc_size;
   
-  for (i = 0; i < ecc->p.size; i++)
+  for (i = 0; i < m->size; i++)
     rp[i] = mpn_addmul_1 (rp + i + k,
-			  ecc->p.redc_mpm1, ecc->p.size - k, rp[i]);
-  hi = mpn_add_n (rp, rp, rp + ecc->p.size, ecc->p.size);
+			  m->redc_mpm1, m->size - k, rp[i]);
+  hi = mpn_add_n (rp, rp, rp + m->size, m->size);
   if (shift > 0)
     {
-      hi = (hi << shift) | (rp[ecc->p.size - 1] >> (GMP_NUMB_BITS - shift));
-      rp[ecc->p.size - 1] = (rp[ecc->p.size - 1]
+      hi = (hi << shift) | (rp[m->size - 1] >> (GMP_NUMB_BITS - shift));
+      rp[m->size - 1] = (rp[m->size - 1]
 			   & (((mp_limb_t) 1 << (GMP_NUMB_BITS - shift)) - 1))
-	+ mpn_addmul_1 (rp, ecc->p.B_shifted, ecc->p.size-1, hi);
+	+ mpn_addmul_1 (rp, m->B_shifted, m->size-1, hi);
 	  
     }
   else
     {
-      cy = cnd_sub_n (hi, rp, ecc->p.m, ecc->p.size);
+      cy = cnd_sub_n (hi, rp, m->m, m->size);
       assert (cy == hi);      
     }
 }
diff --git a/examples/ecc-benchmark.c b/examples/ecc-benchmark.c
index 858acc82..87642913 100644
--- a/examples/ecc-benchmark.c
+++ b/examples/ecc-benchmark.c
@@ -150,7 +150,7 @@ bench_modp (void *p)
 {
   struct ecc_ctx *ctx = (struct ecc_ctx *) p;
   mpn_copyi (ctx->rp, ctx->ap, 2*ctx->ecc->p.size);
-  ctx->ecc->modp (ctx->ecc, ctx->rp);
+  ctx->ecc->modp (&ctx->ecc->p, ctx->rp);
 }
 
 static void
@@ -158,7 +158,7 @@ bench_redc (void *p)
 {
   struct ecc_ctx *ctx = (struct ecc_ctx *) p;
   mpn_copyi (ctx->rp, ctx->ap, 2*ctx->ecc->p.size);
-  ctx->ecc->redc (ctx->ecc, ctx->rp);
+  ctx->ecc->redc (&ctx->ecc->p, ctx->rp);
 }
 
 static void
@@ -166,7 +166,7 @@ bench_modq (void *p)
 {
   struct ecc_ctx *ctx = (struct ecc_ctx *) p;
   mpn_copyi (ctx->rp, ctx->ap, 2*ctx->ecc->p.size);
-  ctx->ecc->modq (ctx->ecc, ctx->rp);
+  ctx->ecc->modq (&ctx->ecc->q, ctx->rp);
 }
 
 static void
diff --git a/testsuite/ecc-mod-test.c b/testsuite/ecc-mod-test.c
index 4787368d..3139e139 100644
--- a/testsuite/ecc-mod-test.c
+++ b/testsuite/ecc-mod-test.c
@@ -42,7 +42,7 @@ test_curve (gmp_randstate_t rands, const struct ecc_curve *ecc)
       ref_mod (ref, a, ecc->p.m, ecc->p.size);
 
       mpn_copyi (m, a, 2*ecc->p.size);
-      ecc->modp (ecc, m);
+      ecc->modp (&ecc->p, m);
       if (mpn_cmp (m, ecc->p.m, ecc->p.size) >= 0)
 	mpn_sub_n (m, m, ecc->p.m, ecc->p.size);
 
@@ -59,7 +59,7 @@ test_curve (gmp_randstate_t rands, const struct ecc_curve *ecc)
       if (ecc->p.B_size < ecc->p.size)
 	{
 	  mpn_copyi (m, a, 2*ecc->p.size);
-	  ecc_generic_modp (ecc, m);
+	  ecc_mod (&ecc->p, m);
 	  if (mpn_cmp (m, ecc->p.m, ecc->p.size) >= 0)
 	    mpn_sub_n (m, m, ecc->p.m, ecc->p.size);
 
@@ -77,7 +77,7 @@ test_curve (gmp_randstate_t rands, const struct ecc_curve *ecc)
       ref_mod (ref, a, ecc->q.m, ecc->p.size);
 
       mpn_copyi (m, a, 2*ecc->p.size);
-      ecc->modq (ecc, m);
+      ecc->modq (&ecc->q, m);
       if (mpn_cmp (m, ecc->q.m, ecc->p.size) >= 0)
 	mpn_sub_n (m, m, ecc->q.m, ecc->p.size);
 
@@ -93,7 +93,7 @@ test_curve (gmp_randstate_t rands, const struct ecc_curve *ecc)
       if (ecc->q.B_size < ecc->p.size)
 	{
 	  mpn_copyi (m, a, 2*ecc->p.size);
-	  ecc_generic_modq (ecc, m);
+	  ecc_mod (&ecc->q, m);
 	  if (mpn_cmp (m, ecc->q.m, ecc->p.size) >= 0)
 	    mpn_sub_n (m, m, ecc->q.m, ecc->p.size);
 
diff --git a/testsuite/ecc-redc-test.c b/testsuite/ecc-redc-test.c
index 1fa61b3f..a561ea9c 100644
--- a/testsuite/ecc-redc-test.c
+++ b/testsuite/ecc-redc-test.c
@@ -73,7 +73,7 @@ test_main (void)
 	  ref_redc (ref, a, ecc->p.m, ecc->p.size);
 
 	  mpn_copyi (m, a, 2*ecc->p.size);
-	  ecc->redc (ecc, m);
+	  ecc->redc (&ecc->p, m);
 	  if (mpn_cmp (m, ecc->p.m, ecc->p.size) >= 0)
 	    mpn_sub_n (m, m, ecc->p.m, ecc->p.size);
 
@@ -89,9 +89,9 @@ test_main (void)
 
 	  mpn_copyi (m, a, 2*ecc->p.size);
 	  if (ecc->p.m[0] == 1)
-	    ecc_pm1_redc (ecc, m);
+	    ecc_pm1_redc (&ecc->p, m);
 	  else
-	    ecc_pp1_redc (ecc, m);
+	    ecc_pp1_redc (&ecc->p, m);
 
 	  if (mpn_cmp (m, ecc->p.m, ecc->p.size) >= 0)
 	    mpn_sub_n (m, m, ecc->p.m, ecc->p.size);
-- 
GitLab