Skip to content
Skip to demo
back to showScene · 05
A live walkthrough · TDD-005 zero-knowledge proofs

Proving alignment,not revealing the score.

Before the orchestrator runs a risky action, it computes a similarity score against the constitution centroid. If the action is safe, that score is high. But shipping the score downstream leaks information about how the constitution was tuned — and an attacker who watches enough scores can reconstruct the centroid itself. Zero-knowledge alignment proofs let the verifier confirm a valid 14-bit commitment to the score and learn nothing else — threshold binding is enforced by a prover-side refusal-to-create rule, not the range proof itself.

Plaintext score
0.92
full reveal
Threshold flag
true
unsigned boolean
This system
14-bit · proven
Pedersen + Schnorr OR · 14-bit range

plaintext: ship the score (0.87…) — full reveal, centroid reconstructable.

flag-only: “passes threshold” — less leakage, but no cryptographic proof.

this system: Pedersen + Schnorr OR range proof — valid 14-bit commitment, mathematically, with nothing else disclosed. Threshold binding by prover refusal-to-create.

Below are five scenarios — high alignment, barely passing, exactly at the threshold, below-threshold creation refusal, and a verifier rejection after a bit-commitment tamper. Each scenario shows what the prover knows, what gets sent on the wire, and what the verifier sees.

Real proofs, built and verified here. The Rust runtime derives one generator differently, so proofs don't carry across between the two.

How faithful is this demo?

Scope: the Pedersen commitments, Schnorr OR proofs, and Fiat-Shamir challenges are real — generated at build time via @noble/curves Ristretto255 + Node's sha3-512. Every bundle actually verifies (or actually fails) within the same library. The protocol shape (per-bit Pedersen commit + Schnorr OR + homomorphic sum, 14-bit fixed-point ×10000) is protocol-faithful to tdd005/crates/tdd004_provenance/src/zk.rs.

Honest divergence: the H generator differs between implementations. Rust derives it via SHA3-512 hash-to-curve of the domain string; this build uses RFC 9380 (SHA-512) via @noble/curves. The two H points don't share bytes, but each is an independent generator with no known discrete log w.r.t. G. Proofs built here verify here; proofs built in Rust verify in Rust. Cross-impl verification would require matching the hash-to-curve algorithm.

spec · TDD-005 zk.rsgenerated · 2026-05-16curve · ristretto255 · 14-bit range
scenario · high-aligned
action · read_file:src/index.ts

A safe read action with strong alignment. Score 0.92, threshold 0.75. Verifier learns the score is at-or-above 0.75. Verifier does not learn it was 0.92 specifically.

proof construction
~10ms
14 × Pedersen commit + 14 × Schnorr OR · estimate from zk.rs §perf, not a benchmark
bundle on the wire
~3168 B
value commit (32B) + 14 bit commits (32B each) + 14 Schnorr proofs (6×32B each)
what verifier learns
a valid 14-bit score
proves: prover knew a 14-bit integer committing to C_value. ≥-threshold binding is by prover-side refusal-to-create, not the range proof.

Prover side — what is known

14-bit fixed-point
similarity score
0.9200
cosine vs constitution centroid
fixed-point value
9,200
threshold 7,500 (0.75)
bit decomposition · 213 ... 20
1213
0212
0211
0210
129
128
127
126
125
124
023
022
021
020
prover also holds 14 fresh blindings r_i — one per bit, never sent

Construction — Pedersen + Schnorr OR per bit

Fiat-Shamir · SHA3-512
pending

Verifier side — runs verify()

knows: threshold, action_hash, constitution_hash, bundle
pending
beat 1 / 9
Prover

Cosine-similarity score: 0.92 — known only to the prover.
protocol details · ristretto255 · 14-bit range
revealed to verifier
  • · action_hash
  • · constitution_hash
  • · threshold
  • · value_commitment
  • · per-bit commitments
  • · per-bit Schnorr OR proofs (a0, a1, e0, s0, e1, s1)
  • · timestamp
hidden from verifier
  • · similarity_score (the actual scalar)
  • · per-bit values (b_i)
  • · per-bit blindings (r_i)
  • · total_blinding (r)
  • · which Schnorr OR branch was the real one

Rust uses SHA3-512 hash-to-curve; this build uses RFC 9380 (SHA-512). H bytes differ between implementations, protocol shape identical.

The ZK primitives on this page (Pedersen commitment C = v·G + r·H, Schnorr OR proof for bit ∈ {0, 1}, bit-decomposition range proof with homomorphic sum, alignment proof bundling) are ported from tdd005/crates/tdd004_provenance/src/zk.rs. Domain constants verbatim: tdd004_pedersen_h_v1, schnorr_or_challenge_v1. Fixed-point scale ×10000. Range bits = 14 (covers [0, 16383], suitable for a score in [0, 1]).

The Rust implementation is wired into the orchestrator via AlignmentProof::create (P102.9) and the JARVIS gateway calls it for high-risk tool gating (P89). The build pipeline lives at demo/build-data-zk-alignment-proof.mjs in Banterpacks. Cross-implementation byte-compatibility is not a goal of this demo — see “honest divergence” above.