Privacy-preserving certificate system using zkSNARK proofs for ECDSA signature verification and STARK proofs for anonymous token spending.
IronLetter combines two cryptographic proof systems for privacy-preserving credential management:
- zkSNARK (Groth16) - Proves possession of a valid ECDSA signature without revealing it
- STARK (FRI) - Enables anonymous spending of certificate-derived tokens
Authority Signs → zkSNARK Proof → Blockchain Certificate → Anonymous Tokens → STARK Spending
↓
Businesses Verify
(No Identity Required)
Components:
blockchain-api(port 5000): Certificate issuance via zkSNARK verificationbusiness-api(port 5001): Anonymous token verification via STARK proofs
IronLetter enables users to prove possession of valid credentials (issued by authorities) without revealing their identity when accessing business services.
Example Flow:
- Authority Issues Certificate: University signs student's degree via ECDSA
- User Generates zkSNARK Proof: Proves they have valid signature without revealing it
- Blockchain Verifies & Issues: Smart contract verifies proof, issues certificate with 20 anonymous tokens
- Anonymous Spending: User spends tokens at businesses (jobs, services) without revealing certificate details
- Business Verification: Business verifies STARK proof and checks blockchain to prevent double-spending
Privacy Benefits:
- User identity never disclosed to businesses
- Same token cannot be spent multiple times (blockchain consensus)
- Different services cannot link user's activities
- Certificate details remain private
# Start services
docker-compose up -d
# Run integration test
python tests/test_complete_integration.pyTest runtime: 10-15 minutes (includes zkSNARK proof generation)
The integration test validates:
- Authority registration with ECDSA keypair (secp256k1)
- Certificate signing and zkSNARK proof generation
- On-chain certificate issuance (Ethereum Sepolia)
- Anonymous token derivation (20 tokens per certificate)
- STARK proof generation and verification
- Cross-business double-spend prevention via blockchain nullifier tracking
- Circuit: 1.64M constraints (circom-ecdsa)
- Proof System: Groth16
- Curve: bn128 (alt_bn128)
- Proving Time: 5-10 minutes
- Verification: On-chain via Solidity verifier
- Gas Cost: ~285,000 gas per certificate
- Tokens: 20 unlinkable tokens per certificate
- Proof System: STARK with FRI
- Security: 128-bit (configurable to 256-bit)
- Proving Time: ~25 second
- Verification: Off-chain by businesses
- Nullifier Tracking: On-chain via AnonymousCertificateRegistry contract
- Signature values (r, s) never revealed
- Certificate details not disclosed during token spending
- Token spending unlinkable across services
- Service-specific nullifiers prevent double-spending
- Blockchain consensus prevents cross-business token reuse
CertificateRegistry: 0x403b4D6A7Bb77bbf97d4649b09E234F0C28EdCDb
Groth16Verifier: 0x99c7Fef711E533ED1d9C8890b39D0c7Adf9D6781
AnonymousCertificateRegistry: [Deploy with scripts/deploy.js]
IronLetter/
├── blockchain-api/ # zkSNARK verification & certificate issuance
│ ├── app.py # FastAPI endpoints
│ ├── blockchain_client.py # Web3 integration
│ ├── anonymous_tokens.py # Token derivation
│ ├── zkproof.py # Proof generation
│ └── contracts/ # Solidity contracts
│
├── business-api/ # Anonymous token verification
│ ├── app.py # Verification endpoints
│ ├── stark_verifier_fri.py # STARK verifier
│ ├── blockchain_nullifier_client.py # On-chain tracking
│ └── replay_protection.py # Local nullifier cache
│
├── circuits/ # zkSNARK circuits
│ ├── attribute_verification.circom
│ ├── attribute_verification_0000.zkey (831 MB)
│ └── circom-ecdsa/ # ECDSA verification library
│
└── tests/
└── test_complete_integration.py # Full system test
POST /setup # Initialize blockchain
POST /register-authority # Register signing authority
POST /verify-and-issue # Verify zkSNARK & issue certificate
GET /authorities # List registered authoritiesPOST /verify-anonymous # Verify STARK proof & spend token
GET /nullifier-stats # Get double-spend statistics
GET /replay-protection-stats # Get replay protection statistics
GET /health # Health checkBusiness Integration:
Businesses integrate with the business-api to verify anonymous tokens:
- User presents token + STARK proof
- Business calls
/verify-anonymouswith proof data - Business-api verifies STARK proof locally (cryptographic validation)
- Business-api checks blockchain nullifier registry (prevents double-spend)
- If valid and not spent, business marks token on blockchain
- Business grants access to user
Benefits for Businesses:
- No need to collect user identity
- Cryptographically verified credentials
- Protection against double-spending
- Cross-business consensus (shared blockchain registry)
- Simple REST API integration
- Docker & Docker Compose
- Python 3.9+
- Node.js 16+ (for circuit compilation)
- ~6GB disk space (5.1GB circuits + Docker images)
Services automatically reload on file changes:
# Edit and save - service reloads automatically
vim blockchain-api/app.pySee BLOCKCHAIN_SETUP.md for full deployment guide.
cd blockchain-api
npx hardhat compile
npx hardhat run scripts/deploy.js --network sepoliaMeasured from actual test run (see tests/test_complete_integration.py):
| Operation | Time |
|---|---|
| Service Health Check | 0.1s |
| ECDSA Keypair Generation | 0.1s |
| Authority Registration | 10s |
| ECDSA Signing | 0.1s |
| zkSNARK Witness | 118s (~2 min) |
| zkSNARK Proof | 274s (~4.5 min) |
| On-chain Verification | 16s |
| Anonymous Token Generation | <1s (20 tokens) |
| STARK Proof Generation | 58s |
| STARK Verification + Blockchain | 25s |
| Double-Spend Detection | <1s |
| Full Integration Test | 705s (~12 min) |
Guarantees:
- Signature privacy (r, s never revealed)
- Attribute privacy (only hash public)
- Soundness (cannot forge proofs)
- Double-spend prevention (blockchain consensus)
- Cross-business unlinkability
Trust Assumptions:
- zkSNARK trusted setup (Powers of Tau ceremony)
- Authority honesty (verifies attributes correctly)
- Smart contract correctness
- Ethereum security
- ARCHITECTURE.md - System design and data flow
- BLOCKCHAIN_SETUP.md - Contract deployment
- TESTING.md - Test documentation
- circuits/SETUP_README.md - Circuit compilation
- circom-ecdsa - ECDSA circuits (0xPARC)
- snarkjs - zkSNARK library (iden3)
- circom - Circuit compiler (iden3)
GNU General Public License v3.0 - See LICENSE file for details