<<

University of Manchester School of Project Report 2016

Primality Testing

Author: Tong Ding

Supervisor: Ian Pratt-hartmann Abstract

Primality Testing

Author: Tong Ding

A prime is a n > 1 with no positive other than 1 and n. This project investigates primality testing – that is, the problem of determining whether a given number is a prime.

In recent decades, a number of sophisticated primality testing have been proposed. These algorithms fall into two categories: non-deterministic algorithms and deterministic al- gorithms. This project focuses on several non-deterministic and deterministic algorithms: our aim is to understand their mathematical foundations, to implement them and to measure their performance. We then investigate the prime generation problem and factoring prob- lem, and relate them to the topics which have important applications in .

This report not only explains the algorithms in a comprehensive way, but also analyzes their performance in respect of running time and accuracy, then uses them to gather data on the density of primes. Supervisor: Ian Pratt-hartmann Acknowledgements

I owe a debt of gratitude to my supervisor supervisor Dr. Ian Pratt-Hartmann for being a constant assistance and guidance throughout this year. I would also like to thank my family and friends for their support and faith during my study.

1 Contents

1 Introduction 3 1.1 Motivation ...... 3 1.2 Aims and Objectives ...... 4 1.3 Report Structure ...... 4

2 Background 5 2.1 Introduction to the Primality Problem ...... 5 2.2 Non-deterministic Algorithms for the Primality Problem ...... 6 2.3 Deterministic Algorithms for the Primality Problem ...... 7 2.4 Prime Generation Problem ...... 7 2.5 Integer Problem ...... 7

3 Non-deterministic Algorithms in Time 8 3.1 Lehmann’s Test ...... 8 3.2 The Solovay-Strassen Test ...... 10 3.3 The Miller-Rabin Test ...... 14

4 Deterministic Algorithms in Polynomial Time 17 4.1 The AKS Test ...... 17 4.2 The Improved AKS Test ...... 21

5 Testing and Evaluation 22 5.1 Run Time ...... 22 5.2 Accuracy ...... 25 5.3 Density of Prime ...... 28

6 Prime Generation 30 6.1 The Sieve of ...... 30 6.2 The Use of Primality Testing Algorithms ...... 31

7 32

8 Conclusion 33 8.1 Achievements ...... 33 8.2 Future Work ...... 33

Bibliography 34

2 Chapter 1

Introduction

1.1 Motivation

The primality problem was first defined in classical antiquity. It can be stated as follows: Given a number n, decide whether n is prime. There is a naive procedure which works well for small inputs.

Algorithm 1: Simple Method Input : Integer n > 2 Output: prime:0, composite:1 1 i ← 2; 2 while i × i < n do 3 if i divides n then 4 return 1; 5 else 6 i ← i + 1; 7 end 8 end 9 return 0;

√ This tests all the from 2 to n, to see whether they are divisors of n. As soon as a is found, the calculation stops and returns n as a . If no divisor is found, n will be returned as a prime.

The method is guaranteed to return a correct answer, and is the best method for small num- bers. But we cannot use this method for large , as it is too time consuming. For ex- ample, if an input number with 60 digits happens to be prime, then the loop will run for more than 1030 rounds. Even if we assume that a very fast computer is used that can carry out one loop in 1 nanosecond, the computing will still take more than 1013 years.

The question arises as to whether we can improve the performance of the naive procedure, increasing its efficiency while keeping its accuracy. A number of improved algorithms have been proposed to date. Based on these previous attempts, we decided to implement the im- proved methods and compare their performance for further study. This forms the main idea of the project.

3 1.2 Aims and Objectives

The purpose of this project is to implement various primality testing algorithms, explain how these algorithm work, and present their performance. Nearly all the work is based on the book Primality Testing in Polynomial Time: From Randomized Algorithms to ”PRIMES is in P”[Die04]. The aims are:

• Understand the mathematical basics in detail.

• Fit the relevant knowledge into the algorithms.

• Produce functions to test input numbers, based on the pseudo-codes.

• Evaluate the performance of different methods by various approaches.

• Improve the code according to the testing results and the most recent developments in the area.

1.3 Report Structure

Chapter 2 talks about some basic notions and their background. Chapter 3 and Chapter 4 in- vestigate three typical randomized algorithms and one representative deterministic algorithm, respectively, and explaining the ways they work in detail. Chapter 5 considers statistics gath- ered from the running of previous algorithms.

In Chapter 6, we focus on prime generation and discuss several methods to achieve that. In Chapter 7, the research goes further into the application in cryptography, which leads to a simple implementation of integer factorization.

4 Chapter 2

Background

2.1 Introduction to the Primality Problem

Based on the introduction, we know that this project focuses on various efficiency approaches to solve the primality problem. Before we start talking about the algorithms, as a general background and a basis for analyzing ,there are some notions from number the- ory that are essential for the primality problem.

Definition 2.1.1 (Prime and Composite). A positive integer n is a if n > 1 and there is no number that divides n except 1 and n. If n is divisible by some a, 1 < a < n, then n is a composite number.

A representation n = p · p1··· pr (r > 0, p1,..., pr stands for prime number which is not necessarily distinct) is called a prime decomposition of n. By using such a representation, we have the following theorem:

Theorem 2.1.2 (The Fundamental Theorem of ). Every integer n > 1 can be written as a product of prime numbers in exactly one way (The order of the factors is disregarded).

The theorem states two terms. For example, 600 = 2 × 2 × 2 × 3 × 5 × 5, 600 can be repre- sented as a product of primes, and 600 can just be written as a product of three 2s, one 3, two 5s, without no other primes in the product.

Definition 2.1.3 (). If n and m are integers, then the largest integer that divides n and divides m is called the great- est common divisor of n and m and denoted by gcd(n,m). If gcd(n,m) = 1, then we say that n and m are relatively prime.

There are quite efficient algorithms for finding the greatest common divisor. For example the Extended (see Algorithm 3.2.4 in [Die04]), which has O(log(n)log(m)).

Theorem 2.1.4 (Integer with ). If n is an integer and d is a positive integer, then there are unique integers q and r such that n = d · q + r and 0 6 r < d. d is the divisor, q is the quotient, r is the remainder.

5 The theorem of division with remainder is so important that we introduce a special notation for it.

Definition 2.1.5 (Modulo and Congruent).

• For an integer n and a positive integer d we let n mod d = r and ndivd = q, where r and q are the uniquely determined numbers that satisfy n = d · q + r and 0 6 r < d.

• Let d > 2 be given. For arbitrary integers a and b, if we have a mod b = r and b mod d = r. We say that a is congruent to b modulo d and write a ≡ b (mod d).

