Skip to main content

Zero-Knowledge Proofs (ZKP)

Zero-Knowledge Proofs enable you to prove a statement is true without revealing any information beyond the validity of the statement itself. In the context of SSI, ZKPs allow you to prove claims about your credentials without disclosing the actual data.

What is a Zero-Knowledge Proof?

A Zero-Knowledge Proof is a cryptographic method where one party (the prover) can prove to another party (the verifier) that a statement is true, without revealing any information beyond the truth of that statement.
Example: Prove you’re over 21 years old without revealing your exact birthdate, or prove you’re a citizen without showing your passport number.

How ZKP Works

ZKP Properties

A valid zero-knowledge proof must have three properties:

Completeness

If the statement is true, an honest prover can convince an honest verifier

Soundness

If the statement is false, no dishonest prover can convince the verifier (except with negligible probability)

Zero-Knowledge

The verifier learns nothing except that the statement is true

Real-World Examples

Age Verification

Traditional Approach:
{
  "name": "Alice Smith",
  "dateOfBirth": "1995-03-15",
  "address": "123 Main St",
  "idNumber": "ABC123456"
}
❌ Reveals unnecessary personal information Zero-Knowledge Approach:
{
  "statement": "holder is over 21 years old",
  "proof": "zkp_proof_data...",
  "result": true
}
✅ Proves age without revealing birthdate

Income Verification

Scenario: Loan application requires proof of income over $50,000 Traditional:
{
  "annualIncome": "$75,000",
  "employer": "Tech Corp",
  "position": "Senior Engineer"
}
Zero-Knowledge:
{
  "statement": "annual income > $50,000",
  "proof": "zkp_proof...",
  "verified": true
}

Citizenship Proof

Scenario: Access to service requires EU citizenship Traditional: Show passport (reveals name, birthdate, passport number, photo) Zero-Knowledge: Prove “I am an EU citizen” without showing passport details

Types of ZKP

Prove a value falls within a range without revealing the exact value.Example: Prove age is between 18-65 without showing exact age
const rangeProof = generateRangeProof({
  value: userAge,
  min: 18,
  max: 65,
  credential: ageCredential
});
Prove you belong to a set without revealing which member you are.Example: Prove you’re an employee of approved companies without saying which one
const membershipProof = generateMembershipProof({
  userCompany: "TechCorp",
  allowedSet: ["TechCorp", "FinanceCo", "HealthInc"],
  credential: employmentCredential
});
Prove two values are equal without revealing the values.Example: Prove your name in two different credentials is the same
const equalityProof = generateEqualityProof({
  credential1: passportCredential,
  credential2: driverLicenseCredential,
  field: "name"
});
Prove the result of a computation without revealing inputs.Example: Prove average salary of a group without revealing individual salaries
const computationProof = generateComputationProof({
  inputs: employeeSalaries,
  computation: "average",
  result: averageSalary
});

ZKP in Sphyre

Sphyre implements ZKP for selective disclosure and privacy-preserving verification:

Implementation

// Generate ZKP for age verification
async function generateAgeProof(
  birthDateCredential: VerifiableCredential,
  minimumAge: number
): Promise<ZeroKnowledgeProof> {
  // Extract birthdate from credential
  const birthDate = new Date(birthDateCredential.credentialSubject.dateOfBirth);
  
  // Calculate age
  const age = calculateAge(birthDate);
  
  // Generate proof that age >= minimumAge
  const proof = await zkp.prove({
    statement: `age >= ${minimumAge}`,
    privateInput: age,
    publicInput: minimumAge,
    credential: birthDateCredential
  });
  
  return proof;
}

// Verify the proof
async function verifyAgeProof(
  proof: ZeroKnowledgeProof,
  minimumAge: number
): Promise<boolean> {
  return await zkp.verify({
    proof: proof,
    statement: `age >= ${minimumAge}`,
    publicInput: minimumAge
  });
}

Use Cases in Sphyre

Age Verification

Prove you meet age requirements without revealing exact birthdate

Income Verification

Prove income threshold without disclosing exact salary

Location Proof

Prove residency in a region without revealing exact address

Qualification Proof

Prove you meet educational requirements without showing full transcript

Credit Score Range

Prove credit score is above threshold without exact number

Access Control

Prove membership in authorized group without identifying yourself

ZKP Workflow in Sphyre

1

Verifier Creates Request

Verifier specifies what they want to prove
{
  "type": "ZeroKnowledgeProofRequest",
  "statement": "age >= 21",
  "requiredCredentialType": "NationalID"
}
2

User Receives Request

Request appears in Sphyre ALV wallet
3

User Selects Credential

Choose which credential to use for the proof
4

Generate ZKP

Wallet generates proof using credential data
const zkProof = await generateZKP({
  credential: selectedCredential,
  statement: request.statement
});
5

Submit Proof

Send proof to verifier (no raw data included)
6

Verifier Validates

Verifier cryptographically validates the proof
const isValid = await verifyZKP(zkProof, statement);

Advanced ZKP Techniques

zk-SNARKs

Zero-Knowledge Succinct Non-Interactive Arguments of Knowledge

Succinct

Proofs are very small (hundreds of bytes)

Non-Interactive

No back-and-forth needed between prover and verifier

Fast Verification

Verification is extremely quick

Privacy-Preserving

Complete privacy for the prover
Use Cases:
  • Complex credential combinations
  • Multiple claim verification
  • Blockchain scalability

zk-STARKs

Zero-Knowledge Scalable Transparent Arguments of Knowledge Advantages:
  • No trusted setup required
  • Quantum-resistant
  • Transparent and auditable
Trade-offs:
  • Larger proof sizes than SNARKs
  • Slower proof generation

Credential Predicates

