...
 
Commits (2)
2020-01-01 Niels Möller <nisse@lysator.liu.se>
* ecc-448.c (ecc_mod_pow_2kp1): New function.
(ecc_mod_pow_446m224m1): Reduce scratch usage from 6*n to 5*n, at
the cost of one copy operation. Also use ecc_mod_pow_2kp1 where
applicable.
(ECC_448_INV_ITCH): Reduce to 5*ECC_LIMB_SIZE.
(ECC_448_SQRT_ITCH): Reduce to 9*ECC_LIMB_SIZE.
* testsuite/eddsa-compress-test.c: Test also with curve448.
2019-12-30 Niels Möller <nisse@lysator.liu.se> 2019-12-30 Niels Möller <nisse@lysator.liu.se>
Preparation for ed448, based on patch by Daiki Ueno. Preparation for ed448, based on patch by Daiki Ueno.
......
...@@ -124,37 +124,48 @@ ecc_mod_pow_2k (const struct ecc_modulo *m, ...@@ -124,37 +124,48 @@ ecc_mod_pow_2k (const struct ecc_modulo *m,
} }
} }
/* Computes a^{(p-3)/4} = a^{2^446-2^222-1} mod m. Needs 6 * n scratch static void
ecc_mod_pow_2kp1 (const struct ecc_modulo *m,
mp_limb_t *rp, const mp_limb_t *xp,
unsigned k, mp_limb_t *tp)
{
ecc_mod_pow_2k (m, tp, xp, k, rp);
ecc_mod_mul (m, rp, tp, xp);
}
/* Computes a^{(p-3)/4} = a^{2^446-2^222-1} mod m. Needs 5 * n scratch
space. */ space. */
static void static void
ecc_mod_pow_446m224m1 (const struct ecc_modulo *p, ecc_mod_pow_446m224m1 (const struct ecc_modulo *p,
mp_limb_t *rp, const mp_limb_t *ap, mp_limb_t *rp, const mp_limb_t *ap,
mp_limb_t *scratch) mp_limb_t *scratch)
{ {
/* Note overlap: operations writing to t0 clobber t1. */
#define t0 scratch #define t0 scratch
#define t1 (scratch + 2*ECC_LIMB_SIZE) #define t1 (scratch + 1*ECC_LIMB_SIZE)
#define t2 (scratch + 4*ECC_LIMB_SIZE) #define t2 (scratch + 3*ECC_LIMB_SIZE)
ecc_mod_sqr (p, rp, ap); /* a^2 */ ecc_mod_sqr (p, rp, ap); /* a^2 */
ecc_mod_mul (p, t0, ap, rp); /* a^3 */ ecc_mod_mul (p, t0, ap, rp); /* a^3 */
ecc_mod_sqr (p, rp, t0); /* a^6 */ ecc_mod_sqr (p, rp, t0); /* a^6 */
ecc_mod_mul (p, t0, ap, rp); /* a^{2^3-1} */ ecc_mod_mul (p, t0, ap, rp); /* a^{2^3-1} */
ecc_mod_pow_2k (p, rp, t0, 3, t2); /* a^{2^6-2^3} */
ecc_mod_mul (p, t1, t0, rp); /* a^{2^6-1} */ ecc_mod_pow_2kp1 (p, t1, t0, 3, rp); /* a^{2^6-1} */
ecc_mod_pow_2k (p, rp, t1, 3, t2); /* a^{2^9-2^3} */ ecc_mod_pow_2k (p, rp, t1, 3, t2); /* a^{2^9-2^3} */
ecc_mod_mul (p, t1, t0, rp); /* a^{2^9-1} */ ecc_mod_mul (p, t2, t0, rp); /* a^{2^9-1} */
ecc_mod_pow_2k (p, t0, t1, 9, t2); /* a^{2^18-2^9} */ ecc_mod_pow_2kp1 (p, t0, t2, 9, rp); /* a^{2^18-1} */
ecc_mod_mul (p, rp, t1, t0); /* a^{2^18-1} */
ecc_mod_sqr (p, t1, rp); /* a^{2^19-2} */ ecc_mod_sqr (p, t1, t0); /* a^{2^19-2} */
ecc_mod_mul (p, t0, ap, t1); /* a^{2^19-1} */ ecc_mod_mul (p, rp, ap, t1); /* a^{2^19-1} */
ecc_mod_pow_2k (p, t1, t0, 18, t2); /* a^{2^37-2^18} */ ecc_mod_pow_2k (p, t1, rp, 18, t2); /* a^{2^37-2^18} */
ecc_mod_mul (p, t0, rp, t1); /* a^{2^37-1} */ ecc_mod_mul (p, rp, t0, t1); /* a^{2^37-1} */
ecc_mod_pow_2k (p, t1, t0, 37, t2); /* a^{2^74-2^37} */ mpn_copyi (t0, rp, p->size);
ecc_mod_mul (p, rp, t0, t1); /* a^{2^74-1} */
ecc_mod_pow_2kp1 (p, rp, t0, 37, t2); /* a^{2^74-1} */
ecc_mod_pow_2k (p, t1, rp, 37, t2); /* a^{2^111-2^37} */ ecc_mod_pow_2k (p, t1, rp, 37, t2); /* a^{2^111-2^37} */
ecc_mod_mul (p, rp, t0, t1); /* a^{2^111-1} */ ecc_mod_mul (p, rp, t0, t1); /* a^{2^111-1} */
ecc_mod_pow_2k (p, t1, rp, 111, t2); /* a^{2^222-2^111} */ ecc_mod_pow_2kp1 (p, t0, rp, 111, t2);/* a^{2^222-1} */
ecc_mod_mul (p, t0, rp, t1); /* a^{2^222-1} */
ecc_mod_sqr (p, t1, t0); /* a^{2^223-2} */ ecc_mod_sqr (p, t1, t0); /* a^{2^223-2} */
ecc_mod_mul (p, rp, ap, t1); /* a^{2^223-1} */ ecc_mod_mul (p, rp, ap, t1); /* a^{2^223-1} */
ecc_mod_pow_2k (p, t1, rp, 223, t2); /* a^{2^446-2^223} */ ecc_mod_pow_2k (p, t1, rp, 223, t2); /* a^{2^446-2^223} */
...@@ -164,8 +175,7 @@ ecc_mod_pow_446m224m1 (const struct ecc_modulo *p, ...@@ -164,8 +175,7 @@ ecc_mod_pow_446m224m1 (const struct ecc_modulo *p,
#undef t2 #undef t2
} }
/* Needs 6*ECC_LIMB_SIZE scratch space. */ #define ECC_448_INV_ITCH (5*ECC_LIMB_SIZE)
#define ECC_448_INV_ITCH (6*ECC_LIMB_SIZE)
static void ecc_448_inv (const struct ecc_modulo *p, static void ecc_448_inv (const struct ecc_modulo *p,
mp_limb_t *rp, const mp_limb_t *ap, mp_limb_t *rp, const mp_limb_t *ap,
...@@ -207,7 +217,7 @@ ecc_448_zero_p (const struct ecc_modulo *p, mp_limb_t *xp) ...@@ -207,7 +217,7 @@ ecc_448_zero_p (const struct ecc_modulo *p, mp_limb_t *xp)
*/ */
/* Needs 4*n space + scratch for ecc_mod_pow_446m224m1. */ /* Needs 4*n space + scratch for ecc_mod_pow_446m224m1. */
#define ECC_448_SQRT_ITCH (10*ECC_LIMB_SIZE) #define ECC_448_SQRT_ITCH (9*ECC_LIMB_SIZE)
static int static int
ecc_448_sqrt(const struct ecc_modulo *p, mp_limb_t *rp, ecc_448_sqrt(const struct ecc_modulo *p, mp_limb_t *rp,
......
...@@ -38,8 +38,14 @@ ...@@ -38,8 +38,14 @@
void test_main (void) void test_main (void)
{ {
const struct ecc_curve *ecc = &_nettle_curve25519;
gmp_randstate_t rands; gmp_randstate_t rands;
unsigned i;
gmp_randinit_default (rands);
for (i = 0; ecc_curves[i]; i++)
{
const struct ecc_curve *ecc = ecc_curves[i];
mp_size_t size, itch; mp_size_t size, itch;
mpz_t zp, t; mpz_t zp, t;
mp_limb_t *s; mp_limb_t *s;
...@@ -51,7 +57,8 @@ void test_main (void) ...@@ -51,7 +57,8 @@ void test_main (void)
uint8_t *c; uint8_t *c;
unsigned j; unsigned j;
gmp_randinit_default (rands); if (!(ecc->p.bit_size == 255 || ecc->p.bit_size == 448))
continue;
size = ecc_size (ecc); size = ecc_size (ecc);
clen = 1 + ecc->p.bit_size / 8; clen = 1 + ecc->p.bit_size / 8;
...@@ -68,6 +75,7 @@ void test_main (void) ...@@ -68,6 +75,7 @@ void test_main (void)
itch = _eddsa_decompress_itch (ecc); itch = _eddsa_decompress_itch (ecc);
if (itch < ecc->mul_g_itch) if (itch < ecc->mul_g_itch)
itch = ecc->mul_g_itch; itch = ecc->mul_g_itch;
ASSERT (_eddsa_compress_itch (ecc) <= itch);
scratch = xalloc_limbs (itch); scratch = xalloc_limbs (itch);
...@@ -99,7 +107,7 @@ void test_main (void) ...@@ -99,7 +107,7 @@ void test_main (void)
fprintf (stderr, ",\n 0x"); fprintf (stderr, ",\n 0x");
mpz_out_str (stderr, 16, y2); mpz_out_str (stderr, 16, y2);
fprintf (stderr, "\n"); fprintf (stderr, "\n");
abort (); FAIL();
} }
} }
mpz_clear (t); mpz_clear (t);
...@@ -109,5 +117,6 @@ void test_main (void) ...@@ -109,5 +117,6 @@ void test_main (void)
free (pa1); free (pa1);
free (pa2); free (pa2);
free (scratch); free (scratch);
}
gmp_randclear (rands); gmp_randclear (rands);
} }