Public verifier · SEU
Check the evidence yourself, in your own browser, without trusting this page.
A custody record for a mail ballot is only worth something if a stranger who distrusts everyone involved can check it. This page does the checking on your device. There is no server to ask, no account to make, and no result that depends on us being honest.
Does this page's own arithmetic hold up?
Two independent implementations, checked against each other on load
The reference implementation is Python. The code running in your browser is a separate JavaScript implementation of the same three primitives. When this page loads, the JavaScript recomputes every digest that the Python side produced and compares them. Agreement between two implementations written in different languages is worth considerably more than either one asserting it is correct.
This is not decoration. Cross-language disagreement is the exact failure this
project already suffered once: Python escaped non-ASCII characters to
\uXXXX while JavaScript emitted UTF-8, so the two engines produced
different Merkle roots for the same records while both looked perfectly healthy.
Doña Ana County, New Mexico is a real jurisdiction, and it is the vector that
surfaced it. If the banner above ever turns red, believe the banner.
Tool one
Is my receipt in the published record?
This is the question that matters to a voter or an observer. The answer needs three links to hold, and this tool checks all three separately so you can see which one breaks when one does.
- The record hashes to the event. The sealed event does not contain the record — it contains a digest of it. That is deliberate: the tree can prove a record's presence without publishing its contents. But it means a record is only meaningful if it hashes to the digest the event committed to.
-
The event hashes to a leaf. The leaf is
sha256(0x00 ‖ canonical(event)). The0x00tag separates leaves from interior nodes, which is what stops someone presenting an interior node as though it were a record. -
The leaf climbs to the published root. Each sibling hash in
the proof is combined as
sha256(0x01 ‖ left ‖ right)until one value remains. It either equals the published root or it does not.
Receipt verification
sha-256 onlyThese five batch-seal events are real output from the reference implementation, not hand-written examples. Swap in your own values if you have them.
What the operator claims was sealed.
Note that it carries payload_hash, not the payload. No
voter-identifying content is in the tree.
Sibling hashes, in order, from the leaf upward.
Take this from a signed tree head, not from whoever handed you the receipt. That substitution is the whole attack.
The demonstration chain
| Index | Batch | Jurisdiction | Sealed | Leaf |
|---|
Tool two
Canonical form, and the bug that made it necessary
Two systems that hash "the same" record must agree on its bytes first. If they serialise it differently, they produce different digests and the disagreement is indistinguishable from tampering. fixes two rules that Python and JavaScript would otherwise get wrong in opposite directions.
- Keys sort by UTF-16 code unit. That is what JavaScript does natively; Python sorts by Unicode code point, and the two orders diverge above the Basic Multilingual Plane. The Python side was taught to imitate JavaScript rather than the reverse, because the existing ballot-tracking engine is JavaScript and changing its sort would have invalidated every root it had already published.
- Non-ASCII characters are emitted as UTF-8, never escaped. This is the one that actually bit. Try the Doña Ana vector below and compare the two digests.
Canonical digest
Edit freely. Accented characters are the interesting case.
Tool three
Who published this root, and when
An inclusion proof shows a record is under some root. A signed tree head is what binds a named key holder to that root at a stated tree size, so they cannot later publish a different history and claim it was always so. This tool verifies the Ed25519 signature.
On browser support. Ed25519 through WebCrypto is recent and not universal. Where it is unavailable this tool says so and refuses, rather than shipping a hand-written elliptic-curve implementation and inviting you to trust it. Everything else on this page needs only SHA-256 and works everywhere.
Signed tree head
ed25519The signature covers the canonical form of every field except the signature itself.
Tool four
Who audits the auditor, and why they cannot be chosen
A jurisdiction cannot credibly verify itself, and a verifier that the subject selected is not a verifier. So the roster is drawn from a national pool by a published random beacon, after the roster is committed to and before the beacon value is known. Recompute it here: given the same roster and the same beacon, the selection is forced.
- The subject is recused absolutely. A state never appears among its own verifiers, under any parameters.
- No jurisdiction fills two seats. One state government cannot supply two verifiers of the same operation, so capturing a single state's apparatus is not enough.
- The system refuses rather than degrades. If the pool cannot fill every seat, the draw fails with a named refusal instead of quietly seating fewer verifiers. Set agencies-per-role high enough and you can watch it refuse.
Recompute the draw
The one being verified. It is recused.
Three is the design figure.
Published after the roster is committed.
Why three per role and not one. If a share
p of the pool is compromised, the chance that every seat in a
role lands on a compromised agency is roughly
p2d at d agencies per role. At one in ten
corrupt, one agency per role gives about 1 in 100 — far too weak to rest an
election on. Three per role gives about 1 in a million. That is the entire
argument for the number.
The state machine
What a ballot is allowed to do, and two things it is not
Every custody event moves a ballot along a permitted edge or is refused. Two edges present in an earlier implementation have been removed, and both removals came from the project's own written specification rather than from anyone's preference. They are marked in red below.
The path a ballot normally takes
Most ballots walk this line and nothing else happens to them. The matrix below is the complete rule set, including every exception.
Every from-and-to pair, exhaustively
Read a row as the state a ballot is in and a column as where it is being asked to go. Column numbers match the row numbers. Hover any mark for the exact rule.
Conflicts resolved, and on whose authority
Where two of the project's own implementations disagreed, the specification decided it and the implementation was recorded as the defect. Nothing here was settled by picking whichever behaviour was easier to build.
| Ref | Edge | Resolution | Reason | Authority |
|---|
Limits
What this cannot tell you
A verifier that overstates its reach is worse than none, because it converts honest doubt into misplaced confidence. Everything in this list is a real limit of the design, not a to-do item.
A verified root does not mean the records are true. It means nobody altered them after sealing. If a false record was sealed at the beginning, it will verify perfectly forever. Cryptography fixes tampering after the fact; it does not fix lying at the moment of entry. That is what physical custody, witnesses, and reconciliation against paper are for.
Not a ballot-casting system
Nothing here lets anyone vote online
This tracks the custody of physical mail ballots. It never transmits a vote, and it never becomes a way to cast one. That boundary is deliberate and permanent.
Not a voter database
No voter identity is in the tree
Events commit to a hash of their payload and reference ballots by opaque handles. You can prove a batch was sealed without publishing who was in it.
Witnesses, not authorizers
A lock, not a vote
Drawn agencies attest that a procedure was followed. They do not approve results, and they hold no authority over any jurisdiction's count. No software in this system is a legal authorizer, and neither is any automated agent.
Uncertainty is preserved
Nobody can click a record into being verified
A record whose provenance is uncertain stays uncertain. There is no acknowledgement, override, or approval that promotes it, because a confirmation button is not evidence.
Fails closed
Where authority is unresolved, nothing proceeds
Several questions here are matters of law rather than engineering, and they are genuinely unsettled. The system refuses in those cases. It does not invent authority in order to make a build pass.
Postal data is advisory
Carrier scans never gate anything
Mail tracking is useful context and an unreliable authority. It is recorded and shown; it never decides whether a ballot counts.
The unresolved legal question, stated plainly
Cross-state verification needs a legal basis, and the obvious precedent does not quite reach. The Emergency Management Assistance Compact — congressionally consented as Public Law 104-321 in October 1996, and a member compact of all fifty states plus the District of Columbia, Puerto Rico, the Virgin Islands and Guam per the compact's public record — already solves the hardest problem, which is legal standing: its Article VI makes visiting officers agents of the requesting state for liability and immunity purposes, excepting wilful misconduct, gross negligence or recklessness.
But EMAC is scoped to declared emergencies. Routine verification of an ordinary election is not an emergency, and pretending otherwise would be both dishonest and legally fragile. So EMAC is cited here as a working model and explicitly refused as an authority. A separate compact is required, and until states enact one this part of the design does not operate. The code says so too: the EMAC template in the reference implementation is flagged as not covering routine verification, and cannot be configured otherwise.
Published values
- Merkle root of the demonstration chain
- Tree size
- Epoch
- Signing public key
- Canonical form version
- Lifecycle version
The chain above is a demonstration built from the reference implementation so that the tools have something real to chew on. It is not a live election record, and this page does not claim otherwise.