forked from phpduke/Algorithms-Notebook
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathMiller Rabin + mod_Mull.cpp
More file actions
39 lines (38 loc) · 1.07 KB
/
Miller Rabin + mod_Mull.cpp
File metadata and controls
39 lines (38 loc) · 1.07 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
/*Miller-Rabin primality probabilistic test.
* Probability of failing one iteration is at most 1/4. 15 iterations should be enough for 50-bit numbers.
* Time: 15 times the complexity of $a^b \mod c$. */
typedef unsigned long long ull;
const int bits = 10;
// if all numbers are less than 2^k, set bits = 64-k
const ull po = 1 << bits;
ull mod_mul(ull a, ull b, ull &c) {
ull x = a * (b & (po - 1)) % c;
while ((b >>= bits) > 0) {
a = (a << bits) % c;
x += (a * (b & (po - 1))) % c;
}
return x % c;
}
ull mod_pow(ull a, ull b, ull mod) {
if (b == 0) return 1;
ull res = mod_pow(a, b / 2, mod);
res = mod_mul(res, res, mod);
if (b & 1) return mod_mul(res, a, mod);
return res;
}
bool prime(ull p) { //Rabin Miller
if (p == 2) return true;
if (p == 1 || p % 2 == 0) return false;
ull s = p - 1;
while (s % 2 == 0) s /= 2;
rep(i,0,15) {
ull a = rand() % (p - 1) + 1, tmp = s;
ull mod = mod_pow(a, tmp, p);
while (tmp != p - 1 && mod != 1 && mod != p - 1) {
mod = mod_mul(mod, mod, p);
tmp *= 2;
}
if (mod != p - 1 && tmp % 2 == 0) return false;
}
return true;
}