Oct 21, 2025
·
11 min read
·
••• views
·
••• likes

Identity systems of today introduces so much trust in companies to store your data securely. Multiple KYC providers hold your data indefinitely. Each app gets your full details even when they only need to know your age is over 18+ years, which is too much information to share and leave fragmented all over the place.
Self-Sovereign Identity SSI fixes this by giving you control of your credentials, you can share only what’s necessary, prove claims without revealing data. basical…
Oct 21, 2025
·
11 min read
·
••• views
·
••• likes

Identity systems of today introduces so much trust in companies to store your data securely. Multiple KYC providers hold your data indefinitely. Each app gets your full details even when they only need to know your age is over 18+ years, which is too much information to share and leave fragmented all over the place.
Self-Sovereign Identity SSI fixes this by giving you control of your credentials, you can share only what’s necessary, prove claims without revealing data. basically verifiable credentials VC lets you prove you are over 18+ without showing your exact birth date. But SSI has an issue - where do you store the private keys that control your identity?
There are lots of fundamental solutions to this and one is biometric crypto identities, which is not one of the popular ones, the question is what if your biometric e.g. face is your private-key? No seed phrases to lose, no passwords to forget, no keys to store. Your biometric generates your wallet, which holds your verifiable credentials, which you prove using ZKPs.
This is possible through fuzzy extractors + zero-knowledge proofs. Here’s how it works.
The Actual Problem This Could Solve
Traditional cryptographic systems were designed for reproducible bits. But biometrics breaks two key rules these systems depend on:
Keys must be perfectly reproducible - They demand bit-perfect key reproduction. Your private key for signing transactions must be identical every single time. But biometrics are noisy, lot’s of variables to consider. Your fingerprint scan today won’t match yesterday’s scan bit-for-bit due to sensor variations, finger placement, moisture, temperature - the list goes on and on. Same with face scans, iris patterns, or any biological measurement.
Keys must be uniformly random - Cryptographic security assumes your key is drawn uniformly at random from the entire keyspace. But biometric data has structure and patterns. Your iris isn’t uniformly random, it has biological constraints, population-level similarities, and entropy concentrated in specific features.
This creates the usual chicken-and-egg problem: you can’t use biometrics directly as keys they’re very noisy, you can’t store them securely they’re PII and immutable, and you can’t just hash them noise breaks hash functions as you know. So what do you do?
Now the sweet spot!
Look at fuzzy extractors as error-correcting cryptography for noisy data. They’re a pair of algorithms, Gen generate and Rep reproduce that do something very exciting:
Gen(w)→(R,P)Gen(w) \rightarrow (R, P) - Takes your noisy biometric input w, outputs a uniformly random string R the actual cryptographic key and a public helper string P. Here’s another fun fact: P can be published openly without compromising security. It doesn’t reveal any meaningful information about your biometric whatsoever.
Rep(w′,P)→RRep(w’, P) \rightarrow R - Takes a different biometric reading w' and the public same helper P, reproduces the exact same R as long as w' is close enough to the original w. Now I know that’s scary, but in this case close enough is measured by distance in some metric space Hamming distance for binary strings, edit distance for sequences, set difference for feature vectors.
The security guarantee is information-theoretic, even given P, the extracted key R is ε\varepsilon-close to uniform as long as your biometric has min-entropy ≥m\geq m. No computational hardness assumptions is needed. An adversary with infinite computing power still cannot distinguish R from a truly random key with advantage greater than ε\varepsilon.
The mathematics is beautiful. For a fuzzy extractor with parameters (m,ℓ,t,ε)(m, \ell, t, \varepsilon):
- mm = min-entropy of your biometric input unpredictability bits
- ℓ\ell = length of extracted key
R - tt = error tolerance how different
w'can be fromw - ε\varepsilon = statistical distance from uniform security parameter
How This Actually Works
The construction uses two primitives working together:
Secure Sketches (SS,Rec)(SS, Rec)
A secure sketch is like a fuzzy commitment. SS(w)→sSS(w) \rightarrow s outputs a sketch s that reveals just enough information to correct errors, but not anywhere near enough to reconstruct w itself. Then Rec(w′,s)→wRec(w’, s) \rightarrow w recovers the original w from a noisy w' using the sketch.
For binary strings with Hamming distance, the Syndrome Construction is optimal:
What’s happening here:
sketch()computes syndrome of biometricw, outputss$n-k$bitsrecover()corrects errors in noisyw_primeusing sketchs- Entropy loss is exactly the sketch length
$n-k$bits - For (128,64,22)(128, 64, 22) extended
BCHcode Bose–Chaudhuri–Hocquenghem codes: lose 64 bits, correct up to t=⌊(22−1)/2⌋=10t = \lfloor(22-1)/2\rfloor = 10 errors
After the error correction, you hash the recovered biometric to extract a uniform key e.g.
The fuzzy_gen() function:
- Creates sketch from biometric
- Generates random seed for hash function
- Extracts key using
hash(biometric || seed) - Returns
key, helperwhere helper =sketch, seed
The fuzzy_rep() function:
- Recovers the original biometric from the noisy scan using the sketch
- Applies the same hash function with the same seed
- Produces the identical key!
For the typical biometrics:
- Iris: 2048-bit raw code ~249 bits actual entropy, 10-30% error → extract 40-105 bit keys
- Fingerprint: 20-80 minutiae ~50-150 bits, high noise → extract 8-40 bit keys
- Face: 512-dim embedding 20-60 bits effective entropy
Note: Raw biometric representations contain redundancy and correlations. Iris codes exhibit ~8:1 ratio between raw bits (2048) and information-theoretic entropy (~249 bits). Key extraction must respect actual entropy, not representation size.
The Identity Play

