docs: Add proper openspec configuration for MVP

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>
This commit is contained in:
Alexis Bruneteau 2025-11-06 18:02:33 +01:00
parent bd3fcac8dc
commit 55995365be
6 changed files with 1220 additions and 0 deletions

View File

@ -0,0 +1,456 @@
# OpenSpec Instructions
Instructions for AI coding assistants using OpenSpec for spec-driven development.
## TL;DR Quick Checklist
- Search existing work: `openspec spec list --long`, `openspec list` (use `rg` only for full-text search)
- Decide scope: new capability vs modify existing capability
- Pick a unique `change-id`: kebab-case, verb-led (`add-`, `update-`, `remove-`, `refactor-`)
- Scaffold: `proposal.md`, `tasks.md`, `design.md` (only if needed), and delta specs per affected capability
- Write deltas: use `## ADDED|MODIFIED|REMOVED|RENAMED Requirements`; include at least one `#### Scenario:` per requirement
- Validate: `openspec validate [change-id] --strict` and fix issues
- Request approval: Do not start implementation until proposal is approved
## Three-Stage Workflow
### Stage 1: Creating Changes
Create proposal when you need to:
- Add features or functionality
- Make breaking changes (API, schema)
- Change architecture or patterns
- Optimize performance (changes behavior)
- Update security patterns
Triggers (examples):
- "Help me create a change proposal"
- "Help me plan a change"
- "Help me create a proposal"
- "I want to create a spec proposal"
- "I want to create a spec"
Loose matching guidance:
- Contains one of: `proposal`, `change`, `spec`
- With one of: `create`, `plan`, `make`, `start`, `help`
Skip proposal for:
- Bug fixes (restore intended behavior)
- Typos, formatting, comments
- Dependency updates (non-breaking)
- Configuration changes
- Tests for existing behavior
**Workflow**
1. Review `openspec/project.md`, `openspec list`, and `openspec list --specs` to understand current context.
2. Choose a unique verb-led `change-id` and scaffold `proposal.md`, `tasks.md`, optional `design.md`, and spec deltas under `openspec/changes/<id>/`.
3. Draft spec deltas using `## ADDED|MODIFIED|REMOVED Requirements` with at least one `#### Scenario:` per requirement.
4. Run `openspec validate <id> --strict` and resolve any issues before sharing the proposal.
### Stage 2: Implementing Changes
Track these steps as TODOs and complete them one by one.
1. **Read proposal.md** - Understand what's being built
2. **Read design.md** (if exists) - Review technical decisions
3. **Read tasks.md** - Get implementation checklist
4. **Implement tasks sequentially** - Complete in order
5. **Confirm completion** - Ensure every item in `tasks.md` is finished before updating statuses
6. **Update checklist** - After all work is done, set every task to `- [x]` so the list reflects reality
7. **Approval gate** - Do not start implementation until the proposal is reviewed and approved
### Stage 3: Archiving Changes
After deployment, create separate PR to:
- Move `changes/[name]/``changes/archive/YYYY-MM-DD-[name]/`
- Update `specs/` if capabilities changed
- Use `openspec archive [change] --skip-specs --yes` for tooling-only changes
- Run `openspec validate --strict` to confirm the archived change passes checks
## Before Any Task
**Context Checklist:**
- [ ] Read relevant specs in `specs/[capability]/spec.md`
- [ ] Check pending changes in `changes/` for conflicts
- [ ] Read `openspec/project.md` for conventions
- [ ] Run `openspec list` to see active changes
- [ ] Run `openspec list --specs` to see existing capabilities
**Before Creating Specs:**
- Always check if capability already exists
- Prefer modifying existing specs over creating duplicates
- Use `openspec show [spec]` to review current state
- If request is ambiguous, ask 12 clarifying questions before scaffolding
### Search Guidance
- Enumerate specs: `openspec spec list --long` (or `--json` for scripts)
- Enumerate changes: `openspec list` (or `openspec change list --json` - deprecated but available)
- Show details:
- Spec: `openspec show <spec-id> --type spec` (use `--json` for filters)
- Change: `openspec show <change-id> --json --deltas-only`
- Full-text search (use ripgrep): `rg -n "Requirement:|Scenario:" openspec/specs`
## Quick Start
### CLI Commands
```bash
# Essential commands
openspec list # List active changes
openspec list --specs # List specifications
openspec show [item] # Display change or spec
openspec diff [change] # Show spec differences
openspec validate [item] # Validate changes or specs
openspec archive [change] [--yes|-y] # Archive after deployment (add --yes for non-interactive runs)
# Project management
openspec init [path] # Initialize OpenSpec
openspec update [path] # Update instruction files
# Interactive mode
openspec show # Prompts for selection
openspec validate # Bulk validation mode
# Debugging
openspec show [change] --json --deltas-only
openspec validate [change] --strict
```
### Command Flags
- `--json` - Machine-readable output
- `--type change|spec` - Disambiguate items
- `--strict` - Comprehensive validation
- `--no-interactive` - Disable prompts
- `--skip-specs` - Archive without spec updates
- `--yes`/`-y` - Skip confirmation prompts (non-interactive archive)
## Directory Structure
```
openspec/
├── project.md # Project conventions
├── specs/ # Current truth - what IS built
│ └── [capability]/ # Single focused capability
│ ├── spec.md # Requirements and scenarios
│ └── design.md # Technical patterns
├── changes/ # Proposals - what SHOULD change
│ ├── [change-name]/
│ │ ├── proposal.md # Why, what, impact
│ │ ├── tasks.md # Implementation checklist
│ │ ├── design.md # Technical decisions (optional; see criteria)
│ │ └── specs/ # Delta changes
│ │ └── [capability]/
│ │ └── spec.md # ADDED/MODIFIED/REMOVED
│ └── archive/ # Completed changes
```
## Creating Change Proposals
### Decision Tree
```
New request?
├─ Bug fix restoring spec behavior? → Fix directly
├─ Typo/format/comment? → Fix directly
├─ New feature/capability? → Create proposal
├─ Breaking change? → Create proposal
├─ Architecture change? → Create proposal
└─ Unclear? → Create proposal (safer)
```
### Proposal Structure
1. **Create directory:** `changes/[change-id]/` (kebab-case, verb-led, unique)
2. **Write proposal.md:**
```markdown
## Why
[1-2 sentences on problem/opportunity]
## What Changes
- [Bullet list of changes]
- [Mark breaking changes with **BREAKING**]
## Impact
- Affected specs: [list capabilities]
- Affected code: [key files/systems]
```
3. **Create spec deltas:** `specs/[capability]/spec.md`
```markdown
## ADDED Requirements
### Requirement: New Feature
The system SHALL provide...
#### Scenario: Success case
- **WHEN** user performs action
- **THEN** expected result
## MODIFIED Requirements
### Requirement: Existing Feature
[Complete modified requirement]
## REMOVED Requirements
### Requirement: Old Feature
**Reason**: [Why removing]
**Migration**: [How to handle]
```
If multiple capabilities are affected, create multiple delta files under `changes/[change-id]/specs/<capability>/spec.md`—one per capability.
4. **Create tasks.md:**
```markdown
## 1. Implementation
- [ ] 1.1 Create database schema
- [ ] 1.2 Implement API endpoint
- [ ] 1.3 Add frontend component
- [ ] 1.4 Write tests
```
5. **Create design.md when needed:**
Create `design.md` if any of the following apply; otherwise omit it:
- Cross-cutting change (multiple services/modules) or a new architectural pattern
- New external dependency or significant data model changes
- Security, performance, or migration complexity
- Ambiguity that benefits from technical decisions before coding
Minimal `design.md` skeleton:
```markdown
## Context
[Background, constraints, stakeholders]
## Goals / Non-Goals
- Goals: [...]
- Non-Goals: [...]
## Decisions
- Decision: [What and why]
- Alternatives considered: [Options + rationale]
## Risks / Trade-offs
- [Risk] → Mitigation
## Migration Plan
[Steps, rollback]
## Open Questions
- [...]
```
## Spec File Format
### Critical: Scenario Formatting
**CORRECT** (use #### headers):
```markdown
#### Scenario: User login success
- **WHEN** valid credentials provided
- **THEN** return JWT token
```
**WRONG** (don't use bullets or bold):
```markdown
- **Scenario: User login**
**Scenario**: User login ❌
### Scenario: User login ❌
```
Every requirement MUST have at least one scenario.
### Requirement Wording
- Use SHALL/MUST for normative requirements (avoid should/may unless intentionally non-normative)
### Delta Operations
- `## ADDED Requirements` - New capabilities
- `## MODIFIED Requirements` - Changed behavior
- `## REMOVED Requirements` - Deprecated features
- `## RENAMED Requirements` - Name changes
Headers matched with `trim(header)` - whitespace ignored.
#### When to use ADDED vs MODIFIED
- ADDED: Introduces a new capability or sub-capability that can stand alone as a requirement. Prefer ADDED when the change is orthogonal (e.g., adding "Slash Command Configuration") rather than altering the semantics of an existing requirement.
- MODIFIED: Changes the behavior, scope, or acceptance criteria of an existing requirement. Always paste the full, updated requirement content (header + all scenarios). The archiver will replace the entire requirement with what you provide here; partial deltas will drop previous details.
- RENAMED: Use when only the name changes. If you also change behavior, use RENAMED (name) plus MODIFIED (content) referencing the new name.
Common pitfall: Using MODIFIED to add a new concern without including the previous text. This causes loss of detail at archive time. If you arent explicitly changing the existing requirement, add a new requirement under ADDED instead.
Authoring a MODIFIED requirement correctly:
1) Locate the existing requirement in `openspec/specs/<capability>/spec.md`.
2) Copy the entire requirement block (from `### Requirement: ...` through its scenarios).
3) Paste it under `## MODIFIED Requirements` and edit to reflect the new behavior.
4) Ensure the header text matches exactly (whitespace-insensitive) and keep at least one `#### Scenario:`.
Example for RENAMED:
```markdown
## RENAMED Requirements
- FROM: `### Requirement: Login`
- TO: `### Requirement: User Authentication`
```
## Troubleshooting
### Common Errors
**"Change must have at least one delta"**
- Check `changes/[name]/specs/` exists with .md files
- Verify files have operation prefixes (## ADDED Requirements)
**"Requirement must have at least one scenario"**
- Check scenarios use `#### Scenario:` format (4 hashtags)
- Don't use bullet points or bold for scenario headers
**Silent scenario parsing failures**
- Exact format required: `#### Scenario: Name`
- Debug with: `openspec show [change] --json --deltas-only`
### Validation Tips
```bash
# Always use strict mode for comprehensive checks
openspec validate [change] --strict
# Debug delta parsing
openspec show [change] --json | jq '.deltas'
# Check specific requirement
openspec show [spec] --json -r 1
```
## Happy Path Script
```bash
# 1) Explore current state
openspec spec list --long
openspec list
# Optional full-text search:
# rg -n "Requirement:|Scenario:" openspec/specs
# rg -n "^#|Requirement:" openspec/changes
# 2) Choose change id and scaffold
CHANGE=add-two-factor-auth
mkdir -p openspec/changes/$CHANGE/{specs/auth}
printf "## Why\n...\n\n## What Changes\n- ...\n\n## Impact\n- ...\n" > openspec/changes/$CHANGE/proposal.md
printf "## 1. Implementation\n- [ ] 1.1 ...\n" > openspec/changes/$CHANGE/tasks.md
# 3) Add deltas (example)
cat > openspec/changes/$CHANGE/specs/auth/spec.md << 'EOF'
## ADDED Requirements
### Requirement: Two-Factor Authentication
Users MUST provide a second factor during login.
#### Scenario: OTP required
- **WHEN** valid credentials are provided
- **THEN** an OTP challenge is required
EOF
# 4) Validate
openspec validate $CHANGE --strict
```
## Multi-Capability Example
```
openspec/changes/add-2fa-notify/
├── proposal.md
├── tasks.md
└── specs/
├── auth/
│ └── spec.md # ADDED: Two-Factor Authentication
└── notifications/
└── spec.md # ADDED: OTP email notification
```
auth/spec.md
```markdown
## ADDED Requirements
### Requirement: Two-Factor Authentication
...
```
notifications/spec.md
```markdown
## ADDED Requirements
### Requirement: OTP Email Notification
...
```
## Best Practices
### Simplicity First
- Default to <100 lines of new code
- Single-file implementations until proven insufficient
- Avoid frameworks without clear justification
- Choose boring, proven patterns
### Complexity Triggers
Only add complexity with:
- Performance data showing current solution too slow
- Concrete scale requirements (>1000 users, >100MB data)
- Multiple proven use cases requiring abstraction
### Clear References
- Use `file.ts:42` format for code locations
- Reference specs as `specs/auth/spec.md`
- Link related changes and PRs
### Capability Naming
- Use verb-noun: `user-auth`, `payment-capture`
- Single purpose per capability
- 10-minute understandability rule
- Split if description needs "AND"
### Change ID Naming
- Use kebab-case, short and descriptive: `add-two-factor-auth`
- Prefer verb-led prefixes: `add-`, `update-`, `remove-`, `refactor-`
- Ensure uniqueness; if taken, append `-2`, `-3`, etc.
## Tool Selection Guide
| Task | Tool | Why |
|------|------|-----|
| Find files by pattern | Glob | Fast pattern matching |
| Search code content | Grep | Optimized regex search |
| Read specific files | Read | Direct file access |
| Explore unknown scope | Task | Multi-step investigation |
## Error Recovery
### Change Conflicts
1. Run `openspec list` to see active changes
2. Check for overlapping specs
3. Coordinate with change owners
4. Consider combining proposals
### Validation Failures
1. Run with `--strict` flag
2. Check JSON output for details
3. Verify spec file format
4. Ensure scenarios properly formatted
### Missing Context
1. Read project.md first
2. Check related specs
3. Review recent archives
4. Ask for clarification
## Quick Reference
### Stage Indicators
- `changes/` - Proposed, not yet built
- `specs/` - Built and deployed
- `archive/` - Completed changes
### File Purposes
- `proposal.md` - Why and what
- `tasks.md` - Implementation steps
- `design.md` - Technical decisions
- `spec.md` - Requirements and behavior
### CLI Essentials
```bash
openspec list # What's in progress?
openspec show [item] # View details
openspec diff [change] # What's changing?
openspec validate --strict # Is it correct?
openspec archive [change] [--yes|-y] # Mark complete (add --yes for automation)
```
Remember: Specs are truth. Changes are proposals. Keep them in sync.

