Signed Bytes All chapters

Chapter 03 · the reading

The reserve circuit is open source. Here is what it actually checks.

Chapter 02 was my model of a reserve desk: three switches, five rounds, a CFO with a better number. The production version is public. Primus ships the zkVM program that aggregates their Proof of Reserves reports, and it is 921 lines of Rust you can read. Two of my three switches are in there. The third is not, and its absence is the interesting part.

Eight handlers

por-client-unitas · zkvm-program/common/src/core.rs

One function per exchange account type. Each verifies the attestation, pins the endpoint against a hardcoded constant, extracts balances by JSON path, and refuses to count the same account twice. The interesting column is the last one: what the circuit uses to decide two proofs are the same account depends entirely on what that exchange happens to return.

handlerpinned endpointdedup keywhich is

Three strategies in one file. Where the exchange returns an account id, the circuit uses it. Where it does not, the circuit builds a fingerprint out of the balances themselves. Aster's spot handler uses $.updateTime, a timestamp, as the identity key.

The fault bench

pick a lie, meet the line

Five things you might try against a reserve report. Two are caught by name. One is caught for the wrong reason. Two go through in silence. The code beside each is the real thing, quoted from the repository.

What sits outside the proof

The circuit proves that every balance came from the pinned endpoint, over a genuine session, signed by the attestor, and that no account was counted twice within the run. It does not prove that any of it is recent. pv.timestamp is assigned in all eight handlers and read by none of them. It leaves the circuit as a public value, which means freshness is a question for whoever consumes the report rather than a property of the proof.

Nor does anything persist between reports. The HashSet that catches duplicates is created inside a single function call and dies with it. Two consecutive reports can count the same account, because as far as the circuit is concerned they are unrelated runs. That is precisely the question Zac Williamson asked me after chapter 02: where would you keep the nullifier state, and how would you bind each attestation to one accounting period before aggregation. The production answer today is that you do not, at this layer.

None of this is an accusation. A report is produced on a schedule by the party that owns the accounts, and the timestamp travels with it in the clear, so a consumer can enforce recency without the circuit doing it. The point of reading the source is to know exactly where that boundary falls, because the marketing word for all of this is simply "verified".

If you wanted the binding inside the proof, the material is already there. additionParams is one of the seven fields inside the attestation digest, so an epoch tag written at request time is signed by the attestor along with the balance. Half-open periods chained end to end give you a nullifier set that resets per period rather than growing forever. That is a design note, not a criticism of a system that is doing something harder than most of what calls itself proof of reserves.

A third deployment is in progress. por-client-xaut is a fork of the Unitas client for XAUT, Tether Gold. The circuit is the same minus the Binance funding wallet handler, which tells you the account mix differs and the checks do not.