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.
|
|
// 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
|