← Índice de Demos
FHE em Ação
Demo Interativa · Skincare sob Cifra
Demonstração Factual

O Espelho que Não Vê.

Acompanhe, em nove passos, como uma consumidora pode receber recomendação de skincare totalmente personalizada — sem que a marca jamais veja sua selfie, seu perfil de pele, ou os scores resultantes.

O Cenário

Uma consumidora gera 8 features de pele localmente a partir de uma selfie. Cifra no próprio celular. Envia ao servidor.

O Servidor

Computa scores de afinidade para 5 produtos do catálogo aplicando um modelo linear — sobre o ciphertext, sem decifrar.

A Garantia

Em nenhum momento o servidor vê o perfil em claro. A garantia é matemática (RLWE), não política.

Tudo o que você verá nesta demo é real Os números, tempos, tamanhos e scores foram capturados de uma execução verdadeira do código demo_fhe_skincare/main.go usando a biblioteca Lattigo v6 com esquema CKKS. Nada é simulado.
Passo 01 · Setup

Definir os parâmetros.

CKKS opera sobre vetores de números reais com aritmética aproximada — o esquema padrão para machine learning sob FHE. Os parâmetros definem segurança, profundidade de cálculo e custo.

Parâmetros Escolhidos

// Lattigo v6 — CKKS
params := ckks.NewParametersFromLiteral({
  LogN: 14,  // N = 16384
  LogQ: [55, 45, 45, 45],
  LogP: [61],
  LogScale: 45,
})

O Que Isso Significa

16 384Grau do anel N
8 192Slots por ciphertext
~45 bitPrecisão por op.
~128 bitSegurança RLWE

Base matemática: RLWE em Zq[x]/(xN+1) — o mesmo problema da criptografia pós-quântica padronizada pelo NIST (ML-KEM, ML-DSA).

Passo 02 · Cliente

Gerar o par de chaves.

A chave privada nasce no celular da consumidora e nunca sai dali. A chave pública é o que viaja para o servidor da marca.

Fluxo de Chaves

📱
Celular
sk (privada)
só pk viaja
Servidor
pk + rlk

A chave de relinearização rlk também vai para o servidor — ela permite multiplicações sob cifra mas não revela sk.

O Que Foi Gerado

23 msTempo total
6.8 KBChave pública
43.9 KBRelinearização
128 bitSegurança
// no celular da consumidora
sk := kgen.GenSecretKey()
pk := kgen.GenPublicKey(sk)
rlk := kgen.GenRelinKey(sk)
Passo 03 · Cliente

Gerar o perfil e cifrar.

Em produção, as 8 features sairiam de um modelo de visão rodando localmente sobre a selfie. Aqui simulamos diretamente o vetor — e cifragem acontece antes de qualquer byte sair do celular.

Perfil de Pele · Em Claro (só a consumidora vê)

oleosidade0.78
hidratação0.32
sensibilidade0.65
manchas0.42
rugas0.18
poros0.71
textura0.55
vermelhidão0.48

Cifragem CKKS

8.3 msTempo de cifragem
64 BPlaintext (8 floats)
1.00 MBCiphertext
~16 000×Overhead

Esse overhead é o preço da privacidade matemática. Em troca, o servidor consegue computar sobre o ciphertext sem nunca conhecer o conteúdo.

Passo 04 · Trânsito

O que o servidor recebe.

Estes são os bytes exatos que saem do celular para o servidor da marca. Para qualquer observador sem a chave sk, é ruído indistinguível.

Amostra Real do Ciphertext (32 primeiros bytes)

01 7b 22 50 6c 61 69 6e
74 65 78 74 4d 65 74 61
44 61 74 61 22 3a 7b 22
53 63 61 6c 65 22 3a 7b
...

O ciphertext completo tem ~1 MB de bytes pseudoaleatórios. Sem a chave secreta, recuperar qualquer feature individual exigiria resolver Ring-LWE em dimensão 16 384 — ~2128 operações.

O Que Trafega

6.8 KBpk · uma vez por sessão
43.9 KBrlk · uma vez por sessão
1.00 MBct_features · por consulta
Passo 05 · Servidor

Calcular scores sob cifra.

Para cada um dos 5 produtos do catálogo, o servidor computa score = bias + Σ(pesoi × featurei) — inteiramente sobre o ciphertext, sem nunca decifrar.

O Algoritmo (por produto)

// servidor: pesos em CLARO, perfil em CIFRA
ptW := encoder.Encode(produto.Pesos)
// (1) multiplicação element-wise sob cifra
ctMult := evaluator.Mul(ctFeatures, ptW)
evaluator.Rescale(ctMult)
// (2) somar os 8 slots → produto interno
ctSum := evaluator.InnerSum(ctMult, 1, 8)
// (3) somar viés escalar
evaluator.Add(ctSum, produto.Bias)

