Skip to content

7. Formal security package — Halborn asks

Audience: Halborn (or equivalent formal security reviewer)
Scope: api-billing-v2 (not full VDI / identity / captcha)
Baseline: main @ 8ec535c (update on each packet refresh)
Companion: Attack matrix · Formal audit runner · Trust surface scope

QuantZK includes a formal security package designed to support an independent review. It documents the threat model, trust assumptions, adversarial test coverage, parser behavior, circuit inventory, canonicalization approach, and known limitations.

This is not a third-party audit report, and we do not claim that “QuantZK has been security audited.” It is QuantZK’s evidence package: what to run, what we claim, what we do not claim, and where to look in code.


Index of the eight asks

#AskSection
1Coverage report§1
2Threat model§2-threat-model
3Assumptions§3-assumptions
4Unsupported cases§4-unsupported-cases--out-of-scope
5Circuit review§5-circuit-review
6Parser review§6-parser-review
7Canonicalization§7-canonicalization
8Trust boundaries§8-trust-boundaries

1. Coverage report

Claim this section supports

The primary adversarial scenarios defined in our threat model are covered by executable tests.

That is the meaningful coverage statement for a security reviewer. Behavioral / scenario coverage matters more than raw line-coverage percentages.

1.1 Behavioral coverage (primary)

Each primary threat in §2 maps to a catalog ID (BV2-* / ADV-*) and an executable test. Fail-closed outcomes are asserted, not merely “code was visited.”

GateCommandExpected
Artifact pinsbash scripts/verify-artifact-hashes.shHash match + offline conformance
Offline adversarialcd protocol && node --test test/adversarial-billing-v2.test.jsAll pass
Pilot (functional)cd verifier-api && npm run test:billing-pilot15/15
Adversarial (HTTP)cd verifier-api && npm run test:billing-adversarial12/12
Full formal gatesbash scripts/run-formal-security-audit.shWrites audit-logs/formal-security-audit-*.json

Catalogs:

  • protocol/conformance/billing-v2-conformance.json — BV2-* (happy, replay, tamper, meter, transparency, Phase-2)
  • protocol/conformance/billing-v2-adversarial.json — ADV-* (proof graft, sig, revocation, forge log, overflow, oversize, canon)

Human matrix: billing-v2-attack-matrix.md

Threat → test mapping is in §2.3.

1.2 Line / statement coverage (optional plumbing aid)

Line percentages alone are not a security claim. If a reviewer wants Istanbul/lcov for the billing trust-surface files only, regenerate:

bash
bash scripts/halborn-coverage-report.sh
# → audit-logs/halborn-coverage-<timestamp>/

The script:

  • Runs pilot and adversarial suites separately (--runInBand)
  • Collects coverage only from vdi.js, vdiBillingRuntime.js, artifactValidator.js, wellKnown.js
  • Disables the repo-wide Jest 85% threshold (that gate is for full-suite CI, not this snapshot)
SuiteToolRole
Billing Jest suitesIstanbul / Jest --coverageOptional attach; secondary to ADV/BV2 vectors
Root Vitest@vitest/coverage-v8Frontend; out of billing trust surface

Do not market a fixed “95% line coverage” (or similar) as assurance. Prefer the behavioral claim above. If halborn:coverage fails, re-check gates with npm run test:billing-pilot / test:billing-adversarial (no coverage) — those are the release bar.

1.3 Circuit constraint inventory

Phase-2 relation inventory is in §5 (public/private signals, Poseidon8 binding). Broader enforced-policy rule→constraint tables live in audit-circuit-coverage.md and are Track B / non-billing.


2. Threat model

2.1 Adversary

  • Class: Probabilistic polynomial-time (PPT) attacker with API visibility and ability to craft HTTP bodies.
  • Can: Reorder JSON; swap proof fields; forge Merkle inclusion proofs; race concurrent attests; supply stale/revoked IDs; send oversized/malformed payloads; attempt meter envelope forgery.
  • Cannot (assumed): Break Ed25519 EUF-CMA, Groth16 soundness under the trusted setup, or find SHA-256 / Poseidon collisions except with negligible probability.

