static uint32 get_initial_inv_sqrt(msieve_obj *obj, mpz_poly_t *alg_poly, mpz_poly_t *prod, mpz_poly_t *isqrt_mod_q, mpz_t q_out) { /* find the prime q_out and the initial value of the reciprocal square root of prod(x) mod q_out to use for the Newton iteration */ uint32 i; uint32 q, start_q; alg_poly->degree++; /* find a prime q for which mp_alg_poly mod q is irreducible. The starting value to try was passed in */ start_q = mpz_get_ui(q_out); for (i = 0; i < ISQRT_NUM_ATTEMPTS; i++) { if (get_prime_for_sqrt(alg_poly, start_q + 1, &q)) { if (start_q > 150) { logprintf(obj, "warning: no irreducible prime " "found, switching to small primes\n"); start_q = 50; /* for octics, even mod 13 works and is resonably fast */ if (alg_poly->degree > 6) start_q = 12; continue; } } /* find the reciprocal square root mod q, or try another q if this fails */ if (inv_sqrt_mod_q(isqrt_mod_q, prod, alg_poly, q, &obj->seed1, &obj->seed2)) { break; } start_q = q; } alg_poly->degree--; if (i == ISQRT_NUM_ATTEMPTS) { logprintf(obj, "error: cannot recover square root mod q\n"); return 0; } logprintf(obj, "initial square root is modulo %u\n", q); mpz_set_ui(q_out, (unsigned long)q); return 1; }
static uint32 get_initial_inv_sqrt(msieve_obj *obj, mp_poly_t *mp_alg_poly, gmp_poly_t *prod, gmp_poly_t *isqrt_mod_q, mpz_t q_out) { /* find the prime q_out and the initial value of the reciprocal square root of prod(x) mod q_out to use for the Newton iteration */ uint32 i, j; uint32 q, start_q; mp_poly_t mp_prod_mod_q; mp_poly_t mp_isqrt_mod_q; /* find a prime q for which mp_alg_poly mod q is irreducible. The starting value to try was passed in */ start_q = mpz_get_ui(q_out); for (i = 0; i < ISQRT_NUM_ATTEMPTS; i++) { if (get_prime_for_sqrt(mp_alg_poly, start_q + 1, &q)) { if (start_q > 150) { logprintf(obj, "warning: no irreducible prime " "found, switching to small primes\n"); start_q = 50; /* for octics, even mod 13 works and is resonably fast */ if (mp_alg_poly->degree > 6) start_q = 12; continue; } } /* convert prod mod q to an mp_poly_t */ memset(&mp_prod_mod_q, 0, sizeof(mp_poly_t)); for (j = 0; j <= prod->degree; j++) { signed_mp_t *coeff = mp_prod_mod_q.coeff + j; uint32 r = mpz_fdiv_ui(prod->coeff[j], (unsigned long)q); coeff->sign = POSITIVE; coeff->num.nwords = (r == 0) ? 0 : 1; coeff->num.val[0] = r; } for (j = prod->degree; j; j--) { signed_mp_t *coeff = mp_prod_mod_q.coeff + j; if (!mp_is_zero(&coeff->num)) break; } mp_prod_mod_q.degree = j; /* find the reciprocal square root mod q, or try another q if this fails */ if (inv_sqrt_mod_q(&mp_isqrt_mod_q, &mp_prod_mod_q, mp_alg_poly, q, &obj->seed1, &obj->seed2)) { break; } start_q = q; } if (i == ISQRT_NUM_ATTEMPTS) { logprintf(obj, "error: cannot recover square root mod q\n"); return 0; } /* initialize isqrt_mod_q */ mpz_set_ui(q_out, (unsigned long)q); for (i = 0; i <= mp_isqrt_mod_q.degree; i++) { signed_mp_t *coeff = mp_isqrt_mod_q.coeff + i; mpz_set_ui(isqrt_mod_q->coeff[i], (unsigned long)coeff->num.val[0]); if (coeff->sign == NEGATIVE) mpz_neg(isqrt_mod_q->coeff[i], isqrt_mod_q->coeff[i]); } isqrt_mod_q->degree = mp_isqrt_mod_q.degree; logprintf(obj, "initial square root is modulo %u\n", q); return 1; }