Lição: 256: ZK-SNARKs e ZK-STARKs
As provas de zero conhecimento (provas ZK) são métodos criptográficos que permitem que uma parte prove à outra que uma afirmação é verdadeira sem revelar nenhuma informação adicional. Dentre as várias formas de provas ZK, os ZK-SNARKs e ZK-STARKs têm ganhado atenção substancial por suas aplicações em blockchain e tecnologias que preservam a privacidade. Esta aula tem como objetivo apresentar esses conceitos e ilustrar seus casos de uso com exemplos.
O que são ZK-SNARKs?
ZK-SNARK significa "Argumento Conciso e Não Interativo de Conhecimento de Zero Conhecimento." Eles oferecem os seguintes recursos:
- Zero Conhecimento: O verificador não aprende nada sobre a afirmação além de sua veracidade.
- Concisão: As provas são muito curtas e podem ser verificadas rapidamente (geralmente em questão de milissegundos).
- Não Interativo: Após uma fase inicial de configuração, a geração e verificação da prova não requerem interação entre provador e verificador.
Exemplo de ZK-SNARKs
Para ilustrar, vamos considerar um cenário onde um usuário quer provar que possui um número secreto ( x ) sem revelá-lo. Suponha que ( x ) seja um resultado de hash de uma função conhecida que gera uma saída pública específica com um compromisso.
Em um contrato inteligente, o processo de verificação pode ser configurado utilizando um framework ZK-SNARK como ZoKrates ou Snarky. Podemos utilizar o esquema de prova groth16
, comumente usado em ZK-SNARKs.
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import "./ZKSnarkVerifier.sol"; // Suponha que este seja um contrato verificador importado gerado a partir de uma configuração zk-SNARK
contract VotacaoSegura {
IERC20 public token;
ZKSnarkVerifier public verifier;
mapping(address => bool) public votou;
constructor(address _token, address _verifier) {
token = IERC20(_token);
verifier = ZKSnarkVerifier(_verifier);
}
function votar(uint256[] calldata proof, uint256[] calldata inputs) external {
require(!votou[msg.sender], "Já votou");
require(verifier.verify(proof, inputs), "Prova inválida");
// Processar voto
votou[msg.sender] = true;
// Lógica adicional para contagem de votos
}
}
Neste contrato, os usuários podem submeter seus votos juntamente com as provas ZK-SNARK. A função verify
verifica se a prova submetida é válida sem revelar a escolha do eleitor.
O que são ZK-STARKs?
ZK-STARK significa "Argumento Escalável e Transparente de Zero Conhecimento." Eles são semelhantes aos ZK-SNARKs, mas possuem algumas diferenças importantes:
- Transparência: ZK-STARKs não requerem uma configuração de confiança, tornando-os mais seguros contra possíveis manipulações.
- Escalabilidade: Eles são projetados para serem escaláveis e eficientes para grandes computações.
Exemplo de ZK-STARKs
Vamos considerar um cenário de votação similar ao anterior, mas utilizando ZK-STARKs. A principal diferença aqui é que não precisaremos de uma configuração de confiança, permitindo-nos provar afirmações sobre computações maiores de forma contínua.
Os ZK-STARKs frequentemente utilizam linguagens de programação e frameworks como Cairo ou StarkNet. Para fins de demonstração, vamos assumir que temos um contrato hipotético StarkVerifier
:
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "./StarkVerifier.sol"; // Suponha que este seja o contrato verificador para ZK-STARKs
contract VotacaoSegura {
StarkVerifier public verifier;
mapping(address => bool) public jaVotou;
constructor(address _verifier) {
verifier = StarkVerifier(_verifier);
}
function registrarVoto(uint256[] calldata proof, uint256[] calldata inputs) external {
require(!jaVotou[msg.sender], "Você já votou");
require(verifier.verify(proof, inputs), "Prova STARK inválida");
// Processar o voto
jaVotou[msg.sender] = true;
// Lógica para manipular contagens de votos
}
}
Aqui, mais uma vez, permitimos que os usuários registrem seus votos enquanto fornecem uma prova gerada via ZK-STARK, garantindo que seu voto permaneça confidencial.
Conclusão
Tanto ZK-SNARKs quanto ZK-STARKs oferecem meios poderosos de alcançar privacidade e segurança em transações. A principal distinção reside nos requisitos de configuração e nas opções de escalabilidade. Ao decidir utilizar um em vez do outro, é essencial considerar as necessidades específicas da sua aplicação, como o modelo de confiança, requisitos de desempenho e tamanho da computação.
Ao incorporar essas ferramentas criptográficas avançadas em seus contratos inteligentes, você pode aprimorar a privacidade e a confiança dos usuários em suas aplicações descentralizadas.