Integer MaurerProvablePrime(RandomNumberGenerator &rng, unsigned int bits) { const unsigned smallPrimeBound = 29, c_opt=10; Integer p; unsigned int primeTableSize; const word16 * primeTable = GetPrimeTable(primeTableSize); if (bits < smallPrimeBound) { do p.Randomize(rng, Integer::Power2(bits-1), Integer::Power2(bits)-1, Integer::ANY, 1, 2); while (TrialDivision(p, 1 << ((bits+1)/2))); } else { const unsigned margin = bits > 50 ? 20 : (bits-10)/2; double relativeSize; do relativeSize = pow(2.0, double(rng.GenerateWord32())/0xffffffff - 1); while (bits * relativeSize >= bits - margin); Integer a,b; Integer q = MaurerProvablePrime(rng, unsigned(bits*relativeSize)); Integer I = Integer::Power2(bits-2)/q; Integer I2 = I << 1; unsigned int trialDivisorBound = (unsigned int)STDMIN((unsigned long)primeTable[primeTableSize-1], (unsigned long)bits*bits/c_opt); bool success = false; while (!success) { p.Randomize(rng, I, I2, Integer::ANY); p *= q; p <<= 1; ++p; if (!TrialDivision(p, trialDivisorBound)) { a.Randomize(rng, 2, p-1, Integer::ANY); b = a_exp_b_mod_c(a, (p-1)/q, p); success = (GCD(b-1, p) == 1) && (a_exp_b_mod_c(b, q, p) == 1); } } } return p; }
/* * It is a function that generates random prime numbers * input: prime (mpz_t) for retrieving the prime and bitUsed for determining the bits size * output: mpz_t prime will be captured in host if parameter of main is void, e.g. main(void) */ void generatePrime(mpz_t prime, int bitUsed){ int check; mpz_t rop; unsigned long int seed; gmp_randstate_t state; srand(time(NULL)); seed = rand(); gmp_randinit_default (state); gmp_randseed_ui(state, seed); mpz_init(rop); int cond = 1; for(check = 0; check != 1;) { switch(cond){ case 1: mpz_urandomb(rop, state, bitUsed); printf("."); if(CheckOdd(rop) == 1){ cond = 2; }else{ cond = 1; } break; case 2: if(TrialDivision(rop) == 1){ cond = 3; }else{ cond = 1; } break; case 3: if(Miller(rop,10) == 1){ check = 1; }else{ cond = 1; } break; } } printf("\n"); mpz_set(prime, rop); gmp_randclear(state); mpz_clear(rop); return 0; }
bool SmallDivisorsTest(const Integer &p) { BuildPrimeTable(); return !TrialDivision(p, primeTable[primeTableSize-1]); }
// general purpose factoring method void factor(vec_pair_ZZ_long& factors, const ZZ& _n, const ZZ& bnd, double failure_prob, bool verbose) { ZZ n(_n); if (n<=1) { abs(n,n); if (n<=1) { factors.SetLength(0); return; } } // upper bound on size of smallest prime factor ZZ upper_bound; SqrRoot(upper_bound,n); if (bnd>0 && bnd<upper_bound) upper_bound=bnd; // figure out appropriate lower_bound for trial division long B1,B2,D; double prob; ECM_parameters(B1,B2,prob,D,NumBits(upper_bound),NumBits(n)); ZZ lower_bound; conv(lower_bound,max(B2,1<<14)); if (lower_bound>upper_bound) lower_bound=upper_bound; // start factoring with trial division TrialDivision(factors,n,n,to_long(lower_bound)); if (IsOne(n)) return; if (upper_bound<=lower_bound || ProbPrime_notd(n)) { addFactor(factors,n); return; } /* n is composite and smallest prime factor is assumed to be such that * lower_bound < factor <= upper_bound * * Ramp-up to searching for factors of size upper_bound. This is a good * idea in cases where we have no idea what size factors N might have, * but we don't want to spend too much time doing this. */ for(lower_bound<<=4; lower_bound<upper_bound; lower_bound<<=4) { ZZ q; ECM(q,n,lower_bound,1,verbose); // one curve only if (!IsOne(q)) { div(n,n,q); if (n<q) swap(n,q); // q is small factor, n is large factor if (ProbPrime_notd(q)) addFactor(factors,q); else factor_r(factors,q,bnd,failure_prob,verbose); if (ProbPrime_notd(n)) { addFactor(factors,n); return; } // new upper_bound SqrRoot(upper_bound,n); if (bnd>0 && bnd<upper_bound) upper_bound=bnd; } } // search for factors of size bnd factor_r(factors,n,bnd,failure_prob,verbose); }
bool SmallDivisorsTest(const Integer &p) { unsigned int primeTableSize; const word16 * primeTable = GetPrimeTable(primeTableSize); return !TrialDivision(p, primeTable[primeTableSize-1]); }