6.0 KiB
6.0 KiB
Step 1: Define Scope and Tools
Objective
Build an MVP where users can register, get eligibility credentials, and submit anonymous opinions on a single legislative matter, with public verification.
Tech Stack Suggestions
- Programming Language: Python (for rapid prototyping, with libraries for crypto) or Rust (for performance and security in production).
- Cryptography Libraries:
py-ecc
orcircom
(for ZKPs like zk-SNARKs).blind-signatures
(Python) orrsa-blind-signatures
(custom implementation).
- Public Ledger:
- Local database (e.g., SQLite) for the MVP.
- Optionally, Ethereum (with a testnet like Sepolia) for blockchain integration later.
- Frontend: Flask (Python) or a simple CLI for the MVP; React/Vue.js later for a user interface.
- Development Environment: Docker (to containerize components), Git (version control).
Step 2: Design the Core Components
Break the system into modular pieces you can build and test independently:
-
Trusted Authority Module
- Purpose: Issues credentials and blind signatures.
- How:
- Simulate a credential issuer with a key pair (public/private).
- Implement a blind signature scheme (e.g., RSA-based).
- Starting Point: Use
blind-signatures
in Python or code a basic RSA blind signature:from blind_signatures import BlindSignature authority = BlindSignature(bits=2048)
-
Participant Module
- Purpose: Generates tokens, commitments, and ZKPs.
- How:
- Generate a random token and secret key per user per matter.
- Create a commitment:
commitment = hash(token || secret || matter_id)
(e.g., SHA-256). - Use a ZKP library like
circom
to prove knowledge of the secret without revealing it.
- Starting Point: Use
hashlib
for commitments:import hashlib token = "random123" secret = "secret456" matter_id = "Law001" commitment = hashlib.sha256((token + secret + matter_id).encode()).hexdigest()
-
Public Ledger
- Purpose: Stores commitments and submissions.
- How: Use SQLite to store
(commitment, blind_signature, matter_id)
tuples for now. - Starting Point:
import sqlite3 conn = sqlite3.connect("ledger.db") conn.execute("CREATE TABLE commitments (id INTEGER PRIMARY KEY, commitment TEXT, signature TEXT, matter_id TEXT)")
-
Verification Module
- Purpose: Validates submissions.
- How: Check blind signatures and ZKPs; ensure token uniqueness.
- Starting Point: Mock a verifier that checks
authority.verify()
output.
Step 3: Build the MVP Workflow
Workflow
- Setup Phase:
- User registers with the authority, gets a credential.
- User generates token, secret, and commitment for a matter (e.g., "Law001").
- User blinds the commitment, gets a signature from the authority, unblinds it, and stores it in the ledger.
- Submission Phase:
- User submits an opinion (e.g., "Yes") with their token and a ZKP.
- System verifies the ZKP and ensures the token is unused.
- Opinion is recorded.
Prototype Code (Python Example)
import hashlib
from blind_signatures import BlindSignature
# Authority setup
authority = BlindSignature(bits=2048)
# User setup
token = "token123"
secret = "secret789"
matter_id = "Law001"
commitment = hashlib.sha256((token + secret + matter_id).encode()).hexdigest()
# Blind and sign
blinded, unblinder = authority.blind(commitment)
signature = authority.sign(blinded)
unblinded_signature = authority.unblind(signature, unblinder)
# Store in ledger
import sqlite3
conn = sqlite3.connect("ledger.db")
conn.execute("INSERT INTO commitments (commitment, signature, matter_id) VALUES (?, ?, ?)",
(commitment, unblinded_signature, matter_id))
conn.commit()
# Submission (simplified ZKP placeholder)
opinion = "Yes"
# In practice, generate a ZKP here with circom or similar
submitted_token = token
print(f"Opinion: {opinion}, Token: {submitted_token}")
Step 4: Add Zero-Knowledge Proofs
Why ZKPs?
They prove the token matches a commitment without revealing which one, ensuring anonymity.
How to Start
- Tool: Use
circom
(a ZK circuit compiler) withsnarkjs
for zk-SNARKs. - Circuit: Define a simple circuit to prove
hash(token, secret, matter_id) == commitment
. - Steps:
- Install
circom
andsnarkjs
(via npm). - Write a circuit in
circom
:template CommitmentCheck() { signal input token; signal input secret; signal input matter_id; signal input commitment; signal output valid; // Simplified hash (use Poseidon or MiMC in practice) valid <== commitment === hash([token, secret, matter_id]); }
- Compile and generate a proof with
snarkjs
. - Verify the proof in your Python verifier.
- Install
Step 5: Test and Iterate
Test Plan
- Unit Tests: Verify each module (authority, participant, ledger).
- Integration Test: Run a full cycle with 5-10 mock users.
- Edge Cases: Test duplicate submissions, invalid signatures.
Tools
pytest
for Python unit tests.- Manual checks via CLI output.
Step 6: Next Steps
Once the MVP works:
- Scalability: Switch to a blockchain (e.g., Ethereum testnet) for the ledger.
- User Interface: Build a Flask or React frontend.
- Efficiency: Optimize ZKPs with zk-STARKs or precomputed trusted setups.
- Security Audit: Review crypto implementations with an expert.
Recommendations
- Start Small: Focus on blind signatures and a basic ledger first; add ZKPs after.
- Learn by Doing: Experiment with
circom
tutorials (e.g., on GitHub) to grasp ZKPs. - Resources:
- “Mastering Zero-Knowledge Proofs” (online guides).
- Ethereum’s zk-SNARK docs.
- GitHub repos like
iden3/circom
.