sitella

From Wiktionary:

sitella f (genitive sitellae); first declension

  1. an urn for holding ballots

Sitella is a prototype of an end-to-end verifiable voting system - one where anybody can check that the announced result is the correct count of the ballots actually cast, without anybody being able to learn how a given person voted. It’s a single Rust binary that plays every role: election server, voter client, organizer tooling, and public auditor.

I’ve heard people saying that the relatively recent development of blockchain technology could bu used to solve issues of election security. I started this project out as an exploration of that idea, but ended up dropping the blockchain aspect entirely. All of the specific requirements I had for the final result were satisfied by cryptography alone.

An election runs in five steps:

  1. Voters register once, and the important detail is that the secret is generated on the voter’s own device - the organizer only ever receives a public commitment to it, and must never generate the secret itself.
  2. At the registration deadline the roll of commitments is frozen and published as a plain text file, with its Merkle root pinned in the first record of the transcript.
  3. To vote, the device encrypts the choice, proves the ciphertext is well-formed (exactly one candidate), proves in zero knowledge that it belongs to some holder of a secret on that frozen roll, and derives a nullifier that spends that identity’s single vote. No name and no commitment travel with the ballot. The server re-checks everything, appends it to a hash-chained public transcript, and hands back a signed receipt pointing at the ballot’s position.
  4. After close, the encrypted ballots are summed while still encrypted, and only the totals get decrypted - by the trustees together, each proving its decryption share is honest, so no individual ballot is ever decrypted and no complete decryption key ever exists.
  5. Then anyone can run sitella verify against the transcript and re-check all of it offline: the hash chain, every membership and ballot proof, every nullifier, the voting window, the sums, the decryption proofs. A voter can additionally point it at their receipt and see their own ballot sitting in the count.

But if you wanted to verify that your ballot was actually cast for a particular candidate/proposal/etc., that is not possible. Before looking into this whole “voting” topic, I knew we’d need to handle attacks from bad actors, but hadn’t really considered legitimate voters misbehaving. You don’t want to give someone the ability to confirm what they voted for - they could show that verification to someone who is either paying them for the vote, or who is coercing them to vote for something against their will.

This system could (theoretically) scale from a national election down to an office lunch poll. Although, it is very much a prototype and not something you’d want to run a real election on (yet). I still have a few improvements planned, and I’ll keep this post updated along with the code.

Get the program here on GitHub.

← Back to Projects