Created comprehensive openspec structure: openspec/specs/: - mvp.md: MVP feature overview - architecture.md: System architecture and data flows openspec/changes/add-pqc-voting-mvp/: - proposal.md: Project proposal with scope and rationale - tasks.md: Detailed implementation tasks (6 phases, 30+ tasks) - design.md: Complete design document - Cryptographic algorithms (Paillier, Kyber, Dilithium, ZKP) - Data structures (Block, Blockchain, Ballot) - API endpoint specifications - Security properties matrix - Threat model and mitigations Follows openspec three-stage workflow: 1. Creating changes (proposal-based) 2. Implementation (tracked via tasks) 3. Completion (with validation) Ready for implementation phase with clear requirements. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
4.6 KiB
4.6 KiB
System Architecture
Overview
Client/Server architecture with blockchain-based vote recording and post-quantum cryptography.
Components
Frontend (Next.js)
- Voting Interface: Election display and ballot selection
- Crypto Client: Paillier encryption and Dilithium signing
- Blockchain Viewer: Display blockchain and verify integrity
- Results Display: Show voting results with proofs
Backend (FastAPI)
- Auth Service: JWT authentication and voter verification
- Voting API: Handle vote submission and blockchain management
- Crypto Service: Paillier key generation, encryption, homomorphic ops
- Blockchain Service: Block creation, chain validation, signature verification
- Scrutator Service: Vote counting and results generation
Database
- Voter Keys: Store Dilithium public keys
- Blockchain Blocks: Persist encrypted votes and signatures
- Emission List: Track voted voters
- Crypto Keys: Store Paillier/Kyber keys
Data Flow
Vote Submission
Frontend (Voter)
↓
1. Fetch public keys
↓
2. Encrypt ballot (Paillier)
↓
3. Generate ZKP
↓
4. Sign (Dilithium)
↓
Backend (API)
↓
5. Verify signature & ZKP
↓
6. Check emission list
↓
7. Create blockchain block
↓
8. Sign block (Dilithium)
↓
9. Persist to database
↓
10. Return confirmation
Vote Counting
Scrutator
↓
1. Fetch blockchain blocks
↓
2. Verify chain integrity
↓
3. Verify all block signatures
↓
4. Homomorphic summation: E(total) = E(v1) × E(v2) × ... × E(vn)
↓
5. Decrypt with Paillier private key
↓
6. Generate verification proofs
↓
7. Publish results
Cryptographic Workflow
Election Setup
- Generate Paillier keypair (Pu, Pr)
- Generate Kyber keypair (KPu, KPr) to protect Pr
- Generate Dilithium keypair (Du, Dr) for block signing
- Publish (Pu, Du)
Voter Registration
- Voter authenticates (JWT)
- Voter generates Dilithium keypair (du, dr)
- System stores voter's du in database
Ballot Submission
- Voter selects candidate: v ∈ {0, 1}
- Frontend: E(v) = Paillier.encrypt(v, Pu)
- Frontend: π = ZKP.prove(E(v) is 0 or 1)
- Frontend: σ = Dilithium.sign(E(v) || π, dr)
- Frontend: submit(voter_id, E(v), π, σ)
- Backend: verify(σ, du) ✓
- Backend: verify(π) ✓
- Backend: check(voter_id not in emission_list) ✓
- Backend: B = Block(index, prev_hash, timestamp, E(v), tx_id)
- Backend: σ_block = Dilithium.sign(B, Dr)
- Backend: blockchain.append(B, σ_block)
Vote Counting
- C ← retrieve all blocks from blockchain
- For each block b in C: verify(b.signature, Du)
- For each block b in C: verify(hash_chain(b.prev_hash))
- E(total) ← E(0)
- For each block b in C: E(total) ← E(total) × b.E(v)
- total ← Paillier.decrypt(E(total), Pr)
- publish(total, proofs)
Security Properties
Vote Secrecy
- Votes encrypted with Paillier before leaving client
- Server never sees plaintext votes
- Homomorphic summation prevents individual vote leakage
Vote Integrity
- Blockchain structure prevents tampering
- SHA-256 hash chain ensures immutability
- Dilithium signatures verify block authenticity
Voter Authentication
- JWT tokens verify voter session
- Dilithium signatures verify ballot authorship
- Emission list prevents double voting
Anonymity
- Only transaction ID stored with vote (not voter ID)
- Voter verified once at submission
- Homomorphic summation preserves anonymity
Verifiability
- ZKP proves ballot validity without revealing vote
- Anyone can verify blockchain integrity
- Hash chain verification ensures chain validity
Post-Quantum Security
- Kyber protects Paillier private key
- Dilithium signatures resist quantum attacks
- Future-proof against quantum computers
File Structure
backend/
├── crypto_tools.py # Paillier, Kyber, Dilithium, ZKP
├── blockchain.py # Block, Blockchain classes
├── routes/
│ ├── votes.py # Voting endpoints
│ └── auth.py # Authentication
├── models.py # Database models
├── services.py # Business logic
└── scripts/
└── scrutator.py # Vote counting
frontend/
├── components/
│ ├── voting-interface.tsx
│ └── blockchain-viewer.tsx
├── lib/
│ ├── crypto-client.ts
│ └── blockchain-verify.ts
└── app/dashboard/
├── blockchain/page.tsx
├── votes/
│ ├── active/page.tsx
│ ├── results/page.tsx
│ └── history/page.tsx
└── profile/page.tsx