Pollard's rho
Find a factor of a composite n with the sequence x² + 1: a slow and a fast pointer run along it until the gcd of their difference with n gives a factor.
Take the sequence x ← x² + 1 (mod n). Modulo an unknown prime factor p of n it has only p possible values, so
sooner or later it cycles, making a shape like the Greek letter ρ. By the birthday paradox, the cycle shows
up after about √p steps.
- Time:
about O(n^¼) steps - Space:
O(1) - CLRS, section 31.9
8051 = 83 × 97; after three moves the gcd gives the factor 97.
from math import gcddef pollard_rho(n):if n % 2 == 0:return 2# A fixed start and f(x) = x² + 1 instead of random ones, so a run is always the same.x = 2y = 2d = 1rows = []while d == 1:x = (x * x + 1) % n # tortoise: one stepy = (y * y + 1) % n # hare: two stepsy = (y * y + 1) % nd = gcd(abs(x - y), n)rows.append((x, y, d))if d == n:return Nonereturn d
Start
The table is still empty.
Local variables
Orange = changed in this step
Call stack
- pollard_rho()line 4
Explanation
The idea
Take the sequence x ← x² + 1 (mod n). Modulo an unknown prime factor p of n it has only p possible values, so
sooner or later it cycles, making a shape like the Greek letter ρ. By the birthday paradox, the cycle shows
up after about √p steps.
Finding the cycle without knowing p
Run two pointers along the sequence: x one step and y two steps per round (Floyd's tortoise and hare). When
they meet modulo p, p divides |x − y|; so gcd(|x − y|, n) gives a factor of n without knowing p in
advance.
Cost
About √p ≤ n^¼ steps, far fewer than the √n divisions of trial division. If the gcd reaches n itself, try again
with another f or start. Here the start and f are fixed, so a run is always the same.