3 Copyright (C) 2014 Niels Möller
5 This file is part of GNU Nettle.
7 GNU Nettle is free software: you can redistribute it and/or
8 modify it under the terms of either:
10 * the GNU Lesser General Public License as published by the Free
11 Software Foundation; either version 3 of the License, or (at your
12 option) any later version.
16 * the GNU General Public License as published by the Free
17 Software Foundation; either version 2 of the License, or (at your
18 option) any later version.
20 or both in parallel, as here.
22 GNU Nettle is distributed in the hope that it will be useful,
23 but WITHOUT ANY WARRANTY; without even the implied warranty of
24 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
25 General Public License for more details.
27 You should have received copies of the GNU General Public License and
28 the GNU Lesser General Public License along with this program. If
29 not, see http://www.gnu.org/licenses/.
32 #include "testutils.h"
36 #if NETTLE_USE_MINI_GMP
37 /* Implements Legendre symbol only, requiring that p is an odd prime */
39 mpz_ui_kronecker (mp_limb_t ul, const mpz_t p)
44 mpz_init_set_ui (u, ul);
47 mpz_tdiv_q_2exp (t, t, 1);
48 mpz_powm (t, u, t, p);
50 r = mpz_cmp_ui (t, 1);
58 ASSERT (mpz_cmp_ui (t, 1) == 0);
66 #endif /* NETTLE_USE_MINI_GMP */
69 test_modulo (gmp_randstate_t rands, const struct ecc_modulo *m)
87 mpz_roinit_n (p, m->m, m->size);
89 up = xalloc_limbs (m->size);
90 vp = xalloc_limbs (m->size);
91 rp = xalloc_limbs (2*m->size);
92 scratch = xalloc_limbs (m->sqrt_itch);
94 /* Find a non-square */
95 for (z = 2; mpz_ui_kronecker (z, p) != -1; z++)
99 fprintf(stderr, "Non square: %d\n", z);
101 for (i = 0; i < COUNT; i++)
105 mpz_rrandomb (u, rands, m->bit_size);
106 mpz_rrandomb (v, rands, m->bit_size);
110 mpz_urandomb (u, rands, m->bit_size);
111 mpz_urandomb (v, rands, m->bit_size);
113 mpz_limbs_copy (up, u, m->size);
114 mpz_limbs_copy (vp, v, m->size);
115 if (!m->sqrt (m, rp, up, vp, scratch))
117 mpz_mul_ui (u, u, z);
119 mpz_limbs_copy (up, u, m->size);
120 if (!m->sqrt (m, rp, up, vp, scratch))
122 fprintf (stderr, "m->sqrt returned failure, bit_size = %d\n"
125 mpz_out_str (stderr, 16, u);
126 fprintf (stderr, "\nv = 0x");
127 mpz_out_str (stderr, 16, v);
128 fprintf (stderr, "\n");
132 /* Check that r^2 v = u */
133 mpz_roinit_n (r, rp, m->size);
136 if (!mpz_congruent_p (t, u, p))
138 fprintf (stderr, "m->sqrt gave incorrect result, bit_size = %d\n"
141 mpz_out_str (stderr, 16, u);
142 fprintf (stderr, "\nv = 0x");
143 mpz_out_str (stderr, 16, v);
144 fprintf (stderr, "\nr = 0x");
145 mpz_out_str (stderr, 16, r);
146 fprintf (stderr, "\n");
162 gmp_randstate_t rands;
165 gmp_randinit_default (rands);
166 for (i = 0; ecc_curves[i]; i++)
168 if (ecc_curves[i]->p.sqrt)
169 test_modulo (rands, &ecc_curves[i]->p);
171 gmp_randclear (rands);