Pollard's p-1

Factorising N when we know a factor is smooth

If we say that N=pqN=pq, where p,qp,q are prime, then we can also say that for any a,ka,k:

ak(pāˆ’1)ā‰”1modā€‰ā€‰pa^{k(p-1)} \equiv 1 \mod p

Due to Fermat's Little Theorem. This would mean ak(pāˆ’1)āˆ’1a^{k(p-1)} - 1 is a factor of pp and therefore NN.

Overview

Let us say that L=k(pāˆ’1)L=k(p-1). If aLā‰”1modā€‰ā€‰pa^L \equiv 1 \mod p, then pāˆ£aLāˆ’1p \mid a^L-1. Since pāˆ£Np \mid N, we know that pāˆ£gcd(aLāˆ’1,N)p \mid gcd(a^L-1, N).

This may seem all well and good, but how does this help us? We don't know pp, nor do we have a way of calculating kk.

What we actually do here is guess the value of LL by (effectively) brute force. Essentially we put aa to the power of integers with a huge number of prime factors, so it's all the more likely that the factors of pāˆ’1p-1 are there. Once we put it to the powers, we can calculate the gcd(aLāˆ’1,N)gcd(a^L-1, N) and if it is not equal to 00 then we have factorised NN successfully.

The most common technique is to calculate ak!modā€‰ā€‰Na^{k!} \mod N and then calculate the GCD from there. We can make this into a more efficient approach by repeatedly putting it to the power of one greater than the previous iteration, e.g. calculate a,a2,(a2)3,((a2)3)4,...a,a^2,(a^2)^3,((a^2)^3)^4,... and calculate the GCD each time - this way, we will have a wealth of factors. A common choice of aa is 22.

Example

Let's try and factorise 713713 using Pollard's pāˆ’1p-1:

21ā‰”2modā€‰ā€‰713,ā€‰ā€‰gcd(1,713)==122ā‰”4modā€‰ā€‰713,ā€‰ā€‰gcd(3,713)==143ā‰”64modā€‰ā€‰713,ā€‰ā€‰gcd(63,713)==1644ā‰”326modā€‰ā€‰713,ā€‰ā€‰gcd(325,713)==13265ā‰”311modā€‰ā€‰713,ā€‰ā€‰gcd(310,713)==312 ^ 1 \equiv 2 \mod 713, \,\, gcd(1, 713) == 1 \\ 2 ^ 2 \equiv 4 \mod 713, \,\, gcd(3, 713) == 1 \\ 4 ^ 3 \equiv 64 \mod 713, \,\, gcd(63, 713) == 1 \\ 64 ^ 4 \equiv 326 \mod 713, \,\, gcd(325, 713) == 1 \\ 326 ^ 5 \equiv 311 \mod 713, \,\, gcd(310, 713) == 31

We get to 25!modā€‰ā€‰7132^{5!} \mod 713, and find that gcd(310,713)=31gcd(310, 713)=31ā€‹. We have successfully factorised NN!

Applications

This algorithm is useful when we know pp is smooth, meaning it has lots of small prime factors. If this is the case, the iterative approach is more likely to include pāˆ’1p-1 sooner rather than later. This leads to the concept of safe primes, primes in the form p=2q+1p=2q+1 where qq is also a prime (called a Sophie Germain prime). In this case, pāˆ’1p-1 is not smooth.

Sage Code

We can implement this algorithm really easily in Sage:

def pollards(n, iterations=50):
    R = IntegerModRing(n)
    cur = R(2)
    
    for i in range(2, iterations):
        print(f'{cur} ^ {i} = {cur**i}')
        
        cur **= i
        tst = gcd(cur-1, n)
        
        print(f'gcd({cur-1}, {n}) = {tst}')
        
        if tst != 1:
            return tst
    else:
        return None

You can remove the print() functions as they are completely unneccessary, but the logging may help visualise what it does.

Last updated