2.2 Non-deterministic Algorithms for the Primality Prob- lem

A non-deterministic algorithm is an algorithm that, even for the same input, can exhibit dif- ferent behaviors on different runs. Here we give the Fermat Test as a simple example of non- deterministic algorithm for the primality problem. As the basis for the , we introduce Fermat’s little theorem first:

Theorem 2.2.1 (Fermats Little Theorem). If p is a prime number, then for any integer a not divisible by p, ap−1 ≡ 1 (mod p)

Algorithm 2: Fermat Test Input : Odd Integer n > 3 Output: prime:0, composite:1 1 Let a be randomly chosen from 2,...,n − 2; n−1 2 if a 6= 1 (mod n) then 3 return 1; 4 else 5 r 6 end 7 eturn 0;

By Fermats Little theorem, if an−1 6= 1 (mod n), then n is not a prime number, in other words, n must be a composite. Otherwise, if ap−1 ≡ 1 (mod b), n might be a prime. In conclusion, if this algorithm returns the answer as prime, there might be a probability that n is actually com- posite. So Fermat Test is a non-deterministic algorithm, because it will not always return the same result giving a particular input. The probability that Fermat Test gives a wrong answer 1 can be proved as to 2 [Die04], of course this is too high in practical application. More con- vincing algorithms will be described in next chapter.

In Algorithm 2 line 2, a method randomization is invoked, which is common in the imple- mentation of non-deterministic algorithms. The purpose of randomization is to generate ran- dom values in hope to verify the algorithm in the average case. In practice we use a pseudo- random generator to implement randomization.

6 2.3 Deterministic Algorithms for the Primality Problem

A deterministic algorithm is an algorithm that, always give the same answer with the same in- put on different runs. When dealing with the primality problem, the deterministic algorithms will never give erroneous outputs. In other words, if we input a prime number, the determinis- tic algorithms will never output it as a composite. Otherwise the deterministic algorithms will never output composite for a prime input.

The AKS test is an unconditional deterministic polynomial time algorithm that works without randomization, it will be described later in chapter 4.

2.4 Prime Generation Problem

In cryptographic applications, we need to be able to solve the prime generation problem. It is essential to produce randomly chosen prime numbers for the creation of key pairs (i.e. RSA cryptosystem requires two distinct prime numbers at the first stage). For small prime genera- tion, a prime sieve is a fast way to obtain a list of primes. A prime sieve works by storing all numbers up to the desired limit first and progressively removing the composite numbers until reach the limit, after searching, the remaining numbers can be confirmed as primes. For large prime generation used in cryptography, primality testing algorithms can be used to find prime efficiently. Alternatively, we can use Theorem 2.1.2, that every integer n > 1 can be written as a product of prime numbers, to generate primes. This method can be called as integer factor- ization, we will introduce it in next session.

2.5 Integer Factorization Problem

Factoring a positive integer n means finding positive integers u and v such that the product of u and v equals n (u,v > 1). Such u and v are called factors of n, and n = u · v is called a fac- torization of n. This can be further restricted to prime factorization, which results in a prod- uct of prime numbers. For example, n = 3 · 7 · 11 is the prime factorization of n = 231; n = 11 is the prime factorization of n = 11. In cryptographic applications (i.e. RSA cryptosystem), we need to be able to decompose a number with hundreds digits. However, the efficient algo- rithms to such a large number havent been found so far. The fastest known general-purpose factoring algorithm is the General Number Sieve (GNFS), its time complexity is expo- nential in n.[Bar04]

7 Chapter 3

Non-deterministic Algorithms in Polynomial Time

In this chapter, we describe and analyze several non-deterministic algorithms. They admit efficient implementation and reasonable error probability. We will describe the algorithm in detail with the help of pseudo-code, and analyze their correctness and time complexity. Sometimes it is necessary for us to explain some background theorems. The proofs of these theorems can be found as further reading in references. This forms the basic structure of the sections in this chapter.

3.1 Lehmann’s Test

Proposed by D. J. Lehmann in 1982, Lehmanns test is based on Fermats Little Theorem.

Here is the algorithm: Algorithm 3: Lehmann’s Primality Test Input : Odd integer n > 3, integer l > 2 Output: prime:0, composite:1 1 a,c : Integer; b[1...l] : array of integer; 2 for i from 1 to l do 3 a ← a randomly chosen element of [1,...,n − 1]; n−1/ 4 c ← a 2 mod n; 5 if c ∈/ [1,n − 1] then 6 return 1; 7 else 8 b[i] ← c; 9 end 10 end 11 if b[1] = ··· = b[l] = 1 then 12 return 1; 13 end 14 return 0; This can be summarized into five steps:

8 1. Pick a random integer a, 1 6 a < n.

n−1 2. Let c be a /2 mod n.

3. If c is neither 1 nor n − 1, then return n as composite, otherwise store c into an array.

4. Loop for l times, keep trying different random values of a.

5. If any element in array is not equal to 1, return n as composite. Otherwise, n is prime.

Recall Fermats Little Theorem, for every prime p we have ap−1 ≡ 1 (mod p). If we use the formula A2 − B2 = (A − B) × (A + B) to expand the expression, we get:

p−1 p−1 ap−1 − 1 = (a /2 − 1) × (a /2 + 1)

From divisibility of numbers, in order to satisfy ap−1 ≡ 1 (mod p), one of the following con- ditions must also hold:

p−1 p−1 a /2 − 1 ≡ 0 (mod b) ⇒ a /2 ≡ 1 (mod b) p−1 p−1 a /2 + 1 ≡ 0 (mod b) ⇒ a /2 ≡ −1 (mod b)

Thats why we use a variable to store the modulo result in step 3.

Theorem 3.1.1. 1 l If the input n is a prime number, the probability that output 1 is given is smaller than ( 2 ) , if n 1 l is composite, the probability that output 0 is given is smaller than ( 2 ) . Proof. Case 1: Assume n is an odd prime. Here we have to introduce the definition of quadratic residues first: Definition 3.1.2 (Quadratic Residues). For integer p > 2 and a an integer with gcd(a, p) = 1, we say that: 1. a is a modulo p if a ≡ x2 (mod p) for some integer x.

2. a is a (quadratic) nonresidue if a is not a quadratic residue modulo p.

Theorem 3.1.3 (Euler Criterion). [KY02] Let p be an odd prime and a an integer with gcd(p,a) = 1. Then

