Exemple #1
0
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;
}
Exemple #2
0
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;
}