Primality Test

Challenge Inside! : Find out where you stand! Try quiz, solve problems & win rewards!

Learn via video course

DSA Problem Solving for Interviews using Java
DSA Problem Solving for Interviews using Java
By Jitender Punia
Free
star4.9
Enrolled: 1000
DSA Problem Solving for Interviews using Java
DSA Problem Solving for Interviews using Java
Jitender Punia
Free
4.9
icon_usercirclecheck-01Enrolled: 1000
Start Learning

Overview

The Primality test is an algorithm for determining whether a given positive integer is a prime number or not.There are many methods to check whether a number is prime or not, like, the School Method, Trial Division Method, Fermat Primality test, and Miller-Rabin Primality test.

Scope of the Article

  • In this article we will discuss different primality tests in data structures.
  • All the primality tests are explained using steps and pseudocode in this article.
  • The complexity analysis of each method will also be discussed in this article.
  • The programs are implemented in C++, Java, and Python in this article.

:::


Takeaways

Algorithm for determining whether a given positive integer is a prime number or not :

  • School method
  • Trial Division Method
  • Fermat Primality Test
  • Miller-Rabin Primality Test

What is Primality Test?

The Primality test is an algorithm for determining whether a given positive integer is a prime number or not.

what is primality test

The primality of a number can also be checked by determining whether it is a composite number or not, because if the number is not a composite number nor 1, then it must be a prime number.

Example

Source Code - C++17

Source Code - Java (1.8)

Source Code - Python 3

The output is the same for all of the implementations as they peform the same thing, the only difference being the programming language.

Output

In the above examples, we are checking whether the given number is a prime number or not, to do so, we are iterating from 22 to n1n-1 to check if these numbers divide the given number. If they do, then the given number is not a prime number, else it is a prime number.

School method

The school method is a simple solution that comes first to everyone's mind for primality check as it is the simplest of all.

In the School Method algorithm, we iterate through all the numbers from 22 to n1n-1 (the number to be checked is nn) and check if they divide the number nn.

school method in primality test

Complexity Analysis

Time Complexity: O(N)O(N)

The time complexity of the School Method primality check is O(N)O(N) as we iterate N2N-2 times.

Space Complexity: O(1)O(1)

The space complexity here is constant.

The algorithm in the example above is School Method only.

Optimized School Method

In the School Method, we can do some optimizations like:

  • Instead of checking till nn, we will check till n\sqrt{n} because a factor of nn larger than n\sqrt{n} must be a multiple of a number smaller than n\sqrt{n} that has been already checked and should not be checked again.
  • We will first check the divisibility of nn by 22 and 33, then check its divisibility by numbers of the form 6k16k-1 and 6k+16k+1 starting at k=1k=1. We do so because any integer greater than 44 can be expressed in the form of 6k16k-1, 6k6k, 6k+16k+1, 6k+26k+2, 6k+36k+3, and 6k+46k+4 (for k>0k>0), but integers of the form 6k6k, 6k+26k+2, 6k+36k+3, and 6k+46k+4 will be divisible by 22 or 33.

Let's have a look at its implementation in the section below.

Implementation of the Optimized School Method

Source Code - C++17

Source Code - Java (1.8)

Source Code - Python 3

The output is the same for all of the implementations as they peform the same thing, the only difference being the programming language.

Output

In the above examples, we are checking whether the given number is a prime number or not, to do so, we are first checking its divisibility by 22 and 33, then checking its divisibility by numbers of the form 6k16k-1 and 6k+16k+1. If the given number is divisible by any number then it is not a prime number, else it is.

Complexity Analysis

Time complexity: O(N)O(\sqrt{N})

The asymptotic time complexity of the Optimized School Method primality check is O(N)O(\sqrt{N}) because we iterate N/6\sqrt{N}/6 (i+=6i+=6 in the for loop) times in this algorithm.

Space Complexity: O(1)O(1)

The space complexity here is constant.

Trial Division Method

The Trial Division Method is a primality check algorithm in which we accept some integer nn, check if any number from 2 to n\sqrt{n} divides the given integer, if a divisor is found then nn is a composite number, otherwise, it is a prime number. It is very similar to the school method.

trial division method in primality test

Complexity Analysis

Time complexity: O(N)O(\sqrt{N})

The time complexity of The Trial Division primality check is O(N)O(\sqrt{N}) as we iterate N1\sqrt{N}-1 times.

Space Complexity: O(1)O(1)

The space complexity here is constant.

Fermat Primality Test

The Fermat Primality test is a probabilistic method to determine whether the given integer is a probable prime number or not.

It is based on Fermat's Little Theorem that states if pp is a prime number and aa is not divisible by pp, then ap11(modp)a^{p-1} \equiv 1\;(mod\;p), i.e ap1=kp+1a^{p-1} = k*p + 1 (where kk is an integer constant).

If we want to test pp for a prime number, then we will pick some random integers aa that are not divisible by pp and see whether the congruency holds or not. If the congruency doesn't hold for a value of aa, then it will be a proof that pp is a composite number, but if the congruency holds for more than one values of aa, then pp is a probable prime number.

