Skip to content

QZR-1: QuantZK Verifiable Usage Receipt Specification

Status: Candidate (not frozen)
Spec id: QZR-1
Schema string: quantzk_billing_receipt_v1
Media type: application/vnd.quantzk.receipt+json
File extension: .qzk (JSON)

This specification separates QuantZK the company from the portable evidence object integrators and customers exchange. Normative language uses RFC 2119 MUST / SHOULD / MAY.

Freeze criterion. QZR-1 freezes only when an engineer with only this document (and listed public trust roots / golden vectors) can implement a verifier that agrees with protocol/conformance/qzr-1/expected-results.json without reading @quantzk/* source.


1. Purpose

A QZR-1 receipt lets any party answer, offline:

  • What usage identity produced a claimed charge?
  • Which tariff / evaluator digests were declared?
  • What public billing commitments were bound?
  • Who signed the meter event (if present)?
  • Which circuit / verification key / issuer produced the proof?
  • Have the settlement-relevant bytes been modified?
  • Does verification succeed without calling the issuer?

Fresh revocation / governance status requires a current revocation snapshot. Historical cryptographic validity of a frozen receipt remains checkable without issuer infrastructure.


2. Conformance levels (normative)

Levels answer different questions:

LevelMeaning
MinimalCryptographic receipt: historically valid attestation for a declared profile, with a recomputable billing fingerprint.
StandardCryptographically bound billing receipt: Minimal + verification receipt + fingerprint integrity + mandatory Phase-2 in-circuit commitment binding under an authorized apiBillingV2 circuit/vkey.
StrictBound receipt + current operational trust: Standard + authenticated meter provenance (when required) + fresh revocation CLEAR + profile transparency policy.

A level evaluation is a boolean PASS / FAIL. Individually reportable checks use the status enum in §6.1.

Downgrade resistance. An issuer MUST NOT omit Phase-2 fields and still claim Standard. For Standard evaluation, phase2_binding = NOT_CHECKED or missing proof ⇒ FAIL (not NOT_CHECKED). For Minimal, phase2_binding = NOT_APPLICABLE.


3. Top-level object

FieldTypeRequiredDescription
schemastringyesMUST be quantzk_billing_receipt_v1
qzrstringyesMUST be QZR-1
media_typestringrecommendedapplication/vnd.quantzk.receipt+json
billing_versionstringyesMUST be v2 for this revision
profileIdstringyesDeclared verification profile id
created_atstring (ISO-8601)recommendedEnvelope creation time
issuerstringoptionalDisplay name (not an authorization root)
attestationobjectyesdecision_attestation_v1
receiptobject | nullStandard+verification_receipt_v1
billingobjectyesCharge + fingerprint + digests + commitments
meter_envelopeobject | nullStrict when requiredExternally signed meter
meter_eventobject | nullrecommendedConvenience copy
tariff_snapshotobject | nullrecommendedConvenience copy
charge_authorityobject | nullrecommendedSigned grant that MUST predate the meter event (quantzk_charge_authority_v1)
execution_intentobject | nullrecommended when grant presentquantzk_execution_intent_v1 committed at preflight
execution_intent_digeststring | nullrecommended when grant present0x || SHA-256(JCS(execution_intent)); also MAY appear on billing_verify_fingerprint
job_idstring | nulloptionalIssuance correlation only
temporary_receipt_hashstring | nulloptionalAsync accept hash
issuanceobject | nulloptionale.g. { "mode": "async", "status": "completed" }

3.1 Integer wire representation

Integer fields that affect settlement (expected_charge_micros, usage_units, unit_price_micros, min/max charge micros) MUST be encoded as JSON numbers that are:

  1. Finite,
  2. Integers (no fractional part),
  3. In the inclusive range 09007199254740991 (2^53 − 1).

Implementations MUST reject values outside this range or with a fractional part. (This keeps cross-language interoperability inside the IEEE–754 / JS safe-integer bound. Larger values require a future QZR revision with string-encoded decimals.)


4. billing object

FieldMinimalStandardStrictDescription
expected_charge_microsMUSTMUSTMUSTSettled charge micros (§3.1)
currencySHOULDSHOULDSHOULDISO 4217
billing_verify_fingerprintMUSTMUSTMUSTCanonical billed fields (§4.1)
billing_verify_fingerprint_hashSHOULDMUSTMUST§5 hash of fingerprint
public_commitmentsMUSTMUSTObject bound by Phase-2
public_commitments_digestMUSTMUSTDigest of public_commitments (§5.2)
transparency_inclusion_proofprofileLog inclusion
transparency_log_entryprofile{ entry_hash, … }

4.1 billing_verify_fingerprint

MUST include at least:

  • event_id, tenant_id, billing_window_id, contract_version
  • usage_units, expected_charge_micros, currency
  • unit_price_micros
  • meter_event_digest, meter_signing_kid
  • tariff_id, tariff_version, tariff_digest
  • evaluator_version, evaluator_digest

Additional keys MAY be present; they MUST be included in canonicalization (§5).

4.2 Phase-2 claim boundary (normative, narrow)

Standard requires that the ordered billing field-images / public commitments are cryptographically bound by the approved Phase-2 circuit apiBillingV2 (binding_version = bn128-poseidon8-v1).

Standard does not claim that the Groth16 circuit recomputes the full deterministic tariff invoice algorithm. Tariff/charge consistency against tariff_snapshot remains a separate verifier invariant unless a future circuit version expands the relation.

4.3 Charge authority (Candidate)

The intended issuance order is authority → execution → charge → receipt.

Charge authority is a separate object from the QZR-1 receipt. The receipt MAY embed charge_authority (or reference digests) so verifiers can check continuity. Authorization answers “what was allowed?”; QZR-1 answers “what was charged?”

QZR-1 evaluate is always receipt-time. It MUST NOT be used as permission to execute a new paid action. Preflight MAY_EXECUTE and attest-time verification of prior consume_if_available are specified in Charge authority.

v1 grants MUST set usage_mode = single_use, a unique authority_id (qza: + SHA-256 hex of the signing message), and a unique nonce. Receipt-time authority: PASS means this receipt binds to this grant. It does not prove the grant was atomically consumed unless authority_consumption_check = PASS with authenticated consumption evidence, and it does not mean the grant may be spent now.

When charge_authority is present it MUST:

  1. Use schema quantzk_charge_authority_v1 with a valid Ed25519 signature over UTF-8 QZK_CHARGE_AUTHORITY_V1 || LF || JCS(canonical_authority_payload). canonical_authority_payload is the grant with authority_id, authority_digest, and signature.value removed. Digest algorithm is FIPS 180-4 SHA-256 of that signing message (full 32 bytes). authority_digest = 0x || lowercase hex; authority_id = qza: || the same hex (64 chars).
  2. Match tenant, contract, tariff id/version/digest, unit_price_micros, and currency of the meter event / tariff snapshot.
  3. Use integer Unix seconds only (issued_at <= valid_from <= valid_until). With skew s (default 60s): valid_from - s <= event_timestamp <= valid_until + s, and independently event_timestamp >= issued_at - s. This is consistency of authenticated timestamps, not independent clock proof. Fractional grant timestamps are invalid.
  4. Optional constraint keys (subject_id, endpoint, vendor_id, model_id, tool_id, cost_center, policy_digest, max_charge_micros): key absent = unconstrained. JSON null and empty string are not unconstrained and MUST FAIL. Present keys MUST match the meter/charge.
  5. If max_charge_micros is present: computed_charge_micros <= max_charge_micros, where computed_charge_micros is billing_verify_fingerprint.expected_charge_micros (the hashed charge). Convenience copies (billing.expected_charge_micros) MUST match that value (§4.4). Taxes/credits/discounts are outside the cap unless already folded into that integer.
  6. Trust: issuer / issuer_role are signed claims only. authority_trust_mode is open_signature (default) or pinned_roots (empty allow-list authorizes nobody). Do not infer trust from list emptiness.
  7. Anti-downgrade (Standard). If charge_authority is present, then billing_verify_fingerprint.authority_id MUST be present and MUST equal the grant’s recomputed authority_id (from canonical_authority_payload digest, not a mutable wire copy of grant.authority_id), and billing_verify_fingerprint.execution_intent_digest MUST be present and MUST match the meter-event intent projection and all intent-digest mirrors. Digest comparison MUST use the same canonical form as §4.4 hex equality (optional 0x stripped, lowercase). Missing identity/intent commitments yield authority_continuity / execution_intent_binding = NOT_CHECKED and MUST FAIL Standard. They MUST NOT be upgraded to authority: PASS by inference. Minimal MAY still PASS when those fields are absent (historical crypto). A present but mismatched digest or authority_id is FAIL at every profile (authority_continuity / execution_intent_binding ≠ FAIL is required for Minimal as well as Standard).

Absence of the grant object is authority = NOT_CHECKED (receipts without Charge Authority). A present but invalid grant is FAIL and MUST fail Standard.

4.4 Authoritative-field consistency (normative)

Committed-value dominance. For every security-relevant semantic value represented in more than one location, the specification identifies exactly one authoritative cryptographically bound representation. All other representations are mirrors. A verifier MUST reject any receipt in which a present mirror does not canonicalize to the authoritative value.

No security decision MAY be made from an uncommitted mirror when a cryptographically committed representation of the same fact exists. Conflicting representations fail verification.

This registry is representation consistency. It does not replace artifact-specific authenticity or derivation checks (recompute authority_id from the signed grant; verify that vkey_hash corresponds to the verification key).

Path presence (leaf of the registry path):

Wire stateMeaning
key / path absent (undefined)absent (ignore unless a profile requires the field)
JSON nullpresent and invalid (FAIL)
""present and invalid (FAIL)
present, valid encodingcanonicalize, then compare

Authoritative values are validated even when every mirror is absent: a malformed authoritative representation is FAIL, not PASS.

Canonical equality (do not invent per-implementation “semantic” equality; do not coerce types):

KindRule
integerJSON number only (typeof number); Number.isSafeInteger; range 0…2^53-1. Strings such as "120" are invalid, not integers.
hex digestJSON string only; optional 0x prefix; lowercase [0-9a-f]; SHA-256 fields MUST be exactly 64 hex characters after prefix removal. Invalid encodings are not equal to each other.
stringJSON string only; exact equality (currency is the ISO-style code as emitted). Numbers are not strings.
structured objectJCS → SHA-256 → compare digests

Authoritative-field registry:

Semantic factAuthoritative representationMirrors (if present)
Chargefingerprint.expected_charge_microsbilling.expected_charge_micros, public commitments
Usage unitsfingerprint.usage_unitsmeter_event.usage_units, public commitments
Event idfingerprint.event_idmeter / envelope / public commitments
Tenantfingerprint.tenant_idmeter / public commitments
Contract versionfingerprint.contract_versionmeter
Billing windowfingerprint.billing_window_idmeter / public commitments
Currencyfingerprint.currencybilling / tariff / public commitments
Unit pricefingerprint.unit_price_microstariff snapshot
Tariff id/version/digestfingerprint fieldstariff snapshot / billing / public commitments
Meter event digestfingerprint.meter_event_digestmeter envelope / public commitments
Authority identitysigned grant authority_id and fingerprint.authority_idenvelope grant
Execution intentfingerprint.execution_intent_digestenvelope / billing copies
Verification keyattestation.billing_proof.vkey_hashbilling.incircuit_binding.vkey_hash

The fingerprint is not automatically authoritative for every fact. Authority identity is recomputed from the signed grant; the fingerprint commits which grant was used. Both MUST agree when the grant is present under Standard. Issuers MUST omit unconstrained convenience keys rather than emit null or "".

Language-neutral registry: protocol/conformance/qzr-1/authoritative-field-registry.json (version 1, SHA-256 1a2e01b8e2a89bf530da4ad87fc185b29f5915882a6fefa9e5dde41c4a762676). Cross-language attack vectors: protocol/conformance/qzr-1/committed-value-vectors.json (SHA-256 138b56b72f2874c869cd44b0ba46c70c6be99b09a48bb47c2f85a954b8973dbb). Artifact digests are SHA-256 over the exact raw UTF-8 file bytes (not JCS re-serialization). Independent implementations MUST agree on those vectors. Changing either file is a spec change, not a casual implementation update. §4.4 is not Standard-only: a conflicting mirror fails Minimal as well as Standard.

Document-level allowed_equality_types and allowed_entry_keys describe the registry schema; they do not extend it. A conforming implementation MUST validate entries against the QZR-1 version's normative constants (integer, hex, string and the entry key set). For registry v1, declared allowed_* arrays MUST exactly match those constants or the registry document is malformed.

Registry schema invariants (enforced at load time by all implementations):

InvariantRule
factunique across all entries
authoritativeexactly one per fact; unique across all entries
mirror pathsunique within the fact; authoritative ≠ mirror
equalityrecognized enum only (integer, hex, string)
unknown entry keysreject
versionexplicit integer ≥ 1
document allowed_*MUST match normative constants for that version; MUST NOT be used as the authority for what is allowed

5. Canonicalization and hashing (normative)

authority: PASS does not claim: permission to execute a new paid action, consumption uniqueness (that requires authority_consumption_check = PASS), budget reservation / concurrency-safe ledgering, path enforcement, QuantZK online at request time, source-clock correctness, current non-revocation without a snapshot, delegation_chain validity, that issuer_role confers trust, in-circuit intent binding, or correctness of an external policy engine beyond a declared policy_digest. See Charge authority.

Issuer: issuer, issuer_role, issuer_kid, signature. QuantZK verifies grants from authorized spend-authority keys; it need not be the issuer.


5. Canonicalization and hashing (normative)

All algorithms below are byte-exact. Implementations MUST NOT consult proprietary QuantZK packages to invent different rules.

5.1 QZR Canonical JSON

Input: a JSON value (after UTF-8 JSON parse).

Output: a Unicode string canonical, then encoded as UTF-8 bytes for hashing.

Rules (inspired by RFC 8785 / JCS, specialized here):

  1. nullnull
  2. true / falsetrue / false
  3. Numbers: MUST be finite. Encode with JSON.stringify semantics for IEEE-754 finite numbers. Negative zero MUST encode as 0. Non-finite numbers MUST be rejected. BigInt MUST be rejected on the wire (use §3.1 integers).
  4. Strings: Encode with JSON.stringify (UTF-16 code units as in ECMA-404 / JSON; escapes for controls). Unicode is preserved as in standard JSON string encoding.
  5. Arrays: [ + elements joined by , + ]. undefined / function / symbol array holes become null.
  6. Objects: Enumerate own enumerable property names, sort by UTF-16 code unit order (String < comparison), omit keys whose values canonicalize to undefined (i.e. undefined / function / symbol values are omitted, not emitted as null). Emit { + "key":value pairs joined by , + }. Key names are JSON.stringify’d.
  7. Top-level undefined is rejected.

Pseudocode:

serialize(v):
  if v is null → "null"
  if v is boolean → "true" | "false"
  if v is number → reject if not finite; if -0 → "0"; else JSONNumber(v)
  if v is string → JSONString(v)
  if v is array → "[" + map(serialize-or-null) + "]"
  if v is object →
       keys = sort(Object.keys(v))
       fields = []
       for k in keys:
         c = serialize(v[k])   # may be undefined → omit
         if c defined: fields.append(JSONString(k) + ":" + c)
       return "{" + join(fields, ",") + "}"

5.2 SHA-256 hex encoding

sha256_hex(bytes) := lowercase hexadecimal encoding of SHA-256(bytes), length 64
wire_hash := "0x" || sha256_hex(bytes)

5.3 Fingerprint hash

Let F = billing.billing_verify_fingerprint.

canonical_bytes = UTF-8( QZR_CanonicalJSON(F) )
billing_verify_fingerprint_hash = "0x" || sha256_hex(canonical_bytes)

QZR-1 does not insert an ASCII domain-separator prefix. Separation is the fixed fingerprint schema (§4.1) hashed in isolation. Introducing "QZR-1:FINGERPRINT:" || … would be a breaking change reserved for a future QZR revision.

5.4 Public commitments digest

Let C = billing.public_commitments.

public_commitments_digest = "0x" || sha256_hex( UTF-8( QZR_CanonicalJSON(C) ) )

5.5 Verification-key hash

For any verification key object V (Groth16 vkey JSON):

verification_key_hash = "0x" || sha256_hex( UTF-8( QZR_CanonicalJSON(V) ) )

This is the hash used in allow-lists (not the raw file bytes of a .vkey.json unless those bytes equal the canonical form).

5.6 Phase-2 field images and commitment digest

binding_version MUST be bn128-poseidon8-v1.

This digest is circomlib Poseidon over the BN128 / BN254 scalar field (alt_bn128), the same family used by Circom Groth16 for apiBillingV2. It is not BLS12-381 Poseidon.

Normative primitive: Poseidon8_circomlib_bn128

ParameterNormative value
Curve / fieldBN128 (a.k.a. BN254 / alt_bn128) scalar field
Prime p21888242871839275222246405745257275088548364400416034343698204186575808495617
HashPoseidon permutation as implemented by circomlib Poseidon.circom / circomlibjs buildPoseidon() default constants
Arity8 field elements (width t = 9 = 8 inputs + capacity)
Parameter setDefault circomlib / circomlibjs Poseidon constants for that width (do not substitute a BLS12-381 or custom S-box table)
OutputSingle field element in [0, p), wire form = decimal string (snarkjs public-signal convention)

Pseudocode (names are normative identifiers):

commitment_digest = Poseidon8_circomlib_bn128(fields)
// == circomlibjs: (await buildPoseidon())(fields) → F.toObject → decimal string

Let p be the bn128 scalar field prime above.

toFieldElement(value):

ValueMapping
null / missing0
finite numbertrunc(value) mod p (normalized into [0, p))
string matching 0x + hexinteger from hex mod p
string matching optional - + digitsdecimal BigInt mod p
other stringSHA-256(UTF-8(string)) interpreted as big-endian integer mod p
object / arraySHA-256(UTF-8(QZR_CanonicalJSON(value))) mod p

Ordered field-images (order is normative; do not reorder without a new binding_version):

fields[0] = toFieldElement(C.event_id)
fields[1] = toFieldElement(C.tenant_id)
fields[2] = toFieldElement(C.api_key_id ?? C.meter_signing_kid)
fields[3] = toFieldElement(C.endpoint ?? C.evaluator_digest)
fields[4] = toFieldElement(C.billing_window_id)
fields[5] = toFieldElement(C.tariff_id)
fields[6] = toFieldElement(C.usage_units)
fields[7] = toFieldElement(C.expected_charge_micros)
commitment_digest = Poseidon8_circomlib_bn128(fields)

Wire form of commitment_digest / Groth16 public signal: decimal string of the field element.

Known-answer test (Normative KAT)

Independent implementers MUST reproduce this digest before claiming §5.6 conformance.

fields = [1, 2, 3, 4, 5, 6, 7, 8]   // already in F_p
Poseidon8_circomlib_bn128(fields) =
  "18604317144381847857886385684060986177838410221561136253933256952257712543953"

Canonical copy: protocol/conformance/qzr-1/poseidon8-kat.json.

The Phase-2 proof relation asserts knowledge of the eight private field-images such that Poseidon8_circomlib_bn128(fields) equals the single public signal. Verifiers MUST:

  1. groth16.verify(authorized_vkey, [public_signal], proof) = true
  2. public_signal === Poseidon8_circomlib_bn128(deriveFieldImages(expected public_commitments))

6. Verification algorithm (normative)

6.1 Check status enum

Every atomic check reports exactly one of:

StatusMeaning
PASSChecked and satisfied
FAILChecked and not satisfied
NOT_CHECKEDApplicable, but verifier lacked required external input (e.g. no revocation snapshot)
NOT_APPLICABLENot required at the evaluated level / absent optional artifact

Rules for NOT_CHECKED:

  • Permitted for Minimal/Standard on revocation and transparency when no snapshot / log head is supplied.
  • Forbidden as a substitute for missing Phase-2 artifacts under Standard (missing ⇒ FAIL).
  • Permitted for charge authority when the envelope has no charge_authority. A present but invalid grant is FAIL. A present grant without fingerprint.authority_id is authority_continuity = NOT_CHECKED and MUST FAIL Standard (anti-downgrade); it MUST NOT be reported as authority: PASS.
  • Permitted for execution_intent_binding when there is no grant. A present grant without fingerprint.execution_intent_digest is NOT_CHECKED and MUST FAIL Standard. A present but mismatched digest is FAIL.
  • Permitted for authority_consumption / authority_consumption_check and authority_revocation when no consumption log / authority revocation snapshot is supplied.
  • Strict MUST NOT return overall PASS while revocation is NOT_CHECKED.

6.2 Authorization predicates (trust ≠ math)

Mathematical proof validity alone is insufficient.

proof_valid              := Groth16 verifies under the key embedded in the attestation
circuit_authorized       := attestation / billing_proof circuit_id (+ version) ∈ profile allow-list
verification_key_authorized := verification_key_hash(vkey) ∈ profile allow-list
issuer_authorized        := attestation.signature.kid (or public key) ∈ profile allow-list
                           OR profile explicitly accepts the embedded key under an pinned issuer registry
profile_satisfied        := all checks required by profileId succeed

A malicious party can generate its own circuit, vkey, and valid proof. Without circuit_authorizedverification_key_authorizedissuer_authorized, a receipt MUST NOT be treated as authorized QZR billing evidence for that profile, even if proof_valid = true.

Profiles MUST publish:

  • authorized_issuer_kids / issuer public keys
  • authorized_attestation_vkey_hashes (main VDI decision circuit)
  • authorized_billing_vkey_hashes (Phase-2 apiBillingV2, Standard+)
  • authorized_circuit_ids / authorized_binding_versions
  • optional authorized_policy_manifest_hashes
  • revocation freshness policy (max_snapshot_age_seconds)

6.3 Envelope validity

envelope_valid :=
    JSON parse succeeds
    AND qzr == "QZR-1"
    AND schema == "quantzk_billing_receipt_v1"
    AND billing_version == "v2"
    AND attestation is present
    AND billing.billing_verify_fingerprint is present
    AND integer fields satisfy §3.1

On failure → levels FAIL; report QZR_VERSION_UNSUPPORTED or QZR_MALFORMED as appropriate.

6.4 Level predicates

attestation_valid :=
    proof_valid
    AND signature_valid
    AND key_integrity_valid
    AND schema/pipeline/policy checks required by profileId
    AND issuer_authorized
    AND verification_key_authorized   // attestation circuit vkey
    AND circuit_authorized            // attestation circuit identity when profile lists it
fingerprint_present := billing.billing_verify_fingerprint is an object with §4.1 required keys
fingerprint_hash_valid :=
    billing.billing_verify_fingerprint_hash == FingerprintHash(§5.3)
QZR1_MINIMAL_PASS :=
    envelope_valid
    AND attestation_valid
    AND declared_profile_satisfied      // profileId checks that Minimal requires
    AND fingerprint_present
    AND (fingerprint_hash_valid OR fingerprint_hash is absent)
    AND committed_consistency ≠ FAIL    // §4.4 applies at every level; not Standard-only
    AND authority_continuity ≠ FAIL     // present identity mismatch is not a Minimal bypass
    AND execution_intent_binding ≠ FAIL // present intent mismatch is not a Minimal bypass

When fingerprint hash is absent under Minimal → fingerprint_hash = NOT_CHECKED (permitted). When present and wrong → FAIL and Minimal FAIL.

receipt_valid := verification_receipt_v1 verifies against attestation (incl. expiry + binding)

public_commitments_present := billing.public_commitments is a non-empty object
public_commitments_digest_valid :=
    billing.public_commitments_digest == CommitmentsDigest(§5.4)

billing_proof_present := attestation.billing_proof is present with binding_version bn128-poseidon8-v1
incircuit_binding_valid :=
    verifyInCircuitBillingProof(attestation.billing_proof,
                                expectedPublicCommitments = billing.public_commitments,
                                allowedVkeyHashes = profile.authorized_billing_vkey_hashes)
    AND billing_proof.circuit_id authorized
    AND billing_proof.vkey_hash authorized

charge_authority_valid :=
    if charge_authority absent: NOT_CHECKED
    else receipt-context bind(grant, meter_event, tariff_snapshot)
         (canonical_authority_payload + integer unix-second window)
         → PASS / FAIL
    // QZR-1 is receipt-time; may_execute is always false here

execution_intent_binding :=
    if no grant: NOT_CHECKED
    else if execution_intent_digest (and optional execution_intent) absent: NOT_CHECKED
    else if SHA-256(JCS(execution_intent)) matches digest
         AND meter_event intent-field projection matches digest: PASS
    else: FAIL

authority_consumption :=
    if no grant or binding failed or no consumption log: NOT_CHECKED
    else if log has no record for authority_id: AVAILABLE
    else if log maps authority_id to this event_id
         AND (when execution_intent_digest is expected: stored digest matches): CONSUMED_BY_THIS_EVENT
    else: CONSUMED_BY_OTHER_EVENT
    // Bare event_id strings are NOT CONSUMED_BY_THIS_EVENT when an intent digest is expected.
    // v1 consumption logs are trusted-channel inputs, not portable self-authenticating proofs.

authority_consumption_check :=   // receipt-derived; do not collapse AVAILABLE with CONSUMED_BY_THIS_EVENT
    if authority_consumption = NOT_CHECKED: NOT_CHECKED
    else if authority_consumption = CONSUMED_BY_THIS_EVENT: PASS
    else: FAIL                   // AVAILABLE or CONSUMED_BY_OTHER_EVENT

QZR1_STANDARD_PASS :=
    QZR1_MINIMAL_PASS
    AND receipt_valid
    AND fingerprint_hash_valid          // hash MUST be present
    AND public_commitments_present
    AND public_commitments_digest_valid
    AND billing_proof_present           // missing ⇒ FAIL (not NOT_CHECKED)
    AND circuit_identity_authorized     // apiBillingV2
    AND verification_key_authorized     // billing vkey allow-list
    AND incircuit_binding_valid
    AND committed_consistency ≠ FAIL
    AND if charge_authority absent: charge_authority_valid = NOT_CHECKED
        else charge_authority_valid = PASS
             AND authority_continuity = PASS
             AND execution_intent_binding = PASS
    AND authority_consumption_check ∈ {PASS, NOT_CHECKED}  // log-backed replay / unconsumed-on-receipt FAIL
meter_trust_valid :=
    if meter_envelope absent:
        NOT_APPLICABLE if profile.allow_missing_meter else FAIL
    else:
        Ed25519 envelope verifies under trusted kid → PASS/FAIL

revocation_status :=
    if no snapshot supplied: NOT_CHECKED
    else if attestation_id or issuer kid revoked: FAIL
    else: PASS   // reported as CLEAR in summaries

revocation_snapshot_fresh :=
    if no snapshot: NOT_CHECKED
    else if now - snapshotTime > profile.max_snapshot_age_seconds: FAIL
    else if attestation.issued_at > snapshotTime: FAIL   // snapshot predates issuance
    else: PASS

transparency_valid := per profile (NOT_APPLICABLE if not required and absent)

QZR1_STRICT_PASS :=
    QZR1_STANDARD_PASS
    AND meter_trust_valid ∈ {PASS, NOT_APPLICABLE}
    AND revocation_status == PASS
    AND revocation_snapshot_fresh == PASS
    AND transparency_valid ∈ {PASS, NOT_APPLICABLE}

6.5 Human summary label

Implementations MAY print QUANTZK VERIFIED when the requested level (default: Standard if Phase-2 present, else Minimal) evaluates to PASS. They MUST still emit the status enum for revocation / transparency so NOT_CHECKED is visible.

Offline Standard PASS with revocation = NOT_CHECKED means: cryptographically bound billing evidence; not “currently non-revoked.”

6.6 Reference implementations

  • JS library: @quantzk/sdkverify()
  • CLI: npx @quantzk/verify receipt.qzk
  • Conformance: protocol/conformance/qzr-1/run-js.mjs
  • Committed-value registry + vectors: protocol/conformance/qzr-1/authoritative-field-registry.json, committed-value-vectors.json (JS + Python)
  • Browser: https://quantzk.com/protocol/verify.html

7. Logical uniqueness (portable protocol)

For a given logical billable event, the uniqueness key is:

(tenant_id, billing_window_id, event_id)

as carried in the fingerprint / meter event.

Issuers MUST ensure that committed charges under the same uniqueness key are idempotent: a duplicate record MUST NOT create a second independent committed charge.

QZR-1 does not require a particular server job identifier. Returning the same job_id on duplicate accepts is a QuantZK API concern, not a QZR-1 wire requirement. Portable verifiers compare uniqueness keys and receipt / attestation identities, not job queues.


8. Versioning

SpecNotes
QZR-1This document
QZR-2Reserved for aggregates, multi-line invoices, cross-currency, and safe large integers

Breaking changes require a new qzr / schema pair. Additive optional fields are allowed within QZR-1 only when they do not weaken §2 level predicates.


9. Security considerations

  • Treat receipts as public evidence, not secrets.
  • proof_valid without authorization predicates is not QZR authorization.
  • Offline Standard PASS ≠ current governance clearance.
  • Do not put attest API secrets inside .qzk files.
  • Independent implementations MUST treat this document + golden vectors as the contract.

10. Example (abbreviated Standard)

json
{
  "schema": "quantzk_billing_receipt_v1",
  "qzr": "QZR-1",
  "billing_version": "v2",
  "profileId": "VDI_VERIFY_STANDARD_V1",
  "attestation": {
    "type": "decision_attestation_v1",
    "attestation_id": "vdi:att:0x…",
    "billing_proof": {
      "schema": "api-billing-v2-incircuit-proof-v1",
      "binding_version": "bn128-poseidon8-v1",
      "circuit_id": "apiBillingV2",
      "vkey_hash": "0xa486fb…",
      "public_signals": ["…"],
      "proof": { "system": "groth16", "curve": "bn128" }
    }
  },
  "receipt": { "type": "verification_receipt_v1", "receipt_id": "vdi:receipt:0x…" },
  "billing": {
    "expected_charge_micros": 221040,
    "currency": "USD",
    "billing_verify_fingerprint": { "usage_units": 1842, "event_id": "evt_123" },
    "billing_verify_fingerprint_hash": "0x…",
    "public_commitments": { "event_id": "evt_123", "usage_units": 1842 },
    "public_commitments_digest": "0x…"
  }
}

11. Conformance vectors

Canonical fixtures: protocol/conformance/qzr-1/.

FixtureExpected (summary)
valid-minimal.qzkMinimal PASS; Standard FAIL (phase2 missing → FAIL)
valid-standard.qzkMinimal PASS; Standard PASS; revocation NOT_CHECKED offline
valid-strict.qzkMinimal/Standard/Strict PASS with fresh CLEAR snapshot
invalid-standard-missing-binding.qzkMinimal PASS; Standard FAIL
invalid-standard-bad-binding.qzkStandard FAIL
invalid-standard-unknown-vkey.qzkStandard FAIL (verification_key_authorized)
valid-standard-revocation-not-checked.qzkStandard PASS; revocation NOT_CHECKED
invalid-strict-stale-revocation.qzkStandard PASS; Strict FAIL
invalid-tampered-*.qzkSettlement / proof / signature / vkey failures
invalid-revoked-attestation.qzkStandard-class receipt whose attestation_id is revoked in revocation-snapshot.json. Offline: Minimal+Standard PASS, Strict FAIL, revocation=NOT_CHECKED. With snapshot: Minimal+Standard PASS, Strict FAIL, revocation=FAIL, current_status=REVOKED.
invalid-version.qzk / invalid-malformed.qzkenvelope FAIL
expected-results.jsonRich oracle (§11.1)
trust-roots.jsonProfile allow-lists for authorization checks

11.1 Oracle shape

json
{
  "fixture": "invalid-revoked-attestation.qzk",
  "offline": {
    "minimal": "PASS",
    "standard": "PASS",
    "strict": "FAIL",
    "historical_crypto_valid": true,
    "phase2_binding": "PASS",
    "revocation": "NOT_CHECKED",
    "current_status": "NOT_CHECKED"
  },
  "with_revocation_snapshot": {
    "minimal": "PASS",
    "standard": "PASS",
    "strict": "FAIL",
    "historical_crypto_valid": true,
    "phase2_binding": "PASS",
    "revocation": "FAIL",
    "current_status": "REVOKED"
  }
}

Standard does not consume the revocation oracle. A revoked Standard receipt still reports standard: PASS when Phase-2 binding holds; only Strict (or an explicit revocation status field) fails. Implementations MUST NOT collapse revocation: FAIL and proof_valid: false into a single undifferentiated valid=false without reporting the separate statuses.

Run:

bash
npm run test:qzr1
npm run test:qzr1:python
npm run test:committed-values

12. Blind validation test

Give valid-standard.qzk, trust-roots.json, and this specification to an engineer who has never seen QuantZK. Do not explain further. Ask:

Can you independently determine whether this receipt meets QZR-1 Standard?

Success means they implement §§5–6 from the text, evaluate the predicates, and match expected-results.json, without opening @quantzk/vdi-billing or any other QuantZK source.

When a blind implementation agrees with the JS and Python runners across the golden vectors, QZR-1 may be considered for freeze as a protocol artifact rather than a vendor serialization format.

Verification keys are embedded in attestations. Verify offline. No QuantZK servers required.