O que são zk-SNARKs e como permitem a privacidade em blockchains?

O que são zk-SNARKs?
zk-SNARKs são provas criptográficas que permitem demonstrar que determinada informação ou um cálculo está correcto, sem revelar informação sensível para a privacidade. Assim, uma blockchain pode, por exemplo, verificar que um pagamento é válido, enquanto dados como o montante ou o destinatário permanecem ocultos. Uma das blockchains mais conhecidas que utiliza esta tecnologia é a Zcash. Aí, os zk-SNARKs são usados para verificar transacções enquanto dados como o montante ou o destinatário podem permanecer ocultos.
O nome zk-SNARK é uma abreviatura de zero-knowledge succinct non-interactive argument of knowledge. Parece complicado, mas pode dividir as partes de forma simples:
- Zero-knowledge: a prova demonstra que uma afirmação está correcta, por exemplo que uma transacção é válida, sem revelar informação sensível para a privacidade, como o endereço de envio, o endereço de recepção ou o montante da transacção.
- Succinct: a prova é curta. Assim, um node ou smart contract pode verificá-la de forma relativamente eficiente.
- Non-interactive: depois de criar a prova, o autor não precisa de comunicar de um lado para o outro com quem a verifica. A prova pode ser criada uma vez e depois verificada.
- Argument of knowledge: o autor demonstra que dispõe da informação necessária para cumprir as regras definidas, por exemplo os dados com que pode ser criada uma transacção válida. A segurança assenta em pressupostos criptográficos: um atacante com capacidade computacional limitada não consegue, na prática, criar uma prova falsa que seja aceite como válida. A informação com que a prova é criada é muitas vezes chamada de witness. Imagine que quer provar que tem saldo suficiente para um pagamento. A witness contém então, por exemplo, os dados com que pode demonstrar que dispõe de fundos suficientes e que os pode gastar. A blockchain não precisa de ver esses dados por si, mas pode verificar que a prova correspondente é válida.
Além da witness privada, um zk-SNARK também pode conter entrada pública. São dados que podem ser visíveis e que o verifier usa em conjunto com a prova para verificar se a afirmação está correcta.
É importante saber: um zk-SNARK não é um protocolo único e fixo, mas um termo genérico para diferentes tipos de sistemas de prova com estas propriedades. O funcionamento exacto pode variar de sistema para sistema. Alguns sistemas, por exemplo, precisam de um trusted setup, enquanto outros podem funcionar sem esse tipo de configuração.
Pontos principais
- Os zk-SNARKs provam que algo está correcto sem revelar informação sensível para a privacidade.
- Os dados privados por trás de uma prova são muitas vezes chamados de witness.
- As provas são curtas e podem ser verificadas de forma relativamente eficiente.
- Uma prova publicada pode ser verificada sem contacto adicional com o autor.
- Os zk-SNARKs são uma categoria de sistemas de prova, não um protocolo único e fixo.
Como funcionam os zk-SNARKs?
Num zk-SNARK, as regras que uma transacção ou cálculo tem de cumprir são primeiro convertidas em verificações que um computador pode executar. Esse conjunto de verificações é chamado de circuito ou sistema de restrições. Aí fica definido exactamente quais as condições que têm de ser cumpridas antes de algo ser considerado válido.
Tomemos um pagamento privado como exemplo. O circuito pode, por exemplo, verificar se alguém dispõe de saldo suficiente, se esse saldo ainda não foi gasto anteriormente e se está autorizado a utilizá-lo. Os dados sensíveis necessários para estas verificações, como o saldo ou os dados com que pode ser gasto, permanecem ocultos para quem verifica a prova.
Em linhas gerais, existem três passos:
-
Setup Em muitos zk-SNARKs clássicos, primeiro são criados parâmetros públicos. Estes dados são necessários para criar e verificar provas.
-
Geração da prova O prover, ou seja, a parte que quer provar algo, usa a witness e as regras do circuito para criar uma prova criptográfica.
-
Verificação O verifier, por exemplo um node ou smart contract, verifica a prova em conjunto com a entrada pública. O verifier não vê a witness privada e não precisa de repetir por si todo o cálculo.
Um bom sistema zk-SNARK procura garantir três propriedades importantes. Em primeiro lugar, completude: se a afirmação estiver correcta e a prova for criada correctamente, a prova é aceite. Em segundo lugar, soundness: um atacante não consegue, na prática, criar uma prova válida para uma afirmação que não esteja correcta. E, em terceiro lugar, zero-knowledge: a prova não revela informação sensível para a privacidade, para além do facto de a afirmação provada estar correcta.
Exemplo: Imagine que tem de provar que tem mais de 18 anos, sem partilhar a sua data de nascimento. Um zk-SNARK pode, em teoria, provar que cumpre essa condição, sem que o verificador veja a sua data de nascimento ou a sua idade exacta.
Há, no entanto, um limite importante. Um zk-SNARK apenas verifica as regras definidas no circuito. Se houver um erro nessas regras, uma prova pode ser tecnicamente válida enquanto o sistema continua a permitir algo que, na realidade, não era a intenção. A criptografia não corrige automaticamente um circuito mal concebido.
Para que são usados os zk-SNARKs?
Os zk-SNARKs são usados quando alguém quer demonstrar que um cálculo foi executado correctamente, sem tornar públicos todos os dados de entrada ou os passos intermédios. Isso torna a técnica interessante para a privacidade, mas também para aplicações em que quem verifica a prova não precisa de repetir todo o cálculo.
Algumas aplicações conhecidas são:
- pagamentos privados;
- aplicações em que a entrada ou partes do cálculo permanecem privadas;
- provas de identidade e credenciais, em que se prova uma característica sem partilhar todos os dados pessoais;
- proof-of-reserves, em que uma parte pode demonstrar que determinadas reservas existem sem tornar públicos todos os dados subjacentes;
- validity rollups, que processam muitas transacções fora da Ethereum e depois colocam na Ethereum uma prova do processamento correcto.
Aleo, por exemplo, utiliza um modelo em que um programa é executado localmente. Depois, é criada uma prova de zero-knowledge com a qual se pode demonstrar que a execução foi correcta. Os validators não precisam então de receber toda a entrada privada e os passos intermédios, mas podem verificar a prova.
A privacidade não surge automaticamente só porque aparece “ZK” em algum lado. Quais os dados que permanecem privados depende do protocolo e do que foi definido no circuito como privado ou público. Se determinados dados da transacção forem tornados públicos de propósito, um zk-SNARK não os consegue ocultar depois.
Como é que os zk-SNARKs apoiam a privacidade?
Os zk-SNARKs apoiam a privacidade porque permitem provar que uma transacção é válida sem revelar os seus detalhes sensíveis. Num pagamento privado, por exemplo, alguém pode provar que dispõe de fundos válidos, que está autorizado a gastá-los e que não está a gastar dinheiro duas vezes. O remetente, o destinatário e o montante não precisam de ser públicos.
A Zcash mostra bem como este tipo de desenho funciona. Aí, é usada uma note para registar de forma privada uma determinada quantidade de ZEC. Na blockchain não consta o conteúdo completo dessa note, mas sim um commitment: um registo criptográfico da mesma. Pode ser visto como um envelope fechado e selado. Toda a gente pode ver que o envelope existe, mas não o que está dentro.
A informação sobre a note é cifrada para o destinatário. Quando uma note é gasta, aparece na blockchain um nullifier único. Esse nullifier não mostra directamente qual a note que foi gasta, mas os nodes podem verificar se o mesmo nullifier já foi usado anteriormente. Assim, a rede pode evitar double spending sem revelar os dados privados subjacentes.
Privacidade, aqui, não significa que não fique qualquer rasto na blockchain. Commitments e nullifiers continuam visíveis. Além disso, dados como endereços IP, temporização, metadados de rede e informação que um utilizador torne pública por sua iniciativa não são automaticamente ocultados por um zk-SNARK.
Como é que os zk-SNARKs são usados para escalabilidade?
Para escalabilidade, os zk-SNARKs podem ser usados para resumir uma grande quantidade de trabalho computacional numa única prova compacta. Isso vê-se, por exemplo, nos validity rollups: as transacções são processadas fora da Ethereum, agrupadas em lotes e, depois, é criada uma prova de que o processamento decorreu correctamente.
O operador de um desses rollups processa as transacções e cria uma validity proof com a qual se demonstra que o novo estado foi calculado de acordo com as regras do rollup. Um contrato verificador na Ethereum só aceita esse novo estado se a prova for válida. Assim, a Ethereum não precisa de repetir todos os cálculos de cada transacção individual.
Com recursão, isto pode ser ainda mais resumido. Nesse caso, uma nova prova pode demonstrar que várias provas anteriores são válidas. Desta forma, muitas transacções ou provas separadas podem, no fim, ser representadas por uma única prova compacta.
A Scroll usa provas zk para demonstrar a execução correcta de lotes de transacções, após o que a prova pode ser verificada na Ethereum.
A Mina usa zk-SNARKs recursivos de outra forma. Em vez de um participante ter de verificar todo o histórico da blockchain desde o início, a validade do estado actual da blockchain pode ser demonstrada com uma prova criptográfica compacta.
Verificação rápida não significa que todo o processo seja barato. Criar uma prova pode, pelo contrário, exigir muita capacidade computacional e memória. Além disso, uma validity proof não resolve automaticamente outros problemas, como a disponibilidade de dados, a censura por parte de um operador ou os riscos associados a bridges entre blockchains.
Que blockchains e criptomoedas utilizam zk-SNARKs?
Vários projectos de criptomoedas utilizam zk-SNARKs, mas muitas vezes para objectivos diferentes. A técnica, portanto, não é usada apenas para transacções privadas.
- Zcash usa zk-SNARKs para transacções shielded. No protocolo Orchard, é usado Halo 2 para provar criptograficamente essas transacções.
- Aleo usa zk-SNARKs para aplicações privadas e programáveis. Os programas podem ser executados localmente, após o que os validators verificam a prova de execução correcta sem precisarem de ver a entrada privada ou os passos intermédios.
- Mina usa zk-SNARKs recursivos para provar de forma compacta a validade do estado da blockchain. O objectivo principal aqui é a verificação compacta e não, automaticamente, a privacidade das transacções.
- Scroll usa zk-SNARKs dentro da sua zkEVM para provar o processamento correcto de lotes de transacções. Estas provas podem depois ser verificadas na Ethereum.
- Ethereum suporta a verificação de certos zk-SNARKs baseados em pairing através de precompiles. Isso permite que smart contracts verifiquem provas zk-SNARK. A Ethereum não usa os zk-SNARKs, por si só, como mecanismo de consenso geral.
Note a diferença entre um zk-SNARK e um zk-STARK. Ambos são sistemas de prova criptográficos que podem suportar zero-knowledge, mas funcionam de forma técnica diferente. Os zk-STARKs, em geral, não precisam de trusted setup, mas costumam produzir provas maiores do que os zk-SNARKs. Por isso, um ZK-rollup não tem necessariamente de usar um zk-SNARK.
O que é um trusted setup nos zk-SNARKs?
Um trusted setup é um processo único em que, para alguns zk-SNARKs, são criados parâmetros públicos necessários para gerar e verificar provas. Estes dados são muitas vezes chamados de structured reference string (SRS) ou common reference string (CRS).
A parte sensível é a informação secreta e aleatória usada durante esse setup. Esta é também chamada de toxic waste. Se alguém guardar essa informação ou a conseguir reconstruir mais tarde, isso pode, em certos sistemas, como o Groth16, ser explorado em teoria para criar provas falsas que ainda assim sejam aceites como válidas.
Por isso, os projectos usam por vezes uma cerimónia de multi-party computation. Vários participantes acrescentam aí a sua própria aleatoriedade secreta. Desde que pelo menos um participante actue de forma honesta e destrua efectivamente a sua contribuição secreta, a informação secreta completa do setup não pode ser reconstruída.
Isso reduz bastante o risco, mas continua a significar que se depende de pelo menos um participante não ter sido comprometido e de ter eliminado realmente a sua contribuição secreta.
Nem todos os zk-SNARKs precisam de um trusted setup. A Zcash usou, para os antigos circuitos Sprout e Sapling, o Groth16, que exigia esse tipo de trusted setup. O protocolo Orchard, mais recente, usa Halo 2 e não precisa de um trusted setup com toxic waste.
Quais são as vantagens dos zk-SNARKs?
A grande vantagem dos zk-SNARKs é que privacidade e verificabilidade podem andar juntas. Pode provar que cumpre determinadas regras sem tornar públicos os dados sensíveis por trás dessa prova.
As principais vantagens, em resumo:
- Privacidade com controlo: os dados sensíveis podem permanecer ocultos, enquanto os nodes continuam a poder verificar se uma transacção ou cálculo é válido.
- Provas curtas: as provas são compactas em comparação com o cálculo que representam.
- Verificação rápida: um node ou smart contract não precisa de repetir todo o cálculo.
- Verificação pública: uma prova pode ser publicada e depois verificada de forma independente.
- Resumir muitos cálculos: com provas recursivas, várias transacções, lotes ou provas anteriores podem, no fim, ser resumidos numa nova prova compacta.
Na Ethereum, certos zk-SNARKs baseados em pairing também podem ser verificados em smart contracts. Isso permite que aplicações, por exemplo, façam verificar na Ethereum provas de cálculos offchain ou controlos orientados para a privacidade.
Ainda assim, é importante: “curto” e “eficiente” dizem sobretudo respeito ao tamanho da prova e à sua verificação. Para o prover, criar essa prova pode exigir muita capacidade computacional e memória.
Quais são as limitações e os riscos dos zk-SNARKs?
Os zk-SNARKs são poderosos, mas não são uma solução para todos os problemas de privacidade ou escalabilidade. A segurança depende da criptografia utilizada, do circuito e da forma como o sistema é integrado numa blockchain ou aplicação.
Um risco importante em sistemas que dependem de um trusted setup é a informação secreta do setup. Se a toxic waste de, por exemplo, um setup Groth16 cair nas mãos erradas, os atacantes podem, potencialmente, criar provas falsas que ainda assim sejam aceites como válidas. Num desenho de pagamento privado, isso pode, no pior dos casos, levar à criação de saldo que, segundo as regras normais, não deveria ter existido.
Além disso, um zk-SNARK apenas prova que as regras do circuito foram cumpridas. Erros no circuito, no código do prover, no código do verifier, nos parâmetros utilizados ou na ligação a uma blockchain podem, por isso, ter consequências graves. Uma prova criptograficamente correcta não ajuda se as regras subjacentes tiverem sido mal concebidas.
A privacidade também tem limites. Em transacções shielded da Zcash, por exemplo, commitments e nullifiers continuam visíveis na blockchain, enquanto a informação sobre as notes permanece cifrada. Além disso, dados públicos, temporização, endereços IP e outros metadados de rede podem, por vezes, ainda revelar informação ou tornar relações visíveis.
Nos zk-rollups, surge outro problema. Uma validity proof pode demonstrar que um lote foi processado correctamente, mas não impede automaticamente que um operador atrase transacções ou censure utilizadores. Também continuam a existir riscos associados a bridges e à disponibilidade de dados.
Por fim, zero-knowledge não significa automaticamente que um sistema esteja preparado para futuros ataques quânticos. Isso depende da construção criptográfica concreta. Os zk-SNARKs clássicos baseados em pairing usam pressupostos criptográficos diferentes dos sistemas STARK transparentes, por exemplo.
Conclusão
Os zk-SNARKs tornam possível provar que uma transacção ou cálculo está correcto, sem revelar os dados sensíveis por trás do mesmo. Por isso, são interessantes para pagamentos privados, aplicações orientadas para a privacidade e escalabilidade através de validity rollups. A Zcash é um dos exemplos mais conhecidos de uma blockchain que usa zk-SNARKs para permitir transacções shielded.
A ideia central é relativamente simples: uma blockchain ou outro verifier não precisa de ver todos os dados subjacentes nem de repetir todo o cálculo, desde que consiga verificar uma prova criptográfica válida. A quantidade de privacidade e segurança que isso acaba por oferecer depende, no entanto, do desenho do sistema. Um zk-SNARK é, no fim, apenas tão fiável quanto o circuito, a criptografia utilizada e a integração à sua volta.