# Design Document Change ID: `add-pqc-voting-mvp` ## Cryptographic Design ### Paillier Homomorphic Encryption - **Key Generation**: Generate (n, λ, g) keypair - **Encryption**: E(m) = g^m * r^n mod n^2 where r is random - **Decryption**: D(c) = L(c^λ mod n^2) / L(g^λ mod n^2) mod n - **Homomorphic Property**: E(m1) * E(m2) = E(m1 + m2) mod n^2 - **Vote Property**: E(0) * E(0) * ... * E(1) = E(total_votes) - **Usage**: Encrypt votes (0 or 1), sum encrypted votes without decryption ### Kyber (ML-KEM) - **Key Encapsulation**: Generate (ek, dk) keypair - **Encapsulation**: (c, ss) = Kyber.Encaps(ek) - shared secret ss - **Decapsulation**: ss = Kyber.Decaps(c, dk) - **Usage**: Encrypt Paillier private key with Kyber public key for PQC protection - **Benefit**: Protects vote counts against future quantum attacks ### Dilithium (ML-DSA) - **Key Generation**: Generate (sk, vk) signing keypair per voter - **Signature**: σ = Dilithium.Sign(msg, sk) - **Verification**: 0/1 = Dilithium.Verify(msg, σ, vk) - **Usage**: - Voter signs encrypted ballot - Authority signs blockchain blocks - **Benefit**: Post-quantum resistant authentication ### Zero-Knowledge Proof (Simplified) - **Goal**: Prove E(v) is encryption of 0 or 1 without revealing v - **Protocol**: 1. Voter commits to 0 and 1: c0 = E(0), c1 = E(1) 2. Voter selects random r, computes challenge response 3. Server verifies without learning v - **Implementation**: Simple version using Paillier properties ### SHA-256 Hash Chain - **Block Hash**: H = SHA256(index || prev_hash || timestamp || E(v) || signature) - **Chain Property**: Each block contains previous block's hash - **Verification**: Recompute all hashes and verify chain integrity - **Immutability**: Changing any block invalidates entire chain ## Data Structures ### Block ```python class Block: index: int # Block number (0, 1, 2, ...) prev_hash: str # SHA256 of previous block timestamp: float # Unix timestamp encrypted_vote: str # Paillier encrypted ballot transaction_id: str # Unique vote identifier block_hash: str # SHA256 of this block signature: str # Dilithium signature of block ``` ### Blockchain ```python class Blockchain: chain: List[Block] # List of blocks authority_sk: str # Authority's Dilithium private key authority_vk: str # Authority's Dilithium public key paillier_pubkey: str # Paillier public key def add_block(encrypted_vote, tx_id) -> Block def verify_chain() -> bool def get_encrypted_sum() -> int (homomorphic) ``` ### Vote Ballot ```typescript interface Ballot { voter_id: string # Voter identifier (verified once) encrypted_vote: string # E(v) with Paillier zkp_proof: string # ZKP that E(v) is 0 or 1 signature: string # Dilithium signature timestamp: number # Client-side timestamp } ``` ### Election Setup ```python class ElectionSetup: paillier_pubkey: str # Distributed to voters paillier_privkey: str # Kyber-encrypted, kept secret authority_sign_sk: str # Dilithium signing key authority_sign_vk: str # Dilithium verification key (public) ``` ## API Endpoints ### POST /api/votes/setup **Purpose**: Initialize election with cryptographic keys **Request**: ```json { "election_id": "2025-vote-01" } ``` **Response**: ```json { "public_keys": { "paillier": "...base64...", "dilithium": "...base64..." }, "status": "initialized" } ``` ### GET /api/votes/public-keys **Purpose**: Retrieve public keys for client encryption **Response**: ```json { "paillier_pubkey": "...base64...", "authority_pubkey": "...base64..." } ``` ### POST /api/votes/register-voter **Purpose**: Register voter with their Dilithium public key **Request**: ```json { "voter_id": "user123", "dilithium_pubkey": "...base64..." } ``` **Response**: ```json { "status": "registered", "voter_id": "user123" } ``` ### POST /api/votes/submit **Purpose**: Submit encrypted ballot **Request**: ```json { "voter_id": "user123", "encrypted_vote": "...base64...", "zkp_proof": "...base64...", "signature": "...base64..." } ``` **Response**: ```json { "status": "recorded", "transaction_id": "tx-abc123", "block_index": 42 } ``` ### GET /api/votes/blockchain **Purpose**: Retrieve blockchain state **Response**: ```json { "blocks": [ { "index": 0, "prev_hash": "0000...", "timestamp": 1730000000, "encrypted_vote": "...base64...", "transaction_id": "tx-0", "block_hash": "abc123...", "signature": "...base64..." } ], "verification": { "chain_valid": true, "signatures_valid": true, "total_votes": 42 } } ``` ### GET /api/votes/results **Purpose**: Get vote counting results **Response**: ```json { "total_votes": 42, "results": { "yes": 28, "no": 14 }, "verification": { "chain_valid": true, "homomorphic_verified": true, "proofs": "...base64..." } } ``` ## Security Properties | Property | Implementation | Guarantee | |----------|----------------|-----------| | **Vote Secrecy** | Paillier encryption | Encrypted before leaving client | | **Vote Integrity** | Blockchain + Dilithium | Immutable, cryptographically signed | | **Anonymity** | Transaction IDs | Voter verified once, not stored with vote | | **Individual Verifiability** | ZKP + blockchain | Voter can verify their vote is counted | | **Universal Verifiability** | Public blockchain | Anyone can verify results are correct | | **Post-Quantum** | Kyber + Dilithium | Resistant to quantum attacks | ## Threat Model ### Threats & Mitigations 1. **Vote Tampering** - Threat: Attacker modifies a vote after submission - Mitigation: Blockchain prevents modification; hash chain breaks - Verification: Recompute hashes to detect tampering 2. **Double Voting** - Threat: Voter votes multiple times - Mitigation: Emission list (voted voters tracked) - Verification: Check voter_id not already submitted 3. **Vote Disclosure** - Threat: Server leaks which voter voted for which candidate - Mitigation: Paillier encryption; server never sees plaintext votes - Verification: Homomorphic summation prevents vote disclosure 4. **Authority Fraud** - Threat: Authority publishes false results - Mitigation: Blockchain is public; results are cryptographically verified - Verification: Anyone can recompute homomorphic sum 5. **Quantum Attack** - Threat: Future quantum computer breaks encryption - Mitigation: Kyber and Dilithium are post-quantum - Verification: Algorithms certified by NIST (FIPS 203, 204) 6. **Denial of Service** - Threat: Attacker prevents votes from being submitted - Mitigation: Rate limiting on API endpoints - Verification: Blockchain size and performance monitoring ## Implementation Notes - **Vote Encoding**: 0 = "No", 1 = "Yes" (can extend for multiple candidates) - **Key Storage**: Paillier private key protected by Kyber encryption at rest - **Database**: Store blocks, voter keys, emission list - **Frontend Crypto**: Use WASM or Node.js crypto libs for performance - **Verification**: Anyone can download blockchain and verify - **Audit Trail**: Complete blockchain is the audit trail