2626/**
2727 * Brents's improvement of Pollard's Rho algorithm, following [Richard P. Brent: An improved Monte Carlo Factorization Algorithm, 1980].
2828 *
29+ * Improvement by Dave McGuigan:
30+ * Use squareAddModN() instead of nested addModN(squareModN())
31+ *
2932 * @author Tilman Neumann
3033 */
3134public class PollardRhoBrent extends FactorAlgorithm {
@@ -60,14 +63,14 @@ public BigInteger findSingleFactor(BigInteger N) {
6063 do {
6164 x = y ;
6265 for (int i =1 ; i <=r ; i ++) {
63- y = addModN ( y . multiply ( y ). mod ( N ) , c );
66+ y = squareAddModN ( y , c );
6467 }
6568 int k = 0 ;
6669 do {
6770 ys = y ;
6871 final int iMax = Math .min (m , r -k );
6972 for (int i =1 ; i <=iMax ; i ++) {
70- y = addModN ( y . multiply ( y ). mod ( N ) , c );
73+ y = squareAddModN ( y , c );
7174 final BigInteger diff = x .compareTo (y ) < 0 ? y .subtract (x ) : x .subtract (y );
7275 q = diff .multiply (q ).mod (N );
7376 }
@@ -81,7 +84,7 @@ public BigInteger findSingleFactor(BigInteger N) {
8184 } while (G .equals (I_1 ));
8285 if (G .equals (N )) {
8386 do {
84- ys = addModN (ys . multiply ( ys ). mod ( N ) , c );
87+ ys = squareAddModN (ys , c );
8588 final BigInteger diff = x .compareTo (ys ) < 0 ? ys .subtract (x ) : x .subtract (ys );
8689 G = diff .gcd (N );
8790 } while (G .equals (I_1 ));
@@ -91,15 +94,14 @@ public BigInteger findSingleFactor(BigInteger N) {
9194 if (DEBUG ) LOG .debug ("Found factor of " + N + " = " + G );
9295 return G ;
9396 }
94-
97+
9598 /**
96- * Addition modulo N, with <code>a, b < N</code>.
97- * @param a
98- * @param b
99- * @return (a+b ) mod N
99+ * Square and add modulo N, with <code>a, b < N</code>.
100+ * @param y
101+ * @param c
102+ * @return () mod N
100103 */
101- private BigInteger addModN (BigInteger a , BigInteger b ) {
102- BigInteger sum = a .add (b );
103- return sum .compareTo (N )<0 ? sum : sum .subtract (N );
104+ private BigInteger squareAddModN (BigInteger y , BigInteger c ) {
105+ return y .multiply (y ).add (c ).mod (N );
104106 }
105107}
0 commit comments