|
| 1 | +<!--?title Primality tests --> |
| 2 | +# Primality tests |
| 3 | + |
| 4 | +This article describes multiple algorithms to determine if a number is prime or not. |
| 5 | + |
| 6 | +## Trial division |
| 7 | + |
| 8 | +By definition a prime number doesn't have any divisors other than $1$ and itself. |
| 9 | +A composite number has at least one additional divisor, let's call it $d$. |
| 10 | +Naturally $\frac{n}{d}$ is also a divisor of $n$. |
| 11 | +It's easy to see, that either $d \le \sqrt{n}$ or $\frac{n}{d} \le \sqrt{n}$, therefore one of the divisors $d$ and $\frac{n}{d}$ is $\le \sqrt{n}$. |
| 12 | +We can use this information to check for primality. |
| 13 | + |
| 14 | +We try to find a non-trivial divisor, by checking if any of the numbers between $2$ and $\sqrt{n}$ is a divisor of $n$. |
| 15 | +If it is a divisor, than $n$ is definitely not prime, otherwise it is. |
| 16 | + |
| 17 | +```cpp |
| 18 | +bool isPrime(int x) { |
| 19 | + for (int d = 2; d * d <= x; d++) { |
| 20 | + if (x % d == 2) |
| 21 | + return false; |
| 22 | + } |
| 23 | + return true; |
| 24 | +} |
| 25 | +``` |
| 26 | +
|
| 27 | +This is the simplest form of a prime check. |
| 28 | +You can optimize this function quite a bit, for instance by only checking all odd numbers in the loop, since the only even prime number is 2. |
| 29 | +
|
| 30 | +## Fermat primality test |
| 31 | +
|
| 32 | +This is a probabilistic test. |
| 33 | +
|
| 34 | +Fermat's little theorem (see also [Euler's totient function](https://cp-algorithms.com/algebra/phi-function.html)) states, that for a prime number $p$ and a coprime integer $a$ the following equation holds: |
| 35 | +
|
| 36 | +$$a^{p-1} \equiv 1 \bmod p$$ |
| 37 | +
|
| 38 | +In general this theorem doesn't hold for composite numbers. |
| 39 | +
|
| 40 | +This can be used to create a primality test. |
| 41 | +We pick an integer $2 \le a \le p - 2$, and check if the equation holds or not. |
| 42 | +If it doesn't hold, e.g. $a^{p-1} \not\equiv 1 \bmod p$, we know that $p$ cannot be a prime number. |
| 43 | +In this case we call the base $a$ a *Fermat witness* for the compositeness of $p$. |
| 44 | +
|
| 45 | +However it is also possible, that the equation holds for a composite number. |
| 46 | +So if the equation holds, we don't have a proof for primality. |
| 47 | +We only can say that $p$ is *probably prime*. |
| 48 | +If it turns out that the number is actually composite, we call the base $a$ a *Fermat liar*. |
| 49 | +
|
| 50 | +By running the test for all possible bases $a$, we can actually prove that a number is prime. |
| 51 | +However this is not done in practice, since this is a lot more effort that just doing *trial division*. |
| 52 | +Instead the test will be repeated multiple times with random choices for $a$. |
| 53 | +If we find no witness for the compositeness, it is very likely that the number is in fact prime. |
| 54 | +
|
| 55 | +```cpp |
| 56 | +bool probablyPrimeFermat(int n, int iter=5) { |
| 57 | + if (n < 4) |
| 58 | + return n == 2 || n == 3; |
| 59 | +
|
| 60 | + for (int i = 0; i < iter; i++) { |
| 61 | + int a = 2 + rand() % (n - 3); |
| 62 | + if (binpower(a, n - 1, n) != 1) |
| 63 | + return false; |
| 64 | + } |
| 65 | + return true; |
| 66 | +} |
| 67 | +``` |
| 68 | + |
| 69 | +We use [Binary Exponentiation](./algebra/binary-exp.html) to efficiently compute the power $a^{p-1}$. |
| 70 | + |
| 71 | +There is one bad news though: |
| 72 | +there exist some composite numbers where $a^{n-1} \equiv 1 \bmod n$ holds for all $a$ coprime to $n$, for instance for the number $561 = 3 \cdot 11 \cdot 17$. |
| 73 | +Such numbers are called *Carmichael numbers*. |
| 74 | +The Fermat primality test can identify these numbers only, if we have immense luck and choose a base $a$ with $\gcd(a, n) \ne 1$. |
| 75 | + |
| 76 | +The Fermat test is still be used in practice, as it is very fast and Carmichael numbers are very rare. |
| 77 | +E.g. there only exist 646 such numbers below $10^9$. |
| 78 | + |
| 79 | +## Miller-Rabin primality test |
| 80 | + |
| 81 | +The Miller-Rabin test extends the ideas from the Fermat test. |
| 82 | + |
| 83 | +For an odd number $n$, $n-1$ is even and we can factor out all powers of 2. |
| 84 | +We can write: |
| 85 | +$$n - 1 = 2^s \cdot d,~\text{with}~d~\text{odd}.$$ |
| 86 | + |
| 87 | +This allows us to factorize the equation of Fermat's little theorem: |
| 88 | +$$\begin{array}{rl} |
| 89 | +a^{n-1} \equiv 1 \bmod n &\Longleftrightarrow a^{2^s d} - 1 \equiv 0 \bmod n \\\\ |
| 90 | +&\Longleftrightarrow (a^{2^{s-1} d} + 1) (a^{2^{s-1} d} - 1) \equiv 0 \bmod n \\\\ |
| 91 | +&\Longleftrightarrow (a^{2^{s-1} d} + 1) (a^{2^{s-2} d} + 1) (a^{2^{s-2} d} - 1) \equiv 0 \bmod n \\\\ |
| 92 | +&\quad\vdots \\\\ |
| 93 | +&\Longleftrightarrow (a^{2^{s-1} d} + 1) (a^{2^{s-2} d} + 1) \cdots (a^{d} + 1) (a^{d} - 1) \equiv 0 \bmod n \\\\ |
| 94 | +\end{array}$$ |
| 95 | + |
| 96 | +If $n$ is prime, then $n$ has to divide one of these factors. |
| 97 | +And in the Miller-Rabin primality test we check exactly that statement, which is a more stricter version of the statement of the Fermat test. |
| 98 | +For a base $2 \le a \le n-2$ we check if either |
| 99 | +$$a^d \equiv 1 \bmod n$$ |
| 100 | +holds or |
| 101 | +$$a^{2^r d} \equiv -1 \bmod n$$ |
| 102 | +holds for some $0 \le r \le s - 1$. |
| 103 | + |
| 104 | +If we found a base $a$ which doesn't satisfy any of the above equalities, than we found a *witness* for the compositeness of $n$. |
| 105 | +In this case we have proven that $n$ is not a prime number. |
| 106 | + |
| 107 | +Similar to the Fermat test, it is also possible that the set of equations is satisfied for a composite number. |
| 108 | +In that case the base $a$ is called a *strong liar*. |
| 109 | +If a base $a$ satisfies the equations (one of them), $n$ is only *strong probable prime*. |
| 110 | +However, there are no numbers like the Carmichael numbers, where all non-trivial bases lie. |
| 111 | +In fact it is possible to show, that at most $\frac{1}{4}$ of the bases can be strong liars. |
| 112 | +If $n$ is composite, we have a probability of $\ge 75\%$ that a random base will tell us that it is composite. |
| 113 | +By doing multiple iterations, choosing different random bases, we can tell with very high probability if the number is truly prime or if it is composite. |
| 114 | + |
| 115 | +Here is an implementation for 64 bit integer. |
| 116 | + |
| 117 | +```cpp |
| 118 | +using u64 = uint64_t; |
| 119 | +using u128 = __uint128_t; |
| 120 | + |
| 121 | +u64 binpower(u64 base, u64 e, u64 mod) { |
| 122 | + u64 result = 1; |
| 123 | + base %= mod; |
| 124 | + while (e) { |
| 125 | + if (e & 1) |
| 126 | + result = (u128)result * base % mod; |
| 127 | + base = (u128)base * base % mod; |
| 128 | + e >>= 1; |
| 129 | + } |
| 130 | + return result; |
| 131 | +} |
| 132 | + |
| 133 | +bool trial_composite(u64 n, u64 a, u64 d, int s) { |
| 134 | + u64 x = binpower(a, d, n); |
| 135 | + if (x == 1 || x == n - 1) |
| 136 | + return true; |
| 137 | + for (int r = 1; r < s; r++) { |
| 138 | + x = (u128)x * x % n; |
| 139 | + if (x == n - 1) |
| 140 | + return true; |
| 141 | + } |
| 142 | + return false; |
| 143 | +}; |
| 144 | + |
| 145 | +bool MillerRabin(u64 n) { |
| 146 | + if (n < 4) |
| 147 | + return n == 2 || n == 3; |
| 148 | + |
| 149 | + int s = 0; |
| 150 | + u64 d = n - 1; |
| 151 | + while ((d & 1) == 0) { |
| 152 | + d >>= 1; |
| 153 | + s++; |
| 154 | + } |
| 155 | + |
| 156 | + for (int i = 0; i < iter; i++) { |
| 157 | + int a = 2 + rand() % (n - 3); |
| 158 | + if (trial_composite(n, a, d, s)) |
| 159 | + return false; |
| 160 | + } |
| 161 | + return true; |
| 162 | +} |
| 163 | +``` |
| 164 | +
|
| 165 | +Before the Miller-Rabin test you can test additionally if one of the first few prime numbers is a divisor. |
| 166 | +This can speed up the test by a lot, since most composite numbers have very small prime divisors. |
| 167 | +E.g. $88\%$ of all numbers have a prime factors smaller than $100$. |
| 168 | +
|
| 169 | +### Deterministic version |
| 170 | +
|
| 171 | +Miller showed that it is possible to make the algorithm deterministic by only checking all bases $\le O((\ln n)^2)$. |
| 172 | +Bach later gave a concrete bound, it is only necessary to test all bases $a \le 2 \ln(n)^2$. |
| 173 | +
|
| 174 | +This is still a pretty large number of bases. |
| 175 | +So people have invested quite a lot of computation power into finding lower bounds. |
| 176 | +It turns out, for testing a 32 bit integer it is only necessary to check the first 4 prime bases: 2, 3, 5 and 7. |
| 177 | +The smallest composite number that fails this test is $3.215.031.751 = 151 \cdot 751 \cdot 28351$. |
| 178 | +And for testing 64 bit integer it is enough to check the first 12 prime bases: 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, and 37. |
| 179 | +
|
| 180 | +This results in the following deterministic implementation: |
| 181 | +
|
| 182 | +```cpp |
| 183 | +bool MillerRabin(u64 n, int iter) { |
| 184 | + if (n < 2) |
| 185 | + return false; |
| 186 | +
|
| 187 | + int r = 0; |
| 188 | + u64 d = n - 1; |
| 189 | + while ((d & 1) == 0) { |
| 190 | + d >>= 1; |
| 191 | + r++; |
| 192 | + } |
| 193 | +
|
| 194 | + for (int a : {2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37}) { |
| 195 | + if (n == a) |
| 196 | + return true; |
| 197 | + if (trial_composite(n, a, d, r)) |
| 198 | + return false; |
| 199 | + } |
| 200 | + return true; |
| 201 | +} |
| 202 | +``` |
| 203 | + |
| 204 | +It's also possible to do the check with only 7 bases: 2, 325, 9375, 28178, 450775, 9780504 and 1795265022. |
| 205 | +However, since these numbers (except 2) are not prime, you need to check additionally if the number you are checking is equal to any prime divisor of those bases: 2, 3, 5, 13, 19, 73, 193, 407521, 299210837. |
| 206 | + |
| 207 | +## Practice Problems |
| 208 | + |
| 209 | +- [SPOJ - Prime or Not](https://www.spoj.com/problems/PON/) |
0 commit comments