Brent's improvement (in 1980) to Pollard's rho method is to extend the core idea by generalizing the cycle by powers of two.
Full details here, with due reference to Floyd - 
http://web.comlab.ox.ac.uk/oucl/work/richard.brent/pd/rpb051i.pdf
The following from Wikipedia:
Input: n, the integer to be factored; x0, such that 0 ≤ x0 ≤ n; m such that m > 0; and f(x), a pseudo-random function modulo n.
Output: a non-trivial factor of n, or failure.
 1. y ← x0, r ← 1, q ← 1.
 2. Do:
 1. x ← y
 2. For i = 1 To r:
 1. y ← f(y)
 3. k ← 0
 4. Do:
 1. ys ← y
 2. For i = 1 To min(m, r − k):
 1. y ← f(y)
 2. q ← (q × |x − y|) mod n
 3. g ← GCD(q, n)
 4. k ← k + m
 5. Until (k ≥ r or g > 1)
 6. r ← 2r
 3. Until g > 1
 4. If g = n then
 1. Do:
 1. ys ← f(ys)
 2. g ← GCD(|x − ys|, n)
 2. Until g > 1
 5. If g = n then return failure, else return g
Also, the pseudocode immediately below is taken from a PD document by Connelly Barnes of Oregon State University
http://oregonstate.edu/~barnesc/documents/factoring.pdf
function brentFactor(N) 
  # Initial values x(i) and x(m) for i = 0. 
  xi  := 2 
  xm  := 2 
  for i from 1 to infinity 
    # Find x(i) from x(i-1). 
    xi := (xi ^ 2 + 1) % N 
    s := gcd(xi - xm, N) 
    if s <> 1 and s <> N then 
      return s, N/s 
    end if 
    if integralPowerOf2(i) then 
      xm := xi 
    end if 
  end do 
end function 
Here is its Java implementation from superfac9:
 BigInteger factorizebrent(BigInteger n) {
  BigInteger k = new BigInteger("1");
  BigInteger r = new BigInteger("1");
  BigInteger i = new BigInteger("1");
  BigInteger m = new BigInteger("1");
  BigInteger iter = new BigInteger("1");
  BigInteger z = new BigInteger("1");
  BigInteger x = new BigInteger("1");
  BigInteger y = new BigInteger("1");
  BigInteger q = new BigInteger("1");
  BigInteger ys = new BigInteger("1");
  m=TEN;
  r=ONE;
  iter=ZERO;
  z=ZERO;
  y=z;
  q=ONE;
  do {
   x=y;
   for (i=ONE;i.compareTo(r)<=0;i=i.add(ONE)) y=((y.multiply(y)).add(THREE)).mod(n);
   k=ZERO;
   do {
    iter=iter.add(ONE);
//    System.out.print("iter=" + iter.toString() + '\r');
    ys=y;
    for (i=ONE;i.compareTo(mr_min(m,r.subtract(k)))<=0;i=i.add(ONE)) {
     y=((y.multiply(y)).add(THREE)).mod(n);
     q=((y.subtract(x)).multiply(q)).mod(n);
    }
    z=n.gcd(q);
    k=k.add(m);
   } while (k.compareTo(r)<0 && z.compareTo(ONE)==0);
   r=r.multiply(TWO);
  } while (z.compareTo(ONE)==0 && iter.compareTo(TENTHOUSAND)<0);
  if (z.compareTo(n)==0) do {
   ys=((ys.multiply(ys)).add(THREE)).mod(n);
   z=n.gcd(ys.subtract(x));
  } while (z.compareTo(ONE)==0);
  return z;
 }
Achievements of this method include the factorization, in 1980, of the eighth Fermat number:
http://wwwmaths.anu.edu.au/~brent/pub/pub061.html
Monday, 5 November 2007
Subscribe to:
Post Comments (Atom)
No comments:
Post a Comment