Primality Tests

Generating Primes by Sieving

A huge amount of what we have built so far leans on primes: unique factorisation, the fact that is a field, Fermat's Little Theorem, and the guarantee that has a primitive element. All of the applications in this topic (RSA, Diffie–Hellman, and friends in Cryptosystems) need us to actually get hold of primes. So there are two practical questions to answer: how do we generate a list of all the primes up to some bound, and how do we decide whether one particular number is prime?

The oldest answer to the first question is over two thousand years old and still the one we use.

Algorithm 6.1 (Sieve of Eratosthenes, or sieving). To generate a list of prime numbers less than or equal to a given number :

  • Start with a list of all integers from up to .
  • The first entry in the list (namely ) is prime. Mark every ​th entry after in as composite.
  • The next entry in the list not marked as composite is prime. Label it , and mark every ​th entry after in as composite.
  • Repeat the previous step until the next non-composite entry is greater than . Then every non-composite entry remaining in the list is prime.

Basically, you walk along the list; the first number you have not already crossed out must be prime, and once you know it is prime you get to delete all of its multiples for free. Nothing in the algorithm ever divides anything — marking "every ​th entry" is just counting — which is exactly why sieving is so cheap compared to testing numbers one at a time.

Why does the first surviving entry have to be prime? Suppose is the first entry not yet marked as composite at some stage. Every prime smaller than has already had its turn, and each of those turns crossed out all of that prime's multiples; so is not a multiple of any prime less than , and hence has no factorisation at all other than . That is precisely what it means for to be prime.

The other question is why we are allowed to stop so early, at rather than .

Note

Fact
Every composite integer has a prime factor with .

Proof. Since is composite we may write with . If we had , then as well, and so

which is absurd; hence . Now , so has some prime factor , and with .

This one was Q7(a) of the Topic 1 tutorial, so it should look familiar. Its consequence for sieving is immediate: if a number survives every pass up to , then has no prime factor , and if were composite the Fact would hand us one. So is prime, and there is no work left to do. Stopping early is only legal because the crossing-out is exhaustive; if you skip a prime pass below , composites survive.

It is worth noticing where each pass starts doing genuinely new work. In the pass for , the multiples have all already been crossed out, because each of has a prime factor smaller than whose pass has already run. So the first new entry killed in the pass is , and once the pass achieves nothing at all — which is the cutoff again, seen from the other side.

Sieving Out the Primes Below 50

Example. Find all primes less than using the sieving technique.
We start with and note that , so the passes will stop as soon as the next surviving entry exceeds .

Pass 1. The first entry is , which is prime. Mark every second entry after it:

Pass 2. The next surviving entry is , which is therefore prime. Mark every third entry after it, namely ; of these, the ones not already crossed out are

Pass 3. The next surviving entry is , so is prime. Mark ; the newly killed entries are

Pass 4. The next surviving entry is , so is prime. Mark ; the only new casualty is

Stop. The next surviving entry is , and , so the algorithm halts and everything still standing is prime. Laying the list out in rows of ten, with a dot for every entry that has been crossed out (or was never in the list), the survivors are:

Therefore, the primes less than are

fifteen of them in total. Notice how little work the later passes did: pass killed two numbers and pass killed exactly one, consistent with the observation that the pass only starts biting at ( and respectively).

Testing One Number at a Time

Sieving is the right tool when you want all the primes up to some bound, but it is wildly wasteful if you only care about one number; to decide whether is prime you would rather not first write down every prime below . Algorithms that decide whether or not a single number is prime are called primality tests.

Algorithm 6.2 (Basic primality test). To test whether a given positive integer is prime:

  • Start with a list of integers (or of primes, obtained via sieving) from up to .
  • For each number in , find , for instance via the Euclidean algorithm. If , we know is not prime and can terminate the algorithm.
  • If the list has been exhausted and the algorithm has not terminated, we know is prime and can terminate the algorithm.

This is just trial division dressed up, and it is correct for exactly the reason the sieve stops at : if is composite it has a prime factor , and that is somewhere in , where it will show up as . In some cases it is faster to run a divisibility test for than to grind through the Euclidean algorithm; if is one of you should just use the digit tricks.

Example. Use the basic primality test on and on .
For , we have , so and . Running down the list,

so the list is exhausted without a hit. Therefore, is prime.
For , again since . The first six entries give , but

so we terminate immediately. Therefore, is not prime; indeed . Notice that the test hands you a factor as a by-product, which no other test in this note does.

So why look any further? Because is enormous for the we actually care about. A -bit RSA modulus has , and no amount of computing power gets you through a list of that length. The obvious patch is to stop being exhaustive and sample at random instead, but that fails badly too. There are exactly integers between and that are not coprime with , and that count can be tiny compared with ; so a randomly chosen almost never detects anything.