View File

@ -0,0 +1,254 @@
# 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

View File

@ -0,0 +1,70 @@
# Proposal: Add PQC-Based Secure Voting MVP
## Summary
Implement Minimum Viable Product for secure electronic voting using Post-Quantum Cryptography (Paillier + Kyber + Dilithium) and Blockchain for vote recording.
## Change ID
`add-pqc-voting-mvp`
## Motivation
- Enable secure electronic voting with vote secrecy and integrity
- Implement homomorphic encryption for private vote counting
- Use post-quantum cryptography (Kyber, Dilithium) for quantum resistance
- Provide blockchain-based immutable vote records
- Support individual and universal verifiability
## Scope
This proposal adds the complete voting system with:
1. Cryptographic toolkit (Paillier, Kyber, Dilithium, ZKP)
2. Blockchain module for vote recording
3. Voting API endpoints for ballot submission
4. Frontend voting interface with client-side encryption
5. Blockchain visualization and verification
6. Vote counting with homomorphic properties
7. Results display and audit reporting
## Affected Capabilities
### New Capabilities
- `voting-encryption`: Homomorphic vote encryption
- `blockchain-votes`: Immutable vote recording
- `pqc-signatures`: Post-quantum ballot and block signing
- `vote-submission`: Secure ballot submission workflow
- `vote-counting`: Homomorphic vote summation
- `blockchain-verification`: Chain integrity verification
### Modified Capabilities
- `authentication`: Extend with voter Dilithium key generation
- `api-structure`: Add new voting endpoints
## Key Design Decisions
1. **Vote Encryption**: Paillier homomorphic encryption allows voting without decrypting individual votes
2. **Post-Quantum**: Kyber protects Paillier key, Dilithium signs ballots and blocks
3. **Blockchain**: SHA-256 hash chain ensures vote immutability
4. **Anonymity**: Transaction IDs instead of voter IDs in blockchain
5. **Verifiability**: ZKP proves ballot validity, chain verification proves counting accuracy
## Implementation Phases
1. **Phase 1**: Cryptographic foundations (crypto_tools.py + blockchain.py)
2. **Phase 2**: Backend API endpoints
3. **Phase 3**: Frontend voting interface
4. **Phase 4**: Blockchain visualization
5. **Phase 5**: Results and reporting
6. **Phase 6**: Technical report and testing
## Success Criteria
- [ ] All cryptographic operations implemented and tested
- [ ] Blockchain structure immutable and verifiable
- [ ] Voting API endpoints functional
- [ ] Frontend enables secure ballot encryption and submission
- [ ] Vote counting produces verifiable results
- [ ] Complete technical & scientific report
- [ ] Docker deployment successful
- [ ] Security properties validated
## Related Issues/Discussions
- Course project: Cryptographie Industrielle Avancée (CIA)
- Requirement: Secure e-voting system with PQC and blockchain

