Math-Prime-Util
view release on metacpan or search on metacpan
Xi = addmod(mont_mulmod64(Xi,Xi,n), a, n);
m = ABSDIFF(Xi,Xm);
while (--irounds > 0) {
Xi = addmod(mont_mulmod64(Xi,Xi,n), a, n);
f = ABSDIFF(Xi,Xm);
m = mont_mulmod64(m, f, n);
}
}
f = gcd_ui(m, n);
if (f != 1)
break;
}
/* If f == 1, then we didn't find a factor. Move on. */
if (f == 1) {
r *= 2;
continue;
}
if (f == n) { /* back up, with safety */
Xi = Xs;
do {
if (n < (1ULL << 63) || a == mont1)
Xi = mont_mulmod(Xi,Xi+a,n);
else
Xi = addmod(mont_mulmod(Xi,Xi,n),a,n);
m = ABSDIFF(Xi,Xm);
f = gcd_ui(m, n);
} while (f == 1 && r-- != 0);
}
if (f == 0 || f == n) {
if (fails-- <= 0) break;
Xi = Xm = mont1;
a = addmod(a, mont_geta(11,n), n);
continue;
}
return found_factor(n, f, factors);
}
return no_factor(n,factors);
}
#else
/* Pollard Rho with Brent's updates. */
int pbrent_factor(UV n, UV *factors, UV rounds, UV a)
{
UV f, m, r, Xi, Xm;
const UV inner = (n <= 4000000000UL) ? 32 : 160;
int fails = 6;
MPUassert( (n >= 3) && ((n%2) != 0) , "bad n in pbrent_factor");
r = f = Xi = Xm = 1;
while (rounds > 0) {
UV rleft = (r > rounds) ? rounds : r;
UV saveXi = Xi;
/* Do rleft rounds, inner at a time */
while (rleft > 0) {
UV dorounds = (rleft > inner) ? inner : rleft;
saveXi = Xi;
rleft -= dorounds;
rounds -= dorounds;
Xi = sqraddmod(Xi, a, n); /* First iteration, no mulmod needed */
m = ABSDIFF(Xi,Xm);
while (--dorounds > 0) { /* Now do inner-1=63 more iterations */
Xi = sqraddmod(Xi, a, n);
f = ABSDIFF(Xi,Xm);
m = mulmod(m, f, n);
}
f = gcd_ui(m, n);
if (f != 1)
break;
}
/* If f == 1, then we didn't find a factor. Move on. */
if (f == 1) {
r *= 2;
Xm = Xi;
continue;
}
if (f == n) { /* back up, with safety */
Xi = saveXi;
do {
Xi = sqraddmod(Xi, a, n);
f = gcd_ui( ABSDIFF(Xi,Xm), n);
} while (f == 1 && r-- != 0);
}
if (f == 0 || f == n) {
if (fails-- <= 0) break;
Xm = addmod(Xm, 11, n);
Xi = Xm;
a++;
continue;
}
return found_factor(n, f, factors);
}
return no_factor(n,factors);
}
#endif
/* Pollard's Rho. */
int prho_factor(UV n, UV *factors, UV rounds)
{
UV f, i, m, oldU, oldV;
const UV inner = 64;
UV U = 7;
UV V = 7;
UV a = 1;
int fails = 3;
MPUassert( (n >= 3) && ((n%2) != 0) , "bad n in prho_factor");
rounds = (rounds + inner - 1) / inner;
while (rounds-- > 0) {
m = 1; oldU = U; oldV = V;
for (i = 0; i < inner; i++) {
U = sqraddmod(U, a, n);
V = sqraddmod(V, a, n);
V = sqraddmod(V, a, n);
f = (U > V) ? U-V : V-U;
m = mulmod(m, f, n);
}
f = gcd_ui(m, n);
if (f == 1)
continue;
( run in 0.784 second using v1.01-cache-2.11-cpan-71847e10f99 )