From: Niels Möller Date: Sat, 23 Aug 2014 19:39:10 +0000 (+0200) Subject: Document and test that ecc_modp_inv produces 0 for input a == 0 (mod p). X-Git-Tag: nettle_3.1rc1~155^2~18 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=02c617a9d1b3211ff63ae176bf162e4bd43a468e;p=thirdparty%2Fnettle.git Document and test that ecc_modp_inv produces 0 for input a == 0 (mod p). --- diff --git a/ChangeLog b/ChangeLog index 956b0ca8..a4e89d42 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +2014-08-23 Niels Möller + + * sec-modinv.c (sec_modinv): Document that for a == 0 (mod m), we + should produce the "inverse" 0. + + * testsuite/ecc-modinv-test.c (test_main): Check that ecc_modp_inv + produces 0 if a == 0 or a == p. + 2014-08-22 Niels Möller * x86_64/ecc-25519-modp.asm: New file. Assembly implementation, diff --git a/sec-modinv.c b/sec-modinv.c index 6c7253df..ea94abd3 100644 --- a/sec-modinv.c +++ b/sec-modinv.c @@ -71,6 +71,7 @@ cnd_swap (int cnd, mp_limb_t *ap, mp_limb_t *bp, mp_size_t n) } /* Compute a^{-1} mod m, with running time depending only on the size. + Returns zero if a == 0 (mod m), to be consistent with a^{phi(m)-1}. Also needs (m+1)/2, and m must be odd. */ void sec_modinv (mp_limb_t *vp, mp_limb_t *ap, mp_size_t n, diff --git a/testsuite/ecc-modinv-test.c b/testsuite/ecc-modinv-test.c index 31b5c27e..ee4267dc 100644 --- a/testsuite/ecc-modinv-test.c +++ b/testsuite/ecc-modinv-test.c @@ -37,6 +37,17 @@ ref_modinv (mp_limb_t *rp, const mp_limb_t *ap, const mp_limb_t *mp, mp_size_t m #define MAX_ECC_SIZE (1 + 521 / GMP_NUMB_BITS) #define COUNT 500 +static int +mpn_zero_p (mp_srcptr ap, mp_size_t n) +{ + while (--n >= 0) + { + if (ap[n] != 0) + return 0; + } + return 1; +} + void test_main (void) { @@ -55,6 +66,36 @@ 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)); + ecc_modp_inv (ecc, ai, a, scratch); + if (!mpn_zero_p (ai, ecc->size)) + { + fprintf (stderr, "ecc_modp_inv failed for zero input (bit size %u):\n", + ecc->bit_size); + gmp_fprintf (stderr, "p = %Nx\n" + "t = %Nx (bad)\n", + ecc->p, ecc->size, + ai, ecc->size); + abort (); + } + + /* Check behaviour for a = p */ + mpn_copyi (a, ecc->p, ecc->size); + memset (ai, 17, ecc->size * sizeof(*ai)); + ecc_modp_inv (ecc, ai, a, scratch); + if (!mpn_zero_p (ai, ecc->size)) + { + fprintf (stderr, "ecc_modp_inv failed for a = p input (bit size %u):\n", + ecc->bit_size); + gmp_fprintf (stderr, "p = %Nx\n" + "t = %Nx (bad)\n", + ecc->p, ecc->size, + ai, ecc->size); + abort (); + } + for (j = 0; j < COUNT; j++) { if (j & 1)