A Análise Cega.
Vendor de IA classifica uma mamografia sem nunca ver a imagem — nem o embedding extraído dela. Este é o padrão real de produção usado por Owkin, Lifebit, Mozaic.
O Cenário
Hospital roda ResNet-50 localmente sobre a mamografia 4000×4000. O CNN produz um embedding de 2048 dimensões. Esse embedding é cifrado e enviado ao vendor de IA. Vendor executa apenas o classificador linear final sob cifra.
O Problema
Rodar CNN pesado (25M parâmetros) sob FHE é inviável. Mas o CNN roda em claro localmente, e só o classificador linear final precisa operar sob cifra. Isso torna o padrão computacionalmente viável e clinicamente plausível.
A Garantia
Vendor nunca vê a imagem original nem o embedding em claro. Mesmo tentando inverter o embedding para reconstruir a imagem (model inversion attack), o resultado seria genérico e borrado — nunca a mamografia específica do paciente.
Definir os parâmetros.
Antes de cifrar o embedding, escolhemos os parâmetros CKKS. O embedding de 2048 dimensões cabe com folga em um único ciphertext de 8 192 slots.
Capacidade · CKKS
O que cada termo significa
CKKS (esquema "aproximado") — Família FHE para números reais. Tem ruído de aproximação controlado (~10⁻⁹). É o esquema padrão para inferência de ML sobre vetores de features contínuas — exatamente o caso deste embedding.
2 048 = saída de ResNet-50 — O ResNet-50 (25M de parâmetros, treinado em ImageNet ou dataset clínico) produz um vetor de 2 048 ativações na penúltima camada. Esse vetor captura toda a informação diagnóstica relevante de uma imagem de qualquer tamanho (224×224 até 4000×4000).
Cabe em 1 ciphertext — 2 048 slots ocupados dos 8 192 disponíveis. Restam 6 144 slots vazios. CKKS processa tudo em paralelo com poucas operações.
Profundidade 3 — Suficiente para: 1 Mul (embedding × pesos) + 1 InnerSum + 1 Mul escalar + Adds. O classificador linear final consome apenas 2-3 níveis.
Base RLWE · ~128 bits — Mesmo problema do ML-KEM/ML-DSA padronizado pelo NIST como criptografia pós-quântica.
Chaves geradas no celular.
A chave secreta nasce no dispositivo do paciente e nunca sai dali. Apenas a chave pública (que não decifra nada sozinha) viaja para o vendor de IA.
O que é gerado
O que cada chave faz
sk (chave secreta) — A única que pode decifrar. Fica trancada no app do paciente, protegida pelo Secure Enclave do iPhone ou Trusted Execution Environment do Android.
pk (chave pública) — Permite que qualquer um cifre dado para você. É enviada ao vendor. Não decifra nada — só cifra. Como uma caixa de correio com fenda: qualquer um deposita, só você abre.
rlk (relinearização) — Permite ao vendor multiplicar ciphertexts. Sem rlk, multiplicação é proibida. Com rlk, multiplicação é possível mas continua sem revelar nada.
Galois keys (rotação) — Permitem operações de soma sobre vetores (InnerSum). Necessárias para o produto interno do modelo logístico.
ResNet-50 roda localmente em claro.
A mamografia original (4000×4000 pixels, ~50 MB em DICOM) é processada pelo ResNet-50 no próprio dispositivo do hospital. Em claro, localmente. O CNN é pesado demais para rodar sob FHE — por isso roda local. O resultado é um embedding de 2 048 ativações.
O que acontece no dispositivo local
img := loadDICOM("mamografia.dcm")
// img ~ 4000×4000 pixels, ~50 MB
// 2. ResNet-50 pré-treinado (EM CLARO)
model := loadResNet50("checkpoint.pt")
embedding := model.extractFeatures(img)
// embedding = [2048] vetor float
// 3. só agora cifra o embedding
pt := encoder.Encode(embedding)
ct := encryptor.Encrypt(pt)
// 4. enviar APENAS ct ao vendor
send(ct) // 1 MB
Por que este padrão é o certo
CNN pesado em claro, localmente — Rodar um ResNet-50 (25M de parâmetros, camadas conv, BatchNorm, ReLU, pooling) sob FHE seria ordens de magnitude mais caro e inviável para produção. A solução padrão da indústria é: rodar o CNN em claro no dispositivo do paciente/hospital, onde a imagem já está autorizada.
Embedding de 2048 floats — A penúltima camada do ResNet-50 é um vetor de 2048 ativações após GlobalAveragePool. ~37% dessas ativações são não-zero (sparse, característico de ReLU). Este vetor preserva toda informação diagnóstica relevante para classificação.
Não-reversível na prática — Inverter ResNet-50 (2048 → imagem original de 16M pixels) é um problema aberto de pesquisa. Ataques de "model inversion" recuperam apenas imagens genéricas e borradas — nunca a mamografia específica do paciente.
8 ms só para cifrar — A cifragem do vetor de 2048 dims leva ~8 ms em CPU comum. A extração do embedding pelo ResNet-50 levaria ~1s em CPU ou ~200ms em GPU — mas acontece em claro, sem overhead de FHE.
O que o vendor recebe.
O vendor de IA recebe aproximadamente 1 MB de bytes. Sem a chave secreta (que ficou no celular), esses bytes são indistinguíveis de ruído puro.
Bytes que chegam (amostra real)
74 65 78 74 4d 65 74 61
44 61 74 61 22 3a 7b 22
53 63 61 6c 65 22 3a 7b
...
Por que é seguro
Bytes pseudoaleatórios — Cada ciphertext é construído adicionando um polinômio de "ruído" cuidadosamente calibrado. Para qualquer observador sem a chave secreta, é estatisticamente indistinguível de ruído puro.
Sem cadeia de custódia frágil — A diferença vs o modelo atual: hoje, a imagem em claro passa por dezenas de pontos (CDN, balanceador, microserviço, banco, log). Cada um é um ponto de vazamento. Sob FHE, cada ponto só vê bytes pseudoaleatórios.
Mesmo se vazar — Se um adversário capturar todo o tráfego do vendor por meses, ainda não consegue extrair uma única imagem. A garantia é matemática, não baseada em "esperar que ninguém olhe".
Classificador linear sob cifra.
O vendor executa apenas o classificador linear final — a última camada densa do modelo — sobre o embedding cifrado. Os pesos do classificador são públicos, treinados offline em dataset clínico rotulado (CheXpert, RSNA Mammography, DDSM).
O algoritmo · pseudo-código real
pesos := loadWeights("classifier.pt")
bias := -0.6
// 2. multiplica embedding × pesos
ctMul := evaluator.Mul(ctEmb, pesos)
evaluator.Rescale(ctMul)
// 3. soma os 2048 produtos
ctLogit := evaluator.InnerSum(ctMul, 2048)
evaluator.Add(ctLogit, bias)
// 4. linearização da sigmoide
evaluator.Mul(ctLogit, 0.2)
evaluator.Add(ctLogit, 0.5)
O que cada operação faz
Mul element-wise — Multiplica cada uma das 2048 ativações do embedding pelo peso correspondente do classificador. CKKS faz tudo em paralelo em uma única operação.
InnerSum sobre 2048 slots — Soma os 2048 produtos para obter o logit (produto interno + bias). Internamente usa log₂(2048) = 11 rotações Galois. É a operação mais cara do pipeline.
Linearização da sigmoide — A sigmoide real é não-linear e cara em FHE. Para uma única inferência onde os logits ficam na faixa [-2, +2], aproximamos por reta: p ≈ 0.5 + 0.2·z. Erro < 0.03 na região útil.
79 ms total — Tempo real medido. Aceitável para diagnóstico não-emergencial. Em produção com aceleração FPGA/HEXL, cai para ~10 ms.
Paciente decifra no celular.
O ciphertext do resultado volta ao dispositivo do paciente. Apenas lá, com a chave secreta, o número se torna legível. O vendor de IA jamais vê este número.
Como ler o resultado
Score > 0.5 — Achado suspeito. App orienta paciente a buscar revisão por radiologista humano. IA é triagem, não diagnóstico.
Score < 0.5 — Sem achado relevante. Pode ser arquivado ou guardado para próximo screening de rotina.
Decisão final sempre humana — Modelo de IA nunca substitui o radiologista. É auxílio à triagem: ajuda a priorizar casos suspeitos em uma fila de milhares de exames, reduzindo tempo até revisão especializada em casos realmente críticos.
Vendor não sabe nem o score — O resultado é cifrado em trânsito de volta. O vendor sabe apenas que processou uma requisição. Nem o desfecho clínico fica com o vendor.
FHE vs plaintext.
Para provar que o cálculo cifrado produz exatamente o mesmo resultado que o cálculo plaintext, recomputamos a mesma inferência diretamente sobre o embedding em claro e comparamos.
Comparação numérica
| Métrica | FHE | Plaintext |
|---|---|---|
| Probabilidade | 0.798029 | 0.798029 |
| Erro | 1.4 × 10⁻⁹ | |
| Decisão final | IDÊNTICA | |
Por que essa precisão basta
9 casas decimais — A diferença entre o cálculo CKKS e o cálculo plaintext é da ordem de 10⁻⁹. Para comparação: a sensibilidade/especificidade de qualquer classificador clínico é da ordem de 10⁻³. Precisão de 9 casas é absurdamente mais que suficiente.
Threshold robusto — Como a decisão é binária (probabilidade > 0.5 ou não), pequenas variações numéricas não alteram a classificação final. O erro 10⁻⁹ jamais faria score 0.51 virar 0.49.
Auditoria reproduzível — Qualquer auditor independente pode rodar a mesma operação sobre o mesmo embedding cifrado e obter exatamente o mesmo score. Reproducibilidade matemática é parte da garantia clínica e regulatória.
Quatro camadas de proteção.
O vendor de IA está em uma posição fraca mesmo em ataque adaptativo. Quatro camadas distintas impedem a recuperação da imagem original.
Camada 1 — Ciphertext opaco
Tentativa: vendor tenta ler o embedding cifrado que recebeu.
Defesa: sem a chave secreta (no dispositivo do paciente), os bytes do ciphertext são pseudoaleatórios. Recuperar o embedding em claro exigiria resolver Ring-LWE em N=16 384 — ~2128 operações. Inviável.
Camada 2 — Inverter ResNet-50
Tentativa: hipoteticamente, vendor obtém o embedding em claro (imagine uma invasão). Tenta reverter ResNet-50 para reconstruir a imagem.
Defesa: inverter ResNet-50 (2048 → 16 milhões de pixels) é um problema aberto de pesquisa. Ataques de "model inversion" conhecidos (Fredrikson 2015, Zhang 2020) recuperam apenas imagens genéricas e borradas — nunca a mamografia específica do paciente. Para diagnóstico clínico, o ataque é absolutamente insuficiente.
Camada 3 — Inferir do score
Tentativa: vendor tenta inferir a imagem a partir apenas do score final (0.798).
Defesa: 1 número de saída, 2048 features, 16 milhões de pixels de entrada. Sistema massivamente sub-determinado. Informação teórica permite recuperar ~0 bits da imagem original.
Camada 4 — Conformidade regulatória
LGPD art. 11 + HIPAA — Dado de saúde é categoria especial. Sob arquitetura tradicional, enviar imagem clínica a vendor estrangeiro é compartilhamento internacional de dado sensível. Sob FHE + embedding local, o "compartilhamento" é matematicamente nulo: o vendor recebe bytes pseudoaleatórios. O dado nunca foi tecnicamente compartilhado. Este é o padrão usado por Owkin em parcerias Sanofi-Roche para imagem oncológica.
IA médica sem ver o paciente.
Em menos de 100 ms, o vendor classificou uma mamografia sem nunca ter visto nem a imagem nem o embedding em claro. Este é o padrão usado em produção por Owkin, Lifebit, Mozaic.
O fluxo completo
- Paciente gerou chaves localmente no dispositivo
- ResNet-50 rodou em claro sobre a mamografia 4000×4000
- Embedding de 2048 dims gerado localmente
- Embedding cifrado antes de sair
- Vendor recebeu apenas 1 MB de bytes pseudoaleatórios
- Classificador linear final executado sob cifra (79 ms)
- Score cifrado devolvido
- Paciente decifrou e viu a recomendação clínica