Skip to content

Commit

Permalink
fix 31bit performance, improve safety by argument check
Browse files Browse the repository at this point in the history
  • Loading branch information
TilmanNeumann committed Jan 3, 2025
1 parent 3958ac4 commit 6ba39a4
Showing 1 changed file with 19 additions and 15 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ public class PollardRhoBrent31 extends FactorAlgorithm {
private static final boolean DEBUG = false;
private static final SecureRandom RNG = new SecureRandom();

private int N;
private int n;

private Gcd31 gcd = new Gcd31();

Expand All @@ -45,17 +45,21 @@ public String getName() {

@Override
public BigInteger findSingleFactor(BigInteger N) {
return BigInteger.valueOf(findSingleFactor(N.intValue()));
if (N.bitLength() > 31) { // this check should be negligible in terms of performance
throw new IllegalArgumentException("N = " + N + " has " + N.bitLength() + " bit, but PollardRho31 only supports arguments <= 31 bit");
}
int factorInt = findSingleFactor(N.intValue());
return BigInteger.valueOf(factorInt);
}

public int findSingleFactor(int N) {
this.N = N;
public int findSingleFactor(int nOriginal) {
this.n = nOriginal<0 ? -nOriginal : nOriginal; // RNG.nextInt(n) below would crash for negative arguments
int G;
int ys, x;
do {
// start with random x0, c from [0, N-1]
int c = RNG.nextInt(N);
int x0 = RNG.nextInt(N);
int c = RNG.nextInt(n);
int x0 = RNG.nextInt(n);
int y = x0;

// Brent: "The probability of the algorithm failing because q_i=0 increases, so it is best not to choose m too large"
Expand All @@ -74,26 +78,26 @@ public int findSingleFactor(int N) {
for (int i=1; i<=iMax; i++) {
y = addModN(squareModN(y), c);
final long diff = x<y ? y-x : x-y;
q = (int) ((diff*q) % N);
q = (int) ((diff*q) % n);
}
G = gcd.gcd(q, N);
G = gcd.gcd(q, n);
// if q==0 then G==N -> the loop will be left and restarted with new x0, c
k += m;
if (DEBUG) LOG.debug("r = " + r + ", k = " + k);
} while (k<r && G==1);
r <<= 1;
if (DEBUG) LOG.debug("r = " + r + ", G = " + G);
} while (G==1);
if (G==N) {
if (G==n) {
do {
ys = addModN(squareModN(ys), c);
int diff = x<ys ? ys-x : x-ys;
G = gcd.gcd(diff, N);
G = gcd.gcd(diff, n);
} while (G==1);
if (DEBUG) LOG.debug("G = " + G);
}
} while (G==N);
if (DEBUG) LOG.debug("Found factor of " + N + " = " + G);
} while (G==n);
if (DEBUG) LOG.debug("Found factor of " + nOriginal + " = " + G);
return G;
}

Expand All @@ -104,8 +108,8 @@ public int findSingleFactor(int N) {
* @return (a+b) mod N
*/
private int addModN(int a, int b) {
int sum = a+b;
return sum<N ? sum : sum-N;
long sum = a + (long)b; // long is needed for the addition of 31 bit numbers
return (int) (sum<n ? sum : sum-n);
}

/**
Expand All @@ -114,6 +118,6 @@ private int addModN(int a, int b) {
* @return
*/
private int squareModN(long x) {
return (int) ((x * x) % N);
return (int) ((x * x) % n);
}
}

0 comments on commit 6ba39a4

Please sign in to comment.