rho1(n)=
{ my(x = 2,y = 5);
while(gcd(y-x,n) == 1,
x = (x^2+1)%n;
y = (y^2+1)%n; y = (y^2+1)%n
);
gcd(n, y-x);
}
rho2(n)=
{ my(m = rho1(n));
if (isprime(m), print(m), rho2(m));
if (isprime(n/m), print(n/m), rho2(n/m));
}
rho(n)=
{ my(m = factor(n,0));
print(m); m = m[,1]; n = m[#m];
if (!isprime(n), rho2(n));
}
rhobrent(n)=
{ my(x,y,x1,k,l,p,c,g);
x1 = x = y = 2;
k = l = p = 1;
c = 0;
while (1,
x=(x^2+1)%n; p=(p*(x1-x))%n;
c++;
if (c==20,
if (gcd(p,n)>1, break);
y = x; c = 0
);
k--;
if (!k,
if (gcd(p,n)>1, break);
x1 = x; k = l; l <<= 1;
for (j=1,k, x = (x^2+1)%n);
y = x; c = 0
)
);
until (g != 1,
y = (y^2+1)%n;
g = gcd(x1-y,n)
);
if (g==n, error("algorithm fails"));
g;
}