static void ref_mod (mp_limb_t *rp, const mp_limb_t *ap, const mp_limb_t *mp, mp_size_t mn) { mpz_t r, a, m; mpz_init (r); mpz_mod (r, mpz_roinit_n (a, ap, 2*mn), mpz_roinit_n (m, mp, mn)); mpz_limbs_copy (rp, r, mn); mpz_clear (r); }
static void test_one(const char *name, const struct ecc_modulo *m, const mpz_t r) { mp_limb_t a[MAX_SIZE]; mp_limb_t t[MAX_SIZE]; mp_limb_t ref[MAX_SIZE]; mpz_limbs_copy (a, r, 2*m->size); ref_mod (ref, a, m->m, m->size); mpn_copyi (t, a, 2*m->size); m->mod (m, t); if (mpn_cmp (t, m->m, m->size) >= 0) mpn_sub_n (t, t, m->m, m->size); if (mpn_cmp (t, ref, m->size)) { fprintf (stderr, "m->mod %s failed: bit_size = %u\n", name, m->bit_size); fprintf (stderr, "a = "); mpn_out_str (stderr, 16, a, 2*m->size); fprintf (stderr, "\nt = "); mpn_out_str (stderr, 16, t, m->size); fprintf (stderr, " (bad)\nref = "); mpn_out_str (stderr, 16, ref, m->size); fprintf (stderr, "\n"); abort (); } if (m->B_size < m->size) { mpn_copyi (t, a, 2*m->size); ecc_mod (m, t); if (mpn_cmp (t, m->m, m->size) >= 0) mpn_sub_n (t, t, m->m, m->size); if (mpn_cmp (t, ref, m->size)) { fprintf (stderr, "ecc_mod %s failed: bit_size = %u\n", name, m->bit_size); fprintf (stderr, "a = "); mpn_out_str (stderr, 16, a, 2*m->size); fprintf (stderr, "\nt = "); mpn_out_str (stderr, 16, t, m->size); fprintf (stderr, " (bad)\nref = "); mpn_out_str (stderr, 16, ref, m->size); fprintf (stderr, "\n"); abort (); } } }
int ecc_scalar_set (struct ecc_scalar *s, const mpz_t z) { mp_size_t size = s->ecc->size; if (mpz_sgn (z) <= 0 || mpz_limbs_cmp (z, s->ecc->q, size) >= 0) return 0; mpz_limbs_copy (s->p, z, size); return 1; }
void test_main (void) { gmp_randstate_t state; mp_limb_t a[MAX_ECC_SIZE]; mp_limb_t ai[MAX_ECC_SIZE]; mp_limb_t ref[MAX_ECC_SIZE]; mp_limb_t scratch[ECC_MODINV_ITCH (MAX_ECC_SIZE)]; unsigned i; mpz_t r; gmp_randinit_default (state); mpz_init (r); for (i = 0; ecc_curves[i]; i++) { const struct ecc_curve *ecc = ecc_curves[i]; unsigned j; for (j = 0; j < COUNT; j++) { if (j & 1) mpz_rrandomb (r, state, ecc->size * GMP_NUMB_BITS); else mpz_urandomb (r, state, ecc->size * GMP_NUMB_BITS); mpz_limbs_copy (a, r, ecc->size); if (!ref_modinv (ref, a, ecc->p, ecc->size)) { if (verbose) fprintf (stderr, "Test %u (bit size %u) not invertible.\n", j, ecc->bit_size); continue; } ecc_modp_inv (ecc, ai, a, scratch); if (mpn_cmp (ref, ai, ecc->size)) { fprintf (stderr, "ecc_modp_inv failed (test %u, bit size %u):\n", j, ecc->bit_size); gmp_fprintf (stderr, "a = %Zx\n" "p = %Nx\n" "t = %Nx (bad)\n" "r = %Nx\n", r, ecc->p, ecc->size, ai, ecc->size, ref, ecc->size); abort (); } mpz_limbs_copy (a, r, ecc->size); if (!ref_modinv (ref, a, ecc->q, ecc->size)) { fprintf (stderr, "Test %u (bit size %u) not invertible.\n", j, ecc->bit_size); continue; } ecc_modq_inv (ecc, ai, a, scratch); if (mpn_cmp (ref, ai, ecc->size)) { fprintf (stderr, "ecc_modq_inv failed (test %u, bit size %u):\n", j, ecc->bit_size); gmp_fprintf (stderr, "a = %Zx\n" "p = %Nx\n" "t = %Nx (bad)\n" "r = %Nx\n", r, ecc->p, ecc->size, ai, ecc->size, ref, ecc->size); abort (); } } } gmp_randclear (state); mpz_clear (r); }
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); }