Skip to content

Commit f42079f

Browse files
committed
use PollardRhoBrentMontgomery64MH to factor 63 bit numbers
1 parent f64a1a3 commit f42079f

11 files changed

+34
-1
lines changed

src/main/java/de/tilman_neumann/jml/factor/CombinedFactorAlgorithm.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
import de.tilman_neumann.jml.factor.ecm.EllipticCurveMethod;
2828
import de.tilman_neumann.jml.factor.ecm.TinyEcm64MHInlined;
2929
import de.tilman_neumann.jml.factor.hart.HartFast2Mult;
30+
import de.tilman_neumann.jml.factor.pollardRho.PollardRhoBrentMontgomery64MH;
3031
import de.tilman_neumann.jml.factor.psiqs.PSIQS;
3132
import de.tilman_neumann.jml.factor.psiqs.PSIQS_U;
3233
import de.tilman_neumann.jml.factor.siqs.SIQS;
@@ -61,6 +62,7 @@ public class CombinedFactorAlgorithm extends FactorAlgorithm {
6162
private TDiv31Barrett tDiv31 = new TDiv31Barrett();
6263
private HartFast2Mult hart = new HartFast2Mult(true); // for general factor arguments, trial division is needed
6364
private TinyEcm64MHInlined tinyEcm = new TinyEcm64MHInlined();
65+
private PollardRhoBrentMontgomery64MH pollardRhoBrentMontgomery64MH = new PollardRhoBrentMontgomery64MH();
6466
private TDiv tdiv = new TDiv();
6567
private EllipticCurveMethod ecm = new EllipticCurveMethod(0);
6668

@@ -123,6 +125,7 @@ public BigInteger findSingleFactor(BigInteger N) {
123125
if (NBits<25) return tDiv31.findSingleFactor(N);
124126
if (NBits<46) return hart.findSingleFactor(N);
125127
if (NBits<63) return tinyEcm.findSingleFactor(N);
128+
if (NBits<64) return pollardRhoBrentMontgomery64MH.findSingleFactor(N);
126129
if (NBits<=150) return siqsForSmallArgs.findSingleFactor(N);
127130
return siqsForBigArgs.findSingleFactor(N);
128131
}

src/main/java/de/tilman_neumann/jml/factor/siqs/tdiv/TDiv_QS_2LP.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
import de.tilman_neumann.jml.factor.base.congruence.SmoothPerfect;
3636
import de.tilman_neumann.jml.factor.ecm.TinyEcm64MHInlined;
3737
import de.tilman_neumann.jml.factor.hart.HartFast2Mult;
38+
import de.tilman_neumann.jml.factor.pollardRho.PollardRhoBrentMontgomery64MH;
3839
import de.tilman_neumann.jml.factor.siqs.SIQSSmall;
3940
import de.tilman_neumann.jml.factor.siqs.data.SolutionArrays;
4041
import de.tilman_neumann.jml.factor.siqs.poly.SIQSPolyGenerator;
@@ -93,6 +94,7 @@ public class TDiv_QS_2LP implements TDiv_QS {
9394

9495
private HartFast2Mult hart = new HartFast2Mult(false);
9596
private TinyEcm64MHInlined tinyEcm = new TinyEcm64MHInlined();
97+
private PollardRhoBrentMontgomery64MH pollardRhoBrentMontgomery64MH = new PollardRhoBrentMontgomery64MH();
9698
// Nested SIQS is required for quite large N only, > 350 bit ?
9799
private SIQSSmall qsInternal;
98100

@@ -366,6 +368,9 @@ private AQPair test(BigInteger A, BigInteger QRest0, int x) {
366368
} else if (QRestBits<63) {
367369
if (DEBUG) LOG.debug("test(): pMax^2 = " + pMaxSquare + ", QRest = " + QRest + " (" + QRestBits + " bits) not prime -> use tinyEcm");
368370
factor1 = tinyEcm.findSingleFactor(QRest);
371+
} else if (QRestBits<64) {
372+
if (DEBUG) LOG.debug("test(): pMax^2 = " + pMaxSquare + ", QRest = " + QRest + " (" + QRestBits + " bits) not prime -> use pollardRhoBrentMontgomery64MH");
373+
factor1 = pollardRhoBrentMontgomery64MH.findSingleFactor(QRest);
369374
} else {
370375
if (DEBUG) LOG.debug("test(): pMax^2 = " + pMaxSquare + ", QRest = " + QRest + " (" + QRestBits + " bits) not prime -> use qsInternal");
371376
factor1 = qsInternal.findSingleFactor(QRest);

src/main/java/de/tilman_neumann/jml/factor/siqs/tdiv/TDiv_QS_2LP_Full.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
import de.tilman_neumann.jml.factor.base.congruence.SmoothPerfect;
3535
import de.tilman_neumann.jml.factor.ecm.TinyEcm64MHInlined;
3636
import de.tilman_neumann.jml.factor.hart.HartFast2Mult;
37+
import de.tilman_neumann.jml.factor.pollardRho.PollardRhoBrentMontgomery64MH;
3738
import de.tilman_neumann.jml.factor.siqs.SIQSSmall;
3839
import de.tilman_neumann.jml.factor.siqs.data.SolutionArrays;
3940
import de.tilman_neumann.jml.factor.siqs.poly.SIQSPolyGenerator;
@@ -86,6 +87,7 @@ public class TDiv_QS_2LP_Full implements TDiv_QS {
8687

8788
private HartFast2Mult hart = new HartFast2Mult(false);
8889
private TinyEcm64MHInlined tinyEcm = new TinyEcm64MHInlined();
90+
private PollardRhoBrentMontgomery64MH pollardRhoBrentMontgomery64MH = new PollardRhoBrentMontgomery64MH();
8991
// Nested SIQS is required for quite large N only, > 350 bit ?
9092
private SIQSSmall qsInternal;
9193

@@ -305,6 +307,9 @@ private AQPair test(BigInteger A, BigInteger Q, int x) {
305307
} else if (QRestBits<63) {
306308
if (DEBUG) LOG.debug("test(): pMax^2 = " + pMaxSquare + ", QRest = " + QRest + " (" + QRestBits + " bits) not prime -> use tinyEcm");
307309
factor1 = tinyEcm.findSingleFactor(QRest);
310+
} else if (QRestBits<64) {
311+
if (DEBUG) LOG.debug("test(): pMax^2 = " + pMaxSquare + ", QRest = " + QRest + " (" + QRestBits + " bits) not prime -> use pollardRhoBrentMontgomery64MH");
312+
factor1 = pollardRhoBrentMontgomery64MH.findSingleFactor(QRest);
308313
} else {
309314
if (DEBUG) LOG.debug("test(): pMax^2 = " + pMaxSquare + ", QRest = " + QRest + " (" + QRestBits + " bits) not prime -> use qsInternal");
310315
factor1 = qsInternal.findSingleFactor(QRest);

src/main/java/de/tilman_neumann/jml/factor/siqs/tdiv/TDiv_QS_3LP.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
import de.tilman_neumann.jml.factor.base.congruence.SmoothPerfect;
3636
import de.tilman_neumann.jml.factor.ecm.TinyEcm64MHInlined;
3737
import de.tilman_neumann.jml.factor.hart.HartFast2Mult;
38+
import de.tilman_neumann.jml.factor.pollardRho.PollardRhoBrentMontgomery64MH;
3839
import de.tilman_neumann.jml.factor.siqs.SIQSSmall;
3940
import de.tilman_neumann.jml.factor.siqs.data.SolutionArrays;
4041
import de.tilman_neumann.jml.factor.siqs.poly.SIQSPolyGenerator;
@@ -93,6 +94,7 @@ public class TDiv_QS_3LP implements TDiv_QS {
9394

9495
private HartFast2Mult hart = new HartFast2Mult(false);
9596
private TinyEcm64MHInlined tinyEcm = new TinyEcm64MHInlined();
97+
private PollardRhoBrentMontgomery64MH pollardRhoBrentMontgomery64MH = new PollardRhoBrentMontgomery64MH();
9698
// Nested SIQS is required for quite large N only, > 350 bit ?
9799
private SIQSSmall qsInternal;
98100

@@ -369,6 +371,9 @@ private AQPair test(BigInteger A, BigInteger QRest0, int x) {
369371
} else if (QRestBits<63) {
370372
if (DEBUG) LOG.debug("test(): pMax^2 = " + pMaxSquare + ", QRest = " + QRest + " (" + QRestBits + " bits) not prime -> use tinyEcm");
371373
factor1 = tinyEcm.findSingleFactor(QRest);
374+
} else if (QRestBits<64) {
375+
if (DEBUG) LOG.debug("test(): pMax^2 = " + pMaxSquare + ", QRest = " + QRest + " (" + QRestBits + " bits) not prime -> use pollardRhoBrentMontgomery64MH");
376+
factor1 = pollardRhoBrentMontgomery64MH.findSingleFactor(QRest);
372377
} else {
373378
if (DEBUG) LOG.debug("test(): pMax^2 = " + pMaxSquare + ", QRest = " + QRest + " (" + QRestBits + " bits) not prime -> use qsInternal");
374379
factor1 = qsInternal.findSingleFactor(QRest);

src/main/java/de/tilman_neumann/jml/factor/siqs/tdiv/TDiv_QS_nLP.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
import de.tilman_neumann.jml.factor.base.congruence.SmoothPerfect;
3535
import de.tilman_neumann.jml.factor.ecm.TinyEcm64MHInlined;
3636
import de.tilman_neumann.jml.factor.hart.HartFast2Mult;
37+
import de.tilman_neumann.jml.factor.pollardRho.PollardRhoBrentMontgomery64MH;
3738
import de.tilman_neumann.jml.factor.siqs.SIQSSmall;
3839
import de.tilman_neumann.jml.factor.siqs.data.SolutionArrays;
3940
import de.tilman_neumann.jml.factor.siqs.poly.SIQSPolyGenerator;
@@ -92,6 +93,7 @@ public class TDiv_QS_nLP implements TDiv_QS {
9293

9394
private HartFast2Mult hart = new HartFast2Mult(false);
9495
private TinyEcm64MHInlined tinyEcm = new TinyEcm64MHInlined();
96+
private PollardRhoBrentMontgomery64MH pollardRhoBrentMontgomery64MH = new PollardRhoBrentMontgomery64MH();
9597
// Nested SIQS is required for quite large N only, > 350 bit ?
9698
private SIQSSmall qsInternal;
9799

@@ -379,6 +381,9 @@ private boolean factor_recurrent(BigInteger QRest) {
379381
} else if (QRestBits<63) {
380382
if (DEBUG) LOG.debug("factor_recurrent(): pMax^2 = " + pMaxSquare + ", QRest = " + QRest + " (" + QRestBits + " bits) not prime -> use tinyEcm");
381383
factor1 = tinyEcm.findSingleFactor(QRest);
384+
} else if (QRestBits<64) {
385+
if (DEBUG) LOG.debug("factor_recurrent(): pMax^2 = " + pMaxSquare + ", QRest = " + QRest + " (" + QRestBits + " bits) not prime -> use pollardRhoBrentMontgomery64MH");
386+
factor1 = pollardRhoBrentMontgomery64MH.findSingleFactor(QRest);
382387
} else {
383388
if (DEBUG) LOG.debug("factor_recurrent(): pMax^2 = " + pMaxSquare + ", QRest = " + QRest + " (" + QRestBits + " bits) not prime -> use qsInternal");
384389
factor1 = qsInternal.findSingleFactor(QRest);

src/main/java/de/tilman_neumann/jml/factor/siqs/tdiv/TDiv_QS_nLP_Full.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
import de.tilman_neumann.jml.factor.base.congruence.SmoothPerfect;
3434
import de.tilman_neumann.jml.factor.ecm.TinyEcm64MHInlined;
3535
import de.tilman_neumann.jml.factor.hart.HartFast2Mult;
36+
import de.tilman_neumann.jml.factor.pollardRho.PollardRhoBrentMontgomery64MH;
3637
import de.tilman_neumann.jml.factor.siqs.SIQSSmall;
3738
import de.tilman_neumann.jml.factor.siqs.data.SolutionArrays;
3839
import de.tilman_neumann.jml.factor.siqs.poly.SIQSPolyGenerator;
@@ -85,6 +86,7 @@ public class TDiv_QS_nLP_Full implements TDiv_QS {
8586

8687
private HartFast2Mult hart = new HartFast2Mult(false);
8788
private TinyEcm64MHInlined tinyEcm = new TinyEcm64MHInlined();
89+
private PollardRhoBrentMontgomery64MH pollardRhoBrentMontgomery64MH = new PollardRhoBrentMontgomery64MH();
8890
// Nested SIQS is required for quite large N only, > 350 bit ?
8991
private SIQSSmall qsInternal;
9092

@@ -317,6 +319,9 @@ private boolean factor_recurrent(BigInteger QRest) {
317319
} else if (QRestBits<63) {
318320
if (DEBUG) LOG.debug("factor_recurrent(): pMax^2 = " + pMaxSquare + ", QRest = " + QRest + " (" + QRestBits + " bits) not prime -> use tinyEcm");
319321
factor1 = tinyEcm.findSingleFactor(QRest);
322+
} else if (QRestBits<64) {
323+
if (DEBUG) LOG.debug("factor_recurrent(): pMax^2 = " + pMaxSquare + ", QRest = " + QRest + " (" + QRestBits + " bits) not prime -> use pollardRhoBrentMontgomery64MH");
324+
factor1 = pollardRhoBrentMontgomery64MH.findSingleFactor(QRest);
320325
} else {
321326
if (DEBUG) LOG.debug("factor_recurrent(): pMax^2 = " + pMaxSquare + ", QRest = " + QRest + " (" + QRestBits + " bits) not prime -> use qsInternal");
322327
factor1 = qsInternal.findSingleFactor(QRest);

src/test/java/de/tilman_neumann/jml/factor/CombinedFactorAlgorithmTest.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,7 @@ public void testSmallCompositesWithSmallFactors() {
8585
public void testSmallCompositesWithManyFactors() {
8686
assertFactorizationSuccess(35184372094495L, "5 * 13^2 * 17 * 19 * 29 * 47 * 271 * 349"); // 46 bit
8787
assertFactorizationSuccess(1096954293075013905L, "3 * 5 * 7^2 * 169681 * 8795650783"); // 60 bit
88+
assertFactorizationSuccess(9223372036854775807L, "7^2 * 73 * 127 * 337 * 92737 * 649657"); // Long.MAX_VALUE = 2^63-1
8889
assertFactorizationSuccess(1100087778366101931L, "3 * 7 * 43 * 89 * 199 * 263 * 307 * 881 * 967"); // Fibonacci(88), 60 bit
8990
}
9091

src/test/java/de/tilman_neumann/jml/factor/pollardRho/PollardRhoBrentMontgomery64MHInlinedTest.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,7 @@ public void testCompositesWithSmallFactors() {
8686
public void testCompositesWithManyFactors() {
8787
assertFactorizationSuccess(35184372094495L, "5 * 13^2 * 17 * 19 * 29 * 47 * 271 * 349"); // 46 bit
8888
assertFactorizationSuccess(1096954293075013905L, "3 * 5 * 7^2 * 169681 * 8795650783"); // 60 bit
89+
assertFactorizationSuccess(9223372036854775807L, "7^2 * 73 * 127 * 337 * 92737 * 649657"); // Long.MAX_VALUE = 2^63-1
8990
assertFactorizationSuccess(1100087778366101931L, "3 * 7 * 43 * 89 * 199 * 263 * 307 * 881 * 967"); // Fibonacci(88), 60 bit
9091
}
9192

src/test/java/de/tilman_neumann/jml/factor/pollardRho/PollardRhoBrentMontgomery64MHTest.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,7 @@ public void testCompositesWithSmallFactors() {
8686
public void testCompositesWithManyFactors() {
8787
assertFactorizationSuccess(35184372094495L, "5 * 13^2 * 17 * 19 * 29 * 47 * 271 * 349"); // 46 bit
8888
assertFactorizationSuccess(1096954293075013905L, "3 * 5 * 7^2 * 169681 * 8795650783"); // 60 bit
89+
assertFactorizationSuccess(9223372036854775807L, "7^2 * 73 * 127 * 337 * 92737 * 649657"); // Long.MAX_VALUE = 2^63-1
8990
assertFactorizationSuccess(1100087778366101931L, "3 * 7 * 43 * 89 * 199 * 263 * 307 * 881 * 967"); // Fibonacci(88), 60 bit
9091
}
9192

src/test/java/de/tilman_neumann/jml/factor/pollardRho/PollardRhoBrentMontgomery64Test.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,7 @@ public void testCompositesWithSmallFactors() {
8686
public void testCompositesWithManyFactors() {
8787
assertFactorizationSuccess(35184372094495L, "5 * 13^2 * 17 * 19 * 29 * 47 * 271 * 349"); // 46 bit
8888
assertFactorizationSuccess(1096954293075013905L, "3 * 5 * 7^2 * 169681 * 8795650783"); // 60 bit
89+
assertFactorizationSuccess(9223372036854775807L, "7^2 * 73 * 127 * 337 * 92737 * 649657"); // Long.MAX_VALUE = 2^63-1
8990
assertFactorizationSuccess(1100087778366101931L, "3 * 7 * 43 * 89 * 199 * 263 * 307 * 881 * 967"); // Fibonacci(88), 60 bit
9091
}
9192

0 commit comments

Comments
 (0)