# Elections on Quidnug
> **Government · Voting · Registration · Universal verifiability · Bring-your-own-identity**
Category: Government
Source: https://github.com/bhmortim/quidnug/tree/main/UseCases/elections
# Elections on Quidnug

**Government · Voting · Registration · Universal verifiability · Bring-your-own-identity**

> A complete design for running a public election on Quidnug:
> voter registration, poll books, ballot anonymity, universal
> verifiability, and instant recount, with no central database
> anyone has to trust, no proprietary voting machine, and a
> paper-ballot fallback that cryptographically matches the
> digital record.

> **This README covers the protocol-level semantics. The
> companion docs cover the operational story that turns this
> design into a deployable system:**
>
> - [`integration.md`](https://github.com/bhmortim/quidnug/blob/main/integration.md), how the design
>   composes on top of the three architectural pillars (QDPs
>   0012 / 0013 / 0014). The governance, multi-jurisdictional
>   federation, and operational topology layers this README
>   only sketches.
> - [`operations.md`](https://github.com/bhmortim/quidnug/blob/main/operations.md), deployment at five
>   scales (pilot to federal), capacity planning, election-day
>   operations, incident response, cost analysis.
> - [`launch-checklist.md`](https://github.com/bhmortim/quidnug/blob/main/launch-checklist.md), sequential
>   T-180 through T+30 go-live checklist.
>
> If you're new to Quidnug as a whole, read
> [`../ARCHITECTURE.md`](https://github.com/bhmortim/quidnug/blob/main/../ARCHITECTURE.md) first, it
> places the elections use case in the broader protocol
> context. Elections is the most complex worked example of a
> coordination-archetype use case; its depth of trust-edge
> semantics and multi-party governance pushes the protocol
> harder than any other use case in the library.

---

## The problem

US elections today are run on a patchwork of systems:

- **Voter registration databases** sit in each state's SOS
  office. The voter has to trust that the DB hasn't been edited,
  corrupted, or subjected to a data-entry error.
- **Poll books** at each precinct are either printed that morning
  (static, can't be rechecked during the day) or "electronic poll
  books" running vendor software the public cannot audit.
- **Voting machines** run closed-source firmware. Public's ability
  to verify their behavior is negligible.
- **Counting** is done by proprietary tabulation software. Recounts
  require physical re-scanning of paper ballots on the same
  machines, i.e. re-running the same vendor software.
- **The public audit story is** "trust the bipartisan election
  boards and approved vendors." Which is reasonable but obviously
  not cryptographically verifiable.

Independent observers, candidates losing close races, and
ordinary citizens have **no technical path** to:

- Personally verify the voter roll is correct.
- Know that poll books at a specific precinct match the authorized
  voter list.
- Verify their own vote was recorded as cast and counted as
  recorded.
- Recount an election themselves without waiting for officials.
- Audit a single ballot from paper through to final tally.

Quidnug's primitives, signed trust edges, per-signer monotonic
nonces, guardian-recoverable keys, per-observer relational trust,
and public append-only event streams, map directly onto what an
election protocol needs. This document specifies a complete
design.

---

## Design principles

Before the mechanics, here's what the design commits to:

| Property                       | Commitment                                                                                             |
|--------------------------------|--------------------------------------------------------------------------------------------------------|
| **Secret ballot**              | No party can correlate a specific cast vote with the voter who cast it, not even the election authority. |
| **Universal verifiability**    | Any member of the public can cryptographically verify the tally from primary data. No special access.    |
| **Individual verifiability**   | Every voter can verify their own vote was counted as they intended, from their own records.              |
| **Eligibility verification**   | Only registered voters can cast ballots; every ballot cast traces to an eligibility attestation.         |
| **One voter, one vote**        | Cryptographic double-vote prevention; no "poll worker discovers it later."                                |
| **Bring-your-own-identity**    | Voter's cryptographic identity is generated by the voter, not issued by the authority.                   |
| **Paper-ballot parity**        | Every digital vote has a paper-ballot equivalent printed at cast time and deposited in a ballot box.     |
| **Recount on demand**          | Anyone, candidate, journalist, citizen, can run a full recount in seconds from the public chain.       |
| **Coercion resistance**        | (Trade-off, addressed in §11.) A voter should not be able to cryptographically prove to a third party how they voted. |
| **Tamper-evident audit**       | Every protocol action is signed and append-only; after-the-fact edits leave evidence.                    |

These aren't aspirations. Each maps to specific mechanisms below.

---

## The 5 quid types in an election

Quidnug elections use five distinct kinds of quids. Keeping them
separate is what gives the design its properties.

### 1. Election Authority Quid (`election-authority-*`)

The government body running the election. Examples:

- `election-authority-williamson-county-tx-2026-nov`
- `election-authority-state-of-ohio-2028-primary`

Each election is its own quid, a new quid per election cycle
rather than one persistent "elections office" quid. This scopes
authority cleanly: a fresh election's keys can't be used to
manipulate a prior election's records.

Under [QDP-0012 Domain Governance](https://github.com/bhmortim/quidnug/blob/main/../../docs/design/0012-domain-governance.md),
the authority's authority-to-act is expressed through two
distinct mechanisms that the original version of this document
conflated. Both are needed; they do different things.

**Governor quorum for the election's domains** (QDP-0012): the
humans / institutions authorized to vote on changes to the
consortium roster + parameters of the election's domain tree.
Typically:

- Chief election official (e.g., county clerk)
- State Secretary of State office
- Bipartisan oversight board (one D-aligned, one R-aligned, one independent)
- Panel of independent election observers (League of Women Voters, etc.)

Recommended structure: 7 governors with weighted votes, 5-of-7
weighted quorum for routine governance actions, unanimous for
`UPDATE_GOVERNORS`. Notice period 72 hours normally; with a
pre-negotiated 1-hour emergency-notice clause active during the
week of the election for `REMOVE_VALIDATOR` actions against
compromised consortium members. See
[`integration.md`](https://github.com/bhmortim/quidnug/blob/main/integration.md) §2 for the concrete setup.

**Guardian quorum per governor key** (QDP-0002): each individual
governor's cryptographic identity has its own M-of-N guardian
set for recovering a lost or compromised key. Guardians are
independent parties trusted for that specific role (spouse,
lawyer, federal monitor, state ethics officer, etc.), not the
same people as the governor quorum. Losing a governor's key
doesn't lose their position, guardians rotate the key to a
fresh one, typically over a 24-hour time-lock.

The two mechanisms serve different purposes: governor quorum
authorizes policy changes; guardian quorum recovers individual
keys. Elections need both.

### 2. Voter Registration Quid (VRQ)

One per registered voter. **Generated by the voter**, not issued
by the authority (this is the Bring-Your-Own-Quid principle).

- Voter generates a keypair on their device (phone, hardware
  token, or at a voter-registration kiosk under their control).
- The quid ID is `sha256(voter's public key)[:16]`.
- Voter keeps the private key; the authority never sees it.

VRQ attributes (public):
- `precinctID`
- `registeredParty` (for primary elections)
- `registrationYear`
- Nothing else, no SSN, no address, no DOB on-chain.

Real-world identity (name, address, DOB) is held **off-chain** by
the election authority in a separate secure database, mapped
one-way to the VRQ. Queries like "is this quid registered?" are
public; queries like "what is this quid's name?" require the
off-chain DB and legitimate access.

### 3. Ballot Quid (BQ)

One per voter per election, but **generated fresh at voting
time**, not persistent.

- Anonymous by construction.
- No on-chain link to the VRQ it corresponds to.
- Voter generates it locally; the authority signs a **blind
  attestation** that it is eligible to vote (see §6 below).

The BQ is how the voter actually votes. It casts trust edges to
candidates/options.

### 4. Contest Quid

One per contest on the ballot. A "contest" is a single voting
decision.

- `contest-williamson-2026-us-senate`
- `contest-williamson-2026-proposition-5-sales-tax`
- `contest-williamson-2026-sheriff`

Contest attributes:
- Title, description, precincts eligible to vote
- Voting method: `plurality`, `ranked-choice-irv`, `approval`,
  `rated-3-star`, `yes-no`
- Candidates (list of quids)
- Start / end times
- Certification deadline

### 5. Candidate Quid

One per candidate or ballot option. Candidates are real quids
(generated by the candidate themselves when they filed candidacy);
ballot options like "YES" and "NO" on propositions are
well-known quids per jurisdiction (e.g.,
`option-yes-williamson-2026` and `option-no-williamson-2026`).

A write-in candidate's quid can be issued on-the-spot by a voter
who specifies a name; write-ins are flagged differently in the
tally.

---

## Domain hierarchy

Everything election-related lives under a carefully-scoped
namespace:

```
elections.<jurisdiction>.<year-cycle>.registration        (voter roll)
elections.<jurisdiction>.<year-cycle>.poll-book.<precinct> (per-precinct roll)
elections.<jurisdiction>.<year-cycle>.ballot-issuance     (eligibility attestations)
elections.<jurisdiction>.<year-cycle>.contests.<contest>  (votes cast per contest)
elections.<jurisdiction>.<year-cycle>.tally              (official tally events)
elections.<jurisdiction>.<year-cycle>.audit              (audit observations)

For primaries:
elections.<jurisdiction>.<year-cycle>.primary.<party>.contests.<contest>
```

Concrete example: Williamson County, Texas, November 2026 general:

```
elections.williamson-county-tx.2026-nov.registration
elections.williamson-county-tx.2026-nov.poll-book.precinct-042
elections.williamson-county-tx.2026-nov.ballot-issuance
elections.williamson-county-tx.2026-nov.contests.us-senate
elections.williamson-county-tx.2026-nov.contests.governor
elections.williamson-county-tx.2026-nov.contests.proposition-5
```

Each domain has its own **consortium** (the election authority
+ observer organizations running physical nodes that produce
blocks; see [QDP-0012](https://github.com/bhmortim/quidnug/blob/main/../../docs/design/0012-domain-governance.md)
for the cache-replica / consortium-member / governor role
separation). Consortium membership is granted by on-chain
`ADD_VALIDATOR` governance transactions signed by the governor
quorum, not self-declared, new operators join the consortium
by policy action, not by spinning up a node.

Vote edges in `contests.us-senate` only count if the edge
signer (the BQ) has a valid ballot issuance in
`ballot-issuance`. This eligibility check is cryptographic and
runs at tally time; nothing in the consortium can bypass it.

**Cache replicas** (typically precinct polling-place devices
plus any observer / journalist / candidate running a mirror)
trust the consortium, mirror the agreed chain locally, serve
reads, and relay transactions, but do not produce blocks.
This keeps the number of block-producing nodes small and
governance-controlled while letting the read-serving
infrastructure scale out cheaply.

---

## Replacing the voter registration system

Today's voter registration is a centralized state database. In
Quidnug it's a public, append-only set of trust edges from the
election authority to voter quids.

### Registration flow (Bring-Your-Own-Quid)

```
Step 1. Voter generates a quid
────────────────────────────────
  On their phone, hardware token, or at a voter-registration
  kiosk they physically control:

    $ quidnug-voter generate
    Your quid ID: a1b2c3d4e5f67890
    Save your private key: <securely stored locally>

  The voter's private key never leaves their device.

Step 2. Voter visits a registrar
────────────────────────────────
  Brings: driver's license / passport / other identity document.
  Registrar verifies real-world identity.

  Registrar enters into their internal system:
    - Name, DOB, address (off-chain DB)
    - Voter's quid ID (from QR code / NFC from voter's device)
    - Precinct (derived from address)
    - Party affiliation (if applicable)

Step 3. Registrar issues the registration
────────────────────────────────
  The election authority's signing service emits a trust edge:

    TRUST:
      truster: "election-authority-williamson-2026-nov"
      trustee: "voter-a1b2c3d4e5f67890"        (voter's VRQ)
      trustLevel: 1.0
      domain: "elections.williamson-county-tx.2026-nov.registration"
      attributes:
        precinct: "042"
        registeredParty: "democratic"
        registrationTimestamp: 1713400000
      validUntil: <next election cycle + 1 year>
      nonce: <next registration nonce>

  The edge is signed by the authority's current-epoch key.

Step 4. Voter can verify they're registered
────────────────────────────────
  From any public Quidnug node:

    $ quidnug-voter check-registration voter-a1b2c3d4e5f67890
    ✓ Registered in: elections.williamson-county-tx.2026-nov.registration
    ✓ Precinct: 042
    ✓ Party: democratic
    ✓ Valid until: 2027-12-31

  The voter did not need to visit the registrar's website or
  trust their proprietary portal. Any Quidnug node has the same
  answer.
```

### How bring-your-own-quid defends against malfeasance

Because the voter generates the quid, the authority cannot:

1. **Assign a voter a quid they control** (and vote as that voter).
   If the authority tried, the voter would detect it, their
   registered quid wouldn't match the public key they generated.

2. **Silently change a voter's quid** (de-registering them).
   Any modification to the registration trust edge requires the
   authority's current-epoch signature. A change without a
   corresponding event on the voter's stream is auditable.

3. **Deny registration arbitrarily**. If the authority refuses to
   issue the trust edge, the voter has a cryptographic record of
   their attempt (they submitted their quid and ID) and the
   refusal is visible to observers.

The authority CAN legitimately deny registration for cause
(ineligibility, duplicate), but that denial is documented as
a signed event, not a silent database omission.

### Anyone can count registered voters

```bash
# Anyone, from any Quidnug node with visibility into the domain:
curl "https://any-node/api/v1/trust/edges?domain=elections.williamson-county-tx.2026-nov.registration&truster=election-authority-williamson-2026-nov" | jq 'length'
# -> 142,847
```

This number matches the authority's count, because it is the
authority's count. There is no separate "authoritative database"
that could disagree.

---

## Replacing poll books

A poll book is the per-precinct list of voters authorized to cast
ballots at that precinct. In Quidnug, this is not a separate
document, it's a **query** against the registration trust edges
filtered by precinct.

```bash
# Poll book for precinct 042, as used by a poll worker's tablet
curl "https://precinct-042-node/api/v1/trust/edges?\
  domain=elections.williamson-county-tx.2026-nov.registration&\
  precinct=042"
```

This returns every VRQ registered at precinct 042. The poll
worker's tablet caches this for the morning and refreshes
throughout the day via push gossip (QDP-0005). Unlike printed
poll books, the digital poll book reflects **late registrations
and corrections** in real time.

### Check-in at the polling place

When a voter arrives:

```
Step 1. Voter identifies themselves
  Shows driver's license or other ID.
  Poll worker looks up off-chain by name → retrieves associated
  VRQ (e.g., "voter-a1b2c3d4e5f67890").

  Alternative: voter scans a QR code from their wallet app that
  contains their VRQ ID + a freshly-signed challenge proving they
  hold the private key.

Step 2. Poll worker's tablet verifies eligibility
  Queries the local Quidnug node:
    "Does voter-a1b2c3d4e5f67890 have a registration trust edge in
     precinct 042 for this election, and is it active?"

  Additionally checks:
    "Does this VRQ have a `voter.voted` event for this election?"
  If yes → voter has already voted; reject (or route to provisional
  if they claim otherwise).

Step 3. Poll worker emits a check-in event
  (ONLY a "voted" flag, reveals nothing about what they voted for)

    EVENT:
      subjectId: "voter-a1b2c3d4e5f67890"
      subjectType: "QUID"
      eventType: "voter.checked-in"
      payload:
        electionId: "elections.williamson-county-tx.2026-nov"
        precinct: "042"
        checkedInAt: 1713400000
      signer: poll-worker-quid

Step 4. Voter moves to ballot issuance
  (See next section.)
```

The `voter.checked-in` event is **public** but only reveals the
fact of voting, not the contents. This is equivalent to the
"I voted" sticker and the public fact of showing up to the polls.
Some jurisdictions prefer not to record even this; the protocol
supports both modes via an election-authority config flag.

---

## Ballot anonymity: the blind-signature issuance flow

This is the critical piece. The voter is already publicly
checked-in. Now we need them to cast a vote that **cannot be
correlated with their VRQ**, while **still proving the vote is
authorized**.

The mechanism is a **blind signature**: the election authority
signs an attestation that a specific Ballot Quid (BQ) is
authorized to vote, but the authority never learns which BQ it
signed.

### Cryptographic primer (blind signature, in plain language)

Think of a blind signature as an opaque envelope with carbon
paper inside.

1. Voter writes their BQ's ID on a piece of paper, seals it in
   the envelope.
2. Authority signs the **outside of the envelope**. The signature
   bleeds through the carbon paper onto the BQ ID inside.
3. Voter opens the envelope. Their BQ ID now has the authority's
   signature on it, but the authority never saw the ID itself.

Cryptographically: voter generates BQ ID `bq_id`, picks a random
blinding factor `r`, computes `blind(bq_id, r) = commitment`.
Authority signs `commitment`. Voter computes
`unblind(signature, r) = valid-signature(bq_id)`. Authority's
signature is on `bq_id` but they never saw `bq_id` unblinded.

Quidnug uses ECDSA P-256; blind signatures on ECDSA curves are
well-studied (RSA blind signatures are the classical form;
Schnorr and EC variants exist). An election-authority node runs
a **Ballot Issuance Service** that implements the blind-signature
protocol.

### Ballot issuance flow

```
Step 1. Voter's device generates a fresh BQ
  Happens inside the voting booth or on the voter's phone in a
  private polling place kiosk.

    $ quidnug-voter-booth generate-ballot-quid
    BQ ID: ballot-Xz7mN2pQ8rK4vL9t
    BQ private key: <stored locally, in voter's wallet app>

  Voter may generate multiple BQs, one per contest, or one per
  election, depending on jurisdiction. Using separate BQs per
  contest provides stronger anonymity (attacker can't cross-
  correlate the voter's votes in different contests).

Step 2. Voter blinds the BQ ID
  Device computes:
    commitment = blind(BQ_ID, random_r)

  The voter's device keeps `random_r` locally.

Step 3. Voter submits commitment to the Issuance Service
  Authenticates with the VRQ's private key + the check-in event:

    POST /api/v2/elections/issue-ballot
    Headers: signed-with-vrq-key
    Body:
      electionId: "elections.williamson-county-tx.2026-nov"
      commitment: <blinded BQ commitment>
      contestId: "contests.us-senate"        (one call per contest)
      nullifier: <one-time secret derived from VRQ + contest>

  Issuance service verifies:
    - VRQ is registered in the election
    - VRQ has checked in (at polling place) or is otherwise eligible
      (mail-in, absentee)
    - For THIS contest, this VRQ has not already been issued a ballot
      (nullifier not yet seen in the issuance domain)
    - Party affiliation matches, for primaries

  If OK, service emits:
    EVENT:
      subjectId: "voter-a1b2c3d4e5f67890"
      subjectType: "QUID"
      eventType: "ballot.issued"
      payload:
        electionId: ...
        contestId: "contests.us-senate"
        nullifier: <the same nullifier the voter submitted>
      signer: election-authority

  And returns to the voter:
    signature_over_commitment (the "blinded signature")

  Now everyone can see "this VRQ received a ballot for this
  contest" but no one can see the BQ ID.

Step 4. Voter unblinds
  Device computes:
    unblinded_sig = unblind(signature_over_commitment, random_r)

  This is a valid authority signature on the BQ_ID that nobody
  else has ever seen, including the authority.

Step 5. Voter's BQ now has its eligibility attestation
  Locally, the voter's device builds:
    BQ "identity transaction":
      quidId: "ballot-Xz7mN2pQ8rK4vL9t"
      publicKey: <BQ's public key>
      creator: "election-authority-williamson-2026-nov"
      attributes:
        electionId: ...
        contestId: "contests.us-senate"
        issuanceEpoch: 0
      signature_from_authority: <unblinded_sig>

  This identity transaction can be submitted to a Quidnug node
  to register the BQ. The authority's signature verifies as
  normally, they signed it, even though they don't know they did.
```

### Why this works

- **Anonymity:** The authority signed the commitment but not the
  BQ ID. Anyone (including the authority, a subpoena'd authority,
  a hacked authority) cannot correlate BQs back to VRQs. The
  blinding factor is only on the voter's device.

- **Uniqueness:** The authority saw the VRQ + contest combination
  and the nullifier. If the voter tries to request another ballot
  for the same contest, the nullifier is already seen → rejected.
  One ballot per (VRQ, contest).

- **Authority compromise-resistant:** Even if the authority's
  signing key is stolen and the attacker tries to forge ballots,
  they can't retroactively attach themselves to an already-cast
  BQ. Rotation + invalidation of the compromised epoch are
  standard Quidnug responses.

### Mail-in / absentee variant

Same flow. Voter receives a mail-in ballot packet that contains:
- A URL / QR to the issuance service.
- Instructions to generate a BQ on their home computer.
- Their identity challenge (based on registered info).

The blind-signature flow happens over HTTPS. Voter casts votes
online, then prints a paper confirmation that gets mailed back
(see §9 Paper-ballot parity).

---

## Casting a vote: "trust" as the voting primitive

Once the voter has a BQ with an authority-signed eligibility
attestation, casting a vote is **a trust edge from the BQ to a
candidate**.

```
Plurality vote (most US elections):
  TRUST:
    truster: "ballot-Xz7mN2pQ8rK4vL9t"        (voter's BQ)
    trustee: "candidate-jane-smith-2026"      (candidate's quid)
    trustLevel: 1.0                            (unit vote)
    domain: "elections.williamson-county-tx.2026-nov.contests.us-senate"
    nonce: 1
    signature: <signed with BQ's private key>
```

One trust edge = one vote.

### Ranked-choice voting

```
1st choice: trustLevel = 1.0
  truster: "ballot-Xz7m..."
  trustee: "candidate-jane-smith"
  trustLevel: 1.0
  domain: "...contests.us-senate"

2nd choice: trustLevel = 0.8
  truster: "ballot-Xz7m..."
  trustee: "candidate-bob-jones"
  trustLevel: 0.8
  domain: "...contests.us-senate"

3rd choice: trustLevel = 0.6
  truster: "ballot-Xz7m..."
  trustee: "candidate-carol-li"
  trustLevel: 0.6
  domain: "...contests.us-senate"
```

The tally algorithm interprets the levels as ranking positions.

### Approval voting

Multiple trust edges at 1.0 each:

```
trust: BQ → candidate-A at 1.0
trust: BQ → candidate-B at 1.0
trust: BQ → candidate-C at 1.0
(all in the same contest domain)
```

### Yes/no proposition

```
TRUST:
  truster: "ballot-Xz7m..."
  trustee: "option-yes-williamson-2026"
  trustLevel: 1.0
  domain: "elections.williamson-county-tx.2026-nov.contests.proposition-5"
```

### Why vote validity is cryptographically enforced

When the tally engine counts trust edges in a contest's domain,
it applies these checks for each edge:

1. **Truster must be a valid BQ.** The truster quid's identity
   transaction must be signed by the election authority's key
   for this election. (Rules out random people trying to vote
   as imaginary BQs.)
2. **BQ must have a ballot.issued event on a VRQ.** Wait, no,
   the BQ has no link to a VRQ. What the tally verifies is that
   the BQ's identity transaction carries a valid authority
   signature (the unblinded one from issuance). That's the
   eligibility proof.
3. **One trust edge per BQ per contest** (for plurality) / edges
   match the contest's voting method (for ranked / approval).
4. **Domain matches the contest.**
5. **Signed with the BQ's private key** and well-formed.

If any check fails → the edge doesn't count.

---

## Paper-ballot parity

Digital-only voting is a hard sell, and rightly so. The design
gives every digital vote a paper-ballot counterpart.

### At the in-person polling place

Voting booth has a printer. When the voter finishes casting their
BQ's trust edges (steps above), the booth:

1. Prints a paper ballot with:
   - The voter's BQ ID printed as QR + human-readable hex.
   - A table of contests and the votes cast.
   - The authority's signed issuance attestation as QR.
   - A ballot sequence number.
2. The voter reviews the paper ballot.
3. Voter drops the ballot into a physical ballot box.

```
┌──────────────────────────────────────────────────────┐
│      Official Paper Ballot, Williamson County TX    │
│      General Election, 2026-11-03                    │
│                                                        │
│  Ballot ID (QR): ballot-Xz7mN2pQ8rK4vL9t              │
│                                                        │
│  Contest: US Senate                                    │
│    Your vote: Jane Smith                              │
│                                                        │
│  Contest: Governor                                     │
│    Your vote: (no vote)                               │
│                                                        │
│  Contest: Proposition 5 (Sales Tax)                    │
│    Your vote: YES                                      │
│                                                        │
│  Authority issuance proof (QR): <compact blob>        │
│  Sequence #: 00142-0042                                │
└──────────────────────────────────────────────────────┘
```

### Cross-verification

At the end of the day, the physical ballot box is opened and
every paper ballot is hand-scanned (or can be hand-verified
visually). Each paper ballot has a BQ ID. Cross-verification:

- Every scanned paper BQ ID should have a matching set of trust
  edges in the digital chain.
- Every digital BQ that voted should have a matching paper
  ballot in the box.
- Any mismatch is a discovered discrepancy, investigated per
  jurisdiction procedure.

Because the BQ is pseudonymous (anonymous to the authority, but
the voter's own device can identify their own ballot), the voter
can privately verify the paper ballot in the box matches their
digital vote (by retrieving their own BQ ID).

### What this gives us that pure-paper doesn't

Traditional paper ballots: counted by hand or by the same
proprietary tabulator each time. A recount re-counts the same
pile of paper by the same process.

Quidnug paper ballots: **every paper ballot has a public
digital counterpart**. A recount can be done by:
- Re-scanning paper and comparing to digital.
- Re-running the digital tally from the chain (takes seconds).
- Comparing two digital tallies from two independent Quidnug
  nodes (they should agree exactly).
- Hand-counting paper per standard procedures.

All four should agree. Disagreement points to a specific
discrepancy that can be investigated, not "the machine said so."

### What this gives us that pure-digital doesn't

A skilled attacker could, in principle, compromise enough
validators or gossip nodes to attempt to manipulate the digital
record. The paper ballots are the ground truth:

- If every paper ballot cross-references a digital record, and
  the digital tally matches paper hand-count, the election is
  verified.
- If they disagree, **the paper wins.** The digital chain is a
  convenience layer for instant tally, not the ultimate record.

---

## Counting and recounts

This is where Quidnug shines. A recount is a trivial query.

### Official initial tally

Pollclose time. The election authority runs the tally from its
own view of the chain:

```bash
# Pseudocode, actual implementation in §Implementation
GET /api/v1/trust/edges?\
  domain=elections.williamson-county-tx.2026-nov.contests.us-senate

Group by trustee:
  candidate-jane-smith    47,282 edges
  candidate-bob-jones     51,039 edges
  candidate-carol-li      21,476 edges
  Total: 119,797 votes

Emit:
  EVENT:
    subjectId: contests.us-senate (the contest quid)
    subjectType: QUID
    eventType: contest.tallied
    payload:
      tallyResult:
        jane-smith: 47282
        bob-jones: 51039
        carol-li: 21476
      totalVotes: 119797
      method: plurality
      firstPlace: candidate-bob-jones
    signer: election-authority
```

### Anyone's recount

**Any member of the public** with access to a Quidnug node serving
this election's domain can run the exact same query. The node
returns the same edges. The grouping produces the same counts.

```bash
# From a citizen's laptop running a read-only Quidnug node
$ quidnug tally \
    --domain elections.williamson-county-tx.2026-nov.contests.us-senate \
    --method plurality
  candidate-jane-smith:  47,282
  candidate-bob-jones:   51,039
  candidate-carol-li:    21,476

$ # The result is deterministic given the chain state. Independent
$ # nodes will produce byte-identical tallies.
```

**Candidate recounts:** the losing candidate's team runs their
own Quidnug node, fetches the chain, and tallies themselves.
No "wait for the Secretary of State to authorize a recount."
No "re-feed paper through the same tabulator."

**Multiple-node agreement:** by running the tally on 10 independent
Quidnug nodes, the candidate's team verifies the chain itself
hasn't been tampered with. If 10 nodes agree on 51,039 for Jones,
that's cryptographic evidence of the network consensus, not
"the SOS said so."

### Discovered discrepancies

If a candidate's independent tally disagrees with the authority's
declared result, that's a major red flag. Two causes:

1. **Chain tampering somewhere**, investigated via cross-node
   comparison. Quidnug's K-of-K bootstrap (QDP-0008) and cross-
   node gossip (QDP-0005) make undetected tampering hard.
2. **Tally-method interpretation differences**, contest-specific
   rules (e.g., how ranked-choice instant-runoff handles
   exhausted ballots) should be explicit in the contest's
   attributes. Any ambiguity is a contest-specification bug.

---

## Individual voter verification

Every voter can verify, from their own records, that their vote
was cast and counted as they intended.

After voting, the voter's device retains:
- Their BQ ID(s) and private key(s).
- The authority's issuance attestation.
- A local record of the trust edges they cast (which candidates,
  which contests).

Any time after election day:

```bash
$ quidnug-voter verify-my-vote
  My ballot BQ: ballot-Xz7mN2pQ8rK4vL9t
  Election: elections.williamson-county-tx.2026-nov

  Casting evidence:
    ✓ Issuance attestation signed by election-authority-...
    ✓ BQ published on chain at block 123,456

  Votes I cast:
    Contest: US Senate
      ✓ Trust edge BQ → candidate-jane-smith @ level 1.0, ON CHAIN
    Contest: Proposition 5
      ✓ Trust edge BQ → option-yes-williamson @ level 1.0, ON CHAIN

  Tally result for US Senate:
    Jane Smith: 47,282 votes (my vote counted in this pool)
```

The voter:
- Sees their BQ cast the trust edges they expected.
- Confirms the authority's tally included those edges.
- Knows this from reading the public chain, no special portal
  required.

### Coercion-resistance trade-off

The same verifiability that lets a voter check their own vote
can also be misused by a coercer: "Show me your BQ private key
so I can verify you voted the way I told you to."

Mitigations (any jurisdiction can choose their level):

1. **Do-nothing mitigation:** accept that coercion happens, rely
   on criminal penalties + witness protection + ballot-booth
   privacy. This is what most current systems do.
2. **Multiple-ballot receipts:** voter's device generates N
   plausible BQs, only one of which is cast. Voter can show the
   coercer any of the N, so the coercer can't distinguish the
   real vote from the decoys. Requires careful UI design.
3. **Revocable ballots:** voter can re-cast later, only the last
   ballot counts. Coercion pressure is limited to final deadline.
   Trade-off: operational complexity + late-vote issues.
4. **Homomorphic voting** (future research): the tally is computed
   over encrypted ballots; individual ballots are never revealed.
   Voter's receipt shows only "my ballot was counted" but not
   what it was. Requires protocol extension beyond Quidnug's
   current primitives.

The v1 recommended approach: mechanism #2 (multiple decoy BQs)
combined with mechanism #1 (legal protections). Decoy BQs don't
cast votes, they're generated for receipt-freeness only. The
voter's actual cast BQ is chosen privately.

---

## Party affiliation and primaries

US primary elections are party-scoped. Registered Democrats vote
in the Democratic primary; registered Republicans in the
Republican primary; unaffiliated voters (in some states) get to
choose.

In Quidnug:

### Party-scoped trust edges

The voter's registration trust edge includes a `registeredParty`
attribute:

```
TRUST:
  truster: election-authority-williamson-2026-nov
  trustee: voter-a1b2c3d4e5f67890
  domain: elections.williamson-county-tx.2026-nov.registration
  attributes:
    registeredParty: "democratic"
    precinct: "042"
```

### Party-scoped domain for primary contests

Democratic primary contests live in a party-scoped sub-domain:

```
elections.williamson-county-tx.2026-primary.democratic.contests.us-senate-primary
elections.williamson-county-tx.2026-primary.republican.contests.us-senate-primary
```

### Party-gated ballot issuance

When a voter requests a ballot for a primary contest, the
issuance service checks:

```
voter.registeredParty == contest's party scope?
  Democratic voter requests Democratic ballot → OK
  Democratic voter requests Republican ballot → rejected
  Unaffiliated voter in open-primary state → they pick at issuance; their choice is recorded in an event, the issuance proceeds on that party's side
```

This enforces party-appropriate voting at the cryptographic level
not just "the UI doesn't show you the other party's contests."

### Party-change during the year

Voter can change party affiliation between elections. This
updates their registration trust edge (authority issues a new
edge with a higher nonce and the new party attribute). Old
edges are historical record; current attribute governs primary
eligibility.

---

## Ballot measures, judges, local offices

All of these are just contests.

- Proposition: contest with candidates = `option-yes` and
  `option-no` quids.
- Retention-judge question: same (yes/no pair).
- School board (single-winner plurality): contest with 4
  candidate quids.
- Ranked-choice mayoral: contest with `votingMethod: ranked-choice-irv`.
- Multi-member city council (vote-for-three): contest with
  `votingMethod: approval` and `maxApproved: 3`.

The voting primitive (trust edges from BQ to options) is the
same. The contest's `votingMethod` attribute dictates how the
tally engine interprets the edges.

---

## Write-in candidates

A voter wants to write in "Mickey Mouse" for Sheriff. The
voting booth:

1. Displays a write-in field.
2. Voter types "Mickey Mouse."
3. Booth generates a one-off write-in candidate quid:
   `candidate-write-in-williamson-2026-sheriff-<hash of name>`
4. Identity transaction registers the write-in with attribute
   `isWriteIn: true, writtenName: "Mickey Mouse"`.
5. Trust edge from BQ → write-in quid casts the vote.

At tally, the election authority:
- Groups trust edges by trustee as usual.
- Flags write-in trustees separately in the results.
- If a write-in candidate receives enough votes to potentially
  win or qualify for further consideration, the name is reviewed
  for consistency (normalizing "Mickey Mouse" vs. "Mike E. Mouse").

---

## Timeline and state machine

```
T-90 days: Election Authority publishes election parameters
  - Authority operator quid + per-governor guardian quorums installed
  - Governor quorum for the election's domain tree configured
    (5-of-7 weighted; see integration.md §2)
  - Domain tree registered via DOMAIN_REGISTRATION transactions,
    consortium members added via ADD_VALIDATOR governance
  - Well-known file (`/.well-known/quidnug-network.json`) published
  - Contests registered as quids
  - Candidates file their quids
  - Pre-election audit delegation configured

T-30 days: Voter registration deadline
  - Authority stops accepting new registrations
  - Publishes registration snapshot (Merkle root) for public audit

T-1 day: Poll books frozen
  - Snapshot of the voter roll captured
  - Each precinct node bootstraps with this snapshot

T-0: Election Day
  06:00: Polls open (contest.opened events)
  20:00: Polls close (contest.closed events)

T+1 to T+30 days: Certification period
  - Audit observations emitted
  - Challenges filed as events
  - Paper-ballot hand audit subset (risk-limiting audit)
  - Recounts on demand

T+30 days: Certification
  - Authority emits contest.certified events
  - Result is final
```

Each stage emits signed events; the full timeline is replayable
from the chain.

---

## What replaces what

| Current system              | Quidnug replacement                                             |
|-----------------------------|------------------------------------------------------------------|
| State voter registration DB | Registration domain + trust edges from authority to VRQs         |
| Printed poll book           | Per-precinct domain query, auto-refreshed on precinct tablets    |
| Electronic poll book vendor | Open-source poll-worker tablet app querying Quidnug              |
| Voting machine firmware     | Open-source voting-booth app generating BQs + emitting trust edges |
| Ballot-box chain of custody | Paper ballots PLUS cryptographically paired digital record       |
| Proprietary tabulator       | Any Quidnug node querying the contest domain                     |
| Recount procedure           | Re-run the tally query; anyone can do it                         |
| Audit trail                 | Signed events end-to-end                                         |
| Secretary of State DB       | Public, signed chain                                             |

---

## Key Quidnug features used

- **Bring-your-own-quid registration:** voter owns identity.
- **Trust edges (per-domain):** registration, poll book, votes.
- **Blind-signature ballot issuance:** anonymity + uniqueness.
- **Event streams:** check-in, voted, tallied, certified, disputes.
- **Guardian recovery (QDP-0002):** authority's key lifecycle.
- **Push gossip (QDP-0005):** real-time propagation of events
  across precincts, state, and observer nodes.
- **K-of-K bootstrap (QDP-0008):** fresh observer nodes seed from
  a quorum of trusted precinct + state nodes.
- **Fork-block (QDP-0009):** coordinate protocol changes between
  elections (e.g., "all 2028 elections must use version 2 of
  ballot format").
- **Lazy epoch probe (QDP-0007):** detect stale authority-key
  signatures at cross-jurisdiction boundaries.
- **Relational trust:** observers can personalize their trust in
  precinct validators.

---

## Value delivered

| Dimension                           | Today                                              | Quidnug                                                |
|-------------------------------------|----------------------------------------------------|--------------------------------------------------------|
| Voter verifies they're registered    | State website + call-back                          | Public chain query in 1 second                          |
| Voter verifies their own vote        | Not possible                                       | Private record + chain query                            |
| Public verifies voter roll           | FOIA request                                       | Public chain query                                      |
| Public does a recount                | Not possible                                       | Run a query                                             |
| Candidate recount                    | Official process, weeks                            | Independent tally from chain, seconds                   |
| Cross-precinct verification         | State aggregation (trust SOS)                     | Any node sees all precincts                             |
| Tamper detection                    | Paper audit after-the-fact                        | Immediate cross-node discrepancy detection              |
| Voter identity forgery resistance    | Database controls                                 | Cryptographic (authority-signed trust edge)             |
| Double-voting resistance             | Poll-book check (same day)                        | Nullifier-enforced cryptographically                    |
| Ballot issuance transparency        | "Trust the vendor"                                 | Signed issuance events, per-VRQ, auditable              |
| Cost of audit                       | Per-jurisdiction audit firms                      | Zero, any citizen can run the same queries             |

---

## What's in this folder

The elections use case is the most detailed in the library.
Six files cover the full lifecycle from design to go-live:

- [`README.md`](https://github.com/bhmortim/quidnug/blob/main/README.md), this document. Protocol-level
  semantics: quid types, trust edges as votes, blind
  signatures, paper parity, recount, etc.
- [`architecture.md`](https://github.com/bhmortim/quidnug/blob/main/architecture.md), data model, domain
  hierarchy, event schemas, sequence diagrams.
- [`implementation.md`](https://github.com/bhmortim/quidnug/blob/main/implementation.md), concrete API
  flows for each role (voter, registrar, poll worker, tally
  engine).
- [`integration.md`](https://github.com/bhmortim/quidnug/blob/main/integration.md), how the election
  design composes on top of the three architectural pillars
  (QDPs 0012 Domain Governance, 0013 Network Federation,
  0014 Node Discovery + Sharding). Fills in the governance,
  multi-jurisdictional federation, and operational topology
  layers that this README only sketches.
- [`operations.md`](https://github.com/bhmortim/quidnug/blob/main/operations.md), deployment topology at
  five scales (pilot to federal), capacity planning, election-
  day operations playbook, incident response, cost analysis.
- [`launch-checklist.md`](https://github.com/bhmortim/quidnug/blob/main/launch-checklist.md), sequential
  T-180 through T+30 go-live checklist. Use this as the
  actual project plan.
- [`threat-model.md`](https://github.com/bhmortim/quidnug/blob/main/threat-model.md), attackers, threats,
  and mitigations.

Recommended reading order for someone implementing:

1. This README (problem + design principles + mechanics).
2. `architecture.md` (data model).
3. `integration.md` (how it fits the larger architecture).
4. `operations.md` (how you'd actually deploy + run it).
5. `threat-model.md` (what you're defending against).
6. `launch-checklist.md` (when you're ready to execute).
7. `implementation.md` for code-level detail when building.

## Related

Protocol QDPs this design uses:

- [QDP-0002 Guardian Recovery](https://github.com/bhmortim/quidnug/blob/main/../../docs/design/0002-guardian-based-recovery.md)
 recovery mechanism for governor / observer / voter keys.
- [QDP-0005 Push Gossip](https://github.com/bhmortim/quidnug/blob/main/../../docs/design/0005-push-based-gossip.md)
 gets fresh check-ins + cast votes across the consortium fast.
- [QDP-0008 K-of-K Bootstrap](https://github.com/bhmortim/quidnug/blob/main/../../docs/design/0008-kofk-bootstrap.md)
 how new observer nodes seed state from the consortium.
- [QDP-0012 Domain Governance](https://github.com/bhmortim/quidnug/blob/main/../../docs/design/0012-domain-governance.md)
 cache replica / consortium member / governor role separation
  that elections load-bears on.
- [QDP-0013 Network Federation](https://github.com/bhmortim/quidnug/blob/main/../../docs/design/0013-network-federation.md)
 cross-jurisdictional federation (state → county, federal →
  state) for multi-level elections.
- [QDP-0014 Node Discovery + Sharding](https://github.com/bhmortim/quidnug/blob/main/../../docs/design/0014-node-discovery-and-sharding.md)
 operational topology for running many nodes across precincts +
  regions + capabilities.

Related use cases:

- [`../healthcare-consent-management/`](https://github.com/bhmortim/quidnug/blob/main/../healthcare-consent-management/)
 similar bring-your-own-identity + guardian override pattern.
- [`../credential-verification-network/`](https://github.com/bhmortim/quidnug/blob/main/../credential-verification-network/)
 similar authority + registered-entity trust graph.
- [`../dns-replacement/`](https://github.com/bhmortim/quidnug/blob/main/../dns-replacement/), similar
  multi-jurisdictional federated governance pattern; the DNS use
  case's TLD-governance-with-delegation mirrors state-delegates-
  to-county in elections.

Operator playbooks (for deployment):

- [`../../deploy/public-network/home-operator-plan.md`](https://github.com/bhmortim/quidnug/blob/main/../../deploy/public-network/home-operator-plan.md)
 the cheap-deployment pattern, adapted for elections in
  `operations.md`.
- [`../../deploy/public-network/governance-model.md`](https://github.com/bhmortim/quidnug/blob/main/../../deploy/public-network/governance-model.md)
 operator-facing QDP-0012 explainer.
- [`../../deploy/public-network/federation-model.md`](https://github.com/bhmortim/quidnug/blob/main/../../deploy/public-network/federation-model.md)
 operator-facing QDP-0013 explainer.
- [`../../deploy/public-network/sharding-model.md`](https://github.com/bhmortim/quidnug/blob/main/../../deploy/public-network/sharding-model.md)
 operator-facing QDP-0014 explainer.

Architecture orientation (start here if you're new):

- [`../ARCHITECTURE.md`](https://github.com/bhmortim/quidnug/blob/main/../ARCHITECTURE.md), single-doc tour
  of the protocol, the three pillars, and how every use case
  fits the same pattern. Elections is the most complex worked
  example.
- [`../BUILDING-A-USE-CASE.md`](https://github.com/bhmortim/quidnug/blob/main/../BUILDING-A-USE-CASE.md),
  the six-phase recipe for designing a use case. Elections was
  designed following this pattern.

## Open research questions (future QDPs)

1. **Blind-signature protocol specification.** Quidnug's native
   ECDSA P-256 doesn't directly support blind signatures. Options:
   add RSA-based issuance as an auxiliary protocol, or use
   EC-Schnorr-style blind signatures (requires protocol
   extension). Needs a QDP.
2. **Homomorphic tallying** for full receipt-freeness, could be
   a future QDP that adds Paillier or ElGamal ciphertext vote
   encoding, with tallying in the ciphertext space.
3. **Risk-limiting audit integration**, formal statistical audit
   procedures that consume Quidnug's paper-vs-digital matching.
4. **Voter's private-key recovery**, if a voter loses their VRQ
   key, how do they re-register? Guardian-recovery-for-voters
   needs an opinionated design.

These don't prevent a production deployment; the core flow works
with v1 Quidnug plus the blind-signature auxiliary. They'd make
successive versions stronger.