Skip to content

About

Noir ZK circuits: cryptographic receipts proving SSCoP conformance without exposing vendor evidence

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Repository files navigation

Colofon — ZK Circuits

ZK Circuits

Zero-knowledge circuits for software supply-chain compliance, written in Noir.

License Noir Circuits IMT library


These circuits prove a software release satisfies a named compliance policy — build provenance, developer authorisation, SBOM hygiene, incident-notification SLA — without exposing the underlying SBOM, builder identities, customer list, or incident contents to the buyer. Each circuit reasons over signed evidence already produced upstream by Sigstore, GitHub Actions, OSV.dev, or the vendor’s mail provider.

For the full motivation, regulatory mapping, and per-circuit threat model, see the Colofon whitepaper and per-circuit deep-dives.

Architecture

A Colofon bundle is the composition of up to five inner proofs. Circuits 1–4 each produce an independently-verifiable proof; Circuit 5 wraps them in a single recursive proof that the buyer’s browser verifies in one shot.

                ┌──────────────────────┐
   SLSA   ─────▶│ 01 Build provenance  │──── binary digest came from approved pipeline
                └──────────┬───────────┘
                           │
                ┌──────────▼───────────┐
   gitsign  ───▶│ 02 Developer auth    │──── commit signed by authorised set member
                └──────────┬───────────┘
                           │
                ┌──────────▼───────────┐
   SBOM    ───▶│ 03 SBOM non-membership│──── no component carries unpatched CVE > threshold
   OSV     ───▶│   (headline)          │
                └──────────┬───────────┘
                           │
                ┌──────────▼───────────┐
   DKIM    ───▶│ 04 Notification SLA   │──── customer notified within window of incident
                └──────────┬───────────┘
                           │
                ┌──────────▼───────────┐
                │ 05 Policy composition │──── all four verify against buyer-committed policy
                │   (recursive wrapper) │     (one proving run, any number of buyer policies)
                └───────────────────────┘

Circuits

# Crate What it proves Public inputs
01 build_provenance Binary digest produced by an authorised build pipeline (SLSA v1.0 in-toto provenance, Fulcio-keyless-signed via GitHub Actions OIDC, Rekor-anchored). Signing identity is in the buyer’s approved-builder Merkle set. pae_digest_hash, approved_builder_root, signer_commitment, binary_digest_high/low
02 dev_auth Commit triggering the build was gitsign-signed by an authorised developer, without revealing which one. commit_hash_high/low, authorised_signer_root, signer_commitment
03 sbom_non_membership No component in the committed CycloneDX SBOM is present in the buyer’s policy-filtered CVE Indexed Merkle Tree. SBOM root is bound to Circuit 1’s SLSA subject. sbom_root, cve_tree_root, component_count
04 dkim_sla A DKIM-RSA-2048-signed notification email was sent to an approved recipient, naming a specific incident, with a mail-provider-attested timestamp and a sender-domain double-binding (From-domain ≡ DKIM d=). dkim_pubkey_hash, signed_digest_commitment, sender_domain_hash, send_timestamp_unix, recipient_identity_hash, approved_recipient_root, incident_id_hash
05 policy_composition All inner proofs verify against the buyer-committed policy. v1a wraps a single Circuit 4 proof; v1b/v1c expand to multi-inner aggregation across 1–4. Pass-through of inner public inputs (v1a); collapsed to bundle-level commitments (v1c)

Library crates

Crate Purpose
imt (colofon_imt) Indexed Merkle Tree primitives for non-membership proofs. Ported from AztecProtocol/aztec-packages and generalised for standalone use; depended on by Circuits 1–4.
imt_bench Reference-sized IMT (CVE_TREE_HEIGHT = 32) for proving-time benchmarking.

Building

Prerequisites

  • Nargo v1.0.0-beta.19 — circuits depend on beta.19-specific features. Install:
    noirup -v 1.0.0-beta.19
  • @aztec/bb.js 4.1.3 for proving and verification.

Compile

# Single circuit
cd build_provenance
nargo compile

# All workspace members
nargo compile --workspace

Test

cd imt
nargo test

# Or run the whole workspace's tests
nargo test --workspace

SRS for recursive Honk (Circuit 5)

policy_composition proves recursively under UltraHonk-with-ZK and requires the outer Barretenberg instance to initialise the Grumpkin SRS to 221 points. This is automatic in colofon-prover and any host that calls Barretenberg.initSRSChonk(2**21) before the first proof; see colofon-prover/Dockerfile for the production-image setup that pre-downloads and pins the CRS.

Dependencies

