A evolução da arquitetura de privacidade: de mixers a protocolos programáveis
Mixers clássicos como Tornado Cash ou Sinbad estão ficando obsoleto sob a pressão de reguladores, sanções do OFAC (Office of Foreign Assets Control) e análises de grafos de transações por rastreamento de clusters heurísticos. A anonimização nativa em nível de pools de liquidez é bloqueada na camada de smart contracts por meio de listas de endereços de alto risco (Chainalysis, Elliptic) integradas aos nós RPC dos principais provedores (Infura, Alchemy).
A indústria está migrando para o conceito de privacidade programável (Programmable Privacy). Em vez de ocultar o fato da transação por meio da diluição de depósitos em um pool, novas soluções em nível de protocolo permitem executar lógica de negócios arbitrária e smart contracts sobre dados criptografados. Os líderes dessa transição são redes baseadas em arquiteturas zk-rollup com suporte a Programmable Privacy, como Aztec (Noir), e redes L1 confidenciais especializadas como COTI 2.0, utilizando primitivas de hardware e criptografia de última geração.
Circuitos Embaralhados (Garbled Circuits) no Blockchain
Na base de plataformas como o COTI 2.0 está a primitiva criptográfica clássica do protocolo de Yao (Yao's Garbled Circuits), adaptada para o ambiente descentralizado do blockchain. Ao contrário das zk-SNARKs, que provam a validade de uma declaração sem revelar os dados subjacentes, os Garbled Circuits permitem que duas ou mais partes que não confiam entre si calculem uma função booleana arbitrária sobre entradas confidenciais, de forma que nenhuma das partes veja os dados da outra.
Mecânica do Circuito Embaralhado
- 1. Representação da lógica como um circuito booleano: Qualquer cálculo (transferência de tokens, verificação de saldo, credit scoring) é compilado em um grafo acíclico direcionado composto por portas lógicas (AND, XOR, NOT).
- 2. Embaralhamento (Garbling): O criador do circuito (o Garbler) gera chaves aleatórias de 128 bits para cada entrada e saída de cada porta. As tabelas verdade das portas são criptografadas com essas chaves em ordem aleatória.
- 3. Transferência Oblívua (Oblivious Transfer, OT): O avaliador do circuito (o Evaluator) obtém suas chaves de entrada do Garbler por meio do protocolo criptográfico OT. O Evaluator descobre apenas as chaves correspondentes à sua entrada real, sem revelá-la ao Garbler e sem obter acesso às demais chaves.
- 4. Computação elemento por elemento: O Evaluator decriptografa as tabelas verdade criptografadas de baixo para cima no circuito, calculando o resultado sem poder conhecer os valores intermediários das variáveis.
Otimizações de Engenharia para Blockchain
Garbled Circuits brutos exigem um volume massivo de comunicações de rede. Para integrá-los ao ambiente de blockchain, os desenvolvedores aplicam duas otimizações principais:
- Técnica Free-XOR: Permite executar portas XOR sem criptografia nem transmissão de dados, reduzindo drasticamente a sobrecarga de memória e a largura de banda do barramento.
- Point-and-permute: Um método de mascaramento de bits que permite ao Evaluator encontrar imediatamente a linha correta na tabela verdade criptografada, sem precisar testar todas as opções de decriptografia por força bruta.
Comparação de Stacks Criptográficos de Confidencialidade
Para escolher o tech stack correto ao projetar aplicativos descentralizados focados em proteção de dados, utiliza-se o mapeamento das métricas-chave dos protocolos modernos.
| Protocolo / Tecnologia | Base Criptográfica | Suporte a Smart Contracts | Sobrecarga Computacional (Overhead) | Modelo de Compliance |
|---|---|---|---|---|
| Tornado Cash (Mixer Histórico) | zk-SNARK (Groth16) | Nenhum (denominações fixas) | Baixo (apenas verificação de prova) | Nenhum (total resistência à censura) |
| Aztec Network | zk-SNARKs + Linguagem Noir | Turing-completo (smart contracts privados) | Moderado (geração de prova no cliente) | View Keys, notas de auditoria programáveis |
| COTI 2.0 | Garbled Circuits + MPC | Suporte nativo a contratos compatíveis com a EVM | Alto (requer circuitos otimizados) | Divulgação Seletiva (Selective Disclosure) |
| Zcash (Shielded Pool) | zk-SNARKs (Halo 2 / Sapling) | Limitado (pools transparentes vs. blindadas) | Médio | Chaves de visualização (Viewing keys) |
Na Prática: Divulgação Seletiva (Selective Disclosure) e Stablecoins
O compliance moderno exige a transição do conceito de "sombra absoluta" para o princípio da divulgação seletiva (Selective Disclosure). O usuário mantém o controle total sobre o histórico de seu capital, mas, quando necessário, pode provar a uma contraparte, regulador ou autoridade fiscal a legitimidade dos fundos sem expor o saldo total da carteira nem toda a matriz de conexões com outros endereços.
Na arquitetura do Aztec, isso é implementado por meio de um sistema de chaves separadas e execução no lado do cliente dentro do Private Execution Environment (PXE).
Arquitetura de Chaves no Aztec
Cada usuário gerencia um conjunto determinístico de chaves vinculadas ao smart contract da conta:
- Nullifier Keys ($nhk$): Usadas para gerar provas de gasto (nullifiers) sem vazar informações sobre qual saldo específico ou note está sendo gasto.
- Incoming Viewing Keys ($ivsk$): Permitem conceder acesso de auditoria a transações de entrada específicas. Você pode repassar uma chave de visualização criptografada a uma contraparte ou regulador, dando-lhes visibilidade estritamente sobre a transação de stablecoin de destino (por exemplo, USDT/USDC empacotado em L2), enquanto mantém todos os outros ativos ocultos.
Exemplo de Implementação: Transferência Privada de Stablecoins em Noir
Abaixo está um trecho de código production-ready em linguagem Noir (o DSL básico para escrever circuitos no Aztec), que implementa a verificação privada de saldo e a geração de compromisso de transferência de tokens sem publicar valores em um registro público.
Trecho de Código
// Dependência em Nargo.toml: poseidon = { tag = "...", git = "https://github.com/noir-lang/poseidon" }
use poseidon::poseidon::bn254::{hash_2, hash_3};
global TREE_DEPTH: u32 = 32;
struct Note {
owner: Field,
amount: u64,
randomness: Field,
}
fn commit(note: Note) -> Field {
hash_3([note.owner, note.amount as Field, note.randomness])
}
fn merkle_root(leaf: Field, index: u32, path: [Field; TREE_DEPTH]) -> Field {
let bits: [u1; TREE_DEPTH] = (index as Field).to_le_bits();
let mut node = leaf;
for i in 0..TREE_DEPTH {
node = if bits[i] == 0 {
hash_2([node, path[i]])
} else {
hash_2([path[i], node])
};
}
node
}
fn main(
// Entradas públicas: nada sobre valores e endereços
merkle_root_pub: pub Field,
nullifier: pub Field,
recipient_commitment: pub Field,
change_commitment: pub Field,
// Entradas privadas
sender_sk: Field,
sender_note: Note,
path: [Field; TREE_DEPTH],
leaf_index: u32,
transfer_amount: u64,
recipient_owner: Field,
recipient_randomness: Field,
change_randomness: Field,
) {
// 1. Propriedade do note (com tag de domínio)
assert(hash_2([sender_sk, 1]) == sender_note.owner);
// 2. Pertencimento à árvore em relação à raiz pública
let sender_commitment = commit(sender_note);
assert(merkle_root(sender_commitment, leaf_index, path) == merkle_root_pub);
// 3. Suficiência de fundos (em caso de escassez, a subtração u64 também falhará)
assert(sender_note.amount >= transfer_amount);
let change_amount = sender_note.amount - transfer_amount;
// 4. Nullifier
assert(hash_3([sender_commitment, sender_sk, 2]) == nullifier);
// 5. Ambos os novos notes estão vinculados aos commitments públicos
assert(commit(Note {
owner: recipient_owner,
amount: transfer_amount,
randomness: recipient_randomness,
}) == recipient_commitment);
assert(commit(Note {
owner: sender_note.owner,
amount: change_amount,
randomness: change_randomness,
}) == change_commitment);
}Permanecem fora do circuito: a criptografia dos notes para o destinatário, o armazenamento e atualização da árvore no contrato, a verificação de unicidade do nullifier e a checagem de merkle_root_pub com a raiz conhecida.
Recomendações de Integração para Desenvolvedores
- 1. Evite Geração de Provas no Servidor: Nunca confie a geração de ZK-proofs a servidores de API remotos de terceiros. Todo o ciclo de computação (PXE no Aztec ou scripts de cliente) deve ser executado localmente no dispositivo do usuário ou em um nó isolado.
- 2. Gerenciamento de Chaves Silos por App (App-Siloed Keys): Utilize chaves derivadas e isoladas para cada aplicativo descentralizado. Isso garante que o comprometimento de uma chave em um protocolo não resulte na desanonimização do histórico de transações do usuário em outros smart contracts.
- 3. Auditoria de Canais de View Keys: Ao projetar gateways corporativos ou de pagamento baseados em privacidade programável, incorpore a lógica de geração de chaves de visualização temporárias com tempo de vida limitado (time-to-live). Isso permite passar pelo compliance bancário e regulatório (AML/KYT) sem precisar publicar as chaves master permanentes da carteira.