View File

@ -0,0 +1,189 @@
# Implementation Tasks
Change ID: `add-pqc-voting-mvp`
## Phase 1: Cryptographic Foundations
### Task 1.1: Create crypto_tools.py
- [ ] Implement Paillier key generation
- [ ] Implement Paillier encryption/decryption
- [ ] Implement Paillier homomorphic operations
- [ ] Integrate Kyber (ML-KEM) key encapsulation
- [ ] Integrate Dilithium (ML-DSA) signing/verification
- [ ] Implement simple ZKP (prove 0 or 1)
- [ ] Implement SHA-256 hashing utilities
- [ ] Add comprehensive docstrings
- [ ] Write unit tests for all operations
### Task 1.2: Create blockchain.py
- [ ] Design Block class (index, prev_hash, timestamp, encrypted_votes, hash, signature)
- [ ] Implement Blockchain class
- [ ] Implement hash chain verification
- [ ] Implement signature verification
- [ ] Implement immutability guarantees
- [ ] Implement homomorphic vote summation
- [ ] Add comprehensive docstrings
- [ ] Write unit tests for blockchain operations
### Task 1.3: Update requirements.txt
- [ ] Add python-paillier
- [ ] Add liboqs-python
- [ ] Add pycryptodome
- [ ] Verify all dependencies resolve
## Phase 2: Backend API Integration
### Task 2.1: Implement voting endpoints
- [ ] POST /api/votes/setup - Initialize election with crypto keys
- [ ] GET /api/votes/public-keys - Return public keys
- [ ] POST /api/votes/register-voter - Register voter and Dilithium keys
- [ ] POST /api/votes/submit - Submit encrypted ballot
- [ ] GET /api/votes/blockchain - Retrieve blockchain state
- [ ] GET /api/votes/results - Homomorphic vote counting
- [ ] Add error handling and validation
- [ ] Add comprehensive docstrings
### Task 2.2: Update database models
- [ ] Add VoterKey model (store Dilithium public keys)
- [ ] Add BlockchainBlock model (persist blocks)
- [ ] Add VoteRecord model (track emission list)
- [ ] Add CryptoKey model (store Paillier/Kyber keys)
- [ ] Write database migrations
### Task 2.3: Create scrutator.py
- [ ] Retrieve blockchain blocks
- [ ] Verify blockchain integrity (hash chain)
- [ ] Verify all block signatures (Dilithium)
- [ ] Compute homomorphic sum: E(total) = E(v1) × E(v2) × ... × E(vn)
- [ ] Decrypt using Paillier private key
- [ ] Generate verification report
- [ ] Add comprehensive docstrings
### Task 2.4: Write integration tests
- [ ] Test vote submission workflow
- [ ] Test blockchain integrity
- [ ] Test homomorphic summation
- [ ] Test results accuracy
- [ ] Test error handling
## Phase 3: Frontend Voting Interface
### Task 3.1: Create voting-interface.tsx
- [ ] Display election details
- [ ] Fetch public keys from backend
- [ ] Implement Paillier encryption UI
- [ ] Implement ballot selection
- [ ] Generate ZKP
- [ ] Sign with Dilithium
- [ ] Submit encrypted ballot
- [ ] Show vote confirmation
- [ ] Add error handling
### Task 3.2: Create crypto-client.ts
- [ ] Implement Paillier encryption operations
- [ ] Implement Dilithium signature operations
- [ ] Implement ZKP generation
- [ ] Implement ballot serialization
- [ ] Add comprehensive JSDoc
### Task 3.3: Update active votes page
- [ ] Integrate voting interface
- [ ] Display election details
- [ ] Show candidate options
- [ ] Add vote confirmation flow
## Phase 4: Blockchain Visualization
### Task 4.1: Create blockchain page
- [ ] Fetch blockchain from API
- [ ] Display blocks in linked chain view
- [ ] Show: index, prev_hash, current_hash, encrypted_vote, signature
- [ ] Display vote count progress
- [ ] Add integrity verification button
### Task 4.2: Create blockchain-viewer.tsx
- [ ] Implement block display component
- [ ] Show block details (formatted)
- [ ] Implement chain visualization
- [ ] Add hash verification indicator
- [ ] Add signature verification indicator
### Task 4.3: Create blockchain-verify.ts
- [ ] Implement hash chain verification
- [ ] Implement signature verification UI
- [ ] Display verification results
- [ ] Add error handling
## Phase 5: Results & Reporting
### Task 5.1: Create results page
- [ ] Display final vote count
- [ ] Show homomorphic verification details
- [ ] Display blockchain integrity report
- [ ] Show audit trail
- [ ] Add verification proof display
### Task 5.2: Update scrutator with reporting
- [ ] Generate detailed results object
- [ ] Create verification proofs
- [ ] Provide transparency report
- [ ] Add result export functionality
## Phase 6: Testing & Technical Report
### Task 6.1: Write technical report
- [ ] Section 1: Introduction & Design Choices
- [ ] Motivation and e-voting challenges
- [ ] System architecture overview
- [ ] Technology justification
- [ ] Detailed voting process
- [ ] Section 2: Cryptographic Analysis
- [ ] Paillier homomorphic encryption
- [ ] Kyber key encapsulation
- [ ] Dilithium signatures
- [ ] ZKP implementation
- [ ] Blockchain hashing
- [ ] How crypto ensures security properties
- [ ] Section 3: Security Properties & Threat Analysis
- [ ] Security properties provided
- [ ] Threat analysis and mitigation
- [ ] Resistance evaluation
### Task 6.2: Write comprehensive tests
- [ ] Unit tests for all crypto operations (90%+ coverage)
- [ ] Integration tests for voting workflow
- [ ] Blockchain integrity tests
- [ ] End-to-end tests for full voting cycle
### Task 6.3: Verify Docker deployment
- [ ] Test docker-compose up
- [ ] Verify all services start
- [ ] Test all endpoints
- [ ] Verify blockchain functionality
- [ ] Test full voting scenario
## Validation Checklist
- [ ] All crypto operations produce correct results
- [ ] Blockchain is immutable and verifiable
- [ ] API endpoints follow REST conventions
- [ ] Frontend securely handles encryption
- [ ] Voting process is complete and usable
- [ ] Results are verifiable and accurate
- [ ] Technical report is comprehensive and clear
- [ ] Code is well-documented
- [ ] Tests cover all critical paths
- [ ] Docker deployment is stable
## Estimated Timeline
- Phase 1: 2-3 days (cryptographic foundations)
- Phase 2: 2-3 days (backend integration)
- Phase 3: 2 days (frontend voting interface)
- Phase 4: 1-2 days (blockchain visualization)
- Phase 5: 1 day (results display)
- Phase 6: 2-3 days (testing & report)
**Total**: ~11-14 days of development