2.2 Assets

AssetWhy it matters
Billing attestation + fingerprintDispute-grade charge/commitment evidence
Replay uniqueness (tenant, window, event_id)Prevents double-spend of usage
Transparency log tip + inclusionNon-equivocation for auditors
Phase-2 billing_proofCryptographic binding of commitment digest when enabled
Artifact pins (WASM/zkey/vkey)Prevent silent circuit substitution

2.3 Threat × evidence

Threat classRepresentative vectorsExpected fail-closed signal
Forged / grafted ZK proofADV-PROOF-01verification.valid: false
Malformed public signalsADV-PROOF-02/03Binding and/or ZK fails
Signature tamperADV-SIG-01, ADV-METER-01Verify/attest reject
Replay / raceBV2-REPLAY-01/02/03HTTP 400 or single-winner race
Fingerprint / commitment swapBV2-TAMPER-01, BV2-INCIRCUIT-02Billing / in-circuit check false
Transparency forgeryADV-LOG-01/02log_proof_verification.valid: false
Revocation abuseADV-REVOC-01/02Strict revocation_status fails
Overflow / DoS payloadADV-CHARGE-01, ADV-PAYLOAD-01HTTP ≥ 400
Artifact substitutionBV2-ART-01Boot validator reject

Full narrative VDI threat model: security-model.md. Billing operationalization: formal-security-audit.md.


3. Assumptions

3.1 Cryptographic

AssumptionUse in product
Ed25519 EUF-CMAAttestation, meter envelope, transparency operator signatures
Groth16 knowledge-soundness (bn128)Attestation ZK + Phase-2 apiBillingV2
SHA-256 collision resistanceDigests, field-images, fingerprints
Poseidon (circomlib) collision / PRF-like bindingPhase-2 commitment digest
Correct key custodyCompromise of VDI_SIGNING_KEY or meter key enables issuance forgery — out of protocol soundness

3.2 Encoding / governance

AssumptionImplication
Field-images are computed off-circuit (SHA-256 → mod p)Circuit proves Poseidon(field-images); not UTF-8 preimage knowledge
Manifest / tariff authoring is honest to intentWrong tariff still proves; it does not prove legal or commercial correctness
Verification profile inputs supplied when requiredStrict profile needs revocation + authority binding data

3.3 Operational (disclosed)

AssumptionStatus
Phase-2 ceremony contributors honestPilot-grade: 3 contributors, single-host ceremony — not adversarial multi-host MPC
Artifact mirrors identicalBoot pin checks ARTIFACT_MANIFEST.json
Meter trust anchors configuredUntrusted kid rejected (BV2-METER-02)
PostgreSQL available for replay + transparencyProduction requirement for v2

4. Unsupported cases / out of scope

4.1 Explicit out of scope for this Halborn engagement

AreaWhy
Landing / marketing UINot part of billing trust surface
Legacy api-billing-v1Deprecated; pilot is v2 only
Identity / captcha circuits (proof_of_identity, adaptive ML)Separate product
Redis / rate-limit hardeningCI adversarial runs with Redis disabled
Stripe / PSP captureWe prove charge relation, not payment settlement
Formal SOC2 / prior third-party audit claimsThis package scopes the review; it is not the audit letter
Independent-host adversarial MPCDocumented limitation; path exists but not completed
causalProof ceremony for identity pipelinesBilling Phase-2 uses apiBillingV2 only
Legal interpretation of tariffs / fair-lending manifestsProofs encode relations, not statutes

4.2 What we do not claim

