To save as PDF: Safari → File → Print → Save as PDF
Or: Cmd+P → select "Save as PDF" in the bottom-left dropdown.
🇨🇭
Operator Manual
Swiss Post E-Voting System
Go Proof-of-Concept Implementation
Version 1.0
February 2026
This manual describes the operational procedures for all roles
participating in the e-voting election ceremony, mapped to the
Go PoC command-line tool evote.
The role structure follows the Ordinance on Electronic Voting (OEV/VEleS)
as mandated by the Federal Chancellery.
Table of Contents
1. Introduction
1.1 Purpose of This Manual
1.2 System Overview
1.3 Role Structure & Legal Basis
1.4 Prerequisites
2. Cantonal Administrator
2.1 Role Description
2.2 Day 1 -- Configuration Phase
2.3 Day 2 -- Release Phase
2.4 Day 3 -- Tally Phase
3. Electoral Board
3.1 Role Description
3.2 Constituting the Board (Day 2)
3.3 Authorizing Decryption (Day 3)
4. Swiss Post -- System Provider
4.1 Role Description
4.2 Infrastructure & Central Services
4.3 Red Phase (Voting Period)
5. Control Component Operators
5.1 Role Description & Split Trust
5.2 Key Generation (Setup Phase)
5.3 Shuffle & Partial Decryption (Tally Phase)
6. Printing Office
6.1 Role Description
6.2 Voting Card Generation & Distribution
7. Voter
7.1 Role Description
7.2 Voting Procedure
7.3 Verifying Your Vote (Individual Verifiability)
8. Independent Verifier
8.1 Role Description
8.2 Setup Verification (Day 2)
8.3 Tally Verification (Day 3)
8.4 Interpreting Verification Results
9. Federal Chancellery & External Examiners
9.1 Oversight Role
9.2 Four Audit Scopes
Appendix A: Command Reference
Appendix B: Ceremony Checklist
Appendix C: Mapping -- Production System vs. Go PoC
1. Introduction
1.1 Purpose of This Manual
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 evote.
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.
Despite the simplified infrastructure, the Go PoC preserves the same role structure 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.
1.2 System Overview
The e-voting system operates in three phases across three days:
| Phase | Day | Key Operations | Primary Roles |
| Configuration | Day 1 | Key generation, voting card creation, system setup | Cantonal Admin, CC Operators |
| Release & Voting | Day 2 + Voting Period | Electoral Board constitution, setup verification, voter portal activation, ballot casting | Electoral Board, Verifier, Voters |
| Tally | Day 3 | Mixing, decryption, tally verification, result publication | CC Operators, Electoral Board, Verifier |
1.3 Role Structure & Legal Basis
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.
The following organizational hierarchy applies:
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)
In the Go PoC, all roles are exercised by the same person on the same machine via different evote subcommands. In production, these roles are performed by different people on different machines with strict access controls and the four-eyes principle.
1.4 Prerequisites
To operate the Go PoC system, you need:
- The
evote binary (build with go build ./cmd/evote from the evote/ directory)
- Go 1.21 or later (only for building; the binary is self-contained)
- A terminal (macOS Terminal, Linux shell, or Windows command prompt)
- No network access, database, or external services required
# Build the binary
cd evote/
go build -o evote ./cmd/evote
# Verify it works
./evote --help
2. Cantonal Administrator
2.1 Role Description
The Cantonal Administrator operates the SDM under cantonal authority, not under Swiss Post. All personal data (electoral registers) remains exclusively at the canton. The four-eyes principle applies to all SDM operations.
In the Go PoC, the Cantonal Administrator's role corresponds to initiating the election setup and configuring the system parameters.
2.2 Day 1 -- Configuration Phase
1
Initialize the election and generate cryptographic parameters
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.
# Full automated ceremony (all roles in one command):
./evote demo --voters=6 --options=2
The demo command performs:
- Safe prime group generation (p = 2q + 1, both prime, 256-bit)
- Generator selection (g = 4, verified as quadratic residue)
- Candidate encoding (Alice = 2² = 4, Bob = 3² = 9, etc.)
2
Coordinate Control Component key generation
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.
Expected output:
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
3
Combine public keys into Election Public Key
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.
ElectionPK = PK0 * PK1 * PK2 * PK3 * PK_EB mod p
4
Generate voting cards
The system generates a unique voting card for each registered voter containing:
- Start Voting Key (SVK) -- used for authentication
- Ballot Casting Key (BCK) -- used to confirm the vote
- Choice Return Codes -- one per candidate, used for individual verifiability
- Vote Cast Code (VCC) -- confirms the vote is sealed
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 never be transmitted electronically.
2.3 Day 2 -- Release Phase
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.
2.4 Day 3 -- Tally Phase
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.
# 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
3. Electoral Board
3.1 Role Description
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.
3.2 Constituting the Board (Day 2)
1
Each board member sets a password
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).
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)
If any board member forgets their password, the ballot box cannot be decrypted. There is no recovery mechanism. This is by design: it prevents any single party from decrypting without the board's collective authorization.
In the Go PoC, the Electoral Board key is generated automatically during the demo command. The system simulates the password entry process.
3.3 Authorizing Decryption (Day 3)
1
Enter passwords on the Tally SDM
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.
2
Authorize the final shuffle and decryption
The system performs the 5th Bayer-Groth shuffle, generates its proof, and removes the last encryption layer. The decrypted votes appear in random order.
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.
4. Swiss Post -- System Provider
4.1 Role Description
4.2 Infrastructure & Central Services
In the production system, Swiss Post operates:
| Component | Technology | Purpose |
| Access Layer | WAF, TLS termination | Protects the Voting Server from direct internet access |
| Voting Server | Spring Boot, Kubernetes | Processes vote submissions, relays to CCs |
| 3 Control Components | Bare metal, diverse OS | Distributed key generation, return codes, shuffle |
| Message Broker | Apache ActiveMQ Artemis | Asynchronous communication between Server and CCs |
| Databases | PostgreSQL | Stores encrypted ballots, configuration, audit logs |
In the Go PoC, all of Swiss Post's infrastructure is simulated within the evote binary. The Voting Server, message broker, and database are replaced by in-memory data structures. The cryptographic operations are identical.
4.3 Red Phase (Voting Period)
During the voting period, Swiss Post enforces a "red phase":
- No system modifications are permitted
- Infrastructure access is strictly controlled
- SIEM monitoring is active for anomaly detection
- Only pre-authorized personnel may access the systems
In the Go PoC, there is no persistent infrastructure. The "red phase" is conceptual: once the demo command enters the voting phase, the system processes all ballots without interruption.
5. Control Component Operators
5.1 Role Description & Split Trust
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.
In the production system, the 4 CCs are deployed on bare-metal servers:
| CC | Location | Hardware | OS | Operated By |
| CC0 | Canton premises | ProLiant BL460c | RHEL 9.6 | Canton |
| CC1 | Swiss Post DC | ProLiant BL460c | Debian 12.12 | Swiss Post Team A |
| CC2 | Swiss Post DC | ProLiant BL460c | Ubuntu 24.04 | Swiss Post Team B |
| CC3 | Swiss Post DC | ProLiant DL385 | Windows Server 2022 | Swiss Post Team C |
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.
5.2 Key Generation (Setup Phase)
1
Generate the key pair
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.
2
Generate the Schnorr proof of knowledge
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.
3
Publish public key and proof
The public key and Schnorr proof are transmitted to the central system for combination with the other CCs' keys.
5.3 Shuffle & Partial Decryption (Tally Phase)
On Day 3, each CC performs the following operations in sequence (CC0 first, then CC1, CC2, CC3):
1
Receive the current ciphertext batch
CC0 receives the original encrypted ballots from the ballot box. Subsequent CCs receive the output of the previous CC's shuffle.
2
Generate a random permutation
Sample a uniformly random permutation π of {0, ..., N-1}. This permutation determines the new order of the ballots.
3
Re-encrypt and shuffle
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.
4
Generate the Bayer-Groth shuffle proof
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.
5
Destroy the permutation
Securely erase the permutation π and all re-encryption randomness. After this step, even the CC operator cannot determine the correspondence between input and output ciphertexts.
6
Perform partial decryption
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.
The permutation must be destroyed immediately after the proof is generated. If any CC retains its permutation, the privacy guarantee for that shuffle step is compromised.
6. Printing Office
6.1 Role Description
6.2 Voting Card Generation & Distribution
The Cantonal Administrator generates voting card data during the Configuration Phase. The Printing Office receives the data and produces physical cards.
Each voting card contains:
| Field | Purpose | Example |
| Start Voting Key (SVK) | Authentication credential | SVK-0000 |
| Ballot Casting Key (BCK) | Vote confirmation credential | BCK-0000 |
| Choice Return Codes | Verify correct recording (one per candidate) | CC00 (Alice), CC01 (Bob) |
| Vote Cast Code (VCC) | Confirm vote is sealed | VCC00 |
In the Go PoC, the demo command displays all voting cards on screen:
+------------------------------------------------------+
| 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 |
+------------------------------------------------------+
Voting cards must be printed on physical paper and delivered via postal mail. The codes must never 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.
7. Voter
7.1 Role Description
7.2 Voting Procedure
1
Open the voting portal
Navigate to the official URL provided on your voting card or the cantonal website. Verify the TLS certificate. Accept the legal terms.
2
Authenticate
Enter your Start Voting Key (SVK) and date of birth. The server verifies your identity using an Argon2id hash (the SVK is never stored in plaintext).
In the Go PoC, authentication is simulated automatically.
3
Cast your vote
Select your candidate(s) on the ballot. Your browser encrypts the vote locally using ElGamal encryption under the Election Public Key. The plaintext vote never leaves your device.
The browser sends two large numbers (γ, φ) to the server -- pure noise to anyone without all 5 secret keys.
4
Verify the Choice Return Code
The server displays a Choice Return Code. Compare it to the code on your physical voting card for the candidate you selected.
- If the codes match: your vote was recorded correctly. Proceed to confirm.
- If the codes do not match: STOP. Do not confirm. Contact the cantonal authority. Your vote may have been intercepted or modified.
5
Confirm with the Ballot Casting Key
Enter your Ballot Casting Key (BCK) to finalize your vote. This is the second factor that prevents the server from confirming a vote without your explicit action.
6
Verify the Vote Cast Code
The server displays a Vote Cast Code (VCC). Compare it to your voting card. If it matches, your vote is sealed and confirmed.
7.3 Verifying Your Vote (Individual Verifiability)
The return code mechanism provides individual verifiability: each voter can personally verify that their vote was cast as intended and recorded as cast, without needing to trust any single system component.
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).
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.
8. Independent Verifier
8.1 Role Description
The Verifier is operated by the electoral commission under the responsibility of the cantons. It provides universal verifiability: any party can audit the election result using only public data and mathematics.
8.2 Setup Verification (Day 2)
After the Configuration Phase, the Verifier checks that the setup was performed correctly:
- Key proofs: Verify the Schnorr proof for each CC's public key (proves the CC knows the corresponding secret key)
- Key combination: Verify the Election Public Key is the correct product of all 5 individual keys
- Voting card integrity: Verify return code mappings are consistent
In the Go PoC, setup verification is performed automatically as part of the demo command.
8.3 Tally Verification (Day 3)
After tallying, the Verifier performs the most critical checks:
1
Verify all Schnorr proofs (4 key proofs)
For each CC, recompute the Schnorr verification equation: gz · pk-e should reconstruct the commitment c, and H(p, q, g, pk, c) should equal e.
CC0 (Bern): [PASS]
CC1 (Zurich): [PASS]
CC2 (Geneva): [PASS]
CC3 (Lugano): [PASS]
2
Verify all Bayer-Groth shuffle proofs (5 shuffle proofs)
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.
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
3
Verify ballot count consistency
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.
Ballots submitted: 6
Ballots decrypted: 6
==> PASS: Every ballot is accounted for.
8.4 Interpreting Verification Results
If all checks pass, the Verifier provides mathematical certainty that:
- All key holders proved knowledge of their secret keys
- All shuffles were honest permutations + re-encryptions (no votes added, removed, or changed)
- The ballot count is consistent throughout the pipeline
- The final tally correctly reflects the decrypted ballots
If any check fails, the election result must not be published. A failed shuffle proof indicates that a CC may have tampered with the ballots. Contact the Federal Chancellery and the cantonal authority immediately.
9. Federal Chancellery & External Examiners
9.1 Oversight Role
The Federal Chancellery does not directly operate any component of the e-voting system. Its role is regulatory and supervisory.
9.2 Four Audit Scopes
The Federal Chancellery commissions independent examiners across 4 scopes:
| Scope | Subject | Examiner |
| Scope 1 | Cryptographic protocol | Academic cryptographers |
| Scope 2 | System software | Software security auditors |
| Scope 3 | Infrastructure & operations | Infrastructure security auditors |
| Scope 4 | Penetration testing | Penetration testers + bug bounty community |
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.
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.
Appendix A: Command Reference
| Command | Description | Key Flags |
evote demo |
Run a full election ceremony: setup → vote → tally → verify |
--voters=N (default 10)
--options=N (default 2) |
evote present |
Interactive step-by-step presentation mode with role-play narration |
(same as demo) |
evote serve |
Serve web presentations on local network (iPad-optimized) |
--port=N (default 8080) |
evote --help |
Show available commands and flags |
-- |
Example Sessions
# 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
Appendix B: Ceremony Checklist
Day 1 -- Configuration
- Cantonal Administrator: election parameters defined (voters, options)
- Cantonal Administrator: cryptographic group generated (safe prime p = 2q + 1)
- CC0: key pair generated, Schnorr proof valid
- CC1: key pair generated, Schnorr proof valid
- CC2: key pair generated, Schnorr proof valid
- CC3: key pair generated, Schnorr proof valid
- Cantonal Administrator: Election Public Key computed (product of 5 keys)
- Cantonal Administrator: candidate encoding computed
- Cantonal Administrator: voting cards generated for all voters
Day 2 -- Release
- Electoral Board: minimum 2 members constituted, passwords set
- Electoral Board: EB key pair generated from passwords
- Verifier: setup verification run -- all checks PASS
- Cantonal Administrator: voter portal activated
- Printing Office: voting cards printed and mailed
Voting Period
- All voters: authenticated, voted, verified return codes, confirmed
- Swiss Post: system monitoring active, no modifications (red phase)
Day 3 -- Tally
- CC0: shuffle + re-encrypt + Bayer-Groth proof + partial decrypt
- CC1: shuffle + re-encrypt + Bayer-Groth proof + partial decrypt
- CC2: shuffle + re-encrypt + Bayer-Groth proof + partial decrypt
- CC3: shuffle + re-encrypt + Bayer-Groth proof + partial decrypt
- Electoral Board: final shuffle + proof + full decryption (passwords entered)
- Cantonal Administrator: votes decoded, result tallied
- Verifier: 4 key proofs verified -- all PASS
- Verifier: 5 shuffle proofs verified -- all PASS
- Verifier: ballot count consistency -- PASS
- Cantonal Administrator: result published
Appendix C: Mapping -- Production System vs. Go PoC
| Aspect | Production System | Go PoC |
| Language | Java 21 + TypeScript + C# | Go |
| Prime size | 3072 bits (128-bit security) | 256 bits (demo only) |
| Infrastructure | Kubernetes cluster + 4 bare-metal CCs + SDM machines | Single binary, single machine |
| Networking | HTTPS/TLS, RSocket/CBOR, ActiveMQ | In-memory (no network) |
| Persistence | PostgreSQL databases | In-memory (no persistence) |
| SDM | Electron desktop app, air-gapped Windows machines | CLI commands |
| Voter Portal | Angular SPA, 4 languages | Simulated in CLI |
| Verifier | Standalone Java application, 50 checks | Built into demo command |
| Electoral Board | Physical password entry on air-gapped machine | Simulated key derivation |
| Voting cards | Printed on paper, mailed by post | Displayed on screen |
| ElGamal encryption | Identical algorithm | Identical algorithm |
| Schnorr proofs | Identical algorithm | Identical algorithm |
| Bayer-Groth shuffle | Identical algorithm | Identical algorithm |
| Fiat-Shamir heuristic | SHA3-256 recursive hash | SHA3-256 recursive hash |
| Role structure | Distributed across organizations | Same roles, single operator |
| Four-eyes principle | Enforced physically | Organizational (not enforced by software) |
| Source code | ~500,000 lines across 14 repos | ~6,500 lines, 1 module |
| Dependencies | BouncyCastle, Spring, Angular, Electron, ... | Cobra + x/crypto |
End of Manual
Swiss Post E-Voting Go PoC -- Operator Manual v1.0
February 2026