Reproducible builds: proving the software running is the software you inspected
Switzerland published its voting source code so anyone could inspect it — and researchers immediately found a hidden backdoor that could forge a perfect-looking proof while silently changing votes.
It is March 2019, and in Bern, Swiss Post is doing something that sounds like the gold standard of election transparency. Its internet voting system — built with Spanish vendor Scytl, intended for use in binding Swiss federal votes — is about to have its full source code published online for the world to read.
This is what democracy advocates had been demanding for years. Open the black box. Let experts look. Trust through inspection.
Within weeks, three independent cryptographers — Sarah Jamie Lewis, Olivier Pereira, and Vanessa Teague — had looked. And what they found was not reassuring.
The trapdoor nobody saw until someone looked
The system's centerpiece was a mathematical proof. After all votes were mixed and shuffled to preserve anonymity, the software would generate a cryptographic "shuffle proof" — a piece of mathematics that supposedly demonstrated, to anyone who checked, that the shuffle had been performed correctly and no votes had been altered.
It was called universal verifiability. The idea: you don't have to trust the server. You check the proof yourself.
The researchers found that the proof was built on something called a trapdoor commitment scheme. In plain English: the shuffle proof could be made to "verify" correctly even if votes had been silently changed — provided you knew the trapdoor value. And the trapdoor value was held by the system's operators.
In other words, an authority who knew that value could generate a shuffle-proof transcript that passed verification while having rearranged every single ballot. The "universal verifiability" claim was unfalsifiable from the outside.
They named their paper "Ceci n'est pas une preuve." This is not a proof.
Swiss Post and Scytl acknowledged the finding. Swiss authorities suspended the system.
The lesson sounds technical. It isn't. The flaw was invisible for as long as the code was closed. It became findable the moment it was opened. But finding it still required world-class cryptographers working for weeks. The broader question — the one that this post is actually about — is: what happens between "someone can read the code" and "you can be sure the code that was read is what ran on the machine"?
The Swiss case cracked open the code. But it exposed a deeper gap that even open source doesn't automatically close.
Reading the recipe is not the same as tasting the dish
Imagine a restaurant that publishes its recipes. Every ingredient, every technique, every step — all online, all the time.
Now imagine the kitchen is locked. You can read what's supposed to happen. You cannot watch what does happen.
This is precisely the situation with most voting software, even open-source voting software. Publishing source code is a necessary condition for independent verification. It is not a sufficient one.
Here is why. The software you read in a repository is not the software that runs on the machine. Between "source code" and "running program" there is a chain of steps:
- A compiler takes the source and translates it into machine-readable binary code.
- That binary is packaged, installed onto voting hardware or servers, and cryptographically sealed — or not.
- At the moment of the election, a machine boots and runs what's on it.
Each of those steps is a place where the running code can diverge from the source you inspected, with no visible evidence. A compiler can be manipulated to insert code that doesn't appear in the source. A binary can be swapped after it's built. A machine can boot a different version than the one you thought was loaded.
The Swiss trapdoor lived in the source. But a different trapdoor could live anywhere in that chain — and never appear in the code at all.
The reproducible-builds problem, in plain language
There is a discipline in software engineering called reproducible builds. Its goal is simple: given the same source code, the same compiler, and the same build instructions, anyone who runs the build process should get an identical binary — byte for byte, bit for bit — every time.
This matters because it gives you a way to check. If the election authority publishes a binary hash — a unique digital fingerprint of the software on the machine — and if you can independently reproduce that exact same binary from the published source, you have a cryptographic guarantee that the code on the machine is the code you read.
If the binary doesn't match, you know something changed between source and machine. You don't know what changed. But you know to ask.
Without reproducible builds, the gap between "inspected source" and "running software" is invisible. You have no tool to check it. You are back to trusting the authority that did the build.
The Reproducible Builds project — a cross-project effort in the software engineering community — has documented systematically how hard this is to achieve and how many ways the build chain can produce different outputs from identical source. Compilers embed timestamps. Linkers insert environment variables. File ordering varies. Each is a mechanism by which two "identical" builds can produce different binaries without anyone intending fraud.
Attestation: the second half of the problem
Even if your build is reproducible, a second problem remains. Reproducibility proves that someone can reconstruct the same binary from the source. It doesn't prove that the binary now running on your voting machine is that binary.
This is where attestation comes in.
Attestation is the process of cryptographically signing a claim: "This device is running software binary X, built at time T, with hash H." The signature must come from something tamper-evident — ideally from hardware that cannot be overridden by software after boot, such as a Trusted Platform Module (TPM) or a hardware security module. The signed claim can then be checked by anyone who has the public key.
Think of it like a tamper-evident seal on a memory card — except instead of a physical sticker that tears when opened, it's a mathematical signature you can verify without trusting the person handing you the card.
Together, reproducible builds and attestation form a chain: you read the source → you build it and get binary H → you verify the running device is attesting to binary H → you're confident the machine is running the code you read.
Without that chain, you have two unconnected facts: here is the source code and here is a machine running something. Whether those two things correspond is a matter of trust, not verification.
"We run certified, open-source software" is a claim. Reproducible builds and attestation are what make it checkable.
What the Swiss case tells us about the deeper problem
Go back to Switzerland. The researchers found the trapdoor because they read the source. Swiss Post acknowledged the flaw and suspended the system. So far: the system working as intended.
But notice what didn't get checked in any reported version of that story. Even if the trapdoor had not existed in the source, no independent party had a mechanism to confirm that the binary running on the Swiss Post servers was compiled from that exact source — and not from a slightly modified version with a flaw that never appeared in the public code.
That is not a hypothetical. In 2003, computer scientist Ken Thompson, in his Turing Award lecture, described how a compiler could be modified to insert a backdoor into a program automatically — and then further modified to insert the backdoor into itself, so that even compiling the compiler from clean source would produce a compromised binary. The source looks pristine. The compiler looks pristine. The output is trojanized.
This is not an exotic theoretical attack. It is a well-understood class of threat. And the defense against it is reproducible builds: if the output is deterministic and published, any independent party can rebuild from source and detect a discrepancy. If it isn't — if every build produces a different binary for innocent technical reasons — the comparison can never be made.
The Swiss case proved that open source is better than closed source. It also proved that open source, alone, is not enough.
The gap our gap tracker is watching
At TrustVoting, we track a specific gap: the absence, in most fielded voting systems, of publicly verified reproducible builds and device attestation. You can see how often this gap appears, and where, across the world.
The Swiss system had open source. It is one of the most transparency-forward internet voting programs in the democratic world. Researchers still found a flaw in the cryptography — which would have been unfindable in a closed system. And even after that flaw was found and fixed, an independent observer would have no mechanism to confirm that the patched binary on the server was derived from the patched source.
This is the gap. It sits precisely at the seam between the code you can read and the software that actually handles your vote.
A few things that would close it:
- Publicly published build instructions that produce the exact binary hash the authority claims to be running — so any sufficiently technical observer can verify independently.
- Signed attestation from tamper-evident hardware on each voting device, publishing the hash of the running binary alongside each result batch.
- Continuous, post-deployment monitoring against the published hash — so that a software swap that happens after certification but before election day would be detectable.
None of these are exotic. They are standard practice in high-security software deployment. They are largely absent from voting-system certification requirements.
What you still cannot verify today — and what would fix it
Here is the uncomfortable position we are left in after Switzerland 2019.
We know open source is better. The trapdoor was found precisely because the code was readable. A closed system would have shipped the flaw undetected.
We know cryptographic verifiability is better than paper trails alone. The Swiss system's entire design philosophy — universal verifiability, mathematically checkable proofs — is an attempt to let voters confirm, without trusting the authority, that their vote was counted.
And we know both are insufficient if they don't include the bridge between source and running binary.
Right now, for virtually every voting system deployed in the world, the honest answer to "how do I know the software on that machine is the software that was reviewed?" is: you can't. You trust the authority that deployed it.
That trust may be well-placed. But trust is not verification. Germany's Federal Constitutional Court understood this when it ruled in 2009 that electronic voting is only legitimate when ordinary citizens — not just experts — can independently verify each essential step from ballot to result. The court's reasoning applies as sharply to software deployment as it does to vote counting: if confirming that the right code is running requires trusting the people running it, the essential verification step is missing.
The fix is not to tear down open-source voting efforts. It is to complete them. Open source plus reproducible builds plus signed attestation plus publicly published binary hashes equals a system where "the software you inspected is the software that ran" is checkable by anyone with a laptop and curiosity — not just by the authority that deployed it.
Until that chain is closed, every "we use open, certified software" claim is an invitation to trust. And an election system that asks you to trust it, instead of showing you the proof, has not finished solving the problem.
See how the reproducible-builds gap appears across voting systems we track
Read the 2-minute version of this argument
Explore the global map of election-technology verification gaps
Sources
- Lewis, Pereira, Teague — Ceci n'est pas une preuve (trapdoor commitments in the Scytl-SwissPost Internet voting system), 2019
- Bundesverfassungsgericht, Judgment of 3 March 2009, 2 BvC 3/07 and 2 BvC 4/07 (English translation)
- Springall, Finkbeiner, Durumeric, Kitcat, Hursti, MacAlpine, Halderman — Security Analysis of the Estonian Internet Voting System, ACM CCS 2014
- California Secretary of State news release (Aug. 21, 2018): certifying LA County VSAP Tally as California's first certified open-source election technology
- Halderman, Teague — The New South Wales iVote System: Security Failures and Verification Flaws in a Live Online Election, E-Vote-ID 2015 (arXiv:1504.05646)
- Curling v. Raffensperger, No. 1:17-cv-2989-AT, Opinion and Order (N.D. Ga. Oct. 11, 2020), Doc. 964 (Justia)