ClaimReality
“Mathematical certainty of legal compliance”Only that encoded checks passed under stated assumptions
“Impossible to bill incorrectly”Bad meter input or wrong authored tariff is outside the relation
“MPC eliminates all setup risk”Current ceremony is pilot-grade / single-machine
“QuantZK has been security audited”This package supports independent review; it is not a completed third-party audit letter
“95% line coverage proves security”Meaningful claim is behavioral: primary threat-model scenarios have executable tests
“Full RFC 8785 JCS conformance suite”Implementation is JCS-aligned + property-tested; not a formal JCS certificate

See also: Trust surface scope.


5. Circuit review

5.1 Inventory (in-scope circuit)

ItemValue
Circuit IDapiBillingV2
Sourcezk-cp/circuits/apiBillingV2.circom
TemplateApiBillingV2
Binding versionbn128-poseidon8-v1
Proof systemGroth16 / bn128
Constraints402 non-linear (manifest)
Public inputs1commitment_digest
Private inputs8 field elements
Artifactsverifier-api/circuits/apiBillingV2/ (+ mirrors)
Prover/verifyprotocol/packages/vdi-billing/commitmentBindingV2.js
PinsARTIFACT_MANIFEST.json + bash scripts/verify-artifact-hashes.sh

5.2 Relation (what the circuit actually proves)

[ \texttt{commitment_digest} = \mathrm{Poseidon}_8(w_0,\ldots,w_7) ]

with commitment_digest public and (w_i) private. Witness field-images are built off-chain by deriveFieldImages(publicCommitments):

Indexpublic_commitments fieldCircuit signal name
0event_idevent_id
1tenant_idtenant_id
2api_key_id (fallback meter_signing_kid)api_key_id
3endpoint (fallback evaluator_digest)endpoint
4billing_window_idbilling_window_id
5tariff_idtariff_id
6usage_unitsusage_units
7expected_charge_microsexpected_charge_micros

Intentional non-goal: The circuit does not prove knowledge of UTF-8 preimages. Preimage integrity for dispute fields is carried by the Ed25519-wrapped attestation and SHA-256 fingerprints / Phase-1 field split. Phase-2 prevents substituting a commitment digest without knowing field-images that Poseidon to that digest.

5.3 Reviewer checklist

  1. Confirm Poseidon input order matches deriveFieldImages (order is binding-versioned).
  2. Confirm Groth16 verify + semantic public_signals[0] === Poseidon8(expected) in verifyInCircuitBillingProof.
  3. Confirm issuer cannot attach a valid Phase-2 proof for commitments that disagree with the fingerprint (BV2-INCIRCUIT-02).
  4. Confirm silent artifact swap fails boot validation (BV2-ART-01).
  5. Confirm ceremony honesty caveat before adversarial trust (trusted setup).

5.4 Out-of-scope circuits for this packet

fairLending, hipaaAccess, euAiAct, soc2Access, causalProof, proof_of_identity — see audit-circuit-coverage.md if Track B is opened.


6. Parser review

6.1 Surfaces that parse untrusted input

SurfaceParser / normalizerFail-closed behavior
HTTP JSON bodyExpress json (~10mb limit)413 oversize (ADV-PAYLOAD-01)
Meter + tariffnormalizeV2MeterEvent / normalizeV2TariffSnapshot / toIntegerMissing/non-integer → 400
Charge mathcomputeChargeMicrosDeterministicUnsafe int / mul overflow throw
Meter envelopeverifyMeterEventEnvelopeDigest/sig length/kid fail → 400
Attestation / proof@quantzk/vdi-verifier + snarkjsInvalid proof/sig → verification.valid: false
Commitment limbsdigestToPublicFieldElements + binding verifyWrong length / swapped limbs fail
Transparency proofMerkle inclusion + entry hash vs receiptADV-LOG-01/02
Revocation snapshotInline or env feed into strict profileADV-REVOC-01/02

6.2 Accepted vs rejected (summary)

Input classAcceptReject
Integers in charge pathSafe integers in rangeNon-integer, overflow product
Meter signature64-byte Ed25519 hexWrong length, bad kid, digest≠canon(event)
Proof public_signals (Phase-1)Length 2 matching field splitTruncation / limb swap
Phase-2 billing_proofMatching Poseidon digestCommitment substitution
JSON key orderAny order (canonicalized)N/A — reorder must not change digest
NaN / Infinity / BigInt in canonThrow (ADV-CANON-02)

