Módulo 6 · Teoria dos números e criptografia
Aritmética modular
Aula 6.1 · cerca de 18 minutos
a ≡ b (mod n) significa que n divide a − b: os dois deixam o mesmo resto. É a aritmética do relógio e dos inteiros de tamanho fixo. Um uint32 faz toda a aritmética mod 2³².
(a + b) mod n = ((a mod n) + (b mod n)) mod n (a · b) mod n = ((a mod n) · (b mod n)) mod n
Essas propriedades permitem reduzir a cada passo e manter os números pequenos. É assim que hashes polinomiais (Rabin–Karp) e geradores congruenciais funcionam.
Exponenciação rápida
Calcular aᵉ mod n multiplicando e vezes é inviável para expoentes de 2048 bits. Elevando ao quadrado repetidamente, bastam O(log e) multiplicações:
def pow_mod(a, e, n):
r = 1
a %= n
while e:
if e & 1:
r = r * a % n
a = a * a % n
e >>= 1
return r
assert pow_mod(3, 200, 1_000_007) == pow(3, 200, 1_000_007)Dica: Cuidado: em muitas linguagens,
% com número negativo dá resultado negativo (-7 % 3 == -1 em C, Java e JS). Em Python dá 2. Para um resto sempre positivo: ((a % n) + n) % n.Exercício 1
Qual é o último dígito de 7²⁰²⁵?
Exercício 2
Por que um hash de string costuma usar h = (h·31 + c) mod M, com M primo?