A decentralized, anonymous voting mechanism.

Let’s now design a decentralized voting mechanism on Ethereum using zero-knowledge proofs to achieve true, cryptographic anonymity. If you are unaware of what zero-knowledge proofs are, I recommend reading up on this and anything on zkp.science.

Background

Ethereum — Ethereum is a blockchain project that enables the execution of smart contracts, which can be thought of as programs running on a decentralized computer.

Zero-knowledge Proof of Knowledge — A ZKP is a cryptographic proof detailing knowledge of an input x to an output f(x) without revealing x.

Anonymous coin mixer/tumbler — An anonymous mixer or tumbler is a service that “mixes” or “tumbles” cryptocurrency to anonymize the trail of ownership. A user deposits coins into a mixer and withdraws them using different, unlinked addresses, preserving anonymity.

Merkle Tree — A merkle tree is a cryptographic binary tree data structure that is built by repeatedly hashing the children to create parent nodes, starting at the leaves or data nodes.

Mechanism Details

The voting mechanism we will build uses:

Anonymous voting strategy Public tallying strategy

and is designed with these groups in mind:

Ethereum owners as the organization entity Any adversary capable of finding and bribing token holders.

Mixer Protocol

The protocol that we will build is largely a derivative of an anonymous coin mixer on Ethereum, called Miximus developed by barryWhiteHat [4].

The mixer functions primarily through the novel usage of a merkle tree and non-interactive zero-knowledge proofs (ZK-SNARKs). The leaf nodes of the merkle tree contain the hash of a secret, which we will call H(x1,…,xN). The scheme works as follows:

First, a user deposits 1 ETH into the smart contract and creates a leaf node in the merkle tree with data H(x1,…,xN) with an address A. Then, using the secret (x1,…,xN), the user creates a special zero-knowledge proof or ZK-SNARK, denoted p. Finally, the user creates a new address B that is not linked in any way to A and withdraws 1 ETH from the mixer, providing p as a proof that the user knows the secret contained in a leaf of the merkle tree.

Security of protocol. The protocol above is secure under the assumption that the Diffie-hellman discrete log problem is hard under the chosen hash function. This hardness prevents any adversary from finding the pre-images of the data of leaf nodes input into the tree. Moreover, the use of a ZKP allows the withdrawer to prove they deposited into the tree without disclosing which leaf is their corresponding deposit. Under the former assumption, finding out which leaf they eventually withdraw from is also hard.

Voting Protocol

We will design a voting protocol that is weighted against token holdings; that is, under a 1 coin, 1 vote paradigm. These are useful in polling the opinions/thoughts of the aggregate market of token holders of a specific token like Ether and have nice analogues to the voting capabilities of shareholders in publicly traded companies on the stock market. Our voting protocol requires a few changes but is derived from the protocol above.

First, a poller/developer deploys an Election smart contract with a future time cliff t for ending the election. The contract contains logic for voting. Then, a user deposits 1 ETH into the smart contract and creates a leaf node in the merkle tree with data H(x1,…,xN) with an address A. This locks the user’s ETH until time t’ such that t<t’. Then, using the secret (x1,…,xN), the user creates a special zero-knowledge proof or ZK-SNARK, denoted p. Next, the user creates a new address B that is not linked in any way to A and submits their vote v, providing p as a proof that the user knows the secret contained in a leaf of the merkle tree. Finally at any time t’ such that t<t’, the user withdraws the 1 ETH stuck in the contract to the same account that voted. This can be handled by storing voters on the contract and marking when various voting addresses have withdrawn or not.

Security of protocol. The protocol above is secure under the same cryptographic assumptions as the Mixer protocol. The reason the votes are not cryptographically linked to the addresses of the token holders is due to the fact that the tokens cannot be either. Following a vote, these new, unlinkable accounts can proceed in a similar fashion — mixing and voting — for as long as they desire.

However, now that we are using a token-weighted voting protocol, there is the potential for linking votes with token holders through statistical analysis. This, however, is largely unavoidable while tallying of votes remains public. In the scheme above, votes are recorded in plaintext and thus provide insight into the state of the market’s belief or side on a given issue, which can pose other issues in relation to voter incentives.

