VDI: Verifiable Decision Infrastructure Protocol
Version: 1.0.0 Status: Draft Authors: QuantZK
Abstract
VDI defines a standard format for cryptographically verifiable decision attestations. A Decision Attestation is a self-contained, portable artifact that proves a decision was made correctly, following defined constraints, by authorized actors, using valid inputs, without revealing the decision logic, input data, or internal state.
Verification requires only the attestation object and a verifier library. No server, no API, no trust in the attestation issuer is required.
0. Cryptographic model (non-normative)
VDI security arguments assume a probabilistic polynomial-time (PPT) adversary with full visibility into attestation and receipt artifacts, verifier code, and network traffic, control over decision inputs, and adaptive interaction with proving/verification interfaces. For signatures, the adversary is in the chosen-message setting (EUF-CMA). Curves referenced as BN128 in this document may also be referred to as BN254 in some tooling/literature.
0.1 Adversary capabilities and limits
Adversary capabilities in scope:
- Construct arbitrary attestation objects (well-formed or malformed) and submit them to verifiers.
- Modify/tamper with attestation payloads in transit.
- Attempt to produce accepting proofs without a satisfying witness.
- Replay old attestations or receipts.
- Attempt manifest/pipeline substitution.
- Exploit key or setup compromise if such compromise occurs.
Adversary limits (assumptions):
- Ed25519 signatures are existentially unforgeable (EUF-CMA).
- Groth16 soundness/knowledge-soundness holds for the instantiated circuits.
- SHA-256 and Poseidon resist preimage, second-preimage, and collision attacks at the intended security level.
- For invalid decisions (relative to the encoded relation), no valid witness exists unless constraint encoding is wrong.
0.2 Enforcement soundness statement
Let $R_M$ be the relation induced by manifest-constrained circuit $M$, and let $x$ denote verifier-visible statement data (including pipeline hash, manifest hash, verification-key binding, and public signals). For any security parameter $\lambda$ and any PPT adversary $\mathcal{A}$, if $\mathcal{A}$ outputs $(x,\pi,\sigma)$ such that verification accepts (proof check, key-integrity check, and signature/binding checks pass), then there exists a witness $w$ such that $R_M(x,w)=1$, except with probability negligible in $\lambda$.
Proof sketch: Groth16 knowledge soundness implies acceptance corresponds to knowledge of a witness for the compiled relation. With correct constraint encoding (equivalently, circuit construction relative to intended policy semantics) plus manifest/pipeline/key/signature binding checks, witness existence implies compliance with encoded constraints. Therefore invalid decisions are unprovable except with probability negligible in $\lambda$.
Reduction-style interpretation: Any adversary that achieves non-negligible success in this enforcement setting can be transformed into an adversary that breaks either Groth16 knowledge soundness (accepting proof without satisfying witness) or Ed25519 EUF-CMA/binding assumptions (successful payload-signature substitution), contradicting the assumptions above.
0.3 Trusted setup assumption
When Groth16 is used, security depends on at least one honest participant in the setup ceremony destroying toxic waste.
0.4 Formal example ($x,w,C_M$)
Let $C_M$ be the compiled constraints for manifest $M$, and define $R_M(x,w)=1 \iff C_M(x,w)$ is satisfied.
- $x$ (public statement): pipeline hash, manifest hash, decision commitment, and policy parameters.
- $w$ (private witness): sensitive attributes and execution-trace values.
Valid case: if there exists $w$ with $C_M(x,w)=1$, completeness implies a proof $\pi$ exists such that Verify(vk, x, pi) = 1.
Invalid case: if for fixed $x$ there is no $w$ with $C_M(x,w)=1$, then no PPT adversary can produce accepting $\pi$ except with probability negligible in $\lambda$.
0.5 Security game view (enforcement unforgeability)
Define game $\mathsf{Game}_{\mathrm{enf}}^\mathcal{A}(\lambda)$:
- Challenger samples setup/keys at security parameter $\lambda$ and publishes verifier-visible parameters.
- Adversary $\mathcal{A}$ obtains adaptive access to allowed interfaces (including chosen-message signature queries where applicable).
- $\mathcal{A}$ outputs candidate $(x,\pi,\sigma)$.
- $\mathcal{A}$ wins iff verification accepts and there is no witness $w$ such that $R_M(x,w)=1$.
Define advantage $\mathrm{Adv}{\mathrm{enf}}^\mathcal{A}(\lambda)=\Pr[\mathsf{Game}{\mathrm{enf}}^\mathcal{A}(\lambda)=1]$. Security claim: $\mathrm{Adv}_{\mathrm{enf}}^\mathcal{A}(\lambda)$ is negligible in $\lambda$ for all PPT $\mathcal{A}$.
0.6 Normative proof backend modes
VDI has one attestation envelope but multiple proving relations. Implementations and documentation MUST use these exact mode identifiers:
| Mode | Canonical meaning | Primary APIs / circuits |
|---|---|---|
causal | zk-cp relation over DAG/path necessity (causalProof) | default attest() path in @quantzk/attest, VDI prover + zk-cp/build/causalProof* |
enforced-policy | policy constraints encoded directly in named Circom policy circuits | PolicyProver, attestEnforcedPolicy(), protocol/build/{fairLending,hipaaAccess,euAiAct,soc2Access} |
compliance | certificate/scoring relation for compliance attestation | ComplianceCertificateProver, protocol/build/complianceCertificate |
Alternate labels for these modes SHOULD NOT be used in normative docs or API surfaces to avoid semantic drift.
1. Decision Attestation Object
The atomic unit of VDI. A JSON object with exactly these fields:
{
"vdi_version": "1.0.0",
"type": "decision_attestation_v1",
"attestation_id": "vdi:att:0x<32-byte-hex>",
"pipeline": {
"id": "vdi:pipeline:0x<16-byte-hex>",
"hash": "0x<32-byte-hex>",
"name": "ACME Bank Lending",
"version": "1.0.0"
},
"policy": {
"manifest_hash": "0x<32-byte-hex>",
"constraint_count": 3,
"authority": {
"type": "self_attested|legal_review|standards_body|audit_firm",
"name": "Covington & Burling LLP",
"reference": "Opinion #2026-AI-FL-014",
"regulation": "Fair Lending Act, ECOA"
}
},
"outcome": {
"id": "decision_output",
"timestamp": 1709078400
},
"proof": {
"system": "groth16",
"curve": "bn128",
"pi_a": ["<field-element>", "<field-element>", "1"],
"pi_b": [["<fe>", "<fe>"], ["<fe>", "<fe>"], ["1", "0"]],
"pi_c": ["<field-element>", "<field-element>", "1"],
"public_signals": []
},
"verification": {
"key": {
"protocol": "groth16",
"curve": "bn128",
"nPublic": 0,
"vk_alpha_1": [...],
"vk_beta_2": [...],
"vk_gamma_2": [...],
"vk_delta_2": [...],
"IC": [...]
},
"key_hash": "0x<32-byte-hex>"
},
"signature": {
"algorithm": "Ed25519",
"kid": "0x<16-byte-hex>",
"public_key": "0x<32-byte-hex>",
"value": "0x<64-byte-hex>"
},
"issued_at": 1709078400,
"expires_at": 1740614400
}2. Verification Algorithm
To verify a Decision Attestation, execute these steps IN ORDER. ALL must pass. If any fails, the attestation is INVALID.
Step 1: Schema Validation
vdi_versionmust be a supported version- All required fields present
attestation_idmatches formatvdi:att:0x[64 hex chars]
Step 2: Timestamp Validation
issued_atmust be in the pastexpires_atmust be in the future (or attestation is expired)
Step 3: Pipeline Integrity
pipeline.hashmust be a valid SHA-256 hex string
Step 4: Policy Integrity
policy.manifest_hashmust be a valid SHA-256 hex stringpolicy.authority.typemust be one of the defined types
Step 5: ZK Proof Verification
- Using
verification.key, verify the Groth16 proof:snarkjs.groth16.verify(verification.key, proof.public_signals, proof) - This is pure math. No server required.
Step 6: Signature Verification
- Reconstruct the canonical payload (all fields except
signature.value) - Verify:
Ed25519.verify(signature.value, canonical_payload, signature.public_key)
Step 7: Verification Key Integrity
- Compute SHA-256 over the RFC 8785 canonical JSON serialization of
verification.key(the same canonicalization scheme as the attestation signing payload; notJSON.stringifyunless it happens to match that canonical form). - The digest MUST match
verification.key_hash(after normalizing optional0xprefixes).
Step 8: Revocation status (profile-dependent)
- Under
VDI_VERIFY_STRICT_V1, the caller MUST supplyrevocationalongside the attestation (offline CRL-style set and/or online fetch result). See Section 7. - If the profile requires revocation data and
revocationis omitted: INVALID (VDI_ERR_REVOCATION_DATA_REQUIRED). - If
attestation_id∈revocation.revokedAttestations: INVALID (VDI_ERR_ATTESTATION_REVOKED). - If
signature.kid∈revocation.revokedKids: INVALID (VDI_ERR_SIGNING_KEY_REVOKED). - If
revocation.snapshotTimeis set andissued_at > snapshotTime: INVALID (VDI_ERR_REVOCATION_STALE— snapshot predates issuance).
Step 9: Authority binding (profile-dependent)
- Under
VDI_VERIFY_STRICT_V1,manifest.authority_signatureMUST be present. authority_signature.signed_hashMUST equalpolicy.manifest_hash.- Verify Ed25519: signature MUST be valid over UTF-8 bytes of the string
signed_hash(identical message encoding to registryManifest.verifyAuthority).
Step 10: Circuit governance (optional)
- If
circuitis present, implementations SHOULD append a metadata step. - Pin enforcement is configurable: it is OFF unless the caller provides
options.circuitRegistry. - If
verifyDecisionis called withoptions.circuitRegistry, the verifier MUST comparecircuit.circuit_hashto the pin forcircuit.circuit_id(wasm_sha256orcircuit_hashfield in the pin object). Mismatch ⇒ INVALID (VDI_ERR_CIRCUIT_HASH_MISMATCH). Pins with"deprecated": true⇒ INVALID (VDI_ERR_CIRCUIT_DEPRECATED). - Example pin file:
protocol/conformance/circuit-registry.example.json. - The example pin file is derived from
protocol/ARTIFACT_MANIFEST.json(circuits.<id>.artifacts.wasm.sha256) and MUST be refreshed whenever circuit artifacts are regenerated.
Result
On success: { valid: true, steps: [...], profileId, ... }. On failure: { valid: false, failedStep, code, reason, profileId?, steps: [...] }. The code string is stable and MUST match §2.1 for normative failures.
2.1 Verification error codes (normative)
| Code | When |
|---|---|
VDI_ERR_UNKNOWN_PROFILE | profileId not in the implementation’s profile registry |
VDI_ERR_INTERNAL | Unexpected exception inside the verifier |
VDI_ERR_SCHEMA_* | Step 1 schema violations (suffix encodes field) |
VDI_ERR_TIMESTAMP_ISSUED_AT | Issued in the future (beyond skew) |
VDI_ERR_TIMESTAMP_EXPIRED | Past expires_at |
VDI_ERR_PIPELINE_HASH_FORMAT | Malformed pipeline hash |
VDI_ERR_POLICY_HASH_FORMAT | Malformed policy.manifest_hash |
VDI_ERR_POLICY_AUTHORITY_TYPE | Unknown authority type |
VDI_ERR_ZK_VERIFY | ZK verifier threw (malformed inputs) |
VDI_ERR_ZK_INVALID | Groth16 verify returned false |
VDI_ERR_SIGNATURE_VERIFY | Exception while verifying attestation Ed25519 |
VDI_ERR_SIGNATURE_INVALID | Attestation Ed25519 verify returned false |
VDI_ERR_KEY_INTEGRITY | key_hash does not match canonical key digest |
VDI_ERR_REVOCATION_DATA_REQUIRED | Strict profile, no revocation object |
VDI_ERR_ATTESTATION_REVOKED | ID in revokedAttestations |
VDI_ERR_SIGNING_KEY_REVOKED | kid in revokedKids |
VDI_ERR_REVOCATION_STALE | snapshotTime too old vs issued_at |
VDI_ERR_AUTHORITY_SIGNATURE_REQUIRED | Strict profile, missing manifest.authority_signature |
VDI_ERR_AUTHORITY_MANIFEST_HASH | Missing policy.manifest_hash for binding |
VDI_ERR_AUTHORITY_HASH_MISMATCH | signed_hash ≠ policy.manifest_hash |
VDI_ERR_AUTHORITY_ALGORITHM | Unsupported authority_signature.algorithm |
VDI_ERR_AUTHORITY_KEY_FORMAT | Bad key/signature length or encoding |
VDI_ERR_AUTHORITY_SIGNATURE_INVALID | Authority Ed25519 verify false |
VDI_ERR_AUTHORITY_SIGNATURE_VERIFY | Exception during authority verify |
VDI_ERR_AUTHORITY_LEVEL | Below profile min_authority_level |
VDI_ERR_AUTHORITY_NOT_ACCEPTED | Authority type not in profile allowlist |
VDI_ERR_MANIFEST_TRUST_CLASS | Strict profile requires manifest.trust_class === "published" |
VDI_ERR_CIRCUIT_ID | Step 10: missing circuit.circuit_id |
VDI_ERR_CIRCUIT_HASH | Step 10: missing circuit.circuit_hash |
VDI_ERR_CIRCUIT_HASH_MISMATCH | Step 10: hash does not match circuitRegistry pin |
VDI_ERR_CIRCUIT_DEPRECATED | Step 10: pin marked deprecated |
VDI_ERR_CIRCUIT_GOVERNANCE | Step 10: other governance failure |
2.2 Policy object: registry-bound issuance (optional)
When an issuer binds an attestation to a published registry manifest, policy.manifest_hash SHOULD equal that manifest’s canonical hash, and the attestation SHOULD include an optional policy.enforcement_parameters_digest (SHA-256 hex) fingerprinting the enforced circuit parameters (e.g. compiled threshold values), so verifiers can distinguish manifest identity from parameterization.
2.3 Conformance execution (non-normative)
Reference conformance artifacts are in protocol/conformance/ and are consumed by JS, Go, and Python test suites. A one-command auditor runner is provided:
bash protocol/scripts/run-vdi-audit-suite.sh
This executes attestation and receipt conformance checks across all three reference implementations.
2.4 Runtime crypto dependency requirements (non-normative)
Implementations MUST NOT silently degrade cryptographic checks.
- Python verifier deployments require:
py_eccfor full Groth16 bn128 pairing verificationPyNaClfor Ed25519 signature verification
- If unavailable, verification SHOULD fail closed with deterministic
VDI_ERR_*codes rather than structural-only or skipped verification behavior.
3. Canonical Payload Format
For signature computation, the canonical payload is computed as:
- Take all fields of the attestation object EXCEPT
signature.value - Serialize using RFC 8785 (JSON Canonicalization Scheme)
- The signature is computed over the bytes of this canonical form
4. Policy Manifest Format
A Policy Manifest is a published, versioned set of constraints:
{
"manifest_version": "1.0.0",
"manifest_id": "vdi:manifest:fair-lending-v1",
"name": "Fair Lending Act Compliance Constraints",
"regulation": "Fair Lending Act, ECOA, CFPB Regulation B",
"authority": { "type": "legal_review", "name": "...", "reference": "..." },
"constraints": [
{ "id": "no_protected_class", "description": "...", "critical": true },
{ "id": "adverse_action_justified", "description": "...", "critical": true },
{ "id": "rate_within_bounds", "description": "...", "critical": false }
],
"manifest_hash": "0x<SHA-256 of constraints array>"
}5. Trust Levels
| Level | Authority | What it means |
|---|---|---|
| 0 | self_attested | Issuer defines own constraints. No external validation. |
| 1 | legal_review | Named law firm reviewed and attested constraint correctness. |
| 2 | audit_firm | Licensed audit firm validated constraints as part of engagement. |
| 3 | standards_body | Standards organization (NIST, ISO, AICPA) published the constraints. |
6. Verification Key Distribution
Verification keys are embedded in the attestation object itself. No key server or PKI infrastructure is required. The key_hash field allows caching and deduplication.
7. Revocation
7.1 Offline vs regulated verification
- Offline / minimal profiles: Revocation MAY be omitted. Verifiers only see cryptographic validity and timestamps.
VDI_VERIFY_STANDARD_V1: Revocation SHOULD be supplied when the deployment maintains CRLs or OCSP-style lists; if omitted, verification proceeds (revocation step is informational pass).VDI_VERIFY_STRICT_V1: Revocation data MUST be supplied as an objectrevocationpassed intoverifyDecision(attestation, { revocation }). Implementations treat an empty object{ "revokedAttestations": [], "revokedKids": [] }as a valid explicit “empty CRL” snapshot.
7.2 Revocation object
{
"revokedAttestations": ["vdi:att:0x..."],
"revokedKids": ["0x..."],
"snapshotTime": 1709078400
}snapshotTime(optional): Unix seconds. If set, an attestation withissued_ataftersnapshotTimeMUST fail withVDI_ERR_REVOCATION_STALE(the snapshot does not cover that issuance period).
7.3 Online hints
Attestations MAY include "revocation_endpoint": "https://..." as a hint for fetchers; the protocol does not mandate TLS or response format here—callers map fetches into the revocation object before calling strict verification.
8. Verification Receipts
A Verification Receipt is a deterministic, signed, cacheable proof-of-verification. When a verifier checks an attestation, it produces a receipt that says: "Verifier X ran these checks, at this time, with this implementation, and got PASS."
Receipts are second-order artifacts. They enable:
- Caching: Verify once, reuse many times
- Trust routing: Specialist verifiers emit receipts consumed by downstream agents
- Multi-hop trust: Agents build trust graphs without every node re-verifying
- Audit trails: Receipts document who verified what, when, with what result
8.1 Receipt Format
{
"vdi_receipt_version": "1.0.0",
"type": "verification_receipt_v1",
"receipt_id": "vdi:receipt:0x<32-byte-hex>",
"attestation_id": "vdi:att:0x...",
"attestation_hash": "0x<32-byte-hex>",
"verifier": {
"implementation": "@quantzk/vdi-verifier",
"version": "1.0.0",
"verifier_id": "vdi:verifier:0x<16-byte-hex>"
},
"policy_manifest_hash": "0x...",
"circuit_id": "causalProof",
"result": {
"valid": true,
"checks": {
"schema": true,
"timestamps": true,
"pipeline_integrity": true,
"policy_integrity": true,
"zk_proof": true,
"signature": true,
"key_integrity": true
},
"failed_step": null
},
"verified_at": 1709078400,
"expires_at": 1709164800,
"signature": {
"algorithm": "Ed25519",
"public_key": "0x<32-byte-hex>",
"value": "0x<64-byte-hex>"
}
}8.2 Receipt Verification
To verify a receipt:
- Check
receipt_idformat:vdi:receipt:0x[64 hex chars] - Verify
attestation_hashmatches SHA-256 of the referenced attestation - Verify Ed25519 signature over the canonical receipt payload
- Check
verified_atis in the past,expires_atis in the future - Optionally: check verifier identity against a trusted verifier set
8.3 Trust Propagation
Agents MAY accept a receipt instead of re-verifying the attestation, subject to:
- The receipt was signed by a trusted verifier
- The receipt has not expired
- The attestation_hash matches the attestation in question
This enables "verified once, reused many times" at network scale.
8.4 Attestation Extension
Attestations MAY include an optional receipts array:
{
"...existing attestation fields...": "",
"receipts": [
{ "receipt": "object" },
{ "receipt": "object" }
]
}9. Trusted Verifier Sets (TVS)
A Trusted Verifier Set defines which verifiers an agent accepts receipts from. This prevents receipt equivocation, a malicious verifier issuing false PASS receipts.
9.1 TVS Format
{
"tvs_version": "1.0.0",
"tvs_id": "vdi:tvs:acme-production",
"name": "ACME Corp Production Verifier Set",
"verifiers": [
{
"verifier_id": "vdi:verifier:0x...",
"name": "ACME Compliance Verifier",
"public_key": "0x...",
"trust_level": "primary"
},
{
"verifier_id": "vdi:verifier:0x...",
"name": "External Audit Verifier",
"public_key": "0x...",
"trust_level": "secondary"
}
],
"tvs_hash": "0x<SHA-256 of verifiers array>"
}9.2 Acceptance Policies
Agents MUST define an acceptance policy for receipt consumption:
| Risk Level | Policy | Description |
|---|---|---|
low | Accept 1 receipt from any TVS member | Fast path for non-critical decisions |
medium | Accept 1 receipt from primary verifier, OR 2 from secondary | Standard enterprise policy |
high | Require k-of-n receipts from independent verifiers | High-stakes decisions (lending, clinical) |
critical | k-of-n receipts + random spot-check full re-verification | Maximum assurance, spot-checks keep verifiers honest |
9.3 Spot-Check Enforcement
For critical acceptance policy, the consuming agent MUST:
- Accept the receipt(s) per quorum rules
- With probability
p(configurable, default 5%), perform full ZK re-verification - If spot-check fails, revoke trust in the offending verifier
- Log all spot-check results for audit
10. Verification Profiles
A Verification Profile defines exactly what "verified" means. Receipts are only comparable if they reference the same profile.
10.1 Profile Format
{
"profile_version": "1.0.0",
"profile_id": "VDI_VERIFY_STRICT_V1",
"name": "VDI Strict Verification Profile",
"checks": [
{ "step": 1, "name": "schema", "required": true },
{ "step": 2, "name": "timestamps", "required": true, "max_clock_skew_seconds": 300 },
{ "step": 3, "name": "pipeline_integrity", "required": true },
{ "step": 4, "name": "policy_integrity", "required": true },
{ "step": 5, "name": "zk_proof", "required": true },
{ "step": 6, "name": "signature", "required": true },
{ "step": 7, "name": "key_integrity", "required": true },
{ "step": 8, "name": "revocation_status", "required": true },
{ "step": 9, "name": "authority_binding", "required": true },
{ "step": 10, "name": "circuit_governance", "required": false, "when_present": true }
],
"accepted_proof_systems": ["groth16"],
"accepted_curves": ["bn128"],
"accepted_authority_types": ["legal_review", "standards_body", "audit_firm"],
"min_authority_level": 1,
"profile_hash": "0x<SHA-256 of profile definition>"
}10.2 Profile Binding
Every receipt MUST include:
verification_profile: the profile ID usedprofile_hash: SHA-256 of the profile definition
Downstream agents can enforce: "only accept receipts verified under profile X."
10.3 Standard Profiles
| Profile ID | Pipeline checks (ordered) | Authority / manifest | Revocation |
|---|---|---|---|
VDI_VERIFY_STRICT_V1 | Steps 1–9 (incl. revocation + authority binding) | min_authority_level ≥ 1, published manifest trust class, cryptographic authority signature | MUST supply revocation |
VDI_VERIFY_STANDARD_V1 | Steps 1–8 (incl. revocation check if data present; not required) | Any accepted authority type | SHOULD supply when operational |
VDI_VERIFY_MINIMAL_V1 | Steps 1, 2, 5 only (schema, timestamps, ZK proof) | None | N/A |
10.4 Profile Enforcement (Normative)
The verifyDecision() function MUST accept optional profileId and revocation parameters. When provided, the verifier:
- Only runs the checks listed in the profile's
checksarray. ForVDI_VERIFY_MINIMAL_V1, pipeline integrity, policy integrity, signature, key integrity, revocation, and authority binding are skipped entirely. - Enforces
accepted_authority_types. If the attestation'spolicy.authority.typeis not in the profile's accepted list, verification fails with codeVDI_ERR_AUTHORITY_NOT_ACCEPTED. - Enforces
min_authority_level. Authority types are mapped to levels:self_attested=0, legal_review=1, audit_firm=2, standards_body=3. If the attestation's authority level is below the profile's minimum, verification fails withVDI_ERR_AUTHORITY_LEVEL. - Strict manifest: For
VDI_VERIFY_STRICT_V1, after pipeline checks,manifest.trust_classMUST be"published"(VDI_ERR_MANIFEST_TRUST_CLASS).
When profileId is omitted, the reference implementation in @quantzk/vdi-verifier defaults to VDI_VERIFY_STRICT_V1. HTTP/integration layers SHOULD default to VDI_VERIFY_STRICT_V1 as well; callers that intentionally need reduced requirements MUST pass profileId: "VDI_VERIFY_STANDARD_V1" explicitly.
11. Receipt Chaining
Receipts can reference parent receipts, creating a trust graph.
11.1 Parent Receipt Reference
A receipt MAY include:
{
"parent_receipt_hash": "0x...",
"chain_depth": 2
}This indicates the verifier considered a prior receipt when making its assessment.
11.2 Receipt Sets
Attestations MAY accumulate receipts over time:
{
...attestation...,
"receipts": [
{ receipt_1 },
{ receipt_2 },
{ receipt_3 }
]
}More receipts from diverse verifiers = higher confidence. This creates an emergent trust graph without central coordination.
11.3 Receipt Set Scoring
Agents MAY compute a trust score from a receipt set:
- Count of unique verifier IDs
- Count of distinct verification profiles used
- Minimum trust level across all receipts
- Whether any receipt includes a full ZK re-verification (spot-check)
12. Receipt Transparency Log
Prevents receipt equivocation. Modeled after Certificate Transparency (RFC 6962).
12.1 Log Structure
Append-only Merkle tree of receipt hashes. Each entry records:
log_index,entry_hash,attestation_id,verifier_id,result,appended_at
12.2 Equivocation Detection
If the same verifier submits contradictory results for the same attestation, the log flags equivocation_detected: true with the conflicting entry index.
12.3 Inclusion Proofs
Any party can request a Merkle inclusion proof for a receipt entry, proving it exists in the log without revealing other entries.
13. Verifier Key Lifecycle
13.1 Key Registration
Verifiers register with: public_key, organization, capabilities. Keys have validity windows (default 1 year).
13.2 Key Rotation
rotateKey(verifierId, newPublicKey, gracePeriod), old key remains valid during the grace period, new key becomes current.
13.3 Revocation
revoke(verifierId, reason), all keys immediately invalidated. Receipts signed before revocation remain valid if verified against the key's validity window at the time of signing.
13.4 Key Validation
validateKey(verifierId, publicKey, atTimestamp), checks whether a specific key was valid at a given time. Used during receipt verification to ensure the signing key was active when the receipt was issued.
14. Circuit Governance
Attestations SHOULD include circuit metadata for auditability:
{
"circuit": {
"circuit_id": "causalProof",
"circuit_version": "2.0.0",
"circuit_hash": "0x<SHA-256 of WASM>",
"r1cs_hash": "0x<SHA-256 of R1CS>",
"compiler": "circom",
"compiler_version": "2.1.9",
"proof_system": "groth16",
"curve": "bn128",
"constraints": 5447,
"audit_reference": "NCC Group Report #2026-ZK-014"
}
}14.1 Purpose
Verifiers and auditors can confirm which circuit logic produced the proof. Without this, there is no way to distinguish proofs from different circuit versions.
14.2 Validation
Circuit metadata is informational, it does not affect proof validity. However, regulated use cases SHOULD require:
circuit_hashmatches a known, audited circuitcompiler_versionis on an approved listaudit_referenceis present for production use
14.3 Artifact Manifest
An ARTIFACT_MANIFEST.json file SHOULD be maintained alongside compiled circuits. It records the SHA-256 hash of every artifact (WASM, zkey, vkey, R1CS, sym) for each circuit. On startup, the prover SHOULD validate all artifact hashes against the manifest. If any hash mismatches, the system SHOULD refuse to generate proofs.
14.4 Artifact authority policy (normative)
- Canonical zkey per circuit is the pin at
ARTIFACT_MANIFEST.json:circuit.<id>.artifacts.zkey. - MPC-backed status is determined from
ARTIFACT_MANIFEST.json:circuit.<id>.ceremonyfields plus transcript hash pins. - Verification pin enforcement is configurable and only active when verifier callers pass
circuitRegistry; strict profile does not implicitly force pin checks. - Rotations MUST update manifest pins and SHOULD update conformance registry pins in the same change window.
14.5 Artifact lifecycle and compatibility rules
- Attestations are validated against embedded
verification.key/verification.key_hashand selected verification profile policy. - Artifact rotations are versioned and MUST NOT be silent.
- Deprecation MUST be explicit (
deprecated: truein registry pin metadata), not implied by replacement. - Historical verification windows and deprecation policy MUST be documented for each deployment.
Upgrade matrix (expected behavior)
| Attestation artifact epoch | Verifier epoch/config | VDI_VERIFY_STANDARD_V1 | VDI_VERIFY_STRICT_V1 |
|---|---|---|---|
| old | new verifier, no circuitRegistry | PASS if embedded proof/signature/timestamps pass | PASS if strict-only checks pass (revocation + authority binding) |
| old | new verifier with circuitRegistry | PASS if circuit_hash matches pin; else VDI_ERR_CIRCUIT_HASH_MISMATCH | same as STANDARD + strict-only checks |
| new | old verifier | PASS if schema/crypto checks supported by that verifier implementation | PASS/FAIL per old strict implementation semantics |
| new | new verifier with circuitRegistry | PASS when manifest and registry pins are updated in lockstep | same as STANDARD + strict-only checks |
Rotation runbook: protocol/docs/circuit-artifact-rotation-runbook.md.
15. enforced-policy and compliance circuits
In addition to the causal circuit family (which proves pipeline execution structure), VDI supports the enforced-policy mode where regulatory constraints are embedded directly in the arithmetic circuit. The prover cannot generate a valid proof for a decision that violates any constraint, not by policy, not by audit, by mathematics.
15.1 Attestation Extension
Enforced policy attestations include two additional top-level fields:
{
"proof_status": "required",
"policy_enforcement": "in_circuit"
}proof_status: "required"indicates the proof is not optional or best-effort.policy_enforcement: "in_circuit"indicates constraints are enforced by the circuit, not by application-layer validation.
15.2 Available Circuits
| Circuit ID | Constraints | Regulation | Public Inputs |
|---|---|---|---|
causalProof | 5,447 | General proof of DAG execution necessity | None (zero public inputs) |
fairLending | 36 | Fair Lending Act, ECOA | min_credit_score, max_dti_x100 |
hipaaAccess | 31 | HIPAA Privacy Rule (45 CFR 164) | min_auth_level, max_fields, min_purpose_code |
euAiAct | 47 | EU AI Act (Reg. 2024/1689, Art. 6-14) | min_risk_level, min_oversight_score, min_transparency_score |
soc2Access | 39 | AICPA Trust Services CC6 | min_auth_factors, max_permission_level, max_session_timeout |
complianceCertificate | 1,937 | General compliance scoring | framework_id, criteria_hash, claimed_score, score_threshold, certificate_id_hash, timestamp |
15.3 Circuit Pattern
All enforced policy circuits follow the same structural pattern:
- Binary input validation, flags are constrained to
{0, 1}. - Forbidden action constraint, a
=== 0constraint on prohibited fields (e.g.,protected_class_used === 0,bulk_export_attempted === 0). - Threshold comparators, private inputs compared against public policy parameters using
GreaterEqThan/LessEqThancomponents. - Conditional approval, approval (
output === 1) requires all checks to pass; denial is always safe.
15.4 compliance certificate circuit
The compliance certificate circuit is a special-purpose circuit for continuous compliance scoring. It computes a weighted score from private evidence results and verifies it against a Poseidon-committed criteria definition.
Key properties:
- 4-level Poseidon hash tree binds framework context, weights, criticality, and criterion IDs into a single
criteria_hashpublic input. - Integer-arithmetic scoring, no division or floating point. Score is in basis points (10000 = 100%).
- Critical criteria enforcement, if any criterion marked
critical=1hasevidence_result=0, proof generation fails. - Score threshold,
claimed_score >= score_thresholdis enforced in-circuit.
16. Cryptographic Authority Binding
16.1 Purpose
Authority identity in Section 5 is declarative, a string name and type. This is sufficient for policy manifests distributed through trusted channels, but it does not prevent an attacker from claiming a false authority in a custom manifest.
Cryptographic authority binding provides an optional mechanism for authorities to Ed25519-sign their manifest hash, creating a verifiable chain: regulation → authority signature → manifest hash → attestation.
16.2 Authority Signature Format
A manifest MAY include an authority_signature field:
{
"authority_signature": {
"algorithm": "Ed25519",
"public_key": "0x<32-byte-hex>",
"value": "0x<64-byte-hex>",
"signed_hash": "0x<manifest-hash>",
"signed_at": 1709078400
}
}16.3 Verification
To verify an authority binding:
- Confirm
signed_hashmatches the manifest's computed hash. - Verify the Ed25519 signature over the manifest hash bytes using
public_key. - Optionally, check
public_keyagainst a known authority key registry.
Authority binding is OPTIONAL. Manifests without an authority signature remain valid, they are equivalent to trust_class: "custom" with self_attested authority.
