...

Commits (2)
 2020-01-01 Niels Möller * 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 Preparation for ed448, based on patch by Daiki Ueno. ... ...
 ... ... @@ -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. */ static void ecc_mod_pow_446m224m1 (const struct ecc_modulo *p, mp_limb_t *rp, const mp_limb_t *ap, mp_limb_t *scratch) { /* Note overlap: operations writing to t0 clobber t1. */ #define t0 scratch #define t1 (scratch + 2*ECC_LIMB_SIZE) #define t2 (scratch + 4*ECC_LIMB_SIZE) #define t1 (scratch + 1*ECC_LIMB_SIZE) #define t2 (scratch + 3*ECC_LIMB_SIZE) ecc_mod_sqr (p, rp, ap); /* a^2 */ ecc_mod_mul (p, t0, ap, rp); /* a^3 */ ecc_mod_sqr (p, rp, t0); /* a^6 */ 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_mul (p, t1, t0, rp); /* a^{2^9-1} */ ecc_mod_pow_2k (p, t0, t1, 9, t2); /* a^{2^18-2^9} */ ecc_mod_mul (p, rp, t1, t0); /* a^{2^18-1} */ ecc_mod_sqr (p, t1, rp); /* a^{2^19-2} */ ecc_mod_mul (p, t0, ap, t1); /* a^{2^19-1} */ ecc_mod_pow_2k (p, t1, t0, 18, t2); /* a^{2^37-2^18} */ ecc_mod_mul (p, t0, rp, t1); /* a^{2^37-1} */ ecc_mod_pow_2k (p, t1, t0, 37, t2); /* a^{2^74-2^37} */ ecc_mod_mul (p, rp, t0, t1); /* a^{2^74-1} */ ecc_mod_mul (p, t2, t0, rp); /* a^{2^9-1} */ ecc_mod_pow_2kp1 (p, t0, t2, 9, rp); /* a^{2^18-1} */ ecc_mod_sqr (p, t1, t0); /* a^{2^19-2} */ ecc_mod_mul (p, rp, ap, t1); /* a^{2^19-1} */ ecc_mod_pow_2k (p, t1, rp, 18, t2); /* a^{2^37-2^18} */ ecc_mod_mul (p, rp, t0, t1); /* a^{2^37-1} */ mpn_copyi (t0, rp, p->size); 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_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_mul (p, t0, rp, t1); /* a^{2^222-1} */ ecc_mod_pow_2kp1 (p, t0, rp, 111, t2);/* a^{2^222-1} */ ecc_mod_sqr (p, t1, t0); /* a^{2^223-2} */ 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} */ ... ... @@ -164,8 +175,7 @@ ecc_mod_pow_446m224m1 (const struct ecc_modulo *p, #undef t2 } /* Needs 6*ECC_LIMB_SIZE scratch space. */ #define ECC_448_INV_ITCH (6*ECC_LIMB_SIZE) #define ECC_448_INV_ITCH (5*ECC_LIMB_SIZE) static void ecc_448_inv (const struct ecc_modulo *p, 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) */ /* 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 ecc_448_sqrt(const struct ecc_modulo *p, mp_limb_t *rp, ... ...
 ... ... @@ -38,76 +38,85 @@ void test_main (void) { const struct ecc_curve *ecc = &_nettle_curve25519; gmp_randstate_t rands; mp_size_t size, itch; mpz_t zp, t; mp_limb_t *s; mp_limb_t *p; mp_limb_t *pa1; mp_limb_t *pa2; mp_limb_t *scratch; size_t clen; uint8_t *c; unsigned j; unsigned i; gmp_randinit_default (rands); size = ecc_size (ecc); clen = 1 + ecc->p.bit_size / 8; mpz_roinit_n (zp, ecc->p.m, size); mpz_init (t); s = xalloc_limbs (size); p = xalloc_limbs (ecc_size_j (ecc)); pa1 = xalloc_limbs (ecc_size_a (ecc)); pa2 = xalloc_limbs (ecc_size_a (ecc)); c = xalloc (clen); itch = _eddsa_decompress_itch (ecc); if (itch < ecc->mul_g_itch) itch = ecc->mul_g_itch; scratch = xalloc_limbs (itch); for (j = 0; j < COUNT; j++) for (i = 0; ecc_curves[i]; i++) { mpz_t x1, y1, x2, y2; mpz_urandomb (t, rands, ecc->q.bit_size); mpz_limbs_copy (s, t, ecc->q.size); ecc->mul_g (ecc, p, s, scratch); _eddsa_compress (ecc, c, p, scratch); ecc->h_to_a (ecc, 0, pa1, p, scratch); _eddsa_decompress (ecc, pa2, c, scratch); mpz_roinit_n (x1, pa1, size); mpz_roinit_n (y1, pa1 + size, size); mpz_roinit_n (x2, pa2, size); mpz_roinit_n (y2, pa2 + size, size); if (!(mpz_congruent_p (x1, x2, zp) && mpz_congruent_p (y1, y2, zp))) const struct ecc_curve *ecc = ecc_curves[i]; mp_size_t size, itch; mpz_t zp, t; mp_limb_t *s; mp_limb_t *p; mp_limb_t *pa1; mp_limb_t *pa2; mp_limb_t *scratch; size_t clen; uint8_t *c; unsigned j; if (!(ecc->p.bit_size == 255 || ecc->p.bit_size == 448)) continue; size = ecc_size (ecc); clen = 1 + ecc->p.bit_size / 8; mpz_roinit_n (zp, ecc->p.m, size); mpz_init (t); s = xalloc_limbs (size); p = xalloc_limbs (ecc_size_j (ecc)); pa1 = xalloc_limbs (ecc_size_a (ecc)); pa2 = xalloc_limbs (ecc_size_a (ecc)); c = xalloc (clen); itch = _eddsa_decompress_itch (ecc); if (itch < ecc->mul_g_itch) itch = ecc->mul_g_itch; ASSERT (_eddsa_compress_itch (ecc) <= itch); scratch = xalloc_limbs (itch); for (j = 0; j < COUNT; j++) { fprintf (stderr, "eddsa compression failed:\nc = "); print_hex (clen, c); fprintf (stderr, "\np1 = 0x"); mpz_out_str (stderr, 16, x1); fprintf (stderr, ",\n 0x"); mpz_out_str (stderr, 16, y1); fprintf (stderr, "\np2 = 0x"); mpz_out_str (stderr, 16, x2); fprintf (stderr, ",\n 0x"); mpz_out_str (stderr, 16, y2); fprintf (stderr, "\n"); abort (); mpz_t x1, y1, x2, y2; mpz_urandomb (t, rands, ecc->q.bit_size); mpz_limbs_copy (s, t, ecc->q.size); ecc->mul_g (ecc, p, s, scratch); _eddsa_compress (ecc, c, p, scratch); ecc->h_to_a (ecc, 0, pa1, p, scratch); _eddsa_decompress (ecc, pa2, c, scratch); mpz_roinit_n (x1, pa1, size); mpz_roinit_n (y1, pa1 + size, size); mpz_roinit_n (x2, pa2, size); mpz_roinit_n (y2, pa2 + size, size); if (!(mpz_congruent_p (x1, x2, zp) && mpz_congruent_p (y1, y2, zp))) { fprintf (stderr, "eddsa compression failed:\nc = "); print_hex (clen, c); fprintf (stderr, "\np1 = 0x"); mpz_out_str (stderr, 16, x1); fprintf (stderr, ",\n 0x"); mpz_out_str (stderr, 16, y1); fprintf (stderr, "\np2 = 0x"); mpz_out_str (stderr, 16, x2); fprintf (stderr, ",\n 0x"); mpz_out_str (stderr, 16, y2); fprintf (stderr, "\n"); FAIL(); } } mpz_clear (t); free (s); free (p); free (c); free (pa1); free (pa2); free (scratch); } mpz_clear (t); free (s); free (p); free (c); free (pa1); free (pa2); free (scratch); gmp_randclear (rands); }