@@ -57,7 +57,7 @@ Wheel wheelByPrimeCardinal(int i) {
5757}
5858
5959// See https://stackoverflow.com/questions/101439/the-most-efficient-way-to-implement-an-integer-based-power-function-powint-int
60- BigInteger ipow (BigInteger base, unsigned exp) {
60+ BigInteger ipow (BigInteger base, size_t exp) {
6161 BigInteger result = 1U ;
6262 for (;;) {
6363 if (exp & 1U ) {
@@ -694,6 +694,30 @@ size_t GetGearIncrement(std::vector<boost::dynamic_bitset<size_t>> *inc_seqs) {
694694 return wheelIncrement;
695695}
696696
697+ // //////////////////////////////////////////////////////////////////////////////////////////////////////////
698+ // WRITTEN WITH HELP FROM ELARA (GPT) BELOW //
699+ // //////////////////////////////////////////////////////////////////////////////////////////////////////////
700+
701+ // Function to compute the Legendre symbol (N / p)
702+ size_t legendreSymbol (BigInteger N, size_t p) {
703+ return (size_t )(ipow (N, (p - 1U ) >> 1U ) % p); // Euler's Criterion: N^((p-1)/2) mod p
704+ }
705+
706+ // Function to generate factor base
707+ std::vector<size_t > selectFactorBase (const BigInteger N, const std::vector<size_t >& primes) {
708+ std::vector<size_t > factorBase;
709+ for (size_t p : primes) {
710+ if (legendreSymbol (N, p) == 1U ) { // Select only primes where (N/p) = 1
711+ factorBase.push_back (p);
712+ }
713+ }
714+ return factorBase;
715+ }
716+
717+ // //////////////////////////////////////////////////////////////////////////////////////////////////////////
718+ // WRITTEN WITH HELP FROM ELARA (GPT) ABOVE //
719+ // //////////////////////////////////////////////////////////////////////////////////////////////////////////
720+
697721struct Factorizer {
698722 std::mutex batchMutex;
699723 BigInteger toFactorSqr;
@@ -1124,14 +1148,7 @@ std::string find_a_factor(std::string toFactorStr, size_t method, size_t nodeCou
11241148 // Primes are only present in range above wheel factorization level
11251149 std::vector<size_t > smoothPrimes;
11261150 if (isFactorFinder) {
1127- for (size_t primeId = 0U ; primeId < primes.size (); ++primeId) {
1128- const size_t p = primes[primeId];
1129- const size_t residue = (size_t )(toFactor % p);
1130- const size_t sr = _sqrt (residue);
1131- if ((sr * sr) == residue) {
1132- smoothPrimes.push_back (p);
1133- }
1134- }
1151+ smoothPrimes = selectFactorBase (toFactor, primes);
11351152 if (smoothPrimes.empty ()) {
11361153 throw std::runtime_error (" No smooth primes found under bound. (The formula smoothness bound calculates to " + std::to_string (primeCeiling) + " .) Increase the smoothness bound multiplier, unless this is in range of check_small_factors=True." );
11371154 }
0 commit comments