mirror of
https://github.com/saymrwulf/swisspost-evoting-go-poc.git
synced 2026-05-14 20:58:03 +00:00
Proof-of-concept reimplementation of the Swiss Post e-voting cryptographic protocol in Go. Single binary, 52 source files, 2 dependencies. Covers ElGamal encryption, Bayer-Groth verifiable shuffles, zero-knowledge proofs, return codes, and a full election ceremony demo.
911 lines
46 KiB
HTML
911 lines
46 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="en">
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
<title>Operator Manual -- Swiss Post E-Voting Go PoC</title>
|
|
<style>
|
|
@page {
|
|
size: A4;
|
|
margin: 25mm 20mm 25mm 20mm;
|
|
}
|
|
@media print {
|
|
body { font-size: 10pt; }
|
|
.no-print { display: none !important; }
|
|
.page-break { page-break-before: always; }
|
|
h2 { page-break-before: always; }
|
|
h2:first-of-type { page-break-before: avoid; }
|
|
pre, .code-block { font-size: 8.5pt; }
|
|
.cover-page { page-break-after: always; height: 100vh; }
|
|
.toc { page-break-after: always; }
|
|
}
|
|
|
|
* { margin: 0; padding: 0; box-sizing: border-box; }
|
|
body {
|
|
font-family: 'Georgia', 'Times New Roman', serif;
|
|
font-size: 11pt;
|
|
line-height: 1.6;
|
|
color: #1a1a1a;
|
|
background: #fff;
|
|
max-width: 210mm;
|
|
margin: 0 auto;
|
|
padding: 20mm;
|
|
}
|
|
|
|
/* Cover page */
|
|
.cover-page {
|
|
display: flex;
|
|
flex-direction: column;
|
|
justify-content: center;
|
|
align-items: center;
|
|
text-align: center;
|
|
min-height: 80vh;
|
|
border: 3px double #333;
|
|
padding: 40px;
|
|
margin-bottom: 40px;
|
|
}
|
|
.cover-page .swiss-cross { font-size: 48px; margin-bottom: 20px; }
|
|
.cover-page h1 { font-size: 24pt; margin-bottom: 8px; color: #111; }
|
|
.cover-page .cover-sub { font-size: 14pt; color: #444; margin-bottom: 30px; }
|
|
.cover-page .cover-detail { font-size: 10pt; color: #666; line-height: 1.8; }
|
|
.cover-page .cover-line { width: 60%; height: 1px; background: #999; margin: 20px auto; }
|
|
|
|
/* Table of Contents */
|
|
.toc { margin-bottom: 40px; }
|
|
.toc h2 { font-size: 18pt; margin-bottom: 20px; border-bottom: 2px solid #333; padding-bottom: 8px; page-break-before: avoid; }
|
|
.toc-entry { display: flex; justify-content: space-between; padding: 4px 0; border-bottom: 1px dotted #ccc; }
|
|
.toc-entry.toc-chapter { font-weight: 700; margin-top: 8px; }
|
|
.toc-entry .toc-page { color: #666; }
|
|
.toc-section { margin-left: 20px; }
|
|
|
|
/* Chapter headings */
|
|
h2 {
|
|
font-size: 18pt;
|
|
color: #111;
|
|
border-bottom: 2px solid #333;
|
|
padding-bottom: 8px;
|
|
margin-bottom: 20px;
|
|
margin-top: 40px;
|
|
}
|
|
h3 {
|
|
font-size: 13pt;
|
|
color: #222;
|
|
margin-top: 24px;
|
|
margin-bottom: 10px;
|
|
border-bottom: 1px solid #ddd;
|
|
padding-bottom: 4px;
|
|
}
|
|
h4 {
|
|
font-size: 11pt;
|
|
color: #333;
|
|
margin-top: 16px;
|
|
margin-bottom: 8px;
|
|
font-style: italic;
|
|
}
|
|
p { margin-bottom: 10px; text-align: justify; }
|
|
ul, ol { margin: 8px 0 12px 24px; }
|
|
li { margin-bottom: 4px; }
|
|
|
|
/* Role header boxes */
|
|
.role-header {
|
|
background: #f5f5f0;
|
|
border: 1px solid #ccc;
|
|
border-left: 4px solid #333;
|
|
padding: 12px 16px;
|
|
margin: 16px 0;
|
|
}
|
|
.role-header .role-name { font-weight: 700; font-size: 12pt; }
|
|
.role-header .role-desc { font-size: 10pt; color: #555; margin-top: 4px; }
|
|
|
|
/* Code blocks */
|
|
.code-block {
|
|
font-family: 'SF Mono', 'Consolas', 'Courier New', monospace;
|
|
background: #f8f8f8;
|
|
border: 1px solid #ddd;
|
|
border-radius: 3px;
|
|
padding: 10px 14px;
|
|
margin: 10px 0;
|
|
font-size: 9.5pt;
|
|
line-height: 1.4;
|
|
overflow-x: auto;
|
|
white-space: pre;
|
|
}
|
|
|
|
/* Step boxes */
|
|
.step {
|
|
border: 1px solid #ddd;
|
|
border-radius: 4px;
|
|
padding: 12px 16px;
|
|
margin: 12px 0;
|
|
background: #fafafa;
|
|
}
|
|
.step-num {
|
|
display: inline-block;
|
|
background: #333;
|
|
color: #fff;
|
|
width: 24px; height: 24px;
|
|
border-radius: 50%;
|
|
text-align: center;
|
|
line-height: 24px;
|
|
font-size: 9pt;
|
|
font-weight: 700;
|
|
margin-right: 8px;
|
|
font-family: 'SF Mono', 'Consolas', monospace;
|
|
}
|
|
.step-title { font-weight: 700; display: inline; }
|
|
|
|
/* Warning/note boxes */
|
|
.warning {
|
|
background: #fff8f0;
|
|
border-left: 4px solid #e67e22;
|
|
padding: 10px 14px;
|
|
margin: 12px 0;
|
|
font-size: 10pt;
|
|
}
|
|
.warning::before { content: 'Warning: '; font-weight: 700; color: #e67e22; }
|
|
|
|
.note-box {
|
|
background: #f0f4ff;
|
|
border-left: 4px solid #3366cc;
|
|
padding: 10px 14px;
|
|
margin: 12px 0;
|
|
font-size: 10pt;
|
|
}
|
|
.note-box::before { content: 'Note: '; font-weight: 700; color: #3366cc; }
|
|
|
|
.legal-box {
|
|
background: #f5f0f5;
|
|
border-left: 4px solid #666;
|
|
padding: 10px 14px;
|
|
margin: 12px 0;
|
|
font-size: 10pt;
|
|
font-style: italic;
|
|
}
|
|
.legal-box::before { content: 'Legal basis: '; font-weight: 700; font-style: normal; color: #666; }
|
|
|
|
/* Tables */
|
|
table {
|
|
width: 100%;
|
|
border-collapse: collapse;
|
|
margin: 12px 0;
|
|
font-size: 10pt;
|
|
}
|
|
th, td {
|
|
padding: 6px 10px;
|
|
border: 1px solid #ccc;
|
|
text-align: left;
|
|
}
|
|
th { background: #f0f0f0; font-weight: 700; }
|
|
|
|
/* Checklist */
|
|
.checklist { list-style: none; margin-left: 0; }
|
|
.checklist li::before { content: '\2610\00a0'; font-size: 13pt; }
|
|
|
|
/* Print hint */
|
|
.print-hint {
|
|
background: #e8f4e8;
|
|
border: 1px solid #4a4;
|
|
padding: 14px 18px;
|
|
margin: 20px 0;
|
|
border-radius: 4px;
|
|
font-family: 'SF Mono', 'Consolas', monospace;
|
|
font-size: 10pt;
|
|
line-height: 1.6;
|
|
}
|
|
|
|
.separator { border-top: 1px solid #ddd; margin: 20px 0; }
|
|
|
|
strong { color: #111; }
|
|
em { color: #333; }
|
|
</style>
|
|
</head>
|
|
<body>
|
|
|
|
<!-- PRINT HINT (screen only) -->
|
|
<div class="print-hint no-print">
|
|
<strong>To save as PDF:</strong> Safari → File → Print → Save as PDF<br>
|
|
Or: Cmd+P → select "Save as PDF" in the bottom-left dropdown.
|
|
</div>
|
|
|
|
<!-- ============================================================ -->
|
|
<!-- COVER PAGE -->
|
|
<!-- ============================================================ -->
|
|
<div class="cover-page">
|
|
<div class="swiss-cross">🇨🇭</div>
|
|
<h1>Operator Manual</h1>
|
|
<div class="cover-sub">Swiss Post E-Voting System<br>Go Proof-of-Concept Implementation</div>
|
|
<div class="cover-line"></div>
|
|
<div class="cover-detail">
|
|
Version 1.0<br>
|
|
February 2026<br><br>
|
|
This manual describes the operational procedures for all roles<br>
|
|
participating in the e-voting election ceremony, mapped to the<br>
|
|
Go PoC command-line tool <code>evote</code>.<br><br>
|
|
The role structure follows the Ordinance on Electronic Voting (OEV/VEleS)<br>
|
|
as mandated by the Federal Chancellery.
|
|
</div>
|
|
</div>
|
|
|
|
<!-- ============================================================ -->
|
|
<!-- TABLE OF CONTENTS -->
|
|
<!-- ============================================================ -->
|
|
<div class="toc">
|
|
<h2>Table of Contents</h2>
|
|
<div class="toc-entry toc-chapter"><span>1. Introduction</span></div>
|
|
<div class="toc-entry toc-section"><span>1.1 Purpose of This Manual</span></div>
|
|
<div class="toc-entry toc-section"><span>1.2 System Overview</span></div>
|
|
<div class="toc-entry toc-section"><span>1.3 Role Structure & Legal Basis</span></div>
|
|
<div class="toc-entry toc-section"><span>1.4 Prerequisites</span></div>
|
|
|
|
<div class="toc-entry toc-chapter"><span>2. Cantonal Administrator</span></div>
|
|
<div class="toc-entry toc-section"><span>2.1 Role Description</span></div>
|
|
<div class="toc-entry toc-section"><span>2.2 Day 1 -- Configuration Phase</span></div>
|
|
<div class="toc-entry toc-section"><span>2.3 Day 2 -- Release Phase</span></div>
|
|
<div class="toc-entry toc-section"><span>2.4 Day 3 -- Tally Phase</span></div>
|
|
|
|
<div class="toc-entry toc-chapter"><span>3. Electoral Board</span></div>
|
|
<div class="toc-entry toc-section"><span>3.1 Role Description</span></div>
|
|
<div class="toc-entry toc-section"><span>3.2 Constituting the Board (Day 2)</span></div>
|
|
<div class="toc-entry toc-section"><span>3.3 Authorizing Decryption (Day 3)</span></div>
|
|
|
|
<div class="toc-entry toc-chapter"><span>4. Swiss Post -- System Provider</span></div>
|
|
<div class="toc-entry toc-section"><span>4.1 Role Description</span></div>
|
|
<div class="toc-entry toc-section"><span>4.2 Infrastructure & Central Services</span></div>
|
|
<div class="toc-entry toc-section"><span>4.3 Red Phase (Voting Period)</span></div>
|
|
|
|
<div class="toc-entry toc-chapter"><span>5. Control Component Operators</span></div>
|
|
<div class="toc-entry toc-section"><span>5.1 Role Description & Split Trust</span></div>
|
|
<div class="toc-entry toc-section"><span>5.2 Key Generation (Setup Phase)</span></div>
|
|
<div class="toc-entry toc-section"><span>5.3 Shuffle & Partial Decryption (Tally Phase)</span></div>
|
|
|
|
<div class="toc-entry toc-chapter"><span>6. Printing Office</span></div>
|
|
<div class="toc-entry toc-section"><span>6.1 Role Description</span></div>
|
|
<div class="toc-entry toc-section"><span>6.2 Voting Card Generation & Distribution</span></div>
|
|
|
|
<div class="toc-entry toc-chapter"><span>7. Voter</span></div>
|
|
<div class="toc-entry toc-section"><span>7.1 Role Description</span></div>
|
|
<div class="toc-entry toc-section"><span>7.2 Voting Procedure</span></div>
|
|
<div class="toc-entry toc-section"><span>7.3 Verifying Your Vote (Individual Verifiability)</span></div>
|
|
|
|
<div class="toc-entry toc-chapter"><span>8. Independent Verifier</span></div>
|
|
<div class="toc-entry toc-section"><span>8.1 Role Description</span></div>
|
|
<div class="toc-entry toc-section"><span>8.2 Setup Verification (Day 2)</span></div>
|
|
<div class="toc-entry toc-section"><span>8.3 Tally Verification (Day 3)</span></div>
|
|
<div class="toc-entry toc-section"><span>8.4 Interpreting Verification Results</span></div>
|
|
|
|
<div class="toc-entry toc-chapter"><span>9. Federal Chancellery & External Examiners</span></div>
|
|
<div class="toc-entry toc-section"><span>9.1 Oversight Role</span></div>
|
|
<div class="toc-entry toc-section"><span>9.2 Four Audit Scopes</span></div>
|
|
|
|
<div class="toc-entry toc-chapter"><span>Appendix A: Command Reference</span></div>
|
|
<div class="toc-entry toc-chapter"><span>Appendix B: Ceremony Checklist</span></div>
|
|
<div class="toc-entry toc-chapter"><span>Appendix C: Mapping -- Production System vs. Go PoC</span></div>
|
|
</div>
|
|
|
|
<!-- ============================================================ -->
|
|
<!-- CHAPTER 1: INTRODUCTION -->
|
|
<!-- ============================================================ -->
|
|
<h2>1. Introduction</h2>
|
|
|
|
<h3>1.1 Purpose of This Manual</h3>
|
|
<p>This manual provides step-by-step operational procedures for all participants in the Swiss Post e-voting election ceremony, as implemented in the Go proof-of-concept (PoC) system <code>evote</code>.</p>
|
|
<p>The Go PoC reimplements the cryptographic core of the production Swiss Post e-voting system in approximately 6,500 lines of Go. It uses the same algorithms (ElGamal encryption, Schnorr proofs, Bayer-Groth verifiable shuffle) but operates as a single-machine, command-line tool rather than a distributed multi-server deployment.</p>
|
|
<p>Despite the simplified infrastructure, the Go PoC preserves the <strong>same role structure</strong> as the production system. Each role's responsibilities, trust boundaries, and ceremony steps are faithfully reproduced. This ensures operational familiarity and avoids disrupting the agreed-upon organizational framework with its legal underpinnings.</p>
|
|
|
|
<h3>1.2 System Overview</h3>
|
|
<p>The e-voting system operates in three phases across three days:</p>
|
|
<table>
|
|
<tr><th>Phase</th><th>Day</th><th>Key Operations</th><th>Primary Roles</th></tr>
|
|
<tr><td>Configuration</td><td>Day 1</td><td>Key generation, voting card creation, system setup</td><td>Cantonal Admin, CC Operators</td></tr>
|
|
<tr><td>Release & Voting</td><td>Day 2 + Voting Period</td><td>Electoral Board constitution, setup verification, voter portal activation, ballot casting</td><td>Electoral Board, Verifier, Voters</td></tr>
|
|
<tr><td>Tally</td><td>Day 3</td><td>Mixing, decryption, tally verification, result publication</td><td>CC Operators, Electoral Board, Verifier</td></tr>
|
|
</table>
|
|
|
|
<h3>1.3 Role Structure & Legal Basis</h3>
|
|
<div class="legal-box">The role structure follows the Ordinance on Electronic Voting (OEV/VEleS) issued by the Federal Chancellery (Bundeskanzlei). All operational roles, trust boundaries, and separation-of-duties requirements are mandated by law. Deviating from the agreed role structure may have legal implications for the authorization of e-voting channels.</div>
|
|
|
|
<p>The following organizational hierarchy applies:</p>
|
|
<div class="code-block">Federal Chancellery (Bundeskanzlei)
|
|
|-- Issues OEV Ordinance, commissions independent examiners
|
|
|
|
|
+-- Cantons (each independent)
|
|
|-- Electoral Board (>= 2 members)
|
|
| +-- Verifier Operator
|
|
|
|
|
|-- Cantonal Administrator
|
|
| +-- Operates SDM (Setup, Online, Tally)
|
|
| +-- Manages 1 Control Component
|
|
| +-- Manages Printing Office
|
|
|
|
|
+-- Contracts with Swiss Post (System Provider)
|
|
|-- Operates Voting Server, Access Layer
|
|
+-- Operates 3 of 4 Control Components (separate teams)</div>
|
|
|
|
<div class="note-box">In the Go PoC, all roles are exercised by the same person on the same machine via different <code>evote</code> subcommands. In production, these roles are performed by <strong>different people on different machines</strong> with strict access controls and the four-eyes principle.</div>
|
|
|
|
<h3>1.4 Prerequisites</h3>
|
|
<p>To operate the Go PoC system, you need:</p>
|
|
<ul>
|
|
<li>The <code>evote</code> binary (build with <code>go build ./cmd/evote</code> from the <code>evote/</code> directory)</li>
|
|
<li>Go 1.21 or later (only for building; the binary is self-contained)</li>
|
|
<li>A terminal (macOS Terminal, Linux shell, or Windows command prompt)</li>
|
|
<li>No network access, database, or external services required</li>
|
|
</ul>
|
|
<div class="code-block"># Build the binary
|
|
cd evote/
|
|
go build -o evote ./cmd/evote
|
|
|
|
# Verify it works
|
|
./evote --help</div>
|
|
|
|
<!-- ============================================================ -->
|
|
<!-- CHAPTER 2: CANTONAL ADMINISTRATOR -->
|
|
<!-- ============================================================ -->
|
|
<h2>2. Cantonal Administrator</h2>
|
|
|
|
<h3>2.1 Role Description</h3>
|
|
<div class="role-header">
|
|
<div class="role-name">Cantonal Administrator (Kantonale/r Administrator/in)</div>
|
|
<div class="role-desc">Operates the Secure Data Manager (SDM) and coordinates the election ceremony. Responsible for processing electoral data, managing the key generation ceremony, generating voting cards, and coordinating between all other roles.</div>
|
|
</div>
|
|
|
|
<div class="legal-box">The Cantonal Administrator operates the SDM under cantonal authority, <strong>not</strong> under Swiss Post. All personal data (electoral registers) remains exclusively at the canton. The four-eyes principle applies to all SDM operations.</div>
|
|
|
|
<p>In the Go PoC, the Cantonal Administrator's role corresponds to initiating the election setup and configuring the system parameters.</p>
|
|
|
|
<h3>2.2 Day 1 -- Configuration Phase</h3>
|
|
|
|
<div class="step">
|
|
<span class="step-num">1</span>
|
|
<div class="step-title">Initialize the election and generate cryptographic parameters</div>
|
|
<p style="margin-top:8px;">Decide on the number of voters and ballot options. The system will generate a safe prime group, encode the candidates, and begin the key generation ceremony.</p>
|
|
<div class="code-block"># Full automated ceremony (all roles in one command):
|
|
./evote demo --voters=6 --options=2</div>
|
|
<p>The <code>demo</code> command performs:</p>
|
|
<ul>
|
|
<li>Safe prime group generation (p = 2q + 1, both prime, 256-bit)</li>
|
|
<li>Generator selection (g = 4, verified as quadratic residue)</li>
|
|
<li>Candidate encoding (Alice = 2² = 4, Bob = 3² = 9, etc.)</li>
|
|
</ul>
|
|
</div>
|
|
|
|
<div class="step">
|
|
<span class="step-num">2</span>
|
|
<div class="step-title">Coordinate Control Component key generation</div>
|
|
<p style="margin-top:8px;">The system generates key pairs for all 4 Control Components and the Electoral Board. Each CC generates a Schnorr proof of knowledge for its secret key. The Cantonal Administrator verifies these proofs are present.</p>
|
|
<p>Expected output:</p>
|
|
<div class="code-block"> CC0 (Bern): Key generated, Schnorr proof VALID
|
|
CC1 (Zurich): Key generated, Schnorr proof VALID
|
|
CC2 (Geneva): Key generated, Schnorr proof VALID
|
|
CC3 (Lugano): Key generated, Schnorr proof VALID</div>
|
|
</div>
|
|
|
|
<div class="step">
|
|
<span class="step-num">3</span>
|
|
<div class="step-title">Combine public keys into Election Public Key</div>
|
|
<p style="margin-top:8px;">The 5 public keys (4 CCs + Electoral Board) are multiplied together to form the joint Election Public Key. This key locks the ballot box -- all 5 key holders must cooperate to decrypt.</p>
|
|
<div class="code-block"> ElectionPK = PK0 * PK1 * PK2 * PK3 * PK_EB mod p</div>
|
|
</div>
|
|
|
|
<div class="step">
|
|
<span class="step-num">4</span>
|
|
<div class="step-title">Generate voting cards</div>
|
|
<p style="margin-top:8px;">The system generates a unique voting card for each registered voter containing:</p>
|
|
<ul>
|
|
<li><strong>Start Voting Key (SVK)</strong> -- used for authentication</li>
|
|
<li><strong>Ballot Casting Key (BCK)</strong> -- used to confirm the vote</li>
|
|
<li><strong>Choice Return Codes</strong> -- one per candidate, used for individual verifiability</li>
|
|
<li><strong>Vote Cast Code (VCC)</strong> -- confirms the vote is sealed</li>
|
|
</ul>
|
|
</div>
|
|
|
|
<div class="warning">In the Go PoC, voting cards are displayed on screen. In production, these are printed on physical paper and mailed to voters. The codes must <strong>never</strong> be transmitted electronically.</div>
|
|
|
|
<h3>2.3 Day 2 -- Release Phase</h3>
|
|
<p>The Cantonal Administrator coordinates the Electoral Board constitution (see Chapter 3) and triggers the setup verification (see Chapter 8). Once verification passes, the voter portal URL is configured and published.</p>
|
|
|
|
<h3>2.4 Day 3 -- Tally Phase</h3>
|
|
<p>The Cantonal Administrator initiates the mixing process, coordinates Electoral Board password entry for decryption (see Chapter 3), and triggers the tally verification (see Chapter 8). Upon successful verification, the results are exported.</p>
|
|
|
|
<div class="code-block"># In the Go PoC, the demo command runs all three days automatically:
|
|
./evote demo --voters=6 --options=2
|
|
|
|
# For the step-by-step theatrical version:
|
|
./evote present</div>
|
|
|
|
<!-- ============================================================ -->
|
|
<!-- CHAPTER 3: ELECTORAL BOARD -->
|
|
<!-- ============================================================ -->
|
|
<h2>3. Electoral Board</h2>
|
|
|
|
<h3>3.1 Role Description</h3>
|
|
<div class="role-header">
|
|
<div class="role-name">Electoral Board (Wahlbehörde / Commission électorale)</div>
|
|
<div class="role-desc">A group of at least 2 board members who collectively hold the 5th encryption key. Each member sets a password during setup; all members must enter their passwords to authorize decryption on election night. The Electoral Board is the final safeguard against unauthorized decryption.</div>
|
|
</div>
|
|
|
|
<div class="legal-box">The Ordinance requires a minimum of 2 Electoral Board members. Each member's password must meet complexity requirements (minimum 24 characters in production). The board operates on air-gapped machines under the four-eyes principle.</div>
|
|
|
|
<h3>3.2 Constituting the Board (Day 2)</h3>
|
|
|
|
<div class="step">
|
|
<span class="step-num">1</span>
|
|
<div class="step-title">Each board member sets a password</div>
|
|
<p style="margin-top:8px;">On the Setup SDM (an air-gapped machine), each board member enters a strong password. The combined passwords are used to derive the Electoral Board's secret key via Argon2id (a memory-hard key derivation function).</p>
|
|
<div class="code-block"> EB member 1: enters password --> |
|
|
EB member 2: enters password --> |-- Argon2id --> sk_EB
|
|
EB member 3: enters password --> |
|
|
|
|
pk_EB = g^sk_EB mod p (published as part of the Election Public Key)</div>
|
|
</div>
|
|
|
|
<div class="warning">If any board member forgets their password, the ballot box <strong>cannot be decrypted</strong>. There is no recovery mechanism. This is by design: it prevents any single party from decrypting without the board's collective authorization.</div>
|
|
|
|
<p>In the Go PoC, the Electoral Board key is generated automatically during the <code>demo</code> command. The system simulates the password entry process.</p>
|
|
|
|
<h3>3.3 Authorizing Decryption (Day 3)</h3>
|
|
|
|
<div class="step">
|
|
<span class="step-num">1</span>
|
|
<div class="step-title">Enter passwords on the Tally SDM</div>
|
|
<p style="margin-top:8px;">After the 4 Control Components have completed their shuffles, the Electoral Board performs the final shuffle and decryption on an air-gapped Tally SDM. Each board member enters their password to reconstruct the EB secret key.</p>
|
|
</div>
|
|
|
|
<div class="step">
|
|
<span class="step-num">2</span>
|
|
<div class="step-title">Authorize the final shuffle and decryption</div>
|
|
<p style="margin-top:8px;">The system performs the 5th Bayer-Groth shuffle, generates its proof, and removes the last encryption layer. The decrypted votes appear in random order.</p>
|
|
</div>
|
|
|
|
<div class="note-box">The Electoral Board never sees which voter cast which vote. The 5 independent shuffles have permanently destroyed the link between voter identities and ballot contents.</div>
|
|
|
|
<!-- ============================================================ -->
|
|
<!-- CHAPTER 4: SWISS POST -->
|
|
<!-- ============================================================ -->
|
|
<h2>4. Swiss Post -- System Provider</h2>
|
|
|
|
<h3>4.1 Role Description</h3>
|
|
<div class="role-header">
|
|
<div class="role-name">Swiss Post (Schweizerische Post / System Provider)</div>
|
|
<div class="role-desc">Develops and maintains the e-voting software. Operates the central infrastructure including the Voting Server, Access Layer, message broker, databases, and 3 of the 4 Control Components. Swiss Post does <strong>not</strong> operate the SDM, Verifier, or the cantonal Control Component.</div>
|
|
</div>
|
|
|
|
<h3>4.2 Infrastructure & Central Services</h3>
|
|
<p>In the production system, Swiss Post operates:</p>
|
|
<table>
|
|
<tr><th>Component</th><th>Technology</th><th>Purpose</th></tr>
|
|
<tr><td>Access Layer</td><td>WAF, TLS termination</td><td>Protects the Voting Server from direct internet access</td></tr>
|
|
<tr><td>Voting Server</td><td>Spring Boot, Kubernetes</td><td>Processes vote submissions, relays to CCs</td></tr>
|
|
<tr><td>3 Control Components</td><td>Bare metal, diverse OS</td><td>Distributed key generation, return codes, shuffle</td></tr>
|
|
<tr><td>Message Broker</td><td>Apache ActiveMQ Artemis</td><td>Asynchronous communication between Server and CCs</td></tr>
|
|
<tr><td>Databases</td><td>PostgreSQL</td><td>Stores encrypted ballots, configuration, audit logs</td></tr>
|
|
</table>
|
|
|
|
<p>In the Go PoC, all of Swiss Post's infrastructure is simulated within the <code>evote</code> binary. The Voting Server, message broker, and database are replaced by in-memory data structures. The cryptographic operations are identical.</p>
|
|
|
|
<h3>4.3 Red Phase (Voting Period)</h3>
|
|
<p>During the voting period, Swiss Post enforces a "red phase":</p>
|
|
<ul>
|
|
<li>No system modifications are permitted</li>
|
|
<li>Infrastructure access is strictly controlled</li>
|
|
<li>SIEM monitoring is active for anomaly detection</li>
|
|
<li>Only pre-authorized personnel may access the systems</li>
|
|
</ul>
|
|
|
|
<div class="note-box">In the Go PoC, there is no persistent infrastructure. The "red phase" is conceptual: once the <code>demo</code> command enters the voting phase, the system processes all ballots without interruption.</div>
|
|
|
|
<!-- ============================================================ -->
|
|
<!-- CHAPTER 5: CONTROL COMPONENT OPERATORS -->
|
|
<!-- ============================================================ -->
|
|
<h2>5. Control Component Operators</h2>
|
|
|
|
<h3>5.1 Role Description & Split Trust</h3>
|
|
<div class="role-header">
|
|
<div class="role-name">Control Component Operator (CC-Betreiber/in)</div>
|
|
<div class="role-desc">Each of the 4 Control Components is operated by a separate team. No person with access to one CC may have access to any other CC. The CCs collectively ensure ballot secrecy (privacy) and election integrity (correctness). The system's security guarantees hold as long as at least one CC is honest.</div>
|
|
</div>
|
|
|
|
<div class="legal-box">OEV Art. 3.15: "If a person has physical or logical access to a control component, that person may not have access to any other control component." The 4 CCs use maximally diverse hardware and operating systems to reduce common-mode failures.</div>
|
|
|
|
<p>In the production system, the 4 CCs are deployed on bare-metal servers:</p>
|
|
<table>
|
|
<tr><th>CC</th><th>Location</th><th>Hardware</th><th>OS</th><th>Operated By</th></tr>
|
|
<tr><td>CC0</td><td>Canton premises</td><td>ProLiant BL460c</td><td>RHEL 9.6</td><td>Canton</td></tr>
|
|
<tr><td>CC1</td><td>Swiss Post DC</td><td>ProLiant BL460c</td><td>Debian 12.12</td><td>Swiss Post Team A</td></tr>
|
|
<tr><td>CC2</td><td>Swiss Post DC</td><td>ProLiant BL460c</td><td>Ubuntu 24.04</td><td>Swiss Post Team B</td></tr>
|
|
<tr><td>CC3</td><td>Swiss Post DC</td><td>ProLiant DL385</td><td>Windows Server 2022</td><td>Swiss Post Team C</td></tr>
|
|
</table>
|
|
|
|
<p>In the Go PoC, all 4 CCs are simulated within the same process. They are named CC0 (Bern), CC1 (Zurich), CC2 (Geneva), CC3 (Lugano) and behave identically to the production CCs cryptographically.</p>
|
|
|
|
<h3>5.2 Key Generation (Setup Phase)</h3>
|
|
|
|
<div class="step">
|
|
<span class="step-num">1</span>
|
|
<div class="step-title">Generate the key pair</div>
|
|
<p style="margin-top:8px;">Each CC generates a secret key vector sk = (sk[0], sk[1]) by sampling uniformly at random from Z_q. The corresponding public key pk = (g^sk[0], g^sk[1]) is computed and published.</p>
|
|
</div>
|
|
|
|
<div class="step">
|
|
<span class="step-num">2</span>
|
|
<div class="step-title">Generate the Schnorr proof of knowledge</div>
|
|
<p style="margin-top:8px;">For each key component, the CC generates a non-interactive Schnorr proof (Fiat-Shamir heuristic) demonstrating knowledge of the secret key without revealing it. The proof consists of two values (e, z) that anyone can verify.</p>
|
|
</div>
|
|
|
|
<div class="step">
|
|
<span class="step-num">3</span>
|
|
<div class="step-title">Publish public key and proof</div>
|
|
<p style="margin-top:8px;">The public key and Schnorr proof are transmitted to the central system for combination with the other CCs' keys.</p>
|
|
</div>
|
|
|
|
<h3>5.3 Shuffle & Partial Decryption (Tally Phase)</h3>
|
|
|
|
<p>On Day 3, each CC performs the following operations in sequence (CC0 first, then CC1, CC2, CC3):</p>
|
|
|
|
<div class="step">
|
|
<span class="step-num">1</span>
|
|
<div class="step-title">Receive the current ciphertext batch</div>
|
|
<p style="margin-top:8px;">CC0 receives the original encrypted ballots from the ballot box. Subsequent CCs receive the output of the previous CC's shuffle.</p>
|
|
</div>
|
|
|
|
<div class="step">
|
|
<span class="step-num">2</span>
|
|
<div class="step-title">Generate a random permutation</div>
|
|
<p style="margin-top:8px;">Sample a uniformly random permutation π of {0, ..., N-1}. This permutation determines the new order of the ballots.</p>
|
|
</div>
|
|
|
|
<div class="step">
|
|
<span class="step-num">3</span>
|
|
<div class="step-title">Re-encrypt and shuffle</div>
|
|
<p style="margin-top:8px;">For each output slot k, re-encrypt the permuted input ciphertext with fresh randomness. The resulting ciphertexts encrypt the same votes but are computationally unlinkable to the inputs.</p>
|
|
</div>
|
|
|
|
<div class="step">
|
|
<span class="step-num">4</span>
|
|
<div class="step-title">Generate the Bayer-Groth shuffle proof</div>
|
|
<p style="margin-top:8px;">Generate a zero-knowledge proof that the output is a valid permutation + re-encryption of the input. The proof has sub-linear O(√N) size and consists of nested sub-arguments: ProductArgument, HadamardArgument, ZeroArgument, SingleValueProductArgument, and MultiExponentiationArgument.</p>
|
|
</div>
|
|
|
|
<div class="step">
|
|
<span class="step-num">5</span>
|
|
<div class="step-title">Destroy the permutation</div>
|
|
<p style="margin-top:8px;">Securely erase the permutation π and all re-encryption randomness. After this step, <strong>even the CC operator cannot determine the correspondence</strong> between input and output ciphertexts.</p>
|
|
</div>
|
|
|
|
<div class="step">
|
|
<span class="step-num">6</span>
|
|
<div class="step-title">Perform partial decryption</div>
|
|
<p style="margin-top:8px;">Remove this CC's encryption layer by computing γ^sk for each ciphertext and dividing from the phi components. This reduces the number of remaining encryption layers by one.</p>
|
|
</div>
|
|
|
|
<div class="warning">The permutation must be destroyed <strong>immediately</strong> after the proof is generated. If any CC retains its permutation, the privacy guarantee for that shuffle step is compromised.</div>
|
|
|
|
<!-- ============================================================ -->
|
|
<!-- CHAPTER 6: PRINTING OFFICE -->
|
|
<!-- ============================================================ -->
|
|
<h2>6. Printing Office</h2>
|
|
|
|
<h3>6.1 Role Description</h3>
|
|
<div class="role-header">
|
|
<div class="role-name">Printing Office (Druckerei)</div>
|
|
<div class="role-desc">Prints and mails the physical voting cards to eligible voters. The voting card is the root of individual verifiability: it contains secret codes that enable the voter to verify that their vote was recorded correctly.</div>
|
|
</div>
|
|
|
|
<h3>6.2 Voting Card Generation & Distribution</h3>
|
|
<p>The Cantonal Administrator generates voting card data during the Configuration Phase. The Printing Office receives the data and produces physical cards.</p>
|
|
|
|
<p>Each voting card contains:</p>
|
|
<table>
|
|
<tr><th>Field</th><th>Purpose</th><th>Example</th></tr>
|
|
<tr><td>Start Voting Key (SVK)</td><td>Authentication credential</td><td>SVK-0000</td></tr>
|
|
<tr><td>Ballot Casting Key (BCK)</td><td>Vote confirmation credential</td><td>BCK-0000</td></tr>
|
|
<tr><td>Choice Return Codes</td><td>Verify correct recording (one per candidate)</td><td>CC00 (Alice), CC01 (Bob)</td></tr>
|
|
<tr><td>Vote Cast Code (VCC)</td><td>Confirm vote is sealed</td><td>VCC00</td></tr>
|
|
</table>
|
|
|
|
<p>In the Go PoC, the <code>demo</code> command displays all voting cards on screen:</p>
|
|
<div class="code-block"> +------------------------------------------------------+
|
|
| SWISS CONFEDERATION |
|
|
| Electronic Voting Card |
|
|
| |
|
|
| Voter ID: voter-0000 |
|
|
| Start Voting Key: SVK-0000 |
|
|
| Ballot Casting Key: BCK-0000 |
|
|
| |
|
|
| Choice Return Codes: |
|
|
| Alice: CC00 |
|
|
| Bob: CC01 |
|
|
| |
|
|
| Vote Cast Code: VCC00 |
|
|
+------------------------------------------------------+</div>
|
|
|
|
<div class="warning">Voting cards must be printed on physical paper and delivered via postal mail. The codes must <strong>never</strong> be transmitted electronically (no email, no SMS, no online download). The physical card is the out-of-band channel that enables individual verifiability even if the voting device is compromised.</div>
|
|
|
|
<!-- ============================================================ -->
|
|
<!-- CHAPTER 7: VOTER -->
|
|
<!-- ============================================================ -->
|
|
<h2>7. Voter</h2>
|
|
|
|
<h3>7.1 Role Description</h3>
|
|
<div class="role-header">
|
|
<div class="role-name">Voter (Stimmberechtigte/r)</div>
|
|
<div class="role-desc">An eligible citizen who casts a vote using the e-voting system. The voter interacts with the system through a web browser and verifies correct recording using the physical voting card received by mail.</div>
|
|
</div>
|
|
|
|
<h3>7.2 Voting Procedure</h3>
|
|
|
|
<div class="step">
|
|
<span class="step-num">1</span>
|
|
<div class="step-title">Open the voting portal</div>
|
|
<p style="margin-top:8px;">Navigate to the official URL provided on your voting card or the cantonal website. Verify the TLS certificate. Accept the legal terms.</p>
|
|
</div>
|
|
|
|
<div class="step">
|
|
<span class="step-num">2</span>
|
|
<div class="step-title">Authenticate</div>
|
|
<p style="margin-top:8px;">Enter your <strong>Start Voting Key (SVK)</strong> and <strong>date of birth</strong>. The server verifies your identity using an Argon2id hash (the SVK is never stored in plaintext).</p>
|
|
<p>In the Go PoC, authentication is simulated automatically.</p>
|
|
</div>
|
|
|
|
<div class="step">
|
|
<span class="step-num">3</span>
|
|
<div class="step-title">Cast your vote</div>
|
|
<p style="margin-top:8px;">Select your candidate(s) on the ballot. Your browser encrypts the vote locally using ElGamal encryption under the Election Public Key. <strong>The plaintext vote never leaves your device.</strong></p>
|
|
<p>The browser sends two large numbers (γ, φ) to the server -- pure noise to anyone without all 5 secret keys.</p>
|
|
</div>
|
|
|
|
<div class="step">
|
|
<span class="step-num">4</span>
|
|
<div class="step-title">Verify the Choice Return Code</div>
|
|
<p style="margin-top:8px;">The server displays a <strong>Choice Return Code</strong>. Compare it to the code on your physical voting card for the candidate you selected.</p>
|
|
<ul>
|
|
<li>If the codes <strong>match</strong>: your vote was recorded correctly. Proceed to confirm.</li>
|
|
<li>If the codes <strong>do not match</strong>: <strong>STOP. Do not confirm.</strong> Contact the cantonal authority. Your vote may have been intercepted or modified.</li>
|
|
</ul>
|
|
</div>
|
|
|
|
<div class="step">
|
|
<span class="step-num">5</span>
|
|
<div class="step-title">Confirm with the Ballot Casting Key</div>
|
|
<p style="margin-top:8px;">Enter your <strong>Ballot Casting Key (BCK)</strong> to finalize your vote. This is the second factor that prevents the server from confirming a vote without your explicit action.</p>
|
|
</div>
|
|
|
|
<div class="step">
|
|
<span class="step-num">6</span>
|
|
<div class="step-title">Verify the Vote Cast Code</div>
|
|
<p style="margin-top:8px;">The server displays a <strong>Vote Cast Code (VCC)</strong>. Compare it to your voting card. If it matches, your vote is sealed and confirmed.</p>
|
|
</div>
|
|
|
|
<h3>7.3 Verifying Your Vote (Individual Verifiability)</h3>
|
|
<p>The return code mechanism provides <strong>individual verifiability</strong>: each voter can personally verify that their vote was cast as intended and recorded as cast, without needing to trust any single system component.</p>
|
|
<p>The security guarantee: if the Choice Return Code matches the code on your physical card, then the ciphertext stored on the server encrypts the candidate you selected. This holds under the assumption that at least 1 of the 4 Control Components is honest (since all 4 contribute to computing the return code).</p>
|
|
|
|
<div class="note-box">Even if your computer is compromised with malware, the return codes on the physical card were generated during setup by the 4 CCs -- independently of your browser. A malware-modified vote would produce the wrong return code.</div>
|
|
|
|
<!-- ============================================================ -->
|
|
<!-- CHAPTER 8: INDEPENDENT VERIFIER -->
|
|
<!-- ============================================================ -->
|
|
<h2>8. Independent Verifier</h2>
|
|
|
|
<h3>8.1 Role Description</h3>
|
|
<div class="role-header">
|
|
<div class="role-name">Verifier Operator (Prüfer/in / Independent Auditor)</div>
|
|
<div class="role-desc">Operates the verification software that independently checks whether all protocol participants faithfully executed their operations. The Verifier runs on an offline, hardened machine under cantonal authority -- <strong>not</strong> under Swiss Post. The Verifier requires no secret keys and uses only publicly available data.</div>
|
|
</div>
|
|
|
|
<div class="legal-box">The Verifier is operated by the electoral commission under the responsibility of the cantons. It provides <strong>universal verifiability</strong>: any party can audit the election result using only public data and mathematics.</div>
|
|
|
|
<h3>8.2 Setup Verification (Day 2)</h3>
|
|
<p>After the Configuration Phase, the Verifier checks that the setup was performed correctly:</p>
|
|
<ul>
|
|
<li><strong>Key proofs:</strong> Verify the Schnorr proof for each CC's public key (proves the CC knows the corresponding secret key)</li>
|
|
<li><strong>Key combination:</strong> Verify the Election Public Key is the correct product of all 5 individual keys</li>
|
|
<li><strong>Voting card integrity:</strong> Verify return code mappings are consistent</li>
|
|
</ul>
|
|
|
|
<p>In the Go PoC, setup verification is performed automatically as part of the <code>demo</code> command.</p>
|
|
|
|
<h3>8.3 Tally Verification (Day 3)</h3>
|
|
<p>After tallying, the Verifier performs the most critical checks:</p>
|
|
|
|
<div class="step">
|
|
<span class="step-num">1</span>
|
|
<div class="step-title">Verify all Schnorr proofs (4 key proofs)</div>
|
|
<p style="margin-top:8px;">For each CC, recompute the Schnorr verification equation: g<sup>z</sup> · pk<sup>-e</sup> should reconstruct the commitment c, and H(p, q, g, pk, c) should equal e.</p>
|
|
<div class="code-block"> CC0 (Bern): [PASS]
|
|
CC1 (Zurich): [PASS]
|
|
CC2 (Geneva): [PASS]
|
|
CC3 (Lugano): [PASS]</div>
|
|
</div>
|
|
|
|
<div class="step">
|
|
<span class="step-num">2</span>
|
|
<div class="step-title">Verify all Bayer-Groth shuffle proofs (5 shuffle proofs)</div>
|
|
<p style="margin-top:8px;">For each of the 5 shuffles (4 CCs + Electoral Board), verify all sub-arguments of the Bayer-Groth shuffle proof. This confirms each shuffle was a valid permutation + re-encryption.</p>
|
|
<div class="code-block"> Shuffle 0 (CC0, Bern):
|
|
ProductArgument .............. PASS
|
|
HadamardArgument ........... PASS
|
|
ZeroArgument ............. PASS
|
|
SingleValueProduct ......... PASS
|
|
MultiExponentiationArgument .. PASS
|
|
==> VERIFIED
|
|
|
|
Shuffle 1 (CC1, Zurich): ==> VERIFIED
|
|
Shuffle 2 (CC2, Geneva): ==> VERIFIED
|
|
Shuffle 3 (CC3, Lugano): ==> VERIFIED
|
|
Shuffle 4 (Electoral Board): ==> VERIFIED</div>
|
|
</div>
|
|
|
|
<div class="step">
|
|
<span class="step-num">3</span>
|
|
<div class="step-title">Verify ballot count consistency</div>
|
|
<p style="margin-top:8px;">Confirm that the number of ballots is preserved at every stage: input to the first shuffle = output of the last shuffle = number of decrypted votes.</p>
|
|
<div class="code-block"> Ballots submitted: 6
|
|
Ballots decrypted: 6
|
|
==> PASS: Every ballot is accounted for.</div>
|
|
</div>
|
|
|
|
<h3>8.4 Interpreting Verification Results</h3>
|
|
<p>If all checks pass, the Verifier provides mathematical certainty that:</p>
|
|
<ol>
|
|
<li>All key holders proved knowledge of their secret keys</li>
|
|
<li>All shuffles were honest permutations + re-encryptions (no votes added, removed, or changed)</li>
|
|
<li>The ballot count is consistent throughout the pipeline</li>
|
|
<li>The final tally correctly reflects the decrypted ballots</li>
|
|
</ol>
|
|
|
|
<div class="warning">If <strong>any</strong> check fails, the election result <strong>must not be published</strong>. A failed shuffle proof indicates that a CC may have tampered with the ballots. Contact the Federal Chancellery and the cantonal authority immediately.</div>
|
|
|
|
<!-- ============================================================ -->
|
|
<!-- CHAPTER 9: FEDERAL CHANCELLERY -->
|
|
<!-- ============================================================ -->
|
|
<h2>9. Federal Chancellery & External Examiners</h2>
|
|
|
|
<h3>9.1 Oversight Role</h3>
|
|
<div class="role-header">
|
|
<div class="role-name">Federal Chancellery (Bundeskanzlei)</div>
|
|
<div class="role-desc">The highest authority overseeing the e-voting system. Issues the Ordinance on Electronic Voting (OEV), commissions independent examinations, approves cantons for e-voting, and publishes examination reports.</div>
|
|
</div>
|
|
|
|
<p>The Federal Chancellery does not directly operate any component of the e-voting system. Its role is regulatory and supervisory.</p>
|
|
|
|
<h3>9.2 Four Audit Scopes</h3>
|
|
<p>The Federal Chancellery commissions independent examiners across 4 scopes:</p>
|
|
<table>
|
|
<tr><th>Scope</th><th>Subject</th><th>Examiner</th></tr>
|
|
<tr><td>Scope 1</td><td>Cryptographic protocol</td><td>Academic cryptographers</td></tr>
|
|
<tr><td>Scope 2</td><td>System software</td><td>Software security auditors</td></tr>
|
|
<tr><td>Scope 3</td><td>Infrastructure & operations</td><td>Infrastructure security auditors</td></tr>
|
|
<tr><td>Scope 4</td><td>Penetration testing</td><td>Penetration testers + bug bounty community</td></tr>
|
|
</table>
|
|
|
|
<p>Additionally, Swiss Post publishes all source code and documentation, and runs a permanent bug bounty programme through YesWeHack, allowing the public to scrutinize the system.</p>
|
|
|
|
<div class="note-box">The Go PoC is a reimplementation for educational and demonstration purposes. It has not undergone the formal examination process. In a production deployment, all four audit scopes would need to be passed before the system is approved for use in federal elections.</div>
|
|
|
|
<!-- ============================================================ -->
|
|
<!-- APPENDIX A: COMMAND REFERENCE -->
|
|
<!-- ============================================================ -->
|
|
<h2>Appendix A: Command Reference</h2>
|
|
|
|
<table>
|
|
<tr><th>Command</th><th>Description</th><th>Key Flags</th></tr>
|
|
<tr>
|
|
<td><code>evote demo</code></td>
|
|
<td>Run a full election ceremony: setup → vote → tally → verify</td>
|
|
<td><code>--voters=N</code> (default 10)<br><code>--options=N</code> (default 2)</td>
|
|
</tr>
|
|
<tr>
|
|
<td><code>evote present</code></td>
|
|
<td>Interactive step-by-step presentation mode with role-play narration</td>
|
|
<td>(same as demo)</td>
|
|
</tr>
|
|
<tr>
|
|
<td><code>evote serve</code></td>
|
|
<td>Serve web presentations on local network (iPad-optimized)</td>
|
|
<td><code>--port=N</code> (default 8080)</td>
|
|
</tr>
|
|
<tr>
|
|
<td><code>evote --help</code></td>
|
|
<td>Show available commands and flags</td>
|
|
<td>--</td>
|
|
</tr>
|
|
</table>
|
|
|
|
<h3>Example Sessions</h3>
|
|
<div class="code-block"># Minimal election: 3 voters, 2 candidates
|
|
./evote demo --voters=3 --options=2
|
|
|
|
# Larger election: 100 voters, 5 candidates
|
|
./evote demo --voters=100 --options=5
|
|
|
|
# Step-by-step theatrical presentation
|
|
./evote present
|
|
|
|
# Serve web presentations on local network
|
|
./evote serve --port=8080</div>
|
|
|
|
<!-- ============================================================ -->
|
|
<!-- APPENDIX B: CEREMONY CHECKLIST -->
|
|
<!-- ============================================================ -->
|
|
<h2>Appendix B: Ceremony Checklist</h2>
|
|
|
|
<h3>Day 1 -- Configuration</h3>
|
|
<ul class="checklist">
|
|
<li>Cantonal Administrator: election parameters defined (voters, options)</li>
|
|
<li>Cantonal Administrator: cryptographic group generated (safe prime p = 2q + 1)</li>
|
|
<li>CC0: key pair generated, Schnorr proof valid</li>
|
|
<li>CC1: key pair generated, Schnorr proof valid</li>
|
|
<li>CC2: key pair generated, Schnorr proof valid</li>
|
|
<li>CC3: key pair generated, Schnorr proof valid</li>
|
|
<li>Cantonal Administrator: Election Public Key computed (product of 5 keys)</li>
|
|
<li>Cantonal Administrator: candidate encoding computed</li>
|
|
<li>Cantonal Administrator: voting cards generated for all voters</li>
|
|
</ul>
|
|
|
|
<h3>Day 2 -- Release</h3>
|
|
<ul class="checklist">
|
|
<li>Electoral Board: minimum 2 members constituted, passwords set</li>
|
|
<li>Electoral Board: EB key pair generated from passwords</li>
|
|
<li>Verifier: setup verification run -- all checks PASS</li>
|
|
<li>Cantonal Administrator: voter portal activated</li>
|
|
<li>Printing Office: voting cards printed and mailed</li>
|
|
</ul>
|
|
|
|
<h3>Voting Period</h3>
|
|
<ul class="checklist">
|
|
<li>All voters: authenticated, voted, verified return codes, confirmed</li>
|
|
<li>Swiss Post: system monitoring active, no modifications (red phase)</li>
|
|
</ul>
|
|
|
|
<h3>Day 3 -- Tally</h3>
|
|
<ul class="checklist">
|
|
<li>CC0: shuffle + re-encrypt + Bayer-Groth proof + partial decrypt</li>
|
|
<li>CC1: shuffle + re-encrypt + Bayer-Groth proof + partial decrypt</li>
|
|
<li>CC2: shuffle + re-encrypt + Bayer-Groth proof + partial decrypt</li>
|
|
<li>CC3: shuffle + re-encrypt + Bayer-Groth proof + partial decrypt</li>
|
|
<li>Electoral Board: final shuffle + proof + full decryption (passwords entered)</li>
|
|
<li>Cantonal Administrator: votes decoded, result tallied</li>
|
|
<li>Verifier: 4 key proofs verified -- all PASS</li>
|
|
<li>Verifier: 5 shuffle proofs verified -- all PASS</li>
|
|
<li>Verifier: ballot count consistency -- PASS</li>
|
|
<li>Cantonal Administrator: result published</li>
|
|
</ul>
|
|
|
|
<!-- ============================================================ -->
|
|
<!-- APPENDIX C: MAPPING -->
|
|
<!-- ============================================================ -->
|
|
<h2>Appendix C: Mapping -- Production System vs. Go PoC</h2>
|
|
|
|
<table>
|
|
<tr><th>Aspect</th><th>Production System</th><th>Go PoC</th></tr>
|
|
<tr><td>Language</td><td>Java 21 + TypeScript + C#</td><td>Go</td></tr>
|
|
<tr><td>Prime size</td><td>3072 bits (128-bit security)</td><td>256 bits (demo only)</td></tr>
|
|
<tr><td>Infrastructure</td><td>Kubernetes cluster + 4 bare-metal CCs + SDM machines</td><td>Single binary, single machine</td></tr>
|
|
<tr><td>Networking</td><td>HTTPS/TLS, RSocket/CBOR, ActiveMQ</td><td>In-memory (no network)</td></tr>
|
|
<tr><td>Persistence</td><td>PostgreSQL databases</td><td>In-memory (no persistence)</td></tr>
|
|
<tr><td>SDM</td><td>Electron desktop app, air-gapped Windows machines</td><td>CLI commands</td></tr>
|
|
<tr><td>Voter Portal</td><td>Angular SPA, 4 languages</td><td>Simulated in CLI</td></tr>
|
|
<tr><td>Verifier</td><td>Standalone Java application, 50 checks</td><td>Built into <code>demo</code> command</td></tr>
|
|
<tr><td>Electoral Board</td><td>Physical password entry on air-gapped machine</td><td>Simulated key derivation</td></tr>
|
|
<tr><td>Voting cards</td><td>Printed on paper, mailed by post</td><td>Displayed on screen</td></tr>
|
|
<tr><td>ElGamal encryption</td><td>Identical algorithm</td><td>Identical algorithm</td></tr>
|
|
<tr><td>Schnorr proofs</td><td>Identical algorithm</td><td>Identical algorithm</td></tr>
|
|
<tr><td>Bayer-Groth shuffle</td><td>Identical algorithm</td><td>Identical algorithm</td></tr>
|
|
<tr><td>Fiat-Shamir heuristic</td><td>SHA3-256 recursive hash</td><td>SHA3-256 recursive hash</td></tr>
|
|
<tr><td>Role structure</td><td>Distributed across organizations</td><td>Same roles, single operator</td></tr>
|
|
<tr><td>Four-eyes principle</td><td>Enforced physically</td><td>Organizational (not enforced by software)</td></tr>
|
|
<tr><td>Source code</td><td>~500,000 lines across 14 repos</td><td>~6,500 lines, 1 module</td></tr>
|
|
<tr><td>Dependencies</td><td>BouncyCastle, Spring, Angular, Electron, ...</td><td>Cobra + x/crypto</td></tr>
|
|
</table>
|
|
|
|
<div class="separator"></div>
|
|
|
|
<p style="text-align:center; color:#888; font-size:9pt; margin-top:30px;">
|
|
End of Manual<br>
|
|
Swiss Post E-Voting Go PoC -- Operator Manual v1.0<br>
|
|
February 2026
|
|
</p>
|
|
|
|
</body>
|
|
</html>
|