View File

@ -0,0 +1,170 @@
# 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
1. Generate Paillier keypair (Pu, Pr)
2. Generate Kyber keypair (KPu, KPr) to protect Pr
3. Generate Dilithium keypair (Du, Dr) for block signing
4. Publish (Pu, Du)
### Voter Registration
1. Voter authenticates (JWT)
2. Voter generates Dilithium keypair (du, dr)
3. System stores voter's du in database
### Ballot Submission
1. Voter selects candidate: v ∈ {0, 1}
2. Frontend: E(v) = Paillier.encrypt(v, Pu)
3. Frontend: π = ZKP.prove(E(v) is 0 or 1)
4. Frontend: σ = Dilithium.sign(E(v) || π, dr)
5. Frontend: submit(voter_id, E(v), π, σ)
6. Backend: verify(σ, du) ✓
7. Backend: verify(π) ✓
8. Backend: check(voter_id not in emission_list) ✓
9. Backend: B = Block(index, prev_hash, timestamp, E(v), tx_id)
10. Backend: σ_block = Dilithium.sign(B, Dr)
11. Backend: blockchain.append(B, σ_block)
### Vote Counting
1. C ← retrieve all blocks from blockchain
2. For each block b in C: verify(b.signature, Du)
3. For each block b in C: verify(hash_chain(b.prev_hash))
4. E(total) ← E(0)
5. For each block b in C: E(total) ← E(total) × b.E(v)
6. total ← Paillier.decrypt(E(total), Pr)
7. 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
```

View File

@ -0,0 +1,81 @@
# MVP Specification - E-Voting System
## Overview
Minimum Viable Product for secure electronic voting with blockchain and post-quantum cryptography.
## Features
### Core Cryptographic Components
- **Paillier Homomorphic Encryption**: Vote encryption and homomorphic summation
- **Kyber (ML-KEM)**: Post-quantum key encapsulation for private key protection
- **Dilithium (ML-DSA)**: Post-quantum digital signatures for ballots and blocks
- **Zero-Knowledge Proofs**: Ballot validity without revealing vote
- **Blockchain**: Immutable vote recording with SHA-256 hashing
### API Endpoints
```
POST /api/votes/setup # Initialize election
GET /api/votes/public-keys # Retrieve public keys
POST /api/votes/register-voter # Register voter with keys
POST /api/votes/submit # Submit encrypted ballot
GET /api/votes/blockchain # Get blockchain state
GET /api/votes/results # Get homomorphic vote count
```
### Frontend Features
- Election details display
- Client-side ballot encryption
- Ballot signing and submission
- Blockchain visualization
- Chain integrity verification
- Results display with proofs
### Backend Modules
- `crypto_tools.py`: Cryptographic operations
- `blockchain.py`: Blockchain data structure
- `routes/votes.py`: Voting API
- `scripts/scrutator.py`: Vote counting
## Security Properties
| Property | Mechanism | Guarantee |
|----------|-----------|-----------|
| Vote Secrecy | Paillier Encryption | Votes encrypted before submission |
| Vote Integrity | Blockchain + Dilithium | Immutable, signed blocks |
| Anonymity | Transaction ID | Voter ID verified once, not stored |
| Verifiability | ZKP + Chain | Ballot and chain verification |
| Post-Quantum | Kyber + Dilithium | Quantum-resistant algorithms |
## Implementation Timeline
### Phase 1: Cryptographic Foundations
- Implement Paillier homomorphic encryption
- Integrate Kyber and Dilithium
- Create blockchain module
- Write unit tests
### Phase 2: Backend API
- Implement voting endpoints
- Database models for crypto keys
- Blockchain persistence
- Scrutator module
### Phase 3: Frontend Interface
- Voting component
- Client-side crypto operations
- Vote submission workflow
### Phase 4: Blockchain Visualization
- Display blockchain blocks
- Chain verification UI
- Vote progress tracking
### Phase 5: Results & Reporting
- Results display page
- Verification proofs
- Audit trail
### Phase 6: Testing & Report
- Technical & scientific report
- Unit and integration tests
- Docker deployment verification