Primality Testing Methods Explained
Primality Testing Methods Explained
QUESTION 8
MR CHE SHIRE’S
PRIMES
PROBLEM
Mr Che Shire likes numbers, but not just any regular numbers, they are particularly fond of
prime numbers. Mr Che Shire knows that there are infinitely many prime numbers, and they
really want to know how one can determine whether an arbitrary number is prime. They
overheard someone at the last ClubPrime meeting mention that such an undertaking is
known as a primality test and they are keen to know more. As an active and enthusiastic
member of ClubPrime, you have taken it upon yourself to prepare a detailed report (via any
format of your choosing) to share with Mr Che Shire on the wonders of primality testing. At
first, you are considering the following:
You present your findings to Mr Che Shire who is so impressed that they would love for you
to build a primality test which members of ClubPrime will use to promote prime numbers to
the community. Mr Che Shire is quite laid back, so they are happy to accept that your
primality test may not be spot on every time.
Some primes garner more attention than others (e.g. neighbouring primes, super
primes, Euler primes, Mersenne primes, etc). ClubPrime is pleased to name a new
category of primes after you for your contribution to the community.
Contents:
1 Introduction 4
2 Primality tests 5
2.1.2.1 Flaws 6
4 Appendix 20
4
1 Introduction
1.1 Paper Definitions
Before the proof begins, we have set a few definitions for this paper:
The only reason we should test for primes is because we know that there are infinite of them,
and we can prove it as such through contrapositive. For the sake of contradiction, let us
assume that there IS a finite number of prime numbers. We will denote the sequence of all
prime numbers with
𝑝1 , 𝑝2 , 𝑝3, .... , 𝑝𝑖
Consider the number n where n equals one more than the product of all primes. Note that
𝑛 − 1 is the product of all primes (where there are a finite number of prime numbers).
𝑛 = 𝑝1 𝑝2 𝑝3 .... 𝑝𝑛 + 1
Since n itself is 1 more than the product of all primes, it cannot be divisible by any of the
primes in our sequence. Therefore there are two possible conclusions we can draw from this.
1. n is prime
2. Lemma 1. n is composite
5
Proof. For any composite number, its prime decomposition must have (a) number(s)
other than 1 and itself. Every number can be factored into a certain prime
decomposition, this is known as the fundamental theorem of arithmetic. However, as
previously stated, it cannot divide any of the primes since it is one larger than the
product of all of them. This contradicts the assumption that n is composite, and
hence n cannot be composite and must be prime, and therefore n is a larger prime
which contradicts the initial assumption that there are finite primes, and thus by
contradiction there must be infinite primes.
2 Primality tests
2.1 Existing primality tests
Using our fundamental knowledge of primes, we can make a very rudimentary primality test.
This is a deterministic primality test that searches every integer less than the ceiling of a
square root of a number and checks whether it divides the number you are testing for. This
method’s basis is the definition of a prime number itself. The only problem it has is that it
requires immense computing power, for a 15 digit number (10*14) your computer would need
7
to run a loop 1 × 10 times. Therefore, this test is basically useless when it comes to large
numbers, so better methods exist. We explore 3 popular ones: The Fermat Test, the
Miller-Rabin test and the Solovay-Strassen Test.
𝑝−1
𝑎 ≡ 1(𝑚𝑜𝑑 𝑝)
This is the key formula to the Fermat primality test. The main flaw is that the
converse of the equation is not generally true. (This will be elaborated upon later)
17−1
For example, if we take the prime number 17, and integer a= 6, 6 ≡ 1 (𝑚𝑜𝑑 17)
will definitely be true.
(221−1)
HOWEVER, if we have the correct equation 38 ≡ 1 (𝑚𝑜𝑑 221), it DOES NOT
necessitate 221 being prime. In this case, we call the number 38 a ‘Fermat Liar’, and
221 is a “Fermat Pseudoprime to the base 38”. In our equation, we try to avoid these
cases with Fermat liars by simply repeatedly running the program. For example,
consider the program is running again such that this time 24 has been chosen.
7
(221−1)
24 is not congruent to 1 modulo 221. This shows that 221 is a composite. This
time, the number 24 is what we call a ‘Fermat witness’.
still well within acceptable limits. (Roughly around 3 in a million chance with just
k=9, and we are testing with k=40, basically very accurate).
Let us denote the input number as n for now. In order to distinguish whether n is
prime or composite, we will first assume that n is prime, and if we arrive at a false
statement, which means we have disproved our beginning assumption, and so our
program will return false because n is now proved composite. Considering Fermat’s
Little Theorem, we can denote that n will be prime if
𝑛−1
𝑎 ≡ 1(𝑚𝑜𝑑 𝑛)
Where a again will be {1 ≤ 𝑎 < 𝑛 − 1}. Using simple modular arithmetic, we can
easily alter the equation to arrive at this revised variation of Fermat’s Little Theorem,
which is
𝑛−1
𝑎 − 1 ≡ 0 (𝑚𝑜𝑑 𝑛)
Keep in mind here that we are still assuming p is prime because we haven’t been
proved otherwise.
factorise (𝑎 2
− 1) through difference of squares, resulting in
𝑛−1 𝑛−1 𝑛−1
4 4 2
(𝑎 − 1)(𝑎 + 1)(𝑎 + 1) ≡ 0 (𝑚𝑜𝑑 𝑛)
This step is repeated until the exponent returns odd and cannot expand further,
resulting in
10
means n must divide one of these terms e.g (𝑎 − 1). This fact is also known as
𝑘
2
Note: Euclid’s Lemma states that if there are integers 𝑎1, 𝑎2,... 𝑎𝑘 such that prime p
divides 𝑎1 𝑎2 ... 𝑎𝑘, then p divides at least one of these values a.
There are quite hefty limitations of this method however. Really it can only generate
8 set prime numbers (any value of n above 8 will cause python to return an error
because the integer is too large) because of the way the equation is set up if the input
n doesn’t change the output prime will remain constant.
Therefore, this method is not effective, and thus we use our primality test as a
method.
11
Using bitwise shifts, we can efficiently create a large range for a computer to take
numbers from to test for primality.
We use the die.randrange() to generate a random number within some range of bits
(which a user can input), Let us denote the number a as a random odd integer with
bits number of bits. We can use the python bitwise left shift operator (<<) to shift the
number 1 (which is now in binary) leftwards by bits number of bits, and then shifting
𝑎−1
it rightwards by 1 bit. This essentially gives the number 2 , which we use as the
lower bound of the random selector. The upper bound of the random selecter is
𝑎
equivalent to 1 bit shifted left bits number of bits, essentially giving the number 2 . A
random number is chosen in this range, and then it is bit shifted once to the left,
essentially doubling its value and thus ensuring it is even.
Furthermore, by adding 1 to the binary after it has been bit shifted, it ensures
that the final digit of the binary is 1, which means that the base 10 number can
be guaranteed to be odd. [to ensure no cpu is wasted on testing even numbers]
however only gives us a 75% chance that our number n is prime. There is still a 25%
1
(or 4
) chance that the number n is composite, through numbers such as
pseudo-primes. This is because we have only tested the input number n in one base,
which was a. This base is also known as a witness, and there is no simple way to find a
witness for a specific number that it isn't a strong pseudoprime to. A naive solution to
this is to test a large number of bases, which results in a relatively less efficient test.
By testing this number once again this time with an altered value of a, the chance of
1
n being composite after passing all tests drops to 6.25% (or 16
) chance.
And we can see where this is going. The bitwise primality test hinges on a certain
number of cycles, or a in this case, for accuracy. This is also held true for both a well
performed Fermat Test, Solovay-Strassen and a Miller Rabin test. The recommended
number of cycles is 40, and will not prove taxing on the computer.
25326001 1 2
False ( 25326000 False
chance to return
True, which is an
incorrect output)
The error made by the primality test is measured by the probability that a composite
number is accidentally declared prime. It can be shown that if n is composite, then at
1
most only 4
of the bases create strong pseudoprimes for n. Therefore if n is
composite and you are running a number of iterations of the test the probability that
−𝑎
the test declares n prime inaccurately is 4 .
For most numbers n, the probability of this occurring is actually bounded by a value
−𝑎
much smaller than 4 . This is because for large values of n (> 64 bit integers ), the
probability of a composite number being declared prime is much smaller. Therefore
−𝑎
the average case has a much better probability of it testing correctly (roughly 8 ).
value in the array and so the time would scale linearly with the array size. If n (which
is denoting the length of the array) doubles, the output time would double as well. To
calculate the Big O notation for our program we denote the input number to be n and
the number of cycles to be k. Since we are testing for primality k number of times we
already know that
Therefore we only need to look at the single_test function from our bitwise
primality test. In the single_test function, we have 2 while loops that are
independent of each other, and each while loop essentially loops through
almost all of n twice, therefore making it 2n. If statements are rendered
redundant because they execute 100% of the time. Also keep in mind that this
is stored in a logarithmic function because the larger the prime number
becomes the less extra computing power is required due to large primes being
extremely rare. Our time complexity would therefore be:
𝑂(𝑘 · 𝑙𝑜𝑔(2𝑛))
We first get access to two libraries: the random and date-time library. The random
library will be used to generate random numbers of a to test for n. The DateTime
library will only be used to see how long it takes for our process to undertake.
16
The single-test function takes in two values, n being the input number we are testing
for primality and a the base we are testing on for primality. Exp is set to n - 1, which
is, through Lemma 2, is the exponent we are testing whether it's odd or even.
There's not much to explain here except for line 6. The code first takes a random
integer between 1 << bits - 1 and 1 << bits. 1 in binary is 00000001, and you bitwise
left shift it by bits number of bits. Let us denote bits as 2 (the user has inputted 2 as
the # ) for the sake of this explanation.
000000001(𝑏𝑎𝑠𝑒 2) << 2 − 1 = 000000010(𝑏𝑎𝑠𝑒 2) = 2
000000001(𝑏𝑎𝑠𝑒 2) << 2 = 000000100(𝑏𝑎𝑠𝑒 2) = 4
17
So the die takes a random integer between 2 and 4. This number is then left shifted
again. Let us consider the following if the die returned with 4.
00000100(𝑏𝑎𝑠𝑒 2) << 1 = 8(𝑏𝑎𝑠𝑒 10)
This always returns an even number due to the nature of the bitwise left shift
function, and to eliminate any useless testing (all evens are composites with the
exception of 2) we will add 1 to ensure the number is odd.
Therefore the code will primality test the number 9 which returns false and the cycle
continues
If it returns true, the cycle ends and the number is printed.
This is all just inputs, first asking for an input number to test and then asking
whether the user wants to generate a prime number with a certain number of bits of
the prime. At the very end, we print the time it took for the process to undergo.
- Not being able to be run in big-O polynomial time. For example, one can you
Wilson’s theorem to find primes, but it is highly inefficient.
- It is dependent on theorems that are yet to be proven. For example, Millers
primality test (deterministic version of miller-rabin) suffers from relying on the
unproven Extended Riemann Hypothesis.
However, there is one deterministic primality test that has been created so far,
known as the AKS primality test. This test is vastly more complex than Miller-Rabin
or Solovay-Strassen, and runs considerably slower.
Sierpinski numbers are odd positive integers K, such that for all positive integers n,
is composite.
On the other hand, Riesel numbers are odd positive integers K such that for all
positive integers n, is composite.
The hunt for Riesel and Sierpinski numbers is a significant challenge, especially
since that there are very few, and it is very hard to determine what numbers are
Riesel and Sierpinski.
The hunt to find the lowest Riesel and Sierpinski Numbers is called the Riesel
Problem and the Sierpinski Problem respectively.
However, it has been proven that there are infinite both Riesel and Sierpinski
Numbers.
The current method to find Riesel and Sierpinski numbers is essentially to eliminate
numbers k that are not Riesel and Sierpinski numbers by testing values of n, yielding
massive numbers which are tested for primality. This ties in with the development of
primality testers, discussed in the previous section of this project. Some immense
primes have been yielded, including those with over 9 million digits.
Furthermore, some numbers are both Riesel Numbers and Sierpinski Numbers.
These are even more incredibly rare, and are called Brier Numbers.
Here is the list of some of the so far confirmed Riesel Numbers [confirmed cover
sets]:
Here is the list of some of the so far confirmed Sierpinski Numbers [confirmed cover
sets]:
78557, 271129, 271577, 322523, 327739, 482719, 575041, 603713, 903983, 934909,
965431, 1259779, 1290677, 1518781, 1624097, 1639459, 1777613, 2131043, 2131099,
2191531, 2510177, 2541601, 2576089, 2931767, 2931991, 3083723, 3098059,
3555593, 3608251.
Our new category of primes is called ‘Brier Primes’. These are prime numbers that
are also either Riesel Numbers or Sierpinski Numbers. They are to use the term Brier
because that is the term given to numbers that are both Riesel Numbers and
Sierpinski Numbers. Although it may be deceptive to call them Brier Primes as they
aren’t necessarily Brier Numbers, the number Brier elucidates the notion that the
category encompasses both Riesel and Sierpenski Numbers.
The strong link between Riesel/Sierpinski Numbers and the need to develop high
efficiency primality testers, along with the strong mathematical intrigue
surrounding these is why we nominate this new category of primes to be made
official by ClubPrime. Using our primality tester we have made, we can test to find
the first few Brier Primes, by inputting the first few known Sierpinski and Reisel
Numbers. (see appendix figure 3.1)
20
4 Appendix
Figure 1 - Trial Division Code
Sorted by category:
Riesel Number
1330207
Riesel Number
2251349
Riesel Number
2554843
Riesel Number
2924861
Riesel Number
3177553
Riesel Number
3292241
Riesel Number
3580901
Sierpinski Number
482719
Sierpinski Number
934909
Sierpinski Number
1639459
Sierpinski Number
2131043
Sierpinski Number
2131099
Sierpinski Number
2576089
Sierpinski Number
3098059
Sierpinski Number
3608251