Skip to content

Trust Model

Deep dive on how trust propagates through the VDI protocol: from attestations to receipts to verifier sets to transparency logs.

Trust Architecture Overview

┌─────────────────────────────────────────────────────┐
│                    Trust Layers                      │
├─────────────────────────────────────────────────────┤
│  Layer 5: Transparency Log (equivocation detection) │
│  Layer 4: Verifier Lifecycle (key rotation/revoke)  │
│  Layer 3: Trusted Verifier Sets (k-of-n quorum)     │
│  Layer 2: Verification Receipts (trust propagation)  │
│  Layer 1: Verification Profiles (check semantics)    │
│  Layer 0: Decision Attestation (ZK proof + sig)      │
├─────────────────────────────────────────────────────┤
│  Foundation: Groth16 + Ed25519 (math)               │
└─────────────────────────────────────────────────────┘

Each layer builds on the one below. The foundation is pure mathematics.

Layer 0: Decision Attestations

An attestation is a cryptographic proof that a decision followed rules. It contains:

  • A Groth16 ZK proof that the execution satisfied all constraints
  • An Ed25519 signature over the canonical JSON payload
  • An embedded verification key so anyone can verify without external lookup
  • A pipeline hash proving the exact process that was executed
  • A manifest hash proving which constraints were applied

Trust guarantee: The attestation is valid if and only if the math checks out. No trust in QuantZK or any third party required.

Layer 1: Verification Profiles

Profiles standardize what "verified" means. Without profiles, two verifiers might run different checks and both claim the attestation is "verified."

Built-in Profiles

javascript
import { PROFILES } from '@quantzk/attest';

// Strict: all 7 checks, requires formal authority
PROFILES.VDI_VERIFY_STRICT_V1
// → checks: ['schema', 'timestamps', 'pipeline_integrity', 'policy_integrity', 'zk_proof', 'signature', 'key_integrity']
// → accepted_authority_types: ['legal_review', 'standards_body', 'audit_firm']

// Standard: all 7 checks, any authority
PROFILES.VDI_VERIFY_STANDARD_V1

// Minimal: just schema, timestamps, and ZK proof
PROFILES.VDI_VERIFY_MINIMAL_V1

When a verifier emits a receipt, the profile ID and hash are recorded:

javascript
receipt.verification_profile  // 'VDI_VERIFY_STRICT_V1'
receipt.profile_hash          // '0x...', SHA-256 of profile definition

This lets downstream consumers know exactly which checks were performed and refuse receipts that don't meet their requirements.

Layer 2: Verification Receipts

A receipt is a signed proof-of-verification. It enables trust propagation, one agent verifies the ZK proof, and downstream agents accept the receipt instead of re-verifying.

Receipt Lifecycle

Attestation ──► Verifier B ──► Receipt ──► Agent C (accepts receipt)

                                  └──► Agent D (accepts receipt)
                                  └──► Agent E (accepts receipt)

Creating a Receipt

javascript
import { verifyAndReceipt } from '@quantzk/attest';

const { verification, receipt } = await verifyAndReceipt(attestation, {
  signingKey: myPrivateKey,
  verifierId: 'vdi:verifier:compliance-bot',
  profileId: 'VDI_VERIFY_STRICT_V1'
});

What a Receipt Contains

  • attestation_hash, SHA-256 binding to the original attestation
  • verifier, Who verified (ID, implementation, version)
  • verification_profile, Which checks were run
  • result, Pass/fail with per-check breakdown
  • signature, Ed25519 signature by the verifier
  • expires_at, 24-hour default TTL

Accepting a Receipt

javascript
import { verifyReceipt } from '@quantzk/attest';

const result = await verifyReceipt(receipt, {
  attestation: originalAttestation,  // verify hash binding
  trustedVerifiers: ['vdi:verifier:compliance-bot']  // trust check
});
// result.valid === true
// result.checks: [expiry, attestation_binding, trusted_verifier, receipt_signature]

Receipt Chaining

Receipts can reference parent receipts, creating verifiable chains:

javascript
const { receipt: receiptC } = await verifyAndReceipt(attestation, {
  signingKey: agentCKey,
  verifierId: 'vdi:verifier:risk-monitor',
  parentReceiptHash: '0x' + sha256(JSON.stringify(receiptB)),
  chainDepth: 1
});

// receiptC.parent_receipt_hash === hash of receiptB
// receiptC.chain_depth === 1

This establishes causal ordering of verifications.

Layer 3: Trusted Verifier Sets (TVS)

A TVS defines which verifiers are trusted and what quorum is required to accept a set of receipts.

Defining a TVS

javascript
const tvs = {
  tvs_id: 'vdi:tvs:acme-production',
  name: 'ACME Corp Production Verifier Set',
  verifiers: [
    { verifier_id: 'vdi:verifier:compliance-bot', name: 'Internal Compliance', trust_level: 'primary' },
    { verifier_id: 'vdi:verifier:auditco-bot', name: 'External Auditor', trust_level: 'secondary' },
    { verifier_id: 'vdi:verifier:risk-monitor', name: 'Risk Monitor', trust_level: 'secondary' }
  ]
};

Acceptance Policies

javascript
import { evaluateAcceptancePolicy } from '@quantzk/attest';

// Low: any 1 trusted receipt
const low = await evaluateAcceptancePolicy(receipts, { level: 'low', tvs });

// Medium: 1 primary OR 2 secondary
const medium = await evaluateAcceptancePolicy(receipts, { level: 'medium', tvs });

