Miller-Rabin primality test (now in 64 bit!)
% Remco Bloemen % 2009-11-27, last updated 2014-03-03
In the previous post I showed an implementation of Miller-Rabin that overflowed when the number was more that 32 bits. In this post I present a way to fix this.
I could remember an instruction I used before, mulq which does 128 bit
multiplication. It multiplies two 64 bit number and stores the least
significant 64 bits in rax and the significant half in rdx.
Now we still need to reduce this number modulo m. Originally I planned
to create a table of 2^n\!\!\mod m, use the bits of rdx to add
them and then add rax % m. But after consulting this x86-64
manual
I found out about divq, which takes a 128 bit number stored in
rdx:rax, a 64 bit number m and p roduces the quotient and remainder.
The whole thing can be coded as:
/// Modular multiplication
/// @param a The first factor, a < m
/// @param a The second factor, b < m
/// @param m The modulus
/// @return The reduced product, a b mod m < m
uint64
This should work fast, but I still need to look into Montgomery reduction. Perhaps I should benchmark the two.
Modular exponentiation can now be implemented using exponentiation by squaring:
/// Modular exponentiation
/// @param b The base, b < m
/// @param e The exponent
/// @param m The modulus
/// @returns The reduced power of a, a^b mod m
uint64
And the Miller-Rabin test becomes:
/// Miller-Rabin probabilistic primality testing
/// @param n The number to test for primality
/// @param k The witness for primality
/// @returns True iff when n is a k-stong pseudoprime
bool
Together with the prime sieve I created earlier a fast probablilistic prime checking procedure can be developed:
const vector<uint64> small_primes = ;
/// Miller-Rabin probabilistic primality testing
/// @param n The number to test for primality
/// @returns False when n is not a prime
bool
This algorithm correctly identifies the first ten primes less than 2^{64}. But then again, so does a single Miller-Rabin round with K= 17. Perhaps I should implement the Baillie-PSW algorithm, there are rumours that it has no false positives for 64 bits!