Tudo acontece sobre ct — o servidor nunca tem acesso aos números reais.

Performance Real Medida

131 msTotal · 5 produtos
26 msPor produto
5Ciphertexts gerados
0Bytes decifrados
O que o servidor sabe agora 5 ciphertexts contendo os scores da consumidora. Não tem ideia de quanto valem. Não sabe se ela tem oleosidade alta, manchas, rugas, sensibilidade. Apenas cumpriu sua função.
Passo 06 · Cliente

Decifrar e recomendar.

Os 5 ciphertexts viajam de volta para o celular. Apenas lá, com a chave secreta sk, eles se tornam números legíveis. A consumidora vê, finalmente, sua recomendação.

Ranking de Recomendação

  1. iLoção Calmante Sensitive+1.4470
  2. iiTônico Matificante Pureté+1.2980
  3. iiiClareador Lumière Spot+0.7250
  4. ivCreme Anti-Idade Absolu+0.6350
  5. vSérum Hidratante Quotidien+0.2990

Por que Faz Sentido

A consumidora tem sensibilidade alta (0.65) e vermelhidão moderada (0.48) → o algoritmo escolheu corretamente a Loção Calmante.

Tem também oleosidade alta (0.78) e poros visíveis (0.71) → o Tônico Matificante aparece em segundo.

O ponto crucial O modelo funcionou exatamente como funcionaria em claro. Mas o servidor nunca viu nenhum dos 8 valores.
Passo 07 · Prova

Validação matemática.

Para provar que o cálculo cifrado é equivalente ao cálculo em claro, recomputamos os scores diretamente em plaintext (apenas para conferência) e comparamos.

FHE vs Plaintext

ProdutoFHEClaroErro
Loção Calmante Sensitive+1.447000+1.4470002.3e-10
Tônico Matificante Pureté+1.298000+1.2980002.7e-10
Clareador Lumière Spot+0.725000+0.7250002.6e-10
Creme Anti-Idade Absolu+0.635000+0.6350001.3e-10
Sérum Hidratante Quotidien+0.299000+0.2990004.0e-10

Resultado

3.96 × 10⁻¹⁰Erro máximo absoluto

CKKS é aproximado por design — o erro vem do ruído controlado inserido durante a cifragem. Para scoring de recomendação, precisão de 9 casas decimais é mais que suficiente.

Para contagens exatas (banco de dados, scoring de fraude), usaríamos BFV/BGV que não tem nenhum erro.

Passo 08 · Adversarial

O que um atacante pode fazer.

Imaginemos que um funcionário desonesto da marca, ou um invasor, capture o ciphertext ct_features. O que ele consegue extrair sem a chave secreta?

Tentativas de Ataque

  • Tentativa 1 — Ler bytes diretamente Resultado: bytes pseudoaleatórios. Nada extraído.
  • Tentativa 2 — Recuperar sk a partir de pk Requer resolver Ring-LWE em dimensão 16 384 com módulo de ~280 bits. Melhor ataque conhecido (BKZ): ~2128 operações. Inviável em hardware clássico ou quântico previsível.
  • Tentativa 3 — Brute force das features Mesmo que tentasse adivinhar, precisaria decifrar para verificar — e cai na barreira da Tentativa 2.

Por que isto é diferente

Em arquiteturas tradicionais (TLS + AES + servidor processando), o dado existe em claro em algum momento — durante o processamento. Esse momento é o calcanhar de aquiles de toda a história da criptografia até hoje.

FHE elimina esse momento. O dado nunca existe em claro fora do dispositivo da consumidora.

O ponto regulatório Para a LGPD/GDPR, a diferença entre "tratamos com cuidado" e "matematicamente impossível ver" é a diferença entre risco residual e risco zero.
Passo 09 · Síntese

O que acabou de acontecer.

Em menos de meio segundo total, executamos um pipeline completo de recomendação personalizada com privacidade matemática verificável. Tudo factual, tudo medido.

O Fluxo Completo

  1. A consumidora gerou 8 features de pele localmente
  2. Cifrou no próprio dispositivo com sua chave privada
  3. Enviou apenas o ciphertext para o servidor
  4. O servidor calculou 5 scores sob cifra (131 ms)
  5. Devolveu 5 ciphertexts de score
  6. A consumidora decifrou no celular e viu a recomendação

Números Reais Desta Execução

8.3 msCifragem
131 msScoring 5 produtos
1 MBCiphertext
10⁻¹⁰Erro de precisão
O Próximo Passo Levar este código ao CTO e pedir para reproduzir substituindo o vetor simulado pelo modelo de visão real da marca.