You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

67 lines
1.5 KiB

// cl_miller_rabin_test().
// General includes.
#include "cl_sysdep.h"
// Specification.
#include "cl_IF.h"
// Implementation.
#include "cln/modinteger.h"
namespace cln {
cl_boolean cl_miller_rabin_test (const cl_I& n, int count, cl_I* factor)
{
// [Cohen], section 8.2, algorithm 8.2.2.
var cl_modint_ring R = find_modint_ring(n); // Z/nZ
var cl_I m = n-1;
var uintL e = ord2(m);
m = m>>e;
// n-1 = 2^e*m
var cl_MI one = R->one();
var cl_MI minusone = R->uminus(one);
for (int i = 0; i < count; i++) {
// Choosing aa small makes the expt_pos faster.
var cl_I aa = (i == 0
? (cl_I) 2
: i <= cl_small_prime_table_size
? (cl_I) (unsigned int) cl_small_prime_table[i-1] // small prime
: 2+random_I(n-2)); // or random >=2, <n
if (aa >= n)
break;
// Now 1 < aa < n.
var cl_MI a = R->canonhom(aa);
var cl_MI b = R->expt_pos(a,m); // b = a^m
if (b == one)
goto passed;
for (uintL s = e; s > 0; s--) {
if (b == minusone)
goto passed;
var cl_MI new_b = R->square(b);
if (new_b == one) {
// (b-1)*(b+1) == 0 mod n, hence n not prime.
if (factor)
*factor = gcd(R->retract(b)-1,n);
return cl_false;
}
b = new_b;
}
// b = a^(2^e*m) = a^(n-1), but b != -1 mod n, hence n not prime.
if (factor) {
var cl_I g = gcd(aa,n);
if (g > 1)
*factor = g;
else
*factor = 0;
}
return cl_false;
passed:
;
}
return cl_true;
}
} // namespace cln