Records
A record is what a settlement publishes about one contribution: 23 words of 32 bits, padded to 24, so 92 bytes in the transaction’s witness.
words 0..16 two new note commitments (8 field elements each)words 16..22 two nullifier keys (3 field elements each)word 22 the data wordword 23 padding: 0 in a contribution's recordFrom the commitments and nullifier keys, anyone can replay every settlement’s records in order and rebuild both trees exactly, because every insert goes at the next free position. Nothing else is needed. There is no off-chain state a verifier or a wallet has to fetch.
The data word
Section titled “The data word”Word 22 carries the one thing a payee cannot compute alone: the amount. Its top bits say what kind of word it is.
| kind | word | who can read it |
|---|---|---|
| deposit | the deposit amount, below 2²⁷ | everyone: it is public, and counted into the deposit total |
| memo | 2³⁰ + (amount + a pad only the payee can derive) mod 2²⁷ | the payee |
| none | 2³⁰ + 27 random bits | nobody: a withdrawal or self-spend looks like a payment |
So a deposit is visible as a deposit, the way a transparent-to-shielded transfer is in Zcash. A payment and a withdrawal look the same in their records. (A withdrawal also has a payout, below.)
Other kinds of records
Section titled “Other kinds of records”Some layers publish records of their own, and each follows the record it belongs to. A payout record is marked by its last word (word 23) set to 1; the others by a tag in word 22 that no deposit or memo word can equal.
- Payout record: after a withdrawal, the amount and a hash of the destination script. The vault pays it.
- Handshake record: a payer’s one-time public key, on the first payment to a payee (payment codes).
- Forced record: an exit request processed by a drain (exits).
- Payroll record: up to two provers’ pay notes (paying the provers).
- Migrate record: a note moving to a successor pool (upgrades).
Records have exactly one size on purpose. If records could vary in length, a cheating builder could choose where to cut a blob after seeing its hash, and search the cuts for one that matches. A fixed size closes that door.
The fingerprint: tying records to the proof
Section titled “The fingerprint: tying records to the proof”The proof and the script speak different hashes. Inside the proof, SHA-256 is expensive;
in script, Poseidon2 is impossible. They meet on a fingerprint (r, v):
- The script computes
r = SHA256(chain end ‖ records)over the records in the witness. - Both sides compute
v, the records read as one polynomial evaluated atr, modulo the prime 2¹²⁷⁹ − 1. - The proof also carries a Poseidon2 chain over the records (the “chain end”), and proves
that the same records, evaluated at
r, givev.
To pass with different records, a cheater would need a polynomial collision at a point
fixed only after the records were chosen. The chance is about n / 2¹²⁷⁹ per try, treating
SHA-256 as a random function. That argument is written down; nobody outside the project
has reviewed it.
This binding is why seed recovery is a property Bitcoin enforces, not a promise: a settlement cannot publish records other than the ones it proved.