I wrote a Miller-Rabin reconciliation criterion based on the following pseudocode:
Input: n > 2, an odd integer to be tested for primality;
k, a parameter that determines the accuracy of the test
Output: composite if n is composite, otherwise probably prime
write n β 1 as 2sΒ·d with d odd by factoring powers of 2 from n β 1
LOOP: repeat k times:
pick a randomly in the range [2, n β 1]
x β ad mod n
if x = 1 or x = n β 1 then do next LOOP
for r = 1 .. s β 1
x β x2 mod n
if x = 1 then return composite
if x = n β 1 then do next LOOP
return composite
return probably prime
The code I rarely get for 31 (if I put it in a loop to check numbers from 2 to 100). There must be something wrong, but I donβt see what it is.
bool isProbablePrime(ulong n, int k) {
if (n < 2 || n % 2 == 0)
return n == 2;
ulong d = n - 1;
ulong s = 0;
while (d % 2 == 0) {
d /= 2;
s++;
}
assert(2 ^^ s * d == n - 1);
outer:
foreach (_; 0 .. k) {
ulong a = uniform(2, n);
ulong x = (a ^^ d) % n;
if (x == 1 || x == n - 1)
continue;
foreach (__; 1 .. s) {
x = (x ^^ 2) % n;
if (x == 1) return false;
if (x == n - 1) continue outer;
}
return false;
}
return true;
}
I also tried option
...
foreach (__; 1 .. s) {
x = (x ^^ 2) % n;
if (x == 1) return false;
if (x == n - 1) continue outer;
}
if ( x != n - 1) return false; // this is different
...
I have another version of the test that works correctly, but uses modpow. I would like to have a version that is closer to the pseudo-code that is part of the description of rossetta.org .
: Re: . - . , Ruby . , - .
BigInt, , , modpow. , . , modpow, , , .
ulong x = ((BigInt(a) ^^ d) % BigInt(n)).toLong();