Kaidul

Miller-rabin Test

Dec 27th, 2016
129
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 1.84 KB | None | 0 0
  1. #define i64 unsigned long long
  2.  
  3. // c <= a x b
  4. i64 mulmod(i64 a, i64 b, i64 mod) {
  5.     i64 x = 0, y = a % mod;
  6.     while(b) {
  7.         if(b & 1) {
  8.             x = (x + y) % mod;
  9.         }
  10.         y = (y << 1) % mod;
  11.         b >>= 1;
  12.     }
  13.     return x;
  14. }
  15.  
  16. i64 power(i64 base, i64 exp, i64 mod) {
  17.     i64 x = 1, y = base % mod;
  18.     while(exp) {
  19.         if(exp & 1) {
  20.             x = mulmod(x, y, mod);
  21.         }
  22.         y = mulmod(y, y, mod);
  23.         exp >>= 1;
  24.     }
  25.     return x;
  26. }
  27.  
  28. // returns false if n is composite and returns true if n is probably prime.
  29. // d is an odd number such that d*2^r = n - 1 for some r >= 1
  30. bool millerTest(i64 n, i64 d) {
  31.  
  32.     // pick a random number between [1 ... n]
  33.     i64 a = rand() % (n - 1) + 1;
  34.  
  35.     // compute a^d % n
  36.     i64 x = power(a, d, n);
  37.  
  38.  
  39.     // Keep squaring x while one of the following doesn't
  40.     // happen
  41.     // (i)   d does not reach n - 1
  42.     // (ii)  (x^2) % n is not 1
  43.     // (iii) (x^2) % n is not n - 1
  44.     while(d != n - 1 and x != 1 and x != n - 1) {
  45.         x = mulmod(x, x, n);
  46.         d <<= 1;
  47.     }
  48.  
  49.     if(x != n - 1 and !(d & 1)) {
  50.         // composite number
  51.         return false;
  52.     }
  53.  
  54.     return true;
  55. }
  56.  
  57. // returns false if n is composite and returns true if n is probably prime.
  58. // iter is an input parameter that determines accuracy level. Higher value of iter indicates more accuracy.
  59. // accurate till 10^18 e.g. isPrime(LLONG_MAX) works even only in 1 iterations
  60. bool isPrime(i64 n, int iter = 1) {
  61.  
  62.     // corner cases
  63.     if(n < 2) {
  64.         return false;
  65.     }
  66.     if(n == 2) {
  67.         return true;
  68.     }
  69.     if(!(n & 1)) { // even
  70.         return false;
  71.     }
  72.  
  73.     // Find d such that n = d * 2^r + 1 for some r >= 1
  74.     i64 d = n - 1;
  75.     while(!(d & 1)) {
  76.         d >>= 1;
  77.     }
  78.  
  79.     // check iter times
  80.     for(int i = 0; i < iter; i++) {
  81.         if(!millerTest(n, d)) {
  82.             return false;
  83.         }
  84.     }
  85.     return true;
  86. }
Advertisement
Add Comment
Please, Sign In to add comment