Privacy-Preserving Biometric Identity for Solana
Your fingerprint becomes your cryptographic identity—without ever leaving your device.
dermagraph_1.mp4
Dermagraph is a biometric identity layer that enables sybil-resistant, privacy-preserving authentication on Solana. It uses zero-knowledge proofs (Noir/Groth16) to prove you're a unique human without revealing your biometric data.
| Traditional Auth | Dermagraph |
|---|---|
| Wallets can be created infinitely | One identity per unique human |
| Airdrops farmed by bots | Sybil-resistant token distribution |
| DAO votes can be bought | One-person-one-vote governance |
| Biometrics stored in databases | Biometric never leaves your device |
Your fingerprint generates a deterministic nullifier through zero-knowledge cryptography. The same person always produces the same nullifier for a given context—but different contexts are unlinkable.
- Biometric data never leaves your device
- ZK proofs reveal nothing about your fingerprint
- Unlinkable across different applications
- One identity per unique human
- Cross-finger detection prevents 10-finger attacks
- Deterministic nullifiers prevent double-voting
- Groth16 proofs verified on Solana (~215k compute units)
- Works with any Solana program via CPI
- Sunspot verifier for Noir circuits
- R503 capacitive fingerprint sensor
- Runs on Raspberry Pi 4
- Production-ready daemon with encrypted storage
See ARCHITECTURE.md for detailed technical documentation.
https://x.com/stcisgood/status/2018140868868293118
What you're seeing:
- User scans fingerprint on R503 sensor
- Daemon generates Noir witness + Groth16 proof
- Proof submitted to Solana with vote
- Sunspot verifier confirms on-chain
- Vote recorded with nullifier (prevents double-voting)
Transaction Example: View on Solana Explorer →
fn main(
// Private (never revealed)
embedding: [Field; 32], // Quantized biometric
blinding: Field, // Commitment randomness
merkle_proof: MerkleProof, // Membership proof
// Public (verified on-chain)
commitment: pub Field, // Pedersen commitment
merkle_root: pub Field, // Registered identities
scope: pub Field, // Application context
nullifier: pub Field // Sybil-resistance token
) {
// 1. Verify commitment opens correctly
assert(poseidon([DOMAIN, compress(embedding), blinding]) == commitment);
// 2. Verify membership in identity tree
assert(merkle_proof.verify(commitment, merkle_root));
// 3. Verify nullifier derivation
assert(poseidon([NULLIFIER_DOMAIN, compress(embedding), scope]) == nullifier);
}Circuit Stats:
- Constraints: 33,700
- Proof generation: ~2.1 seconds (Raspberry Pi 4)
- Proof size: 324 bytes (Groth16)
- On-chain verification: ~188k compute units
Traditional biometrics: Each finger = separate identity = 10 sybil accounts per person.
Dermagraph solution: We trained a ResNet18-based contrastive learning model that produces similar embeddings for all fingers of the same person.
Thumb ──┐
Index ──┼──▶ CNN ──▶ [0.42, -0.31, ...] ──▶ Same Nullifier
Middle ──┘ ↑ (for same scope)
│
InfoNCE loss
128-dim embeddings
~94% cross-finger TAR
Based on Columbia University research (Science Advances 2024). See ARCHITECTURE.md for technical details.
Handles biometric noise (sweat, dust, angle variations) without leaking helper data:
// Enrollment: Store helper data for 3 fingers
let helper = XLock::enroll(&[thumb, index, middle])?;
storage.store_xlock(&helper).await?;
// Verification: Any enrolled finger works
let (matched, nullifier) = XLock::verify(&fresh_scan, &helper)?;
// matched = "index finger", nullifier = 0x8fd2f7ab...dermagraph/
├── crates/
│ ├── turing-core/ # Cryptographic primitive (Poseidon, field ops)
│ ├── biometric-extract/ # Fingerprint feature extraction
│ ├── noir-witness/ # ZK witness generation
│ ├── dermagraphd/ # Background daemon (runs on Pi)
│ └── hardware/ # R503 sensor driver
├── circuits/
│ └── person_identity/ # Noir ZK circuit
├── solana/
│ └── programs/
│ └── dao-voting/ # On-chain voting program
├── web-app/ # React frontend
└── bridge-server/ # Node.js proxy
# Rust
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
# Node.js 18+
# https://nodejs.org/
# Solana CLI
sh -c "$(curl -sSfL https://release.solana.com/stable/install)"
# Noir (nargo)
curl -L https://raw.githubusercontent.com/noir-lang/noirup/main/install | bash
noirup
# Sunspot (Groth16 prover for Solana)
cargo install sunspot-cligit clone https://github.com/STCisGOOD/dermagraph.git
cd dermagraph
# Download pre-trained CNN weights from release (~45MB)
mkdir -p crates/biometric-extract/checkpoints
curl -L -o crates/biometric-extract/checkpoints/best_burn.safetensors \
https://github.com/STCisGOOD/dermagraph/releases/download/v1.0.0/best_burn.safetensors# Set up web app environment
cd web-app
cp .env.example .env.local
# Edit .env.local:
# - Get a Privy App ID from https://dashboard.privy.io
# - Set VITE_DAEMON_URL=http://localhost:31415 for local dev
# - Set VITE_USE_REAL_SOLANA=false for mock mode (no SOL needed)cd .. # back to repo root
# Build Rust crates
cargo build --release
# Build Noir circuit
cd circuits/person_identity && nargo compile && cd ../..
# Install frontend deps
cd web-app && npm install && cd ..
# Install bridge server deps
cd bridge-server && npm install && cd ..# Terminal 1: Daemon with mock sensor
cargo run --release -p dermagraphd -- --sensor mock
# Terminal 2: Bridge server
cd bridge-server && npm start
# Terminal 3: Frontend
cd web-app && npm run devOpen http://localhost:5173 and connect your wallet!
Note: Mock mode simulates fingerprint scans. For real hardware setup with Raspberry Pi + R503 sensor, see SETUP.md.
Minimum Hardware (~$140):
- R503 Capacitive Fingerprint Sensor (~$25)
- Raspberry Pi 4 (~$100)
- MicroSD card (~$8)
- Jumper wires (~$3)
Wiring:
R503 Raspberry Pi
──── ────────────
VCC (Red) → 3.3V (Pin 1)
GND (Black)→ GND (Pin 6)
TX (Yellow)→ GPIO15/RX (Pin 10)
RX (Green) → GPIO14/TX (Pin 8)
Best Non-Financial Use Case
Dermagraph uses Noir for privacy-preserving biometric authentication:
person_identitycircuit proves identity without revealing biometrics- Groth16 proofs verified on Solana via Sunspot
- Novel: Fingerprint-derived nullifiers for sybil resistance
Supported by Light Protocol & Solana Foundation
Dermagraph brings hardware-backed privacy to Solana:
- Real fingerprint sensor integration (not simulated)
- On-chain proof verification in a single transaction
- Composable with any Solana program via CPI
| Property | Mechanism |
|---|---|
| Biometric Privacy | ZK proofs—embedding never leaves device |
| Sybil Resistance | Deterministic nullifiers from biometric |
| Unlinkability | Different scope → different nullifier |
| Non-Transferability | Requires physical finger + device |
| Liveness | Capacitive sensor detects real finger |
| Double-Vote Prevention | Nullifier stored on-chain |
POST /enroll-fingers-stream
Content-Type: application/json
{"scope": "dermagraph:identity:v1"}
# Response: SSE stream with enrollment progressPOST /verify-finger
Content-Type: application/json
{"scope": "dao:proposal:0", "passphrase": null}
# Response:
{
"success": true,
"data": {
"verified": true,
"nullifier": "0x8fd2f7ab...",
"matched_finger": "index"
}
}POST /prove-person
Content-Type: application/json
{"scope": "dao:proposal:0"}
# Response:
{
"success": true,
"data": {
"proof": "0x0a1d8388...",
"nullifier": "0x1352d91f...",
"merkle_root": "0x04493830...",
"commitment": "0x2310e8fd..."
}
}- Core cryptographic primitive (Poseidon-based)
- Noir ZK circuit for person identity
- R503 sensor integration
- On-chain Groth16 verification (Sunspot)
- DAO voting demo
- Mobile app (iOS/Android)
- Multi-device sync
- Decentralized identity registry
- Integration with Light Protocol compressed accounts
Dermagraph builds on peer-reviewed research:
-
Cross-Finger Matching Guo et al. "Unveiling intra-person fingerprint similarity via deep contrastive learning" Science Advances (2024) — DOI
-
Fuzzy Extractors Dodis et al. "Fuzzy Extractors: How to Generate Strong Keys from Biometrics" SIAM Journal on Computing (2008)
-
X-Lock Construction Kurbatov et al. "Unforgettable Fuzzy Extractor: Practical Construction and Security Model" IACR ePrint (2025) — ePrint 2025/1799
-
Poseidon Hash Grassi et al. "Poseidon: A New Hash Function for Zero-Knowledge Proof Systems" USENIX Security (2021)
Built for the Solana Privacy Hackathon by:
- @STCisGOOD — Building systems that amplify individual expression and cultural evolution.
MIT License. See LICENSE.