Predicates define conditions that can be proven with ZKP:
{
  "predicates": [
    {
      "type": "greaterThan",
      "attribute": "age",
      "value": 21
    },
    {
      "type": "lessThan",
      "attribute": "income",
      "value": 100000
    },
    {
      "type": "memberOf",
      "attribute": "country",
      "values": ["USA", "Canada", "Mexico"]
    },
    {
      "type": "equal",
      "attribute": "verified",
      "value": true
    }
  ]
}

Privacy Levels

Different scenarios require different privacy levels:
When: High trust relationship, legal requirement
{
  "name": "Alice Smith",
  "dateOfBirth": "1990-01-01",
  "address": "123 Main St"
}
Privacy: ⭐ (Low)

Implementation Example

Complete Age Verification Flow

// 1. Verifier creates ZKP request
const zkRequest = {
  id: "req_123",
  type: "ZKPresentationRequest",
  verifierId: "did:alyra:VerifierDID...",
  predicate: {
    type: "greaterThanOrEqual",
    attribute: "age",
    value: 21
  },
  requiredCredentialType: "NationalID",
  challenge: generateChallenge()
};

// 2. User's wallet processes request
class ZKPService {
  async createAgeProof(
    credential: VerifiableCredential,
    minimumAge: number,
    challenge: string
  ): Promise<ZKProof> {
    // Extract private data
    const birthDate = credential.credentialSubject.dateOfBirth;
    const age = this.calculateAge(birthDate);
    
    // Generate commitment
    const commitment = this.generateCommitment(age);
    
    // Create proof
    const proof = await this.proveInequality({
      privateValue: age,
      publicThreshold: minimumAge,
      commitment: commitment,
      challenge: challenge
    });
    
    return {
      statement: `age >= ${minimumAge}`,
      commitment: commitment,
      proof: proof,
      credentialId: credential.id,
      issuerDid: credential.issuer
    };
  }
  
  private calculateAge(birthDate: string): number {
    const birth = new Date(birthDate);
    const today = new Date();
    let age = today.getFullYear() - birth.getFullYear();
    const monthDiff = today.getMonth() - birth.getMonth();
    
    if (monthDiff < 0 || (monthDiff === 0 && today.getDate() < birth.getDate())) {
      age--;
    }
    
    return age;
  }
}

// 3. Verifier validates proof
async function validateZKProof(
  zkProof: ZKProof,
  minimumAge: number,
  challenge: string
): Promise<VerificationResult> {
  // Verify commitment
  const commitmentValid = await verifyCommitment(
    zkProof.commitment,
    zkProof.proof
  );
  
  // Verify inequality proof
  const proofValid = await verifyInequalityProof({
    commitment: zkProof.commitment,
    threshold: minimumAge,
    proof: zkProof.proof,
    challenge: challenge
  });
  
  // Verify credential validity
  const credentialValid = await verifyCredentialSignature(
    zkProof.credentialId,
    zkProof.issuerDid
  );
  
  return {
    valid: commitmentValid && proofValid && credentialValid,
    statement: zkProof.statement,
    timestamp: new Date()
  };
}

Security Considerations

Risk: Reusing the same proof multiple timesMitigation: Include unique challenges and timestamps
const proof = {
  challenge: verifierChallenge,
  timestamp: Date.now(),
  nonce: generateNonce()
};
Risk: Correlating proofs to track usersMitigation: Use different credentials or randomized proofs
const proof = addRandomness(baseProof);
Risk: Leaking information through timing or resourcesMitigation: Constant-time operations, noise injection
Risk: Proving claims from revoked credentialsMitigation: Include non-revocation proofs
const proof = {
  claimProof: zkClaimProof,
  nonRevocationProof: zkNonRevocationProof
};

Performance Considerations

ZKP TypeProof SizeProof TimeVerify TimeSetup
zk-SNARK~200 bytes~1 second~1 msTrusted setup
zk-STARK~50 KB~5 seconds~10 msTransparent
Bulletproofs~1 KB~2 seconds~5 msNone
Range Proofs~2 KB~500 ms~2 msNone

Comparison: Traditional vs ZKP

AspectTraditional VerificationZero-Knowledge Proof
Data SharedFull credentialNo raw data
PrivacyLowMaximum
Trust RequiredHighMinimal
VerificationCheck all dataVerify proof only
ComplexityLowMedium to High
SpeedInstant~1-5 seconds
StandardsWell establishedEmerging

ZKP Libraries & Tools

Sphyre uses and recommends these ZKP libraries:

circom

Circuit compiler for zk-SNARKscircom documentation

snarkjs

JavaScript library for zk-SNARKssnarkjs on GitHub

ZoKrates

High-level language for ZKPZoKrates documentation

libsnark

C++ library for zk-SNARKslibsnark on GitHub

Future of ZKP in Sphyre

1

Enhanced Privacy

More granular ZKP options for complex predicates
2

Performance Optimization

Faster proof generation using optimized circuits
3

Recursive Proofs

Combine multiple proofs into a single compact proof
4

Universal Composability

Standard ZKP format across all SSI systems

Common Use Cases

KYC Compliance

Prove identity verification without revealing PII

Financial Services

Prove creditworthiness without exposing financial details

Healthcare

Prove insurance coverage without sharing medical history

Education

Prove qualifications without full transcript

Employment

Prove work authorization without visa details

Voting

Prove eligibility without revealing identity

Resources

Next Steps

1

Try ZKP in Sphyre

Use ZKP for age verification in the quickstart guide
2

Explore Wallet Features

Learn about Sphyre ALV ZKP capabilities
3

Developer Integration

Implement ZKP in your app with our API guide
4

Advanced Tutorials

Check out developer guides for custom ZKP circuits