Skip to content
Related Articles
Open in App
Not now

Related Articles

Fermat’s Factorization method for large numbers

Improve Article
Save Article
  • Last Updated : 16 Mar, 2023
Improve Article
Save Article

Given a large number N, the task is to divide this number into a product of two factors, using Fermat’s Factorisation method. Examples

Input: N = 105327569 Output: 10223, 10303 Input: N = 249803 Output: 23, 10861

Fermat Factorization: Fermat’s Factorization method is based on the representation of an odd integer as the difference of two squares. For an integer N, we want a and b such as:

N = a2 - b2 = (a+b)(a-b) 

where (a+b) and (a-b) are 
the factors of the number N.

Approach:

  1. Get the number as an object of BigInteger class
  2. Find the square root of N.
  3. It is guaranteed that the value of a is greater than sqrt(N) and value of b less than sqrt(N).
  4. Take the value of sqrt(n) as a and increment the number until and unless a number b is found such that N – a^2 is a perfect square.

Below is the implementation of the above approach: 

Java




// Java program for Fermat's Factorization
// method for large numbers
 
import java.math.*;
import java.util.*;
 
class Solution {
 
    // Function to find the Floor
    // of square root of a number
    public static BigInteger sqrtF(BigInteger x)
        throws IllegalArgumentException
    {
        // if x is less than 0
        if (x.compareTo(BigInteger.ZERO) < 0) {
            throw new IllegalArgumentException(
                "Negative argument.");
        }
 
        // if x==0 or x==1
        if (x.equals(BigInteger.ZERO)
            || x.equals(BigInteger.ONE)) {
            return x;
        }
 
        BigInteger two
            = BigInteger.valueOf(2L);
        BigInteger y;
 
        // run a loop
        y = x.divide(two);
        while (y.compareTo(x.divide(y)) > 0)
            y = ((x.divide(y)).add(y))
                    .divide(two);
        return y;
    }
 
    // function to find the Ceil
    // of square root of a number
    public static BigInteger sqrtC(BigInteger x)
        throws IllegalArgumentException
    {
        BigInteger y = sqrtF(x);
 
        if (x.compareTo(y.multiply(y)) == 0) {
            return y;
        }
 
        else {
            return y.add(BigInteger.ONE);
        }
    }
 
    // Fermat factorisation
    static String FermatFactors(BigInteger n)
    {
        // constants
        BigInteger ONE = new BigInteger("1");
        BigInteger ZERO = new BigInteger("0");
        BigInteger TWO = new BigInteger("2");
 
        // if n%2 ==0 then return the factors
        if (n.mod(TWO).equals(ZERO)) {
            return n.divide(TWO)
                       .toString()
                + ", 2";
        }
 
        // find the square root
        BigInteger a = sqrtC(n);
 
        // if the number is a perfect square
        if (a.multiply(a).equals(n)) {
            return a.toString()
                + ", " + a.toString();
        }
 
        // else perform factorisation
        BigInteger b;
        while (true) {
            BigInteger b1 = a.multiply(a)
                                .subtract(n);
            b = sqrtF(b1);
 
            if (b.multiply(b).equals(b1))
                break;
            else
                a = a.add(ONE);
        }
 
        return a.subtract(b).toString()
            + ", " + a.add(b).toString();
    }
 
    // Driver code
    public static void main(String args[])
    {
        String N = "105327569";
 
        System.out.println(
            FermatFactors(
                new BigInteger(N)));
    }
}

Javascript




function sqrtF(x) {
  if (x < 0) {
    throw new Error("Negative argument.");
  }
 
  if (x === 0 || x === 1) {
    return x;
  }
 
  let y = BigInt(x >> 1n);
  while (y > BigInt(x / y)) {
    y = BigInt((BigInt(x) / BigInt(y) + BigInt(y)) >> 1n);
  }
  return y;
}
 
function sqrtC(x) {
  const y = sqrtF(x);
 
  if (x === y * y) {
    return y;
  } else {
    return y + 1n;
  }
}
 
function FermatFactors(n) {
  const ONE = 1n;
  const ZERO = 0n;
  const TWO = 2n;
 
  if (n % TWO === ZERO) {
    return `${n / TWO}, 2`;
  }
 
  const a = sqrtC(n);
 
  if (a * a === n) {
    return `${a}, ${a}`;
  }
 
  let b;
  while (true) {
    const b1 = a * a - n;
    b = sqrtF(b1);
 
    if (b * b === b1) {
      break;
    } else {
      a += 1n;
    }
  }
 
  return `${a - b}, ${a + b}`;
}
 
const N = "105327569";
console.log(FermatFactors(BigInt(N)));

Output:

10223, 10303

Performance Analysis : 

Time Complexity: O(sqrt(N))
Space Complexity: O(1)


My Personal Notes arrow_drop_up
Related Articles

Start Your Coding Journey Now!