( 2 p−1 1 (modp) if there is an integer x such that a ≡ x (mod p) a 2 = −1 (modp) if there is no such integer

p−1 From the definition of quadratic residues and Euler criterion, we can conclude that a /2 ≡ 1 p−1 (mod p) if a is a quadratic residues, and a /2 ≡ −1 (mod p) if a is a (quadratic) nonresidue.

Proposition 3.1.4. [Sil10] (p−1) Let p be an odd prime. Then there are exactly /2 quadratic residues modulo p and ex- (p−1) actly /2 nonresidues modulo p.

9 As stated in the above theorems, for n an odd prime, half of the elements of [1...n − 1] satisfy n−1 n−1 a /2 ≡ 1 (mod n), the other half satisfies a /2 ≡ −1 (mod n). Store the modulo result as 1 c, then c must be 1 or n − 1, while the probability of c equals to 1 is 2 . So in step 3, prime n will never be mistaken for composite. In step 5, after running the loop through l times, the 1 l probability that c1 = ...cl = 1 and the wrong output is ( 2 ) .

Case 2: Assume n is an odd composite. n−1 If there is no a in [1...n − 1] with a /2 ≡ −1 (mod n), the output is guaranteed to be cor- rect. On the other hand, it can be shown (see Lemma 5.3.1 in [Die04]) that if there is some n−1 a in [1...n] satisfy a /2 ≡ −1 (mod n), then more than half of the elements in [1...n − 1] n−1 satisfy a /2 6= −1 or 1 (mod n). This means that the probability that the loop runs for l 1 l times is no more than ( 2 ) . The probability that output 0 is produced cannot be larger than this bound.

1 l In summary, the probability of the wrong output P 6 ( 2 ) . Theorem 3.1.5. When apply the Lehmann’s test to an input number n, the time complexity is O(c · (logn)3).

n−1 Proof. From the pseudo-code, we can find that line 3 which calculates a /2 mod n and the loop in line 2 will be time consuming.

n−1 1. a /2 mod n: Use Fast Algorithm (see Algorithm 2.3.3 in [Die04]), which does only O(logn) multiplications and O((logn)3) expected time complexity.

2. The for loop: The times of loop is determined by user, which is a constant c.

In summary, the time complexity of Lehmans test is O(c · (logn)3).

3.2 The Solovay-Strassen Test

The SolovayStrassen primality test was developed by Robert M. Solovay and Volker Strassen in 1977. The most important part of this test is the calculation of .

Definition 3.2.1 (). For a prime number p > 3 and an integer a we let:  1 if a is a quadratic residue modulo p and a 6= 0 (mod p) a  ( ) = −1 if a is a quadratic non-residue modulo p p  0 if a ≡ 0 (mod p)

a ( p ) is called the Legendre symbol of a and p.

10 Definition 3.2.2 (Jacobi Symbol). Let n > 3 be an odd integer with prime decomposition n = p1 ··· pr. For integer a we let: ( a ) = ( a )···( a ) n p1 pr a ( n ) is called the Jacobi symbol of a and n. The Jacobi Symbol has many properties which may help us better in the further calculation. We now summarize them as the Law. Theorem 3.2.3 (Quadratic Reciprocity Law). a If a,n > 3 are odd integers, then ( n ) can be calculated by the following rules: a mod n 1. If a is not in the interval [1,...,n − 1], the result is ( n ). 2. If a = 0, the result is 0. 3. If a = 1, the result is 1. a /4 4. If 4 divides a, the result is ( n ). a a /2 /2 5. If 2 divides a, the result is ( n ) if n mod 8 ∈ (1,7), and (− n ) if n mod 8 ∈ (3,5). n mod a 6. If a ≡ 1 or n ≡ 1 (mod 4)(a > 1), the result is ( n ). n mod a 7. If a ≡ 3 and n ≡ 3 (mod 4), the result is −( n ). a Applying Quadratic Reciprocity Law, we get the algorithm to calculate Jacobi Symbol ( n ): Algorithm 4: Jacobi Symbol Input : Integer a, odd integer n > 3. a Output: value of ( n ) 1 c,b,s:integer; 2 b ← a mod n; 3 c ← n; s ← 1; 4 while b > 2 do 5 while 4|b do 6 b ← b/4; 7 end 8 if 2|b then 9 if c mod 8 ∈ (3,5) then 10 s ← (−s); 11 end 12 b ← b/2; 13 end 14 if b = 1 then 15 break; 16 end 17 if b mod 4 = c mod = 3 then 18 s ← (−s); 19 end 20 (b,c) ← (c mod b,b); 21 end 22 return s · b;

11 This can be summarized into four parts:

1. The big while loop (line 4-21): Loop until b has reached a value in 0,1.

2. The small while loop (line 5-7): Loop until b is not a multiple of 4. [Theorem 3.2.3 (4)].

3. The first if if condition (line 8-13): If b is the multiple of 2, divide b by 2. Then check if c mod 8 = 3 or 5, if so negate s. [Theorem 3.2.3 (5)].

4. The third if condition(line 17-20): b n mod a If b mod 4 = c mod = 3, negate s. Then replace ( c ) by ( n ). [Theorem 3.2.3(7)].

We first use Theorem 3.2.3 (1) to deal with a and n into b and c. The variable s ∈ (1,−1) is used to accumulate the sign changes caused by previous iterations. So in part 3 and 4, if the conditions are met, s will be negated according to the corresponding laws. More precisely, in part 3, as c is an odd number, if c mod 8 6= 3 or 5, then c mod 8 = 1 or 7, so we do not need to negate s [Theorem 3.2.3 (5)]. Part 4 is similar with part 3, as both b and c are odd numbers at this stage. If b 6= 3 or c 6= 3 (mod 4), then there must be b = 1 or c = 1 (mod 4), we do not need to negate s [Theorem 3.2.3 (6)]. Part 1 results in b is 0 or 1, at which point we b have ( c ) = b [Theorem 3.2.3 (2), (3)]. After multiplying it with the sign s, the return result is a exactly the value of Jacobi symbol ( n ).

Algorithm 5: Solovay-Strassen Test Input : Odd Integer n > 3 Output: prime:0, composite:1 1 Let a be randomly chosen from [2,...,n − 1]; (n−1) /2 a 2 if a · ( n ) mod n 6= 1 then 3 return 1; 4 else 5 return 0; 6 end

a Line 2 uses Algorithm 4 to calculate Jacobi symbol ( n ). Theorem 3.2.4. If the input n is a prime number, the output is 0; if n is composite, the probability that output 0 1 l is given is smaller than ( 2 ) . Proof. Case 1: Assume n is an odd prime.

1. a is a quadratic residue modulo n: a According to Definition 3.2.1 and 3.2.2, the Jacobi symbol ( n ) = 1. (p−1) According to Definition 3.1.2 and Theorem 3.1.3, a /2 ≡ 1 (mod p).

12 2. a is a quadratic nonresidue modulo n: (p−1) a /2 The Jacobi symbol ( n ) = −1 · a ≡ −1 (mod p).

(p−1) a /2 In both conditions ( n ) · a ≡ 1. The probability of wrong output is 0.

Case 2: Assume n is an odd composite.

In reference to the Euler criterion from Theorem 3.1.3 and Proposition 3.1.4, we can define the following Euler witness similarly: Definition 3.2.5 (Euler witness). Let n be an odd composite number. A number a, 1 6 a < n, is called an Euler witness for n if (p−1) a /2 ( n ) · a 6= 1 (mod p). Following is an important property of Euler witness, which can help us draw a conclusion. Proposition 3.2.6. [Run15] When n is an odd composite, at least half of all a with gcd(a,n) = 1, 1 6 a < n, are Euler witnesses. 1 Hence the probability that a is not Euler witness is smaller than 2 in one loop.

1 l In summary, the probability of wrong output P 6 ( 2 ) . Theorem 3.2.7. When apply the Solovay-Strassen test to an input number n, the time complexity is O(c·(logn)3).

n−1 Proof. From the pseudo-code, we can find that line 1 which calculate a /2 mod n and the calculation of Jacobi Symbol be time consuming.

1. Jacobi Symbol (Algorithm 4): Line 6 and 12: Dividing a number b given in binary by 2 or by 4 amounts to dropping one or two 0 at the end. Line 9 and 17: Determining the remainder of b and c modulo 8 or modulo 4 amounts to looking at the last two or three bits. Lines 2 and 20: Use the Extended Euclidean Algorithm to calculate the divisions with remainder, the time complexity is O(logn).

n−1 2. a /2 mod n: Use Fast Modular Exponentiation Algorithm, the time complexity is O((logn)3).

In summary, the time complexity of the Solovay-Strassen test is O(c · (logn)3).

13 3.3 The Miller-Rabin Test

Constructed by Gary L. Miller in 1976, the Miller-Rabin test was originally deterministic, but it depended upon an unproven hypothesis. To deal with this issue, Michael O. Rabin then redesigned it to non-deterministic version later in 1980.

Here is the Algorithm: Algorithm 6: Miller-Rabin Test Input : Odd Integer n > 3 Output: prime:0, composite:1 k 1 Find u odd and k satisfy n = u · 2 ; 2 Let a be randomly chosen from [2,...,n − 2]; u 3 b ← a mod n; 4 if b ∈ (1,n − 1) then 5 return 0; 6 end 7 for (i = 1; i < k; i + +) do 2 8 b ← b mod n; 9 if b = n − 1 then 10 return 0; 11 end 12 if b = 1 then 13 return 1; 14 end 15 end 16 return 1;

Recall Fermats Little Theorem, which says that if n is a prime number and 1 6 a < n, then an−1 − 1 ≡ 0 (mod n). For n − 1, we can write it in the form n − 1 = u · 2k, where u is an k odd number (line 1). Substitute it into Fermats Little Theorem, we get au∗2 − 1 ≡ 0 (mod n). Expand this equation using the formula A2 − B2 = (A − B) × (A + B):

k au·2 − 1 = k−1 k−1 (au·2 + 1) × (au·2 − 1) = k−1 k−2 k−2 (au·2 + 1) × (au·2 + 1) × (au·2 − 1) = k−1 k−2 (au·2 + 1) × (au·2 + 1) × ... × (au + 1) × (au − 1)

If n is prime, at least one of the above expressions must equal to 0 modulo n. In other words, if none of above expressions equal to 0 modulo n, we know for sure that n is not a prime.

Algorithm 6 can be summarized into four steps: 1. Line 3: Set b as (au mod n).

2. Line 4-6: If b = 1 or n−1, which means (au −1) or (au +1) = 0 (mod n), returned n as an unsure prime.

14 3. Line 7-15: u·2i Repeat squaring b, bi = (a ) mod n. Check whether bi = −1, then n is an unsure prime. Otherwise the equation bi = 1 held for n is composite. 4. Line 16: k After k − 1 times repeating, we can make sure that au·2 − 1 6= 0 (mod n), return com- posite. Theorem 3.3.1. If the Miller-Rabin test yields output 1, then n is composite. If the Miller-Rabin test yields 1 l output 0, the probability that n is composite is smaller than ( 4 ) . Proof. Case 1: Assume output composite. There are two ways for the output composite to occur. 1. Line 13: There is some i, 1 6 i 6 k − 1, such that in the ith execution of line 13, the algorithm finds that bi = 1. By the test in line 4, and the tests in lines 9 and 12 carried out during the previous executions of the loop, we know that b0,...,bi−1 ∈/ (1,1). This entails that 2 b0 ...bk−1 does not contain −1 as bi = (bi−1) , Hence n is not a prime. 2. Line 16: By the tests performed in line 4 and in the k − 1 executions of lines 9 and 12, this means that b0 ...bk−1 are all different from 1 and −1. Hence n is not a prime. Case 2: Assume output prime.

According to our explanations before, we know that the Miller-Rabin algorithm tests prime by an−1 − 1 ≡ 0 (mod n). However some composite numbers may also satisfy this equation, we call them . Definition 3.3.2 (Carmichael Number). An odd composite number n is called a Carmichael number if an−1 − 1 ≡ 0 (mod n), for all a with gcd(a,n) = 1. Proposition 3.3.3. [Kle10] If n is a Carmichael number, then Miller-Rabin test outputs composite with probability at 3 least 4 . Applying this property, we can prove the error rate as following. There are two ways for the output prime to occur.

1. Line 5: We know that b0 = 1 or −1, this entails that an−1 ≡ −1 or 1 (mod n).

2. Line 7: There is some i, 1 6 i 6 k −1, such that in the ith execution of line 9, the algorithm finds u·2i that bi = −1. This means that (a ) ≡ −1 (mod n)

Hence if n is an odd composite, n is a Carmichael number in both conditions. Then Miller- 1 Rabin test outputs prime with probability smaller than 4 .

15 1 l In summary, the probability of wrong output P 6 ( 2 ) . Theorem 3.3.4. When apply the Miller-Rabin test to an input number n, the time complexity is O(c · (logn)3).

Proof. From the pseudo-code, the only time consuming parts are the multiplication and mod- ulo operation in line 3 and 8. Use Fast Modular Exponentiation, the time complexity is O((logn)3).

In summary, the time complexity of the Miller-Rabin test is O(c · (logn)3).

16 Chapter 4

Deterministic Algorithms in Polynomial Time

In this chapter, we are going to discuss the deterministic polynomial time primality test. The first deterministic algorithm was published by M. Agrawal, N. Kayal, and N. Saxena on 2002, in a paper titled ”PRIMES is in P”. This algorithm is also known as the AKS test.

4.1 The AKS Test

This section is organized as follows. We first describe some properties of prime numbers and a definition about modulo, which leads to the basic ideas of the AKS algorithm. The algo- rithm given here is the revised version [AKS04] proposed in 2004. The main part is the cor- rectness proof. Following is the time analysis. Similar to the last chapter, some basic proofs will be given in reference as further reading.

The theorem on which the test is based can be stated as follows: Theorem 4.1.1. Let n > 2 be arbitrary, and let a < n be an integer that gcd(a,n) = 1. Then n is prime if and only if (X + a)n ≡ Xn + a (mod n), for all values of x. The above theorem is easy to prove by Binomial Theorem and Fermats Little Theorem. The details can be found in [Aar03]. This provides us a way of testing the primality of n, but this way needs to evaluate n coefficients in the worst case, so the time complexity will be O(n). In order to speed up this, the AKS algorithm extends the congruence in Theorem 4.1.1 to below:

(X + a)n ≡ Xn + a (mod Xr − 1,n), r is an integer.

This means we mod both sides in Theorem 4.1.1 by a polynomial of the form Xr − 1 first, and then mod the result by n. That is, instead of computing (X + a)n, this way computes the remainder when (X + a)n is divided by Xr − 1, it reduces the maximum degree to r. Since theorem 4.1.1 is always true when n is prime, it is obvious that all primes n satisfy the new equation. The problem is that there might exists some composite numbers, which also satisfy the equation for some r and a. In order to solve this, the AKS test chooses an appro- priate variable r, and test the equation for all a ∈ (1,2,...,s) (s determined by the value of r). Before we talk about the choice of r and s, we first give a definition.

17 Definition 4.1.2 (Multiplicative Order). Given an integer a and a positive integer n with gcd(a,n) = 1, the multiplicative order of a modulo n is the smallest positive integer k with ak ≡ 1 (mod n). The order of a mod n is usu- ally written as ordn(a).

Here is the algorithm: Algorithm 7: AKS Test Input : Integer n > 2 Output: prime:0, composite:1 b 1 if n = a for some a,b > 2 then 2 return 1; 3 end 4 r ← 2; 5 while r < n do 6 if r divides n then 7 return 1; 8 end 9 if r is a prime number then 2 i 10 if for all i,(1 6 i 6 4dlogne ), n mod r 6= 1 then 11 break; 12 end 13 end 14 r ← r + 1; 15 end 16 if r = n then 17 return 0; 18 end √  19 for a from 1 to 2 r · dlogne do n r n mod r 20 if (X + a) (mod X − 1) 6= X + a then 21 return 1; 22 end 23 end 24 return 0;

This can be summarized into five main steps:

1. Line 1: Test whether n is a power of an integer, if so return composite.

2. Line 6: For all r (r < n) test whether r divides n, if so return composite.

3. Line 9-13: i For a prime number r, i will be ordr(n) if n ≡ 1 (mod r). In other words, if we cannot 2 2 find i (1 6 i 6 4(logn) ) satisfies this equation, then ordr(n) > 4(logn) . Break the while loop with the value of r.

4. Line 16-18:

18 If r > n, return prime.

5. Line 19-23: √ For a = 1 to 2 rlogn, check (X + a)n 6= Xn + a (mod Xr − 1,n). If any a satisfies this, return composite. The extended version of Theorem 4.1.1 can be reflected in step 5. The original equation is (X + a)n ≡ Xn + a (mod Xr − 1,n). If we use Polynomial [Kna97] to calculate Xn + a divides Xr − 1, the remainder will be equal to Xn mod r + a for every a and for every r. This means in the implementation we dont need to calculate every Xn + a (mod Xr − 1), which is time consuming as this calculation is between . Instead, we can calculate Xn mod r just once and save it for further . Theorem 4.1.3. Assume the AKS test is run on input n > 2. Then the output is 0 if and only if n is a prime number.

Proof. This part is organized around a main theorem. The proof of the main theorem in- volves deep knowledge from analytic . Full details can be found in Chapter 8 of [Die04]. Theorem 4.1.4 (Main Theorem). Assume n and r are integers so that

1.n > 3. 2.r < n is a prime number.

3. a doesn’t divide n for 2 6 a 6 r. 2 4. ordr(n) > 4(logn) .

n n r √ 5. (X + a) ≡ X + a (mod X − 1,n), for 1 6 a 6 2 rlogn Then n is a power of prime Case 1: Assume n is a prime.

It is obvious that n is not a for any a,b > 1, the condition in line 1 is not sat- isfied. The condition in line 5 limits r to always smaller than n, hence line 6-8 is not satis- fied as n is a prime. If the while loop in lines 515 is left because r has reached n, then line 16-18 will output prime. If the while loop is left via the break statement in line 11, then r > 2 ordr(n) > 4(logn) (If r 6 ordr(n)), then before we test ordr(n), we will definitely find (r−1) n ≡√1 (mod r) as r is confirmed√ as a prime in line 9. This contradicts Definition 4.1.2). Hence r > 2logn and n > r > 2 rlogn. By the previous test in line 6-8, we can know that every value 6 r is coprime with n. Combine this√ with the extended version of Theorem 4.1.1, line 20 will yield equality for all a with a 6 2 rlogn. Hence line 24 will output prime at the end.

