Exploring coordinator hiding in ZK voting: homomorphic tally without decrypting individual votes
ethresear.ch
I’ve been exploring a different design space for private onchain voting, specifically around what the coordinator should and shouldn’t see, and whether voter addresses appear onchain at all. ## Motivation Most ZK voting schemes (like MACI) focus on **anti collusion**: preventing voters from proving how they voted to a briber. The coordinator decrypts all votes at the end to compute the tally, which is fine under this threat model. I was curious about a stricter model where the tallying coordinator is not trusted with per vote plaintext visibility. **Why does this matter?** - **Coordinator insider risk**: Even a trusted coordinator can be compromised, bribed, or coerced into leaking individual votes - **Data minimization**: If you don’t need per vote data, don’t collect it - **Governance manipulation**: Knowing how specific parties voted mid process could enable targeted pressure or strategic changes In contexts where the coordinator is a DAO multisig, a third party service, or any entity with potential conflicts of interest, hiding individual votes from the coordinator may be a meaningful property. ## Design Overview The system I built uses: - **Relayed transactions** so voter addresses never appear onchain - **ElGamal encryption on BabyJubJub** for votes - **Homomorphic addition** of encrypted votes (no per vote decryption) - **Groth16 proofs** for both vote validity and tally correctness - **Native token weighted voting** for DAO governance use cases ### Vote Submission Each voter encrypts their choice with the coordinator’s public key and submits a Groth16 proof showing: - Membership in a Merkle tree of eligible voters - Correct nullifier derivation (prevents double voting) - Valid EdDSA signature The coordinator relays the transaction onchain, so the voter’s EOA never appears as a transaction sender. ### Tally Instead of decrypting each vote, the coordinator: 1. Homomorphically sums all encrypted votes 2. Decrypts only the aggregate using BSGS (baby step giant step) 3. Generates a tally proof verifying correct aggregation and decryption ``` MACI style: Enc(v1) → Dec(v1), Enc(v2) → Dec(v2), … → sum This system: Enc(v1) + Enc(v2) + … = Enc(sum) → Dec(sum) → BSGS → result ``` The discrete log is bounded by the maximum total voting weight (currently hardcoded to 1,000,000), making BSGS feasible with minimal computation. ## Comparison with MACI | | MACI | This approach | |—|------|---------------| | **Coordinator sees individual votes** | Yes (decrypts each) | Not by design (only aggregate decryption performed) | | **Voter address onchain** | Yes (voter calls contract) | No (coordinator relays) | | **Blockchain scan reveals voters** | Yes (EOAs visible) | No (only coordinator address) | | **Anti collusion** | Yes (key rotation) | Partial (no receipt, but no key rotation) | | **Weight based voting** | Requires customization | Native (token weighted) | | **Tally complexity** | O(n) decryptions | O(1) decryption + BSGS | These are different threat models, not competing implementations: - **MACI**: “Protect the voter from external pressure”, anti bribery centered - **This approach**: “Limit what everyone, including the coordinator, can learn”, data minimization centered ## Limitations (Honest Assessment) **Coordinator single key**: Currently the coordinator holds a single decryption key. The protocol only performs aggregate decryption, but a malicious coordinator could technically decrypt individual ciphertexts. Threshold ElGamal (k of n) would eliminate this capability, so no individual keyholder could decrypt alone. **No anti collusion**: Without MACI’s key rotation mechanism, a voter could potentially prove how they voted. This is an intentional scope decision: the threat model prioritizes coordinator hiding over bribery resistance. **Relayer censorship**: The coordinator relays all votes, which introduces a censorship surface. A malicious coordinator could selectively refuse to submit votes. ## Questions 1. Are there known attacks on this model I should consider? 2. Any thoughts on combining coordinator hiding with stronger anti collusion? 3. Does the relayer model introduce assumptions I’m underestimating? I have a working implementation with onchain verification on Sepolia. Happy to share the demo walkthrough if useful for context: github.com/0xgumi/Commitra samples/demo/walkthrough.md 36332ee56 # Demo Walkthrough: End-to-End Vote Lifecycle This document traces a **complete vote session** on the Commitra demo environment, from vote creation to on-chain tally finalization. This walkthrough is based on the public demo environment, which intentionally simplifies certain assumptions while preserving the full verification model. Every step includes either a **browser screenshot** or an **on-chain transaction link**, allowing independent verification without access to any source code. **Network:** Ethereum Sepolia **Vote session:** voteId = 123 **Title:** Governance Proposal: Community Fund Allocation --- ## Step 1. Vote creation This file has been truncated. show original Feedback welcome. 1 post - 1 participant Read full topic