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.

Scope: the Pedersen commitments, Schnorr OR proofs, and Fiat-Shamir challenges are real — generated at build time via @noble/curvesRistretto255 + 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
G (Ristretto basepoint)e2f2ae0a6abc…45e08d2d76
H = hash-to-curve("tdd004_pedersen_h_v1")5052fd082537…74d5bb973a
per-bit Pedersen commits · C_i = b_i · G + r_i · H
2c9c0026b13
62245a11b12
60ac3e51b11
ba532f7fb10
a6c6ed39b9
d469ee3db8
f0ca9d2cb7
deecec4cb6
18980e27b5
900bfc7cb4
548ec830b3
c691687cb2
444d4071b1
9a47a80cb0
per-bit Schnorr OR proof · 6 scalars · prove b_i ∈ {0, 1} without revealing which
bit-0 proof bundle (verifier-visible only)
0404a51f…628843
563afdcb…acc33c
b8fd56ec…290200
cf48fc6a…70ad0a
57f30fa2…8fd405
d1c33326…0aa901
+ 13 more identical-shape proofs (one per bit)
value commitment · Σ(2i · C_i) — homomorphic sum binds the bits together
C_value46c79ce174de…1c8eea350d

Verifier side — runs verify()

knows: threshold, action_hash, constitution_hash, bundle
per-bit Schnorr OR check (e_0 + e_1 ≟ Fiat-Shamir(C, a_0, a_1) & branch equations)
b13
b12
b11
b10
b9
b8
b7
b6
b5
b4
b3
b2
b1
b0
homomorphic sum check · Σ(2i · C_i) ≟ C_value
✓ Σ(2^i · C_i) == C_value — bits committed consistently
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.