Case 2: Assume Algorithm 7 returns prime.

There are two ways for the output prime to occur.

19 1. Line 16-18: This means the loop in lines 5-15 runs until r reaches n. By the previous test in line 6-8, every number r, 2 6 r 6 n, has been tested for dividing n. Hence n is a prime number. 2. Line 24: This means the loop in lines 515 is left via the break statement in line 11. We check that if n and r meet the conditions in the Main Theorem: (1) is trivial; (2) is tested in line 9; (3) is tested in the previous executions of line 6-8; (4) is tested in step 3 (line 5-7); (5) is tested in step 5 (line 10-12). Thus, we can conclude that n = pb for a prime p and some b > 1. However, n cannot be a perfect power of any number because the test carried out in line 1 must have given a negative result. Hence i = 1, and n is a prime number.

Theorem 4.1.5. When apply Algorithm7 to an input number n, the time complexity is O(c · logn10.5). Proof. From the pseudo-code, the following three parts will be time consuming. 1. Line 1: Here we choose to use the Perfect Power Test Algorithm (Algorithm 2.3.5 in [Die04]), the time complexity of which is O((logn)3). Remark that this may be further reduced to essentially linear time O((logn)1+o(1)) by using a different approach.[Ber98] 2. Line 5-15 (while loop): This loop tests numbers r for several properties. Let R be the maximal r executed by this loop.