Example. For with prime, what is the chance that a randomly chosen integer between and fails to be coprime with ?
Recall from Fermats Little Theorem and Eulers Theorem that . So

Therefore, the chance of a random exposing as composite is only , and the chance of independent random choices all missing is . If has a hundred digits then and you would need on the order of attempts before seeing anything; the randomised basic test is worthless. The problem is not that the basic test is wrong — it is perfectly correct — it is that its evidence is far too rare to stumble across by chance. What we want is a test whose evidence for compositeness is common, so that random sampling actually finds it.

Fermat's Little Theorem as a Primality Test

Recall Fermat's Little Theorem: if is prime, then for all integers with ,

Read forwards, this is a statement about primes. Read backwards — as its contrapositive — it becomes a statement about non-primes, and that is the version that does the work.

Note

Fact (contrapositive of Fermat's Little Theorem)
Given , if there is some with and , then is not prime.

Basically, every prime is obliged to satisfy for every it does not divide; so a single value of that breaks the rule is a cast-iron proof that is composite. An like this is called a witness to the compositeness of . The beauty of this is that computing by repeated squaring is fast even for astronomically large , and — unlike the basic test — witnesses turn out to be abundant rather than rare.

Algorithm 6.3 (Exhaustive Fermat primality test). To test whether a given positive integer is prime:

  • Start with a list of integers from up to .
  • For each number in , find . If , we know is not prime and can terminate the algorithm.
  • If the list has been exhausted and the algorithm has not terminated, we know is prime and can terminate the algorithm.

The list runs from to because the two endpoints it leaves out are useless: always, and for odd we have in as well, since is even. Neither can ever be a witness, so there is no point testing them.

It is worth checking that the exhaustive version really is a genuine primality test in both directions, and the key observation is that non-units can never pass.

Note

Lemma
If , then in .

Proof. Suppose instead , so . Since , transitivity gives . But and , so too; subtracting, divides

so , contradicting .

So if is composite it has some divisor with , and taking (which lies in the list, since for ) gives a value that fails the test. Hence Algorithm 6.3 reports "prime" only for genuine primes. The catch, of course, is that running modular exponentiations is even worse than the gcd computations of the basic test; the exhaustive version is a proof of concept, not a practical algorithm.

Example. Use the Fermat primality test to deduce that is prime.
Here , so the list is and we need in for each of them:

The list has been exhausted and no failed. Therefore, is prime. Notice how writing as and as meant we only ever really computed ; when running these by hand, always look for a way to recycle a power you have already found.

Example. Use the Fermat primality test to deduce that is not prime.
Here , so the list is and we need in . Taking the first entry ,

so we terminate at once. Therefore, is not prime. In this case every entry of the list is a witness, as you can check:

using , , and . So whichever the algorithm happens to try first, is exposed immediately — which is the behaviour we are hoping for in general.

When the Fermat Test Lies

The exhaustive test is airtight but slow; the whole point of Fermat's test is that we would like to run only a handful of values of and draw a conclusion. That raises the obvious worry: can a composite number pass the Fermat test for some particular ? It absolutely can, and such numbers get a name.

Note

Definition
For a given , if is not prime but there is some integer such that , we call a Fermat pseudoprime to the base .

If is a Fermat pseudoprime to every base that is coprime with , we call a Carmichael number. That is, is a Carmichael number if and only if is composite and for all .

The sequence of Carmichael numbers begins

Basically, a Fermat pseudoprime is a composite number that is impersonating a prime for one particular base, and a Carmichael number is a composite number that impersonates a prime for every base it possibly could. For a Carmichael number the Fermat primality test is no better than the basic primality test, since the only that can ever expose it are the ones with — exactly the that the basic test was already looking for, and exactly the ones we showed are hopelessly rare.

Example. Show that is a Fermat pseudoprime to the base , but not to the base .
First, , so is certainly composite. For the base , the key observation is

and since this gives

So sails through the Fermat test to the base ; it is a Fermat pseudoprime to base . For the base we repeatedly square:

Now notice something lovely: , and so is a unit; cancelling gives , i.e. or a divisor of it. Since , we can reduce the exponent modulo the order:

Therefore, is a Fermat pseudoprime to base but not to base ; the single value is a witness proving composite. Passing the Fermat test for one base proves nothing whatsoever; only a failure is conclusive.

Example. Find all integers such that is a Fermat pseudoprime to base .
Certainly is composite, so we just need every in range with in . By the Lemma above we may ignore any that is not a unit, so the candidates are

Now , so for every unit; and happens exactly when . Combining the two,

so if and only if . Squaring each candidate,

Therefore, is a Fermat pseudoprime exactly to the bases . Notice the count: of the units pass the test and the other are witnesses, i.e. exactly half — which is the worst case permitted by the next result.

The Randomised Fermat Test

Running the Fermat primality test up to times is still hopeless for very large . Instead we choose the test integers randomly and report whether is likely to be prime after a limited number of checks.

Algorithm 6.5 (Fermat primality test, randomised). To test whether a given positive integer is prime:

  • Start with a list of integers from up to .
  • Repeat the following up to times:
    • Randomly choose (and remove) an integer from the list.
    • If , report that is not prime and terminate.
    • If , report that is not prime and terminate.
  • If the algorithm has not terminated after iterations, report that is probably prime and terminate.

The gcd check is strictly speaking redundant — by the Lemma, any with automatically fails the exponentiation check too — but a gcd is much cheaper than a modular exponentiation, so it is worth doing first.

Everything now hinges on how likely a random is to be a witness. This is where the Fermat test decisively beats the basic test.

Note

Lemma
If there is any such that , then there are at least such .

Proof. Split the unit group into the elements that pass the test and the elements that fail it:

so that . Assume is non-empty and fix one witness . For each , the element is a product of units and hence a unit, and

so . Moreover the map is injective, since is invertible and we can recover ; so distinct give distinct . Hence , and therefore

Basically, the witnesses come for free in bulk: multiply every liar by a single witness and you get that many distinct witnesses back, so witnesses can never be the minority. This is the entire reason the randomised Fermat test is useful — evidence of compositeness is either completely absent or at least half the group, never merely rare.

Consequently each round of the loop, conditional on being composite with at least one witness in , has probability at least of catching it, and so the algorithm has at worst a

Contrast this with the worst-case false-positive rate we computed for the randomised basic test on : that quantity barely moves as grows, while collapses. Twenty rounds already gives a false positive rate below one in a million, and makes an error less likely than a hardware fault.

Two warnings before moving on. A report of "probably prime" is never a proof; a composite number that survives rounds is still composite, you were just unlucky times in a row. And more seriously: the bound assumes at least one witness exists in , which is precisely what fails for a Carmichael number. For every unit passes, so and the argument above says nothing at all; the randomised Fermat test will happily report that is probably prime no matter how large you make , as long as it keeps drawing units.

Example. Run the randomised Fermat test on with first random choice .
First , so we proceed to the exponentiation. Since in ,

Therefore, the test reports (correctly, and after a single round) that is not prime. Had it instead drawn , or first, that round would have passed and the loop would have continued; but as we counted above, those are only of the candidates in , so the odds are heavily in our favour.

Certifying Primes with the Lucas Test

The randomised Fermat test can prove a number composite but can never prove one prime. That is genuinely annoying if you are building a cryptosystem and want a guarantee. The fix is to stop asking for a symptom of primality and start asking for a certificate, and the order of a unit provides exactly the right one.

Recall two facts we already have. First, if and only if is prime, so for any composite we must have . Second, if is prime then has a primitive element, i.e. a unit whose order is the full . Together these give a clean characterisation.

Note

Theorem
A positive integer is prime if and only if there is some such that .

Proof. () Suppose is prime. Then , and has a primitive element ; by definition .
() Suppose for some unit . By the theorem that order divides the totient, , and in particular

But counts the integers in coprime with , and itself is never one of them (as ), so always. Hence ; that is, every one of is coprime with . So has no divisor with , and therefore is prime.

Basically, " is prime" and " contains an element of order " are the same statement, so finding such an element is a proof of primality. And we already know how to check whether a given has full order without computing the order itself — it is the primitive-element test from Order and Primitive Elements.

Algorithm 6.6 (Lucas primality test, randomised). To test whether a given positive integer is prime:

  • Start with a list of integers from up to .
  • Repeat the following up to times:
    • Randomly choose (and remove) an integer from the list.
    • If , report that is not prime and terminate.
    • If , report that is not prime and terminate.
    • If for all primes that divide , report that is prime and terminate.
  • If the algorithm has not terminated after iterations, report that is probably not prime and terminate.

The first three bullets are identical to the randomised Fermat test; all the new content is in the fourth. Why does it detect ? The condition already forces . If the order were a proper divisor of , its prime factorisation would be missing at least one copy of some prime , so we would have and hence for that . So the fourth bullet holding for every is precisely the statement that no proper divisor of is the order — i.e. , and by the characterisation theorem is prime.

Notice that the Lucas primality test can in some cases guarantee a number is prime, unlike the (non-exhaustive) Fermat primality test. The price is twofold. First, the Lucas test is only practical when can be easily factorised — and factorising a -bit is exactly the sort of problem we invented these tests to avoid. Second, a report of "probably not prime" is genuinely weak evidence: the test only certifies when the random draw lands on a primitive element, and a prime has only of those among its units, which can be a modest fraction. A "prime" verdict from Lucas is a proof; a "probably not prime" verdict is just an admission that no certificate turned up in tries.

Example. Use the Lucas primality test to deduce that is prime.
Here , so the primes dividing are and , and the two exponents to check are

The candidate list is . Suppose the first random draw is . Then , and in as computed earlier, so the first two checks pass; but

so the fourth bullet fails at and this round ends with no conclusion. Suppose the next draw is . Then , and

So , while and . Therefore, and the test reports that is prime — and this time that is a proof, not a probability. As a sanity check, we found in Order and Primitive Elements that the primitive elements of are exactly and ; those are the only two draws that can certify, and since and both fail, the worst possible ordering needs iterations.

Example. Use the Lucas primality test to demonstrate that is prime, and find the maximum number of iterations the test could need.
Here , so the primes dividing are and , and the exponents to check are

Suppose the first draw is . Then and

so passes the Fermat check, but kills the certificate. No conclusion; draw again. Suppose the next draw is , and build up the powers by squaring:

Hence , so the Fermat check passes; and the two certificate checks give and . Therefore , and the test reports that is prime.
For the maximum number of iterations, note that the test can only terminate with "prime" when the drawn is a primitive element of . By the corollary in Order and Primitive Elements there are exactly

primitive elements. Neither (order ) nor (order ) is one of them, so all sit inside the candidate list , which has entries. In the worst case the first draws are the non-primitive candidates, and then the ​th draw is forced to be primitive. Therefore, at most iterations are needed before the test concludes that is certainly prime.

Why Lucas Never Certifies a Carmichael Number

Example. Suppose that when applying the Lucas primality test to , all the chosen integers happen to be coprime with . What will the test report?
First set up the numbers. We have

so is composite, the primes dividing are , and , and the three certificate exponents are

The gcd check. By assumption every drawn satisfies , so this check never fires.
The Fermat check. Let , so is coprime with each of , and . Fermat's Little Theorem in each prime modulus gives

and since , each of , and divides . Raising to the appropriate powers,

and as are pairwise coprime, the CRT glues these into . So the Fermat check never fires either — and this is exactly the computation proving that is a Carmichael number.
The certificate check. Now run the identical argument with in place of . Since

each of , and divides as well, so the same three congruences and the same application of the CRT give

But is one of the three exponents that the fourth bullet requires to be . So for the condition fails, for every single unit , on every single iteration. The test can therefore never reach the "report that is prime" line.
Therefore, the algorithm runs all iterations without terminating early and reports that is probably not prime.

That verdict happens to be correct, but it is worth being very clear about what did and did not just happen. The test has not proved anything about ; it has simply failed to find a unit of order , and by the characterisation theorem no such unit can exist, because is composite. In fact we have shown something sharper: every unit satisfies , so for all , and the largest order in the whole group is — nowhere near .

Compare this with what the randomised Fermat test does on the same input. Every unit passes , so under the same assumption (all draws coprime with ) Fermat runs its rounds and reports that is probably prime, which is simply wrong, no matter how large is. This is the punchline of the whole lecture: Fermat asks for a symptom of primality and a Carmichael number can fake it, whereas Lucas asks for a certificate — an element of order exactly — which a composite number cannot fake, because it does not have one.

Comparing the Three Tests

All three algorithms in this lecture answer the same question, and they fail in completely different ways; it is worth keeping the differences straight.

Basic (6.2) Fermat (6.3 / 6.5) Lucas (6.6)
Evidence of compositeness a shared factor a witness either of the two on the left
How common is that evidence , often tiny or at least , never in between or at least
Can report "not prime" correctly yes yes yes
Can report "prime" correctly yes, but only after steps only in the exhaustive version (6.3) yes, whenever it reports "prime"
What "no conclusion" means probably prime probably not prime
Worst-case false positive in rounds for , but useless on Carmichael numbers none; a "prime" report is a proof
Extra input needed none none the prime factorisation of
Bonus hands you an actual factor hands you a primitive element

So the working method in practice is:

  • If is small and you want all primes up to , sieve (Algorithm 6.1); it is far cheaper per prime than any individual test.
  • If is small, use the basic test (Algorithm 6.2); it is simple, exact, and gives you a factor when it fails.
  • If is large, run the randomised Fermat test (Algorithm 6.5) with a decent to throw away composites quickly and cheaply.
  • If you need an actual guarantee and you happen to know the factorisation of , finish with the Lucas test (Algorithm 6.6).

Finally, keep the asymmetry of all of this in mind. Proving a number composite is easy — one witness does it, and witnesses are abundant whenever they exist at all. Proving a number prime is hard, because "no factor exists" is a statement about everything, and the only way around it is to produce a positive object like a primitive element instead. That asymmetry is not just a quirk of these algorithms; it is the whole reason RSA works, since generating large primes is comparatively easy while factorising their product is not.