Example. There are 3 owners of tokens: Alice, Bob, and Charlie. Assume for the sake of argument that Alice, Bob, and Charlie purchased all the tokens in an ICO; that is, the tokens were sent to addresses of Alice, Bob, and Charlie. Since these fractions were disclosed through the on-chain transfer of tokens, we can potentially link the votes of a user depending on how many votes we have. Under a rational voter model, a truthful voter will vote for only their side of an issue. Thus, when and if they use all their tokens to vote, it is possible to link, with some probability, the likelihood that Alice voted a certain way AND controls the mixed tokens from the resulting protocol.

Say what? More security!

In the example described above, we’ve potentially run into an issue due to the public tally of our designated voting protocol. We can resolve this by changing a portion of the protocol, instead requiring a commitment to a vote. Our changes start at step 4, but we repeat its entirety for clarity. Recall H is our chosen hash function, we use (y1,…,yM) to denote randomness for obfuscating a committed vote.

First, a poller/developer deploys an Election smart contract with a future time cliff t for ending the election and a further time period Δ for the revealing of commitments. The contract contains logic for voting. Then, a user deposits 1 ETH into the smart contract and creates a leaf node in the merkle tree with data H(x1,…,xN) with an address A. This locks the user’s ETH until time t’>t. Then, using the secret (x1,…,xN), the user creates a special zero-knowledge proof or ZK-SNARK, denoted p. Next, the user creates a new address B that is not linked in any way to A and submits a commitment to a vote H(v,y1,…,yM), providing p as a proof that the user knows the secret contained in a leaf of the merkle tree. Finally at any time t’ such that t<t’<t + Δ, the user reveals their vote v’ along with the randomness (y’1,…,y’M) to be verified by the contract such that the following relation holds H(v,y1,…,yM)=H(v’,y’1,…,y’M). In the event this doesn’t hold, i.e. a user submits a false vote, the voter loses their deposit. If ultimately there are unrevealed votes at time t’ such that t + Δ<t’, those deposits are also similarly slashed and kept as punishment. This provides an incentive for users to actually reveal their votes in the allotted time.

With hashed commitments, our election or poll is no longer publicly tallying. Instead, votes are revealed after the voting protocol has closed and tallied at the time t’ such that t<t’<t + Δ. The downside of this enhancement is that it requires more effort on behalf of the voters, though it provides added incentives or rather punishment against not revealing.

Applications

The protocols above are examples of a token based voting system, weighted by the number of tokens a voter has. It can be extended to allow larger casting of votes on arbitrary orders such as X coins for X votes.

We can utilize tokens as the de facto method for casting anonymous votes but alter the distribution process of those tokens. Perhaps, a trusted third party such as a basketball team can issue tokens to season ticket holders. Then using these tokens, 1 per season ticket holder, they can vote on new changes they would like to see in stadium offerings.

I leave most of this imagination up for another time. I think there are interesting applications with these protocols when combined with other identity solutions and wonder if they’re even possible given the structure of the protocols defined above.

Attacks

I will conclude the article with a discussion on where these voting systems fail. The downside of anonymous voting on blockchain based networks using the protocols defined above rests precisely on their anonymity. These problems potentially restrict the solution above to only successfully handle weighted-token voting schemes. The reason anonymity is a downside is because it opens up the possibility for bribery and election fraud.

Recall our previous ICO example with potentially many more token owners. Alice and Bob can collude off-chain and share secret information for verifying their respective ZKPs. Then, either of them can cast votes on behalf of newly anonymized accounts.

Season ticket holders can purchase votes from one another outside and away from the basketball team’s owners. The main reason is there is pure anonymity and thus no guarantee that the future owners of the tokens remain the same. After all, coin mixing services were designed to obscure the path of ownership of tokens. We simply abuse that principle to handle anonymous voting.

Furthermore, this attack vector makes it nearly impossible to handle reputation or identity within the protocol, since there should not be a way to transfer reputation or identity to anyone.

Protocol and proof extensions

On the contrary and with a more delicate design, there may be ways to build a system to allow for reputation and/or greater identity based voting solutions, beyond owning tokens. Some of these ideas lead to alternative weighted voting mechanisms where: