I have written the Rabin-Miller test in Python and ported it to C. But somehow, the C version is ~20 times slower on my system, and I am not sure how. Anyway, here is my code.
Python
import random
import time
def rabin_miller(n):
if n in [2, 3, 5]:
return True
if n < 2 or n % 2 == 0:
return False
s = 0
d = n - 1
while d % 2 == 0:
s += 1
d >>= 1
for k in range(2 ** 4):
a = random.randrange(2, n - 1)
x = pow(a, d, n)
if x == 1 or x == n - 1:
continue
c = False
for r in range(s - 1):
x = pow(x, 2, n)
if x == 1:
return False
if x == n - 1:
break
else:
return False
return True
for i in range(10000):
rabin_miller(i)
C
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
long mod_pow(long b, long e, long m){
if(m == 1)
return 0;
long c = 1;
for(long i = 0; i < e; i++)
c = (c * b) % m;
return c;
}
int rabin_miller(long n){
if(n == 2 || n == 3)
return 1;
if(n < 2 || n % 2 == 0)
return 0;
long s = 0, d = n - 1, k = 10, a, x, stop;
while(d % 2 == 0)
s += 1, d >>= 1;
srand(time(NULL));
for(long i = 0; i < k; i++){
a = (long) (((float) rand() / RAND_MAX) * (n - 3)) + 2;
x = mod_pow(a, d, n);
if(x == 1 || x == n - 1)
continue;
stop = 1;
for(long r = 0; r < s - 1; r++){
x = mod_pow(x, 2, n);
if(x == 1)
return 0;
if(x == n - 1){
stop = 0;
break;
}
}
if(stop){
return 0;
}
}
return 1;
}
int main(int argc, char *argv[]){
for(long i = 1; i < 10000; i++){
rabin_miller(i);
}
return 0;
}
while (d % 2 == 0)With I thinkwhile (~t & 1)\$\endgroup\$