Use Case Overview
Privacy-preserving attestations enable verification of claims without revealing sensitive underlying data. Users can prove compliance, eligibility, or credentials while maintaining control over their personal information. Ideal For:- Zero-knowledge identity verification
- Selective disclosure systems
- Privacy-compliant KYC/AML
- Anonymous credential systems
- GDPR-compliant verification
- Medical record verification
- Financial privacy protection
Privacy Architecture Patterns
Data Minimization Strategies
Implement attestations that reveal only necessary information:Copy
interface PrivacyArchitecture {
// 1. Minimal Disclosure
minimalDisclosure: {
onChain: 'boolean_results_only'; // Only yes/no answers
offChain: 'detailed_proofs'; // Full verification data
encrypted: 'sensitive_fields'; // Encrypted personal data
};
// 2. Selective Disclosure
selectiveDisclosure: {
claims: 'user_controlled'; // Users choose what to reveal
granular: 'field_level_control'; // Individual field control
contextual: 'purpose_specific'; // Different data for different uses
};
// 3. Zero-Knowledge Proofs
zkProofs: {
range: 'age_income_verification'; // Prove values in ranges
membership: 'list_inclusion'; // Prove list membership
computation: 'private_calculations'; // Prove computations on private data
};
// 4. Temporal Privacy
temporalPrivacy: {
ephemeral: 'short_lived_proofs'; // Time-limited attestations
rotating: 'key_rotation'; // Regular key updates
expiring: 'automatic_deletion'; // Self-destructing data
};
}
Privacy-Preserving Implementation
Zero-Knowledge Attestations
Implement ZK-based verification systems:Copy
import { StellarAttestSDK, SolanaAttestSDK } from '@attestprotocol/sdk';
import { generateProof, verifyProof, CircuitInput } from 'snarkjs'; // Example ZK library
class ZeroKnowledgeAttestationSystem {
private sdk: StellarAttestSDK | SolanaAttestSDK;
private zkCircuits: Map<string, ZKCircuit>;
constructor(sdk: StellarAttestSDK | SolanaAttestSDK) {
this.sdk = sdk;
this.initializeZKCircuits();
}
async createZKAgeVerification(
userAddress: string,
actualAge: number,
minimumAge: number,
proofData: AgeProofData
): Promise<ZKAttestationResult> {
const sessionId = `zk-age-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
try {
// Step 1: Generate zero-knowledge proof
const proof = await this.generateAgeProof(actualAge, minimumAge, proofData);
// Step 2: Create attestation with proof result
const attestation = await this.createAgeAttestation(userAddress, minimumAge, proof, sessionId);
// Step 3: Store proof data securely
await this.storeAgeProofData(sessionId, proof, attestation);
return this.buildZKResult(sessionId, attestation, proof);
} catch (error) {
await this.logZKError(sessionId, error);
throw error;
}
}
async createZKIncomeVerification(
userAddress: string,
actualIncome: number,
incomeThresholds: number[],
proofData: IncomeProofData
): Promise<ZKAttestationResult> {
const sessionId = `zk-income-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
try {
// Step 1: Generate income threshold proof
const proof = await this.generateIncomeProof(actualIncome, incomeThresholds, proofData);
// Step 2: Create income attestation
const attestation = await this.createIncomeAttestation(userAddress, actualIncome, incomeThresholds, proof, sessionId);
// Step 3: Store proof data
await this.storeIncomeProofData(sessionId, proof, attestation);
return this.buildZKResult(sessionId, attestation, proof);
} catch (error) {
await this.logZKError(sessionId, error);
throw error;
}
}
async verifyZKAttestation(
attestationUID: string,
verificationContext: ZKVerificationContext
): Promise<ZKVerificationResult> {
try {
// Step 1: Fetch and validate attestation
const attestation = await this.fetchAndValidateAttestation(verificationContext);
if (!attestation.valid) {
return { valid: false, reason: attestation.reason };
}
// Step 2: Retrieve stored proof data
const storedProof = await this.retrieveZKProof(attestation.data.reference);
if (!storedProof) {
return { valid: false, reason: 'ZK proof data not found' };
}
// Step 3: Verify the zero-knowledge proof
const proofVerification = await this.verifyStoredProof(storedProof, verificationContext);
return this.buildVerificationResult(attestation.data, proofVerification);
} catch (error) {
return {
valid: false,
reason: `ZK verification failed: ${error.message}`
};
}
}
Copy
private async generateAgeProof(
actualAge: number,
minimumAge: number,
proofData: AgeProofData
) {
// Generate zero-knowledge proof that age >= minimumAge without revealing actual age
const circuitInput: CircuitInput = {
age: actualAge,
minimumAge: minimumAge,
salt: this.generateSalt(),
documentHash: proofData.documentHash
};
const proof = await this.generateZKProof('age-verification', circuitInput);
if (!proof.valid) {
throw new Error('Zero-knowledge proof generation failed');
}
return proof;
}
Copy
private async createAgeAttestation(
userAddress: string,
minimumAge: number,
proof: any,
sessionId: string
) {
const attestation = await this.sdk.attest({
schemaUID: 'zk-age-verification-v1',
subject: userAddress,
value: `ageRequirementMet:true,minimumAge:${minimumAge},proofHash:${proof.hash},verificationMethod:zk_proof,timestamp:${Math.floor(Date.now() / 1000)}`,
reference: sessionId
});
if (attestation.error) {
throw new Error(`ZK attestation failed: ${attestation.error}`);
}
return attestation.data;
}
Copy
private async storeAgeProofData(sessionId: string, proof: any, attestation: string) {
await this.storeZKProof({
sessionId,
proofData: proof,
circuitType: 'age-verification',
attestationUID: attestation,
timestamp: Date.now()
});
}
Copy
private async generateIncomeProof(
actualIncome: number,
incomeThresholds: number[],
proofData: IncomeProofData
) {
const circuitInput: CircuitInput = {
income: actualIncome,
thresholds: incomeThresholds,
salt: this.generateSalt(),
documentHash: proofData.taxDocumentHash
};
const proof = await this.generateZKProof('income-verification', circuitInput);
if (!proof.valid) {
throw new Error('Income verification proof generation failed');
}
return proof;
}
Copy
private async createIncomeAttestation(
userAddress: string,
actualIncome: number,
incomeThresholds: number[],
proof: any,
sessionId: string
) {
// Calculate threshold results
const thresholdResults = incomeThresholds.map(threshold => ({
threshold,
meets: actualIncome >= threshold
}));
const thresholdString = thresholdResults
.map(r => `${r.threshold}:${r.meets}`)
.join('|');
const attestation = await this.sdk.attest({
schemaUID: 'zk-income-verification-v1',
subject: userAddress,
value: `thresholdResults:${thresholdString},proofHash:${proof.hash},verificationMethod:zk_proof,timestamp:${Math.floor(Date.now() / 1000)}`,
reference: sessionId
});
if (attestation.error) {
throw new Error(`ZK income attestation failed: ${attestation.error}`);
}
return attestation.data;
}
Copy
private async storeIncomeProofData(sessionId: string, proof: any, attestation: string) {
await this.storeZKProof({
sessionId,
proofData: proof,
circuitType: 'income-verification',
attestationUID: attestation,
timestamp: Date.now()
});
}
Copy
private buildZKResult(sessionId: string, attestation: string, proof: any): ZKAttestationResult {
return {
success: true,
sessionId,
attestationUID: attestation,
proofHash: proof.hash,
verificationMethod: 'zero_knowledge',
privacyLevel: 'maximum'
};
}
Copy
private async fetchAndValidateAttestation(context: ZKVerificationContext) {
const attestation = await this.sdk.fetchAttestation({
schemaUID: context.schemaUID,
subject: context.subject
});
if (attestation.error || !attestation.data || attestation.data.revoked) {
return {
valid: false,
reason: 'Attestation not found or revoked'
};
}
return {
valid: true,
data: attestation.data
};
}
Copy
private async verifyStoredProof(storedProof: any, context: ZKVerificationContext) {
return await this.verifyZKProof(
storedProof.circuitType,
storedProof.proofData,
context.publicInputs
);
}
Copy
private buildVerificationResult(attestationData: any, proofVerification: any): ZKVerificationResult {
const parsedData = this.parseAttestationData(attestationData.value);
return {
valid: proofVerification.valid,
reason: proofVerification.reason,
proofHash: parsedData.proofHash,
verificationMethod: parsedData.verificationMethod,
timestamp: parseInt(parsedData.timestamp)
};
}
private async generateZKProof(
circuitType: string,
input: CircuitInput
): Promise<{ valid: boolean; hash: string; proof: any }> {
const circuit = this.zkCircuits.get(circuitType);
if (!circuit) {
throw new Error(`ZK circuit not found: ${circuitType}`);
}
try {
// Generate proof using circuit
const { proof, publicSignals } = await generateProof(circuit.wasm, circuit.zkey, input);
// Create proof hash for attestation
const proofHash = this.hashProof(proof, publicSignals);
return {
valid: true,
hash: proofHash,
proof: { proof, publicSignals }
};
} catch (error) {
return {
valid: false,
hash: '',
proof: null
};
}
}
private async verifyZKProof(
circuitType: string,
storedProof: any,
publicInputs: any[]
): Promise<{ valid: boolean; reason: string }> {
const circuit = this.zkCircuits.get(circuitType);
if (!circuit) {
return {
valid: false,
reason: 'Verification circuit not found'
};
}
try {
const isValid = await verifyProof(
circuit.vkey,
storedProof.publicSignals,
storedProof.proof
);
return {
valid: isValid,
reason: isValid ? 'Proof verified successfully' : 'Proof verification failed'
};
} catch (error) {
return {
valid: false,
reason: `Verification error: ${error.message}`
};
}
}
private initializeZKCircuits(): void {
// Initialize ZK circuits for different verification types
this.zkCircuits = new Map([
['age-verification', {
wasm: 'circuits/age_verification.wasm',
zkey: 'circuits/age_verification.zkey',
vkey: 'circuits/age_verification_vkey.json'
}],
['income-verification', {
wasm: 'circuits/income_verification.wasm',
zkey: 'circuits/income_verification.zkey',
vkey: 'circuits/income_verification_vkey.json'
}],
['membership-verification', {
wasm: 'circuits/membership_verification.wasm',
zkey: 'circuits/membership_verification.zkey',
vkey: 'circuits/membership_verification_vkey.json'
}]
]);
}
private generateSalt(): string {
return Math.random().toString(36).substring(2, 15);
}
private hashProof(proof: any, publicSignals: any[]): string {
// Create deterministic hash of proof
return `0x${Buffer.from(JSON.stringify({ proof, publicSignals })).toString('hex').slice(0, 64)}`;
}
private parseAttestationData(value: string): Record<string, string> {
const pairs = value.split(',');
const result: Record<string, string> = {};
pairs.forEach(pair => {
const [key, val] = pair.split(':');
result[key] = val;
});
return result;
}
private async storeZKProof(proofRecord: ZKProofRecord): Promise<void> {
// Store proof data in secure, encrypted storage
// Implementation would use secure database or IPFS
}
private async retrieveZKProof(sessionId: string): Promise<ZKProofRecord | null> {
// Retrieve proof data from secure storage
return null; // Placeholder
}
private async logZKError(sessionId: string, error: any): Promise<void> {
// Log error for debugging while maintaining privacy
}
}
interface ZKCircuit {
wasm: string;
zkey: string;
vkey: string;
}
interface AgeProofData {
documentHash: string;
documentType: string;
issuingAuthority: string;
}
interface IncomeProofData {
taxDocumentHash: string;
year: number;
source: string;
}
interface ZKAttestationResult {
success: boolean;
sessionId: string;
attestationUID: string;
proofHash: string;
verificationMethod: string;
privacyLevel: string;
}
interface ZKVerificationContext {
schemaUID: string;
subject: string;
publicInputs: any[];
}
interface ZKVerificationResult {
valid: boolean;
reason: string;
proofHash?: string;
verificationMethod?: string;
timestamp?: number;
}
interface ZKProofRecord {
sessionId: string;
proofData: any;
circuitType: string;
attestationUID: string;
timestamp: number;
}
Selective Disclosure System
Enable users to control what information they reveal:Copy
class SelectiveDisclosureSystem {
private sdk: StellarAttestSDK | SolanaAttestSDK;
private encryptionService: EncryptionService;
constructor(
sdk: StellarAttestSDK | SolanaAttestSDK,
encryptionService: EncryptionService
) {
this.sdk = sdk;
this.encryptionService = encryptionService;
}
async createSelectiveDisclosureAttestation(
userAddress: string,
fullData: PersonalData,
disclosurePolicy: DisclosurePolicy
): Promise<SelectiveAttestationResult> {
const sessionId = `sd-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
try {
// Step 1: Process and encrypt sensitive data
const processedData = await this.processSelectiveDisclosureData(fullData, disclosurePolicy);
// Step 2: Create the selective disclosure attestation
const attestation = await this.createDisclosureAttestation(userAddress, processedData, sessionId);
// Step 3: Store encryption keys and policies
await this.storeDisclosureMetadata(sessionId, attestation, processedData, disclosurePolicy, userAddress);
return this.buildSelectiveDisclosureResult(sessionId, attestation, processedData, fullData);
} catch (error) {
await this.logDisclosureError(sessionId, error);
throw error;
}
}
async requestDisclosure(
attestationUID: string,
requesterAddress: string,
requestedFields: string[],
purpose: string
): Promise<DisclosureRequestResult> {
try {
// Step 1: Validate attestation and policy
const validation = await this.validateDisclosureRequest(attestationUID);
if (!validation.valid) {
return { approved: false, reason: validation.reason };
}
// Step 2: Evaluate field access permissions
const evaluation = this.evaluateFieldAccess(requestedFields, purpose, requesterAddress, validation.policy);
if (!evaluation.approved) {
return evaluation;
}
// Step 3: Generate disclosure proof for approved fields
const disclosureProof = await this.generateDisclosureProof(validation.attestation, requestedFields, validation.policy);
return this.buildDisclosureRequestResult(evaluation, disclosureProof);
} catch (error) {
return {
approved: false,
reason: `Disclosure request failed: ${error.message}`
};
}
}
async verifySelectiveDisclosure(
disclosureProof: DisclosureProof,
verificationContext: DisclosureVerificationContext
): Promise<DisclosureVerificationResult> {
try {
// Step 1: Verify proof authenticity
const proofValid = await this.verifyDisclosureProof(disclosureProof);
if (!proofValid) {
return { valid: false, reason: 'Disclosure proof verification failed' };
}
// Step 2: Decrypt and verify field data
const dataVerification = await this.verifyDisclosedData(disclosureProof);
if (!dataVerification.valid) {
return { valid: false, reason: dataVerification.reason };
}
return this.buildDisclosureVerificationResult(disclosureProof, dataVerification.data);
} catch (error) {
return {
valid: false,
reason: `Verification failed: ${error.message}`
};
}
}
private async encryptSelectiveFields(
data: PersonalData,
policy: DisclosurePolicy
): Promise<{ encryptedData: Record<string, string>; keys: Record<string, string> }> {
const encryptedData: Record<string, string> = {};
const keys: Record<string, string> = {};
for (const [field, value] of Object.entries(data)) {
if (policy.encryptedFields.includes(field)) {
const { encrypted, key } = await this.encryptionService.encrypt(JSON.stringify(value));
encryptedData[field] = encrypted;
keys[field] = key;
} else {
// Store plain text for non-sensitive fields
encryptedData[field] = JSON.stringify(value);
}
}
return { encryptedData, keys };
}
Copy
private async processSelectiveDisclosureData(
fullData: PersonalData,
disclosurePolicy: DisclosurePolicy
) {
// Encrypt sensitive fields
const encryptedData = await this.encryptSelectiveFields(fullData, disclosurePolicy);
// Create disclosure map
const disclosureMap = this.createDisclosureMap(fullData, disclosurePolicy);
return { encryptedData, disclosureMap };
}
Copy
private async createDisclosureAttestation(
userAddress: string,
processedData: any,
sessionId: string
) {
const attestationValue = this.buildSelectiveAttestationValue(
processedData.encryptedData,
processedData.disclosureMap
);
const attestation = await this.sdk.attest({
schemaUID: 'selective-disclosure-v1',
subject: userAddress,
value: attestationValue,
reference: sessionId
});
if (attestation.error) {
throw new Error(`Selective disclosure attestation failed: ${attestation.error}`);
}
return attestation.data;
}
Copy
private async storeDisclosureMetadata(
sessionId: string,
attestation: string,
processedData: any,
disclosurePolicy: DisclosurePolicy,
userAddress: string
) {
await this.storeDisclosureKeys({
sessionId,
attestationUID: attestation,
encryptionKeys: processedData.encryptedData.keys,
disclosurePolicy,
userAddress,
timestamp: Date.now()
});
}
Copy
private buildSelectiveDisclosureResult(
sessionId: string,
attestation: string,
processedData: any,
fullData: PersonalData
): SelectiveAttestationResult {
return {
success: true,
sessionId,
attestationUID: attestation,
disclosureCapabilities: processedData.disclosureMap,
availableFields: Object.keys(fullData)
};
}
Copy
private async validateDisclosureRequest(attestationUID: string) {
const attestation = await this.getAttestationDetails(attestationUID);
if (!attestation) {
return {
valid: false,
reason: 'Attestation not found'
};
}
const policy = await this.getDisclosurePolicy(attestation.sessionId);
if (!policy) {
return {
valid: false,
reason: 'Disclosure policy not found'
};
}
return {
valid: true,
attestation,
policy
};
}
Copy
private evaluateFieldAccess(
requestedFields: string[],
purpose: string,
requesterAddress: string,
policy: DisclosurePolicy
) {
return this.evaluateDisclosureRequest(
requestedFields,
purpose,
requesterAddress,
policy
);
}
Copy
private buildDisclosureRequestResult(
evaluation: any,
disclosureProof: DisclosureProof
): DisclosureRequestResult {
return {
approved: true,
disclosureProof,
revealedFields: evaluation.allowedFields,
restrictions: evaluation.restrictions
};
}
Copy
private async verifyDisclosedData(disclosureProof: DisclosureProof) {
// Decrypt requested fields
const decryptedData = await this.decryptDisclosedFields(
disclosureProof.encryptedData,
disclosureProof.decryptionKeys
);
// Verify field integrity
const integrityCheck = await this.verifyFieldIntegrity(
decryptedData,
disclosureProof.fieldHashes
);
if (!integrityCheck.valid) {
return {
valid: false,
reason: 'Field integrity verification failed'
};
}
return {
valid: true,
data: decryptedData
};
}
Copy
private buildDisclosureVerificationResult(
disclosureProof: DisclosureProof,
decryptedData: any
): DisclosureVerificationResult {
return {
valid: true,
revealedData: decryptedData,
verificationLevel: disclosureProof.verificationLevel,
restrictions: disclosureProof.restrictions,
expiresAt: disclosureProof.expiresAt
};
}
private createDisclosureMap(
data: PersonalData,
policy: DisclosurePolicy
): DisclosureCapabilities {
const capabilities: DisclosureCapabilities = {
publicFields: [],
conditionalFields: [],
restrictedFields: [],
requiresConsent: []
};
for (const field of Object.keys(data)) {
if (policy.publicFields.includes(field)) {
capabilities.publicFields.push(field);
} else if (policy.conditionalFields.includes(field)) {
capabilities.conditionalFields.push(field);
} else if (policy.restrictedFields.includes(field)) {
capabilities.restrictedFields.push(field);
}
if (policy.consentRequired.includes(field)) {
capabilities.requiresConsent.push(field);
}
}
return capabilities;
}
private buildSelectiveAttestationValue(
encryptedData: Record<string, string>,
disclosureMap: DisclosureCapabilities
): string {
// Build attestation value with encrypted fields and disclosure metadata
const components = [
`publicFields:${disclosureMap.publicFields.join('|')}`,
`conditionalFields:${disclosureMap.conditionalFields.join('|')}`,
`restrictedFields:${disclosureMap.restrictedFields.join('|')}`,
`encryptedFieldCount:${Object.keys(encryptedData).length}`,
`timestamp:${Math.floor(Date.now() / 1000)}`
];
return components.join(',');
}
private evaluateDisclosureRequest(
requestedFields: string[],
purpose: string,
requesterAddress: string,
policy: DisclosurePolicy
): DisclosureEvaluation {
const allowedFields: string[] = [];
const deniedFields: string[] = [];
const restrictions: string[] = [];
for (const field of requestedFields) {
if (policy.publicFields.includes(field)) {
allowedFields.push(field);
} else if (policy.conditionalFields.includes(field)) {
// Check conditions
const conditionMet = this.checkDisclosureConditions(field, purpose, requesterAddress, policy);
if (conditionMet) {
allowedFields.push(field);
restrictions.push(`${field}: conditional disclosure for ${purpose}`);
} else {
deniedFields.push(field);
}
} else if (policy.restrictedFields.includes(field)) {
// Check if requester has special privileges
if (policy.privilegedRequesters.includes(requesterAddress)) {
allowedFields.push(field);
restrictions.push(`${field}: privileged access only`);
} else {
deniedFields.push(field);
}
} else {
deniedFields.push(field);
}
}
return {
approved: deniedFields.length === 0,
allowedFields,
deniedFields,
restrictions,
reason: deniedFields.length > 0 ? `Access denied for fields: ${deniedFields.join(', ')}` : undefined
};
}
private checkDisclosureConditions(
field: string,
purpose: string,
requesterAddress: string,
policy: DisclosurePolicy
): boolean {
// Implement business logic for conditional disclosure
const conditions = policy.conditions[field] || [];
return conditions.every(condition => {
switch (condition.type) {
case 'purpose':
return condition.values.includes(purpose);
case 'requester_type':
return this.getRequesterType(requesterAddress) === condition.value;
case 'time_limit':
return Date.now() < condition.expiresAt;
default:
return false;
}
});
}
private getRequesterType(address: string): string {
// Determine requester type (e.g., verified_business, government, individual)
return 'individual'; // Placeholder
}
}
interface PersonalData {
firstName: string;
lastName: string;
dateOfBirth: string;
address: string;
phone: string;
email: string;
ssn: string;
income: number;
creditScore: number;
}
interface DisclosurePolicy {
publicFields: string[];
conditionalFields: string[];
restrictedFields: string[];
encryptedFields: string[];
consentRequired: string[];
privilegedRequesters: string[];
conditions: Record<string, DisclosureCondition[]>;
}
interface DisclosureCondition {
type: 'purpose' | 'requester_type' | 'time_limit';
values?: string[];
value?: string;
expiresAt?: number;
}
interface DisclosureCapabilities {
publicFields: string[];
conditionalFields: string[];
restrictedFields: string[];
requiresConsent: string[];
}
interface SelectiveAttestationResult {
success: boolean;
sessionId: string;
attestationUID: string;
disclosureCapabilities: DisclosureCapabilities;
availableFields: string[];
}
interface DisclosureRequestResult {
approved: boolean;
reason?: string;
disclosureProof?: DisclosureProof;
revealedFields?: string[];
restrictions?: string[];
}
interface DisclosureProof {
proofId: string;
attestationUID: string;
encryptedData: Record<string, string>;
decryptionKeys: Record<string, string>;
fieldHashes: Record<string, string>;
verificationLevel: string;
restrictions: string[];
expiresAt: number;
}
interface DisclosureEvaluation {
approved: boolean;
allowedFields: string[];
deniedFields: string[];
restrictions: string[];
reason?: string;
}
interface DisclosureVerificationContext {
expectedFields: string[];
purpose: string;
maxAge: number;
}
interface DisclosureVerificationResult {
valid: boolean;
reason?: string;
revealedData?: Record<string, any>;
verificationLevel?: string;
restrictions?: string[];
expiresAt?: number;
}
Advanced Privacy Techniques
Homomorphic Encryption for Computations
Enable computations on encrypted attestation data:Copy
class HomomorphicAttestationSystem {
private sdk: StellarAttestSDK | SolanaAttestSDK;
private heService: HomomorphicEncryptionService;
constructor(
sdk: StellarAttestSDK | SolanaAttestSDK,
heService: HomomorphicEncryptionService
) {
this.sdk = sdk;
this.heService = heService;
}
async createHomomorphicAttestation(
userAddress: string,
numericData: NumericData,
computationPolicy: ComputationPolicy
): Promise<HomomorphicAttestationResult> {
const sessionId = `he-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
try {
// Encrypt numeric data homomorphically
const encryptedData = await this.heService.encryptData(numericData);
// Create attestation with encrypted values
const attestationValue = this.buildHomomorphicAttestationValue(
encryptedData,
computationPolicy
);
const attestation = await this.sdk.attest({
schemaUID: 'homomorphic-data-v1',
subject: userAddress,
value: attestationValue,
reference: sessionId
});
if (attestation.error) {
throw new Error(`Homomorphic attestation failed: ${attestation.error}`);
}
return {
success: true,
sessionId,
attestationUID: attestation.data,
supportedOperations: computationPolicy.allowedOperations,
encryptionScheme: encryptedData.scheme
};
} catch (error) {
throw error;
}
}
async performHomomorphicComputation(
attestationUIDs: string[],
operation: HomomorphicOperation
): Promise<ComputationResult> {
try {
// Fetch encrypted data from attestations
const encryptedValues = await this.fetchEncryptedValues(attestationUIDs);
// Perform homomorphic computation
const result = await this.heService.compute(encryptedValues, operation);
// Create attestation for computation result
const resultAttestation = await this.attestComputationResult(result, operation);
return {
success: true,
resultAttestation,
operation: operation.type,
inputCount: attestationUIDs.length,
preservesPrivacy: true
};
} catch (error) {
return {
success: false,
error: error.message
};
}
}
private buildHomomorphicAttestationValue(
encryptedData: EncryptedNumericData,
policy: ComputationPolicy
): string {
return [
`encryptedValue:${encryptedData.ciphertext}`,
`encryptionScheme:${encryptedData.scheme}`,
`allowedOps:${policy.allowedOperations.join('|')}`,
`precision:${encryptedData.precision}`,
`timestamp:${Math.floor(Date.now() / 1000)}`
].join(',');
}
}
interface NumericData {
value: number;
type: 'income' | 'age' | 'score' | 'count';
precision: number;
}
interface ComputationPolicy {
allowedOperations: ('add' | 'multiply' | 'compare' | 'aggregate')[];
maxComputationDepth: number;
authorizedComputors: string[];
}
interface EncryptedNumericData {
ciphertext: string;
scheme: string;
precision: number;
publicKey: string;
}
interface HomomorphicOperation {
type: 'add' | 'multiply' | 'compare' | 'aggregate';
parameters: any;
}
interface HomomorphicAttestationResult {
success: boolean;
sessionId: string;
attestationUID: string;
supportedOperations: string[];
encryptionScheme: string;
}
interface ComputationResult {
success: boolean;
resultAttestation?: string;
operation?: string;
inputCount?: number;
preservesPrivacy?: boolean;
error?: string;
}
Anonymous Credentials System
Implement unlinkable anonymous credentials:Copy
class AnonymousCredentialSystem {
private sdk: StellarAttestSDK | SolanaAttestSDK;
private credentialService: AnonymousCredentialService;
constructor(
sdk: StellarAttestSDK | SolanaAttestSDK,
credentialService: AnonymousCredentialService
) {
this.sdk = sdk;
this.credentialService = credentialService;
}
async issueAnonymousCredential(
credentialData: CredentialData,
anonymitySet: string[]
): Promise<AnonymousCredentialResult> {
const sessionId = `anon-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
try {
// Generate anonymous credential
const credential = await this.credentialService.issueCredential({
data: credentialData,
anonymitySet,
unlinkable: true
});
// Create attestation without revealing identity
const attestation = await this.sdk.attest({
schemaUID: 'anonymous-credential-v1',
subject: credential.pseudonymousId, // Use pseudonym instead of real address
value: `credentialType:${credentialData.type},anonymitySetSize:${anonymitySet.length},issued:true,unlinkable:true,timestamp:${Math.floor(Date.now() / 1000)}`,
reference: sessionId
});
if (attestation.error) {
throw new Error(`Anonymous credential attestation failed: ${attestation.error}`);
}
return {
success: true,
sessionId,
credentialToken: credential.token,
attestationUID: attestation.data,
anonymitySetSize: anonymitySet.length,
unlinkable: true
};
} catch (error) {
throw error;
}
}
async presentAnonymousCredential(
credentialToken: string,
presentationPolicy: PresentationPolicy
): Promise<CredentialPresentationResult> {
try {
// Generate presentation proof
const presentation = await this.credentialService.present({
credential: credentialToken,
revealedAttributes: presentationPolicy.revealedAttributes,
predicates: presentationPolicy.predicates
});
if (!presentation.valid) {
return {
valid: false,
reason: 'Credential presentation generation failed'
};
}
return {
valid: true,
presentationProof: presentation.proof,
revealedData: presentation.revealedData,
anonymityPreserved: true,
unlinkable: true
};
} catch (error) {
return {
valid: false,
reason: `Presentation failed: ${error.message}`
};
}
}
async verifyAnonymousPresentation(
presentationProof: string,
verificationContext: AnonymousVerificationContext
): Promise<AnonymousVerificationResult> {
try {
// Verify presentation without learning identity
const verification = await this.credentialService.verifyPresentation({
proof: presentationProof,
expectedPredicates: verificationContext.expectedPredicates,
trustAnchors: verificationContext.trustedIssuers
});
return {
valid: verification.valid,
satisfiedPredicates: verification.satisfiedPredicates,
revealedAttributes: verification.revealedAttributes,
identityRevealed: false,
linkable: false
};
} catch (error) {
return {
valid: false,
reason: `Verification failed: ${error.message}`
};
}
}
}
interface CredentialData {
type: string;
attributes: Record<string, any>;
validityPeriod: number;
}
interface PresentationPolicy {
revealedAttributes: string[];
predicates: CredentialPredicate[];
}
interface CredentialPredicate {
attribute: string;
operation: 'greater_than' | 'less_than' | 'equals' | 'in_set';
value: any;
}
interface AnonymousCredentialResult {
success: boolean;
sessionId: string;
credentialToken: string;
attestationUID: string;
anonymitySetSize: number;
unlinkable: boolean;
}
interface CredentialPresentationResult {
valid: boolean;
reason?: string;
presentationProof?: string;
revealedData?: Record<string, any>;
anonymityPreserved?: boolean;
unlinkable?: boolean;
}
interface AnonymousVerificationContext {
expectedPredicates: CredentialPredicate[];
trustedIssuers: string[];
}
interface AnonymousVerificationResult {
valid: boolean;
reason?: string;
satisfiedPredicates?: string[];
revealedAttributes?: Record<string, any>;
identityRevealed: boolean;
linkable: boolean;
}
Privacy Compliance Implementation
GDPR Compliance System
Implement privacy-by-design for GDPR compliance:Copy
class GDPRCompliantAttestationSystem {
private sdk: StellarAttestSDK | SolanaAttestSDK;
private dataProcessor: DataProcessor;
private consentManager: ConsentManager;
constructor(
sdk: StellarAttestSDK | SolanaAttestSDK,
dataProcessor: DataProcessor,
consentManager: ConsentManager
) {
this.sdk = sdk;
this.dataProcessor = dataProcessor;
this.consentManager = consentManager;
}
async createGDPRCompliantAttestation(
userAddress: string,
personalData: PersonalData,
processingPurpose: ProcessingPurpose,
consent: ConsentRecord
): Promise<GDPRAttestationResult> {
const sessionId = `gdpr-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
try {
// Step 1: Validate consent and legal basis
await this.validateGDPRConsent(consent, processingPurpose);
// Step 2: Process data according to GDPR principles
const processedData = await this.processGDPRData(personalData, processingPurpose, userAddress);
// Step 3: Create GDPR-compliant attestation
const attestation = await this.createGDPRAttestation(processedData, processingPurpose, consent, sessionId);
// Step 4: Record processing activity for compliance
await this.recordGDPRActivity(sessionId, attestation, userAddress, processingPurpose, consent);
return this.buildGDPRResult(sessionId, attestation, processedData, processingPurpose);
} catch (error) {
await this.logGDPRError(sessionId, error);
throw error;
}
}
async exerciseDataSubjectRights(
userAddress: string,
rightType: DataSubjectRight,
requestDetails: RightExerciseRequest
): Promise<RightExerciseResult> {
try {
// Route to appropriate right handler
return await this.routeDataSubjectRight(userAddress, rightType, requestDetails);
} catch (error) {
return {
success: false,
rightType,
reason: error.message
};
}
}
private async handleDataErasure(
userAddress: string,
request: RightExerciseRequest
): Promise<RightExerciseResult> {
// Step 1: Find all user attestations
const userAttestations = await this.findUserAttestations(userAddress);
// Step 2: Process erasure for each attestation
const erasureResults = await this.processErasureRequests(userAttestations, request, userAddress);
return this.buildErasureResult(erasureResults);
}
Copy
private async validateGDPRConsent(
consent: ConsentRecord,
processingPurpose: ProcessingPurpose
) {
const consentValidation = await this.consentManager.validateConsent(
consent,
processingPurpose
);
if (!consentValidation.valid) {
throw new Error(`Invalid consent: ${consentValidation.reason}`);
}
}
Copy
private async processGDPRData(
personalData: PersonalData,
processingPurpose: ProcessingPurpose,
userAddress: string
) {
// Apply data minimization principles
const minimizedData = this.dataProcessor.minimizeData(
personalData,
processingPurpose
);
// Pseudonymize identifiers for privacy protection
const pseudonymizedData = await this.dataProcessor.pseudonymize(
minimizedData,
userAddress
);
return pseudonymizedData;
}
Copy
private async createGDPRAttestation(
processedData: any,
processingPurpose: ProcessingPurpose,
consent: ConsentRecord,
sessionId: string
) {
const attestationValue = this.buildGDPRAttestationValue(
processedData,
processingPurpose,
consent
);
const attestation = await this.sdk.attest({
schemaUID: 'gdpr-compliant-data-v1',
subject: processedData.pseudonymousId,
value: attestationValue,
reference: sessionId
});
if (attestation.error) {
throw new Error(`GDPR attestation failed: ${attestation.error}`);
}
return attestation.data;
}
Copy
private async recordGDPRActivity(
sessionId: string,
attestation: string,
userAddress: string,
processingPurpose: ProcessingPurpose,
consent: ConsentRecord
) {
await this.recordProcessingActivity({
sessionId,
attestationUID: attestation,
dataSubject: userAddress,
processingPurpose,
legalBasis: consent.legalBasis,
retentionPeriod: processingPurpose.retentionPeriod,
timestamp: Date.now()
});
}
Copy
private buildGDPRResult(
sessionId: string,
attestation: string,
processedData: any,
processingPurpose: ProcessingPurpose
): GDPRAttestationResult {
return {
success: true,
sessionId,
attestationUID: attestation,
pseudonymousId: processedData.pseudonymousId,
dataMinimized: true,
consentRecorded: true,
retentionPeriod: processingPurpose.retentionPeriod
};
}
Copy
private async routeDataSubjectRight(
userAddress: string,
rightType: DataSubjectRight,
requestDetails: RightExerciseRequest
): Promise<RightExerciseResult> {
switch (rightType) {
case 'access':
return await this.handleDataAccess(userAddress, requestDetails);
case 'rectification':
return await this.handleDataRectification(userAddress, requestDetails);
case 'erasure':
return await this.handleDataErasure(userAddress, requestDetails);
case 'portability':
return await this.handleDataPortability(userAddress, requestDetails);
case 'objection':
return await this.handleProcessingObjection(userAddress, requestDetails);
default:
throw new Error(`Unsupported right type: ${rightType}`);
}
}
Copy
private async processErasureRequests(
userAttestations: UserAttestation[],
request: RightExerciseRequest,
userAddress: string
) {
const erasureResults = [];
for (const attestation of userAttestations) {
const result = await this.processIndividualErasure(attestation, request, userAddress);
erasureResults.push(result);
}
return erasureResults;
}
Copy
private async processIndividualErasure(
attestation: UserAttestation,
request: RightExerciseRequest,
userAddress: string
) {
// Check if erasure is legally required
const erasureRequired = await this.assessErasureRequirement(attestation, request);
if (erasureRequired.required) {
// Revoke attestation
const revocation = await this.sdk.revokeAttestation({
schemaUID: attestation.schemaUID,
subject: userAddress,
reference: attestation.reference
});
if (!revocation.error) {
// Remove from processing records
await this.removeProcessingRecord(attestation.uid);
return {
attestationUID: attestation.uid,
erased: true,
method: 'revocation'
};
}
}
return {
attestationUID: attestation.uid,
erased: false,
reason: erasureRequired.reason
};
}
Copy
private buildErasureResult(erasureResults: any[]): RightExerciseResult {
return {
success: true,
rightType: 'erasure',
details: erasureResults,
completedAt: Date.now()
};
}
private buildGDPRAttestationValue(
pseudonymizedData: PseudonymizedData,
purpose: ProcessingPurpose,
consent: ConsentRecord
): string {
return [
`dataProcessed:true`,
`purpose:${purpose.type}`,
`legalBasis:${consent.legalBasis}`,
`dataMinimized:true`,
`pseudonymized:true`,
`retentionPeriod:${purpose.retentionPeriod}`,
`consentId:${consent.consentId}`,
`timestamp:${Math.floor(Date.now() / 1000)}`
].join(',');
}
private async recordProcessingActivity(activity: ProcessingActivity): Promise<void> {
// Record in GDPR processing register
// Implementation would store in secure, auditable database
}
private async findUserAttestations(userAddress: string): Promise<UserAttestation[]> {
// Find all attestations for a user across different schemas
return []; // Placeholder
}
private async assessErasureRequirement(
attestation: UserAttestation,
request: RightExerciseRequest
): Promise<{ required: boolean; reason?: string }> {
// Assess whether erasure is legally required
// Consider retention periods, legal obligations, legitimate interests
return { required: true };
}
}
interface ProcessingPurpose {
type: string;
description: string;
retentionPeriod: number;
necessaryData: string[];
}
interface ConsentRecord {
consentId: string;
legalBasis: 'consent' | 'contract' | 'legal_obligation' | 'vital_interests' | 'public_task' | 'legitimate_interests';
granted: boolean;
timestamp: number;
specific: boolean;
informed: boolean;
unambiguous: boolean;
}
interface PseudonymizedData {
pseudonymousId: string;
processedData: Record<string, any>;
pseudonymizationMethod: string;
}
interface ProcessingActivity {
sessionId: string;
attestationUID: string;
dataSubject: string;
processingPurpose: ProcessingPurpose;
legalBasis: string;
retentionPeriod: number;
timestamp: number;
}
interface GDPRAttestationResult {
success: boolean;
sessionId: string;
attestationUID: string;
pseudonymousId: string;
dataMinimized: boolean;
consentRecorded: boolean;
retentionPeriod: number;
}
type DataSubjectRight = 'access' | 'rectification' | 'erasure' | 'portability' | 'objection';
interface RightExerciseRequest {
requestId: string;
details: any;
urgency?: 'normal' | 'urgent';
}
interface RightExerciseResult {
success: boolean;
rightType: DataSubjectRight;
details?: any;
reason?: string;
completedAt?: number;
}
interface UserAttestation {
uid: string;
schemaUID: string;
reference: string;
createdAt: number;
}