In one loop,√ for line 9 if we√ use the naive algorithm1 for checking, then the time com- plexity is O( r), and O( R) in the worst case. In line 10 we calculate ni mod r for 2 2 every 1 6 i 6 4(logn) .The number of multiplications modulo r is O((logn) ) for one 3 2 r. Thus the worst time complexity of this part is O(R 2 ·(logn) ). Actually, when we test the real run time by using Profiler in NetBeans, this part runs much faster than next part, which might results from the fact that the naive algorithm seldom runs under the worst case.

3. Line 19-23 (polynomials):√ We need to loop for 2 R · logn times. (X + a)n (mod XR − 1,n) is surely the most time-consuming part. It needs O(logn) multiplications if we use the fast modular expo- nentiation algorithm. Recall the analysis we gave for the extended version of Theorem 4.1.1, the polynomials have maximum degree R and coefficients of size O(logn). Thus √ 3 3 the time complexity of this part is O( Rlogn · logn · R · logn) = O(R 2 (logn) ). The maximal r can be shown by the following proposition: Proposition 4.1.6. 5 For all n > 2, there exits a prime number r 6 20(logn) such that r doesn’t divide n and 2 ordr(n) > 4(logn) .

Hence R = O((logn)5). In summary, the time complexity of the AKS test is O(c · logn10.5).

