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); }
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; }