How it works.
Start with the plain version. The mathematics is further down, and so is the list of things this cannot do.
The plain version
Think of a sealed envelope. Before anything runs, the model owner seals their weights in one envelope and the input is sealed in another. Sealing produces a short code — a fingerprint — that they hand out. The fingerprint reveals nothing about the contents, but it is impossible to seal different contents and still get the same code.
Now the model runs and produces an answer. Along with it comes a proof: a small file that says the contents of envelope A, applied to the contents of envelope B, produce exactly this answer. You check that proof against the two fingerprints. Either the mathematics works out or it does not.
What makes this useful is what you never need: the weights, the input, a trusted log, or the provider's good word. And what makes it honest is how narrow the claim is — the proof is about one computation, not about whether that computation was a sensible thing to run.
What is in a receipt
A receipt is public. Everything in it can be handed to an adversary without leaking the model or the data:
- The model fingerprint — a salted Poseidon hash of the weights and the checkpoint number.
- The input fingerprint — a salted Poseidon hash of the input features.
- The answer — as a fixed-point integer, plus a copy inside the proof's public signals.
- The request details — task id, model id, operation, verification key id, step and a random challenge.
- The proof — three group elements. About 800 bytes of Groth16 over the BN254 curve.
The salts are what keep a fingerprint from being brute-forced. They stay private, so a receipt never lets you reconstruct the weights or the input by guessing candidates and re-hashing them.
The mathematics
The claim is expressed as an arithmetic circuit, written in Circom 2. The circuit takes the weights, the salts and the input features as private inputs, and the two fingerprints, the step and the challenge as public inputs. Inside, it enforces three things at once:
- Re-hashing the private weights with the private salt reproduces the public model fingerprint.
- Re-hashing the private features reproduces the public input fingerprint.
- The linear combination of those weights and features equals the answer that is published as a public signal.
Because all three constraints live in one circuit, they cannot be satisfied separately. A proof exists only if the same weights that match the fingerprint are the weights that produced the answer.
The circuit is compiled to a constraint system and proved with Groth16. Verification is a pairing check against a verification key: constant-size, and fast regardless of how the proof was produced. All arithmetic happens in a prime field, so the model is fixed-point, not floating-point — weights and features are integers scaled by 256, and the prediction is encoded with an offset so negative values survive the field encoding.
The current circuit proves a two-feature linear regression. A second circuit proves a weight update: given a previous checkpoint fingerprint and a data fingerprint, it enforces one step of gradient descent at rate 1/16 with floor rounding, and outputs the next checkpoint fingerprint. That is what makes a retraining step checkable instead of merely announced.
Recorded proofs versus live acceptance
The demo on the home page verifies a proof that was generated earlier on our machine. That check is genuine — the pairing check runs in your browser and fails if anything is altered — but it establishes a mathematical statement, not a fresh event. Replaying it tomorrow proves the same thing it proves today.
Freshness is a separate problem, and it is handled outside the proof. The command-line controller issues each task with a random challenge and an expiry, remembers which tasks it issued, rejects a receipt whose challenge it did not issue, rejects one that arrives late, rejects a replay of one it has already accepted, and advances its checkpoint only after accepting a valid update. So the controller's accepted state — not any single proof — is what says which checkpoint is current.
This is worth being precise about, because it is the usual place where verifiable-computation demos quietly overclaim. A proof is evidence about arithmetic. Knowing when a computation happened, and that it happened only once, needs a protocol around it.
What it does not prove
The proof is narrow on purpose. It does not establish:
- That the answer is any good. Accuracy, calibration and fairness are untouched. A proved prediction from a bad model is a bad prediction with a receipt.
- That the input is true. The proof binds a fingerprint of the input, not the reality behind it. Garbage in still yields provably computed garbage out.
- How the input was produced. Whatever preprocessing turned raw data into those features sits outside the circuit.
- What else the provider did. A proved computation does not rule out other computations, other models, or a discarded second opinion.
- That the fingerprints mean what you assume. Committing to weights is only useful if you know how the committed model was obtained. That first link is a trust decision, not a proof.
- Anything about a language model. Proving an LLM forward pass is not economical with current proving systems. This is a small numeric model.
Status and honest disclosure
This is a working research prototype, built in the open by baz consulting. It runs real Circom circuits and real Groth16 proofs — nothing on this site is simulated — but it is not a production service, and it would be wrong to present it as one:
- The trusted setup is a development ceremony, not a multi-party production ceremony.
- There has been no independent security audit.
- In the local demo the worker and the controller run as the same operating-system user. Separate directories are not isolation.
- Update history is checked one step at a time. There is no recursive proof over a whole training run.
- There are no customers, deployments or case studies behind this. When that changes, it will say so here.
Measurements
Measured on 17 September 2026, on one laptop, for the two-feature circuit on this site — a deliberately tiny model. Treat these as an order of magnitude, not a benchmark:
- Verifying in a browser: tens of milliseconds, including the fingerprint and key checks. Constant in the size of the computation.
- Proving: roughly half a second per inference, including process startup.
- Receipt size: under a kilobyte of proof, plus the fingerprints.
Verification cost is the number that stays flat as models grow. Proving cost is the one that does not, and it is the reason this technique fits small, high-stakes decisions long before it fits a chatbot.
Want to know whether your model fits this shape?
Talk to us