diff --git a/ChangeLog b/ChangeLog index f570a1d445c393192f2b3b119e2eecc1393d7258..637060bd7bd63eeee8bdb880c913b1dc1fe27b1d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,9 @@ 2014-10-02 Niels Möller <nisse@lysator.liu.se> + * testsuite/ecc-sqrt-test.c: New test case. + * testsuite/Makefile.in (TS_HOGWEED_SOURCES): Added + ecc-sqrt-test.c. + * ecc-25519.c (PHIGH_BITS): Always define this constant. (ecc_25519_zero_p): New function. (ecc_25519_sqrt): Take a ratio u/v as input. Added scratch diff --git a/testsuite/.test-rules.make b/testsuite/.test-rules.make index fc87f1ebe1a62b36f220bad52e94eed65e80b85c..3399f9ef58ace2223a70ee5fb04653ea53e9ae8d 100644 --- a/testsuite/.test-rules.make +++ b/testsuite/.test-rules.make @@ -187,12 +187,6 @@ dsa-test$(EXEEXT): dsa-test.$(OBJEXT) dsa-keygen-test$(EXEEXT): dsa-keygen-test.$(OBJEXT) $(LINK) dsa-keygen-test.$(OBJEXT) $(TEST_OBJS) -o dsa-keygen-test$(EXEEXT) -curve25519-dup-test$(EXEEXT): curve25519-dup-test.$(OBJEXT) - $(LINK) curve25519-dup-test.$(OBJEXT) $(TEST_OBJS) -o curve25519-dup-test$(EXEEXT) - -curve25519-add-test$(EXEEXT): curve25519-add-test.$(OBJEXT) - $(LINK) curve25519-add-test.$(OBJEXT) $(TEST_OBJS) -o curve25519-add-test$(EXEEXT) - curve25519-dh-test$(EXEEXT): curve25519-dh-test.$(OBJEXT) $(LINK) curve25519-dh-test.$(OBJEXT) $(TEST_OBJS) -o curve25519-dh-test$(EXEEXT) @@ -205,6 +199,9 @@ ecc-modinv-test$(EXEEXT): ecc-modinv-test.$(OBJEXT) ecc-redc-test$(EXEEXT): ecc-redc-test.$(OBJEXT) $(LINK) ecc-redc-test.$(OBJEXT) $(TEST_OBJS) -o ecc-redc-test$(EXEEXT) +ecc-sqrt-test$(EXEEXT): ecc-sqrt-test.$(OBJEXT) + $(LINK) ecc-sqrt-test.$(OBJEXT) $(TEST_OBJS) -o ecc-sqrt-test$(EXEEXT) + ecc-dup-test$(EXEEXT): ecc-dup-test.$(OBJEXT) $(LINK) ecc-dup-test.$(OBJEXT) $(TEST_OBJS) -o ecc-dup-test$(EXEEXT) diff --git a/testsuite/Makefile.in b/testsuite/Makefile.in index a5c5458c205cda6c6dd2d0703f000f98c5050d42..31bd29d5808b1fedbce405f862cce5070091b607 100644 --- a/testsuite/Makefile.in +++ b/testsuite/Makefile.in @@ -40,6 +40,7 @@ TS_HOGWEED_SOURCES = sexp-test.c sexp-format-test.c \ dsa-test.c dsa-keygen-test.c \ curve25519-dh-test.c \ ecc-mod-test.c ecc-modinv-test.c ecc-redc-test.c \ + ecc-sqrt-test.c \ ecc-dup-test.c ecc-add-test.c \ ecc-mul-g-test.c ecc-mul-a-test.c \ ecdsa-sign-test.c ecdsa-verify-test.c \ diff --git a/testsuite/ecc-sqrt-test.c b/testsuite/ecc-sqrt-test.c new file mode 100644 index 0000000000000000000000000000000000000000..08cd8f38ac505bb41e31710e2708c40dce835bd7 --- /dev/null +++ b/testsuite/ecc-sqrt-test.c @@ -0,0 +1,140 @@ +/* ecc-sqrt.c + + Copyright (C) 2014 Niels Möller + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + or + + * the GNU General Public License as published by the Free + Software Foundation; either version 2 of the License, or (at your + option) any later version. + + or both in parallel, as here. + + GNU Nettle is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +*/ + +#include "testutils.h" + +#define COUNT 5000 + +static void +test_modulo (gmp_randstate_t rands, const struct ecc_modulo *m) +{ + mpz_t u; + mpz_t v; + mpz_t p; + mpz_t r; + mpz_t t; + + unsigned z, i; + mp_limb_t *up; + mp_limb_t *vp; + mp_limb_t *rp; + mp_limb_t *scratch; + + mpz_init (u); + mpz_init (v); + mpz_init (t); + + mpz_roinit_n (p, m->m, m->size); + + up = xalloc_limbs (m->size); + vp = xalloc_limbs (m->size); + rp = xalloc_limbs (2*m->size); + scratch = xalloc_limbs (m->sqrt_itch); + + /* Find a non-square */ + for (z = 2; mpz_ui_kronecker (z, p) != -1; z++) + ; + + if (verbose) + fprintf(stderr, "Non square: %d\n", z); + + for (i = 0; i < COUNT; i++) + { + if (i & 1) + { + mpz_rrandomb (u, rands, m->bit_size); + mpz_rrandomb (v, rands, m->bit_size); + } + else + { + mpz_urandomb (u, rands, m->bit_size); + mpz_urandomb (v, rands, m->bit_size); + } + mpz_limbs_copy (up, u, m->size); + mpz_limbs_copy (vp, v, m->size); + if (!m->sqrt (m, rp, up, vp, scratch)) + { + mpz_mul_ui (u, u, z); + mpz_mod (u, u, p); + mpz_limbs_copy (up, u, m->size); + if (!m->sqrt (m, rp, up, vp, scratch)) + { + fprintf (stderr, "m->sqrt returned failure, bit_size = %d\n" + "u = 0x", + m->bit_size); + mpz_out_str (stderr, 16, u); + fprintf (stderr, "\nv = 0x"); + mpz_out_str (stderr, 16, v); + fprintf (stderr, "\n"); + abort (); + } + } + /* Check that r^2 v = u */ + mpz_roinit_n (r, rp, m->size); + mpz_mul (t, r, r); + mpz_mul (t, t, v); + if (!mpz_congruent_p (t, u, p)) + { + fprintf (stderr, "m->sqrt gave incorrect result, bit_size = %d\n" + "u = 0x", + m->bit_size); + mpz_out_str (stderr, 16, u); + fprintf (stderr, "\nv = 0x"); + mpz_out_str (stderr, 16, v); + fprintf (stderr, "\nr = 0x"); + mpz_out_str (stderr, 16, r); + fprintf (stderr, "\n"); + abort (); + } + } + mpz_clear (u); + mpz_clear (v); + mpz_clear (t); + free (up); + free (vp); + free (rp); + free (scratch); +} + +void +test_main (void) +{ + gmp_randstate_t rands; + unsigned i; + + gmp_randinit_default (rands); + for (i = 0; ecc_curves[i]; i++) + { + if (ecc_curves[i]->p.sqrt) + test_modulo (rands, &ecc_curves[i]->p); + } + gmp_randclear (rands); +}