## Proving Primality

### February 2, 2010

We examined algorithms for checking the primality of a number in two previous exercises. Both algorithms are probabilistic; the Rabin-Miller algorithm has known false positives, and Carl Pomerance proved that the Baillie-Wagstaff algorithm has an infinite number of false positives, even though none are known.

Today’s exercise describes an algorithm for *proving* that a number is prime, not probably but certainly. The algorithm works by a theorem of Edouard Lucas, which is based on Fermat’s Little Theorem (if *n* is prime then *b*^{n-1} ≡ 1 (mod *n*) for every integer *b* coprime to *n*):

If, for some integer

b,b^{n-1}≡ 1 (modn), and ifb^{(n-1)/q}≢ 1 (modn) foranyprime divisorqofn-1, thennis a prime number.

Thus, if the factors of *n*-1 are known, it is easy to determine the primality of *n*.

Your task is to write a function that determines the primality of an integer using Lucas’ primality test; use it to prove the primality of 2^{89}-1. When you are finished, you are welcome to read or run a suggested solution , or to post your own solution or discuss the exercise in the comments below.

[…] Praxis – Proving Primality By Remco Niemeijer In today’s Programming Praxis exercise we have to implement an algorithm to prove the primality of a number. […]

My Haskell solution (see http://bonsaicode.wordpress.com/2010/02/02/programming-praxis-proving-primality/ for a version with comments):

I found the description of the algorithm confusing. When I implemented it, the routine would report some multiples of 5 (e.g., 15 and 35) to be prime.

Studying the proof at the mathpages.com link, given above, I think the algorithm should be to find a b so that b^(x-1) == 1 (mod n) then, if b^((n-1)/q) != 1 (mod n) for *all* prime divisors q of n-1, n is prime. If b^((n-1)/q) == 1 (mod n) for some q, then try a new value for b. This matches the pseudocode at wikipedia.

My python code is below:

It wasn’t confusing, it was wrong. Thanks for pointing out the bug. I’ve updated the solution and added a test function.

By the way, your version of is_prime incorrectly reports that 2 is composite. You should change the test at lines 22 and 23 to read:

`if n%2 == 0:`

return n == 2

Don’t feel bad; Jon Bentley got that wrong in one of his books, so you’re in good company.

D’oh…guess that’ll teach me not to edit a routine and not test it again before posting.

Is there a way to edit my earlier post fix lines 22 and 23? Or should I just repost a correct version?

My confusion was over the word “any” in

“… if b^((n-1)/q) != 1 (mod n) for *any* prime divisor q of n-1, n is prime.”

At first, I read the phrase to mean if I found any one q for which the non-congruence was true, then n is prime. However, the correct reading is that the non-congruence holds no matter which q you try. Therefore, you have to try every q to prove n is prime. Perhaps using “every” instead of “any” would be clearer.

Here’s a corrected version of the python code for proving a number is prime using the Lucas algorithm.