diff --git a/ChangeLog b/ChangeLog
index cb3edea5629acb23218ac153b42a892245c2bbfc..e1abab9b861cecfea5b1dfcc628b541600639c74 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+2014-09-22  Niels Möller  <nisse@lysator.liu.se>
+
+	* 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.
+	Updated all ecc-related files.
+
 2014-09-17  Niels Möller  <nisse@lysator.liu.se>
 
 	* gmp-glue.c (mpn_get_base256_le): Fixed missing update of rn
diff --git a/curve25519-eh-to-x.c b/curve25519-eh-to-x.c
index 14dcc4e87ffc66e61ff036e664cde8a971dae3c8..4d05a6bf583b6622088bdf19c22bd67b381c187b 100644
--- a/curve25519-eh-to-x.c
+++ b/curve25519-eh-to-x.c
@@ -46,11 +46,11 @@ void
 curve25519_eh_to_x (mp_limb_t *xp, const mp_limb_t *p,
 		    mp_limb_t *scratch)
 {
-#define vp (p + ecc->size)
-#define wp (p + 2*ecc->size)
+#define vp (p + ecc->p.size)
+#define wp (p + 2*ecc->p.size)
 #define t0 scratch
-#define t1 (scratch + ecc->size)
-#define t2 (scratch + 2*ecc->size)
+#define t1 (scratch + ecc->p.size)
+#define t2 (scratch + 2*ecc->p.size)
 
   const struct ecc_curve *ecc = &nettle_curve25519;  
   mp_limb_t cy;
@@ -71,8 +71,8 @@ curve25519_eh_to_x (mp_limb_t *xp, const mp_limb_t *p,
   ecc_modp_add (ecc, t0, wp, vp);
   ecc_modp_mul (ecc, t2, t0, t1);
 
-  cy = mpn_sub_n (xp, t2, ecc->p, ecc->size);
-  cnd_copy (cy, xp, t2, ecc->size);
+  cy = mpn_sub_n (xp, t2, ecc->p.m, ecc->p.size);
+  cnd_copy (cy, xp, t2, ecc->p.size);
 #undef vp
 #undef wp
 #undef t0
diff --git a/curve25519-mul-g.c b/curve25519-mul-g.c
index 9aec180b4b60bd089c35dbfcbf0424913ddc3967..f2d39f78b8d0fa5e5250f622ac790b33969498e4 100644
--- a/curve25519-mul-g.c
+++ b/curve25519-mul-g.c
@@ -49,23 +49,23 @@ curve25519_mul_g (uint8_t *r, const uint8_t *n)
   mp_limb_t *scratch;
   mp_size_t itch;
 
-#define p scratch
-#define x (scratch + 3*ecc->size)
-#define scratch_out (scratch + 4*ecc->size)
+#define ng scratch
+#define x (scratch + 3*ecc->p.size)
+#define scratch_out (scratch + 4*ecc->p.size)
   
   memcpy (t, n, sizeof(t));
   t[0] &= ~7;
   t[CURVE25519_SIZE-1] = (t[CURVE25519_SIZE-1] & 0x3f) | 0x40;
 
-  itch = 4*ecc->size + ecc->mul_g_itch;
+  itch = 4*ecc->p.size + ecc->mul_g_itch;
   scratch = gmp_alloc_limbs (itch);
 
-  mpn_set_base256_le (x, ecc->size, t, CURVE25519_SIZE);
+  mpn_set_base256_le (x, ecc->p.size, t, CURVE25519_SIZE);
 
-  ecc_mul_g_eh (ecc, p, x, scratch_out);
-  curve25519_eh_to_x (x, p, scratch_out);
+  ecc_mul_g_eh (ecc, ng, x, scratch_out);
+  curve25519_eh_to_x (x, ng, scratch_out);
 
-  mpn_get_base256_le (r, CURVE25519_SIZE, x, ecc->size);
+  mpn_get_base256_le (r, CURVE25519_SIZE, x, ecc->p.size);
   gmp_free_limbs (scratch, itch);
 #undef p
 #undef x
diff --git a/curve25519-mul.c b/curve25519-mul.c
index dc50dce19a135bc98bca4c66bc6e6799f3be8314..263a33aa45063cfb27476a94394d27626e897f23 100644
--- a/curve25519-mul.c
+++ b/curve25519-mul.c
@@ -54,30 +54,30 @@ curve25519_mul (uint8_t *q, const uint8_t *n, const uint8_t *p)
      overlap C, D, and CB overlap A, D. And possibly reusing some of
      x2, z2, x3, z3. */
 #define x1 scratch
-#define x2 (scratch + ecc->size)
-#define z2 (scratch + 2*ecc->size)
-#define x3 (scratch + 3*ecc->size)
-#define z3 (scratch + 4*ecc->size)
-
-#define A  (scratch + 5*ecc->size)
-#define B  (scratch + 6*ecc->size)
-#define C  (scratch + 7*ecc->size)
-#define D  (scratch + 8*ecc->size)
-#define AA  (scratch + 9*ecc->size)
-#define BB  (scratch +10*ecc->size)
-#define E  (scratch + 10*ecc->size) /* Overlap BB */
-#define DA  (scratch + 9*ecc->size) /* Overlap AA */
-#define CB  (scratch + 10*ecc->size) /* Overlap BB */
-
-  itch = ecc->size * 12;
+#define x2 (scratch + ecc->p.size)
+#define z2 (scratch + 2*ecc->p.size)
+#define x3 (scratch + 3*ecc->p.size)
+#define z3 (scratch + 4*ecc->p.size)
+
+#define A  (scratch + 5*ecc->p.size)
+#define B  (scratch + 6*ecc->p.size)
+#define C  (scratch + 7*ecc->p.size)
+#define D  (scratch + 8*ecc->p.size)
+#define AA  (scratch + 9*ecc->p.size)
+#define BB  (scratch +10*ecc->p.size)
+#define E  (scratch + 10*ecc->p.size) /* Overlap BB */
+#define DA  (scratch + 9*ecc->p.size) /* Overlap AA */
+#define CB  (scratch + 10*ecc->p.size) /* Overlap BB */
+
+  itch = ecc->p.size * 12;
   scratch = gmp_alloc_limbs (itch);
 
-  mpn_set_base256_le (x1, ecc->size, p, CURVE25519_SIZE);
+  mpn_set_base256_le (x1, ecc->p.size, p, CURVE25519_SIZE);
 
   /* Initialize, x2 = x1, z2 = 1 */
-  mpn_copyi (x2, x1, ecc->size);
+  mpn_copyi (x2, x1, ecc->p.size);
   z2[0] = 1;
-  mpn_zero (z2+1, ecc->size - 1);
+  mpn_zero (z2+1, ecc->p.size - 1);
 
   /* Get x3, z3 from doubling. Since bit 254 is forced to 1. */
   ecc_modp_add (ecc, A, x2, z2);
@@ -93,7 +93,7 @@ curve25519_mul (uint8_t *q, const uint8_t *n, const uint8_t *p)
     {
       int bit = (n[i/8] >> (i & 7)) & 1;
 
-      cnd_swap (bit, x2, x3, 2*ecc->size);
+      cnd_swap (bit, x2, x3, 2*ecc->p.size);
 
       /* Formulas from draft-turner-thecurve25519function-00-Mont. We
 	 compute new coordinates in memory-address order, since mul
@@ -118,7 +118,7 @@ curve25519_mul (uint8_t *q, const uint8_t *n, const uint8_t *p)
       ecc_modp_sqr (ecc, DA, C);
       ecc_modp_mul (ecc, z3, DA, x1);
 
-      cnd_swap (bit, x2, x3, 2*ecc->size);
+      cnd_swap (bit, x2, x3, 2*ecc->p.size);
     }
   /* Do the 3 low zero bits, just duplicating x2 */
   for ( ; i >= 0; i--)
@@ -134,9 +134,9 @@ curve25519_mul (uint8_t *q, const uint8_t *n, const uint8_t *p)
     }
   ecc_modp_inv (ecc, x3, z2, z3);
   ecc_modp_mul (ecc, z3, x2, x3);
-  cy = mpn_sub_n (x2, z3, ecc->p, ecc->size);
-  cnd_copy (cy, x2, z3, ecc->size);
-  mpn_get_base256_le (q, CURVE25519_SIZE, x2, ecc->size);
+  cy = mpn_sub_n (x2, z3, ecc->p.m, ecc->p.size);
+  cnd_copy (cy, x2, z3, ecc->p.size);
+  mpn_get_base256_le (q, CURVE25519_SIZE, x2, ecc->p.size);
 
   gmp_free_limbs (scratch, itch);
   return 1;
diff --git a/ecc-192.c b/ecc-192.c
index 9165976346813d4505dfedb6cecb96ee17d1393f..227bdd219f135be219778dd199cd431139f11110 100644
--- a/ecc-192.c
+++ b/ecc-192.c
@@ -112,13 +112,28 @@ ecc_192_modp (const struct ecc_curve *ecc UNUSED, mp_limb_t *rp)
 
 const struct ecc_curve nettle_secp_192r1 =
 {
-  192,
-  ECC_LIMB_SIZE,
-  ECC_BMODP_SIZE,
-  192,
-  ECC_BMODQ_SIZE,
+  {
+    192,
+    ECC_LIMB_SIZE,
+    ECC_BMODP_SIZE,
+    ECC_REDC_SIZE,
+    ecc_p,
+    ecc_Bmodp,
+    ecc_Bmodp_shifted,    
+    ecc_redc_ppm1,
+  },
+  {
+    192,
+    ECC_LIMB_SIZE,
+    ECC_BMODQ_SIZE,
+    0,
+    ecc_q,
+    ecc_Bmodq,
+    ecc_Bmodq_shifted,
+    NULL,
+  },
+  
   USE_REDC,
-  ECC_REDC_SIZE,
   ECC_PIPPENGER_K,
   ECC_PIPPENGER_C,
 
@@ -137,18 +152,11 @@ const struct ecc_curve nettle_secp_192r1 =
   ecc_mul_g,
   ecc_j_to_a,
 
-  ecc_p,
   ecc_b,
-  ecc_q,
   ecc_g,
   NULL,
-  ecc_Bmodp,
-  ecc_Bmodp_shifted,
   ecc_pp1h,
-  ecc_redc_ppm1,
   ecc_unit,
-  ecc_Bmodq,
-  ecc_Bmodq_shifted,
   ecc_qp1h,
   ecc_table
 };
diff --git a/ecc-224.c b/ecc-224.c
index 29aa2f3f515266d68fa10403cd913c936aa2f944..5b4e58d4de2be397613547fcf6db579bdcaad7fe 100644
--- a/ecc-224.c
+++ b/ecc-224.c
@@ -64,13 +64,28 @@ ecc_224_modp (const struct ecc_curve *ecc, mp_limb_t *rp);
 
 const struct ecc_curve nettle_secp_224r1 =
 {
-  224,
-  ECC_LIMB_SIZE,    
-  ECC_BMODP_SIZE,
-  224,
-  ECC_BMODQ_SIZE,
+  {
+    224,
+    ECC_LIMB_SIZE,    
+    ECC_BMODP_SIZE,
+    -ECC_REDC_SIZE,
+    ecc_p,
+    ecc_Bmodp,
+    ecc_Bmodp_shifted,
+    ecc_redc_ppm1,
+  },
+  {
+    224,
+    ECC_LIMB_SIZE,    
+    ECC_BMODQ_SIZE,
+    0,
+    ecc_q,
+    ecc_Bmodq,
+    ecc_Bmodq_shifted,
+    NULL,
+  },
+  
   USE_REDC,
-  ECC_REDC_SIZE,
   ECC_PIPPENGER_K,
   ECC_PIPPENGER_C,
 
@@ -89,18 +104,11 @@ const struct ecc_curve nettle_secp_224r1 =
   ecc_mul_g,
   ecc_j_to_a,
 
-  ecc_p,
   ecc_b,
-  ecc_q,
   ecc_g,
   NULL,
-  ecc_Bmodp,
-  ecc_Bmodp_shifted,
   ecc_pp1h,
-  ecc_redc_ppm1,
   ecc_unit,
-  ecc_Bmodq,
-  ecc_Bmodq_shifted,
   ecc_qp1h,
   ecc_table
 };
diff --git a/ecc-25519.c b/ecc-25519.c
index 996e6bdd4e5283850bcb461b16d0a4dd8d41f381..c8ffba4497a7a4a54ada742714acbfef491dbeba 100644
--- a/ecc-25519.c
+++ b/ecc-25519.c
@@ -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->Bmodq_shifted, ECC_LIMB_SIZE,
+			 ecc->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, ECC_LIMB_SIZE);
+      cnd_add_n (cy, rp+n, ecc->q.m, ECC_LIMB_SIZE);
     }
 
-  cy = mpn_submul_1 (rp, ecc->q, ECC_LIMB_SIZE,
+  cy = mpn_submul_1 (rp, ecc->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, ECC_LIMB_SIZE);
+  cnd_add_n (cy, rp, ecc->q.m, ECC_LIMB_SIZE);
 }
 
 /* Needs 2*ecc->size limbs at rp, and 2*ecc->size additional limbs of
@@ -200,8 +200,8 @@ ecc_25519_sqrt(mp_limb_t *rp, const mp_limb_t *ap)
   ecc_modp_mul (ecc, xp, t0, ap); /* a^{(p+3)/8 */
   ecc_modp_mul (ecc, bp, t0, xp); /* a^{(p-1)/4} */
   /* Check if b == 1 (mod p) */
-  if (mpn_cmp (bp, ecc->p, ECC_LIMB_SIZE) >= 0)
-    mpn_sub_n (bp, bp, ecc->p, ECC_LIMB_SIZE);
+  if (mpn_cmp (bp, ecc->p.m, ECC_LIMB_SIZE) >= 0)
+    mpn_sub_n (bp, bp, ecc->p.m, ECC_LIMB_SIZE);
   if (mpn_cmp (bp, ecc->unit, ECC_LIMB_SIZE) == 0)
     {
       mpn_copyi (rp, xp, ECC_LIMB_SIZE);
@@ -210,7 +210,7 @@ ecc_25519_sqrt(mp_limb_t *rp, const mp_limb_t *ap)
   else
     {
       mpn_add_1 (bp, bp, ECC_LIMB_SIZE, 1);
-      if (mpn_cmp (bp, ecc->p, ECC_LIMB_SIZE) == 0)
+      if (mpn_cmp (bp, ecc->p.m, ECC_LIMB_SIZE) == 0)
 	{
 	  ecc_modp_mul (&nettle_curve25519, bp, xp, ecc_sqrt_z);
 	  mpn_copyi (rp, bp, ECC_LIMB_SIZE);
@@ -232,13 +232,28 @@ ecc_25519_sqrt(mp_limb_t *rp, const mp_limb_t *ap)
 
 const struct ecc_curve nettle_curve25519 =
 {
-  255,
-  ECC_LIMB_SIZE,
-  ECC_BMODP_SIZE,
-  253,
-  ECC_BMODQ_SIZE,
+  {
+    255,
+    ECC_LIMB_SIZE,
+    ECC_BMODP_SIZE,
+    0,
+    ecc_p,
+    ecc_Bmodp,
+    ecc_Bmodp_shifted,
+    NULL,
+  },
+  {
+    253,
+    ECC_LIMB_SIZE,
+    ECC_BMODQ_SIZE,
+    0,
+    ecc_q,
+    ecc_Bmodq,  
+    ecc_mBmodq_shifted, /* Use q - 2^{252} instead. */
+    NULL,
+  },
+
   0, /* No redc */
-  0,
   ECC_PIPPENGER_K,
   ECC_PIPPENGER_C,
 
@@ -257,18 +272,11 @@ const struct ecc_curve nettle_curve25519 =
   ecc_mul_g_eh,
   ecc_eh_to_a,
 
-  ecc_p,
   ecc_d, /* Use the Edwards curve constant. */
-  ecc_q,
   ecc_g,
   ecc_edwards,
-  ecc_Bmodp,
-  ecc_Bmodp_shifted,
   ecc_pp1h,
-  ecc_redc_ppm1,
   ecc_unit,
-  ecc_Bmodq,  
-  ecc_mBmodq_shifted, /* Use q - 2^{252} instead. */ 
   ecc_qp1h,
   ecc_table
 };
diff --git a/ecc-256.c b/ecc-256.c
index 1d2a5ec7c7210ccc65ebcd18f264e0cdc5920152..3e51304f767a961d57d3a2c4ed959b548c545287 100644
--- a/ecc-256.c
+++ b/ecc-256.c
@@ -75,12 +75,12 @@ ecc_256_modp (const struct ecc_curve *ecc, mp_limb_t *rp)
   mp_limb_t u1, u0;
   mp_size_t n;
 
-  n = 2*ecc->size;
+  n = 2*ecc->p.size;
   u1 = rp[--n];
   u0 = rp[n-1];
 
   /* This is not particularly fast, but should work well with assembly implementation. */
-  for (; n >= ecc->size; n--)
+  for (; n >= ecc->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, 2, q1);
-      t += cnd_sub_n (q2, rp + n - 3, ecc->p, 1);
+      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 += (-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, 3);
+      u1 += cnd_add_n (t, rp + n - 4, ecc->p.m, 3);
       u1 -= (-t) & 0xffffffff;
     }
   rp[2] = u0;
@@ -137,12 +137,12 @@ ecc_256_modq (const struct ecc_curve *ecc, mp_limb_t *rp)
   mp_limb_t u2, u1, u0;
   mp_size_t n;
 
-  n = 2*ecc->size;
+  n = 2*ecc->q.size;
   u2 = rp[--n];
   u1 = rp[n-1];
 
   /* This is not particularly fast, but should work well with assembly implementation. */
-  for (; n >= ecc->size; n--)
+  for (; n >= ecc->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, 1);
-      c0 += (-q2) & ecc->q[1];
-      t = mpn_submul_1 (rp + n - 4, ecc->q, 2, q1);
+      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 += 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, 2);
+      t = cnd_add_n (t, rp + n - 4, ecc->q.m, 2);
       u1 += t;
       u2 += (u1 < t);
     }
@@ -227,13 +227,28 @@ ecc_256_modq (const struct ecc_curve *ecc, mp_limb_t *rp)
 
 const struct ecc_curve nettle_secp_256r1 =
 {
-  256,
-  ECC_LIMB_SIZE,    
-  ECC_BMODP_SIZE,
-  256,
-  ECC_BMODQ_SIZE,
+  {
+    256,
+    ECC_LIMB_SIZE,    
+    ECC_BMODP_SIZE,
+    ECC_REDC_SIZE,
+    ecc_p,
+    ecc_Bmodp,
+    ecc_Bmodp_shifted,
+    ecc_redc_ppm1,
+  },
+  {
+    256,
+    ECC_LIMB_SIZE,    
+    ECC_BMODQ_SIZE,
+    0,
+    ecc_q,
+    ecc_Bmodq,
+    ecc_Bmodq_shifted,
+    NULL,
+  },
+
   USE_REDC,
-  ECC_REDC_SIZE,
   ECC_PIPPENGER_K,
   ECC_PIPPENGER_C,
 
@@ -252,18 +267,11 @@ const struct ecc_curve nettle_secp_256r1 =
   ecc_mul_g,
   ecc_j_to_a,
 
-  ecc_p,
   ecc_b,
-  ecc_q,
   ecc_g,
   NULL,
-  ecc_Bmodp,
-  ecc_Bmodp_shifted,
   ecc_pp1h,
-  ecc_redc_ppm1,
   ecc_unit,
-  ecc_Bmodq,
-  ecc_Bmodq_shifted,
   ecc_qp1h,
   ecc_table
 };
