Function Repository Resource:

FactorIntegerFermat

Source Notebook

Factor an integer using Fermat's factorization algorithm

Contributed by: Sam Blake

ResourceFunction["FactorIntegerFermat"][n]

factors the integer n using Fermat's algorithm.

Details and Options

Fermat's factorization algorithm is based on the representation of an odd integer, N, as the difference of two squares, N=a2-b2=(a-b)(a+b). If neither factor equals 1, then it is a proper factorization of N.
Fermat’s factorization algorithm works best when a factor of N is close to .
Fermat’s factorization algorithm has been used to break weak RSA keys.
ResourceFunction["FactorIntegerFermat"] accepts the option MaxIterations, which limits how far ResourceFunction["FactorIntegerFermat"] searches for a factor of n. The default is 216.

Examples

Basic Examples (2) 

A trivial factorization for Fermat's algorithm:

In[1]:=
ResourceFunction[
 "FactorIntegerFermat"][1606938044258990275541962092664413505580401416855058301074367]
Out[1]=

A slightly larger example:

In[2]:=
ResourceFunction[
 "FactorIntegerFermat"][265613988875874769338781322035779626829233357014667387578556441708419524100796833638525071933897]
Out[2]=

Scope (2) 

In the following example, we see that the factor returned by FactorIntegerFermat is close to :

In[3]:=
bign = 240996652064411002800472575812344220719424874389331766063202278486530840068559048927230554671091;
facs = ResourceFunction["FactorIntegerFermat"][bign]
Out[4]=

The ratio of size difference between the square root and a factor to the size of the square root is around 1/2, which means the factor is removed from the square root of bign by approximately its fourth root.

In[5]:=
sqrt = bign // Sqrt // Floor;
Log[sqrt - facs[[1]]]/Log[sqrt] // N
Out[6]=
In[7]:=
sqrt - facs[[1]] // Round
Out[7]=
In[8]:=
bign^(1/4) // Round
Out[8]=

FactorIntegerFermat scales well to larger semiprimes, providing the two primes are close to :

In[9]:=
p1 = NextPrime[2^2000 - 2^1006];
p2 = NextPrime[2^2000 + 2^1006];
prod = p1*p2;
prod // ResourceFunction["FactorIntegerFermat"] // RepeatedTiming
Out[12]=

Options (2) 

MaxIterations (2) 

Factoring the following semiprime requires 262143 iterations, which is more than the default number of iterations (216):

In[13]:=
ResourceFunction[
 "FactorIntegerFermat"][10715086071862673209484250490600018105614048117055336074437503883703510511249361224931983788156958581275946729175531468251871452856923140435984574143903706136498819800180294396169989554930875672786351231768129652579095803100072779709877039363679564582043463808490862461439663296755827156821135555868597]
Out[13]=

Increasing MaxIterations obtains the factorization:

In[14]:=
ResourceFunction[
 "FactorIntegerFermat"][10715086071862673209484250490600018105614048117055336074437503883703510511249361224931983788156958581275946729175531468251871452856923140435984574143903706136498819800180294396169989554930875672786351231768129652579095803100072779709877039363679564582043463808490862461439663296755827156821135555868597, MaxIterations -> 1*^6]
Out[14]=

Properties and Relations (2) 

Lehman extended Fermat's algorithm to factor N=p q using a rational approximation to the ratio of the factors, p/q:

In[15]:=
ResourceFunction[
 "FactorIntegerFermat"][23813249614209455339425406274200110969]
Out[15]=
In[16]:=
23813249614209455339425406274200110969;
ResourceFunction["FactorIntegerFermat"][10277 1199 %];
GCD[%, %%]
Out[18]=

This works as 10277/1199 is a good approximation to p/q:

In[19]:=
10277/1199 - 14286732670391399261/1666808651327348429 // N
Out[19]=

Possible Issues (3) 

Unlike FactorInteger, FactorIntegerFermat is not a general purpose factoring algorithm:

In[20]:=
p1 = RandomPrime[{2^127, 2^128}]
Out[20]=
In[21]:=
p2 = RandomPrime[{2^63, 2^64}]
Out[21]=
In[22]:=
p1 p2
Out[22]=

FactorInteger succeeds:

In[23]:=
FactorInteger[p1 p2] // Timing
Out[23]=

FactorIntegerFermat does not handle this case:

In[24]:=
ResourceFunction["FactorIntegerFermat"][p1 p2] // Timing
Out[24]=

Publisher

Sam Blake

Requirements

Wolfram Language 13.0 (December 2021) or above

Version History

  • 1.0.0 – 22 November 2023

Related Resources

Author Notes

This implementation could be improved by directly calling GNU-MP routines for integer square roots (mpz_sqrtrem) and checking for perfect squares (mpz_perfect_square_p).

License Information