20 4.2 The Improved AKS Test

The AKS test is the first algorithm in history that can determine the primality problem in polynomial time complexity. However, from the previous description, the time complexity of the improved AKS test is O((logn)10.5). The original one even runs in O((logn)12). It is much slower than the non-deterministic algorithms in last chapter, especially when we test primes with hundreds of digits for practical purpose.

The AKS test then has been improved based on various modifications. It was then proved that, by using the theorem of Fouvry [Fri89], there is a choice for r with R = O((logn)3). This leads the time complexity down to O((logn)7.5). In 2005, and H. W. Lenstra, Jr. demonstrated a variant of AKS test [LJP02] that runs in O((logn)6), reduced the exponent from 12 to 6. This is a marked improvement over the initial bound.

21 Chapter 5

Testing and Evaluation

In this chapter we test on the implemented algorithms, in order to make sure the programs perform correctly and meet the relevant requirements. The results are given by figures and tables, together with the comparisons between different algorithms. Further, we evaluate the algorithms; the evaluation employs the results of testing. Tests are carried out from three as- pects: run time, accuracy and the density of primes shown by different algorithms.

5.1 Run Time

In this section information on how the testing data was conducted will be given first. This will help us to get a more comprehensive view of the results. All the tests were completed by similar methods except some tricky parts. In order to generate enough input data, a program will execute the algorithms repeatedly. The iteration time is specified by the user: the user inputs the number of digits; the program then tests numbers from 2 to the number with input digits.

It is obvious that for primality testing algorithms, the time of giving an answer for composite and prime input will be different. Thus we just record the run time for numbers which are returned as primes, and write the data into a file. Finally, we plot the data in matlab and view the results in intuitive way.

The following figure shows the relationship between the input number and run time of Miller- Rabin test. The x-axis represents input number, which ranges up to number with 6 digits. The y-axis represents the run time corresponding to each input. The execute time is recorded in nanoseconds, because the testing on small primes is so quick that data may be lost if we record the time in seconds or milliseconds.

22 9 x 10 Miller−Rabin Testing Running Time 14 Iteration: 10 Iteration: 6 12 Iteration: 2

10

8

6 Runtime(nanosecond) 4

2

0 0 1 2 3 4 5 6 10 10 10 10 10 10 10 Input number(Prime)

Figure 5.1: the Miller-Rabin test run time (1st Version)

Recall Theorem 3.3.4, the time complexity of Miller-Rabin test is O(c · (logn)3). The constant c is the loop time, so when we increase the number of iterations, the run time increases. The shapes of curves are similar to those in logarithm, but we cannot make sure in this stage. According to the time complexity, the relationship between input number and run time must in the form y = a · (logx)b. In MATLAB, a loglog plot can set logarithmic scales on both the horizontal and vertical axes. Hence we apply log-log plot to the data and get a new graph:

Miller−Rabin Testing Running Time 11 10 Iteration: 10 10 Iteration: 6 10 Iteration: 2

9 10

8 10

7 10

6 10 Runtime(nanosecond)

5 10

4 10

3 10 0 1 2 3 4 5 6 10 10 10 10 10 10 10 Input number(Prime)

Figure 5.2: the Miller-Rabin test run time (2nd Version)

The relationship is still imperceptible. We need some explicit parameters to distinguish differ- ent lines from each other clearly. Hence we further apply curve fitting to the data and get a new graph:

23 Miller−Rabin Testing Running Time 11 10 Iteration: 10 Iteration: 6 10 10 Iteration: 2

9 10

8 10

7 10

Runtime(nanosecond) 6 10

5 10

4 10 0 1 2 3 4 5 6 10 10 10 10 10 10 10 Input number(Prime)

Figure 5.3: the Miller-Rabin test run time (3rd Version)

By using curve fitting, we get 3 straight lines best fit in log-log plot, which is an exact fit to the data. We can even get the slope of every line from the polynomial curve fitting method in MATLAB. The slope of 10 iterations line is 0.9829, 6 iterations line is 0.9598, 2 iter- ations line is 0.8296. This gives us a clear distinction that iterating 10 times takes most time, and then is 6 iterations, while 2 iterations takes the least time for the same input.

Analyzing the influence of iterations for every algorithm is unnecessary. Therefore, we start comparing the run time between algorithms. Iteration time was set as 10 here for more obvi- ous differences. Following is the figure illustrating the run time of four algorithms: Lehmanns test, the Solovay-Strassen test, the Miller-Rabin test and the AKS test.

Running Time Comparison 11 10 Lehmann Solovay−Strassen 10 10 Miller−Rabin AKS

9 10

8 10

7 10

Runtime(nanosecond) 6 10

5 10

4 10 0 1 2 3 4 5 6 10 10 10 10 10 10 10 Input number(Prime)

Figure 5.4: Run Time Comparison

24 This figure was obtained by employing log-log plot and curve fitting operations on original data. It gives us a straightforward view of the elapsed running time between algo- rithms. In three non-deterministic algorithms, Lehmanns test is the fastest one and Miller- Rabin test is the slowest under the same input. The AKS test runs much slower than other tests. Considering the slopes, the slop of the Lehmanns test is 0.8238; the Solovay-Strassen test is 0.9116; the Miller-Rabin test is 0.9829; the AKS test is 1.2099. The slope of three non- deterministic algorithms are floating around 0.9 while the slope of the AKS test is higher than 1.2. This means, if the input number has hundreds of digits, the AKS test will use far more time than others. Look back to the figure, even when we examine a number with just five dig- its, the AKS test will use approximate 10 seconds to get the answer.

