Privacy-preserving DAO voting using AlignedLayer and PLONK proofs. In DAOs (Decentralized Autonomous Organizations), voting is the basic mechanism that enables the community to make decisions together. In these systems, each member generally votes in proportion to the tokens he/she owns. All transactions can be viewed transparently in voting on the blockchain; who has how much voting power and how they vote can be clearly tracked. Although this transparency provides advantages, it also eliminates user privacy. In current DAO voting systems, voting preferences are not hidden. Anyone can review the game via a user's wallet address, meaning private preferences are disclosed. This situation is worrying in matters where anonymity and personal privacy become important.
In this project, homomorphic encryption and zero-knowledge proof technologies are combined to protect users' privacy and ensure a fair voting process. Users cast encrypted votes using their voting power, which is determined by the amount of tokens they own. Thanks to homomorphic encryption during the voting process, these votes remain anonymous, but the total votes can be verified by the community. Zero-knowledge proofs verify that each user votes according to their voting power and does not cast negative votes. Thus, the reliability and integrity of the system are ensured while each individual's preferences remain confidential.
After reviewing the literature at the end of the project, we realized that it is similar to the Helios protocol. However, due to the year it was designed, zk-snarks were not used on Helios. Also, since Helios is a classic voting, there is no vote power and only 1 vote can be given.
Network: Ethereum Holesky
AGYSO DAO Vote Validator Contract: 0x2DF98167F436d676B57614892Fb490D749b9c43b
TL;DR A blockchain-based voting system designed to preserve voter privacy and ensure accurate vote weighting based on each participant’s token balance (vote power). The system achieves confidentiality by storing encrypted votes on-chain, leveraging homomorphic encryption for private vote aggregation, and using zero-knowledge proofs (ZKPs) for verification.
In Protocol, all ciphertexts proceed on ElGamal Homomorphic Encryption. First, the person who initiates the vote generates a private-public key pair and shares the public key. Voters then cast their votes using this public key. Votes are collected by homomorphic addition and decrypted when the voting process is finished.
The ElGamal encryption implementation outside and inside the circuit is available in the zk/zk
folder. The reduced form of Twisted Edwards]of BN254 was used as the elliptic curve.
Assume
After brute-force (or using Shanks Algorithm) we can get message m.
Let's say there is another encryption with
We can add these two encryptions.
Then, by decrypting it, we obtain the sum of the two plaintexts
Plonk on BN254 was used in the project. Since the protocol is based on encrypted votes, it must be proven that the encrypted votes are created properly. ZKP verified the following:
- Vote Power Validation: ZKP confirms the encrypted votes accurately represent the voter’s token-based power (No more votes were given than token power).
- Non-Negative Vote Check: ZKP ensures no negative values are encrypted.
- Homomorphic Summation Correctness: ZKP confirms that homomorphic encryption and summation were correctly applied, enabling accurate aggregation without revealing individual votes.
Gnark was used for proof generation and its circuit structure is as follows. (The number of ballots is fixed at 4.)
type CircuitMain struct {
VoteWeight frontend.Variable `gnark:",public"` //
MasterPubKey twistededwards.Point `gnark:",public"`
Vote [4]frontend.Variable
Randoms [4]frontend.Variable
EncVoteOld VotesCircuit `gnark:",public"`
EncVoteNew VotesCircuit `gnark:",public"`
}
- VoteWeight represents vote power.
- MasterPubKey represents the encryption public key.
- Vote represents votes.
- Randoms represents randoms used in encryption.
- EncVoteOld represents the encrypted votes to be exchanged in the chain.
- EncVoteNew represents new encrypted votes added to EncVoteOld.
Tested with Debian 11, Ubuntu 22, go1.23, rust 1.82.0.
- Clone repository
git clone --recursive https://github.com/mrkaurelius/agyso-zkdaovote
- Copy
./agyso-zkdaovote/vault
dir to/var/tmp/agyso-daovote/vault
- Build
sdk/daovote-rs
and add the generated binary to the shell PATH - Initialise circuit and protocol with
cd ./zk && make cli
- Start
daovote-zk-service
service withcd ./zk && make service
which generates proof and submits proofs to the aligned layer - Start dapp frontend with
cd ./app && npm i && npm run dev
- profit :)
Go codebase for zk.
zk/cmd/zkdaovote-cli
handles zkdaovote protocol initialization which includes circuit and key generation.
zk/cmd/zkdaovote-service
serves as an HTTP service for performing generation and proof submission to the aligned layer. It
uses daovote-rs
for aligned network operations. You could also use imsonia.json
file for zkvote-service
request examples.
daovote-rs
uses aligned-SDK for submitting proofs to the aligned layer. It also generates call data for app
to use.
Used aligned_layer version: v0.9.2
.
A Hardhat project which includes AGYSODaoVoteValidator.sol
contract. Our contract verifies vote proof and set state
accordingly.
Fronted app for zkdaovote. Developed with react, vite chakra-ui.
Applied Cryptographer. Scholar, Github
- Protocol robustness and decentralization.
- Web-native decentralized application deployment.
- Deploying protocol and app in one web app (dapp).
- Proof creation on the browser.
- Testnet deployment
- Splitting the private key, which will end the voting and decrypt the encrypted votes, using secret sharing and threshold decryption.