8 ref_mod (mp_limb_t *rp, const mp_limb_t *ap, const mp_limb_t *mp, mp_size_t mn)
12 mpz_mod (r, mpz_roinit_n (a, ap, 2*mn), mpz_roinit_n (m, mp, mn));
13 mpz_limbs_copy (rp, r, mn);
18 #define MAX_ECC_SIZE (1 + 521 / GMP_NUMB_BITS)
19 #define MAX_SIZE (2*MAX_ECC_SIZE)
23 test_one(const char *name,
24 const struct ecc_modulo *m,
27 mp_limb_t a[MAX_SIZE];
28 mp_limb_t t[MAX_SIZE];
29 mp_limb_t ref[MAX_SIZE];
31 mpz_limbs_copy (a, r, 2*m->size);
33 ref_mod (ref, a, m->m, m->size);
35 mpn_copyi (t, a, 2*m->size);
37 if (mpn_cmp (t, m->m, m->size) >= 0)
38 mpn_sub_n (t, t, m->m, m->size);
40 if (mpn_cmp (t, ref, m->size))
42 fprintf (stderr, "m->mod %s failed: bit_size = %u\n",
45 fprintf (stderr, "a = ");
46 mpn_out_str (stderr, 16, a, 2*m->size);
47 fprintf (stderr, "\nt = ");
48 mpn_out_str (stderr, 16, t, m->size);
49 fprintf (stderr, " (bad)\nref = ");
50 mpn_out_str (stderr, 16, ref, m->size);
51 fprintf (stderr, "\n");
55 if (m->B_size < m->size)
57 mpn_copyi (t, a, 2*m->size);
59 if (mpn_cmp (t, m->m, m->size) >= 0)
60 mpn_sub_n (t, t, m->m, m->size);
62 if (mpn_cmp (t, ref, m->size))
64 fprintf (stderr, "ecc_mod %s failed: bit_size = %u\n",
66 fprintf (stderr, "a = ");
67 mpn_out_str (stderr, 16, a, 2*m->size);
68 fprintf (stderr, "\nt = ");
69 mpn_out_str (stderr, 16, t, m->size);
70 fprintf (stderr, " (bad)\nref = ");
71 mpn_out_str (stderr, 16, ref, m->size);
72 fprintf (stderr, "\n");
79 test_modulo (gmp_randstate_t rands, const char *name,
80 const struct ecc_modulo *m, unsigned count)
87 for (j = 0; j < count; j++)
90 mpz_rrandomb (r, rands, 2*m->size * GMP_NUMB_BITS);
92 mpz_urandomb (r, rands, 2*m->size * GMP_NUMB_BITS);
94 test_one (name, m, r);
105 /* Triggered a bug reported by Hanno Böck. */
106 mpz_set_str (r, "FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFF001C2C00", 16);
107 mpz_mul_2exp (r, r, 256);
108 test_one ("p", &nettle_secp_256r1.p, r);
109 test_one ("q", &nettle_secp_256r1.q, r);
111 mpz_set_str (r, "ffffffff00000001fffffffeffffffffffffffffffffffffffffffc0000000000007ffffffffffffffffffffffffffff00000000000000000fffffffffffffff", 16);
112 test_one ("p", &nettle_secp_256r1.p, r);
113 test_one ("q", &nettle_secp_256r1.q, r);
115 /* Triggered a bug reported by Hanno Böck. */
116 mpz_set_str (r, "4c9000000000000000000000000000000000000000000000004a604db486e000000000000000000000000000000000000000121025be29575adb2c8ffffffffffffffffffffffffffffffffffffffffffffffffffffffff", 16);
117 test_one ("p", &nettle_secp_384r1.p, r);
118 test_one ("q", &nettle_secp_384r1.q, r);
120 /* Triggered a carry bug in development version. */
121 mpz_set_str (r, "e64a84643150260640e4677c19ffc4faef06042132b86af6e9ee33fe1850222e57a514d5f1d6d444008bb896a96a43d5629945e57548f5e12f66be132b24110cbb2df6d7d3dd3aaadc98b0bbf29573843ad72e57f59fc5d4f56cc599da18bb99", 16);
123 test_one ("p", &nettle_secp_384r1.p, r);
124 test_one ("q", &nettle_secp_384r1.q, r);
130 test_patterns (const char *name,
131 const struct ecc_modulo *m)
138 for (j = m->bit_size; j < 2*m->bit_size; j++)
141 mpz_mul_2exp (r, r, j);
143 test_one (name, m, r);
148 #if !NETTLE_USE_MINI_GMP
150 get_random_seed(mpz_t seed)
154 f = fopen ("/dev/urandom", "rb");
161 res = fread (&buf, sizeof(buf), 1, f);
165 nettle_mpz_set_str_256_u (seed, sizeof(buf), buf);
168 fprintf (stderr, "Read of /dev/urandom failed: %s\n",
171 gettimeofday(&tv, NULL);
172 mpz_set_ui (seed, tv.tv_sec);
173 mpz_mul_ui (seed, seed, 1000000UL);
174 mpz_add_ui (seed, seed, tv.tv_usec);
176 #endif /* !NETTLE_USE_MINI_GMP */
181 const char *nettle_test_seed;
182 gmp_randstate_t rands;
183 unsigned count = COUNT;
186 gmp_randinit_default (rands);
190 for (i = 0; ecc_curves[i]; i++)
192 test_patterns ("p", &ecc_curves[i]->p);
193 test_patterns ("q", &ecc_curves[i]->p);
196 #if !NETTLE_USE_MINI_GMP
197 nettle_test_seed = getenv ("NETTLE_TEST_SEED");
198 if (nettle_test_seed && *nettle_test_seed)
202 if (mpz_set_str (seed, nettle_test_seed, 0) < 0
203 || mpz_sgn (seed) < 0)
204 die ("Invalid NETTLE_TEST_SEED: %s\n",
206 if (mpz_sgn (seed) == 0)
207 get_random_seed (seed);
208 fprintf (stderr, "Using NETTLE_TEST_SEED=");
209 mpz_out_str (stderr, 10, seed);
210 fprintf (stderr, "\n");
212 gmp_randseed (rands, seed);
216 #endif /* !NETTLE_USE_MINI_GMP */
218 for (i = 0; ecc_curves[i]; i++)
220 test_modulo (rands, "p", &ecc_curves[i]->p, count);
221 test_modulo (rands, "q", &ecc_curves[i]->q, count);
223 gmp_randclear (rands);