5.2 Accuracy

This section will focus on the algorithms accuracy. For primality testing, the accuracy is the degree to which the output is right and consequently we need to count the number of right outputs. Hence, we need a benchmark, in other words, a desired answer for every input. In the design level, a method named isProbablePrime(int certainty) was used to gen- erate definite right answer. This method will return false if the input is definitely compos- ite, and true if the input is probably prime. The probability of wrong output will not exceed 1 certainty ( 2 ) , because the certainty is a parameter determined by caller (i.e. certainty = 100 1 100 means the probability of wrong output is smaller than 1 − ( 2 ) , which is extremely close to 0).

One may ask why we didnt chose the AKS test here as the benchmark. The answer can be found from the last session, for the AKS test runs so slow that it will affect the efficiency of testing program. On the other hand, the isProbablePrime method runs fast enough for our test, even when we choose the certainty as 100. Then we compare the real answer with the desired answer and increment the counter if two answers are same. Finally, we calculate the accuracy and write the data into a file.

The following figure shows the relationship between the input number and the accuracy of Lehmanns test. The x-axis represents the input number, which ranges up to number with 6 digits. The y-axis represents the accuracy corresponding to each input.

25 Lehmann Testing Accuracy 1

0.95 Accucacy

0.9

Iteration: 1 Iteration: 2 Iteration: 3 0.85 0 1 2 3 4 5 6 10 10 10 10 10 10 10 Input number(odd)

Figure 5.5: Lehmann’s Testing Accuracy

1 l Recall Theorem 3.1.1, the probability that Lehmanns test output wrong is smaller than ( 2 ) . The constant l is the loop time. Thus, when l = 1, the accuracy should always be higher than 1 1 1 2 1 − ( 2 ) = 0.5; when l = 2, the accuracy should always be higher than 1 − ( 2 ) = 0.75; 1 3 when l = 3, the accuracy should always be higher than 1 − ( 2 ) = 0.875. From the figure, the actual values of accuracy satisfy all three conditions. They also increase when we increase the number of iterations. Leaving out the accuracy testing figures of the remaining algorithms, we start comparing the accuracy between algorithms. Iteration time was set as 1 here for more obvious differ- ences. Following is the figure illustrating the accuracy of three non-deterministic algorithms: Lehmanns test, the Solovay-Strassen test and the Miller-Rabin test.

Accuracy Comparison 1

0.95

0.9

Lehmann Solovay−Strassen Miller−Rabin 0.85 0 1 2 3 4 5 6 10 10 10 10 10 10 10

Figure 5.6: Accuracy Comparison (1st Version)

26 The Miller-Rabin test seems to have the highest accuracy. Again, we need some explicit val- ues to distinguish between their differences clearly. Hence we further create a table based on the obtained data: 1 Iteration 2 Iterations 3 Iterations Input L S M L S M L S M 100 86 99 100 93 99 100 97 99 100 1000 920 998 997 960 999 1000 985 1000 1000 10000 9363 9988 9988 9700 9999 9999 9847 10000 10000 100000 95129 99951 99960 97660 99999 99999 98772 100000 100000 1000000 960763 999844 999908 980235 999993 999995 990257 999999 1000000

Table 5.1: Accuracy Comparison (2nd Version)

(L means Lehmann’s test, S means the Solovay-Strassen test, M means the Miller-Rabin test)

The first column is the maximum testing number. The rest cells are the total number of right answers, corresponding to first column. Assuming the maximum testing number is 106 with 1 iteration, we can find that the Miller-Rabin test has the most correct answers. Then the next is the Solovay-Strassen test, while the Lehmanns test has the least correct answers. This is always true for any maximum testing number and iteration in this table.

Combining this with the conclusion in last session, the Miller-Rabin test has the highest ac- curacy, but the maximum run time. The Lehmanns test has the lowest accuracy, but the mini- mum run time. The Solovay-Strassen test has the intermediate results on both ends.

In order to make sure the AKS test also performs correctly, we test its accuracy as well. Re- call Theorem4.1.3, the AKS test is a deterministic test which always gives the right output. The following figure proves this statement.

AKS Test Accuracy 2

1.8

1.6

1.4

1.2

1 Accuracy 0.8

0.6

0.4

0.2

0 0 1 2 3 4 10 10 10 10 10 Input number(odd)

Figure 5.7: the AKS test Accuracy

27 5.3 Density of Prime

In this section, we test the density of prime behaved by different algorithms. Let π(x) denotes the number of primes less than or equal to the input number x. The following famous theorem gives an estimation of π(x). Theorem 5.3.1 (Chebychev’s Theorem).

π(x) lim = 1 x→∞ x/lnx

x This means, for enough large x, we can estimate π(x) by lnx , and furthermore estimate the π(x) 1 density of primes x by lnx . More detailed statements and full proof in Sec3.6 in [Die04].

In the design level, we adopt a counter to record the number of primes no greater than the in- put number. Note that the primes here are determined by our algorithms. The data is stored in 1 a file and divided by the input number in MATLAB. We then plot the percentages with lnx to see their degree of fitting. In the figure, two curves seem very similar to every algorithm, which cannot provide us useful information. Therefore, instead of testing and plotting the density of prime, we examine the number of primes and compare it with π(x) values estimated by Chebychevs Theorem to distinguish their differences clearly. Hence we create the following table:

Actual Input Number Theory L S M 10 4 4 4 4 100 15 21 25 25 1000 114 168 168 145 10000 896 1230 1229 1086 100000 7280 9595 9592 8686 1000000 58886 78507 78502 72382

Table 5.2: Number of Primes

(L means Lehmann’s testing, S means the Solovay-Strassen test, M means the Miller-Rabin test)

The first column is the the maximum testing number x. The final column is π(x) calculated by Chebychevs Theorem. The rest cells record the number of primes less than or equal to the input number. By observing this table line by line, we can find that from the input number 1000, the Lehmanns test always returns less primes than estimation, but the Solovay-Strassen test and the Miller-Rabin test always return more primes than estimation, while the primes returned by the Solovay-Strassen test is a little more than the Miller-Rabin test.

To explain the results, lets recall the proved parts of Theorem 3.1.1, Theorem 3.2.4 and Theo- rem 3.3.1. Check up the two cases in every proof, so it is easy to conclude that:

