Skip to content

Commit 58fadb9

Browse files
Fix factor base selection
1 parent aee0cc6 commit 58fadb9

File tree

1 file changed

+26
-9
lines changed

1 file changed

+26
-9
lines changed

FindAFactor/_find_a_factor.cpp

Lines changed: 26 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -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+
697721
struct 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

Comments
 (0)