Exemplo n.º 1
0
void zTrial(fact_obj_t *fobj)
{
	//trial divide n using primes below limit. optionally, print factors found.
	//input expected in the gmp_n field of div_obj.
	uint32 r,k=0;
	uint32 limit = fobj->div_obj.limit;
	int print = fobj->div_obj.print;
	FILE *flog;
	fp_digit q;
	mpz_t tmp;
	mpz_init(tmp);

	flog = fopen(fobj->flogname,"a");
	if (flog == NULL)
	{
		printf("fopen error: %s\n", strerror(errno));
		printf("could not open %s for writing\n",fobj->flogname);
		return;
	}

	if (P_MAX < limit)
	{
		free(PRIMES);
		PRIMES = soe_wrapper(spSOEprimes, szSOEp, 0, limit, 0, &NUM_P);
		P_MIN = PRIMES[0];
		P_MAX = PRIMES[NUM_P-1];
	}

	while ((mpz_cmp_ui(fobj->div_obj.gmp_n, 1) > 0) && 
		(PRIMES[k] < limit) && 
		(k < (uint32)NUM_P))
	{
		q = (fp_digit)PRIMES[k];
		r = mpz_tdiv_ui(fobj->div_obj.gmp_n, q);
		
		if (r != 0)
			k++;
		else
		{			
			mpz_tdiv_q_ui(fobj->div_obj.gmp_n, fobj->div_obj.gmp_n, q);
			mpz_set_64(tmp, q);

			add_to_factor_list(fobj, tmp);

#if BITS_PER_DIGIT == 64
			logprint(flog,"div: found prime factor = %" PRIu64 "\n",q);
#else
			logprint(flog,"div: found prime factor = %u\n",q);
#endif

			if (print && (VFLAG > 0))
#if BITS_PER_DIGIT == 64
				printf("div: found prime factor = %" PRIu64 "\n",q);
#else
				printf("div: found prime factor = %u\n",q);
#endif
		}
	}

	fclose(flog);
	mpz_clear(tmp);
}
Exemplo n.º 2
0
void trial_divide_Q_siqs(uint32 report_num,  uint8 parity,
                         uint32 poly_id, uint32 bnum,
                         static_conf_t *sconf, dynamic_conf_t *dconf)
{
    //we have flagged this sieve offset as likely to produce a relation
    //nothing left to do now but check and see.
    uint64 q64, f64;
    int j,it;
    uint32 prime;
    int smooth_num;
    uint32 *fb_offsets;
    uint32 polya_factors[20];
    sieve_fb *fb;
    uint32 offset, block_loc;
    fb_offsets = &dconf->fb_offsets[report_num][0];
    smooth_num = dconf->smooth_num[report_num];
    block_loc = dconf->reports[report_num];

#ifdef QS_TIMING
    gettimeofday(&qs_timing_start, NULL);
#endif

    offset = (bnum << sconf->qs_blockbits) + block_loc;

    if (parity)
        fb = dconf->fb_sieve_n;
    else
        fb = dconf->fb_sieve_p;

#ifdef USE_YAFU_TDIV
    z32_to_mpz(&dconf->Qvals32[report_num], dconf->Qvals[report_num]);
#endif

    //check for additional factors of the a-poly factors
    //make a separate list then merge it with fb_offsets
    it=0;	//max 20 factors allocated for - should be overkill
    for (j = 0; (j < dconf->curr_poly->s) && (it < 20); j++)
    {
        //fbptr = fb + dconf->curr_poly->qlisort[j];
        //prime = fbptr->prime;
        prime = fb[dconf->curr_poly->qlisort[j]].prime;

        while ((mpz_tdiv_ui(dconf->Qvals[report_num],prime) == 0) && (it < 20))
        {
            mpz_tdiv_q_ui(dconf->Qvals[report_num], dconf->Qvals[report_num], prime);
            polya_factors[it++] = dconf->curr_poly->qlisort[j];
        }
    }

    //check if it completely factored by looking at the unfactored portion in tmp
    //if ((mpz_size(dconf->Qvals[report_num]) == 1) &&
    //(mpz_get_64(dconf->Qvals[report_num]) < (uint64)sconf->large_prime_max))
    if ((mpz_size(dconf->Qvals[report_num]) == 1) &&
            (mpz_cmp_ui(dconf->Qvals[report_num], sconf->large_prime_max) < 0))
    {
        uint32 large_prime[2];

        large_prime[0] = (uint32)mpz_get_ui(dconf->Qvals[report_num]); //Q->val[0];
        large_prime[1] = 1;

        //add this one
        if (sconf->is_tiny)
        {
            // we need to encode both the a_poly and b_poly index
            // in poly_id
            poly_id |= (sconf->total_poly_a << 16);
            buffer_relation(offset,large_prime,smooth_num+1,
                            fb_offsets,poly_id,parity,dconf,polya_factors,it);
        }
        else
            buffer_relation(offset,large_prime,smooth_num+1,
                            fb_offsets,poly_id,parity,dconf,polya_factors,it);

#ifdef QS_TIMING
        gettimeofday (&qs_timing_stop, NULL);
        qs_timing_diff = my_difftime (&qs_timing_start, &qs_timing_stop);

        TF_STG6 += ((double)qs_timing_diff->secs + (double)qs_timing_diff->usecs / 1000000);
        free(qs_timing_diff);
#endif

        return;
    }

    if (sconf->use_dlp == 0)
        return;

    //quick check if Q is way too big for DLP (more than 64 bits)
    if (mpz_sizeinbase(dconf->Qvals[report_num], 2) >= 64)
        return;

    q64 = mpz_get_64(dconf->Qvals[report_num]);

    if ((q64 > sconf->max_fb2) && (q64 < sconf->large_prime_max2))
    {
        //quick prime check: compute 2^(residue-1) mod residue.
        uint64 res;
        //printf("%llu\n",q64);

#if BITS_PER_DIGIT == 32
        mpz_set_64(dconf->gmptmp1, q64);
        mpz_set_64(dconf->gmptmp2, 2);
        mpz_set_64(dconf->gmptmp3, q64-1);

        mpz_powm(dconf->gmptmp1, dconf->gmptmp2, dconf->gmptmp3, dconf->gmptmp1);
        res = mpz_get_64(dconf->gmptmp1);
#else
        spModExp(2, q64 - 1, q64, &res);
#endif

        //if equal to 1, assume it is prime.  this may be wrong sometimes, but we don't care.
        //more important to quickly weed out probable primes than to spend more time to be
        //more sure.
        if (res == 1)
        {
#ifdef QS_TIMING
            gettimeofday (&qs_timing_stop, NULL);
            qs_timing_diff = my_difftime (&qs_timing_start, &qs_timing_stop);

            TF_STG6 += ((double)qs_timing_diff->secs + (double)qs_timing_diff->usecs / 1000000);
            free(qs_timing_diff);
#endif
            dconf->dlp_prp++;
            return;
        }

        //try to find a double large prime
#ifdef HAVE_CUDA
        {
            uint32 large_prime[2] = {1,1};

            // remember the residue and the relation it is associated with
            dconf->buf_id[dconf->num_squfof_cand] = dconf->buffered_rels;
            dconf->squfof_candidates[dconf->num_squfof_cand++] = q64;

            // buffer the relation
            buffer_relation(offset,large_prime,smooth_num+1,
                            fb_offsets,poly_id,parity,dconf,polya_factors,it);
        }
#else

        dconf->attempted_squfof++;
        mpz_set_64(dconf->gmptmp1, q64);
        f64 = sp_shanks_loop(dconf->gmptmp1, sconf->obj);
        if (f64 > 1 && f64 != q64)
        {
            uint32 large_prime[2];

            large_prime[0] = (uint32)f64;
            large_prime[1] = (uint32)(q64 / f64);

            if (large_prime[0] < sconf->large_prime_max
                    && large_prime[1] < sconf->large_prime_max)
            {
                //add this one
                dconf->dlp_useful++;
                buffer_relation(offset,large_prime,smooth_num+1,
                                fb_offsets,poly_id,parity,dconf,polya_factors,it);
            }

        }
        else
        {
            dconf->failed_squfof++;
            //printf("squfof failure: %" PRIu64 "\n", q64);
        }
#endif

    }
    else
        dconf->dlp_outside_range++;

#ifdef QS_TIMING
    gettimeofday (&qs_timing_stop, NULL);
    qs_timing_diff = my_difftime (&qs_timing_start, &qs_timing_stop);

    TF_STG6 += ((double)qs_timing_diff->secs + (double)qs_timing_diff->usecs / 1000000);
    free(qs_timing_diff);
#endif

    return;
}