Four words for this page.
Each elementary step of the computation the proof covers. "Born 18 or more years ago" becomes about two thousand steps; checking a SHA-256 becomes two hundred thousand. More steps, costlier proof.
Work done once before any proof, producing the keys for proving and for checking. It is not part of the cost of each proof.
The file the prover needs at hand. It can be large: 371 kB to 51 MB here. It is public; it holds nobody's secret.
The mathematical recipe that turns the computation into a proof. We measured two of the most used, Groth16 and PLONK, which trade size for convenience.
Four claims, two systems, one machine.
Everything ran on an Apple M2 with 8 GB of memory, using gnark (version 0.16.3), an open-source Go library, over the BN254 curve, the most common one for this kind of proof. The library uses all of the machine's cores when proving and checking.
For each claim, we counted the steps in the computation, measured the setup once, and then the time to generate the proof (best of five attempts with Groth16, of three with PLONK) and to check it (best of twenty). "Best of" means the fastest time: what the machine can do when nothing else gets in the way.
The claims are not toys. Age and balance are tied to a commitment, a seal published beforehand by the issuer, so you cannot prove the age on a made-up document. The list uses a tree with 1,048,576 leaves. SHA-256 is the fingerprint used in almost everything on the internet.
| Claim | System | Constraints | Setup | Generate proof | Check | Proof size | Proving key |
|---|---|---|---|---|---|---|---|
| Over 18 | Groth16 | 2,184 | 184 ms | 26 ms | 1.42 ms | 164 B | 371 kB |
| PLONK | 4,085 | 65 ms | 91 ms | 2.11 ms | 520 B | – | |
| Balance above X | Groth16 | 2,249 | 236 ms | 25 ms | 1.38 ms | 164 B | 381 kB |
| PLONK | 4,212 | 54 ms | 169 ms | 2.12 ms | 520 B | – | |
| On the list of 1 million | Groth16 | 13,261 | 1.9 s | 220 ms | 1.94 ms | 164 B | 2.5 MB |
| PLONK | 17,781 | 414 ms | 859 ms | 2.82 ms | 520 B | – | |
| Text behind the SHA-256 | Groth16 | 200,599 | 45.7 s | 1.6 s | 3.25 ms | 196 B | 51.3 MB |
| PLONK | 601,601 | 7.3 s | 40.6 s | 2.49 ms | 584 B | – |
For PLONK, the proving key was not measured, and the setup used was a test version generated on the spot. In production it would come from a public ceremony done once for all claims. That does not change the time to prove or to check.
Proving is expensive. Checking is cheap.
The time to generate the proof grows with the size of the computation: 26 ms for age, 220 ms for the list, 1.6 s for SHA-256 with Groth16, and up to 40 s with PLONK. Checking stays between 1.4 and 3.3 milliseconds in every case, no matter how big the computation behind it.
That difference is what makes the idea useful. The prover pays once, on their own device. The checker, a website with millions of visits or an auditor with thousands of reports, pays almost nothing per proof. For age, one proof costs as much as about 18 checks; for SHA-256 with PLONK, about 16 thousand.
Why is SHA-256 so much costlier? It was designed for ordinary computers, built from bit operations. Inside a proof, every bit becomes a computation. The fingerprint we used for age, balance and the list (MiMC) was designed precisely to fit inside proofs: it plays the same role with hundreds of times fewer steps.
Smaller and faster, or easier to set up.
The most compact proof
Proofs of 164 bytes for almost any claim, and the fastest to generate on this bench. The price is in the setup: each claim needs its own, and it uses a secret number that has to be destroyed afterwards.
If someone keeps that number, they can forge false proofs that pass the check. That is why a real setup is done in a ceremony with many participants: it takes just one of them destroying their share for the whole to be safe.
One setup for all
A single setup, done once, works for any claim up to a certain size. If the rule changes, no new ceremony is needed.
The price: proofs of 520 bytes, three times larger, and here 3 to 25 times slower to generate. Checking costs the same. On this bench, the setup was a test version, not fit for real use.
There are also systems that need no secret setup at all, known as STARKs, generally with much larger proofs. We did not measure them here.
We tried to cheat. No false proof got through.
A test that only shows the right case does not say much. So we asked for proofs that should be impossible, and checked that the library refused to generate or accept them.
| Attempt | How | Result |
|---|---|---|
| Minor | Born in 2010, proving over 18 in 2026 | rejected |
| Someone else's document | A date of birth that does not match the seal published by the issuer | rejected |
| Reused proof | A proof valid for 2026, presented as if it were for the year 2000 | rejected |
| Insufficient balance | A balance of 9,000 proving it is above 10,000 | rejected |
What this bench did not measure.
The phone
In real life, whoever proves their age does it on a phone, with less memory and no fan. An eight-core M2 is optimistic. The 51 MB key for SHA-256 would weigh on a basic device.
The browser
Proofs generated inside a web page tend to be much slower than the same code running directly on the machine. We did not measure it.
Other libraries
The age proof Google open-sourced in 2025 (Longfellow) uses a different design, built for phone credentials. Its numbers are not these.
One run, one machine
"Best of five" shows what the machine can do without interference, not the average of a busy server. And the memory used while proving was left out.
Run it yourself.
The bench code is a little over 200 lines of Go and is published here: main.go, falsa_test.go, go.mod and go.sum (with a README, in Portuguese). Download the four into one folder and, with Go installed, run two commands:
# prints the table on this page go run . # tries the four cheats; passes if all are rejected go test -run TestFalsa -count=1 .
To go deeper.
Does this apply to your case?
Tell us in two lines what you need to decide or measure. The first conversation is to see whether measurement solves your case, and if it does not, we say so.
- Our own bench, September 30, 2026: gnark v0.16.3 and gnark-crypto v0.21.0 (github.com/Consensys/gnark), BN254 curve, Apple M2 with 8 GB. Groth16: best of 5 proofs and 20 checks. PLONK: best of 3 proofs, test setup (unsafekzg).
- Groth, "On the size of pairing-based non-interactive arguments" (EUROCRYPT 2016).
- Gabizon, Williamson and Ciobotaru, "PLONK: Permutations over Lagrange-bases for Oecumenical Noninteractive arguments of Knowledge" (2019).
- The specimen's per-day figures are our own arithmetic: measured time times quantity, on an identical dedicated machine.