Library Version Used by Purpose
sha256 0.3.0 01, 04 SHA-256 hash computation in-circuit
poseidon 0.1.1 01, 02, 03, 04, IMT ZK-friendly Poseidon2 hash for commitments and Merkle trees
noir_rsa (zkpassport fork) 0.10.0 04 RSA-2048 PKCS#1v1.5 verification for DKIM signatures
bignum 0.9.2 04 Big-integer arithmetic for RSA limbs
base64 0.4.2 04 Base64 decoding for DKIM bh= body-hash tag
bb_proof_verification v4.0.0-devnet.2-patch.3 05 Recursive UltraHonk proof verification
colofon_imt local 01, 02, 03, 04 In-tree IMT membership and non-membership primitives

The DKIM stack uses zkpassport’s noir_rsa fork, the same RSA-2048 stack Apertrue’s C2PA circuits run in production. (We evaluated zkemail.nr v2.0.0 in the Gate-0 OSS scan but it required idents and integer-arithmetic patterns that beta.19 has tightened, so it didn’t compile against our pinned Noir version. Tracked for re-evaluation when zkemail.nr publishes a Noir-1.0-compatible release.)

Security model

  • Signed-input grounding. Every circuit takes as witness an artefact signed by a third party that is not the vendor (Sigstore-keyless GitHub Actions, gitsign commit signatures, OSV.dev CVE feed, mail-provider DKIM). Vendor self-attestation alone never satisfies a circuit.
  • Trust boundary. X.509 / Fulcio chain validation and Rekor inclusion proofs are performed off-circuit by colofon-sdk before witness construction. The circuits trust the SDK to derive builder_identity_hash / signer_identity_hash from the validated SAN URI; an SDK-level bug here would be a soundness bug at the bundle level even when the circuit itself is sound. Independent cryptographic review of the SDK’s SAN parser is part of the pre-launch audit scope.
  • Cross-circuit binding. Circuits 1–4 commit to overlapping anchors (the binary digest, the commit hash, the SBOM root, the incident ID, the customer-set root). The bundle verifier — and, in v1c, Circuit 5 itself — cross-checks these so a bundle assembled from inconsistent inner proofs is rejected.
  • Pubkey-to-identity binding. Circuits 1 and 2 each emit a signer_commitment = Poseidon2(pubkey_halves, identity_hash). Without this, a prover could mix one identity’s key with another’s Merkle opening and the proof would still verify; the binding closes that gap.
  • Sender-domain double-binding (Circuit 4). The From-header domain and the DKIM-Signature d= tag value both hash to the same public sender_domain_hash. Closes the shared-key / mail-relay attack where an adversary holding a DKIM signature for one domain substitutes a different domain in the From: header.
  • Honest caveats. Each deep-dive page documents the circuit’s limitations explicitly — the SLSA subject-digest anchor is substring-based rather than structural; the OSV trust anchor is HTTPS-pinned in v1, Sigstore-signed in v2; Circuit 4’s anchor-based header parsing leans on Merkle membership for its real soundness rather than the byte anchors alone. See the per-circuit deep-dives.
  • No independent cryptographic audit yet. One is in progress; the whitepaper is the current authoritative reference.

Acknowledgements

These circuits are built on the work of:

  • Noir by Aztec Labs — zero-knowledge circuit language and compiler
  • Barretenberg by Aztec Labs — UltraHonk proving backend and recursive verification
  • Aztec Indexed Merkle Tree by Aztec Labs — non-membership-friendly tree construction; colofon_imt is a port-and-generalise of the protocol-internal version into a standalone Noir library
  • noir_rsa by zkpassport — RSA verification used for DKIM signature checks in Circuit 4
  • noir-bignum, poseidon, sha256, noir_base64 by Noir Lang — standard cryptographic primitives
  • Sigstore (Linux Foundation / OpenSSF) — keyless signing, Rekor transparency log, gitsign, Fulcio
  • SLSA by OpenSSF — in-toto attestation framework that Circuit 1 proves over
  • CycloneDX by OWASP — SBOM specification consumed by Circuit 3
  • OSV.dev by Google — CVE feed used as the trust anchor for Circuit 3’s policy-filtered exclusion tree
  • The ZK Email project — reference work on in-circuit DKIM verification that informed Circuit 4’s design

Apertrue Ltd’s C2PA media-authenticity stack (production since 2025) provided the Noir / Barretenberg / Aztec proving infrastructure pattern, the recursive aggregation primitive, and several cryptographic primitives that Colofon reuses directly.

License

Apache 2.0 — Copyright 2026 Apertrue Ltd / Colofon. See LICENSE.

About

Noir ZK circuits: cryptographic receipts proving SSCoP conformance without exposing vendor evidence

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages