Criptografia homomórfica, medida 8 testes · uma máquina · nada citado sem marcação

O Google diz que FHE ficou prático.
Medimos onde ele para.

Três documentos recentes dizem que a criptografia totalmente homomórfica virou tecnologia de produção. Nenhum deles publica os números lado a lado. Montamos a bancada, rodamos oito testes na mesma máquina e escrevemos onde exatamente a fronteira fica.

A resposta curta: existe uma fatia de FHE pronta para produção hoje, e ela é menor e mais específica do que o anúncio sugere. A fatia de fora não é "lenta" — em vários casos é matematicamente impossível com os parâmetros que se usa na prática.

1 min 14 s

Um bootstrap CKKS com parâmetros reais de 128 bits (logN=16)

10,26 GB

Chaves que o cliente envia antes de qualquer computação útil

40× / 232×

A rotação custa 40× a multiplicação — e empacotar direito devolve 232×

2−30

Abaixo desta diferença, comparar dois cifrados não tem resultado definido

darwin/arm64 · 8 CPUs lógicas · Go 1.24.0 · single-thread · Lattigo v6.2.0 · agosto de 2026

O que estamos conferindo

A observação que organiza tudo

O HEIR não é um esquema novo nem uma aceleração. É um compilador que emite código para as mesmas bibliotecas que já usamos — Lattigo inclusive. O teto de performance do HEIR é, literalmente, o que esta bancada mede.

Ele automatiza as reescritas de empacotamento e a análise de profundidade, que são trabalho real e chato. Não muda a física. Por isso as quatro demos escolhidas pelo Google são todas modelos rasos sobre features pré-extraídas — exatamente a região verde do quadro abaixo. Nenhuma envolve comparação cifrada em profundidade nem lookup em vocabulário grande.

A fronteira em três regimes — no ramo aritmético

A distinção que importa não é "roda ou não roda" — quase tudo roda se você esperar o suficiente. É se o custo cabe num orçamento de produção.

Funciona
  • Soma e multiplicação SIMD
  • Produto interno / camada densa
  • Ativações suaves em intervalo garantido
  • Agregação: votação, gradientes federados, contagens
Funciona, mas custa
  • Profundidade multiplicativa acima de 8
  • Divisão por valor cifrado
  • Bootstrapping
  • Banda e chaves de avaliação
Não funciona na prática
  • Comparação, máximo, argmax, ordenação
  • ReLU exato
  • Indexação por posição cifrada em vocabulário grande
  • Qualquer ramificação dependente de dado cifrado
Em uma frase

FHE funciona hoje quando a computação é um circuito aritmético fixo e raso, aplicado a um lote grande, com toda comparação e decisão empurradas para o cliente, que tem a chave.

Sai da fronteira assim que aparece profundidade indefinida, indexação por valor cifrado, ou decisão dependente de dado cifrado.

Os oito testes

Cada teste tem um veredito declarado antes de rodar e um número medido depois.

T1

Camada linear sobre embedding cifrado

Funciona

Produto interno de 2048 dimensões — o padrão que o Google demonstra para recomendação e que a indústria já usa: a CNN pesada roda em claro no dispositivo, só o embedding é cifrado.

CKKS, logN=14, 8192 slots, embedding no formato ResNet-50
EtapaMedido
Multiplicação ct × pt + rescale1,6 ms
InnerSum — 12 rotações62,8 ms
Precisão do resultado28,2 bits
Slowdown sobre o claro~27.500×
Amortizado em lote de 416 ms/item
Chaves Galois + relinearização97,5 MB
O achado

A rotação custa 40× mais que a multiplicação. "FHE é lento porque multiplicar cifrado é caro" está errado — multiplicar é barato. O que é caro é mover dados entre slots, e é disso que qualquer redução, soma de vetor ou convolução é feita.

Otimizar FHE é, na prática, minimizar rotações. É a reescrita mais valiosa que o HEIR automatiza.

T2

Orçamento de profundidade multiplicativa

Custa

Cada multiplicação consome um nível do módulo. Quando os níveis acabam, o ciphertexto vira ruído. Rodamos quadrados sucessivos até quebrar — e os dois modos de BGV quebram de formas muito diferentes.

ModoMorre emComo morre
BGV (com rescale)profundidade 4Erro explícito: sem nível para rescalar
BFV (scale-invariant)profundidade 8Silenciosamente — resultado errado
CKKS8 multiplicaçõesGradual: 0,6 bits de precisão por nível
│ depth  nível  esperado  obtido  status
│ 7      4      15028     15028   ✅ exato
│ 8      4      282       28323   ❌ RUÍDO — resultado errado, sem aviso
O achado

O BFV dá mais profundidade e falha sem aviso. É a combinação mais perigosa que existe em produção: nenhum erro, nenhuma exceção, um número plausível que está simplesmente errado.

Consequência de projeto: o circuito precisa ser conhecido antes das chaves. É por isso que agregação funciona tão bem — somar é profundidade zero.

T3

Não-linearidades: onde o custo explode

Não funciona

FHE oferece exatamente dois operadores: soma e produto. Todo o resto vira polinômio — e polinômio custa profundidade, o recurso escasso de T2.

(a) Ativações suaves — funciona, com uma ressalva

Sigmoid por Chebyshev em [−8, 8]: grau 31 dá erro de 4,7e−5 em 5 níveis; grau 63 dá 4,4e−8 em 6. Mas fora do intervalo o polinômio não degrada — explode:

│ x = 7.9   sigmoid real 0.999629   polinômio  0.999629      
│ x = 10.0  sigmoid real 0.999955   polinômio -74.773.876    
│ x = 15.0  sigmoid real 1.000000   polinômio -9,2e22        

O servidor computa sobre cifrado e portanto não tem como detectar isso. Garantir o domínio vira cláusula contratual do cliente.

(b) Comparação e sinal — o penhasco

O polinômio composto padrão para sign(): nove polinômios encadeados, graus 15/15/15/17/31/31/31/31/7, com profundidade somada de 40 níveis — contra os 4 a 8 de um conjunto de parâmetros normal. Sem bootstrapping não é lento: é impossível.

A zona cega, medida. O limiar documentado é 2⁻³⁰ ≈ 9,31e−10.
EntradaSinal corretoSinal sob FHE
±1e−9±1±1,000000
±1e−10±1+0,553 / −0,680
±1e−12±1−0,004 / −0,009
00−0,059

A fronteira medida cai exatamente entre 1e−9 e 1e−10, cercando 2⁻³⁰. Comparar dois valores cifrados que diferem por menos de 2⁻³⁰ é uma operação sem resultado definido.

(c) Divisão — barata, se o intervalo for declarado

Goldschmidt para 1/x em [0,25 · 1]: 52 ms, 31 bits, zero bootstraps. O que encarece não é dividir — é dividir sem saber o intervalo.

O achado

O padrão de projeto correto não é fazer argmax sob cifra — é devolver os scores cifrados ao cliente e deixar a decisão acontecer em claro, do lado de quem tem a chave. Custo: zero.

Isso também explica por que redes profundas sob FHE trocam ReLU por x² e são retreinadas com essa ativação: ReLU exato tem o custo do sinal.

T4

O custo real do bootstrapping

Custa

Bootstrapping é o que transforma "leveled HE" em fully homomorphic. Todo texto de divulgação cita Gentry (2009). Quase nenhum publica o custo.

Medida logN=13 brinquedo logN=16 128 bits reais
Keygen1,5 s20,2 s
Chaves de bootstrapping840 MB10,26 GB
Instanciar o avaliador0,7 s23,1 s
Um bootstrap1,25 s1 min 14 s
Precisão de saída25,0 bits24,6 bits
Níveis gastos para recuperar 101515

Duas leituras que costumam ficar de fora dos diagramas. Primeiro: o bootstrapping gasta 15 níveis para devolver 10 — o ganho é líquido, mas modesto. Segundo: a diferença entre o conjunto de brinquedo e o de segurança real é de 60×, e a maior parte do material publicado não diz qual dos dois está citando.

Combinando os contadores medidos em T3 com o bootstrap real de 1 min 14 s
OperaçãoBootstrapsTempo
1 sign()45 min
argmax de 103645 min
argmax de 1003968 h 12 min
argmax de 10003.99682 horas
O achado

Um argmax sobre mil candidatos — a operação final de qualquer classificador — custa três dias e meio de CPU sob cifra. Do lado do cliente, que tem a chave: microssegundos.

Por isso a arquitetura que funciona hoje é leveled: dimensione o módulo para caber o circuito inteiro e nunca bootstrappe. E por isso as parcerias de hardware anunciadas pelo Google importam mais que o compilador — o gargalo é este número, e ele não cai por software.

T5

Lookup em tabela de embeddings

Não funciona

O problema central do HE-LRM, e o que separa "busca privada" de ficção. Se o índice está cifrado, o servidor não pode saltar para a linha certa — o padrão de acesso à memória vazaria justamente o dado que se queria proteger. Toda a tabela precisa ser tocada. Custo linear em |V|, sem escapatória possível.

Medido acima da linha; projetado a 69 µs e 2 KB por linha abaixo
VocabulárioTempoBanda cliente → servidor
51236 ms1,0 MB
8.192569 ms16 MB
10⁴ — CEPs do Brasil0,7 s20 MB
10⁵ — SKUs de e-commerce6,9 s195 MB
10⁶ — IDs de usuário69 s1,9 GB
10⁷ — escala Criteo11,6 min19 GB
O achado

A coluna da banda é a que mata: gigabytes enviados pelo cliente para buscar 16 números.

O modelo do Criteo tem cerca de 26 features categóricas. Pela via ingênua isso dá ~5 horas contra os 228–489 s declarados no paper — um ganho de ordem ~45×, coerente com os 56× reivindicados. A bancada não reproduz o método deles, mas confirma que o problema atacado é real e é desta escala.

T6

Banda, armazenamento e chaves

Custa

O custo que raramente entra no slide. Em arquitetura real, o que inviabiliza primeiro costuma ser a banda, não a CPU.

logNSlotsCiphertextoExpansão
122.048192 KB12×
148.1921,75 MB28×
1516.3844,50 MB36×
Um único número1 de 8.1921,75 MB229.428×
O achado

Contra-intuitivo: a expansão melhora com logN maior, porque os slots dobram junto com o ciphertexto. Batching não é otimização — é pré-requisito.

FHE recompensa lotes grandes e homogêneos e pune consultas pontuais. Um cálculo sobre 10.000 registros é barato; uma consulta sobre 1 registro é caríssima. Isso inverte a intuição de quem vem de banco de dados, e é a origem da maior parte das arquiteturas FHE mal dimensionadas.

T7

Empacotamento: onde o compilador paga

Funciona

T1 mostrou que a rotação custa ~40× a multiplicação. Segue-se que otimizar FHE é minimizar rotações — e isso é um problema de empacotamento, não de criptografia. É exatamente o que o HEIR automatiza. Este teste mede quanto vale.

(A) Matriz fina — 256 produtos × 8 dimensões

A forma do scoring de catálogo e de qualquer cabeça de classificação
EstratégiaChamadasRotaçõesTempoErro máx
ingênuo (1 InnerSum/produto)2567681,81 s5,35e−10
replicado138 ms4,88e−10

(B) Matriz quadrada 2048×2048 — uma camada densa de verdade

EstratégiaRotaçõesChavesTempocts saídaErro máx
ingênuo22.5289,00 MB15,78 s20481,91e−09
diagonal2.0481,50 GB611 ms15,57e−11
diagonal + BSGS9571,3 MB156 ms15,58e−11
O achado

232× no caso fino, 101× no quadrado. Mesma biblioteca, mesmos parâmetros, mesma máquina — só o empacotamento mudou. O BSGS ainda reduz as chaves em 21× e devolve 1 ciphertexto em vez de 2048, e a precisão fica melhor que a do ingênuo: menos operações acumulam menos ruído.

Isto fecha o argumento aberto em T1 e torna o valor do HEIR concreto. A reescrita é mecânica e fácil de errar — escolher n1·n2, montar as diagonais, gerar o conjunto exato de chaves Galois. Ninguém deveria fazer isso à mão.

Ressalva que impede a leitura errada: o ganho vale para este formato de problema. Não se transfere para T3 nem T5 — comparação continua exigindo bootstrapping, lookup continua linear no vocabulário. Empacotamento melhor não move a fronteira; faz o lado de dentro dela caber no orçamento.

T8

TFHE/CGGI: o esquema que inverte tudo

Custa

T1–T7 mediram BGV, BFV e CKKS. TFHE — chamado CGGI no HEIR — inverte todas as propriedades desses esquemas de uma vez. Cada gate booleana faz o seu próprio bootstrapping embutido, então não existe orçamento de níveis e a profundidade é ilimitada. Em troca, um ciphertexto carrega um bit.

go-tfhe v0.2.2, 128 bits de segurança, Go puro
MedidaValor
Keygen (secreta + nuvem)145 ms
Chave de avaliação164,20 MB
Latência por gate31,95 ms
Um bit cifrado2,7 KB
NOTgrátis

Todas as gates (AND, OR, XOR, NAND, NOR, XNOR) conferem em todas as entradas — cada célula da tabela de verdade é um bootstrapping real, não simulação. Um comparador de 8 bits são 32 gates e 1,02 s; um somador de 8 bits, 40 gates e 1,28 s.

A comparação frontal: os dois esquemas são inversos

OperaçãoCKKSTFHEVencedor
1 comparação4 min 58 s1,02 sTFHE por ~291×
produto interno 2048-dim64 ms~112 hCKKS por ~6×10⁶
profundidade máxima8 multsilimitadaTFHE
dados por ciphertexto8.192 números1 bitCKKS por ~10⁴
chave de avaliação10,26 GB164 MBTFHE por ~64×
O achado

Isto reposiciona duas conclusões dos testes anteriores. T2 não se aplica ao TFHE — não há níveis para acabar, não há falha silenciosa. E T3 era uma afirmação sobre CKKS, não sobre FHE: "comparação é inviável" vale para CKKS; sob TFHE é a operação natural.

Nenhum dos dois ganha em tudo, e a diferença não é de maturidade — é estrutural. A pergunta de projeto deixa de ser "FHE serve?" e passa a ser: o meu circuito é aritmético ou é lógico?

E é por isso que o HEIR suporta os dois lados — BGV/BFV/CKKS via OpenFHE e Lattigo, CGGI via tfhe-rs e Jaxite. A escolha de esquema é uma decisão de compilação, e é a mais importante do projeto.

O que muda a partir daqui

Nenhuma das três fontes está errada. O HEIR é um projeto sério e o HE-LRM resolve um problema real. O que a bancada acrescenta é a escala: os números que nenhuma das três publica lado a lado, medidos no mesmo hardware, com a mesma biblioteca que o próprio HEIR usa como backend.

A conclusão prática é chata e útil: projete para leveled. Dimensione o módulo para caber o circuito inteiro, empacote tudo em lotes grandes, minimize rotações, e mande toda decisão para o lado do cliente. Tudo que exige bootstrapping frequente sai de "latência de API" e entra em "job em lote" — e essa fronteira não se move por software.

Faça

Agregar, pontuar e classificar sobre lotes grandes de features já extraídas

Cuidado

Divisão, profundidade acima de 8, e qualquer coisa que precise bootstrappar

Não faça

Comparar, ordenar, ramificar ou indexar por valor cifrado no servidor

Antes de assinar um piloto de FHE

A pergunta que separa projeto viável de projeto caro é sempre a mesma: qual é a profundidade multiplicativa do circuito, e onde a decisão acontece? Se a resposta envolve comparação no servidor, o orçamento está errado por uma ordem de grandeza. Fazemos esse laudo antes de você comprometer engenharia.

Todas as medições vêm de execuções da bancada nesta máquina, em agosto de 2026. Números atribuídos a terceiros estão marcados como citação e não foram reproduzidos. Os contadores de bootstrap de T3 foram medidos com logN=12 e o tempo de T4 com logN=16 — a tabela de argmax é ordem de grandeza, não previsão exata.