diff --git a/ecc-384.c b/ecc-384.c
index 3145afe1481ef2ef2f88e8fc434cf60f8d1c446b..7ef9b1b31320c7c0628d09566988d9649d949538 100644
--- a/ecc-384.c
+++ b/ecc-384.c
@@ -140,7 +140,7 @@ 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->Bmodp, ECC_LIMB_SIZE);
+  cy = cnd_add_n (cy, rp, ecc->p.B, ECC_LIMB_SIZE);
   assert (cy == 0);  
 }
 #else
@@ -149,13 +149,28 @@ ecc_384_modp (const struct ecc_curve *ecc, mp_limb_t *rp)
   
 const struct ecc_curve nettle_secp_384r1 =
 {
-  384,
-  ECC_LIMB_SIZE,    
-  ECC_BMODP_SIZE,
-  384,
-  ECC_BMODQ_SIZE,
+  {
+    384,
+    ECC_LIMB_SIZE,    
+    ECC_BMODP_SIZE,
+    ECC_REDC_SIZE,
+    ecc_p,
+    ecc_Bmodp,
+    ecc_Bmodp_shifted,
+    ecc_redc_ppm1,
+  },
+  {
+    384,
+    ECC_LIMB_SIZE,    
+    ECC_BMODQ_SIZE,
+    0,
+    ecc_q,
+    ecc_Bmodq,
+    ecc_Bmodq_shifted,
+    NULL,
+  },
+
   USE_REDC,
-  ECC_REDC_SIZE,
   ECC_PIPPENGER_K,
   ECC_PIPPENGER_C,
 
@@ -174,18 +189,11 @@ const struct ecc_curve nettle_secp_384r1 =
   ecc_mul_g,
   ecc_j_to_a,
 
-  ecc_p,
   ecc_b,
-  ecc_q,
   ecc_g,
   NULL,
-  ecc_Bmodp,
-  ecc_Bmodp_shifted,
   ecc_pp1h,
-  ecc_redc_ppm1,
   ecc_unit,
-  ecc_Bmodq,
-  ecc_Bmodq_shifted,
   ecc_qp1h,
   ecc_table
 };
diff --git a/ecc-521.c b/ecc-521.c
index b0c1ed92b1ca5c6c29b43259f8b27c53f803ff21..c3fed94fd943fd9820cb378e21785da094d434a9 100644
--- a/ecc-521.c
+++ b/ecc-521.c
@@ -77,13 +77,28 @@ ecc_521_modp (const struct ecc_curve *ecc UNUSED, mp_limb_t *rp)
 
 const struct ecc_curve nettle_secp_521r1 =
 {
-  521,
-  ECC_LIMB_SIZE,    
-  ECC_BMODP_SIZE,
-  521,
-  ECC_BMODQ_SIZE,
+  {
+    521,
+    ECC_LIMB_SIZE,    
+    ECC_BMODP_SIZE,
+    ECC_REDC_SIZE,
+    ecc_p,
+    ecc_Bmodp,
+    ecc_Bmodp_shifted,
+    ecc_redc_ppm1,
+  },
+  {
+    521,
+    ECC_LIMB_SIZE,    
+    ECC_BMODQ_SIZE,
+    0,
+    ecc_q,
+    ecc_Bmodq,
+    ecc_Bmodq_shifted,
+    NULL,
+  },
+  
   USE_REDC,
-  ECC_REDC_SIZE,
   ECC_PIPPENGER_K,
   ECC_PIPPENGER_C,
 
@@ -102,18 +117,11 @@ const struct ecc_curve nettle_secp_521r1 =
   ecc_mul_g,
   ecc_j_to_a,
 
-  ecc_p,
   ecc_b,
-  ecc_q,
   ecc_g,
   NULL,
-  ecc_Bmodp,
-  ecc_Bmodp_shifted,
   ecc_pp1h,
-  ecc_redc_ppm1,
   ecc_unit,
-  ecc_Bmodq,
-  ecc_Bmodq_shifted,
   ecc_qp1h,
   ecc_table
 };