Algorithm Steps

  • Repeat the following kk times (higher value of kk indicates higher probability of correct results):
    • Handle corner cases for p<3p<3 (pp is the number to be tested).
    • Pick a random number aa in the range 1<a<p1 < a < p.
    • If ap1̸1(modp)a^{p-1} \not\equiv 1\;(mod\;p), then return FalseFalse.
  • Return TrueTrue, pp is probably a prime number.

Example

Let us assume, we have to check whether n=221n = 221 is a prime number or not. We will randomly pick a number aa in the range 1<a<2211 < a < 221. Then we will check whether the congruency holds or not.

For a=38a = 38,

3822111(mod221)38^{221-1} \equiv 1\;(mod\;221), as ap11(modp)a^{p-1} \equiv 1\;(mod\;p) =>382201(mod221)=> 38^{220} \equiv 1\;(mod\;221),

Now there can be two cases, 221221 is a prime number, or 3838 is a Fermat liar. To proceed, let's take a=24a=24.

but, 24220̸1(mod221)24^{220} \not\equiv 1\;(mod\;221), as 2422081(mod221)24^{220} \equiv 81\;(mod\;221).

This proves that 221221 is a composite number and 3838 is Fermat liar, 2424 being the Fermat witness for the compositeness of 221221.

Complexity Analysis

Time Complexity: O(Klog(N))O(K*log(N))

Here, KK is the number of iterations, and NN is the number to be tested for primality. log(N)log(N) is the time complexity for computing ap1a^{p-1} and the algorithm is repeated KK times. So the time complexity is O(Klog(N))O(K*log(N)).

Space Complexity: O(1)O(1)

There is no need for extra space, so the space complexity is constant.

The Fermat's little theorem is used for one more Primality test, called the Miller-Rabin Primality Test.

Miller-Rabin Primality Test

The Miller-Rabin Primality Test is also a probabilistic method to determine whether the given integer is a prime number or not, similar to the Fermat Primality Test. It is also based on the Fermat's Little Theorem (discussed in the above section).

This test was discovered by Gary Lee Miller in 1976, later modified by Michael Oser Rabin in 1980.

The result of this test will be whether the given number is a composite number or a probable prime number. The probable prime numbers in the Miller-Rabin Primality Test are called strong probable numbers, as they have a higher chance of being a prime number than in the Fermat's Primality Test.

A number nn is said to be strong probable prime number to base aa if one of these congruence relations (equivalence relations in modulo arithmetics, AB(modC)A \equiv B(mod\;C) means AA is congruent to BB modulo CC) holds:

  • ad1(modn)a^d \equiv 1\;(mod\;n)
  • a2rd1(modn)a^{2^{r}*d} \equiv -1\;(mod\;n)

Algorithm Steps

nn is the number to be tested.

kk indicates the accuracy of the test.

dd is an odd number such that n1n-1 can be written in the form of d2rd*2^r (Since nn is odd, n1n-1 must be even and r>0r>0).

isPrime(intn,intk)isPrime(int\; n, int\; k)

  • Handle base cases for n<3n < 3.
  • if nn is even, return FalseFalse.
  • Find an odd number dd.
  • Loop the following kk times:
    • Check if millerTest(n,d)==falsemillerTest(n, d)==false, if yes, return FalseFalse.
  • Return TrueTrue.

millerRabinTest(intn,intd)millerRabinTest(int \;n, int \;d)

  • Pick a random number aa in the range 2an22 \leq a \leq n-2.
  • Compute KaTeX parse error: Expected 'EOF', got '%' at position 15: x = pow(a, d) %̲ n.
  • Return TrueTrue if x==1orx==n1x==1 \;or \;x==n-1.
  • Loop the following till d==n1d == n-1.
    • x=(xx)%nx = (x*x)\%n.
    • Return FalseFalse if x==1x==1.
    • Return TrueTrue if x==n1x==n-1.

Implementation of the Miller-Rabin Primality Test

Source Code - C++17

Source Code - Java (1.8)

Source Code - Python 3

The output is the same for all of the implementations as they peform the same thing, the only difference being the programming language.

Output

In the above examples, we are checking whether the given number is a probable prime number or a composite number, to do so, we are using the Miller-Rabin Primality Test. If the function returns TrueTrue, then the given number is a probable prime number, otherwise, it is a composite number.

The Miller-Rabin Test, being an extension of the Fermat's Primality Test, is more accurate than Fermat's Primality Test, thus, it is preferred over that.

Complexity Analysis

Time Complexity: O(Klog3(N)O(K*log^3(N)

The time complexity of the Miller-Rabin Primality Test is O(Klog3(N)O(K*log^3(N), where NN is the number to be checked for primality, and KK is the number of iterations performed for accuracy as per the requirement.

Space Complexity: O(1)O(1)

There is no need for extra space, so the space complexity is constant.

Conclusion

  • Primality tests are used to determine whether a given number is a prime or not.
  • The School method is a naive algorithm of O(N)O(N) time complexity.
  • The Optimized School method and the Trial Division algorithm have a time complexity of O(n)O(\sqrt{n}).
  • The Fermat's Primality test and Miller-Rabin Primality test return whether a number is composite or a probable prime, and are based on Fermat's Little Theorem.
  • The time complexity of the Fermat's Primality Theorem is O(Klog(N))O(K*log(N)).
  • The time complexity of the Miller-Rabin Primality Test is O(Klog3(N)O(K*log^3(N).