O que é Criptografia Homomórfica?
A criptografia homomórfica é um tipo especial de esquema criptográfico que permite realizar operações matemáticas diretamente sobre dados criptografados, sem precisar descriptografá-los primeiro. A propriedade fundamental é que uma operação realizada sobre o texto cifrado produz um resultado que, quando descriptografado, é equivalente à operação realizada sobre o texto plano.
Formalmente, um esquema criptográfico (E, D) é homomórfico em relação a uma operação ⊕ se: D(E(m₁) ⊗ E(m₂)) = m₁ ⊕ m₂, onde E é a função de criptografia, D é a função de descriptografia, ⊗ é uma operação sobre textos cifrados e ⊕ é uma operação sobre textos planos. Essa propriedade revoluciona a forma como pensamos sobre privacidade de dados, pois permite que terceiros processem informações sensíveis sem nunca ter acesso ao conteúdo real. Este é o fundamento da computação segura moderna.
Propriedades e Classificações
Existem três categorias principais de criptografia homomórfica: parcialmente homomórfica, parcialmente homomórfica múltipla e completamente homomórfica. Um esquema parcialmente homomórfico suporta apenas uma operação (adição ou multiplicação), enquanto um completamente homomórfico suporta ambas sem limitação de profundidade. A criptografia completamente homomórfica (FHE) é a mais poderosa, mas também computacionalmente intensiva, tornando sua adoção em produção ainda limitada.
A importância prática está em cenários como processamento em nuvem privada, análise de dados genéticos confidenciais, computações financeiras seguras e aprendizado de máquina sobre dados sensíveis. Quando um usuário envia dados cifrados para uma nuvem processar sem compartilhar a chave, o servidor nunca conhece o conteúdo, apenas realiza operações criptografadas que produzem resultados corretos após descriptografia.
Fundamentos Matemáticos e Esquemas Práticos
RSA Homomórfico Multiplicativo
O RSA é um exemplo clássico de criptografia parcialmente homomórfica com suporte à multiplicação. Se você criptografa duas mensagens m₁ e m₂ com o mesmo módulo n e expoente público e, então E(m₁) × E(m₂) mod n = E(m₁ × m₂). Essa propriedade multiplicativa torna o RSA útil para delegação de cálculos multiplicativos seguros.
Aqui está uma implementação funcional em Python que demonstra essa propriedade:
from Crypto.PublicKey import RSA
from Crypto.Cipher import PKCS1_v1_5
import random
class RSAHomomorphic:
def __init__(self, key_size=2048):
self.key = RSA.generate(key_size)
self.public_key = self.key.publickey()
self.n = self.key.n
self.e = self.key.e
self.d = self.key.d
def encrypt(self, message):
"""Criptografa um número inteiro"""
if isinstance(message, str):
message = int(message.encode().hex(), 16)
return pow(message, self.e, self.n)
def decrypt(self, ciphertext):
"""Descriptografa um número inteiro"""
plaintext = pow(ciphertext, self.d, self.n)
return plaintext
def multiply_encrypted(self, encrypted_m1, encrypted_m2):
"""Multiplica dois textos cifrados diretamente"""
return (encrypted_m1 * encrypted_m2) % self.n
# Uso prático
rsa_homo = RSAHomomorphic()
m1, m2 = 12, 5
# Criptografa mensagens individuais
c1 = rsa_homo.encrypt(m1)
c2 = rsa_homo.encrypt(m2)
# Multiplica os cifrados
c_product = rsa_homo.multiply_encrypted(c1, c2)
# Descriptografa resultado
result = rsa_homo.decrypt(c_product)
print(f"m1 = {m1}, m2 = {m2}")
print(f"E(m1) × E(m2) descriptografado = {result}")
print(f"m1 × m2 esperado = {m1 * m2}")
print(f"Propriedade homomórfica confirmada: {result == m1 * m2}")
Paillier: Homomorfismo Aditivo
O esquema Paillier é parcialmente homomórfico para adição. Sua elegância reside em permitir que E(m₁) × E(m₂) mod n² = E(m₁ + m₂). Essa propriedade é especialmente valiosa em votação eletrônica segura, leilões privados e agregação de dados confidenciais.
import random
from math import gcd
class PaillierCrypto:
def __init__(self, bit_length=512):
# Gera dois números primos grandes
self.p = self._generate_prime(bit_length)
self.q = self._generate_prime(bit_length)
self.n = self.p * self.q
self.n_sq = self.n * self.n
self.lambda = self._lcm(self.p - 1, self.q - 1)
# Encontra g tal que mdc(L(g^lambda mod n²), n) = 1
self.g = self._find_generator()
def _generate_prime(self, bits):
"""Gera um número primo aleatório com número de bits especificado"""
while True:
num = random.getrandbits(bits)
if self._is_prime(num):
return num
def _is_prime(self, n, k=5):
"""Teste de Miller-Rabin para primalidade"""
if n < 2:
return False
if n == 2 or n == 3:
return True
if n % 2 == 0:
return False
r, d = 0, n - 1
while d % 2 == 0:
r += 1
d //= 2
for _ in range(k):
a = random.randrange(2, n - 1)
x = pow(a, d, n)
if x == 1 or x == n - 1:
continue
for _ in range(r - 1):
x = pow(x, 2, n)
if x == n - 1:
break
else:
return False
return True
def _lcm(self, a, b):
"""Calcula o mínimo múltiplo comum"""
return abs(a * b) // gcd(a, b)
def _find_generator(self):
"""Encontra um gerador válido g"""
while True:
g = random.randint(2, self.n_sq - 1)
if gcd(g, self.n_sq) == 1:
return g
def encrypt(self, message):
"""Criptografa uma mensagem"""
r = random.randint(1, self.n - 1)
c = (pow(self.g, message, self.n_sq) * pow(r, self.n, self.n_sq)) % self.n_sq
return c
def decrypt(self, ciphertext):
"""Descriptografa uma mensagem"""
# Simplificado: em produção seria necessário implementar L propriamente
# Para este exemplo, usamos uma abordagem educacional
lambda_inv = pow(self.lambda, -1, self.n)
c_lambda = pow(ciphertext, self.lambda, self.n_sq)
return (self._L(c_lambda) * lambda_inv) % self.n
def _L(self, u):
"""Função L(u) = (u - 1) / n"""
return (u - 1) // self.n
def add_encrypted(self, c1, c2):
"""Soma dois textos cifrados: E(m1) × E(m2) = E(m1 + m2)"""
return (c1 * c2) % self.n_sq
# Demonstração
paillier = PaillierCrypto(bit_length=256)
m1, m2 = 100, 50
c1 = paillier.encrypt(m1)
c2 = paillier.encrypt(m2)
# Operação homomórfica: adição sobre cifrados
c_sum = paillier.add_encrypted(c1, c2)
result = paillier.decrypt(c_sum)
print(f"Mensagem 1: {m1}")
print(f"Mensagem 2: {m2}")
print(f"E(m1) + E(m2) descriptografado: {result}")
print(f"Soma esperada: {m1 + m2}")
print(f"Propriedade homomórfica confirmada: {result == m1 + m2}")
Criptografia Completamente Homomórfica (FHE)
Conceitos e Desafios
A criptografia completamente homomórfica permite computação arbitrária sobre dados criptografados. Gentry provou em 2009 que FHE é teoricamente possível através de esquemas baseados em redes (lattice-based cryptography), especificamente usando o problema Learning With Errors (LWE). No entanto, a complexidade computacional é significativa: uma operação simples pode levar horas em hardware padrão.
O principal desafio técnico é o "crescimento do ruído". Cada operação adiciona ruído ao ciphertext, e quando esse ruído ultrapassa um limite, a descriptografia falha. A solução é o "bootstrapping", uma operação custosa que reduz o ruído avaliando a própria função de descriptografia de forma homomórfica. Esquemas modernos como BGV (Brakerski-Gentry-Vaikuntanathan) e CKKS (Cheon-Kim-Kim-Song) implementam variações sofisticadas dessa ideia.
Implementação com a Biblioteca SEAL
Microsoft SEAL é uma biblioteca C++ que implementa FHE prático com o esquema CKKS. Aqui está um exemplo funcional em C++ que você pode compilar e testar:
#include <iostream>
#include <vector>
#include "seal/seal.h"
using namespace std;
using namespace seal;
int main() {
// Configura parâmetros de segurança
EncryptionParameters parms(scheme_type::ckks);
size_t poly_modulus_degree = 8192;
parms.set_poly_modulus_degree(poly_modulus_degree);
parms.set_coeff_modulus(CoeffModulus::Create(poly_modulus_degree, {60, 40, 40, 60}));
// Define escala para números de ponto flutuante
double scale = pow(2.0, 40);
// Gera contexto e chaves
auto context = SEALContext::Create(parms);
KeyGenerator keygen(context);
auto secret_key = keygen.secret_key();
PublicKey public_key;
keygen.create_public_key(public_key);
// Cria encriptador, avaliador e descriptador
Encryptor encryptor(context, public_key);
Evaluator evaluator(context);
Decryptor decryptor(context, secret_key);
// Cria codificador para números reais
CKKSEncoder encoder(context);
// Dados: duas listas de números
vector<double> values1{1.5, 2.5, 3.5, 4.5};
vector<double> values2{2.0, 3.0, 4.0, 5.0};
// Criptografa os valores
Plaintext plain1, plain2;
encoder.encode(values1, scale, plain1);
encoder.encode(values2, scale, plain2);
Ciphertext encrypted1, encrypted2;
encryptor.encrypt(plain1, encrypted1);
encryptor.encrypt(plain2, encrypted2);
// Realiza operações diretamente sobre cifrados
Ciphertext encrypted_result;
evaluator.add(encrypted1, encrypted2, encrypted_result);
// Descriptografa e decodifica o resultado
Plaintext decrypted_result;
decryptor.decrypt(encrypted_result, decrypted_result);
vector<double> result;
encoder.decode(decrypted_result, result);
// Exibe resultados
cout << "Valores originais 1: ";
for (auto v : values1) cout << v << " ";
cout << "\nValores originais 2: ";
for (auto v : values2) cout << v << " ";
cout << "\nResultado (E(v1) + E(v2)): ";
for (auto v : result) cout << v << " ";
cout << "\n";
return 0;
}
Para compilar este código com SEAL instalado:
g++ -o fhe_example fhe_example.cpp -I/path/to/seal/include -L/path/to/seal/lib -lseal-3.7
./fhe_example
Aplicações Práticas e Futuro da Computação Segura
Casos de Uso Contemporâneos
Computação homomórfica está transformando industrias sensíveis a privacidade. Em healthcare, hospitais podem enviar dados de pacientes criptografados para análise em nuvem sem expor informações pessoais. Pesquisas genômicas beneficiam enormemente: pesquisadores processam DNA de milhões de pessoas identificando padrões sem nunca acessar dados brutos. No setor financeiro, instituições compartilham modelos de risco creditício sem revelar portfolios individuais. Governos usam computação segura em censos e estatísticas onde confidencialidade é crítica.
Uma aplicação emergente é machine learning seguro (Secure ML). Um provedor de dados pode treinar modelos sobre informações criptografadas, permitindo que empresas de IA desenvolvam soluções de IA sem conhecer dados de treinamento. Exemplos incluem diagnósticos médicos com dados de imagem protegidos e recomendações financeiras sobre históricos de transações cifrados. A legislação reguladora como GDPR e HIPAA está impulsionando ainda mais essa demanda.
Tendências e Perspectivas Futuras
O futuro próximo envolve otimizações significativas em velocidade através de hardware especializado. Processadores FPGA e ASIC dedicados aos esquemas FHE podem reduzir latência de horas para segundos. Bibliotecas como OpenFHE (sucessora do SEAL), Lattigo (em Go) e PALISADE estão evoluindo rapidamente com suportes a operações mais complexas.
Híbridos práticos já existem: usar criptografia parcialmente homomórfica onde possível (Paillier para análises simples) e FHE apenas quando necessário computa. Padronização está em andamento através do NIST Post-Quantum Cryptography Project, garantindo que esquemas homomórficos sejam seguros mesmo contra computadores quânticos futuros. A convergência de computação em nuvem confiável, edge computing seguro e IoT privado posicionará criptografia homomórfica como pilar da infraestrutura digital da próxima década.
# Exemplo prático: agregação privada de salários (Paillier)
# Uma empresa quer calcular salário médio sem revelar individuais
class PrivatePayrollAggregator:
def __init__(self):
self.crypto = PaillierCrypto(bit_length=512)
self.encrypted_sum = None
def add_encrypted_salary(self, salary):
"""Um funcionário adiciona salário criptografado ao agregador"""
encrypted = self.crypto.encrypt(salary)
if self.encrypted_sum is None:
self.encrypted_sum = encrypted
else:
self.encrypted_sum = self.crypto.add_encrypted(
self.encrypted_sum, encrypted
)
def get_average_decrypted(self, num_employees):
"""Apenas administrador pode descriptografar a soma e calcular média"""
total = self.crypto.decrypt(self.encrypted_sum)
return total / num_employees
# Uso
aggregator = PrivatePayrollAggregator()
salaries = [3000, 3500, 4200, 3800, 4500]
for salary in salaries:
aggregator.add_encrypted_salary(salary)
average = aggregator.get_average_decrypted(len(salaries))
print(f"Salário médio (calculado sobre cifrados): ${average:.2f}")
print(f"Salário médio esperado: ${sum(salaries)/len(salaries):.2f}")
Conclusão
Aprendemos que criptografia homomórfica transforma o paradigma de privacidade em computação na nuvem: permitem-se operações sobre dados sem nunca descriptografá-los. A progressão de esquemas parcialmente homomórficos (RSA multiplicativo, Paillier aditivo) para completamente homomórficos (CKKS, BGV) reflete o avanço tecnológico, embora ainda com custos computacionais elevados.
O segundo aprendizado crucial é que essa tecnologia não é futurística — já está em produção em contextos reais: análise de dados genômicos sensíveis, votação eletrônica auditável e processamento de informações financeiras reguladas. A combinação de criptografia homomórfica com infraestrutura moderna de nuvem cria o fundamento para confiança sem transparência invasiva.
Finalmente, a trajetória técnica mostra que otimizações acelerarão adoção massiva. Hardware especializado, padronização NIST, e segurança pós-quântica integrada farão dessa tecnologia invisível mas omnipresente na próxima década de computação segura.
Referências
- Microsoft SEAL - Homomorphic Encryption Library
- OpenFHE: Open-Source Fully Homomorphic Encryption Library
- NIST Post-Quantum Cryptography Project
- Gentry, C. (2009). "Fully Homomorphic Encryption over the Integers". IACR Cryptology ePrint Archive
- Lattigo: Lattice-based Cryptography in Go