Skip to content

Commit f1b3a10

Browse files
committed
add unit tests for more PollardRho variants
1 parent 766c6ee commit f1b3a10

File tree

7 files changed

+526
-0
lines changed

7 files changed

+526
-0
lines changed
Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
/*
2+
* java-math-library is a Java library focused on number theory, but not necessarily limited to it. It is based on the PSIQS 4.0 factoring project.
3+
* Copyright (C) 2018-2025 Tilman Neumann - tilman.neumann@web.de
4+
*
5+
* This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License
6+
* as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version.
7+
*
8+
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied
9+
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
10+
*
11+
* You should have received a copy of the GNU General Public License along with this program;
12+
* if not, see <http://www.gnu.org/licenses/>.
13+
*/
14+
package de.tilman_neumann.jml.factor.pollardRho;
15+
16+
import java.math.BigInteger;
17+
import java.util.List;
18+
19+
import org.apache.logging.log4j.LogManager;
20+
import org.apache.logging.log4j.Logger;
21+
import org.junit.BeforeClass;
22+
import org.junit.Test;
23+
24+
import de.tilman_neumann.jml.factor.FactorTestInfrastructure;
25+
import de.tilman_neumann.util.ConfigUtil;
26+
import de.tilman_neumann.util.SortedMultiset;
27+
28+
import static org.junit.Assert.assertEquals;
29+
import static org.junit.Assert.assertNotEquals;
30+
31+
public class PollardRho31Test {
32+
private static final Logger LOG = LogManager.getLogger(PollardRho31Test.class);
33+
34+
private static final PollardRho31 pollardRho = new PollardRho31();
35+
36+
@BeforeClass
37+
public static void setup() {
38+
ConfigUtil.initProject();
39+
}
40+
41+
@Test
42+
public void testSmallestComposites() {
43+
List<Integer> fails = FactorTestInfrastructure.testSmallComposites(100000, pollardRho);
44+
assertEquals("Failed to factor n = " + fails, 0, fails.size());
45+
}
46+
47+
@Test
48+
public void testCompositesWithSmallFactors() {
49+
assertFactorizationSuccess(949443, "3 * 11 * 28771"); // 20 bit
50+
assertFactorizationSuccess(996433, "31 * 32143"); // 20 bit
51+
assertFactorizationSuccess(1340465, "5 * 7 * 38299"); // 21 bit
52+
assertFactorizationSuccess(1979435, "5 * 395887"); // 21 bit
53+
assertFactorizationSuccess(2514615, "3 * 5 * 167641"); // 22 bit
54+
assertFactorizationSuccess(5226867, "3^2 * 580763"); // 23 bit
55+
assertFactorizationSuccess(10518047, "61 * 172427"); // 24 bit
56+
assertFactorizationSuccess(30783267, "3^3 * 1140121"); // 25 bit
57+
assertFactorizationSuccess(62230739, "67 * 928817"); // 26 bit
58+
assertFactorizationSuccess(84836647, "7 * 17 * 712913"); // 27 bit
59+
assertFactorizationSuccess(94602505, "5 * 18920501"); // 27 bit
60+
assertFactorizationSuccess(258555555, "3^2 * 5 * 5745679"); // 28 bit
61+
assertFactorizationSuccess(436396385, "5 * 87279277"); // 29 bit
62+
assertFactorizationSuccess(612066705, "3 * 5 * 40804447"); // 30 bit
63+
assertFactorizationSuccess(2017001503, "11 * 183363773"); // 31 bit
64+
assertFactorizationSuccess(712869263, "89 * 8009767"); // 30 bit
65+
assertFactorizationSuccess(386575807, "73 * 5295559"); // 29 bit
66+
assertFactorizationSuccess(569172749, "83 * 6857503"); // 30 bit
67+
}
68+
69+
@Test
70+
public void testSquares() {
71+
assertFactorizationSuccess(100140049, "10007^2"); // 27 bit
72+
}
73+
74+
private void assertFactorizationSuccess(long N, String expectedPrimeFactorizationStr) {
75+
BigInteger NBig = BigInteger.valueOf(N);
76+
LOG.info("Test " + N + " (" + NBig.bitLength() + " bit)");
77+
SortedMultiset<BigInteger> factors = pollardRho.factor(NBig);
78+
LOG.info(N + " = " + factors.toString("*", "^"));
79+
assertEquals(expectedPrimeFactorizationStr, factors.toString("*", "^"));
80+
}
81+
82+
@SuppressWarnings("unused")
83+
private void assertFactorizationError(long N, String expectedPrimeFactorizationStr) {
84+
BigInteger NBig = BigInteger.valueOf(N);
85+
LOG.info("Test " + N + " (" + NBig.bitLength() + " bit)");
86+
SortedMultiset<BigInteger> factors = pollardRho.factor(NBig);
87+
LOG.info(N + " = " + factors.toString("*", "^"));
88+
assertNotEquals(expectedPrimeFactorizationStr, factors.toString("*", "^"));
89+
}
90+
}
Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
/*
2+
* java-math-library is a Java library focused on number theory, but not necessarily limited to it. It is based on the PSIQS 4.0 factoring project.
3+
* Copyright (C) 2018-2025 Tilman Neumann - tilman.neumann@web.de
4+
*
5+
* This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License
6+
* as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version.
7+
*
8+
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied
9+
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
10+
*
11+
* You should have received a copy of the GNU General Public License along with this program;
12+
* if not, see <http://www.gnu.org/licenses/>.
13+
*/
14+
package de.tilman_neumann.jml.factor.pollardRho;
15+
16+
import java.math.BigInteger;
17+
import java.util.List;
18+
19+
import org.apache.logging.log4j.LogManager;
20+
import org.apache.logging.log4j.Logger;
21+
import org.junit.BeforeClass;
22+
import org.junit.Test;
23+
24+
import de.tilman_neumann.jml.factor.FactorTestInfrastructure;
25+
import de.tilman_neumann.util.ConfigUtil;
26+
import de.tilman_neumann.util.SortedMultiset;
27+
28+
import static org.junit.Assert.assertEquals;
29+
import static org.junit.Assert.assertNotEquals;
30+
31+
public class PollardRhoBrent31Test {
32+
private static final Logger LOG = LogManager.getLogger(PollardRhoBrent31Test.class);
33+
34+
private static final PollardRhoBrent31 pollardRho = new PollardRhoBrent31();
35+
36+
@BeforeClass
37+
public static void setup() {
38+
ConfigUtil.initProject();
39+
}
40+
41+
@Test
42+
public void testSmallestComposites() {
43+
List<Integer> fails = FactorTestInfrastructure.testSmallComposites(100000, pollardRho);
44+
assertEquals("Failed to factor n = " + fails, 0, fails.size());
45+
}
46+
47+
@Test
48+
public void testCompositesWithSmallFactors() {
49+
assertFactorizationSuccess(949443, "3 * 11 * 28771"); // 20 bit
50+
assertFactorizationSuccess(996433, "31 * 32143"); // 20 bit
51+
assertFactorizationSuccess(1340465, "5 * 7 * 38299"); // 21 bit
52+
assertFactorizationSuccess(1979435, "5 * 395887"); // 21 bit
53+
assertFactorizationSuccess(2514615, "3 * 5 * 167641"); // 22 bit
54+
assertFactorizationSuccess(5226867, "3^2 * 580763"); // 23 bit
55+
assertFactorizationSuccess(10518047, "61 * 172427"); // 24 bit
56+
assertFactorizationSuccess(30783267, "3^3 * 1140121"); // 25 bit
57+
assertFactorizationSuccess(62230739, "67 * 928817"); // 26 bit
58+
assertFactorizationSuccess(84836647, "7 * 17 * 712913"); // 27 bit
59+
assertFactorizationSuccess(94602505, "5 * 18920501"); // 27 bit
60+
assertFactorizationSuccess(258555555, "3^2 * 5 * 5745679"); // 28 bit
61+
assertFactorizationSuccess(436396385, "5 * 87279277"); // 29 bit
62+
assertFactorizationSuccess(612066705, "3 * 5 * 40804447"); // 30 bit
63+
assertFactorizationSuccess(2017001503, "11 * 183363773"); // 31 bit
64+
assertFactorizationSuccess(712869263, "89 * 8009767"); // 30 bit
65+
assertFactorizationSuccess(386575807, "73 * 5295559"); // 29 bit
66+
assertFactorizationSuccess(569172749, "83 * 6857503"); // 30 bit
67+
}
68+
69+
@Test
70+
public void testSquares() {
71+
assertFactorizationSuccess(100140049, "10007^2"); // 27 bit
72+
}
73+
74+
private void assertFactorizationSuccess(long N, String expectedPrimeFactorizationStr) {
75+
BigInteger NBig = BigInteger.valueOf(N);
76+
LOG.info("Test " + N + " (" + NBig.bitLength() + " bit)");
77+
SortedMultiset<BigInteger> factors = pollardRho.factor(NBig);
78+
LOG.info(N + " = " + factors.toString("*", "^"));
79+
assertEquals(expectedPrimeFactorizationStr, factors.toString("*", "^"));
80+
}
81+
82+
@SuppressWarnings("unused")
83+
private void assertFactorizationError(long N, String expectedPrimeFactorizationStr) {
84+
BigInteger NBig = BigInteger.valueOf(N);
85+
LOG.info("Test " + N + " (" + NBig.bitLength() + " bit)");
86+
SortedMultiset<BigInteger> factors = pollardRho.factor(NBig);
87+
LOG.info(N + " = " + factors.toString("*", "^"));
88+
assertNotEquals(expectedPrimeFactorizationStr, factors.toString("*", "^"));
89+
}
90+
}
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
/*
2+
* java-math-library is a Java library focused on number theory, but not necessarily limited to it. It is based on the PSIQS 4.0 factoring project.
3+
* Copyright (C) 2018-2025 Tilman Neumann - tilman.neumann@web.de
4+
*
5+
* This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License
6+
* as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version.
7+
*
8+
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied
9+
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
10+
*
11+
* You should have received a copy of the GNU General Public License along with this program;
12+
* if not, see <http://www.gnu.org/licenses/>.
13+
*/
14+
package de.tilman_neumann.jml.factor.pollardRho;
15+
16+
import java.math.BigInteger;
17+
import java.util.List;
18+
19+
import org.apache.logging.log4j.LogManager;
20+
import org.apache.logging.log4j.Logger;
21+
import org.junit.BeforeClass;
22+
import org.junit.Test;
23+
24+
import de.tilman_neumann.jml.factor.FactorTestInfrastructure;
25+
import de.tilman_neumann.util.ConfigUtil;
26+
import de.tilman_neumann.util.SortedMultiset;
27+
28+
import static org.junit.Assert.assertEquals;
29+
30+
public class PollardRhoBrentModBlockTest {
31+
private static final Logger LOG = LogManager.getLogger(PollardRhoBrentModBlockTest.class);
32+
33+
private static final PollardRhoBrentModBlock pollardRho = new PollardRhoBrentModBlock();
34+
35+
@BeforeClass
36+
public static void setup() {
37+
ConfigUtil.initProject();
38+
}
39+
40+
@Test
41+
public void testSmallestComposites() {
42+
List<Integer> fails = FactorTestInfrastructure.testSmallComposites(100000, pollardRho);
43+
assertEquals("Failed to factor n = " + fails, 0, fails.size());
44+
}
45+
46+
@Test
47+
public void testSomeInputs() {
48+
assertFactorizationSuccess("9223372036854775807", "7^2 * 73 * 127 * 337 * 92737 * 649657"); // Long.MAX_VALUE = 2^63-1
49+
assertFactorizationSuccess("18446744073709551617", "274177 * 67280421310721"); // F6
50+
assertFactorizationSuccess("5679148659138759837165981543", "3^3 * 466932157 * 450469808245315337");
51+
assertFactorizationSuccess("8225267468394993133669189614204532935183709603155231863020477010700542265332938919716662623",
52+
"1234567891 * 1234567907 * 1234567913 * 1234567927 * 1234567949 * 1234567967 * 1234567981 * 1234568021 * 1234568029 * 1234568047");
53+
}
54+
55+
private void assertFactorizationSuccess(String oddNStr, String expectedPrimeFactorizationStr) {
56+
long t0, t1;
57+
t0 = System.currentTimeMillis();
58+
BigInteger N = new BigInteger(oddNStr);
59+
SortedMultiset<BigInteger> factorResult = pollardRho.factor(N);
60+
assertEquals(expectedPrimeFactorizationStr, factorResult.toString("*", "^"));
61+
t1 = System.currentTimeMillis();
62+
LOG.info("Factoring " + oddNStr + " took " + (t1-t0) + "ms");
63+
}
64+
}
Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
/*
2+
* java-math-library is a Java library focused on number theory, but not necessarily limited to it. It is based on the PSIQS 4.0 factoring project.
3+
* Copyright (C) 2018-2025 Tilman Neumann - tilman.neumann@web.de
4+
*
5+
* This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License
6+
* as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version.
7+
*
8+
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied
9+
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
10+
*
11+
* You should have received a copy of the GNU General Public License along with this program;
12+
* if not, see <http://www.gnu.org/licenses/>.
13+
*/
14+
package de.tilman_neumann.jml.factor.pollardRho;
15+
16+
import java.math.BigInteger;
17+
import java.util.List;
18+
19+
import org.apache.logging.log4j.LogManager;
20+
import org.apache.logging.log4j.Logger;
21+
import org.junit.BeforeClass;
22+
import org.junit.Test;
23+
24+
import de.tilman_neumann.jml.factor.FactorTestInfrastructure;
25+
import de.tilman_neumann.util.ConfigUtil;
26+
import de.tilman_neumann.util.SortedMultiset;
27+
28+
import static org.junit.Assert.assertEquals;
29+
import static org.junit.Assert.assertNotEquals;
30+
31+
public class PollardRhoBrentMontgomery32Test {
32+
private static final Logger LOG = LogManager.getLogger(PollardRhoBrentMontgomery32Test.class);
33+
34+
private static final PollardRhoBrentMontgomery32 pollardRho = new PollardRhoBrentMontgomery32();
35+
36+
@BeforeClass
37+
public static void setup() {
38+
ConfigUtil.initProject();
39+
}
40+
41+
@Test
42+
public void testSmallestComposites() {
43+
List<Integer> fails = FactorTestInfrastructure.testSmallComposites(100000, pollardRho);
44+
assertEquals("Failed to factor n = " + fails, 0, fails.size());
45+
}
46+
47+
@Test
48+
public void testCompositesWithSmallFactors() {
49+
assertFactorizationSuccess(949443, "3 * 11 * 28771"); // 20 bit
50+
assertFactorizationSuccess(996433, "31 * 32143"); // 20 bit
51+
assertFactorizationSuccess(1340465, "5 * 7 * 38299"); // 21 bit
52+
assertFactorizationSuccess(1979435, "5 * 395887"); // 21 bit
53+
assertFactorizationSuccess(2514615, "3 * 5 * 167641"); // 22 bit
54+
assertFactorizationSuccess(5226867, "3^2 * 580763"); // 23 bit
55+
assertFactorizationSuccess(10518047, "61 * 172427"); // 24 bit
56+
assertFactorizationSuccess(30783267, "3^3 * 1140121"); // 25 bit
57+
assertFactorizationSuccess(62230739, "67 * 928817"); // 26 bit
58+
assertFactorizationSuccess(84836647, "7 * 17 * 712913"); // 27 bit
59+
assertFactorizationSuccess(94602505, "5 * 18920501"); // 27 bit
60+
assertFactorizationSuccess(258555555, "3^2 * 5 * 5745679"); // 28 bit
61+
assertFactorizationSuccess(436396385, "5 * 87279277"); // 29 bit
62+
assertFactorizationSuccess(612066705, "3 * 5 * 40804447"); // 30 bit
63+
assertFactorizationSuccess(2017001503, "11 * 183363773"); // 31 bit
64+
assertFactorizationSuccess(712869263, "89 * 8009767"); // 30 bit
65+
assertFactorizationSuccess(386575807, "73 * 5295559"); // 29 bit
66+
assertFactorizationSuccess(569172749, "83 * 6857503"); // 30 bit
67+
}
68+
69+
@Test
70+
public void testSquares() {
71+
assertFactorizationSuccess(100140049, "10007^2"); // 27 bit
72+
}
73+
74+
private void assertFactorizationSuccess(long N, String expectedPrimeFactorizationStr) {
75+
BigInteger NBig = BigInteger.valueOf(N);
76+
LOG.info("Test " + N + " (" + NBig.bitLength() + " bit)");
77+
SortedMultiset<BigInteger> factors = pollardRho.factor(NBig);
78+
LOG.info(N + " = " + factors.toString("*", "^"));
79+
assertEquals(expectedPrimeFactorizationStr, factors.toString("*", "^"));
80+
}
81+
82+
@SuppressWarnings("unused")
83+
private void assertFactorizationError(long N, String expectedPrimeFactorizationStr) {
84+
BigInteger NBig = BigInteger.valueOf(N);
85+
LOG.info("Test " + N + " (" + NBig.bitLength() + " bit)");
86+
SortedMultiset<BigInteger> factors = pollardRho.factor(NBig);
87+
LOG.info(N + " = " + factors.toString("*", "^"));
88+
assertNotEquals(expectedPrimeFactorizationStr, factors.toString("*", "^"));
89+
}
90+
}

0 commit comments

Comments
 (0)