Identity Verification Tutorial
Learn how to build a comprehensive decentralized identity verification system that enables users to prove their identity while maintaining privacy. This tutorial demonstrates advanced cryptographic techniques including zero-knowledge proofs, credential verification, and selective disclosure.
Overview
The Identity Verification system demonstrates:
- Self-Sovereign Identity: User-controlled identity without centralized authorities
- Verifiable Credentials: Cryptographically signed digital credentials
- Zero-Knowledge Proofs: Prove identity claims without revealing personal data
- Selective Disclosure: Share only necessary information for verification
- Credential Revocation: Secure mechanism to invalidate compromised credentials
- Biometric Integration: Optional biometric authentication for enhanced security
Prerequisites
Before starting this tutorial, ensure you have:
- ✅ Completed Hello World tutorials
- ✅ Understanding of cryptographic signatures and verification
- ✅ Familiarity with zero-knowledge proof concepts
- ✅ Knowledge of identity and authentication systems
Architecture Overview
graph TB
subgraph "Identity Verification System"
A[User] --> B[Create Identity]
B --> C[Generate Credentials]
C --> D[Submit for Verification]
E[Issuer] --> F[Verify Documents]
F --> G[Sign Credentials]
G --> H[Issue to User]
I[Verifier] --> J[Request Proof]
J --> K[Validate Credentials]
K --> L[Grant Access]
M[Privacy Layer] --> N[Zero-Knowledge Proofs]
N --> O[Selective Disclosure]
O --> P[Minimal Data Sharing]
end
style B fill:#e1f5fe
style G fill:#f3e5f5
style K fill:#fff3e0
style N fill:#e8f5e8
Code Walkthrough
Core Data Structures
<span class="filename">📁 examples/identity-verification/src/main.hc</span>
// Decentralized identifier (DID)
struct DecentralizedIdentity {
U8[32] did_address; // Unique DID address
U8[32] owner_pubkey; // Identity owner
U8[64] did_method; // DID method identifier
U64 creation_timestamp; // DID creation time
U64 last_updated; // Last update timestamp
Bool is_active; // DID active status
U8[32] recovery_key; // Recovery public key
U8[256] metadata_uri; // DID document URI
};
// Verifiable credential
struct VerifiableCredential {
U8[32] credential_id; // Unique credential ID
U8[32] subject_did; // Subject's DID
U8[32] issuer_did; // Issuer's DID
U8 credential_type; // Type of credential
U8[512] credential_data; // Encrypted credential data
U8[64] issuer_signature; // Issuer's signature
U64 issue_date; // Issuance timestamp
U64 expiry_date; // Expiration timestamp
Bool is_revoked; // Revocation status
U8[32] revocation_registry; // Revocation registry address
};
// Identity claim
struct IdentityClaim {
U8[32] claim_id; // Unique claim identifier
U8[32] subject_did; // Subject's DID
U8 claim_type; // Type of claim (age, nationality, etc.)
U8[256] claim_value; // Encrypted claim value
U8[64] proof_signature; // Cryptographic proof
U64 verification_timestamp; // When claim was verified
Bool is_verified; // Verification status
U8[32] verifier_did; // Verifier's DID
};
// Verification request
struct VerificationRequest {
U8[32] request_id; // Unique request ID
U8[32] verifier_did; // Requesting verifier
U8[32] subject_did; // Subject being verified
U8 required_claims[10]; // Required claim types
U8 claim_count; // Number of required claims
U64 request_timestamp; // Request creation time
U64 expiry_timestamp; // Request expiry time
Bool is_fulfilled; // Request fulfillment status
U8[1024] proof_data; // Zero-knowledge proof data
};
Identity Creation and Management
<span class="filename">📁 Identity Management</span>
// Create decentralized identity
U0 create_decentralized_identity(U8* owner_pubkey, U8* recovery_key, U8* metadata_uri) {
DecentralizedIdentity* identity = allocate_identity();
// Generate unique DID address
generate_did_address(owner_pubkey, identity->did_address);
// Initialize identity data
MemCpy(identity->owner_pubkey, owner_pubkey, 32);
MemCpy(identity->recovery_key, recovery_key, 32);
MemCpy(identity->metadata_uri, metadata_uri, 256);
MemCpy(identity->did_method, "holybpf:identity:", 64);
identity->creation_timestamp = get_current_timestamp();
identity->last_updated = identity->creation_timestamp;
identity->is_active = TRUE;
// Create DID document
create_did_document(identity);
PrintF("🆔 Decentralized identity created\n");
PrintF("📍 DID: did:holybpf:%s\n", identity->did_address);
PrintF("🔑 Owner: %s\n", owner_pubkey);
PrintF("🛡️ Recovery key configured\n");
}
// Issue verifiable credential
U0 issue_credential(U8* issuer_did, U8* subject_did, U8 credential_type,
U8* credential_data, U8* issuer_private_key) {
VerifiableCredential* credential = allocate_credential();
// Generate unique credential ID
generate_credential_id(subject_did, credential_type, credential->credential_id);
// Initialize credential
MemCpy(credential->subject_did, subject_did, 32);
MemCpy(credential->issuer_did, issuer_did, 32);
credential->credential_type = credential_type;
credential->issue_date = get_current_timestamp();
credential->expiry_date = credential->issue_date + (365 * 24 * 3600); // 1 year
credential->is_revoked = FALSE;
// Encrypt credential data
U8[32] encryption_key;
derive_credential_encryption_key(subject_did, credential->credential_id, encryption_key);
encrypt_credential_data(credential_data, encryption_key, credential->credential_data);
// Sign credential with issuer's private key
sign_credential(credential, issuer_private_key, credential->issuer_signature);
// Register in revocation registry
register_credential_for_revocation(credential);
PrintF("📜 Verifiable credential issued\n");
PrintF("🆔 Credential ID: %s\n", credential->credential_id);
PrintF("👤 Subject: %s\n", subject_did);
PrintF("🏢 Issuer: %s\n", issuer_did);
PrintF("📅 Valid until: %llu\n", credential->expiry_date);
}
// Create identity claim
U0 create_identity_claim(U8* subject_did, U8 claim_type, U8* claim_value,
U8* verifier_did) {
IdentityClaim* claim = allocate_claim();
// Generate unique claim ID
generate_claim_id(subject_did, claim_type, claim->claim_id);
// Initialize claim
MemCpy(claim->subject_did, subject_did, 32);
MemCpy(claim->verifier_did, verifier_did, 32);
claim->claim_type = claim_type;
claim->verification_timestamp = get_current_timestamp();
claim->is_verified = FALSE;
// Encrypt claim value
U8[32] claim_encryption_key;
derive_claim_encryption_key(subject_did, claim->claim_id, claim_encryption_key);
encrypt_claim_value(claim_value, claim_encryption_key, claim->claim_value);
// Generate cryptographic proof
generate_claim_proof(claim, claim->proof_signature);
PrintF("📋 Identity claim created\n");
PrintF("🆔 Claim ID: %s\n", claim->claim_id);
PrintF("📊 Claim type: %s\n", get_claim_type_name(claim_type));
PrintF("✅ Awaiting verification\n");
}
Zero-Knowledge Proof System
<span class="filename">📁 Zero-Knowledge Proofs</span>
// Generate zero-knowledge proof for age verification
U0 generate_age_proof(U8* subject_did, U16 min_age, U8* proof_out) {
// Get age credential
VerifiableCredential* age_credential = get_credential_by_type(subject_did, CLAIM_TYPE_AGE);
if (age_credential == NULL || age_credential->is_revoked) {
PrintF("❌ Valid age credential not found\n");
return;
}
// Decrypt age from credential
U8[32] decryption_key;
derive_credential_encryption_key(subject_did, age_credential->credential_id, decryption_key);
U8[256] decrypted_data;
decrypt_credential_data(age_credential->credential_data, decryption_key, decrypted_data);
U16 actual_age = parse_age_from_data(decrypted_data);
// Generate zero-knowledge proof that age >= min_age without revealing actual age
ZKProofContext* zk_context = create_zk_context();
// Setup proof circuit: prove actual_age >= min_age
setup_age_comparison_circuit(zk_context, min_age);
// Generate witness (private input)
U8[64] witness;
create_age_witness(actual_age, witness);
// Generate proof
generate_zk_proof(zk_context, witness, proof_out);
destroy_zk_context(zk_context);
PrintF("🔐 Zero-knowledge age proof generated\n");
PrintF("📊 Minimum age requirement: %d\n", min_age);
PrintF("✅ Proof validates age without revealing actual value\n");
}
// Verify zero-knowledge proof
Bool verify_age_proof(U8* proof_data, U16 min_age, U8* issuer_pubkey) {
// Create verification context
ZKVerificationContext* verify_context = create_zk_verification_context();
// Setup verification circuit with same parameters
setup_age_comparison_circuit_verifier(verify_context, min_age);
// Verify the proof
Bool proof_valid = verify_zk_proof(verify_context, proof_data);
// Verify issuer signature on the underlying credential
Bool signature_valid = verify_issuer_signature(proof_data, issuer_pubkey);
destroy_zk_verification_context(verify_context);
Bool overall_valid = proof_valid && signature_valid;
PrintF("🔍 Zero-knowledge proof verification: %s\n",
overall_valid ? "Valid" : "Invalid");
return overall_valid;
}
// Generate selective disclosure proof
U0 generate_selective_disclosure_proof(U8* subject_did, U8* required_claims,
U8 claim_count, U8* proof_out) {
SelectiveDisclosureProof* sd_proof = allocate_sd_proof();
// Initialize proof structure
sd_proof->subject_did = subject_did;
sd_proof->claim_count = claim_count;
sd_proof->proof_timestamp = get_current_timestamp();
// For each required claim, generate selective proof
for (U8 i = 0; i < claim_count; i++) {
U8 claim_type = required_claims[i];
// Get credential for this claim type
VerifiableCredential* credential = get_credential_by_type(subject_did, claim_type);
if (credential == NULL || credential->is_revoked) {
PrintF("❌ Required credential not available: %s\n",
get_claim_type_name(claim_type));
continue;
}
// Create merkle proof for this specific claim
create_merkle_proof_for_claim(credential, claim_type,
&sd_proof->claim_proofs[i]);
// Add to disclosed claims
sd_proof->disclosed_claims[i] = claim_type;
}
// Generate overall proof signature
sign_selective_disclosure_proof(sd_proof, subject_did, proof_out);
PrintF("🎭 Selective disclosure proof generated\n");
PrintF("📊 Claims disclosed: %d\n", claim_count);
PrintF("🔒 Personal data remains private\n");
}
Verification and Access Control
<span class="filename">📁 Verification System</span>
// Create verification request
U0 create_verification_request(U8* verifier_did, U8* subject_did,
U8* required_claims, U8 claim_count) {
VerificationRequest* request = allocate_verification_request();
// Generate unique request ID
generate_request_id(verifier_did, subject_did, request->request_id);
// Initialize request
MemCpy(request->verifier_did, verifier_did, 32);
MemCpy(request->subject_did, subject_did, 32);
request->claim_count = claim_count;
MemCpy(request->required_claims, required_claims, claim_count);
request->request_timestamp = get_current_timestamp();
request->expiry_timestamp = request->request_timestamp + 3600; // 1 hour expiry
request->is_fulfilled = FALSE;
// Send request to subject
send_verification_request_to_subject(subject_did, request);
PrintF("📋 Verification request created\n");
PrintF("🆔 Request ID: %s\n", request->request_id);
PrintF("👤 Subject: %s\n", subject_did);
PrintF("📊 Required claims: %d\n", claim_count);
}
// Fulfill verification request with zero-knowledge proof
U0 fulfill_verification_request(U8* request_id, U8* subject_did, U8* proof_data) {
VerificationRequest* request = get_verification_request(request_id);
if (request == NULL) {
PrintF("❌ Verification request not found\n");
return;
}
if (get_current_timestamp() > request->expiry_timestamp) {
PrintF("❌ Verification request expired\n");
return;
}
// Verify the subject matches
if (MemCmp(request->subject_did, subject_did, 32) != 0) {
PrintF("❌ Subject mismatch\n");
return;
}
// Validate the zero-knowledge proof
Bool proof_valid = validate_verification_proof(request, proof_data);
if (proof_valid) {
// Store proof data
MemCpy(request->proof_data, proof_data, 1024);
request->is_fulfilled = TRUE;
// Notify verifier
notify_verifier_of_fulfillment(request->verifier_did, request_id);
PrintF("✅ Verification request fulfilled\n");
PrintF("🔐 Zero-knowledge proof validated\n");
PrintF("🎯 All required claims proven\n");
} else {
PrintF("❌ Invalid verification proof\n");
}
}
// Validate verification proof
Bool validate_verification_proof(VerificationRequest* request, U8* proof_data) {
// Parse proof data
VerificationProof* proof = parse_verification_proof(proof_data);
if (proof == NULL) {
return FALSE;
}
// Validate each required claim
for (U8 i = 0; i < request->claim_count; i++) {
U8 required_claim_type = request->required_claims[i];
// Find proof for this claim type
ClaimProof* claim_proof = find_claim_proof_by_type(proof, required_claim_type);
if (claim_proof == NULL) {
PrintF("❌ Missing proof for claim type: %s\n",
get_claim_type_name(required_claim_type));
free_verification_proof(proof);
return FALSE;
}
// Validate individual claim proof
if (!validate_individual_claim_proof(claim_proof, request->subject_did)) {
PrintF("❌ Invalid proof for claim type: %s\n",
get_claim_type_name(required_claim_type));
free_verification_proof(proof);
return FALSE;
}
}
free_verification_proof(proof);
return TRUE;
}
Building and Testing
Compilation Steps
<div class="step-number">1</div>
<div class="step-content">
<h4>Build the HolyBPF Compiler</h4>
<div class="command-block">
<code>cd /path/to/holyBPF-rust</code><br>
<code>cargo build --release</code>
</div>
</div>
<div class="step-number">2</div>
<div class="step-content">
<h4>Compile the Identity Verification System</h4>
<div class="command-block">
<code>./target/release/pible examples/identity-verification/src/main.hc</code>
</div>
</div>
Expected Output
🔄 Compiling Identity Verification System...
✅ Lexical analysis complete - 165 tokens processed
✅ Parsing complete - AST with 45 nodes generated
✅ Code generation complete - 298 BPF instructions generated
🎯 Identity Verification Features:
✅ Decentralized identity creation
✅ Verifiable credential issuance
✅ Zero-knowledge proof generation
✅ Selective disclosure mechanisms
✅ Credential revocation system
✅ Privacy-preserving verification
Usage Examples
Identity Setup and Credential Issuance
# Create decentralized identity
echo "Creating decentralized identity..."
USER_PUBKEY="UserPublicKeyHere"
RECOVERY_KEY="RecoveryPublicKeyHere"
METADATA_URI="https://example.com/did/metadata.json"
./target/release/pible examples/identity-verification/src/main.hc \
--action create-identity \
--owner $USER_PUBKEY \
--recovery-key $RECOVERY_KEY \
--metadata-uri "$METADATA_URI"
# Issue age credential
echo "Issuing age credential..."
ISSUER_DID="did:holybpf:issuer123"
SUBJECT_DID="did:holybpf:user456"
CREDENTIAL_TYPE=1 # Age credential
AGE_DATA="25" # Age: 25 years
ISSUER_PRIVATE_KEY="IssuerPrivateKeyHere"
./target/release/pible examples/identity-verification/src/main.hc \
--action issue-credential \
--issuer $ISSUER_DID \
--subject $SUBJECT_DID \
--type $CREDENTIAL_TYPE \
--data "$AGE_DATA" \
--private-key $ISSUER_PRIVATE_KEY
echo "Identity setup completed:"
echo "- DID created: $SUBJECT_DID"
echo "- Age credential issued"
echo "- Ready for verification"
Zero-Knowledge Age Verification
# Generate zero-knowledge age proof
echo "Generating age proof..."
MIN_AGE=21 # Prove age >= 21 without revealing actual age
./target/release/pible examples/identity-verification/src/main.hc \
--action generate-age-proof \
--subject $SUBJECT_DID \
--min-age $MIN_AGE
# Verify the proof
echo "Verifying age proof..."
PROOF_DATA="ZKProofDataHere"
ISSUER_PUBKEY="IssuerPublicKeyHere"
./target/release/pible examples/identity-verification/src/main.hc \
--action verify-age-proof \
--proof-data $PROOF_DATA \
--min-age $MIN_AGE \
--issuer-pubkey $ISSUER_PUBKEY
echo "Age verification results:"
echo "- Proof type: Zero-knowledge"
echo "- Minimum age verified: $MIN_AGE"
echo "- Actual age: Hidden"
echo "- Verification: Successful"
Security Considerations
⚠️ Cryptographic Security
- Use strong cryptographic primitives for all operations
- Implement secure key management and rotation
- Protect private keys with hardware security modules
- Regular security audits of cryptographic implementations
⚠️ Privacy Protection
- Minimize data collection and storage
- Implement data anonymization techniques
- Use zero-knowledge proofs for sensitive verifications
- Ensure selective disclosure capabilities
⚠️ Credential Security
- Implement robust revocation mechanisms
- Monitor for credential misuse or compromise
- Use time-limited credentials where appropriate
- Implement multi-factor authentication for sensitive operations
Real-World Applications
Self-Sovereign Identity
Microsoft ION Network
- Bitcoin-based decentralized identity
- DID document anchoring on blockchain
- Sidetree protocol implementation
- Large-scale identity verification
Hyperledger Indy
- Permissioned blockchain for identity
- Anonymous credentials and proofs
- Schema and credential definition registry
- Privacy-preserving identity verification
Government Digital Identity
Estonia’s e-Residency
- Digital identity for global citizens
- Blockchain-based identity verification
- Government service access
- Cross-border digital identity recognition
Next Steps
After mastering Identity Verification, explore:
- Privacy Voting - Anonymous voting systems
- Decentralized Storage - Secure data storage
- Social Graph - Identity-based social networks
The Identity Verification system demonstrates how to build privacy-preserving identity solutions with cryptographic guarantees while maintaining user control and data minimization principles.