Accuracy not guaranteed. Neither is Congress's. At least we're honest about it. Always verify at Congress.gov.

Leg day: Fri → Fri (28d) Recess

VoteChain Evidence Board

Bulletin Board Transparency
Diagram Board

How the append-only Merkle tree, signed tree heads, and inclusion proofs create a publicly auditable transparency log for every cast ballot.

Append-Only Verified
Leaf Hash
SHA-256
Tree Type
Binary Merkle
STH Signatures
ECDSA
Append Policy
Append-Only
Domain Separated
Yes

Tree Structure

Merkle Tree Construction

Ballots are hashed into leaves, paired into nodes, and reduced to a single root hash.

Boundary: Public Audit Surface

Boundary: Merkle Builder Runtime

Boundary: Bulletin Board Ingress

canonical JSON payload

leaf hash

leaf hash

leaf hash

leaf hash

Ingress Boundary
Public BB API · HTTPS 443 writes

Ballot Payload
Canonical vote event · append-only queue via HTTPS 443

Leaf Hash Builder
bbLeafHash function · prefixes votechain bb leaf v1 then hashes

Merkle Boundary
DO SQLite tree runtime · append-only build + inclusion serving

Leaf 0
First ballot leaf hash · anchors block zero

Leaf 1
Second ballot leaf hash · anchors block one

Leaf 2
Third ballot leaf hash · anchors block two

Leaf 3
Fourth ballot leaf hash · anchors block three

Node 0-1
Internal Merkle parent · hashes L0 + L1 with node prefix

Node 2-3
Internal Merkle parent · hashes L2 + L3 with node prefix

Root Hash
Tree commitment value · anchors state for STH

Audit Boundary
External verifier access · STH + proof checks via HTTPS 443

Domain Separator Policy
Hash prefix policy · leaf, node, empty prefixes for collision safety

Signed Tree Head
tree_size + root_hash + timestamp + ECDSA sig · immutable snapshot

Inclusion Verifier
Proof replay verification · recomputes sibling path, confirms STH root

Commitment

Signed Tree Head (STH)

Each BB update produces a signed snapshot of the tree state, creating an unforgeable commitment.

tree_size number Count of leaves at signing time
root_hash string (base64url) Merkle root of all leaves
timestamp string (ISO 8601) When the STH was issued
kid string BB key identifier
sig string (base64url) ECDSA signature over canonical JSON of unsigned fields
Verification
verifyB64u(bb.jwk_public, canonicalJson(unsigned), sig)

Sign: signB64u(bb.jwk_private, canonicalJson({ tree_size, root_hash, timestamp, kid }))

Audit

Inclusion Proof Verification

Given a leaf and its index, walk sibling hashes up the tree to the root. If the computed root matches the STH root, the leaf is proven to exist.

1
Start with leaf hash acc = b64uToBytes(proof.leaf_hash)
2
Walk sibling path for each step in proof.path: if step.side == 'left': acc = bbNodeHash(sibling, acc) else: acc = bbNodeHash(acc, sibling)
3
Compare to STH root bytesToB64u(acc) === proof.root_hash

If match: leaf is proven included in the tree at the signed state

PocInclusionProof
leaf_hash string
root_hash string
tree_size number
leaf_index number
path Array<{ side: 'left'|'right', hash: string }>

Timeline

STH History and Monitoring

Each BB append triggers a new STH. Monitors compare STH snapshots to detect equivocation.

STH #1
tree_size: 1, root: ab3f... First ballot appended
STH #2
tree_size: 2, root: 7c1e... Second ballot appended
STH #n
tree_size: n, root: d4f2... Each append grows the tree
Non-equivocation: If two monitors observe different STHs for the same tree_size, the BB operator is cheating. The trust-portal page computes the root independently and compares against the latest STH.

Chain Of Trust

VCL Event Anchoring

Each ballot cast creates a chain: individual ballot to BB leaf to STH to VCL event, providing end-to-end auditability.

Ballot Cast
encrypted ballot + nullifier + credential proof
BB Leaf
bbLeafHash(payload) → leaf_hash
Signed Tree Head
issueBbSth(state) → STH with root + sig
VCL Events
ewp_ballot_cast + bb_sth_published Signed with VCL key, immutable audit trail
The VCL event payload includes sth_root_hash, binding the ballot cast to a specific tree state. Any tampering breaks the signature chain.