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

25 years ago
25 years ago
25 years ago
  1. // cl_miller_rabin_test().
  2. // General includes.
  3. #include "cl_sysdep.h"
  4. // Specification.
  5. #include "cl_IF.h"
  6. // Implementation.
  7. #include "cln/modinteger.h"
  8. namespace cln {
  9. cl_boolean cl_miller_rabin_test (const cl_I& n, int count, cl_I* factor)
  10. {
  11. // [Cohen], section 8.2, algorithm 8.2.2.
  12. var cl_modint_ring R = find_modint_ring(n); // Z/nZ
  13. var cl_I m = n-1;
  14. var uintL e = ord2(m);
  15. m = m>>e;
  16. // n-1 = 2^e*m
  17. var cl_MI one = R->one();
  18. var cl_MI minusone = R->uminus(one);
  19. for (int i = 0; i < count; i++) {
  20. // Choosing aa small makes the expt_pos faster.
  21. var cl_I aa = (i == 0
  22. ? (cl_I) 2
  23. : i <= cl_small_prime_table_size
  24. ? (cl_I) (unsigned int) cl_small_prime_table[i-1] // small prime
  25. : 2+random_I(n-2)); // or random >=2, <n
  26. if (aa >= n)
  27. break;
  28. // Now 1 < aa < n.
  29. var cl_MI a = R->canonhom(aa);
  30. var cl_MI b = R->expt_pos(a,m); // b = a^m
  31. if (b == one)
  32. goto passed;
  33. for (uintL s = e; s > 0; s--) {
  34. if (b == minusone)
  35. goto passed;
  36. var cl_MI new_b = R->square(b);
  37. if (new_b == one) {
  38. // (b-1)*(b+1) == 0 mod n, hence n not prime.
  39. if (factor)
  40. *factor = gcd(R->retract(b)-1,n);
  41. return cl_false;
  42. }
  43. b = new_b;
  44. }
  45. // b = a^(2^e*m) = a^(n-1), but b != -1 mod n, hence n not prime.
  46. if (factor) {
  47. var cl_I g = gcd(aa,n);
  48. if (g > 1)
  49. *factor = g;
  50. else
  51. *factor = 0;
  52. }
  53. return cl_false;
  54. passed:
  55. ;
  56. }
  57. return cl_true;
  58. }
  59. } // namespace cln