28 1. Lehmanns test: 1 l The probability of mistaking prime for composite equals to ( 2 ) . The probability of 1 l mistaking composite for prime is no more than ( 2 ) . 2. The Solovay-Strassen test The probability of mistaking prime for composite equals to 0. 1 l The probability of mistaking composite for prime is no more than ( 2 ) . 3. The Miller-Rabin test The probability of mistaking prime for composite equals to 0. 1 l The probability of mistaking composite for prime is no more than ( 4 ) . In conclusion, Lehmanns test will mistake some primes for composite numbers; the Solovay- Strassen test and the Miller-Rabin test will mistake some composite numbers for primes, the mistake probability of the Solovay-Strassen test is higher than the Miller-Rabin test. This clarifies the previous observation in a sensible way.

29 Chapter 6

Prime Generation

By reviewing the introduction of prime generation problem in background, prime sieve can be found to be a fast way to obtain a list of small primes, and the primality testing algorithms can be used to find large primes efficiently. These two methods will be studied respectively in this chapter.

6.1 The

In order to make a list of the prime numbers up to some number n, the easiest way is to use the Sieve of Eratosthenes Algorithm. This is a classical algorithm that can be described infor- mally as follows: Algorithm 8: The Sieve of Eratosthenes Input : Integer n > 2 Output: array of prime 1 m[2...n]: array of integer; 2 for j from 2 to n do m[ j] ← 0; 3 j ← 2; 4 while j · j 6 n do 5 if m[ j] = 0 then 6 i ← j · j; 7 while i 6 n do 8 if m[i] = 0 then 9 m[i] ← j; 10 end 11 i ← i + j; 12 end 13 end 14 j ← j + 1; 15 end 16 return m[2...n]; This algorithm can be summarized into three steps:

1. Set up a list of integers of all numbers in [2...n]. All the numbers are unmarked ini- tially.

30 √ 2. For every integer j from 2 to n. Check if j is unmarked, and then mark all unmarked multiples of j until reach n.

3. After the while loop, the numbers that are left unmarked are returned as prime.

Indeed, no prime number is ever marked, since only numbers which can be written as s × j(s > j > 2) are marked. Conversely, if k 6 n is composite, by Theorem 2.1.2 there exists prime number p that divides k. Then we may write it as k = s × p (s > b > 2). When step 2 attains the value p, this prime number turns out to be unmarked, and the number k becomes marked as it is the multiple of p. The time complexity of the Sieve of Eratosthenes can be proved as O(nloglogn). (See Algorithm 3.5.4 in [Die04]) The fastest known prime sieve algo- rithm is the , the time complexity of which is O(N).[AB04]

6.2 The Use of Primality Testing Algorithms

For generating large primes used in cryptography, the standard way is to take a list of prese- lected random numbers with the desired length, and then apply a primality testing algorithm (i.e. the Miller-Rabin test) to get a number which has high probability to be a prime. The iter- 1 100 ation times depends on the length and the maximum allowed error rate (i.e. ( 2 ) ).

The preselection can be done either by test divisions by small prime numbers (up to a few hundreds) or by prime sieve. The deterministic primality testing like the AKS test is improper for its slow nature.

31 Chapter 7

Integer Factorization

Trial division is the simplest√ algorithm for factoring an integer. Recalling Algorithm1, we test every integer j from 2 to n, to see whether they can divide n. If so, instead of returning n as a composite number, we record j as one factor of n and divide n by j. Otherwise we incre- ment j. If this algorithm is given a composite√ n, it will return a list of factors. Obviously, the time complexity of this algorithm is O( n). This works well for small input, alternatively, more algorithms including Fermat Factorization, Pollard rho Factorization, Brents Factoriza- tion Method and Pollard p-1 Factorization. Full details and run time analysis can be found as further reading in [Bar04].

32 Chapter 8

Conclusion

This chapter concludes the work that has been done during this project development process. It describes the main achievements and gives an overview of the future work in case that one might wish to do further investigation.

8.1 Achievements

I successful complete the main purposes of the project. In this report, many algorithms relate relate to the primality problem are carefully described, their accuracy and time complexity are proved theoretically. By using MATLAB, we test the performance of the algorithms with explanations for the results. The improved versions of the primality testing algorithms are stated and given as further reading in reference. Furthermore, we investigate the application of our primality testing algorithms in prime generation and integer factorization.

8.2 Future Work

Due to the lack of time, for the AKS test I have just implemented one updated version. As in Sec 4.2, the latest version of the AKS test has a remarkable improvement on time complexity, which can be implemented in the future.

I used BigInteger class in JAVA for implementation, which is a data type like int, double and long. But the maximum value for a BigInteger can reach or even more than thousands of digits. However due to the limitations of my personal computer, the testing was done with the maximum input 106. This can be extended to hundreds or thousands of digits for more precise measurement in the future.

Two simple methods for prime generation and integer factorization were implemented. We can do more research and implement more efficient algorithms in the future.

33 Bibliography

[Aar03] Scott Aaronson. The prime facts: From to aks. http://www. scottaaronson.com/writings/prime.pdf, 2003.

[AB04] A Atkin and D Bernstein. Prime sieves using binary quadratic forms. Mathematics of Computation, 73(246):1023–1030, 2004.

[AKS04] , Neeraj Kayal, and Nitin Saxena. Primes is in p. Annals of mathematics, pages 781–793, 2004.

[Bar04] Connelly Barnes. Integer factorization algorithms. Oregon State University, 2004.

[Ber98] Daniel Bernstein. Detecting perfect powers in essentially linear time. Mathematics of Computation of the American Mathematical Society, 67(223):1253–1283, 1998.

[Die04] Martin Dietzfelbinger. Primality testing in polynomial time: from randomized algo- rithms to” PRIMES is in P”, volume 3000. Springer, 2004.

[Fri89] John B Friedlander. Shifted primes without large prime factors. Number theory and applications, pages 393–401, 1989.

[Kle10] Bobby Kleinberg. The miller-rabin randomized primality test. http://www.cs. cornell.edu/courses/cs4820/2010sp/handouts/MillerRabin.pdf, 2010.

[Kna97] Helmut Knaust. The prime facts: From euclid to aks. http://www.sosmath.com/ algebra/factor/fac01/fac01.html, 1997.

[KY02] Koro and Yark. Proof of eulers criterion. http://planetmath.org/ proofofeulerscriterion, 2002.

[LJP02] Hendrik W Lenstra Jr and Carl Pomerance. Primality testing with gaussian periods. Lecture Notes in Computer Science, pages 1–1, 2002.

[Run15] William Rundell. Primality testing. http://calclab.math.tamu.edu/ ˜rundell/m470/notes/primality.pdf, 2015.

[Sil10] Joseph H. Silverman. Squares modulo p. http://www.math.brown.edu/˜jhs/ MA0042/FRINTNewCh2324.pdf, 2010.

34