from Crypto.Util.number import getPrime, isPrime, sieve_base, GCD
import random
def jacobi_symbol(a, n):
if a ==0:
return 0
if a ==1:
return 1
#write a = 2^e *s where a1 is odd
e =0
a1 = a
while a1 & 1==0: #while a1 is even
a1>>=1
e+=1
#if e is even set s = 1
if e & 1 == 0:
s = 1
elif n % 8 == 7 or n % 8 == 1:
s = 1
elif n % 8 == 3 or n % 8 == 5:
s = -1
if n % 4 == 3 and a1 % 4 == 3:
s = -s
n1 = n % a1
if a1 ==1:
return s
else:
return s * jacobi_symbol(n1, a1)
First, suppose $p$ is prime, and consider the modular equation $x^2 \equiv 1 \pmod{p}$.
What are the solutions to this equation?
Since $p$ is prime, $p$ has to divide either $x-1$ or $x+1$ => $x \equiv \pm 1 \pmod{p}$
Let
Then one of the following two conditions is true:
Miller rabin test uses the contrapositive of this
Remarks:
def miller_rabin_test(n, k):
'''
Arguments:
n: int -- number to be tested
k: int -- number of trials
Return: `Composite` or `Probably prime`'''
#check parity
if not n & 1:
return 'Composite'
r = 0
s = n-1
#write n-1 = 2^r*s
while not s & 1:
s = s>>1
r+=1
assert(pow(2, r)* s == n-1)
for i in range(k):
a = random.randint(2, n-2)
x = pow(a, s, n)
if x == 1 or x == n-1:
continue #search for another witness
for _ in range(r):
x = pow(x, 2, n)
if x == n-1:
break
else:
#if it doesnt break, neither condition is satisfied => this executes => we found a composite
return "Composite"
return "Probably prime"
print(miller_rabin_test(2403, 100))
p = getPrime(512)
print(miller_rabin_test(p, 100))
print(miller_rabin_test(561, 100))
Composite Probably prime Composite
def miller_rabin_test_fixed(n, a_list):
'''returns Composite or Probably prime'''
#check parity
if not n & 1:
return 'Composite'
r = 0
s = n-1
#write n-1 = 2^r*s
while not s & 1:
s = s>>1
r+=1
assert(pow(2, r)* s == n-1)
for a in a_list:
x = pow(a, s, n)
if x == 1 or x == n-1:
continue #search for another witness
for _ in range(r):
x = pow(x, 2, n)
if x == n-1:
break
else:
#if it doesnt break, neither condition is satisfied => this executes => we found a composite
return "Composite"
return "Probably prime"
Let $n = p_1p_2..p_h$ Define:
If $k_i, m_i \in \mathbb{Z} \ \forall 2 \leq i \leq h => n$ is a Carmichael number
(The law of quadratic reciprocity) If $p$ and $q$ are distinct odd primes, we have $\left(\dfrac{q}{p}\right)\left(\dfrac{p}{q}\right)=(-1)^{\frac{p-1}{2} \frac{q-1}{2}}$
Additional proprieties:
Starting with some $p_1$ we can determine the other $p_i$ of the form $p_i = k_i(p_1 - 1)+ 1$ for all $1 \leq i \leq h => $ $$k_i(p_1 - 1) + 1 \bmod 4a \in S_a \ \forall 1\leq i \leq h$$
If the coeff $k_i$ are coprime to $a$ then the condition becomes:$$p_1 \bmod 4a∈⋂^h_{i=1}k^{−1}_i(S_a+k_i−1)$$ where $k^{−1}_i(S_a+k_i−1)$ is the set $\{k^{−1}_i(s+k_i−1) | s \in S_a\}$ => We have a set of conditions for the values of $p_1$ for each $a$
So for each value of $a$ we have a few candidates in our subset from $S_a$. We select one of these candidates $z_a$ for each $a \in A$ and using the CRT we can combine these conditions into a single one $p_1 \bmod \text{lcm}(4, a_1, .. a_h)$
The $k_i$ are a set of primes usually smaller than $\max(A)$ such that $k_i^{-1}$ exists mod $4a$
Algorithm:
(Korselt's Criterion): A composite integer $n$ is a Carmichael number if and only if the following two conditions are satisfied:
Erdos's idea to construct pseudoprimes
Then C is a Carmichael number because C satisfies the Korselt's criterion
Note: One can hope to find such sets $$ if $R$ contains more than about $\log_2(M)$ primes
Additionally, a Carmichael number $C$ is a strong pseudoprime for a base $a$ if the order of $a$ modulo $r$ is divisible by the same power of 2 for all primes factors $r$ of $C$.
If all prime factors $r$ are congruent 3 modulo 4 then this condition is satisfied when $a$ is a quadratic residue modulo either all prime factors $r$ or none at all, because in that case the order of $a$ modulor is either even or odd for all $r$
Algorithm