diff --git a/ecc-a-to-j.c b/ecc-a-to-j.c
index 36e4d150383bb4be6b3ea6650f9be7ce83a71716..7852e14acacf8e42627b081b018b9aa67b268784 100644
--- a/ecc-a-to-j.c
+++ b/ecc-a-to-j.c
@@ -44,16 +44,16 @@ ecc_a_to_j (const struct ecc_curve *ecc,
 {
   if (ecc->use_redc)
     {
-      mpn_copyd (r + ecc->size, p, 2*ecc->size);
+      mpn_copyd (r + ecc->p.size, p, 2*ecc->p.size);
 
-      mpn_zero (r, ecc->size);
+      mpn_zero (r, ecc->p.size);
       ecc->modp (ecc, r);
 
-      mpn_zero (r + ecc->size, ecc->size);
-      ecc->modp (ecc, r + ecc->size);
+      mpn_zero (r + ecc->p.size, ecc->p.size);
+      ecc->modp (ecc, r + ecc->p.size);
     }
   else if (r != p)
-    mpn_copyi (r, p, 2*ecc->size);
+    mpn_copyi (r, p, 2*ecc->p.size);
 
-  mpn_copyi (r + 2*ecc->size, ecc->unit, ecc->size);
+  mpn_copyi (r + 2*ecc->p.size, ecc->unit, ecc->p.size);
 }
diff --git a/ecc-add-eh.c b/ecc-add-eh.c
index 311b2d9b3f666677c1e1c2f4f144cce7958dc1aa..34b39f03583e0baf9d3784ff29433e265a915531 100644
--- a/ecc-add-eh.c
+++ b/ecc-add-eh.c
@@ -39,7 +39,7 @@
 mp_size_t
 ecc_add_eh_itch (const struct ecc_curve *ecc)
 {
-  return ECC_ADD_EH_ITCH (ecc->size);
+  return ECC_ADD_EH_ITCH (ecc->p.size);
 }
 
 /* Add two points on an Edwards curve, with result and first point in
@@ -50,15 +50,15 @@ ecc_add_eh (const struct ecc_curve *ecc,
 	    mp_limb_t *scratch)
 {
 #define x1 p
-#define y1 (p + ecc->size)
-#define z1 (p + 2*ecc->size)
+#define y1 (p + ecc->p.size)
+#define z1 (p + 2*ecc->p.size)
 
 #define x2 q
-#define y2 (q + ecc->size)
+#define y2 (q + ecc->p.size)
 
 #define x3 r
-#define y3 (r + ecc->size)
-#define z3 (r + 2*ecc->size)
+#define y3 (r + ecc->p.size)
+#define z3 (r + 2*ecc->p.size)
 
   /* Formulas (from djb,
      http://www.hyperelliptic.org/EFD/g1p/auto-edwards-projective.html#doubling-dbl-2007-bl):
@@ -77,10 +77,10 @@ ecc_add_eh (const struct ecc_curve *ecc,
      z3 = F*G		mul
   */
 #define C (scratch)
-#define D (scratch + 1*ecc->size)
-#define T (scratch + 2*ecc->size)
-#define E (scratch + 3*ecc->size) 
-#define B (scratch + 4*ecc->size)
+#define D (scratch + 1*ecc->p.size)
+#define T (scratch + 2*ecc->p.size)
+#define E (scratch + 3*ecc->p.size) 
+#define B (scratch + 4*ecc->p.size)
 #define F D
 #define G E
   
@@ -109,5 +109,5 @@ ecc_add_eh (const struct ecc_curve *ecc,
 
   /* z3 */
   ecc_modp_mul (ecc, B, F, G);
-  mpn_copyi (z3, B, ecc->size);
+  mpn_copyi (z3, B, ecc->p.size);
 }
diff --git a/ecc-add-ehh.c b/ecc-add-ehh.c
index b293290b2192198aac0a8fe2e27cc2e81f22aa9c..46a9149213c0981197b434d82df87242d9741d37 100644
--- a/ecc-add-ehh.c
+++ b/ecc-add-ehh.c
@@ -39,7 +39,7 @@
 mp_size_t
 ecc_add_ehh_itch (const struct ecc_curve *ecc)
 {
-  return ECC_ADD_EHH_ITCH (ecc->size);
+  return ECC_ADD_EHH_ITCH (ecc->p.size);
 }
 
 /* Add two points on an Edwards curve, in homogeneous coordinates */
@@ -49,16 +49,16 @@ ecc_add_ehh (const struct ecc_curve *ecc,
 	     mp_limb_t *scratch)
 {
 #define x1 p
-#define y1 (p + ecc->size)
-#define z1 (p + 2*ecc->size)
+#define y1 (p + ecc->p.size)
+#define z1 (p + 2*ecc->p.size)
 
 #define x2 q
-#define y2 (q + ecc->size)
-#define z2 (q + 2*ecc->size)
+#define y2 (q + ecc->p.size)
+#define z2 (q + 2*ecc->p.size)
 
 #define x3 r
-#define y3 (r + ecc->size)
-#define z3 (r + 2*ecc->size)
+#define y3 (r + ecc->p.size)
+#define z3 (r + 2*ecc->p.size)
 
   /* Formulas (from djb,
      http://www.hyperelliptic.org/EFD/g1p/auto-edwards-projective.html#doubling-dbl-2007-bl):
@@ -82,11 +82,11 @@ ecc_add_ehh (const struct ecc_curve *ecc,
      G.
   */
 #define C scratch
-#define D (scratch + ecc->size)
-#define T (scratch + 2*ecc->size)
-#define E (scratch + 3*ecc->size) 
-#define A (scratch + 4*ecc->size)
-#define B (scratch + 5*ecc->size)
+#define D (scratch + ecc->p.size)
+#define T (scratch + 2*ecc->p.size)
+#define E (scratch + 3*ecc->p.size) 
+#define A (scratch + 4*ecc->p.size)
+#define B (scratch + 5*ecc->p.size)
 #define F D
 #define G E
 
@@ -117,5 +117,5 @@ ecc_add_ehh (const struct ecc_curve *ecc,
 
   /* z3 */
   ecc_modp_mul (ecc, B, F, G);
-  mpn_copyi (z3, B, ecc->size);
+  mpn_copyi (z3, B, ecc->p.size);
 }
diff --git a/ecc-add-jja.c b/ecc-add-jja.c
index 128a44c3087fd53894fc0bc6f46cf31256d1b1c1..40f5a0cf3cff753436084f0ffe2504cb8f5dd88c 100644
--- a/ecc-add-jja.c
+++ b/ecc-add-jja.c
@@ -52,7 +52,7 @@
 mp_size_t
 ecc_add_jja_itch (const struct ecc_curve *ecc)
 {
-  return ECC_ADD_JJA_ITCH (ecc->size);
+  return ECC_ADD_JJA_ITCH (ecc->p.size);
 }
 
 void
@@ -78,17 +78,17 @@ ecc_add_jja (const struct ecc_curve *ecc,
       Y_3 = W*(V-X_3)-2*Y_1*J	mul, mul
   */
 #define zz  scratch
-#define h  (scratch + ecc->size)
-#define hh (scratch + 2*ecc->size)
-#define w  (scratch + 3*ecc->size)
-#define j  (scratch + 4*ecc->size)
+#define h  (scratch + ecc->p.size)
+#define hh (scratch + 2*ecc->p.size)
+#define w  (scratch + 3*ecc->p.size)
+#define j  (scratch + 4*ecc->p.size)
 #define v   scratch
 
 #define x1  p
-#define y1 (p + ecc->size)
-#define z1 (p + 2*ecc->size)
+#define y1 (p + ecc->p.size)
+#define z1 (p + 2*ecc->p.size)
 #define x2  q
-#define y2 (q + ecc->size)
+#define y2 (q + ecc->p.size)
 
   /* zz */
   ecc_modp_sqr (ecc, zz, z1);
@@ -100,10 +100,10 @@ ecc_add_jja (const struct ecc_curve *ecc,
   /* Do z^3 early, store at w. */
   ecc_modp_mul (ecc, w, zz, z1);
   /* z_3, use j area for scratch */
-  ecc_modp_add (ecc, r + 2*ecc->size, p + 2*ecc->size, h);
-  ecc_modp_sqr (ecc, j, r + 2*ecc->size);
+  ecc_modp_add (ecc, r + 2*ecc->p.size, p + 2*ecc->p.size, h);
+  ecc_modp_sqr (ecc, j, r + 2*ecc->p.size);
   ecc_modp_sub (ecc, j, j, zz);
-  ecc_modp_sub (ecc, r + 2*ecc->size, j, hh);
+  ecc_modp_sub (ecc, r + 2*ecc->p.size, j, hh);
   
   /* w */
   ecc_modp_mul (ecc, j, y2, w);
@@ -124,8 +124,8 @@ ecc_add_jja (const struct ecc_curve *ecc,
 
   /* y_3, use (h, hh) as sqratch */
   ecc_modp_mul (ecc, h, y1, j); /* frees j */
-  ecc_modp_sub (ecc, r + ecc->size, v, r);
-  ecc_modp_mul (ecc, j, r + ecc->size, w);
+  ecc_modp_sub (ecc, r + ecc->p.size, v, r);
+  ecc_modp_mul (ecc, j, r + ecc->p.size, w);
   ecc_modp_submul_1 (ecc, j, h, 2);
-  mpn_copyi (r + ecc->size, j, ecc->size);
+  mpn_copyi (r + ecc->p.size, j, ecc->p.size);
 }
diff --git a/ecc-add-jjj.c b/ecc-add-jjj.c
index 9179462484b0ba92f1f42f8085b8a801e82230b6..d298b5172dd878cf7e6b9d4827098f03bd74ed05 100644
--- a/ecc-add-jjj.c
+++ b/ecc-add-jjj.c
@@ -41,8 +41,8 @@
 mp_size_t
 ecc_add_jjj_itch (const struct ecc_curve *ecc)
 {
-  /* Needs 8 * ecc->size */
-  return ECC_ADD_JJJ_ITCH (ecc->size);
+  /* Needs 8 * ecc->p.size */
+  return ECC_ADD_JJJ_ITCH (ecc->p.size);
 }
 
 void
@@ -71,24 +71,24 @@ ecc_add_jjj (const struct ecc_curve *ecc,
       Y3 = W*(V-X3)-2*S1*J	mul, mul
   */
   mp_limb_t *z1z1 = scratch;
-  mp_limb_t *z2z2 = scratch + ecc->size;
-  mp_limb_t *u1   = scratch + 2*ecc->size;
-  mp_limb_t *u2   = scratch + 3*ecc->size;
+  mp_limb_t *z2z2 = scratch + ecc->p.size;
+  mp_limb_t *u1   = scratch + 2*ecc->p.size;
+  mp_limb_t *u2   = scratch + 3*ecc->p.size;
   mp_limb_t *s1   = scratch; /* overlap z1z1 */
-  mp_limb_t *s2   = scratch + ecc->size; /* overlap z2z2 */
-  mp_limb_t *i    = scratch + 4*ecc->size;
-  mp_limb_t *j    = scratch + 5*ecc->size;
-  mp_limb_t *v    = scratch + 6*ecc->size;
+  mp_limb_t *s2   = scratch + ecc->p.size; /* overlap z2z2 */
+  mp_limb_t *i    = scratch + 4*ecc->p.size;
+  mp_limb_t *j    = scratch + 5*ecc->p.size;
+  mp_limb_t *v    = scratch + 6*ecc->p.size;
 
   /* z1^2, z2^2, u1 = x1 x2^2, u2 = x2 z1^2 - u1 */
-  ecc_modp_sqr (ecc, z1z1, p + 2*ecc->size);
-  ecc_modp_sqr (ecc, z2z2, q + 2*ecc->size);
+  ecc_modp_sqr (ecc, z1z1, p + 2*ecc->p.size);
+  ecc_modp_sqr (ecc, z2z2, q + 2*ecc->p.size);
   ecc_modp_mul (ecc, u1, p, z2z2);
   ecc_modp_mul (ecc, u2, q, z1z1);
   ecc_modp_sub (ecc, u2, u2, u1);  /* Store h in u2 */
 
   /* z3, use i, j, v as scratch, result at i. */
-  ecc_modp_add (ecc, i, p + 2*ecc->size, q + 2*ecc->size);
+  ecc_modp_add (ecc, i, p + 2*ecc->p.size, q + 2*ecc->p.size);
   ecc_modp_sqr (ecc, v, i);
   ecc_modp_sub (ecc, v, v, z1z1);
   ecc_modp_sub (ecc, v, v, z2z2);
@@ -96,15 +96,15 @@ ecc_add_jjj (const struct ecc_curve *ecc,
   /* Delayed write, to support in-place operation. */
 
   /* s1 = y1 z2^3, s2 = y2 z1^3, scratch at j and v */
-  ecc_modp_mul (ecc, j, z1z1, p + 2*ecc->size); /* z1^3 */
-  ecc_modp_mul (ecc, v, z2z2, q + 2*ecc->size); /* z2^3 */
-  ecc_modp_mul (ecc, s1, p + ecc->size, v);
-  ecc_modp_mul (ecc, v, j, q + ecc->size);
+  ecc_modp_mul (ecc, j, z1z1, p + 2*ecc->p.size); /* z1^3 */
+  ecc_modp_mul (ecc, v, z2z2, q + 2*ecc->p.size); /* z2^3 */
+  ecc_modp_mul (ecc, s1, p + ecc->p.size, v);
+  ecc_modp_mul (ecc, v, j, q + ecc->p.size);
   ecc_modp_sub (ecc, s2, v, s1);
   ecc_modp_mul_1 (ecc, s2, s2, 2);
 
   /* Store z3 */
-  mpn_copyi (r + 2*ecc->size, i, ecc->size);
+  mpn_copyi (r + 2*ecc->p.size, i, ecc->p.size);
 
   /* i, j, v */
   ecc_modp_sqr (ecc, i, u2);
@@ -123,5 +123,5 @@ ecc_add_jjj (const struct ecc_curve *ecc,
   ecc_modp_sub (ecc, u2, v, r);  /* Frees v */
   ecc_modp_mul (ecc, i, s2, u2);
   ecc_modp_submul_1 (ecc, i, u1, 2);
-  mpn_copyi (r + ecc->size, i, ecc->size);
+  mpn_copyi (r + ecc->p.size, i, ecc->p.size);
 }
diff --git a/ecc-dup-eh.c b/ecc-dup-eh.c
index 6258071a7c54f646112ed229cbb57e6e312d62bf..ab6b841825730f4ac9ec997f6cec6f091f274396 100644
--- a/ecc-dup-eh.c
+++ b/ecc-dup-eh.c
@@ -39,7 +39,7 @@
 mp_size_t
 ecc_dup_eh_itch (const struct ecc_curve *ecc)
 {
-  return ECC_DUP_EH_ITCH (ecc->size);
+  return ECC_DUP_EH_ITCH (ecc->p.size);
 }
 
 /* Double a point on an Edwards curve, in homogeneous coordinates */
@@ -76,21 +76,21 @@ ecc_dup_eh (const struct ecc_curve *ecc,
      z' = e*j		mul
   */
 #define b scratch 
-#define c (scratch  + ecc->size)
-#define d (scratch  + 2*ecc->size)
-#define e (scratch  + 3*ecc->size)
-#define j (scratch  + 4*ecc->size)
+#define c (scratch  + ecc->p.size)
+#define d (scratch  + 2*ecc->p.size)
+#define e (scratch  + 3*ecc->p.size)
+#define j (scratch  + 4*ecc->p.size)
 
   /* b */
-  ecc_modp_add (ecc, e, p, p + ecc->size);
+  ecc_modp_add (ecc, e, p, p + ecc->p.size);
   ecc_modp_sqr (ecc, b, e);
 
   /* c */
   ecc_modp_sqr (ecc, c, p);
   /* d */
-  ecc_modp_sqr (ecc, d, p + ecc->size);
+  ecc_modp_sqr (ecc, d, p + ecc->p.size);
   /* h, can use r as scratch, even for in-place operation. */
-  ecc_modp_sqr (ecc, r, p + 2*ecc->size);
+  ecc_modp_sqr (ecc, r, p + 2*ecc->p.size);
   /* e, */
   ecc_modp_sub (ecc, e, d, c);
   /* b - c - d */
@@ -104,8 +104,8 @@ ecc_dup_eh (const struct ecc_curve *ecc,
   ecc_modp_mul (ecc, r, b, j);
   /* y' */
   ecc_modp_add (ecc, c, c, d); /* Redundant */
-  ecc_modp_mul (ecc, r + ecc->size, e, c);
+  ecc_modp_mul (ecc, r + ecc->p.size, e, c);
   /* z' */
   ecc_modp_mul (ecc, b, e, j);
-  mpn_copyi (r + 2*ecc->size, b, ecc->size);
+  mpn_copyi (r + 2*ecc->p.size, b, ecc->p.size);
 }
diff --git a/ecc-dup-jj.c b/ecc-dup-jj.c
index c3cb839608e141e71ee765363e084ad34dc8f509..7466976a8b98d2c71fd2330980f2594145659020 100644
--- a/ecc-dup-jj.c
+++ b/ecc-dup-jj.c
@@ -45,7 +45,7 @@
 mp_size_t
 ecc_dup_jj_itch (const struct ecc_curve *ecc)
 {
-  return ECC_DUP_JJ_ITCH (ecc->size);
+  return ECC_DUP_JJ_ITCH (ecc->p.size);
 }
 
 void
@@ -67,15 +67,15 @@ ecc_dup_jj (const struct ecc_curve *ecc,
   */
 
 #define delta  scratch
-#define gamma (scratch + ecc->size)
-#define beta  (scratch + 2*ecc->size)
-#define g2    (scratch + 3*ecc->size)
-#define sum   (scratch + 4*ecc->size)
+#define gamma (scratch + ecc->p.size)
+#define beta  (scratch + 2*ecc->p.size)
+#define g2    (scratch + 3*ecc->p.size)
+#define sum   (scratch + 4*ecc->p.size)
 #define alpha  scratch /* Overlap delta */
   
 #define xp p
-#define yp (p + ecc->size)
-#define zp (p + 2*ecc->size)
+#define yp (p + ecc->p.size)
+#define zp (p + 2*ecc->p.size)
   
   /* delta */
   ecc_modp_sqr (ecc, delta, zp);
@@ -84,10 +84,10 @@ ecc_dup_jj (const struct ecc_curve *ecc,
   ecc_modp_sqr (ecc, gamma, yp);
 
   /* z'. Can use beta area as scratch. */
-  ecc_modp_add (ecc, r + 2*ecc->size, yp, zp);
-  ecc_modp_sqr (ecc, beta, r + 2*ecc->size);
+  ecc_modp_add (ecc, r + 2*ecc->p.size, yp, zp);
+  ecc_modp_sqr (ecc, beta, r + 2*ecc->p.size);
   ecc_modp_sub (ecc, beta, beta, gamma);
-  ecc_modp_sub (ecc, r + 2*ecc->size, beta, delta);
+  ecc_modp_sub (ecc, r + 2*ecc->p.size, beta, delta);
   
   /* alpha. Can use beta area as scratch, and overwrite delta. */
   ecc_modp_add (ecc, sum, xp, delta);
@@ -106,11 +106,11 @@ ecc_dup_jj (const struct ecc_curve *ecc,
   /* x' */
   ecc_modp_sqr (ecc, gamma, alpha);   /* Overwrites gamma and beta */
   ecc_modp_submul_1 (ecc, gamma, sum, 2);
-  mpn_copyi (r, gamma, ecc->size);
+  mpn_copyi (r, gamma, ecc->p.size);
 
   /* y' */
   ecc_modp_sub (ecc, sum, sum, r);
   ecc_modp_mul (ecc, gamma, sum, alpha);
   ecc_modp_submul_1 (ecc, gamma, g2, 8);
-  mpn_copyi (r + ecc->size, gamma, ecc->size);
+  mpn_copyi (r + ecc->p.size, gamma, ecc->p.size);
 }
diff --git a/ecc-ecdsa-sign.c b/ecc-ecdsa-sign.c
index 7fe8373b9c15e4d350c4b0c28715a4171a7b2695..61a75e547934b3ccad1d6ad28718cb4f4c9709f8 100644
--- a/ecc-ecdsa-sign.c
+++ b/ecc-ecdsa-sign.c
@@ -46,9 +46,9 @@
 mp_size_t
 ecc_ecdsa_sign_itch (const struct ecc_curve *ecc)
 {
-  /* Needs 3*ecc->size + scratch for ecc->mul_g. Currently same for
+  /* Needs 3*ecc->p.size + scratch for ecc->mul_g. Currently same for
      ecc_mul_g and ecc_mul_g_eh. */
-  return ECC_ECDSA_SIGN_ITCH (ecc->size);
+  return ECC_ECDSA_SIGN_ITCH (ecc->p.size);
 }
 
 /* NOTE: Caller should check if r or s is zero. */
@@ -63,9 +63,9 @@ ecc_ecdsa_sign (const struct ecc_curve *ecc,
 		mp_limb_t *scratch)
 {
 #define P	    scratch
-#define kinv	    scratch                /* Needs 5*ecc->size for computation */
-#define hp	    (scratch  + ecc->size) /* NOTE: ecc->size + 1 limbs! */
-#define tp	    (scratch + 2*ecc->size)
+#define kinv	    scratch                /* Needs 5*ecc->p.size for computation */
+#define hp	    (scratch  + ecc->p.size) /* NOTE: ecc->p.size + 1 limbs! */
+#define tp	    (scratch + 2*ecc->p.size)
   /* Procedure, according to RFC 6090, "KT-I". q denotes the group
      order.
 
@@ -78,12 +78,12 @@ ecc_ecdsa_sign (const struct ecc_curve *ecc,
      4. s2 <-- (h + z*s1)/k mod q.
   */
 
-  ecc->mul_g (ecc, P, kp, P + 3*ecc->size);
+  ecc->mul_g (ecc, P, kp, P + 3*ecc->p.size);
   /* x coordinate only, modulo q */
-  ecc->h_to_a (ecc, 2, rp, P, P + 3*ecc->size);
+  ecc->h_to_a (ecc, 2, rp, P, P + 3*ecc->p.size);
 
-  /* Invert k, uses 5 * ecc->size including scratch */
-  mpn_copyi (hp, kp, ecc->size);
+  /* Invert k, uses 5 * ecc->p.size including scratch */
+  mpn_copyi (hp, kp, ecc->p.size);
   ecc_modq_inv (ecc, kinv, hp, tp);
   
   /* Process hash digest */
@@ -93,7 +93,7 @@ ecc_ecdsa_sign (const struct ecc_curve *ecc,
   ecc_modq_add (ecc, hp, hp, tp);
   ecc_modq_mul (ecc, tp, hp, kinv);
 
-  mpn_copyi (sp, tp, ecc->size);
+  mpn_copyi (sp, tp, ecc->p.size);
 #undef P
 #undef hp
 #undef kinv
diff --git a/ecc-ecdsa-verify.c b/ecc-ecdsa-verify.c
index edd6600a5fbb11c39ad04676c295b3c151a50c84..5f4229b39d2f1b4275f9c700a813cb4b33767594 100644
--- a/ecc-ecdsa-verify.c
+++ b/ecc-ecdsa-verify.c
@@ -43,6 +43,7 @@
 
 /* Low-level ECDSA verify */
 
+/* FIXME: Use mpn_zero_p. */
 static int
 zero_p (const mp_limb_t *xp, mp_size_t n)
 {
@@ -55,15 +56,15 @@ zero_p (const mp_limb_t *xp, mp_size_t n)
 static int
 ecdsa_in_range (const struct ecc_curve *ecc, const mp_limb_t *xp)
 {
-  return !zero_p (xp, ecc->size)
-    && mpn_cmp (xp, ecc->q, ecc->size) < 0;
+  return !zero_p (xp, ecc->p.size)
+    && mpn_cmp (xp, ecc->q.m, ecc->p.size) < 0;
 }
 
 mp_size_t
 ecc_ecdsa_verify_itch (const struct ecc_curve *ecc)
 {
   /* Largest storage need is for the ecc->mul call. */
-  return 5*ecc->size + ecc->mul_itch;
+  return 5*ecc->p.size + ecc->mul_itch;
 }
 
 /* FIXME: Use faster primitives, not requiring side-channel silence. */
@@ -91,11 +92,11 @@ ecc_ecdsa_verify (const struct ecc_curve *ecc,
   */
 
 #define P2 scratch
-#define P1 (scratch + 3*ecc->size)
-#define sinv (scratch + 3*ecc->size)
-#define u2 (scratch + 4*ecc->size)
-#define hp (scratch + 4*ecc->size)
-#define u1 (scratch + 6*ecc->size)
+#define P1 (scratch + 3*ecc->p.size)
+#define sinv (scratch + 3*ecc->p.size)
+#define u2 (scratch + 4*ecc->p.size)
+#define hp (scratch + 4*ecc->p.size)
+#define u1 (scratch + 6*ecc->p.size)
 
   if (! (ecdsa_in_range (ecc, rp)
 	 && ecdsa_in_range (ecc, sp)))
@@ -106,14 +107,14 @@ ecc_ecdsa_verify (const struct ecc_curve *ecc,
      division, I think), and write an ecc_add_ppp. */
   
   /* Compute sinv, use P2 as scratch */
-  mpn_copyi (sinv + ecc->size, sp, ecc->size);
-  ecc_modq_inv (ecc, sinv, sinv + ecc->size, P2);
+  mpn_copyi (sinv + ecc->p.size, sp, ecc->p.size);
+  ecc_modq_inv (ecc, sinv, sinv + ecc->p.size, P2);
 
   /* u2 = r / s, P2 = u2 * Y */
   ecc_modq_mul (ecc, u2, rp, sinv);
 
-   /* Total storage: 5*ecc->size + ecc->mul_itch */
-  ecc->mul (ecc, P2, u2, pp, u2 + ecc->size);
+   /* Total storage: 5*ecc->p.size + ecc->mul_itch */
+  ecc->mul (ecc, P2, u2, pp, u2 + ecc->p.size);
 
   /* u1 = h / s, P1 = u1 * G */
   ecc_hash (ecc, hp, length, digest);
@@ -121,10 +122,10 @@ ecc_ecdsa_verify (const struct ecc_curve *ecc,
 
   /* u = 0 can happen only if h = 0 or h = q, which is extremely
      unlikely. */
-  if (!zero_p (u1, ecc->size))
+  if (!zero_p (u1, ecc->p.size))
     {
-      /* Total storage: 6*ecc->size + ecc->mul_g_itch (ecc->size) */
-      ecc->mul_g (ecc, P1, u1, u1 + ecc->size);
+      /* Total storage: 6*ecc->p.size + ecc->mul_g_itch (ecc->p.size) */
+      ecc->mul_g (ecc, P1, u1, u1 + ecc->p.size);
 
       /* NOTE: ecc_add_jjj and/or ecc_j_to_a will produce garbage in
 	 case u1 G = +/- u2 V. However, anyone who gets his or her
@@ -140,13 +141,13 @@ ecc_ecdsa_verify (const struct ecc_curve *ecc,
 	 s_1 = z. Hitting that is about as unlikely as finding the
 	 private key by guessing.
        */
-      /* Total storage: 6*ecc->size + ecc->add_hhh_itch */
+      /* Total storage: 6*ecc->p.size + ecc->add_hhh_itch */
       ecc->add_hhh (ecc, P1, P1, P2, u1);
     }
   /* x coordinate only, modulo q */
   ecc->h_to_a (ecc, 2, P2, P1, u1);
 
-  return (mpn_cmp (rp, P2, ecc->size) == 0);
+  return (mpn_cmp (rp, P2, ecc->p.size) == 0);
 #undef P2
 #undef P1
 #undef sinv
diff --git a/ecc-eh-to-a.c b/ecc-eh-to-a.c
index 7891aa774b26e95b32c190e8a4732286fe07666c..aed176c11bb5ac5296ed2877b674f93630d57050 100644
--- a/ecc-eh-to-a.c
+++ b/ecc-eh-to-a.c
@@ -41,8 +41,8 @@
 mp_size_t
 ecc_eh_to_a_itch (const struct ecc_curve *ecc)
 {
-  /* Needs ecc->size + scratch for ecc_modq_inv */
-  return ECC_EH_TO_A_ITCH (ecc->size);
+  /* Needs ecc->p.size + scratch for ecc_modq_inv */
+  return ECC_EH_TO_A_ITCH (ecc->p.size);
 }
 
 /* Convert from homogeneous coordinates on the Edwards curve to affine
@@ -54,22 +54,22 @@ ecc_eh_to_a (const struct ecc_curve *ecc,
 	     mp_limb_t *scratch)
 {
 #define izp scratch
-#define tp (scratch + ecc->size)
+#define tp (scratch + ecc->p.size)
 
 
 #define xp p
-#define yp (p + ecc->size)
-#define zp (p + 2*ecc->size)
+#define yp (p + ecc->p.size)
+#define zp (p + 2*ecc->p.size)
 
   mp_limb_t cy;
 
-  mpn_copyi (tp, zp, ecc->size);
+  mpn_copyi (tp, zp, ecc->p.size);
   /* Needs 3*size scratch */
-  ecc_modp_inv (ecc, izp, tp, tp + ecc->size);
+  ecc_modp_inv (ecc, izp, tp, tp + ecc->p.size);
 
   ecc_modp_mul (ecc, tp, xp, izp);
-  cy = mpn_sub_n (r, tp, ecc->p, ecc->size);
-  cnd_copy (cy, r, tp, ecc->size);
+  cy = mpn_sub_n (r, tp, ecc->p.m, ecc->p.size);
+  cnd_copy (cy, r, tp, ecc->p.size);
 
   if (op)
     {
@@ -81,16 +81,16 @@ ecc_eh_to_a (const struct ecc_curve *ecc,
 	     at all? Full reduction mod p is maybe sufficient. */
 	  mp_limb_t cy;
 	  unsigned shift;
-	  assert (ecc->bit_size == 255);
-	  shift = 252 - GMP_NUMB_BITS * (ecc->size - 1);
-	  cy = mpn_submul_1 (r, ecc->q, ecc->size,
-			     r[ecc->size-1] >> shift);
+	  assert (ecc->p.bit_size == 255);
+	  shift = 252 - GMP_NUMB_BITS * (ecc->p.size - 1);
+	  cy = mpn_submul_1 (r, ecc->q.m, ecc->p.size,
+			     r[ecc->p.size-1] >> shift);
 	  assert (cy < 2);
-	  cnd_add_n (cy, r, ecc->q, ecc->size);
+	  cnd_add_n (cy, r, ecc->q.m, ecc->p.size);
 	}
       return;
     }
   ecc_modp_mul (ecc, tp, yp, izp);
-  cy = mpn_sub_n (r + ecc->size, tp, ecc->p, ecc->size);
-  cnd_copy (cy, r + ecc->size, tp, ecc->size);
+  cy = mpn_sub_n (r + ecc->p.size, tp, ecc->p.m, ecc->p.size);
+  cnd_copy (cy, r + ecc->p.size, tp, ecc->p.size);
 }
diff --git a/ecc-generic-modp.c b/ecc-generic-modp.c
index e0893c88cc24a47b467cb501683c3283b4bf1542..5bd4eecec02171b73c69cdf495dbff058672d80f 100644
--- a/ecc-generic-modp.c
+++ b/ecc-generic-modp.c
@@ -42,9 +42,7 @@
 void
 ecc_generic_modp (const struct ecc_curve *ecc, mp_limb_t *rp)
 {
-  assert (ecc->Bmodp_size < ecc->size);
+  assert (ecc->p.B_size < ecc->p.size);
   
-  ecc_mod (rp, 2*ecc->size, ecc->size, ecc->Bmodp, ecc->Bmodp_size,
-	   ecc->Bmodp_shifted,
-	   ecc->size * GMP_NUMB_BITS - ecc->bit_size);
+  ecc_mod (&ecc->p, rp, 2*ecc->p.size);
 }
diff --git a/ecc-generic-modq.c b/ecc-generic-modq.c
index a0165ff7449629b572084ebb373ce41498ce5362..c66113d6a47bbdad5645e276c3c103632f691857 100644
--- a/ecc-generic-modq.c
+++ b/ecc-generic-modq.c
@@ -42,9 +42,7 @@
 void
 ecc_generic_modq (const struct ecc_curve *ecc, mp_limb_t *rp)
 {
-  assert (ecc->Bmodq_size < ecc->size);
+  assert (ecc->q.B_size < ecc->q.size);
 
-  ecc_mod (rp, 2*ecc->size, ecc->size, ecc->Bmodq, ecc->Bmodq_size,
-	   ecc->Bmodq_shifted,
-	   ecc->size * GMP_NUMB_BITS - ecc->bit_size);
+  ecc_mod (&ecc->q, rp, 2*ecc->q.size);
 }
diff --git a/ecc-hash.c b/ecc-hash.c
index 547e8dbd89fb27e810725a4055c70499915f8fc7..780d0a666f0ee62c113108535ba241c196f9b10e 100644
--- a/ecc-hash.c
+++ b/ecc-hash.c
@@ -47,17 +47,20 @@
    Requires ecc->size + 1 limbs, the extra limb may be needed for
    unusual limb sizes.
 */
+
+/* FIXME: Take a struct ecc_modulo * as argument, and it would make
+   more sense to pass q than p. */
 void
 ecc_hash (const struct ecc_curve *ecc,
 	  mp_limb_t *hp,
 	  size_t length, const uint8_t *digest)
 {
-  if (length > ((size_t) ecc->bit_size + 7) / 8)
-    length = (ecc->bit_size + 7) / 8;
+  if (length > ((size_t) ecc->p.bit_size + 7) / 8)
+    length = (ecc->p.bit_size + 7) / 8;
 
-  mpn_set_base256 (hp, ecc->size + 1, digest, length);
+  mpn_set_base256 (hp, ecc->p.size + 1, digest, length);
 
-  if (8 * length > ecc->bit_size)
+  if (8 * length > ecc->p.bit_size)
     /* We got a few extra bits, at the low end. Discard them. */
-    mpn_rshift (hp, hp, ecc->size + 1, 8*length - ecc->bit_size);
+    mpn_rshift (hp, hp, ecc->p.size + 1, 8*length - ecc->p.bit_size);
 }
diff --git a/ecc-internal.h b/ecc-internal.h
index 777ab77e1706e4fef355373ee661187a9be546d1..b81da1f337368a414f7f2685a7cfadf6e405cb1a 100644
--- a/ecc-internal.h
+++ b/ecc-internal.h
@@ -77,10 +77,26 @@
 /* And for ecc_mul_a_eh */
 #define ECC_MUL_A_EH_WBITS 4
 
+struct ecc_modulo
+{
+  unsigned short bit_size;
+  unsigned short size;
+  unsigned short B_size;
+  unsigned short redc_size;
+
+  const mp_limb_t *m;
+  /* B^size mod m. Expected to have at least 32 leading zeros
+     (equality for secp_256r1). */
+  const mp_limb_t *B;
+  /* 2^{bit_size} - p, same value as above, but shifted. */
+  const mp_limb_t *B_shifted;
+  /* m +/- 1, for redc, excluding redc_size low limbs. */
+  const mp_limb_t *redc_mpm1;
+};
 
 /* Reduces from 2*ecc->size to ecc->size. */
 /* Required to return a result < 2q. This property is inherited by
-   modp_mul and modp_add. */
+   modp_mul and modp_sqr. */
 typedef void ecc_mod_func (const struct ecc_curve *ecc, mp_limb_t *rp);
 
 typedef void ecc_add_func (const struct ecc_curve *ecc,
@@ -107,18 +123,14 @@ typedef void ecc_h_to_a_func (const struct ecc_curve *ecc,
 */
 struct ecc_curve
 {
-  unsigned short bit_size;
-  /* Limb size of elements in the base field, size of a point is
-     2*size in affine coordinates and 3*size in jacobian
-     coordinates. */
-  unsigned short size;
-  unsigned short Bmodp_size;
-  unsigned short q_bit_size;
-  unsigned short Bmodq_size;
+  /* The prime p. */
+  struct ecc_modulo p;
+  /* Group order. FIXME: Currently, many fucntions rely on q.size ==
+     p.size. This has to change for radix-51 implementation of
+     curve25519 mod p arithmetic. */
+  struct ecc_modulo q;
+
   unsigned short use_redc;
-  /* +k if p+1 has k low zero limbs, -k if p-1 has k low zero
-     limbs. */
-  short redc_size;
   unsigned short pippenger_k;
   unsigned short pippenger_c;
 
@@ -137,34 +149,20 @@ struct ecc_curve
   ecc_mul_g_func *mul_g;
   ecc_h_to_a_func *h_to_a;
 
-  /* The prime p. */
-  const mp_limb_t *p;
+  /* Curve constant */
   const mp_limb_t *b;
-  /* Group order. */
-  const mp_limb_t *q;
   /* Generator, x coordinate followed by y (affine coordinates).
-   Currently used only by the test suite. */
+     Currently used only by the test suite. */
   const mp_limb_t *g;
   /* If non-NULL, the constant needed for transformation to the
      equivalent Edwards curve. */
   const mp_limb_t *edwards_root;
 
-  /* B^size mod p. Expected to have at least 32 leading zeros
-     (equality for secp_256r1). */
-  const mp_limb_t *Bmodp;
-  /* 2^{bit_size} - p, same value as above, but shifted. */
-  const mp_limb_t *Bmodp_shifted;
   /* (p+1)/2 */
   const mp_limb_t *pp1h;
-  /* p +/- 1, for redc, excluding |redc_size| low limbs. */
-  const mp_limb_t *redc_ppm1;
   /* For redc, same as Bmodp, otherwise 1. */
   const mp_limb_t *unit;
 
-  /* Similarly, B^size mod q */
-  const mp_limb_t *Bmodq;
-  /* 2^{bit_size} - q, same value as above, but shifted. */
-  const mp_limb_t *Bmodq_shifted;
   /* (q+1)/2 */
   const mp_limb_t *qp1h;
   
@@ -236,9 +234,7 @@ 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 (mp_limb_t *rp, mp_size_t rn, mp_size_t mn,
-	 const mp_limb_t *bp, mp_size_t bn,
-	 const mp_limb_t *b_shifted, unsigned shift);
+ecc_mod (const struct ecc_modulo *m, mp_limb_t *rp, mp_size_t rn);
 
 void
 ecc_hash (const struct ecc_curve *ecc,
diff --git a/ecc-j-to-a.c b/ecc-j-to-a.c
index e945929d549cc729ed0902df5027bf3534aa9747..eb22ecab6ad5a796978ad9fb6ef8a4cf787fe026 100644
--- a/ecc-j-to-a.c
+++ b/ecc-j-to-a.c
@@ -42,7 +42,7 @@ mp_size_t
 ecc_j_to_a_itch (const struct ecc_curve *ecc)
 {
   /* Needs 2*ecc->size + scratch for ecc_modq_inv */
-  return ECC_J_TO_A_ITCH (ecc->size);
+  return ECC_J_TO_A_ITCH (ecc->p.size);
 }
 
 void
@@ -52,10 +52,10 @@ ecc_j_to_a (const struct ecc_curve *ecc,
 	    mp_limb_t *scratch)
 {
 #define izp   scratch
-#define up   (scratch + ecc->size)
-#define iz2p (scratch + ecc->size)
-#define iz3p (scratch + 2*ecc->size)
-#define izBp (scratch + 3*ecc->size)
+#define up   (scratch + ecc->p.size)
+#define iz2p (scratch + ecc->p.size)
+#define iz3p (scratch + 2*ecc->p.size)
+#define izBp (scratch + 3*ecc->p.size)
 #define tp    scratch
 
   mp_limb_t cy;
@@ -71,17 +71,17 @@ ecc_j_to_a (const struct ecc_curve *ecc,
 	 representation.
       */
 
-      mpn_copyi (up, p + 2*ecc->size, ecc->size);
-      mpn_zero (up + ecc->size, ecc->size);
+      mpn_copyi (up, p + 2*ecc->p.size, ecc->p.size);
+      mpn_zero (up + ecc->p.size, ecc->p.size);
       ecc->redc (ecc, up);
-      mpn_zero (up + ecc->size, ecc->size);
+      mpn_zero (up + ecc->p.size, ecc->p.size);
       ecc->redc (ecc, up);
 
-      ecc_modp_inv (ecc, izp, up, up + ecc->size);
+      ecc_modp_inv (ecc, izp, up, up + ecc->p.size);
 
       /* Divide this common factor by B */
-      mpn_copyi (izBp, izp, ecc->size);
-      mpn_zero (izBp + ecc->size, ecc->size);
+      mpn_copyi (izBp, izp, ecc->p.size);
+      mpn_zero (izBp + ecc->p.size, ecc->p.size);
       ecc->redc (ecc, izBp);
 
       ecc_modp_mul (ecc, iz2p, izp, izBp);
@@ -90,8 +90,8 @@ ecc_j_to_a (const struct ecc_curve *ecc,
     {
       /* Set s = p_z^{-1}, r_x = p_x s^2, r_y = p_y s^3 */
 
-      mpn_copyi (up, p+2*ecc->size, ecc->size); /* p_z */
-      ecc_modp_inv (ecc, izp, up, up + ecc->size);
+      mpn_copyi (up, p+2*ecc->p.size, ecc->p.size); /* p_z */
+      ecc_modp_inv (ecc, izp, up, up + ecc->p.size);
 
       ecc_modp_sqr (ecc, iz2p, izp);
     }
@@ -99,8 +99,8 @@ ecc_j_to_a (const struct ecc_curve *ecc,
   ecc_modp_mul (ecc, iz3p, iz2p, p);
   /* ecc_modp (and ecc_modp_mul) may return a value up to 2p - 1, so
      do a conditional subtraction. */
-  cy = mpn_sub_n (r, iz3p, ecc->p, ecc->size);
-  cnd_copy (cy, r, iz3p, ecc->size);
+  cy = mpn_sub_n (r, iz3p, ecc->p.m, ecc->p.size);
+  cnd_copy (cy, r, iz3p, ecc->p.size);
 
   if (op)
     {
@@ -110,16 +110,16 @@ ecc_j_to_a (const struct ecc_curve *ecc,
 	  /* Also reduce the x coordinate mod ecc->q. It should
 	     already be < 2*ecc->q, so one subtraction should
 	     suffice. */
-	  cy = mpn_sub_n (scratch, r, ecc->q, ecc->size);
-	  cnd_copy (cy == 0, r, scratch, ecc->size);
+	  cy = mpn_sub_n (scratch, r, ecc->q.m, ecc->p.size);
+	  cnd_copy (cy == 0, r, scratch, ecc->p.size);
 	}
       return;
     }
   ecc_modp_mul (ecc, iz3p, iz2p, izp);
-  ecc_modp_mul (ecc, tp, iz3p, p + ecc->size);
+  ecc_modp_mul (ecc, tp, iz3p, p + ecc->p.size);
   /* And a similar subtraction. */
-  cy = mpn_sub_n (r + ecc->size, tp, ecc->p, ecc->size);
-  cnd_copy (cy, r + ecc->size, tp, ecc->size);
+  cy = mpn_sub_n (r + ecc->p.size, tp, ecc->p.m, ecc->p.size);
+  cnd_copy (cy, r + ecc->p.size, tp, ecc->p.size);
 
 #undef izp
 #undef up
diff --git a/ecc-mod.c b/ecc-mod.c
index 3301506dd8c99eb4c1532b85cc87c5fe92fd21eb..68576a8b01066e3fef94bdbf007d680f6856b780 100644
--- a/ecc-mod.c
+++ b/ecc-mod.c
@@ -39,22 +39,22 @@
 
 #include "ecc-internal.h"
 
-/* Computes r mod m, where m is of size mn. bp holds B^mn mod m, as mn
-   limbs, but the upper mn - bn limbs are zero. */
+/* Computes r mod m. */
 void
-ecc_mod (mp_limb_t *rp, mp_size_t rn, mp_size_t mn,
-	 const mp_limb_t *bp, mp_size_t bn,
-	 const mp_limb_t *b_shifted, unsigned shift)
+ecc_mod (const struct ecc_modulo *m, mp_limb_t *rp, mp_size_t rn)
 {
   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 i;
+  unsigned shift;
 
   assert (sn > 0);
 
   /* FIXME: Could use mpn_addmul_2. */
-  /* Eliminate sn = mn - bn limbs at a time */
-  if (bp[bn-1] < ((mp_limb_t) 1 << (GMP_NUMB_BITS - 1)))
+  /* Eliminate sn limbs at a time */
+  if (m->B[bn-1] < ((mp_limb_t) 1 << (GMP_NUMB_BITS - 1)))
     {
       /* Multiply sn + 1 limbs at a time, so we get a mn+1 limb
 	 product. Then we can absorb the carry in the high limb */
@@ -63,7 +63,7 @@ ecc_mod (mp_limb_t *rp, mp_size_t rn, mp_size_t mn,
 	  rn -= sn;
 
 	  for (i = 0; i <= sn; i++)
-	    rp[rn+i-1] = mpn_addmul_1 (rp + rn - mn - 1 + i, bp, bn, rp[rn+i-1]);
+	    rp[rn+i-1] = mpn_addmul_1 (rp + rn - mn - 1 + i, m->B, bn, rp[rn+i-1]);
 	  rp[rn-1] = rp[rn+sn-1]
 	    + mpn_add_n (rp + rn - sn - 1, rp + rn - sn - 1, rp + rn - 1, sn);
 	}
@@ -76,10 +76,10 @@ ecc_mod (mp_limb_t *rp, mp_size_t rn, mp_size_t mn,
 	  rn -= sn;
 
 	  for (i = 0; i < sn; i++)
-	    rp[rn+i] = mpn_addmul_1 (rp + rn - mn + i, bp, bn, rp[rn+i]);
+	    rp[rn+i] = mpn_addmul_1 (rp + rn - mn + i, m->B, bn, rp[rn+i]);
 				     
 	  hi = mpn_add_n (rp + rn - sn, rp + rn - sn, rp + rn, sn);
-	  hi = cnd_add_n (hi, rp + rn - mn, bp, mn);
+	  hi = cnd_add_n (hi, rp + rn - mn, m->B, mn);
 	  assert (hi == 0);
 	}
     }
@@ -90,22 +90,23 @@ ecc_mod (mp_limb_t *rp, mp_size_t rn, mp_size_t mn,
       sn = rn - mn;
       
       for (i = 0; i < sn; i++)
-	rp[mn+i] = mpn_addmul_1 (rp + i, bp, bn, rp[mn+i]);
+	rp[mn+i] = mpn_addmul_1 (rp + i, m->B, bn, rp[mn+i]);
 
       hi = mpn_add_n (rp + bn, rp + bn, rp + mn, sn);
       hi = sec_add_1 (rp + bn + sn, rp + bn + sn, mn - bn - sn, hi);
     }
 
+  shift = m->size * GMP_NUMB_BITS - m->bit_size;
   if (shift > 0)
     {
       /* Combine hi with top bits, add in */
       hi = (hi << shift) | (rp[mn-1] >> (GMP_NUMB_BITS - shift));
       rp[mn-1] = (rp[mn-1] & (((mp_limb_t) 1 << (GMP_NUMB_BITS - shift)) - 1))
-	+ mpn_addmul_1 (rp, b_shifted, mn-1, hi);
+	+ mpn_addmul_1 (rp, m->B_shifted, mn-1, hi);
     }
   else
     {
-      hi = cnd_add_n (hi, rp, bp, mn);
+      hi = cnd_add_n (hi, rp, m->B_shifted, mn);
       assert (hi == 0);
     }
 }
diff --git a/ecc-modp.c b/ecc-modp.c
index 2d50cd0d4b0294dfb7354eba03518eac51d17c3e..fe6c54a45bf834681030ae1956f1e9b4e797a9a8 100644
--- a/ecc-modp.c
+++ b/ecc-modp.c
@@ -47,9 +47,9 @@ ecc_modp_add (const struct ecc_curve *ecc, mp_limb_t *rp,
 	      const mp_limb_t *ap, const mp_limb_t *bp)
 {
   mp_limb_t cy;
-  cy = mpn_add_n (rp, ap, bp, ecc->size);
-  cy = cnd_add_n (cy, rp, ecc->Bmodp, ecc->size);
-  cy = cnd_add_n (cy, rp, ecc->Bmodp, ecc->size);
+  cy = mpn_add_n (rp, ap, bp, ecc->p.size);
+  cy = cnd_add_n (cy, rp, ecc->p.B, ecc->p.size);
+  cy = cnd_add_n (cy, rp, ecc->p.B, ecc->p.size);
   assert (cy == 0);  
 }
 
@@ -58,9 +58,9 @@ ecc_modp_sub (const struct ecc_curve *ecc, mp_limb_t *rp,
 	      const mp_limb_t *ap, const mp_limb_t *bp)
 {
   mp_limb_t cy;
-  cy = mpn_sub_n (rp, ap, bp, ecc->size);
-  cy = cnd_sub_n (cy, rp, ecc->Bmodp, ecc->size);
-  cy = cnd_sub_n (cy, rp, ecc->Bmodp, ecc->size);
+  cy = mpn_sub_n (rp, ap, bp, ecc->p.size);
+  cy = cnd_sub_n (cy, rp, ecc->p.B, ecc->p.size);
+  cy = cnd_sub_n (cy, rp, ecc->p.B, ecc->p.size);
   assert (cy == 0);  
 }
 
@@ -71,10 +71,10 @@ ecc_modp_mul_1 (const struct ecc_curve *ecc, mp_limb_t *rp,
   mp_limb_t hi;
 
   assert (b <= 0xffffffff);
-  hi = mpn_mul_1 (rp, ap, ecc->size, b);
-  hi = mpn_addmul_1 (rp, ecc->Bmodp, ecc->size, hi);
+  hi = mpn_mul_1 (rp, ap, ecc->p.size, b);
+  hi = mpn_addmul_1 (rp, ecc->p.B, ecc->p.size, hi);
   assert (hi <= 1);
-  hi = cnd_add_n (hi, rp, ecc->Bmodp, ecc->size);
+  hi = cnd_add_n (hi, rp, ecc->p.B, ecc->p.size);
   /* Sufficient if b < B^size / p */
   assert (hi == 0);
 }
@@ -86,10 +86,10 @@ ecc_modp_addmul_1 (const struct ecc_curve *ecc, mp_limb_t *rp,
   mp_limb_t hi;
 
   assert (b <= 0xffffffff);
-  hi = mpn_addmul_1 (rp, ap, ecc->size, b);
-  hi = mpn_addmul_1 (rp, ecc->Bmodp, ecc->size, hi);
+  hi = mpn_addmul_1 (rp, ap, ecc->p.size, b);
+  hi = mpn_addmul_1 (rp, ecc->p.B, ecc->p.size, hi);
   assert (hi <= 1);
-  hi = cnd_add_n (hi, rp, ecc->Bmodp, ecc->size);
+  hi = cnd_add_n (hi, rp, ecc->p.B, ecc->p.size);
   /* Sufficient roughly if b < B^size / p */
   assert (hi == 0);
 }
@@ -101,20 +101,20 @@ ecc_modp_submul_1 (const struct ecc_curve *ecc, mp_limb_t *rp,
   mp_limb_t hi;
 
   assert (b <= 0xffffffff);
-  hi = mpn_submul_1 (rp, ap, ecc->size, b);
-  hi = mpn_submul_1 (rp, ecc->Bmodp, ecc->size, hi);
+  hi = mpn_submul_1 (rp, ap, ecc->p.size, b);
+  hi = mpn_submul_1 (rp, ecc->p.B, ecc->p.size, hi);
   assert (hi <= 1);
-  hi = cnd_sub_n (hi, rp, ecc->Bmodp, ecc->size);
+  hi = cnd_sub_n (hi, rp, ecc->p.B, ecc->p.size);
   /* Sufficient roughly if b < B^size / p */
   assert (hi == 0);
 }
 
-/* NOTE: mul and sqr needs 2*ecc->size limbs at rp */
+/* NOTE: mul and sqr needs 2*ecc->p.size limbs at rp */
 void
 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->size);
+  mpn_mul_n (rp, ap, bp, ecc->p.size);
   ecc->reduce (ecc, rp);
 }
 
@@ -122,7 +122,7 @@ void
 ecc_modp_sqr (const struct ecc_curve *ecc, mp_limb_t *rp,
 	      const mp_limb_t *ap)
 {
-  mpn_sqr (rp, ap, ecc->size);
+  mpn_sqr (rp, ap, ecc->p.size);
   ecc->reduce (ecc, rp);
 }
 
@@ -130,6 +130,6 @@ void
 ecc_modp_inv (const struct ecc_curve *ecc, mp_limb_t *rp, mp_limb_t *ap,
 	      mp_limb_t *scratch)
 {
-  sec_modinv (rp, ap, ecc->size, ecc->p, ecc->pp1h, ecc->bit_size, scratch);
+  sec_modinv (rp, ap, ecc->p.size, ecc->p.m, ecc->pp1h, ecc->p.bit_size, scratch);
 }
 
diff --git a/ecc-modq.c b/ecc-modq.c
index 1555486633106cc12b27fe14b7b445409e5d8f75..850290a22269d8601b088b03599986bdc67a3431 100644
--- a/ecc-modq.c
+++ b/ecc-modq.c
@@ -46,9 +46,9 @@ ecc_modq_add (const struct ecc_curve *ecc, mp_limb_t *rp,
 	      const mp_limb_t *ap, const mp_limb_t *bp)
 {
   mp_limb_t cy;
-  cy = mpn_add_n (rp, ap, bp, ecc->size);
-  cy = cnd_add_n (cy, rp, ecc->Bmodq, ecc->size);
-  cy = cnd_add_n (cy, rp, ecc->Bmodq, ecc->size);
+  cy = mpn_add_n (rp, ap, bp, ecc->q.size);
+  cy = cnd_add_n (cy, rp, ecc->q.B, ecc->q.size);
+  cy = cnd_add_n (cy, rp, ecc->q.B, ecc->q.size);
   assert (cy == 0);  
 }
 
@@ -56,7 +56,7 @@ void
 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->size);
+  mpn_mul_n (rp, ap, bp, ecc->q.size);
   ecc->modq (ecc, rp);
 }
 
@@ -64,5 +64,5 @@ void
 ecc_modq_inv (const struct ecc_curve *ecc, mp_limb_t *rp, mp_limb_t *ap,
 	      mp_limb_t *scratch)
 {
-  sec_modinv (rp, ap, ecc->size, ecc->q, ecc->qp1h, ecc->q_bit_size, scratch);
+  sec_modinv (rp, ap, ecc->q.size, ecc->q.m, ecc->qp1h, ecc->q.bit_size, scratch);
 }
diff --git a/ecc-mul-a-eh.c b/ecc-mul-a-eh.c
index 095e870c24cc1e795850efbdc44c975c14c36880..2e2733498f75aa7c49e927f61d1367e26dfe2249 100644
--- a/ecc-mul-a-eh.c
+++ b/ecc-mul-a-eh.c
@@ -41,13 +41,13 @@
 mp_size_t
 ecc_mul_a_eh_itch (const struct ecc_curve *ecc)
 {
-  /* Binary algorithm needs 6*ecc->size + scratch for ecc_add_ehh,
-     total 13 ecc->size
+  /* Binary algorithm needs 6*ecc->p.size + scratch for ecc_add_ehh,
+     total 13 ecc->p.size
 
-     Window algorithm needs (3<<w) * ecc->size for the table,
-     3*ecc->size for a temporary point, and scratch for
+     Window algorithm needs (3<<w) * ecc->p.size for the table,
+     3*ecc->p.size for a temporary point, and scratch for
      ecc_add_ehh. */
-  return ECC_MUL_A_EH_ITCH (ecc->size);
+  return ECC_MUL_A_EH_ITCH (ecc->p.size);
 }
 
 #if ECC_MUL_A_EH_WBITS == 0
@@ -58,18 +58,18 @@ ecc_mul_a_eh (const struct ecc_curve *ecc,
 	      mp_limb_t *scratch)
 {
 #define pe scratch
-#define tp (scratch + 3*ecc->size)
-#define scratch_out (scratch + 6*ecc->size)
+#define tp (scratch + 3*ecc->p.size)
+#define scratch_out (scratch + 6*ecc->p.size)
 
   unsigned i;
 
   ecc_a_to_j (ecc, pe, p);
 
   /* x = 0, y = 1, z = 1 */
-  mpn_zero (r, 3*ecc->size);
-  r[ecc->size] = r[2*ecc->size] = 1;
+  mpn_zero (r, 3*ecc->p.size);
+  r[ecc->p.size] = r[2*ecc->p.size] = 1;
   
-  for (i = ecc->size; i-- > 0; )
+  for (i = ecc->p.size; i-- > 0; )
     {
       mp_limb_t w = np[i];
       mp_limb_t bit;
@@ -85,7 +85,7 @@ ecc_mul_a_eh (const struct ecc_curve *ecc,
 
 	  digit = (w & bit) > 0;
 	  /* If we had a one-bit, use the sum. */
-	  cnd_copy (digit, r, tp, 3*ecc->size);
+	  cnd_copy (digit, r, tp, 3*ecc->p.size);
 	}
     }
 }
@@ -94,7 +94,7 @@ ecc_mul_a_eh (const struct ecc_curve *ecc,
 #define TABLE_SIZE (1U << ECC_MUL_A_EH_WBITS)
 #define TABLE_MASK (TABLE_SIZE - 1)
 
-#define TABLE(j) (table + (j) * 3*ecc->size)
+#define TABLE(j) (table + (j) * 3*ecc->p.size)
 
 static void
 table_init (const struct ecc_curve *ecc,
@@ -105,8 +105,8 @@ table_init (const struct ecc_curve *ecc,
   unsigned size = 1 << bits;
   unsigned j;
 
-  mpn_zero (TABLE(0), 3*ecc->size);
-  TABLE(0)[ecc->size] = TABLE(0)[2*ecc->size] = 1;
+  mpn_zero (TABLE(0), 3*ecc->p.size);
+  TABLE(0)[ecc->p.size] = TABLE(0)[2*ecc->p.size] = 1;
 
   ecc_a_to_j (ecc, TABLE(1), p);
 
@@ -124,12 +124,12 @@ ecc_mul_a_eh (const struct ecc_curve *ecc,
 	      mp_limb_t *scratch)
 {
 #define tp scratch
-#define table (scratch + 3*ecc->size)
-  mp_limb_t *scratch_out = table + (3*ecc->size << ECC_MUL_A_EH_WBITS);
+#define table (scratch + 3*ecc->p.size)
+  mp_limb_t *scratch_out = table + (3*ecc->p.size << ECC_MUL_A_EH_WBITS);
 
   /* Avoid the mp_bitcnt_t type for compatibility with older GMP
      versions. */
-  unsigned blocks = (ecc->bit_size + ECC_MUL_A_EH_WBITS - 1) / ECC_MUL_A_EH_WBITS;
+  unsigned blocks = (ecc->p.bit_size + ECC_MUL_A_EH_WBITS - 1) / ECC_MUL_A_EH_WBITS;
   unsigned bit_index = (blocks-1) * ECC_MUL_A_EH_WBITS;
 
   mp_size_t limb_index = bit_index / GMP_NUMB_BITS;
@@ -140,12 +140,12 @@ ecc_mul_a_eh (const struct ecc_curve *ecc,
 
   w = np[limb_index];
   bits = w >> shift;
-  if (limb_index < ecc->size - 1)
+  if (limb_index < ecc->p.size - 1)
     bits |= np[limb_index + 1] << (GMP_NUMB_BITS - shift);
 
   assert (bits < TABLE_SIZE);
 
-  sec_tabselect (r, 3*ecc->size, table, TABLE_SIZE, bits);
+  sec_tabselect (r, 3*ecc->p.size, table, TABLE_SIZE, bits);
 
   for (;;)
     {
@@ -171,7 +171,7 @@ ecc_mul_a_eh (const struct ecc_curve *ecc,
 	ecc_dup_eh (ecc, r, r, scratch_out);
 
       bits &= TABLE_MASK;
-      sec_tabselect (tp, 3*ecc->size, table, TABLE_SIZE, bits);
+      sec_tabselect (tp, 3*ecc->p.size, table, TABLE_SIZE, bits);
       ecc_add_ehh (ecc, r, tp, r, scratch_out);
     }
 #undef table
diff --git a/ecc-mul-a.c b/ecc-mul-a.c
index 82f72e65540ad35317040a38b5aaffb36bdacfd3..9b2be3d8895eefd3319d546ca5b91bd3c421b99c 100644
--- a/ecc-mul-a.c
+++ b/ecc-mul-a.c
@@ -43,13 +43,13 @@
 mp_size_t
 ecc_mul_a_itch (const struct ecc_curve *ecc)
 {
-  /* Binary algorithm needs 6*ecc->size + scratch for ecc_add_jja.
-     Current total is 12 ecc->size, at most 864 bytes.
+  /* Binary algorithm needs 6*ecc->p.size + scratch for ecc_add_jja.
+     Current total is 12 ecc->p.size, at most 864 bytes.
 
-     Window algorithm needs (3<<w) * ecc->size for the table,
-     3*ecc->size for a temporary point, and scratch for
+     Window algorithm needs (3<<w) * ecc->p.size for the table,
+     3*ecc->p.size for a temporary point, and scratch for
      ecc_add_jjj. */
-  return ECC_MUL_A_ITCH (ecc->size);
+  return ECC_MUL_A_ITCH (ecc->p.size);
 }
 
 #if ECC_MUL_A_WBITS == 0
@@ -60,17 +60,17 @@ ecc_mul_a (const struct ecc_curve *ecc,
 	   mp_limb_t *scratch)
 {
 #define tp scratch
-#define pj (scratch + 3*ecc->size)
-#define scratch_out (scratch + 6*ecc->size)
+#define pj (scratch + 3*ecc->p.size)
+#define scratch_out (scratch + 6*ecc->p.size)
 
   int is_zero;
 
   unsigned i;
 
   ecc_a_to_j (ecc, pj, p);
-  mpn_zero (r, 3*ecc->size);
+  mpn_zero (r, 3*ecc->p.size);
   
-  for (i = ecc->size, is_zero = 1; i-- > 0; )
+  for (i = ecc->p.size, is_zero = 1; i-- > 0; )
     {
       mp_limb_t w = np[i];
       mp_limb_t bit;
@@ -87,10 +87,10 @@ ecc_mul_a (const struct ecc_curve *ecc,
 	  digit = (w & bit) > 0;
 	  /* If is_zero is set, r is the zero point,
 	     and ecc_add_jja produced garbage. */
-	  cnd_copy (is_zero, tp, pj, 3*ecc->size);
+	  cnd_copy (is_zero, tp, pj, 3*ecc->p.size);
 	  is_zero &= ~digit;
 	  /* If we had a one-bit, use the sum. */
-	  cnd_copy (digit, r, tp, 3*ecc->size);
+	  cnd_copy (digit, r, tp, 3*ecc->p.size);
 	}
     }
 }
@@ -99,7 +99,7 @@ ecc_mul_a (const struct ecc_curve *ecc,
 #define TABLE_SIZE (1U << ECC_MUL_A_WBITS)
 #define TABLE_MASK (TABLE_SIZE - 1)
 
-#define TABLE(j) (table + (j) * 3*ecc->size)
+#define TABLE(j) (table + (j) * 3*ecc->p.size)
 
 static void
 table_init (const struct ecc_curve *ecc,
@@ -110,7 +110,7 @@ table_init (const struct ecc_curve *ecc,
   unsigned size = 1 << bits;
   unsigned j;
 
-  mpn_zero (TABLE(0), 3*ecc->size);
+  mpn_zero (TABLE(0), 3*ecc->p.size);
   ecc_a_to_j (ecc, TABLE(1), p);
 
   for (j = 2; j < size; j += 2)
@@ -127,13 +127,13 @@ ecc_mul_a (const struct ecc_curve *ecc,
 	   mp_limb_t *scratch)
 {
 #define tp scratch
-#define table (scratch + 3*ecc->size)
-  mp_limb_t *scratch_out = table + (3*ecc->size << ECC_MUL_A_WBITS);
+#define table (scratch + 3*ecc->p.size)
+  mp_limb_t *scratch_out = table + (3*ecc->p.size << ECC_MUL_A_WBITS);
   int is_zero = 0;
 
   /* Avoid the mp_bitcnt_t type for compatibility with older GMP
      versions. */
-  unsigned blocks = (ecc->bit_size + ECC_MUL_A_WBITS - 1) / ECC_MUL_A_WBITS;
+  unsigned blocks = (ecc->p.bit_size + ECC_MUL_A_WBITS - 1) / ECC_MUL_A_WBITS;
   unsigned bit_index = (blocks-1) * ECC_MUL_A_WBITS;
 
   mp_size_t limb_index = bit_index / GMP_NUMB_BITS;
@@ -144,12 +144,12 @@ ecc_mul_a (const struct ecc_curve *ecc,
 
   w = np[limb_index];
   bits = w >> shift;
-  if (limb_index < ecc->size - 1)
+  if (limb_index < ecc->p.size - 1)
     bits |= np[limb_index + 1] << (GMP_NUMB_BITS - shift);
 
   assert (bits < TABLE_SIZE);
 
-  sec_tabselect (r, 3*ecc->size, table, TABLE_SIZE, bits);
+  sec_tabselect (r, 3*ecc->p.size, table, TABLE_SIZE, bits);
   is_zero = (bits == 0);
 
   for (;;)
@@ -176,13 +176,13 @@ ecc_mul_a (const struct ecc_curve *ecc,
 	ecc_dup_jj (ecc, r, r, scratch_out);
 
       bits &= TABLE_MASK;
-      sec_tabselect (tp, 3*ecc->size, table, TABLE_SIZE, bits);
-      cnd_copy (is_zero, r, tp, 3*ecc->size);
+      sec_tabselect (tp, 3*ecc->p.size, table, TABLE_SIZE, bits);
+      cnd_copy (is_zero, r, tp, 3*ecc->p.size);
       ecc_add_jjj (ecc, tp, tp, r, scratch_out);
 
       /* Use the sum when valid. ecc_add_jja produced garbage if
 	 is_zero != 0 or bits == 0, . */	  
-      cnd_copy (bits & (is_zero - 1), r, tp, 3*ecc->size);
+      cnd_copy (bits & (is_zero - 1), r, tp, 3*ecc->p.size);
       is_zero &= (bits == 0);
     }
 #undef table
diff --git a/ecc-mul-g-eh.c b/ecc-mul-g-eh.c
index 4242479c9bfb88ea9392cffd5eb730a0bdd62c58..fc0f565c8b32b1498fe25b4ef9d110bca7a3cb4d 100644
--- a/ecc-mul-g-eh.c
+++ b/ecc-mul-g-eh.c
@@ -43,8 +43,8 @@
 mp_size_t
 ecc_mul_g_eh_itch (const struct ecc_curve *ecc)
 {
-  /* Needs 3*ecc->size + scratch for ecc_add_jja. */
-  return ECC_MUL_G_EH_ITCH (ecc->size);
+  /* Needs 3*ecc->p.size + scratch for ecc_add_jja. */
+  return ECC_MUL_G_EH_ITCH (ecc->p.size);
 }
 
 void
@@ -52,9 +52,9 @@ ecc_mul_g_eh (const struct ecc_curve *ecc, mp_limb_t *r,
 	      const mp_limb_t *np, mp_limb_t *scratch)
 {
   /* Scratch need determined by the ecc_add_eh call. Current total is
-     9 * ecc->size, at most 648 bytes. */
+     9 * ecc->p.size, at most 648 bytes. */
 #define tp scratch
-#define scratch_out (scratch + 3*ecc->size)
+#define scratch_out (scratch + 3*ecc->p.size)
 
   unsigned k, c;
   unsigned i, j;
@@ -63,11 +63,11 @@ ecc_mul_g_eh (const struct ecc_curve *ecc, mp_limb_t *r,
   k = ecc->pippenger_k;
   c = ecc->pippenger_c;
 
-  bit_rows = (ecc->bit_size + k - 1) / k;
+  bit_rows = (ecc->p.bit_size + k - 1) / k;
 
   /* x = 0, y = 1, z = 1 */
-  mpn_zero (r, 3*ecc->size);
-  r[ecc->size] = r[2*ecc->size] = 1;
+  mpn_zero (r, 3*ecc->p.size);
+  r[ecc->p.size] = r[2*ecc->p.size] = 1;
 
   for (i = k; i-- > 0; )
     {
@@ -89,15 +89,15 @@ ecc_mul_g_eh (const struct ecc_curve *ecc, mp_limb_t *r,
 	      bit_index -= k;
 
 	      limb_index = bit_index / GMP_NUMB_BITS;
-	      if (limb_index >= ecc->size)
+	      if (limb_index >= ecc->p.size)
 		continue;
 
 	      shift = bit_index % GMP_NUMB_BITS;
 	      bits = (bits << 1) | ((np[limb_index] >> shift) & 1);
 	    }
-	  sec_tabselect (tp, 2*ecc->size,
+	  sec_tabselect (tp, 2*ecc->p.size,
 			 (ecc->pippenger_table
-			  + (2*ecc->size * (mp_size_t) j << c)),
+			  + (2*ecc->p.size * (mp_size_t) j << c)),
 			 1<<c, bits);
 
 	  ecc_add_eh (ecc, r, r, tp, scratch_out);
diff --git a/ecc-mul-g.c b/ecc-mul-g.c
index d2a32d4136e33612036a2094f92e1b69a762b4a7..b2dcb404b30ffb280966a3ea2e80b1522a2c5848 100644
--- a/ecc-mul-g.c
+++ b/ecc-mul-g.c
@@ -43,8 +43,8 @@
 mp_size_t
 ecc_mul_g_itch (const struct ecc_curve *ecc)
 {
-  /* Needs 3*ecc->size + scratch for ecc_add_jja. */
-  return ECC_MUL_G_ITCH (ecc->size);
+  /* Needs 3*ecc->p.size + scratch for ecc_add_jja. */
+  return ECC_MUL_G_ITCH (ecc->p.size);
 }
 
 void
@@ -52,9 +52,9 @@ ecc_mul_g (const struct ecc_curve *ecc, mp_limb_t *r,
 	   const mp_limb_t *np, mp_limb_t *scratch)
 {
   /* Scratch need determined by the ecc_add_jja call. Current total is
-     9 * ecc->size, at most 648 bytes. */
+     9 * ecc->p.size, at most 648 bytes. */
 #define tp scratch
-#define scratch_out (scratch + 3*ecc->size)
+#define scratch_out (scratch + 3*ecc->p.size)
 
   unsigned k, c;
   unsigned i, j;
@@ -65,9 +65,9 @@ ecc_mul_g (const struct ecc_curve *ecc, mp_limb_t *r,
   k = ecc->pippenger_k;
   c = ecc->pippenger_c;
 
-  bit_rows = (ecc->bit_size + k - 1) / k;
+  bit_rows = (ecc->p.bit_size + k - 1) / k;
   
-  mpn_zero (r, 3*ecc->size);
+  mpn_zero (r, 3*ecc->p.size);
   
   for (i = k, is_zero = 1; i-- > 0; )
     {
@@ -89,23 +89,23 @@ ecc_mul_g (const struct ecc_curve *ecc, mp_limb_t *r,
 	      bit_index -= k;
 
 	      limb_index = bit_index / GMP_NUMB_BITS;
-	      if (limb_index >= ecc->size)
+	      if (limb_index >= ecc->p.size)
 		continue;
 
 	      shift = bit_index % GMP_NUMB_BITS;
 	      bits = (bits << 1) | ((np[limb_index] >> shift) & 1);
 	    }
-	  sec_tabselect (tp, 2*ecc->size,
+	  sec_tabselect (tp, 2*ecc->p.size,
 			 (ecc->pippenger_table
-			  + (2*ecc->size * (mp_size_t) j << c)),
+			  + (2*ecc->p.size * (mp_size_t) j << c)),
 			 1<<c, bits);
-	  cnd_copy (is_zero, r, tp, 2*ecc->size);
-	  cnd_copy (is_zero, r + 2*ecc->size, ecc->unit, ecc->size);
+	  cnd_copy (is_zero, r, tp, 2*ecc->p.size);
+	  cnd_copy (is_zero, r + 2*ecc->p.size, ecc->unit, ecc->p.size);
 	  
 	  ecc_add_jja (ecc, tp, r, tp, scratch_out);
 	  /* Use the sum when valid. ecc_add_jja produced garbage if
 	     is_zero != 0 or bits == 0, . */	  
-	  cnd_copy (bits & (is_zero - 1), r, tp, 3*ecc->size);
+	  cnd_copy (bits & (is_zero - 1), r, tp, 3*ecc->p.size);
 	  is_zero &= (bits == 0);
 	}
     }
diff --git a/ecc-pm1-redc.c b/ecc-pm1-redc.c
index 02231f729d31894c635cef84352b1c54d46235d5..6e742e9e280a60fb06bbeab8d61298b4d0d346cf 100644
--- a/ecc-pm1-redc.c
+++ b/ecc-pm1-redc.c
@@ -46,25 +46,23 @@ 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;
+  unsigned shift = ecc->p.size * GMP_NUMB_BITS - ecc->p.bit_size;
+  mp_size_t k = ecc->p.redc_size;
   
-  assert (k > 0);
-
-  for (i = 0; i < ecc->size; i++)
+  for (i = 0; i < ecc->p.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);
+			  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);
   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]
+      hi = (rp[ecc->p.size - 1] >> (GMP_NUMB_BITS - shift));
+      rp[ecc->p.size - 1] = (rp[ecc->p.size - 1]
 			   & (((mp_limb_t) 1 << (GMP_NUMB_BITS - shift)) - 1))
-	+ mpn_addmul_1 (rp, ecc->Bmodp_shifted, ecc->size-1, hi);
+	+ mpn_addmul_1 (rp, ecc->p.B_shifted, ecc->p.size-1, hi);
     }
 }
diff --git a/ecc-point-mul-g.c b/ecc-point-mul-g.c
index 7485fa2c0e48cba6dd1b46764f459542af1254be..46fceb81ea459472776d496d01cfa8f486a5c63e 100644
--- a/ecc-point-mul-g.c
+++ b/ecc-point-mul-g.c
@@ -46,7 +46,7 @@ ecc_point_mul_g (struct ecc_point *r, const struct ecc_scalar *n)
 {
   TMP_DECL(scratch, mp_limb_t, 3*ECC_MAX_SIZE + ECC_MUL_G_ITCH (ECC_MAX_SIZE));
   const struct ecc_curve *ecc = r->ecc;
-  mp_limb_t size = ecc->size;
+  mp_limb_t size = ecc->p.size;
   mp_size_t itch = 3*size + ecc->mul_g_itch;
 
   assert (n->ecc == ecc);
diff --git a/ecc-point-mul.c b/ecc-point-mul.c
index d2ba9e8385feff85832c43b249d165b3f6c61ca7..2be1c5c41d3d139e3d3bf206082769cf09fb1db2 100644
--- a/ecc-point-mul.c
+++ b/ecc-point-mul.c
@@ -45,7 +45,7 @@ ecc_point_mul (struct ecc_point *r, const struct ecc_scalar *n,
 	       const struct ecc_point *p)
 {
   const struct ecc_curve *ecc = r->ecc;
-  mp_limb_t size = ecc->size;
+  mp_limb_t size = ecc->p.size;
   mp_size_t itch = 3*size + ecc->mul_itch;
   mp_limb_t *scratch = gmp_alloc_limbs (itch);
 
diff --git a/ecc-point.c b/ecc-point.c
index 59d2372be7393380ed6edced589a6570d7ecfbda..31e3115abbbc39dc7508e8a3aea72c90e527e455 100644
--- a/ecc-point.c
+++ b/ecc-point.c
@@ -42,13 +42,13 @@ void
 ecc_point_init (struct ecc_point *p, const struct ecc_curve *ecc)
 {
   p->ecc = ecc;
-  p->p = gmp_alloc_limbs (2*ecc->size);
+  p->p = gmp_alloc_limbs (2*ecc->p.size);
 }
 
 void
 ecc_point_clear (struct ecc_point *p)
 {
-  gmp_free_limbs (p->p, 2*p->ecc->size);
+  gmp_free_limbs (p->p, 2*p->ecc->p.size);
 }
 
 int
@@ -59,10 +59,10 @@ ecc_point_set (struct ecc_point *p, const mpz_t x, const mpz_t y)
   mpz_t t;
   int res;
 
-  size = p->ecc->size;
+  size = p->ecc->p.size;
   
-  if (mpz_sgn (x) < 0 || mpz_limbs_cmp (x, p->ecc->p, size) >= 0
-      || mpz_sgn (y) < 0 || mpz_limbs_cmp (y, p->ecc->p, size) >= 0)
+  if (mpz_sgn (x) < 0 || mpz_limbs_cmp (x, p->ecc->p.m, size) >= 0
+      || mpz_sgn (y) < 0 || mpz_limbs_cmp (y, p->ecc->p.m, size) >= 0)
     return 0;
 
   mpz_init (lhs);
@@ -70,7 +70,7 @@ ecc_point_set (struct ecc_point *p, const mpz_t x, const mpz_t y)
 
   mpz_mul (lhs, y, y);
   
-  if (p->ecc->bit_size == 255)
+  if (p->ecc->p.bit_size == 255)
     {
       /* ed25519 special case. FIXME: Do in some cleaner way? */
       mpz_t x2;
@@ -94,7 +94,7 @@ ecc_point_set (struct ecc_point *p, const mpz_t x, const mpz_t y)
       mpz_add (rhs, rhs, mpz_roinit_n (t, p->ecc->b, size));
     }
 
-  res = mpz_congruent_p (lhs, rhs, mpz_roinit_n (t, p->ecc->p, size));
+  res = mpz_congruent_p (lhs, rhs, mpz_roinit_n (t, p->ecc->p.m, size));
 
   mpz_clear (lhs);
   mpz_clear (rhs);
@@ -111,7 +111,7 @@ ecc_point_set (struct ecc_point *p, const mpz_t x, const mpz_t y)
 void
 ecc_point_get (const struct ecc_point *p, mpz_t x, mpz_t y)
 {
-  mp_size_t size = p->ecc->size;
+  mp_size_t size = p->ecc->p.size;
   if (x)
     mpz_set_n (x, p->p, size);
   if (y)
diff --git a/ecc-pp1-redc.c b/ecc-pp1-redc.c
index e221611913fe5923a22593821ce80653d4395b16..f631f094262e76bece70010d624159d00e4fc50e 100644
--- a/ecc-pp1-redc.c
+++ b/ecc-pp1-redc.c
@@ -46,26 +46,24 @@ 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;
+  unsigned shift = ecc->p.size * GMP_NUMB_BITS - ecc->p.bit_size;
+  mp_size_t k = ecc->p.redc_size;
   
-  assert (k > 0);
-
-  for (i = 0; i < ecc->size; i++)
+  for (i = 0; i < ecc->p.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);
+			  ecc->p.redc_mpm1, ecc->p.size - k, rp[i]);
+  hi = mpn_add_n (rp, rp, rp + ecc->p.size, ecc->p.size);
   if (shift > 0)
     {
-      hi = (hi << shift) | (rp[ecc->size - 1] >> (GMP_NUMB_BITS - shift));
-      rp[ecc->size - 1] = (rp[ecc->size - 1]
+      hi = (hi << shift) | (rp[ecc->p.size - 1] >> (GMP_NUMB_BITS - shift));
+      rp[ecc->p.size - 1] = (rp[ecc->p.size - 1]
 			   & (((mp_limb_t) 1 << (GMP_NUMB_BITS - shift)) - 1))
-	+ mpn_addmul_1 (rp, ecc->Bmodp_shifted, ecc->size-1, hi);
+	+ mpn_addmul_1 (rp, ecc->p.B_shifted, ecc->p.size-1, hi);
 	  
     }
   else
     {
-      cy = cnd_sub_n (hi, rp, ecc->p, ecc->size);
+      cy = cnd_sub_n (hi, rp, ecc->p.m, ecc->p.size);
       assert (cy == hi);      
     }
 }
diff --git a/ecc-random.c b/ecc-random.c
index 765908ba124bbaaabd4e5cfe6864777d11a4918d..f3c83f5323e939beeb8f3f73df861d46fe35caa5 100644
--- a/ecc-random.c
+++ b/ecc-random.c
@@ -48,7 +48,7 @@ zero_p (const struct ecc_curve *ecc,
   mp_limb_t t;
   mp_size_t i;
 
-  for (i = t = 0; i < ecc->size; i++)
+  for (i = t = 0; i < ecc->p.size; i++)
     t |= xp[i];
 
   return t == 0;
@@ -60,7 +60,7 @@ ecdsa_in_range (const struct ecc_curve *ecc,
 {
   /* Check if 0 < x < q, with data independent timing. */
   return !zero_p (ecc, xp)
-    & (mpn_sub_n (scratch, xp, ecc->q, ecc->size) != 0);
+    & (mpn_sub_n (scratch, xp, ecc->q.m, ecc->p.size) != 0);
 }
 
 void
@@ -68,19 +68,18 @@ ecc_modq_random (const struct ecc_curve *ecc, mp_limb_t *xp,
 		 void *ctx, nettle_random_func *random, mp_limb_t *scratch)
 {
   uint8_t *buf = (uint8_t *) scratch;
-  unsigned nbytes = (ecc->bit_size + 7)/8;
+  unsigned nbytes = (ecc->q.bit_size + 7)/8;
 
   /* The bytes ought to fit in the scratch area, unless we have very
      unusual limb and byte sizes. */
-  assert (nbytes <= ecc->size * sizeof (mp_limb_t));
+  assert (nbytes <= ecc->p.size * sizeof (mp_limb_t));
 
   do
     {
-      /* q and p are of the same bitsize. */
       random (ctx, nbytes, buf);
-      buf[0] &= 0xff >> (nbytes * 8 - ecc->bit_size);
+      buf[0] &= 0xff >> (nbytes * 8 - ecc->q.bit_size);
 
-      mpn_set_base256 (xp, ecc->size, buf, nbytes);
+      mpn_set_base256 (xp, ecc->p.size, buf, nbytes);
     }
   while (!ecdsa_in_range (ecc, xp, scratch));
 }
@@ -90,7 +89,7 @@ ecc_scalar_random (struct ecc_scalar *x,
 		   void *random_ctx, nettle_random_func *random)
 {
   TMP_DECL (scratch, mp_limb_t, ECC_MODQ_RANDOM_ITCH (ECC_MAX_SIZE));
-  TMP_ALLOC (scratch, ECC_MODQ_RANDOM_ITCH (x->ecc->size));
+  TMP_ALLOC (scratch, ECC_MODQ_RANDOM_ITCH (x->ecc->p.size));
 
   ecc_modq_random (x->ecc, x->p, random_ctx, random, scratch);
 }
diff --git a/ecc-scalar.c b/ecc-scalar.c
index 880bbdf7884363c38e6d44de6da64e5e45397021..2111ea298aaac409e269065231faa1f4f9965a04 100644
--- a/ecc-scalar.c
+++ b/ecc-scalar.c
@@ -42,21 +42,21 @@ void
 ecc_scalar_init (struct ecc_scalar *s, const struct ecc_curve *ecc)
 {
   s->ecc = ecc;
-  s->p = gmp_alloc_limbs (ecc->size);
+  s->p = gmp_alloc_limbs (ecc->p.size);
 }
 
 void
 ecc_scalar_clear (struct ecc_scalar *s)
 {
-  gmp_free_limbs (s->p, s->ecc->size);
+  gmp_free_limbs (s->p, s->ecc->p.size);
 }
 
 int
 ecc_scalar_set (struct ecc_scalar *s, const mpz_t z)
 {
-  mp_size_t size = s->ecc->size;
+  mp_size_t size = s->ecc->p.size;
 
-  if (mpz_sgn (z) <= 0 || mpz_limbs_cmp (z, s->ecc->q, size) >= 0)
+  if (mpz_sgn (z) <= 0 || mpz_limbs_cmp (z, s->ecc->q.m, size) >= 0)
     return 0;
 
   mpz_limbs_copy (s->p, z, size);
@@ -66,5 +66,5 @@ ecc_scalar_set (struct ecc_scalar *s, const mpz_t z)
 void
 ecc_scalar_get (const struct ecc_scalar *s, mpz_t z)
 {
-  mpz_set_n (z, s->p, s->ecc->size);  
+  mpz_set_n (z, s->p, s->ecc->p.size);  
 }
diff --git a/ecc-size.c b/ecc-size.c
index 6e29c8c2b446b5d39b14e8fe3f9e2aa590c2ca13..38b59139c20cd32624938ea46767de7ba85fbda3 100644
--- a/ecc-size.c
+++ b/ecc-size.c
@@ -41,23 +41,23 @@
 unsigned
 ecc_bit_size (const struct ecc_curve *ecc)
 {
-  return ecc->bit_size;
+  return ecc->p.bit_size;
 }
 
 mp_size_t
 ecc_size (const struct ecc_curve *ecc)
 {
-  return ecc->size;
+  return ecc->p.size;
 }
 
 mp_size_t
 ecc_size_a (const struct ecc_curve *ecc)
 {
-  return 2*ecc->size;
+  return 2*ecc->p.size;
 }
 
 mp_size_t
 ecc_size_j (const struct ecc_curve *ecc)
 {
-  return 3*ecc->size;
+  return 3*ecc->p.size;
 }
diff --git a/ecdsa-keygen.c b/ecdsa-keygen.c
index d5b55256ca7e77a93b8f05c4aa50d825d813d01b..ec3ecfdc8022a21ebfdf4484b2f30c2af5829378 100644
--- a/ecdsa-keygen.c
+++ b/ecdsa-keygen.c
@@ -49,13 +49,13 @@ ecdsa_generate_keypair (struct ecc_point *pub,
 {
   TMP_DECL(p, mp_limb_t, 3*ECC_MAX_SIZE + ECC_MUL_G_ITCH (ECC_MAX_SIZE));
   const struct ecc_curve *ecc = pub->ecc;
-  mp_size_t itch = 3*ecc->size + ecc->mul_g_itch;
+  mp_size_t itch = 3*ecc->p.size + ecc->mul_g_itch;
 
   assert (key->ecc == ecc);
 
   TMP_ALLOC (p, itch);
 
   ecc_modq_random (ecc, key->p, random_ctx, random, p);
-  ecc->mul_g (ecc, p, key->p, p + 3*ecc->size);
-  ecc->h_to_a (ecc, 0, pub->p, p, p + 3*ecc->size);
+  ecc->mul_g (ecc, p, key->p, p + 3*ecc->p.size);
+  ecc->h_to_a (ecc, 0, pub->p, p, p + 3*ecc->p.size);
 }
diff --git a/ecdsa-sign.c b/ecdsa-sign.c
index 623827e5b28e13a82c1452ae2cb81a5bd102a569..11987eea35e51d51ee533cf5d3e90750d377cb19 100644
--- a/ecdsa-sign.c
+++ b/ecdsa-sign.c
@@ -51,7 +51,7 @@ ecdsa_sign (const struct ecc_scalar *key,
 {
   /* At most 936 bytes. */
   TMP_DECL(k, mp_limb_t, ECC_MAX_SIZE + ECC_ECDSA_SIGN_ITCH (ECC_MAX_SIZE));
-  mp_limb_t size = key->ecc->size;
+  mp_limb_t size = key->ecc->p.size;
   mp_limb_t *rp = mpz_limbs_write (signature->r, size);
   mp_limb_t *sp = mpz_limbs_write (signature->s, size);
 
diff --git a/examples/ecc-benchmark.c b/examples/ecc-benchmark.c
index 89ef2f54b41630351a98cc206fff8393a55ff8ff..858acc821b38de3f6e3341927bf01b0b78f57bbc 100644
--- a/examples/ecc-benchmark.c
+++ b/examples/ecc-benchmark.c
@@ -113,7 +113,7 @@ static int
 modinv_gcd (const struct ecc_curve *ecc,
 	    mp_limb_t *rp, mp_limb_t *ap, mp_limb_t *tp)
 {
-  mp_size_t size = ecc->size;
+  mp_size_t size = ecc->p.size;
   mp_limb_t *up = tp;
   mp_limb_t *vp = tp + size+1;
   mp_limb_t *gp = tp + 2*(size+1);
@@ -121,13 +121,13 @@ modinv_gcd (const struct ecc_curve *ecc,
   mp_size_t gn, sn;
 
   mpn_copyi (up, ap, size);
-  mpn_copyi (vp, ecc->p, size);
+  mpn_copyi (vp, ecc->p.m, size);
   gn = mpn_gcdext (gp, sp, &sn, up, size, vp, size);
   if (gn != 1 || gp[0] != 1)
     return 0;
   
   if (sn < 0)
-    mpn_sub (sp, ecc->p, size, sp, -sn);
+    mpn_sub (sp, ecc->p.m, size, sp, -sn);
   else if (sn < size)
     /* Zero-pad. */
     mpn_zero (sp + sn, size - sn);
@@ -149,7 +149,7 @@ static void
 bench_modp (void *p)
 {
   struct ecc_ctx *ctx = (struct ecc_ctx *) p;
-  mpn_copyi (ctx->rp, ctx->ap, 2*ctx->ecc->size);
+  mpn_copyi (ctx->rp, ctx->ap, 2*ctx->ecc->p.size);
   ctx->ecc->modp (ctx->ecc, ctx->rp);
 }
 
@@ -157,7 +157,7 @@ static void
 bench_redc (void *p)
 {
   struct ecc_ctx *ctx = (struct ecc_ctx *) p;
-  mpn_copyi (ctx->rp, ctx->ap, 2*ctx->ecc->size);
+  mpn_copyi (ctx->rp, ctx->ap, 2*ctx->ecc->p.size);
   ctx->ecc->redc (ctx->ecc, ctx->rp);
 }
 
@@ -165,7 +165,7 @@ static void
 bench_modq (void *p)
 {
   struct ecc_ctx *ctx = (struct ecc_ctx *) p;
-  mpn_copyi (ctx->rp, ctx->ap, 2*ctx->ecc->size);
+  mpn_copyi (ctx->rp, ctx->ap, 2*ctx->ecc->p.size);
   ctx->ecc->modq (ctx->ecc, ctx->rp);
 }
 
@@ -173,8 +173,8 @@ static void
 bench_modinv (void *p)
 {
   struct ecc_ctx *ctx = (struct ecc_ctx *) p;
-  mpn_copyi (ctx->rp + ctx->ecc->size, ctx->ap, ctx->ecc->size);
-  ecc_modp_inv (ctx->ecc, ctx->rp, ctx->rp + ctx->ecc->size, ctx->tp);
+  mpn_copyi (ctx->rp + ctx->ecc->p.size, ctx->ap, ctx->ecc->p.size);
+  ecc_modp_inv (ctx->ecc, ctx->rp, ctx->rp + ctx->ecc->p.size, ctx->tp);
 }
 
 #if !NETTLE_USE_MINI_GMP
@@ -182,8 +182,8 @@ static void
 bench_modinv_gcd (void *p)
 {
   struct ecc_ctx *ctx = (struct ecc_ctx *) p;
-  mpn_copyi (ctx->rp + ctx->ecc->size, ctx->ap, ctx->ecc->size);
-  modinv_gcd (ctx->ecc, ctx->rp, ctx->rp + ctx->ecc->size, ctx->tp);  
+  mpn_copyi (ctx->rp + ctx->ecc->p.size, ctx->ap, ctx->ecc->p.size);
+  modinv_gcd (ctx->ecc, ctx->rp, ctx->rp + ctx->ecc->p.size, ctx->tp);  
 }
 #endif
 
@@ -193,7 +193,7 @@ bench_modinv_powm (void *p)
 {
   struct ecc_ctx *ctx = (struct ecc_ctx *) p;
   const struct ecc_curve *ecc = ctx->ecc;
-  mp_size_t size = ecc->size;
+  mp_size_t size = ecc->p.size;
   
   mpn_sub_1 (ctx->rp + size, ecc->p, size, 2);
   mpn_sec_powm (ctx->rp, ctx->ap, size,
@@ -273,30 +273,30 @@ bench_curve (const struct ecc_curve *ecc)
   mp_size_t itch;
 
   ctx.ecc = ecc;
-  ctx.rp = xalloc_limbs (3*ecc->size);
-  ctx.ap = xalloc_limbs (3*ecc->size);
-  ctx.bp = xalloc_limbs (3*ecc->size);
+  ctx.rp = xalloc_limbs (3*ecc->p.size);
+  ctx.ap = xalloc_limbs (3*ecc->p.size);
+  ctx.bp = xalloc_limbs (3*ecc->p.size);
   itch = ecc->mul_itch;
 #ifdef mpn_sec_powm
   {
     mp_size_t powm_itch
-      = mpn_sec_powm_itch (ecc->size, ecc->bit_size, ecc->size);
+      = mpn_sec_powm_itch (ecc->p.size, ecc->bit_size, ecc->p.size);
     if (powm_itch > itch)
       itch = powm_itch;
   }
 #endif
   ctx.tp = xalloc_limbs (itch);
 
-  mpn_random (ctx.ap, 3*ecc->size);
-  mpn_random (ctx.bp, 3*ecc->size);
+  mpn_random (ctx.ap, 3*ecc->p.size);
+  mpn_random (ctx.bp, 3*ecc->p.size);
 
-  mask = (~(mp_limb_t) 0) >> (ecc->size * GMP_NUMB_BITS - ecc->bit_size);
-  ctx.ap[ecc->size - 1] &= mask;
-  ctx.ap[2*ecc->size - 1] &= mask;
-  ctx.ap[3*ecc->size - 1] &= mask;
-  ctx.bp[ecc->size - 1] &= mask;
-  ctx.bp[2*ecc->size - 1] &= mask;
-  ctx.bp[3*ecc->size - 1] &= mask;
+  mask = (~(mp_limb_t) 0) >> (ecc->p.size * GMP_NUMB_BITS - ecc->p.bit_size);
+  ctx.ap[ecc->p.size - 1] &= mask;
+  ctx.ap[2*ecc->p.size - 1] &= mask;
+  ctx.ap[3*ecc->p.size - 1] &= mask;
+  ctx.bp[ecc->p.size - 1] &= mask;
+  ctx.bp[2*ecc->p.size - 1] &= mask;
+  ctx.bp[3*ecc->p.size - 1] &= mask;
 
   modp = time_function (bench_modp, &ctx);
   redc = ecc->redc ? time_function (bench_redc, &ctx) : 0;
@@ -314,7 +314,7 @@ bench_curve (const struct ecc_curve *ecc)
 #else
   modinv_powm = 0;
 #endif
-  if (ecc->bit_size == 255)
+  if (ecc->p.bit_size == 255)
     {
       /* For now, curve25519 is a special case */
       dup_jj = time_function (bench_dup_eh, &ctx);
@@ -335,7 +335,7 @@ bench_curve (const struct ecc_curve *ecc)
   free (ctx.tp);
 
   printf ("%4d %6.4f %6.4f %6.4f %6.2f %6.3f %6.2f %6.3f %6.3f %6.3f %6.1f %6.1f\n",
-	  ecc->bit_size, 1e6 * modp, 1e6 * redc, 1e6 * modq,
+	  ecc->p.bit_size, 1e6 * modp, 1e6 * redc, 1e6 * modq,
 	  1e6 * modinv, 1e6 * modinv_gcd, 1e6 * modinv_powm,
 	  1e6 * dup_jj, 1e6 * add_jja, 1e6 * add_hhh,
 	  1e6 * mul_g, 1e6 * mul_a);
diff --git a/testsuite/ecc-add-test.c b/testsuite/ecc-add-test.c
index 0fccb71c823b4e554146ee118e55c7609d736874..54fae31fa155857a9ae820348647bd6b68101202 100644
--- a/testsuite/ecc-add-test.c
+++ b/testsuite/ecc-add-test.c
@@ -12,14 +12,14 @@ test_main (void)
       mp_limb_t *g2 = xalloc_limbs (ecc_size_j (ecc));
       mp_limb_t *g3 = xalloc_limbs (ecc_size_j (ecc));
       mp_limb_t *p = xalloc_limbs (ecc_size_j (ecc));
-      mp_limb_t *scratch = xalloc_limbs (ECC_ADD_JJJ_ITCH(ecc->size));
+      mp_limb_t *scratch = xalloc_limbs (ECC_ADD_JJJ_ITCH(ecc->p.size));
 
-      if (ecc->bit_size == 255)
+      if (ecc->p.bit_size == 255)
 	{
 	  mp_limb_t *z = xalloc_limbs (ecc_size_j (ecc));
 	  /* Zero point has x = 0, y = 1, z = 1 */
-	  mpn_zero (z, 3*ecc->size);
-	  z[ecc->size] = z[2*ecc->size] = 1;
+	  mpn_zero (z, 3*ecc->p.size);
+	  z[ecc->p.size] = z[2*ecc->p.size] = 1;
 	  
 	  ecc_a_to_j (ecc, g, ecc->g);
 
diff --git a/testsuite/ecc-dup-test.c b/testsuite/ecc-dup-test.c
index 82c31e75cf7dbdd0b4aef360259dd8e1188c54b8..b92352c111387964ca6955f1487afc536e817f29 100644
--- a/testsuite/ecc-dup-test.c
+++ b/testsuite/ecc-dup-test.c
@@ -10,14 +10,14 @@ test_main (void)
       const struct ecc_curve *ecc = ecc_curves[i];
       mp_limb_t *g = xalloc_limbs (ecc_size_j (ecc));
       mp_limb_t *p = xalloc_limbs (ecc_size_j (ecc));
-      mp_limb_t *scratch = xalloc_limbs (ECC_DUP_EH_ITCH(ecc->size));;
+      mp_limb_t *scratch = xalloc_limbs (ECC_DUP_EH_ITCH(ecc->p.size));;
 
-      if (ecc->bit_size == 255)
+      if (ecc->p.bit_size == 255)
 	{
 	  mp_limb_t *z = xalloc_limbs (ecc_size_j (ecc));
 	  /* Zero point has x = 0, y = 1, z = 1 */
-	  mpn_zero (z, 3*ecc->size);
-	  z[ecc->size] = z[2*ecc->size] = 1;
+	  mpn_zero (z, 3*ecc->p.size);
+	  z[ecc->p.size] = z[2*ecc->p.size] = 1;
 	  
 	  ecc_a_to_j (ecc, g, ecc->g);
 
diff --git a/testsuite/ecc-mod-test.c b/testsuite/ecc-mod-test.c
index c8af4a722b6a19fc4c1e04acb58a1decb9e3ade1..4787368d654e9e1580111e87eecf943ae65045e6 100644
--- a/testsuite/ecc-mod-test.c
+++ b/testsuite/ecc-mod-test.c
@@ -33,77 +33,77 @@ test_curve (gmp_randstate_t rands, const struct ecc_curve *ecc)
   for (j = 0; j < COUNT; j++)
     {
       if (j & 1)
-	mpz_rrandomb (r, rands, 2*ecc->size * GMP_NUMB_BITS);
+	mpz_rrandomb (r, rands, 2*ecc->p.size * GMP_NUMB_BITS);
       else
-	mpz_urandomb (r, rands, 2*ecc->size * GMP_NUMB_BITS);
+	mpz_urandomb (r, rands, 2*ecc->p.size * GMP_NUMB_BITS);
 
-      mpz_limbs_copy (a, r, 2*ecc->size);
+      mpz_limbs_copy (a, r, 2*ecc->p.size);
 
-      ref_mod (ref, a, ecc->p, ecc->size);
+      ref_mod (ref, a, ecc->p.m, ecc->p.size);
 
-      mpn_copyi (m, a, 2*ecc->size);
+      mpn_copyi (m, a, 2*ecc->p.size);
       ecc->modp (ecc, m);
-      if (mpn_cmp (m, ecc->p, ecc->size) >= 0)
-	mpn_sub_n (m, m, ecc->p, ecc->size);
+      if (mpn_cmp (m, ecc->p.m, ecc->p.size) >= 0)
+	mpn_sub_n (m, m, ecc->p.m, ecc->p.size);
 
-      if (mpn_cmp (m, ref, ecc->size))
+      if (mpn_cmp (m, ref, ecc->p.size))
 	{
 	  fprintf (stderr, "ecc->modp failed: bit_size = %u\n",
-		   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);
+		   ecc->p.bit_size);
+	  gmp_fprintf (stderr, "a   = %Nx\n", a, 2*ecc->p.size);
+	  gmp_fprintf (stderr, "m   = %Nx (bad)\n", m, ecc->p.size);
+	  gmp_fprintf (stderr, "ref = %Nx\n", ref, ecc->p.size);
 	  abort ();
 	}
 
-      if (ecc->Bmodp_size < ecc->size)
+      if (ecc->p.B_size < ecc->p.size)
 	{
-	  mpn_copyi (m, a, 2*ecc->size);
+	  mpn_copyi (m, a, 2*ecc->p.size);
 	  ecc_generic_modp (ecc, m);
-	  if (mpn_cmp (m, ecc->p, ecc->size) >= 0)
-	    mpn_sub_n (m, m, ecc->p, ecc->size);
+	  if (mpn_cmp (m, ecc->p.m, ecc->p.size) >= 0)
+	    mpn_sub_n (m, m, ecc->p.m, ecc->p.size);
 
-	  if (mpn_cmp (m, ref, ecc->size))
+	  if (mpn_cmp (m, ref, ecc->p.size))
 	    {
 	      fprintf (stderr, "ecc_generic_modp failed: bit_size = %u\n",
-		       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);
+		       ecc->p.bit_size);
+	      gmp_fprintf (stderr, "a   = %Nx\n", a, 2*ecc->p.size);
+	      gmp_fprintf (stderr, "m   = %Nx (bad)\n", m, ecc->p.size);
+	      gmp_fprintf (stderr, "ref = %Nx\n", ref, ecc->p.size);
 	      abort ();
 	    }
 	}
 
-      ref_mod (ref, a, ecc->q, ecc->size);
+      ref_mod (ref, a, ecc->q.m, ecc->p.size);
 
-      mpn_copyi (m, a, 2*ecc->size);
+      mpn_copyi (m, a, 2*ecc->p.size);
       ecc->modq (ecc, m);
-      if (mpn_cmp (m, ecc->q, ecc->size) >= 0)
-	mpn_sub_n (m, m, ecc->q, ecc->size);
+      if (mpn_cmp (m, ecc->q.m, ecc->p.size) >= 0)
+	mpn_sub_n (m, m, ecc->q.m, ecc->p.size);
 
-      if (mpn_cmp (m, ref, ecc->size))
+      if (mpn_cmp (m, ref, ecc->p.size))
 	{
 	  fprintf (stderr, "ecc->modq failed: bit_size = %u\n",
-		   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);
+		   ecc->p.bit_size);
+	  gmp_fprintf (stderr, "a   = %Nx\n", a, 2*ecc->p.size);
+	  gmp_fprintf (stderr, "m   = %Nx (bad)\n", m, ecc->p.size);
+	  gmp_fprintf (stderr, "ref = %Nx\n", ref, ecc->p.size);
 	  abort ();
 	}
-      if (ecc->Bmodq_size < ecc->size)
+      if (ecc->q.B_size < ecc->p.size)
 	{
-	  mpn_copyi (m, a, 2*ecc->size);
+	  mpn_copyi (m, a, 2*ecc->p.size);
 	  ecc_generic_modq (ecc, m);
-	  if (mpn_cmp (m, ecc->q, ecc->size) >= 0)
-	    mpn_sub_n (m, m, ecc->q, ecc->size);
+	  if (mpn_cmp (m, ecc->q.m, ecc->p.size) >= 0)
+	    mpn_sub_n (m, m, ecc->q.m, ecc->p.size);
 
-	  if (mpn_cmp (m, ref, ecc->size))
+	  if (mpn_cmp (m, ref, ecc->p.size))
 	    {
-	      fprintf (stderr, "ecc_generic_modp failed: bit_size = %u\n",
-		       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);
+	      fprintf (stderr, "ecc_generic_modq failed: bit_size = %u\n",
+		       ecc->q.bit_size);
+	      gmp_fprintf (stderr, "a   = %Nx\n", a, 2*ecc->p.size);
+	      gmp_fprintf (stderr, "m   = %Nx (bad)\n", m, ecc->p.size);
+	      gmp_fprintf (stderr, "ref = %Nx\n", ref, ecc->p.size);
 	      abort ();
 	    }
 	}
diff --git a/testsuite/ecc-modinv-test.c b/testsuite/ecc-modinv-test.c
index 7324880a7a056a09bfea78954894340fe055b1e7..734700c6bb3348868713cefe2056ea1a8997e44d 100644
--- a/testsuite/ecc-modinv-test.c
+++ b/testsuite/ecc-modinv-test.c
@@ -56,86 +56,86 @@ test_main (void)
       const struct ecc_curve *ecc = ecc_curves[i];
       unsigned j;
       /* Check behaviour for zero input */
-      mpn_zero (a, ecc->size);
-      memset (ai, 17, ecc->size * sizeof(*ai));
+      mpn_zero (a, ecc->p.size);
+      memset (ai, 17, ecc->p.size * sizeof(*ai));
       ecc_modp_inv (ecc, ai, a, scratch);
-      if (!mpn_zero_p (ai, ecc->size))
+      if (!mpn_zero_p (ai, ecc->p.size))
 	{
 	  fprintf (stderr, "ecc_modp_inv failed for zero input (bit size %u):\n",
-		       ecc->bit_size);
+		       ecc->p.bit_size);
 	  gmp_fprintf (stderr, "p = %Nx\n"
 		       "t = %Nx (bad)\n",
-		       ecc->p, ecc->size,
-		       ai, ecc->size);
+		       ecc->p.m, ecc->p.size,
+		       ai, ecc->p.size);
 	  abort ();
 	}
 	  
       /* Check behaviour for a = p */
-      mpn_copyi (a, ecc->p, ecc->size);
-      memset (ai, 17, ecc->size * sizeof(*ai));
+      mpn_copyi (a, ecc->p.m, ecc->p.size);
+      memset (ai, 17, ecc->p.size * sizeof(*ai));
       ecc_modp_inv (ecc, ai, a, scratch);
-      if (!mpn_zero_p (ai, ecc->size))
+      if (!mpn_zero_p (ai, ecc->p.size))
 	{
 	  fprintf (stderr, "ecc_modp_inv failed for a = p input (bit size %u):\n",
-		       ecc->bit_size);
+		       ecc->p.bit_size);
 	  gmp_fprintf (stderr, "p = %Nx\n"
 		       "t = %Nx (bad)\n",
-		       ecc->p, ecc->size,
-		       ai, ecc->size);
+		       ecc->p.m, ecc->p.size,
+		       ai, ecc->p.size);
 	  abort ();
 	}
 	
       for (j = 0; j < COUNT; j++)
 	{
 	  if (j & 1)
-	    mpz_rrandomb (r, rands, ecc->size * GMP_NUMB_BITS);
+	    mpz_rrandomb (r, rands, ecc->p.size * GMP_NUMB_BITS);
 	  else
-	    mpz_urandomb (r, rands, ecc->size * GMP_NUMB_BITS);
+	    mpz_urandomb (r, rands, ecc->p.size * GMP_NUMB_BITS);
 
-	  mpz_limbs_copy (a, r, ecc->size);
+	  mpz_limbs_copy (a, r, ecc->p.size);
 
-	  if (!ref_modinv (ref, a, ecc->p, ecc->size))
+	  if (!ref_modinv (ref, a, ecc->p.m, ecc->p.size))
 	    {
 	      if (verbose)
 		fprintf (stderr, "Test %u (bit size %u) not invertible.\n",
-			 j, ecc->bit_size);
+			 j, ecc->p.bit_size);
 	      continue;
 	    }
 	  ecc_modp_inv (ecc, ai, a, scratch);
-	  if (mpn_cmp (ref, ai, ecc->size))
+	  if (mpn_cmp (ref, ai, ecc->p.size))
 	    {
 	      fprintf (stderr, "ecc_modp_inv failed (test %u, bit size %u):\n",
-		       j, ecc->bit_size);
+		       j, ecc->p.bit_size);
 	      gmp_fprintf (stderr, "a = %Zx\n"
 			   "p = %Nx\n"
 			   "t = %Nx (bad)\n"
 			   "r = %Nx\n",
-			   r, ecc->p, ecc->size,
-			   ai, ecc->size,
-			   ref, ecc->size);
+			   r, ecc->p.m, ecc->p.size,
+			   ai, ecc->p.size,
+			   ref, ecc->p.size);
 	      abort ();
 	    }
 
-	  mpz_limbs_copy (a, r, ecc->size);
+	  mpz_limbs_copy (a, r, ecc->p.size);
 
-	  if (!ref_modinv (ref, a, ecc->q, ecc->size))
+	  if (!ref_modinv (ref, a, ecc->q.m, ecc->p.size))
 	    {
 	      fprintf (stderr, "Test %u (bit size %u) not invertible.\n",
-		       j, ecc->bit_size);
+		       j, ecc->q.bit_size);
 	      continue;
 	    }
 	  ecc_modq_inv (ecc, ai, a, scratch);
-	  if (mpn_cmp (ref, ai, ecc->size))
+	  if (mpn_cmp (ref, ai, ecc->p.size))
 	    {
 	      fprintf (stderr, "ecc_modq_inv failed (test %u, bit size %u):\n",
-		       j, ecc->bit_size);
+		       j, ecc->q.bit_size);
 	      gmp_fprintf (stderr, "a = %Zx\n"
 			   "p = %Nx\n"
 			   "t = %Nx (bad)\n"
 			   "r = %Nx\n",
-			   r, ecc->p, ecc->size,
-			   ai, ecc->size,
-			   ref, ecc->size);
+			   r, ecc->p.m, ecc->p.size,
+			   ai, ecc->p.size,
+			   ref, ecc->p.size);
 	      abort ();
 	    }
 	}
diff --git a/testsuite/ecc-mul-a-test.c b/testsuite/ecc-mul-a-test.c
index 87de873b7b8fea260cf2f67ffbdf151cbbf6a751..e1958a1e106d6b157f7fed6ca38f35d3f8cbf3a8 100644
--- a/testsuite/ecc-mul-a-test.c
+++ b/testsuite/ecc-mul-a-test.c
@@ -35,7 +35,7 @@ test_main (void)
       ecc->h_to_a (ecc, 0, p, p, scratch);
 
       if (mpn_cmp (p, ecc->g, 2*size != 0))
-	die ("curve %d: ecc->mul with n = 1 failed.\n", ecc->bit_size);
+	die ("curve %d: ecc->mul with n = 1 failed.\n", ecc->p.bit_size);
 
       for (n[0] = 2; n[0] <= 4; n[0]++)
 	{
@@ -44,15 +44,15 @@ test_main (void)
 	}
 
       /* (order - 1) * g = - g */
-      mpn_sub_1 (n, ecc->q, size, 1);
+      mpn_sub_1 (n, ecc->q.m, size, 1);
       ecc->mul (ecc, p, n, ecc->g, scratch);
       ecc->h_to_a (ecc, 0, p, p, scratch);
-      if (ecc->bit_size == 255)
+      if (ecc->p.bit_size == 255)
 	/* For edwards curves, - (x,y ) == (-x, y). FIXME: Swap x and
 	   y, to get identical negation? */
-	mpn_sub_n (p, ecc->p, p, size);
+	mpn_sub_n (p, ecc->p.m, p, size);
       else
-	mpn_sub_n (p + size, ecc->p, p + size, size);
+	mpn_sub_n (p + size, ecc->p.m, p + size, size);
       if (mpn_cmp (p, ecc->g, 2*size) != 0)
 	{
 	  fprintf (stderr, "ecc->mul with n = order - 1 failed.\n");
@@ -70,7 +70,7 @@ test_main (void)
 
 	  /* Reduce so that (almost surely) n < q */
 	  mpz_limbs_copy (n, r, size);
-	  n[size - 1] %= ecc->q[size - 1];
+	  n[size - 1] %= ecc->q.m[size - 1];
 
 	  ecc->mul (ecc, p, n, ecc->g, scratch);
 	  ecc->h_to_a (ecc, 0, p, p, scratch);
@@ -84,7 +84,7 @@ test_main (void)
 			   "Different results from ecc->mul and ecc->mul_g.\n"
 			   " bits = %u\n"
 			   " n = %Nx\n",
-			   ecc->bit_size, n, size);
+			   ecc->p.bit_size, n, size);
 	      gmp_fprintf (stderr, "p = %Nx,\n    %Nx\n",
 			   p, size, p + size, size);
 	      gmp_fprintf (stderr, "q = %Nx,\n    %Nx\n",
diff --git a/testsuite/ecc-mul-g-test.c b/testsuite/ecc-mul-g-test.c
index 64d3191b1b1b00a6fa5051e59edef0a834cad04e..fbd082aa17c73407caea42c839fe626193158639 100644
--- a/testsuite/ecc-mul-g-test.c
+++ b/testsuite/ecc-mul-g-test.c
@@ -46,15 +46,15 @@ test_main (void)
 	}
 
       /* (order - 1) * g = - g */
-      mpn_sub_1 (n, ecc->q, size, 1);
+      mpn_sub_1 (n, ecc->q.m, size, 1);
       ecc->mul_g (ecc, p, n, scratch);
       ecc->h_to_a (ecc, 0, p, p, scratch);
-      if (ecc->bit_size == 255)
+      if (ecc->p.bit_size == 255)
 	/* For edwards curves, - (x,y ) == (-x, y). FIXME: Swap x and
 	   y, to get identical negation? */
-	mpn_sub_n (p, ecc->p, p, size);
+	mpn_sub_n (p, ecc->p.m, p, size);
       else
-	mpn_sub_n (p + size, ecc->p, p + size, size);
+	mpn_sub_n (p + size, ecc->p.m, p + size, size);
       if (mpn_cmp (p, ecc->g, 2*size) != 0)
 	{
 	  fprintf (stderr, "ecc->mul_g with n = order - 1 failed.\n");
diff --git a/testsuite/ecc-redc-test.c b/testsuite/ecc-redc-test.c
index 538cd5f0b2f18b6d98d65b09045191de3fd12858..1fa61b3fb0f47c975e96abac2411174c19f90c40 100644
--- a/testsuite/ecc-redc-test.c
+++ b/testsuite/ecc-redc-test.c
@@ -59,49 +59,50 @@ test_main (void)
       unsigned j;
       if (!ecc->redc)
 	continue;
+      ASSERT (ecc->p.redc_size != 0);
 
       for (j = 0; j < COUNT; j++)
 	{
 	  if (j & 1)
-	    mpz_rrandomb (r, rands, 2*ecc->size * GMP_NUMB_BITS);
+	    mpz_rrandomb (r, rands, 2*ecc->p.size * GMP_NUMB_BITS);
 	  else
-	    mpz_urandomb (r, rands, 2*ecc->size * GMP_NUMB_BITS);
+	    mpz_urandomb (r, rands, 2*ecc->p.size * GMP_NUMB_BITS);
 
-	  mpz_limbs_copy (a, r, 2*ecc->size);
+	  mpz_limbs_copy (a, r, 2*ecc->p.size);
 
-	  ref_redc (ref, a, ecc->p, ecc->size);
+	  ref_redc (ref, a, ecc->p.m, ecc->p.size);
 
-	  mpn_copyi (m, a, 2*ecc->size);
+	  mpn_copyi (m, a, 2*ecc->p.size);
 	  ecc->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, ecc->p.m, ecc->p.size) >= 0)
+	    mpn_sub_n (m, m, ecc->p.m, ecc->p.size);
 
-	  if (mpn_cmp (m, ref, ecc->size))
+	  if (mpn_cmp (m, ref, ecc->p.size))
 	    {
 	      fprintf (stderr, "ecc->redc failed: bit_size = %u\n",
-		       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);
+		       ecc->p.bit_size);
+	      gmp_fprintf (stderr, "a   = %Nx\n", a, 2*ecc->p.size);
+	      gmp_fprintf (stderr, "m   = %Nx (bad)\n", m, ecc->p.size);
+	      gmp_fprintf (stderr, "ref = %Nx\n", ref, ecc->p.size);
 	      abort ();
 	    }
 
-	  mpn_copyi (m, a, 2*ecc->size);
-	  if (ecc->redc_size > 0)
-	    ecc_pp1_redc (ecc, m);
-	  else
+	  mpn_copyi (m, a, 2*ecc->p.size);
+	  if (ecc->p.m[0] == 1)
 	    ecc_pm1_redc (ecc, m);
+	  else
+	    ecc_pp1_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, ecc->p.m, ecc->p.size) >= 0)
+	    mpn_sub_n (m, m, ecc->p.m, ecc->p.size);
 
-	  if (mpn_cmp (m, ref, ecc->size))
+	  if (mpn_cmp (m, ref, ecc->p.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);
+		       (ecc->p.m[0] == 1) ? 'm' : 'p', ecc->p.bit_size);
+	      gmp_fprintf (stderr, "a   = %Nx\n", a, 2*ecc->p.size);
+	      gmp_fprintf (stderr, "m   = %Nx (bad)\n", m, ecc->p.size);
+	      gmp_fprintf (stderr, "ref = %Nx\n", ref, ecc->p.size);
 	      abort ();
 	    }
 	}
diff --git a/testsuite/ecdsa-keygen-test.c b/testsuite/ecdsa-keygen-test.c
index c74eb608e840f9061b73ca4cee88d0453d4b8784..a96c09effeef6c7a679513b2e71fcc1ae6a230e3 100644
--- a/testsuite/ecdsa-keygen-test.c
+++ b/testsuite/ecdsa-keygen-test.c
@@ -10,11 +10,11 @@ ecc_valid_p (struct ecc_point *pub)
   int res;
   mp_size_t size;
 
-  size = pub->ecc->size;
+  size = pub->ecc->p.size;
 
   /* First check range */
-  if (mpn_cmp (pub->p, pub->ecc->p, size) >= 0
-      || mpn_cmp (pub->p + size, pub->ecc->p, size) >= 0)
+  if (mpn_cmp (pub->p, pub->ecc->p.m, size) >= 0
+      || mpn_cmp (pub->p + size, pub->ecc->p.m, size) >= 0)
     return 0;
 
   mpz_init (lhs);
@@ -25,7 +25,7 @@ ecc_valid_p (struct ecc_point *pub)
 
   mpz_mul (lhs, y, y);
   
-  if (pub->ecc->bit_size == 255)
+  if (pub->ecc->p.bit_size == 255)
     {
       /* Check that
 	 121666 (1 + x^2 - y^2) = 121665 x^2 y^2 */
@@ -48,7 +48,7 @@ ecc_valid_p (struct ecc_point *pub)
       mpz_mul (rhs, rhs, x);
       mpz_add (rhs, rhs, mpz_roinit_n (t, pub->ecc->b, size));
     }
-  res = mpz_congruent_p (lhs, rhs, mpz_roinit_n (t, pub->ecc->p, size));
+  res = mpz_congruent_p (lhs, rhs, mpz_roinit_n (t, pub->ecc->p.m, size));
   
   mpz_clear (lhs);
   mpz_clear (rhs);
@@ -79,7 +79,7 @@ test_main (void)
       struct ecc_scalar key;
 
       if (verbose)
-	fprintf (stderr, "Curve %d\n", ecc->bit_size);
+	fprintf (stderr, "Curve %d\n", ecc->p.bit_size);
 
       ecc_point_init (&pub, ecc);
       ecc_scalar_init (&key, ecc);
@@ -91,11 +91,11 @@ test_main (void)
       if (verbose)
 	{
 	  fprintf (stderr, "Public key:\nx = ");
-	  write_mpn (stderr, 16, pub.p, ecc->size);
+	  write_mpn (stderr, 16, pub.p, ecc->p.size);
 	  fprintf (stderr, "\ny = ");
-	  write_mpn (stderr, 16, pub.p + ecc->size, ecc->size);
+	  write_mpn (stderr, 16, pub.p + ecc->p.size, ecc->p.size);
 	  fprintf (stderr, "\nPrivate key: ");
-	  write_mpn (stderr, 16, key.p, ecc->size);
+	  write_mpn (stderr, 16, key.p, ecc->p.size);
 	  fprintf (stderr, "\n");
 	}
       if (!ecc_valid_p (&pub))
diff --git a/testsuite/ecdsa-sign-test.c b/testsuite/ecdsa-sign-test.c
index 794ad7219ea8e5f0a7c974fba3c0b0638d5e401c..f111b38c922ca660dc4bf5bdc3bfe0f9726d3a2d 100644
--- a/testsuite/ecdsa-sign-test.c
+++ b/testsuite/ecdsa-sign-test.c
@@ -14,8 +14,8 @@ test_ecdsa (const struct ecc_curve *ecc,
   struct dsa_signature ref;
   mpz_t z;
   mpz_t k;
-  mp_limb_t *rp = xalloc_limbs (ecc->size);
-  mp_limb_t *sp = xalloc_limbs (ecc->size);
+  mp_limb_t *rp = xalloc_limbs (ecc->p.size);
+  mp_limb_t *sp = xalloc_limbs (ecc->p.size);
   mp_limb_t *scratch = xalloc_limbs (ecc_ecdsa_sign_itch (ecc));
 
   dsa_signature_init (&ref);
@@ -23,21 +23,21 @@ test_ecdsa (const struct ecc_curve *ecc,
   mpz_init_set_str (z, sz, 16);
   mpz_init_set_str (k, sk, 16);
 
-  ecc_ecdsa_sign (ecc, mpz_limbs_read_n (z, ecc->size),
-		  mpz_limbs_read_n (k, ecc->size),
+  ecc_ecdsa_sign (ecc, mpz_limbs_read_n (z, ecc->p.size),
+		  mpz_limbs_read_n (k, ecc->p.size),
 		  h->length, h->data, rp, sp, scratch);
 
   mpz_set_str (ref.r, r, 16);
   mpz_set_str (ref.s, s, 16);
 
-  if (mpz_limbs_cmp (ref.r, rp, ecc->size) != 0
-      || mpz_limbs_cmp (ref.s, sp, ecc->size) != 0)
+  if (mpz_limbs_cmp (ref.r, rp, ecc->p.size) != 0
+      || mpz_limbs_cmp (ref.s, sp, ecc->p.size) != 0)
     {
-      fprintf (stderr, "_ecdsa_sign failed, bit_size = %u\n", ecc->bit_size);
+      fprintf (stderr, "_ecdsa_sign failed, bit_size = %u\n", ecc->p.bit_size);
       fprintf (stderr, "r     = ");
-      write_mpn (stderr, 16, rp, ecc->size);
+      write_mpn (stderr, 16, rp, ecc->p.size);
       fprintf (stderr, "\ns     = ");
-      write_mpn (stderr, 16, sp, ecc->size);
+      write_mpn (stderr, 16, sp, ecc->p.size);
       fprintf (stderr, "\nref.r = ");
       mpz_out_str (stderr, 16, ref.r);
       fprintf (stderr, "\nref.s = ");
diff --git a/testsuite/ecdsa-verify-test.c b/testsuite/ecdsa-verify-test.c
index b39dbfdac6682f0a65e87096373400c8c851bdcb..4e0fd80f7ab86d631db614432336be083f1d8ada 100644
--- a/testsuite/ecdsa-verify-test.c
+++ b/testsuite/ecdsa-verify-test.c
@@ -29,7 +29,7 @@ test_ecdsa (const struct ecc_curve *ecc,
     {
       fprintf (stderr, "ecdsa_verify failed with valid signature.\n");
     fail:
-      fprintf (stderr, "bit_size = %u\nx = ", ecc->bit_size);
+      fprintf (stderr, "bit_size = %u\nx = ", ecc->p.bit_size);
       mpz_out_str (stderr, 16, x);
       fprintf (stderr, "\ny = ");
       mpz_out_str (stderr, 16, y);
@@ -43,21 +43,21 @@ test_ecdsa (const struct ecc_curve *ecc,
       abort();
     }
 
-  mpz_combit (signature.r, ecc->bit_size / 3);
+  mpz_combit (signature.r, ecc->p.bit_size / 3);
   if (ecdsa_verify (&pub, h->length, h->data, &signature))
     {
       fprintf (stderr, "ecdsa_verify unexpectedly succeeded with invalid signature.\n");
       goto fail;
     }
-  mpz_combit (signature.r, ecc->bit_size / 3);
+  mpz_combit (signature.r, ecc->p.bit_size / 3);
   
-  mpz_combit (signature.s, 4*ecc->bit_size / 5);
+  mpz_combit (signature.s, 4*ecc->p.bit_size / 5);
   if (ecdsa_verify (&pub, h->length, h->data, &signature))
     {
       fprintf (stderr, "ecdsa_verify unexpectedly succeeded with invalid signature.\n");
       goto fail;
     }
-  mpz_combit (signature.s, 4*ecc->bit_size / 5);
+  mpz_combit (signature.s, 4*ecc->p.bit_size / 5);
 
   h->data[2*h->length / 3] ^= 0x40;
   if (ecdsa_verify (&pub, h->length, h->data, &signature))
diff --git a/testsuite/testutils.c b/testsuite/testutils.c
index c6778e36305e80ea1f3bfa4269a1c39bcea6c2aa..e30f76dac9e81d9b528a6ddfeb1ad9402856fc1c 100644
--- a/testsuite/testutils.c
+++ b/testsuite/testutils.c
@@ -1302,15 +1302,15 @@ test_ecc_point (const struct ecc_curve *ecc,
 		const struct ecc_ref_point *ref,
 		const mp_limb_t *p)
 {
-  if (! (test_mpn (ref->x, p, ecc->size)
-	 && test_mpn (ref->y, p + ecc->size, ecc->size) ))
+  if (! (test_mpn (ref->x, p, ecc->p.size)
+	 && test_mpn (ref->y, p + ecc->p.size, ecc->p.size) ))
     {
       fprintf (stderr, "Incorrect point!\n"
 	       "got: x = ");
-      write_mpn (stderr, 16, p, ecc->size);
+      write_mpn (stderr, 16, p, ecc->p.size);
       fprintf (stderr, "\n"
 	       "     y = ");
-      write_mpn (stderr, 16, p + ecc->size, ecc->size);
+      write_mpn (stderr, 16, p + ecc->p.size, ecc->p.size);
       fprintf (stderr, "\n"
 	       "ref: x = %s\n"
 	       "     y = %s\n",
@@ -1392,16 +1392,16 @@ test_ecc_mul_a (unsigned curve, unsigned n, const mp_limb_t *p)
     {
       /* Makes sense for curve25519 only */
       const struct ecc_curve *ecc = ecc_curves[curve];
-      assert (ecc->bit_size == 255);
-      if (!mpn_zero_p (p, ecc->size)
-	  || mpn_cmp (p + ecc->size, ecc->unit, ecc->size) != 0)
+      assert (ecc->p.bit_size == 255);
+      if (!mpn_zero_p (p, ecc->p.size)
+	  || mpn_cmp (p + ecc->p.size, ecc->unit, ecc->p.size) != 0)
 	{
 	  fprintf (stderr, "Incorrect point (expected (0, 1))!\n"
 		   "got: x = ");
-	  write_mpn (stderr, 16, p, ecc->size);
+	  write_mpn (stderr, 16, p, ecc->p.size);
 	  fprintf (stderr, "\n"
 		   "     y = ");
-	  write_mpn (stderr, 16, p + ecc->size, ecc->size);
+	  write_mpn (stderr, 16, p + ecc->p.size, ecc->p.size);
 	  fprintf (stderr, "\n");
 	  abort();
 	}
@@ -1409,20 +1409,20 @@ test_ecc_mul_a (unsigned curve, unsigned n, const mp_limb_t *p)
   else if (n == 1)
     {
       const struct ecc_curve *ecc = ecc_curves[curve];
-      if (mpn_cmp (p, ecc->g, 2*ecc->size) != 0)
+      if (mpn_cmp (p, ecc->g, 2*ecc->p.size) != 0)
 	{
 	  fprintf (stderr, "Incorrect point (expected g)!\n"
 		   "got: x = ");
-	  write_mpn (stderr, 16, p, ecc->size);
+	  write_mpn (stderr, 16, p, ecc->p.size);
 	  fprintf (stderr, "\n"
 		   "     y = ");
-	  write_mpn (stderr, 16, p + ecc->size, ecc->size);
+	  write_mpn (stderr, 16, p + ecc->p.size, ecc->p.size);
 	  fprintf (stderr, "\n"
 		   "ref: x = ");
-	  write_mpn (stderr, 16, ecc->g, ecc->size);
+	  write_mpn (stderr, 16, ecc->g, ecc->p.size);
 	  fprintf (stderr, "\n"
 		   "     y = ");
-	  write_mpn (stderr, 16, ecc->g + ecc->size, ecc->size);
+	  write_mpn (stderr, 16, ecc->g + ecc->p.size, ecc->p.size);
 	  fprintf (stderr, "\n");
 	  abort();
 	}