6.3 Known residual risks (disclosed)

  • Env revocation feed clamps snapshotTime up to now in normalizeSnapshot — stale-cache semantics for auditors should use inline revocation on verify (exercised by ADV-REVOC-02).
  • Protocol tests historically had a simplified canonicalize helper in protocol/test/helpers.js; production SoT is protocol/lib/canonicalize.js — do not treat the helper as normative.
  • Billing path is JavaScript-centric; cross-language verify packs exist for generic VDI, not a full billing-bundle multi-language suite.

7. Canonicalization

7.1 Source of truth

protocol/lib/canonicalize.js — shared by prover, verifier, meter signer, commitments, transparency receipt hashing.

Normative framing: VDI-SPEC § Canonical Payload (RFC 8785 / JCS-aligned).

7.2 Invariants (property-tested)

IDInvariantTest
ADV-CANON-01Object key order does not affect canonical bytesOffline adversarial
ADV-CANON-02Non-finite numbers rejectedOffline
ADV-CANON-03-0 normalizes to 0Offline
Meter resignReordered meter event → same digestOffline
Production pinCanonical vkey hash = smoke billing_proof.vkey_hashArtifact / smoke

7.3 Where canonicalization binds trust

UseWhat is hashed / signed
Attestation Ed25519Canonical payload with signature.value null
Meter envelopeCanonical event → digest + signature
Public commitments digestCanonical commitments object
Transparency receiptCanonical receipt hash for Merkle entry
Verification key pinCanonical JSON of vkey → vkey_hash

7.4 Honesty bar

This is an engineering property suite, not a mathematical “proof” of full JCS equivalence across all Unicode edge cases. Auditors should treat ADV-CANON-* + call-site usage as the acceptance criteria for this engagement unless a deeper JCS conformance suite is contracted.

Reproduce:

bash
cd protocol && node --test test/adversarial-billing-v2.test.js

8. Trust boundaries

8.1 Who must trust what

(Same boundary model as Architecture Diagram 6.)

8.2 In-circuit vs off-circuit (critical)

FactBound how?Notes
Poseidon8(field-images)In-circuit (Phase-2, opt-in)apiBillingV2
SHA-256 field-image preimagesOff-circuit + Ed25519 wrapCircuit does not see UTF-8
Charge arithmeticDeterministic evaluator + fingerprintNot a circuit witness today
Replay uniquenessPostgreSQL unique constraintOperational integrity
RevocationProfile + snapshot inputVerifier fails if present+revoked

Full table: vdi-cryptographic-binding-model.md.

8.3 Party map

PartyTrust boundary
CustomerMust be able to verify without QuantZK uptime using saved bundle
Meter operatorSigns usage; must be in trust anchors
QuantZK issuerSigns attestation; key compromise = forgery
Transparency operatorSigns log entries / checkpoints
Ceremony contributorsPilot setup honesty; rotate before adversarial threat model
Halborn / auditorVerifies gates offline; no need to trust marketing

Reproduce (one command)

bash
# Formal gates (artifacts + conformance + pilot + adversarial)
bash scripts/run-formal-security-audit.sh

# Optional coverage snapshot for attachment
bash scripts/halborn-coverage-report.sh

# Optional scale methodology sample (local API must be up)
npm run audit:scale -- --total 100

Suggested Halborn findings format

SeverityExamples
CriticalProof forgery path; replay bypass; key/material leak
HighBinding mismatch accepted; artifact pin bypass
MediumStale revocation defaults; DoS wedges
Low / InfoDocs drift; ceremony maturity; coverage gaps

Scope ack + numbered answers to trust surface questions remain in §4 of the base packet.

Contact: Omar@quantzk.com · security@quantzk.com

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