We are currently investigating ways in which we can integrate private voting into our Opinion Market system. In this post, I will detail our system requirements, initial implementation approach, as well as future improvements we intend to make to the first working version of this private voting system.
Requirements
Our existing system requirements are as follows:
- We need to enable users to submit private votes onchain and have the opinion market contract store these encrypted votes as ciphertext in an appropriate data structure.
- We need a way for users to reliably encrypt their votes client-side before submitting them to the contract. Votes values need to remain hidden for the duration of the market such that they can’t be tallied while the market is live.
- We need a way to trustlessly decrypt votes offchain when the market closes and submit the vote tally to the contract to settle the market.
- Finally, we must be able to tie a user’s vote back to them upon market settlement so that we can accurately update the internal reputation / scoring system.
Implementation Details
Initial Implementation Flow
- Drand publishes a public key for a future round.
- Voters encrypt their votes offchain with the Drand public key & a noise value.
- The user submits their encrypted vote as ciphertext to the opinion market contract.
- After the voting period ends, the corresponding Drand private key is released.
- The settlement process follows these key steps:
-
The aggregator script performs three main operations offchain:
- Collects and decrypts all user votes from the encrypted onchain submissions
- Generates a merkle tree from the decrypted votes for efficient verification
- Computes the final vote tally
-
These results are then atomically submitted to the opinion market contract through a single settle() function call, which includes the following as calldata:
- Merkle root - enables efficient verification of vote integrity
- Decrypted vote data - allows for vote verification
- Final calculated tally - the ultimate outcome of the vote
- The Opinion Market contract will then fetch a random value from the randomness oracle and decrypt a predefined threshold of randomly selected encrypted votes onchain. Provided the randomly selected votes that were decrypted onchain match the corresponding decrypted votes in the Merkle tree that was constructed offchain, the tally will be accepted by the contract and the market will settle successfully. Otherwise, the contract will reject the tally and the function will fail to settle the market.
For this initial implementation, all private votes submitted to the contract will be made public after the market ends and the Drand private key is released. For full vote privacy in perpetuity, we would require the use of more advanced cryptographic techniques such as additive homomorphic encryption. This is something we are mindful of and intend to iterate on this in the second version of this system.
System Component Details
Cairo Contracts
- Store encrypted votes as ciphertext in an appropriate data structure. This needs to include the user’s address, noise, and the vote values.
- Decrypt a predetermined threshold of randomly selected encrypted votes to ensure statistical confidence in the offchain decryption process. In other words, we need to verify randomly selected votes from the merkle tree constructed offchain. We will need to create an algorithm to choose random votes from the list of encrypted votes.
- The randomness oracle is queried by the contract to determine which votes to decrypt onchain.
Client-side Libraries
- Encryption Process:
- Ensure users correctly encrypt their votes with the Drand Public Key (Dpk) prior to submitting them to the Opinion Market contract.
- This is what the structure of the vote should look like before encrypting:
- <key:value pair>
- <user’s address: boolean answer to question Q, boolean answer to question P, noise>
- This is what the structure of the vote should look like before encrypting:
- Correctly format each vote during the encryption process such that questions Q and P are formatted consistently and the final ciphertext output can be stored correctly in a cairo contract.
- Introduce a noise value to the encryption process to ensure that it would be impossible to guess the values of encrypted votes from the ciphertext stored onchain.
- Ensure users correctly encrypt their votes with the Drand Public Key (Dpk) prior to submitting them to the Opinion Market contract.
- Decryption Process:
- Fetch Drand Private Key (DprivK) for the respective round from the Drand API.
- Fetch all encrypted votes from the Opinion Market contract.
- Decrypt all votes offchain and construct the merkle tree or merkle patricia trie with the decrypted votes.
- Store the merkle tree off-chain (e.g. IPFS) or publish it to the Opinion Market contract.
Oracle
- Provide verifiable randomness that the contract can use to randomly select encrypted votes to decrypt onchain and compare with the corresponding values in the merkle tree constructed offchain.
- Randomness Oracle Options:
Future Improvements
Private Voting
- Leverage Homomorphic Encryption to tally encrypted votes onchain without the need to ever reveal them.
- Explore the use of pallier & exponential ELGamal implementations which allow for additive homomorphic encryption.
- TSS (Threshold Signature Scheme) to maintain a group which can decrypt HME.
- Explore the use of SNARK/STARK proofs to verify the entire computation from decrypting the votes to the production of the final merkle root and vote tally that are submitted to the contract.
Anonymity
- Utilise client side proving tools such as Noir.Js that enable users to generate proofs locally on their device without revealing any sensitive information. These proofs would be used to verify the validity of a given user’s vote on submission as well as verify a user’s proof of personhood (PoP).
- Client side proofs would be verified directly on Starknet via Garaga verifier contracts.
Additional Resources
- Announcing NoirJS: Privacy-Preserving ZK Applications In Your Browser | Aztec Blog
- Client-side Proof Generation | Aztec Blog
- blog/pdf/private-voting.pdf at main · aragonzkresearch/blog · GitHub
- The Time NounsDAO Got Private Voting | Aztec Blog
- Further Work - HackMD
- Nouns Private Voting Research Sprint - General Report - Aragon ZK Research - blog
- Nouns Private Voting Research Sprint - Technical Report - Aragon ZK Research - blog
- GitHub - aragonzkresearch/nouns-anonymous-voting: The anonymous voting application implementation for Nouns project.
- Suffragium: An Encrypted Onchain Voting System Leveraging ZK and FHE Using Zama's fhEVM
- Vocdoni Protocol: Enabling Decentralized Voting for the Masses with ZK Technology - zk-s[nt]arks - Ethereum Research
- Thinking in Circuits | Noir Documentation