FlashProve: How an AI Provider Can Prove Which Model Answered You
You send a prompt to a hosted LLM. A reply comes back. Do you actually know which model produced it? In 2026, mostly you don't. You trust the provider's dashboard, its SLA, and its incentive to keep a good reputation. Every so often the industry rediscovers that this trust has cracks: models get silently swapped, quantized copies are served under a flagship's name, or a cheaper substitute quietly handles off-peak traffic. It is the bait-and-switch problem of the API economy.
Anthropic has published a research artifact that attacks this problem head-on. It's called FlashProve, it lives at github.com/anthropics/FlashProve, and it lets an AI provider prove which model answered a request — without revealing the model's weights. Apache 2.0, version 0.16.0, and clearly labeled for what it is: a research prototype, not maintained, not accepting contributions.
Here's what it does, how the cryptography works, what it honestly doesn't prove, and why a privacy-first developer should care.
The Problem: Verifiable Inference
When you call a hosted model API, you're renting computation you cannot inspect. The provider could serve a smaller, cheaper model and bill you for the big one. Regulators and auditors can't easily check either — weights are trade secrets, so nobody outside the provider can look inside the box.
The crypto research community has worked on this under names like zkML and verifiable inference: prove that a specific computation happened on specific committed data, without revealing the data. Applied to LLMs, that means proving "this reply came from the model I committed to," while the weights stay secret. FlashProve is one of the first full-size, end-to-end implementations of that idea, from a major lab, with the soundness of its core verifier machine-checked in the Lean proof assistant.
The Three-Step Protocol: Commit, Prove, Verify
FlashProve splits the problem into three roles:
- Commit. The provider runs
cp_commiton its GPU machine. Out comes a commitment ID — 64 hex digits hashing the model's configuration, a Merkle root, a masked encoding of the weights, and some auxiliary seeds. The ID cryptographically binds the provider to exactly one set of weights. The weights themselves never leave: every published value that depends on them is masked. - Prove. For each reply, the provider's GPU (a single NVIDIA H100) produces a proof that the reply is the committed model's output. Proofs are generated in batches during serving.
- Verify. Anyone — a client, an auditor, a regulator — checks the proof with
cp_verifyon an ordinary CPU, in seconds, with no access to the weights. Accept, reject, or no verdict. That's the whole loop.
The client-side rules matter as much as the math: build the request file yourself from the tokens you actually sent and received, get the commitment ID from a party you trust (never from the server being checked), and name the acceptance policy you expect. The tooling even ships a Python integration wrapper that handles the comparisons.
What's Under the Hood
FlashProve is built from proven cryptographic building blocks rather than a new exotic assumption:
- Hash-based proofs. The core is an interactive oracle proof made non-interactive with Merkle trees and the Fiat-Shamir transform. Sumcheck protocols and lookup arguments reduce "these committed numbers are a correct run of the model" down to a few linear claims.
- A proximity test. A code-proximity check (from Chiesa, Fenzi and Weissenberg's work, ePrint 2026/391, with stated differences) shows the committed data is close to a valid codeword.
- Standard hashing. BLAKE2b everywhere it counts — Merkle trees, Fiat-Shamir transcripts, the commitment ID itself.
One subtlety deserves attention: proofs need exact arithmetic, but trained LLMs run in floating point. So the committed model is an integer model that approximates the floating-point model. In the expected deployment, vLLM (or another engine) serves the floating-point model to users, and the proof is produced afterwards from one prefill pass of the integer model. FlashProve's documentation is refreshingly blunt that no theorem says how close the integer model is to the float model — that gap is a known limit, not a hidden one.
Two Acceptance Policies: YES and WITHIN LIMITS
What does a valid proof actually certify? FlashProve supports two policies:
Exact match. The strict one. A YES verdict means each checked token is the committed integer model's top choice at its position, up to a stated error bound. If the serving engine's token disagrees with the integer model anywhere, exact match fails — which is why it's not the practical serving policy.
Clipped gap. The realistic one. Each checked token gets a cost based on how far its logit lies below the top choice's (built on the Token-DiFR score, arXiv 2511.20621, with stated modifications). A reply passes — WITHIN LIMITS — if at most cap tokens exceed threshold C and the clipped costs average at most theta. This tolerates the small divergences real serving produces while still catching wholesale substitution. Crucially, the client names the policy and its numbers when verifying; loose limits make almost anything pass, so the policy is part of the trust contract.
What Is Actually Proved — and What Isn't
This is where FlashProve is more honest than most verifiable-inference marketing, and it's worth reading closely:
- Soundness is machine-checked. For the Lean verifier, at exact match: it accepts a false claim with probability at most about q/2124 + 2-101 after q hash queries. That's the theorem, in Lean 4, checkable by anyone.
- Completeness and zero knowledge are proved for the protocol — an honest prover succeeds, and proofs leak nothing about weights beyond a declared list (plus one bit per request: served or refused). Again in Lean, at full size, within stated bounds.
- The programs you actually run are tested, not proved. The C++ verifier (
cp_verify) and the CUDA prover follow the protocol and are tested against it, but no theorem covers them directly. The docs say this in plain words. - Known open questions. Two published Fiat-Shamir attacks have not been examined against this protocol. The integer-versus-float gap is unproved. And the full pipeline — FP serving plus live proof generation on a trained model — has not run as a single production service.
For a research prototype, this level of candor is a feature. It tells you exactly where the trust boundary sits: the math is checked, the engineering is well-tested, and the deployment story is still future work.
Performance and Practicality
FlashProve runs Llama 4 Maverick at full size — with a 1,024-token context window — on a single NVIDIA H100, reaching roughly 110 tokens/second of prefill at 24 requests per batch. That's not web-scale serving; it's a proof that the approach fits real model sizes on real, single-GPU hardware rather than a datacenter full of provers.
Verification is the cheap side by design: checking a stored example proof takes under two seconds on an ordinary CPU with under 2 GB of RAM. The asymmetry is the point — one expensive GPU proves, everyone else verifies nearly for free.
Built to Be Run by an Agent
The most 2026 thing about this repository: the README contains a section literally titled "For agents." Long builds, exact exit-code comparisons, and multi-step verification flows are exactly what coding agents do well, so FlashProve's docs are written to be executed by one. You point your agent at the repo with a short instruction — build the verifier, check the stored proof, report the exit code and last line — and it works through the routes: verify a stored proof on CPU, run toy proofs, build the GPU prover with a small synthetic model, or go full size with Maverick.
It's a small but telling artifact of where developer tooling is heading: reproducible verification workflows designed first for agent consumption, humans second.
Why This Matters
For API buyers: proof-of-model becomes checkable. A marketplace or enterprise can demand a commitment ID and verify replies against it — no more taking "we serve you the model on the label" on faith.
For providers: verifiable inference could become a differentiator — and eventually a procurement requirement. Open weights make substitution detectable; closed weights don't, which puts the burden on protocols like this one.
For the ecosystem: FlashProve joins a small but growing set of verifiable-inference efforts, and its Lean-verified soundness plus honest limits documentation raises the bar for how these systems should be published.
Try It Yourself
The cheapest route needs only a Linux box, g++ 13, and 2 GB of RAM: build cp_verify, check the stored example proof, and watch for the final YES. From there the routes scale up to the full H100 prover. And when you're finished poking at Merkle roots and Fiat-Shamir transcripts, the rest of your verification toolkit can stay client-side: decode and inspect tokens with Formatho's JWT debugger, examine proof-sized JSON artifacts with the JSON linter, and encode or decode committed values with the Base64 tool — all in your browser, nothing uploaded.
Frequently Asked Questions
Does FlashProve reveal the model's weights?
No. That's its core property. All published values derived from the weights are masked; zero-knowledge proofs (machine-checked in Lean for the protocol) say the proofs reveal nothing about the weights beyond a declared list, plus one bit per request.
Can it prove OpenAI's or Google's models answered me?
Not as shipped. FlashProve currently demonstrates the approach on Llama 4 Maverick, and only the provider that holds the weights can generate proofs. It's a template for how any provider could offer verifiable inference — adoption is the open question.
Is FlashProve production-ready?
No, and it says so. It's an unmaintained research artifact. Soundness of the Lean verifier is machine-checked; the C++ and CUDA programs are tested but not proved; live FP-serving plus proof generation hasn't run as one service on a trained model.
What hardware do I need to verify a proof?
An ordinary CPU and under 2 GB of RAM. Building the verifier takes a minute or two; checking a proof takes seconds. Only generating proofs needs the H100.
Where do I read the actual theorem?
The repository ships the Lean theorem (lean/THEOREM.md), a paper PDF, full limits documentation, and checkable Lean sources — everything needed to audit the claims in this post.
Conclusion
FlashProve won't verify your next API call — it's a prototype, running one open model, on one GPU, maintained by nobody. But as a blueprint it matters: a major lab has shown that full-size models can be held to cryptographic account without giving up weight secrecy, with the core soundness machine-checked in Lean and the limits documented with unusual honesty. The bait-and-switch era of LLM APIs has an expiration date. Verify, don't trust.