// High: 2+ independent verifiers
const high = await evaluateAcceptancePolicy(receipts, { level: 'high', tvs });

// Critical: 2+ independent + probabilistic spot-check (re-runs ZK proof)
const critical = await evaluateAcceptancePolicy(receipts, {
  level: 'critical',
  tvs,
  spotCheckRate: 0.05  // 5% chance of re-verification
}, attestation);

Spot-Check Enforcement

At the critical level, the policy randomly re-runs the full ZK verification to catch fraudulent receipts:

javascript
// If spot-check triggers and fails:
// { accepted: false, reason: 'Spot-check FAILED, receipts may be fraudulent' }

// If spot-check triggers and passes:
// { accepted: true, reason: '2 independent verifiers + spot-check PASSED' }

The spot-check rate is configurable. Even a low rate (1-5%) creates a strong deterrent because verifiers cannot predict when they'll be checked.

Layer 4: Verifier Key Lifecycle

The verifier registry manages identity and key lifecycle.

Registration

javascript
import { VerifierRegistry } from '@quantzk/attest';

const registry = new VerifierRegistry();
registry.register({
  verifierId: 'vdi:verifier:compliance-bot',
  name: 'ACME Compliance Verifier',
  publicKey: '0x...',
  organization: 'ACME Corp',
  capabilities: ['full_verification']
});

Key Rotation

Keys can be rotated with a grace period where both old and new keys are valid:

javascript
const rotation = registry.rotateKey('vdi:verifier:compliance-bot', newPublicKey, 86400);
// → { new_key_version: 2, grace_period_seconds: 86400 }

// During grace period:
registry.validateKey(verifierId, oldKey);  // { valid: true, status: 'grace_period' }
registry.validateKey(verifierId, newKey);  // { valid: true, status: 'active' }

Revocation

Verifiers can be revoked (e.g., after equivocation detection):

javascript
registry.revoke('vdi:verifier:rogue-bot', 'Equivocation detected');
registry.isRevoked('vdi:verifier:rogue-bot');  // true
registry.validateKey('vdi:verifier:rogue-bot', anyKey);  // { valid: false }

Layer 5: Transparency Log

The transparency log is a Merkle-tree-based append-only log, modeled after Certificate Transparency (RFC 6962).

Why It Exists

Without a transparency log, a malicious verifier could:

  1. Issue a PASS receipt to Agent C
  2. Issue a FAIL receipt to Agent D
  3. Neither agent would know the other received a contradictory receipt

The transparency log makes this detectable.

Appending Receipts

javascript
import { TransparencyLog } from '@quantzk/attest';

const log = new TransparencyLog();

const entry = log.append(receipt);
// entry.log_index === 0
// entry.tree_root === '0x...' (Merkle root)
// entry.equivocation_detected === false

Inclusion Proofs

Prove a receipt exists in the log:

javascript
const proof = log.getInclusionProof(entry.log_index);
const valid = log.verifyInclusionProof(proof);
// valid === true

Equivocation Detection

When a verifier issues contradictory receipts, the log detects it:

javascript
// Verifier D issues PASS, then FAIL for the same attestation
log.append(passReceipt);  // equivocation_detected: false
log.append(failReceipt);  // equivocation_detected: true

const check = log.checkEquivocation(attestation.attestation_id);
// check.clean === false
// check.equivocations[0].verifier_id === 'vdi:verifier:rogue-bot'

Response to Equivocation

  1. Detect equivocation via transparency log
  2. Revoke the verifier in the registry
  3. All receipts from that verifier become invalid
  4. Downstream agents reject those receipts

Trust Scoring

The scoreReceiptSet() function provides a quantitative trust assessment:

javascript
import { scoreReceiptSet } from '@quantzk/attest';

const score = scoreReceiptSet([receiptB, receiptC]);
// {
//   total_receipts: 2,
//   valid_receipts: 2,
//   unique_verifiers: 2,
//   unique_profiles: 2,
//   all_valid: true,
//   includes_zk_verification: true,
//   trust_score: 100,              // 0-100
//   recommendation: 'high_confidence'
// }

Scoring Formula

  • 25 points per unique verifier (up to 75)
  • 25 points if at least one receipt includes ZK proof verification
  • 25 points if all receipts are valid

Recommendation Thresholds

Score RangeRecommendation
75+ with ZK verifyhigh_confidence
50-74medium_confidence
< 50low_confidence

End-to-End Trust Flow

1. Decision Made
   └─► VDI Prover generates attestation with Groth16 proof

2. Primary Verification
   └─► Verifier B runs 7-step verification (strict profile)
   └─► Emits signed receipt
   └─► Receipt appended to transparency log
   └─► Inclusion proof generated

3. Secondary Verification
   └─► Verifier C runs 7-step verification (standard profile)
   └─► Emits signed receipt (chained to B)
   └─► Receipt appended to transparency log

4. Trust Evaluation
   └─► Agent D evaluates receipt set against TVS
   └─► Acceptance policy: 2 independent verifiers ✅
   └─► Spot-check: probabilistic ZK re-verification
   └─► Trust score: 100/100, high_confidence

5. Trust Propagation
   └─► Agent E accepts D's evaluation
   └─► No ZK re-verification needed
   └─► ~2ms per receipt check

6. Continuous Monitoring
   └─► Transparency log monitors for equivocation
   └─► Key rotation on schedule
   └─► Revocation if malfeasance detected

Verification keys are embedded in attestations. The verifier is open source.