ZK Credential Verification: Selective Disclosure in Practice
Verifiable credentials with selective disclosure let users prove specific claims without revealing full credentials. ZK proofs make this cryptographically secure. This guide covers practical implementation.
Credential Structure
A verifiable credential contains:
- Claims: Statements about the subject (name, age, address, etc.)
- Issuer signature: Cryptographic proof of issuance
- Metadata: Issuance date, expiration, schema
{
"subject": "did:example:user123",
"claims": {
"name": "Alice Smith",
"birthDate": "1990-05-15",
"citizenship": "US",
"employerVerified": true
},
"issuer": "did:example:government",
"signature": "..."
}
Selective Disclosure
With ZK, users control what to reveal:
Disclosure Options
Full disclosure: Reveal claim value
Predicate proof: Prove condition (age > 18)
Existence proof: Prove claim exists
Non-disclosure: Prove credential valid without revealing claim
ZK Credential Proof
// Generate selective disclosure proof
const proof = await zkCredentials.prove({
credential: myCredential,
disclose: ['citizenship'], // Reveal this
predicates: [
{ claim: 'birthDate', predicate: 'olderThan', value: 21 }
],
hide: ['name', 'employerVerified'] // Don't reveal
});
// Verifier learns:
// - citizenship is "US" (disclosed)
// - user is over 21 (predicate satisfied)
// - credential is valid (signature verified)
// Verifier does NOT learn: name, exact birth date, employer status
Credential Schemas
Define credential structure for interoperability:
{
"type": "IdentityCredential",
"version": "1.0",
"claims": {
"name": { "type": "string", "required": true },
"birthDate": { "type": "date", "required": true },
"citizenship": { "type": "string", "required": false }
},
"predicates": {
"birthDate": ["olderThan", "youngerThan", "between"]
}
}
Issuer Implementation
Credential issuers must:
- Verify subject identity before issuance
- Sign credentials with ZK-compatible signatures
- Publish public keys for verification
- Maintain revocation registry
Verifier Implementation
Verifiers specify requirements:
// Verifier requests proof
const request = {
required: [
{ claim: 'citizenship', disclose: true },
{ claim: 'birthDate', predicate: 'olderThan', value: 18 }
],
trustedIssuers: ['did:example:government'],
purpose: "Age verification for alcohol purchase"
};
// User generates proof matching request
const proof = await wallet.generateProof(request);
// Verifier validates
const valid = await verifier.check(proof, request);
Privacy Considerations
- Issuer unlinkability: Issuers shouldn't learn when credentials are used
- Verifier unlinkability: Different verifiers can't correlate proofs
- Minimal disclosure: Only prove what's asked
Revocation
Handle credential revocation privately:
- Accumulators allow ZK membership proof
- User proves credential not revoked without revealing which credential
- Update accumulator when revoking
ZK credentials are the foundation of privacy-respecting identity. Users control their data while verifiers get cryptographic assurance.
Ready to Go Quantum-Secure?
Start protecting your users with post-quantum authentication today. 1,000 free auths, no credit card required.
Get Free API Key โ