The SSI trust model has three actors:
- Identity Holder - You, with wallet containing credentials
- Issuer - Source of trust (government, university, KYC provider)
- Verifier - Consumer of trust (dApps, smart contracts)
- Real World Trust - Bridge between issuer and verifier
The complete flow: Biometric → Wallet → Credentials → ZK Proofs → Verified Identity

Let’s look at it step by step:
Biometric to Wallet
The process:
- Preprocess biometric → binary vector iris code, face embedding, etc.
- Run
fuzzy_gen()→ get 40-128 bit key + public helper - Convert to
BIP39mnemonic → derive HD wallet seed - Derive addresses for BTC
P2WPKH, ETHEVM, SOLEd25519 - Return addresses + helper string + salt store all publicly!
For Solana specifically it’s a different curve:
Note: Solana uses
Ed25519, notsecp256k1. So in your implementation useed25519-hd-keyforSLIP-0010compliance matchesPhantom,Solflare.
Getting Your Verifiable Credentials
Your wallet now has a DID, but to prove anything, you need a Verifiable Credentials VC. This is where the trust triangle starts. The issuer verifies your documents off-chain and issues a cryptographically signed proof:
What happened:
- Issuer verifies your documents off-chain e.g. passport, selfie, etc.
- Issues a
cryptographicallysignedVCwith your claims VCincludes issuer’sDIDsignature proves authenticity- Stored locally in your wallet, not on the blockchain
- Multiple
VCsfrom different issuers education, employment, KYC
The credential schema defines what’s in the VC:
Now when a verifier asks prove you’re 18+, you generate a ZKP from this credential.
The Zero Knowledge Proof Layer
This is where you can prove your personal details like age, citizenship, a degree, address, birthdate, etc. without revealing these sensitive data.
What’s proven:
- User is over
minAgeyears old - Credential is signed by trusted issuer
- NOT revealed: actual age, birthdate, name, or any PII
The Circom circuit:
On-chain verification - Solidity:
The contract:
- Verifies the ZK proof cryptographically
- Checks the public signals issuer DID, age threshold
- Marks user as verified
- Executes business logic airdrop, DAO access, etc.
So from this flow you could see how your biometric became:
- Your wallet - Multi-chain, non-custodial, no seed phrase
- Your identity - Decentralized identifier
DIDanchored to your biometric - Your credentials - Verifiable credentials
VCfrom trusted issuers - Your privacy - Zero-knowledge proofs
ZKPreveal nothing about you
And this isn’t multiple separate systems - it’s ONE unified flow. The wallet generation happens once during enrollment. The ZKP flow can be used whenever identity verification is needed. Think of it like this: you can use your biometric wallet just like any other crypto wallet for normal transactions. But when a dApp needs KYC or any sort of PII based verification like Polygon ID use cases, the ZKP layer kicks in to prove credentials without exposing your data.
Some Possible Use Cases
- Agentic Passports:
Every AI agent can have a biometric-derived DID. Imagine an AI trading agent with its own wallet and verified credentials:
The agent:
- Derives wallet from its
biometricneural network hash - Proves reputation 1000+ successful trades via
ZKP - Operates autonomously with a verified track record
SingularityNET are building exactly this, an AI Agent Trust Registry where agents prove authenticity, safety, and audit status using verifiable credentials. The biometric-wallet-ZKP flow enables agents to operate on their own while maintaining accountability.
- dApp Identity Layer:
A DeFi protocol needs KYC but doesn’t want to store user data regulatory liability + honeypot for hackers:
The protocol never sees your passport, name, or address. Compliance achieved, privacy preserved.
The same pattern for:
- DAO voting prove membership, not identity
- Airdrops prove human, prevent bots
- Age gates prove 18+, not exact age
- Web2 Passwordless Login
Each site gets a unique derived key. No password sent, no credentials to phish.
- Biometric Payments:
Your biometric authorizes the transaction:
BMONI + BKey currently implements this where your wallets are all fully derived from your biometric “Your Face” and provisiond wallets across specifc EVM chains & tokens, all via your face!
- Scam Prevention Database:
dApps query before allowing access. Known scammers are blocked network-wide and some with a history of weird activity are noted as well, while integrators receives a notification of past suspicious activity.
Dev Integrations
Building with biometric identities needs infrastructure. The ecosystem provides three core components:
Issuer Node
Organizations run self-hosted issuer nodes to issue credentials:
Features:
- Create issuer
DID - Define credential
schemas - Issue/revoke
VCs - Manage user connections
- Transit state on-chain Polygon
API example:
Tools Ecosystem
- Schema Builder: Create custom VC schemas at
tools.privado.id/builder - Query Builder: Design ZKP queries at
tools.privado.id/query-builder - Schema Explorer: Browse community
schemas - Marketplace: Discover credential
issuers
Some Technical Challenges & Solutions
1: Biometric Variability
Your fingerprint varies 10-15% between scans. Solution: BCH codes are optimal for bit-level error correction. For 2048-bit iris code which contains ~249 bits of actual entropy with 10% errors (~205 bit errors):
- Use BCH [2048,1122,341][2048, 1122, 341] code over GF(211)GF(2^{11}) - corrects up to 170 bit errors
- Entropy loss, 2048−1122=9262048 - 1122 = 926 bits (sketch length)
- Remaining entropy, 249−(926/8.2)≈136249 - (926 / 8.2) \approx 136 bits effective entropy
- Extract 128-bit key conservative, accounts for entropy loss
Critical distinction: The 2048 bits are the RAW iris code representation Daugman’s algorithm output. Actual information-theoretic entropy is only ~249 bits due to biological correlations and redundancy ~8:1 ratio.
2: Template Aging
Problem: Your face changes over time aging, weight, facial hair, etc.
Solution: Periodic re-enrollment with key migration:
Re-enroll every 2-3 years for face, 5 years for iris, annually for voice etc.
3: Liveness Detection
Problem: Attackers with your photo shouldn’t be able to access your wallet.
Solution: Liveness checks during biometric capture:
WorldCoin’s Orb does this with iris scans: 25+ liveness checks, 3D imaging, infrared + RGB cameras. Works incredibly well - false accept rate <0.0001%< 0.0001%.
4: Helper String Privacy
Does P explained earlier leak biometric info? No. Theorem Dodis et al., attacker learns at most n−kn-k bits sketch length, key R remains statistically random. For our iris: learns 408 bits, 392 bits entropy remain.
Is It Production-Ready?
The pieces exist already:
- Fuzzy Extractors:
CompFElibrary (MIT), runs on mobile - ZK Proofs: BKey, Privado ID & others live on mainnet
- Hardware: D’CENT wallet, FaceID, fingerprint sensors are everywhere
- Standards: W3C DIDs, VCs, WebAuthn
- Networks: BTC, ETH, Polygon, Solana all support HD wallets BIP32/39/44 since 2013
What’s missing? Integrations...
Example Prod Implementation
Here’s what it looks like to actually use this system in prod environment
Normal wallet flow and identity flow coexist. ZKP comes up only when verification is needed, either for KYC or for any PII based verification like age, citizenship, a degree, address, birthdate, etc.
Your biometric is your key, your wallet is your identity across all supported chains & you never have to worry about loosing your seed phase or private keys, it’s all tied to your physical attributes, in BMoni’s implementation it’s your face!
Essential Links
- Fuzzy Extractors Survey - Dodis, Reyzin, Smith
- Fuzzy Extractors (SIAM)
- Efficient Reusable Fuzzy Extractors from LWE - Post-quantum constructions
- CompFE
- Polygon ID SDK - ZKP identity system
- BMoni’s Security - Our security architecture
- snarkjs - ZK-SNARK lib
•••
Share this post:
Built with ❤️ © 2025