ZK10: Zero knowledge proof-based onchain private voting - Ahmad Afuni
28 Sept 2023 · 15:16
Recorded at ZK Summit 10 in London, Ahmad Afuni presents an approach to zero-knowledge proof based private voting for DAOs built on Ethereum state and storage proofs. The talk covers work jointly developed by Aragon ZK Research and Aztec as part of Nouns DAO's Private Voting Research Sprint, addressing how zero-knowledge proofs can make private onchain governance practical.
Speakers
Topics
Transcript
foreign [Music] so I'll be talking about some joint work we've been doing with Aztec as part of nouns desk private voting research Sprint um so just as a summary we have this token-based voting system so one nft one vote we have voter anonymity for the duration of the voting process and Beyond so you shouldn't be able to correlate votes with the actual voters the votes themselves are private for the duration of the voting period and then revealed at the end and finally everything is verified on chain
so just as an introduction I'll talk about the design from a high level so first of all from the front-end perspective you basically acquire an nft that gives you you know membership in a tower some voting power right one nft one vote as I mentioned you have to enroll to vote so it's assumed everybody in the Dow has registered in a certain sense and I'll talk about in a moment and then somebody creates a voting process people vote the votes are actually encrypted with a certain um key pair whose public key is revealed at the start and private Keys revealed at the end via time Lock Service which I won't go into detail on but that's something that was a component of our project a massive one actually
um so private key revealed decrypt votes compute results publish them um and you know everything is kind of uh made more solid by ZK proofs which I'll elaborate on in a moment and on the back end basically each of these steps except for the starred ones involve running some computation generating a ZK proof submitting that together with appropriate public inputs some of the public inputs can actually be obtained on chain so that's you know extra um yeah makes it extra solid that way smart contract verifies proof and then something is done some data stored some data is emitted in the form of logs so and uh well let's have a quick look at well just a quick refresher on blocks in
ethereum so this is all happening on ethereum blocks kind of look like this you know the usual linked list picture um inside each block we have a so-called state route that basically resolves addresses uh down to account data right and uh via you know Merkel Patricia tries and essentially to prove you have some data in some account you can basically start from the root of this uh try and go down to the account where you have yet another try the storage try and uh so in the K in our case what we want is we want all voters to prove their eligibility in zero knowledge and that basically involves proving that you have an nft and you've registered to vote
so in this you know for this example you're kind of you're resolving the address of one of those contracts and once you actually get to the account you have to go through the storage try to actually get at the value you want so you want to resolve nft ID to address in the case of proving ownership of an nft or you want to resolve an address to a certain public key public key not being the public key of your you know wallet but uh so purpose-built public key that's snark friendly so that's kind of like the gist of what's going on and this is very expensive in a snark because to actually resolve these Keys you have to you know take this hex string and basically go one letter at a time decompose it you also have to compute
ketchak hashes to make sure everything is you know legit so it's quite expensive to do in a snark um so let me talk about the implementation in more detail maybe it'll start making maybe it'll make more sense in that case um so we have the ethereum blockchain we have some fixed nft contracts we have some ZK snark proving system with an embedded curve possibility advantage and verification in our concrete case it's Ultra plug via Noir the embedded curve is baby job job primordial subgroup of baby job we have some ZK snark friendly hash function um so in our case it's Poseidon or Poseidon in quotation marks because uh the form of Poseidon usually used is you fix a an input length and then you apply
the permutation then you project which is technically not exactly hash function the way it's defined but that's the one we use and then we have an additional hash function to aggregate ballots and that's all that also happens to be Poseidon and we assume given some time lock service for verifiably random key generation to be able to encrypt our votes for the duration of the voting period so the contracts involved so we have essentially these contracts we have a registry contract so that contains pairs of addresses and public Keys necessary to um to basic to basically sign your ballots um and also compute a nullifier we also have a voting contract which contains the specifics of the various voting
processes so process number ipfs linked to a proposal vote choices period the time lock public key as votes come in they're aggregated in the sense that you basically keep a running hash of the encrypted ballots that come in this is necessary for computing the results and verifying that actually all of the ballots have been counted all ballots are logged not stored and we have some verifier smart contracts to basically verify these uh these proofs so here's how registration works you connect your wallet you generate a private key private baby job Key by signing a certain message from your wallet and then you compute the corresponding public key and submit that to the registry contract so why do we do this
because using your private key in a snark is probably not a good idea I mean you can't really do the snack stuff on a hardware wallet and this was kind of our approach to getting around that so this approach is used in several other places seems to be a standard technique um and then for voting process creation so here's where things get a bit tricky so what you want to do is you want to take a census at the moment of voting process creation to say hey everybody who's registered up until this point everybody who owns the nft is eligible to vote so we essentially take a snapshot of the blockchain now on the blockchain itself in smart contracts you cannot get the state route or the storage route all you can get is the
block hash of one of the past few blocks right so what you do is when you create your voting process you obtain all the necessary information via you know RPC and then you put together a succinct proof in our case it's the ZK proof but it only has to be succinct that all these routes you get are actually consistent with the current block hash and then you submit this to sync proof to the smart contract together with the data the smart contract doesn't have and then the smart contract is going to verify that this proof is legit and accept these values and store them at the same time you also call out to that time Lock Service to obtain a public key to encrypt votes with and of course you you supply all the necessary voting parameters
and then when each person comes to vote what they do is they compute a couple of signatures they basically sign their nft ID together with the ID of the voting process including blockchain ID and so on using this baby job private key they also sign um assign their vote choice and they compute a nullifier by hashing one of these signatures so to prevent double voting we generate a random one-time private key and use that together with the uh baby together with the uh time lock public key to compute a shared secret which is used to encrypt the vote and so the vote can only be decrypted once the private time lock key is revealed because we're
going to throw away this random private key and of course you fetch storage proofs basically proving that you own the nft that you have enrolled to vote you generate a ZK proof verifying all of this submit everything to the smart contract I mean everything that's public at least smart contract verifies everything and then it logs your ballot according to the ID of the voting process the um the public key corresponding to this one-time private key and your encrypted ballot and then at the end of the voting process the private key has just shown up out of thin air so you can actually decrypt all the ballots compute the results compute the aggregation of all the ballots put a ZK proof together that everything is good and submit it to the
smart contract and then the smart contract will take care of the rest so this approach is not without its drawbacks so for example to obtain those storage proofs on the last slide I mean if your voting process is longer than you know an hour or two then um you can't necessarily ask any ethereum node for that data you'll need an archive node but everybody uses inferior so we're okay right try proofs are very expensive in a ZK snark so lots and lots and lots of constraints takes minutes to generate proofs for all these things so you know it's a bit tricky and Ultra plonk helps a lot with that with the lookups um a gas yeah we're talking several hundred k
um and also whale sightings are possible because one nft one vote so it might be possible to correlate you know votes to certain whales so saving the whales is one of the yeah one of the things we need to look into so the Outlook is to all of this actually happens natively on your computer we have a CLI prototype online it's on GitHub um we're hoping to move this to the browser with you know recursive with recurs recursion in uh Noir maybe look into some kind of relayer service to save the whales optimization and integration into Dow Solutions like Aragon's Dao framework so yeah if you're interested in learning more uh this QR code takes you to our research blog and you can reach me on
decentralized social media thank you for your attention and also perfectly in time I'm impressed so we have time for questions yes [Music] hi uh so two questions on my side so the first one is around the tallying of the boats do you have to reveal the private key before you actually start counting the votes and like determining like who won or who lost or whatever the the outcome and the second one is
regarding the Poseidon hashing function that you mentioned uh you did it in like quotation marks and then described something that really wasn't like hashing uh did you roll out your own like hashing function for this okay so I'll answer the so first question was about the uh private key absolutely required yeah I mean to actually decrypt the votes um so the idea is there would be some time Lock Service um so we have this this solution this blockchain based solution where you can essentially call out and request a private key at some later time and it should be trustworthy if at least one party's honest so it's called the time Lock Service we you can read up on that on our blog that's where Poseidon we didn't roll out our own so we use the implementation we use is equivalent to
circom's implementation it seems to be the de facto standard hash function even though it's not technically a hash function um it's not the sponge it's not the one in the paper but it's you know part of it yeah more questions so this is a prototype I guess so any ideas like when could someone use this kind of thing in production it's a good question um I mean uh so from the side so apart from the time Lock Service I would say actually
pretty soon so the short answer is pretty soon but that depends on how much you're willing to tolerate the long improving times and the amount of gas you have to pay so technically most of this is sound I mean we're pretty close so you know soonish like within the next year in theory uh there are a few technical issues that need to be addressed um but yeah for the most part I would say very soon in theory with enough funding Etc yes someone would want have to want this yeah with the um
so can you say a bit more what your use cases what use cases you would envision for well I mean private doubt doubt well that was where you want any form of privacy I mean that was kind of noun's motivation extra privacy um So within without sort of re I guess re deploying your now your your Dao so this can kind of like plug in rather easily to an existing Dow setup that's that's kind of what we envisioned yeah feasible to support weighted voting with this protocol hmm weighted voting
potentially I mean at the moment yeah we're kind of implicitly doing like nft ownership weighted voting but um in theory yes okay thanks okay last question and maybe the next speaker can already come up to Stage please yeah thanks um was the choice around going with like results revealed at the end is that a result from nouns perspective of that that was the requirements they wanted or was this the simpler solve technically no I think it was one of their requirements I am fairly sure it was
right yeah I've yeah because you mentioned it's interesting you mentioned like you need users to accept because I've got one potential user who wants shielded as in revealed and one who just doesn't understand that and just wants it always to be anonymous um so yeah I'm interested in both implementations okay I mean it would be possible to to do without yeah I mean without the yeah it doesn't simplify things in any case yeah all right so yeah thank you Ahmad let's thank him again [Applause]