Modular Arithmetic Cheatsheet
GCD(Greatest Common Divisor)
Euclidean Algorithm is based on the principle that the greatest common divisor of two numbers doesn't change if the larger number is replaced by its difference with the smaller one.
def gcd(a, b):
while b != 0:
t = b
b = a % b
a = t
return a
Community Implementation (gmpy2
)
from gmpy2 import *
print(gcd(15, 35))
5
Extended GCD
The Extended Euclidean Algorithm provide a efficient way to find integers \(u, v\) such that:
\begin{align} a \cdot u + b \cdot v &= gcd(a, b) \\ &= gcd(b, a \bmod b) \tag{Euclidean algorithm apply} \\ &= b \cdot u_1 + (a \bmod b) \cdot v_1 \tag{Extened GCD apply} \\ &= b \cdot u_1 + (a - (a \div b) \cdot b) \cdot v_1 \\ &= a \cdot v_1 + b \cdot (u_1 - (a \div b) \cdot v_1) \\ &\Downarrow \\ u &= v_1 \\ v &= u_1 - (a \div b) \cdot v_1 \\ \end{align}def ext_gcd(a, b):
if b == 0:
return 1, 0
else:
u, v = ext_gcd(b, a % b)
return v, u - (a // b) * v
Community Implementation (gmpy2
)
from gmpy2 import *
print(gcdext(15, 35)) # return a 3-element tuple (g, u, v) such that g = gcd(a, b) = a*u + b*v
(mpz(5), mpz(-2), mpz(1))
Fermat's Little Theorem
Fermat's Little Theore states that if \(p\) is a prime that:
\begin{align} & \forall a \in \mathbb{Z}, (a^p - a) \bmod p = 0 \\ & \text{if } a \text{ is not divisible by } p, \text{then:} \\ & a^{p-1} \equiv 1 \pmod p \\ & \text{else: } \\ & a^{p-1} \equiv 0 \pmod p \end{align}TODO Application
Quadratic Residue
The definition like this: let's work on modulo \(p\), and we take two integers \(x, a\), which satisfied that \(x^2 \equiv a \pmod p\) then \(x\) is square root of \(a\)
Discriminant
we can see that \(\forall a \in \mathbb{F}_p\) not every element has a square root. So we say that an integer \(a\) is Quadratic Residue if there exist an \(x\) that \(x^2 \equiv a \pmod p\) else not.
Property
- Quadratic Residue * Quadratic Residue = Quadratic Residue
- Quadratic Residue * Quadratic Non-Residue = Quadratic Non-Residue
- Quadratic Non-Residue * Quadratic Non-Residue = Quadratic Residue
Just replace Quadratic Residue
as 1
and Quadratic Non-Residue
as -1
will help remember it.
Legendre Symbol
Legendre_symbol gives a efficient way to determine whether an integer is Quadratic Residue
modulo an
odd prime \(p\)
\(a/p = a^{p-1/2} \bmod p\) :
1
if \(a\) is Quadratic Residue and \(a \not\equiv 0 \pmod p\)-1
if \(a\) is Quadratic Non-Residue0
if \(a \equiv 0 \pmod p\)
Tonelli-Shanks Algorithm
As now, we have efficient way to determine whether an integer is Quadratic Residue
or not. but how
we find the square root fastly too? for All prime divisor, the answer is Tonelli-Shanks algorithm.
sympy
implementation
from sympy import sqrt_mod
a = 11
p = 43
print(sqrt_mod(a, p))
21
Chinese Remainder Theorem
The CRT
provide an unique solution to a set of linear congruence's equations if their moduli are coprime.
This means that given a set of arbitrary integers \(a_i\) and pairwise coprime integers \(n_i\) with following equations hold:
\begin{align} x &\equiv a_1 \pmod {n_1} \\ x &\equiv a_2 \pmod {n_2} \\ x &\equiv a_3 \pmod {n_3} \\ &\dots \\ x &\equiv a_n \pmod {n_n} \\ \end{align}from functools import reduce
moduli = [5, 11, 17]
remainder = [2, 3, 5]
N = reduce(lambda x, y: x * y, moduli)
m = [N // m for m in moduli]
# when exponent is negative, this function use extend Euclidean algorithm to find the inverse modular
mi = [pow(m[i], -1, moduli[i]) for i in range(len(moduli))]
x = sum(a * mi[i] * m[i] for i, a in enumerate(remainder))
print(f"solution: {x % N}")