Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit f668d9c

Browse files
authored
Add article about primality check (#412)
1 parent 12f8e4b commit f668d9c

File tree

3 files changed

+214
-1
lines changed

3 files changed

+214
-1
lines changed

src/algebra/montgomery_multiplication.md

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
<!--?title Montgomery Multiplication -->
22
# Montgomery Multiplication
33

4-
Many algorithms in number theory, like prime testing or factorization, and in cryptography, like RSA, require lots of operations modulo a large number.
4+
Many algorithms in number theory, like [prime testing](./algebra/primality_tests.html) or factorization, and in cryptography, like RSA, require lots of operations modulo a large number.
5+
56
A multiplications like $x y \bmod{n}$ is quite slow to compute with the typical algorithms, since it requires a division to know how many times $n$ has to be subtracted from the product.
67
And division is a really expensive operation, especially with big numbers.
78

@@ -33,6 +34,7 @@ You can add two elements ($x \cdot r + y \cdot r \equiv (x + y) \cdot r \bmod n$
3334
All with the usual algorithms.
3435

3536
However this is not the case for multiplication.
37+
3638
We expect the result to be:
3739
$$\bar{x} * \bar{y} = \overline{x \cdot y} = (x \cdot y) \cdot r \bmod n.$$
3840
But the normal multiplication will give us:
@@ -168,6 +170,7 @@ There are faster ways.
168170
169171
You can notice the following relation:
170172
$$\bar{x} := x \cdot r \bmod n = x \cdot r^2 / r = x * r^2$$
173+
171174
Transforming a number into the space is just a multiplication inside the space of the number with $r^2$.
172175
Therefore we can precompute $r^2 \bmod n$ and just perform a multiplication instead of shifting the number 128 times.
173176

src/algebra/primality_tests.md

Lines changed: 209 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,209 @@
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/)

src/index.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ and adding new articles to the collection.*
2020
- **Prime numbers**
2121
- [Sieve of Eratosthenes](./algebra/sieve-of-eratosthenes.html)
2222
- [Sieve of Eratosthenes With Linear Time Complexity](./algebra/prime-sieve-linear.html)
23+
- [Primality tests](./algebra/primality_tests.html)
2324
- **Number-theoretic functions**
2425
- [Euler's totient function](./algebra/phi-function.html)
2526
- [Number of divisors / sum of divisors](./algebra/divisors.html)

0 commit comments

Comments
 (0)