
For forty years cryptographers have tried to build digital cash and failed. Chaum's DigiCash (1990s) had the mathematics but went bankrupt for want of merchant adoption. Bitcoin gave us digital scarcity but no native bearer-paper form – Casascius coins and BIP-38 paper wallets are aftermarket wrappers, not first-class instruments. Central bank digital currencies threaten the opposite: digital surveillance with no bearer privacy at all.
The Alberta Buck identity, reserve, and demurrage machinery – combined with one new primitive, a global commitment pool – finally permits a native digital-private bearer instrument. This document specifies that primitive.
A BUCK Note is an on-chain commitment whose opening authorises a private mint to a registered identity. The same commitment can live only on chain (a software-only transfer between two of a user's own private accounts), travel between parties as a digital message, or be printed on paper as a QR-encoded slip – all three surfaces sharing the same cryptography and the same on-chain footprint, indistinguishable in use from a $20 bill while being cryptographically impossible to counterfeit.
Notes defeat bulk on-chain traceability – KYC-provider subpoenas,
chain-analytics fingerprinting, omnibus surveillance – while preserving
bilateral Identity disclosure: the two named parties to any specific note
always learn each other's M, and either is compellable on warrant. This is
stronger compliance than physical cash provides today, stronger privacy than
any CBDC has ever proposed, and the first design where a private bearer
instrument is a native, first-class primitive of the monetary system rather
than an aftermarket wrapper. (PDF, Text, Walkthrough)
The Cash Paradox
Physical cash is simultaneously irreplaceable and impossible to digitize.
It is irreplaceable because it does things no digital instrument has ever matched. A $20 bill works without a network, a battery, a bank, an ID check, or a counterparty to your transaction. It clears instantly, finally, and without fees. It is the single most successful monetary instrument in human history – so successful that roughly half the value of US currency in circulation is held overseas as a global store of value, in defiance of every theoretical reason it shouldn't be.1
It is impossible to digitize because every attempt has reproduced the surveillance properties of bank money instead of the privacy properties of cash. Modern card networks log every transaction. Bank wire transfers require both parties to be identified. Stablecoins record every transfer publicly on chain. Central bank digital currencies, where they exist or are being designed (China's e-CNY, Europe's digital euro proposals), are explicitly programmable surveillance tools – the central bank can see, restrict, expire, or geofence any holder's balance at will.2
The closest existing analogues to digital cash are aftermarket bearer wrappers around cryptocurrencies: Casascius physical Bitcoin coins (2011-2013), OpenDime USB sticks, BIP-38 paper wallets, and the various scratch-card "crypto gift cards" sold at convenience stores. These work, technically – a Casascius coin is a genuine bearer instrument – but they are workarounds, not designs. The underlying token (Bitcoin) does not natively understand bearer-paper form. Loss of the physical coin is permanent loss of the value. Counterfeiting requires faith in the manufacturer's hologram, not in the cryptography.3
What if the bearer-paper form were a first-class instrument of the system? Designed in from the start, with the same cryptographic and economic properties as on-chain balances, integrated with the identity and reserve mechanics that already exist?
That is what BUCK Notes is.
Why Forty Years of Trying
David Chaum invented digital cash in 1982 with the blind-signature e-cash scheme.4 By 1989 he had founded DigiCash to commercialize it. By 1998 DigiCash was bankrupt – not because the cryptography failed (it worked), but because no merchant wanted to be the first to accept it and no consumer wanted to be the first to hold it. The two-sided market never bootstrapped.
Stefan Brands extended Chaum's work in 1993 with offline divisible coins that revealed the spender's identity if (and only if) they double-spent.5 Camenisch, Hohenberger, and Lysyanskaya improved on this in 2005 with compact divisible e-cash.6 None of these schemes ever shipped in production at scale.
Bitcoin, when it arrived in 2009, was deliberately not digital cash in the Chaumian sense. It was digital scarcity with public ledger transparency – closer to digital gold than digital cash. The bearer-paper market that grew up around it (Casascius, OpenDime, paper wallets) was an afterthought, not a design goal.
Zerocash (2014)7 and its production deployment as Zcash gave us the first scalable on-chain commitment-and-nullifier UTXO model – the cryptographic primitive that BUCK Notes use. Zcash showed that you can have private on-chain balances; it did not extend that to printable physical bearer instruments. Aztec8 extended the model with predicate-encrypted notes for private smart contract calls, but again, no paper.
Tornado Cash9 reduced the primitive to its simplest form (fixed-denomination commitments in, anonymous withdrawals out) and was OFAC-sanctioned in 2022. Privacy Pools10 extended Tornado with per-spend association-set proofs, restoring compliance paths without abandoning the privacy primitive.
The reason all of this never produced BUCK Notes – a printable, demurrage-aware, identity-aware private bearer instrument – is that it required four pieces to come together simultaneously, and they did not until now:
- A commitment-and-nullifier UTXO model on a smart contract platform (Zerocash gave us this in 2014; Aztec deployed it on Ethereum in 2018-2020).
- A cryptographic identity layer that lets some notes be targeted to a specific recipient and others be self-wormholed between a user's own unlinkable accounts (the BUCK identity system, with PS signatures, ElGamal credentials, and Chaum-Pedersen re-encryption – see Identity).
- A demurrage mechanism that solves the lost-cash problem and gives bearer notes a finite lifespan (BUCK's demurrage and Jubilee are unique among monetary systems).
- A jurisdictional reserve that backs the value, so the bearer note represents a real claim on real assets, not a speculative crypto-token whose price might collapse between print and deposit (Alberta Buck's commodity-basket-stabilized reserve and the BuckK PID controller).
Alberta Buck has all four. No prior system had all four. That is why BUCK Notes is a design, not a workaround.
BUCK Notes at a Glance
Before the chapter-length treatment, here is the entire design in one page.
One on-chain primitive. A single Merkle tree of note commitments and a single nullifier set replace every parallel bearer-instrument architecture the Alberta Buck series has previously explored (self-wormholes between private accounts, signed cheques, targeted gifts, printable paper notes).
Two orthogonal axes parameterise a note. Depositor Identity
binding (present: only the named recipient may deposit; absent: any
registered holder of the opening may) crosses with issuer
visibility (public: the issuer's Identity M is in the clear on
the note; private: it is encrypted to the recipient). Crossing
these yields three realisable flavors – the private-bearer cell is
ruled out by BUCK's mutual-decryptability invariant:
- A2 – Addressed Cheque, Private Issuer. The issuer re-randomizes the recipient's registered ElGamal credential into the note payload; the A-spend predicate requires the depositor to produce \( sk_{\text{rec}} \) (the mint-time private key paired with the \( pk_{\text{rec}} \) used for the re-randomization) and prove it decrypts both \( E_{\text{note}} \) and the depositor's own registered credential to the same identity point. A note Alice issues from a private account to a named recipient (including herself at another of her own accounts) with no on-chain edge visible to third parties. The canonical wormhole is the degenerate self-issued subcase.
- A1 – Addressed Cheque, Public Issuer. Same addressed binding
as A2, plus a Schnorr signature by the issuer over the commitment
with their plaintext
M_issuer. A cheque whose maker is publicly attributable and whose recipient is named but not visible to third parties – payroll, audit-friendly disbursement, B2C payment. - B1 – Bearer Cheque, Public Issuer. Plaintext issuer
M; no recipient binding; first registered holder to publish the nullifier \( \rho \) redeems. A cashier's cheque: maker known, bearer not, cash-on-presentation.
Demurrage needs no new machinery. The Notes Pool is simply the
Notes contract's own ERC-20 balance – a regular BUCK account
tracked by the existing demurrage ledger. Mint pulls
totalFace BUCK from the caller via standard ERC-20 transfer
(sender pays their own outgoing demurrage fee). Spend uses a
carrying transfer unique to the Notes contract's single egress
path: the recipient's nominal balance rises by the full face
value, and their _indexAtLastTouch weighted-merges toward the
pool's stale index, inheriting the average pool-residence
demurrage on the inflowing share. Donations to the contract
freshen the pool's index, directly lowering the demurrage absorbed
by all subsequent spends. Conservation is automatic; the
Jubilee continues to grow autonomously per BUCK's standard
accounting.
Lost notes return value to the commons. Demurrage solves physical cash's oldest problem: a lost note's value decays at the same rate as an on-chain balance, with the difference accruing to the Jubilee rather than as seigniorage to the issuer.
Holding semantics differ by flavor. The addressed flavors
(A1, A2) are cryptographically safe for long-term holding, because
the spend predicate binds the recipient's Identity M and no
mint-time knowledge enables a non-recipient to spend. The
bearer flavor (B1) is a civil-trust instrument: the issuer
necessarily knows \( \rho \) and could race the holder to deposit,
so B1 cheques are meant to be cashed promptly and trusted only to
the extent the issuer's legal standing and operational discipline
warrant. This is an intrinsic cryptographic property, not a policy
choice.
The remainder of this document develops each piece in detail and establishes the formal proofs (Theorems 7-11 of the companion Proofs document).
The Core Primitive: One Global Commitment Pool
The entire BUCK Notes design rests on a single on-chain primitive: a
Merkle tree of commitments with a nullifier set, accompanied by a
carrying transfer (transferCarrying) that delivers the opening's
face value to a recipient and weighted-merges the pool's
accumulated demurrage index into the recipient's account. Everything
else – paper notes, addressed cheques, bearer cheques,
self-wormholes – is a consequence of varying the spend predicate
inside the commitment.
The Note Contract State
The Notes contract is a separate, dedicated contract (src/Notes.sol)
holding a Tornado-style incremental Poseidon-T3 Merkle tree, a
nullifier set, and a small ring buffer of historical roots.
| State | Type | Purpose |
|---|---|---|
nullifiers |
mapping(uint256 =\Rightarrow bool)= |
Double-spend prevention |
noteFaceSum |
uint256 |
Total face value of all outstanding notes (audit scalar) |
nextLeafIndex |
uint32 |
Next free leaf slot (also = current leaf count) |
roots[30] |
uint256[ROOT_HISTORY_SIZE] |
Recent root ring buffer; spends may use any historical root |
currentRootIndex |
uint32 |
Newest entry in roots[] |
mintVerifiers[N] |
mapping(uint256 =\Rightarrow IMintVerifier)= |
Per-N batch-mint verifier dispatch (pinned set, e.g. 16/128/1024) |
The tree is fixed at depth \( d=20 \) (\(\approx 1{,}048{,}576\) leaves) and
uses Poseidon-T3 (2-input) at every internal node. Under Phase-7-bis the
per-leaf Merkle insertion logic lives inside the mint SNARK; the contract
itself does not maintain zeros[] or filledSubtrees[] and does not expose
an on-chain _insert() entry point. Every mint submits a SNARK-attested
newRoot which the contract writes into roots[] in one step. The ring
buffer holds the 30 most recent roots so spends remain valid for a short
window after new notes are inserted, without requiring per-spend root-update
synchronisation. The per-commitment commitmentExists duplicate-reject
map from Phase 7 has also been retired – duplicate mints are now
economically self-punishing via the deterministic nullifier
\( \text{Poseidon}_3(\rho, \text{idHash}, 4242) \), so the chain does not
need an explicit check.
The Notes pool – the BUCK custody side of the design – is just the
Notes contract's own ERC-20 balance. No separate poolBalance,
poolAge, or poolT state is maintained: the BUCK ledger's own
per-account balance and demurrage index for address(notes) already
are the pool, and noteFaceSum is a pure audit scalar (the total
face-value liability outstanding). The pool is registered
isSystemPublic in the IdentityRegistry so that identity-bound
transfers from any registered party can land at it.
BUCKs transferred to the Notes contract on mint join its ERC-20
balance through the normal path. BUCKs transferred out on spend use
a single new BUCK primitive – transferCarrying – which moves both
face value and a proportional share of accumulated demurrage (via a
weighted-index merge on the recipient's _indexAtLastTouch) from the
pool to the recipient. This is the only non-standard BUCK operation
in the design; see "Demurrage at the Pool Level" below.
The Note Commitment
A note commitment is a Poseidon hash of the fields the SNARK will later open:
\[ cm \;=\; H_{\text{cm}}\!\left(\text{flavor},\; v,\; \rho,\; \text{id-payload},\; \text{predicate}\right) \]
with:
- flavor \( \in \{A1, A2, B1\} \): the Identity-binding flavor
- v \( \in \mathbb{Z}_q \): face value
- \( \rho \): per-note randomness (source of the nullifier)
- id-payload: Identity-binding data (see "Note Flavors" section)
- predicate: optional additional spend predicate (time locks,
oracle conditions, multi-sig; not elaborated in detail here – a
single bit
predicate == Nonekeeps the SNARK to the three base flavors. See "Open Questions" for bounded-programmability notes.)
No per-note timestamp or baked-in BUCK-age: demurrage is computed at redemption time from the pool's account state \( (B, A) \), not from the individual note's life history, so no per-note age fields need to ride in the commitment11.
The commitment is inserted as a leaf of noteTree at mint time.
The Note Nullifier
The nullifier is a pseudo-random function of the note's secret witness material:
\[ nf \;=\; \text{PRF}_{\text{key}}(\rho) \]
where key is the spend-side secret specific to the flavor: the
recipient's identity point \( M_{\text{rec}} \) for A-spend
(recovered in-circuit by ElGamal-decrypting \( E_{\text{note}} \)
under the depositor-supplied \( sk_{\text{dep}} \), which must
equal the mint-time \( sk_{\text{rec}} \)), or \( \rho \) itself
for B-spend (publicly derivable by any holder of the opening).
The PRF is instantiated via Poseidon in the SNARK-friendly
setting.
The nullifier is emitted on deposit; double-spend is rejected by set-membership check.
Lifecycle
mint (burn, Phase-7-bis batch):
# The caller supplies a batch of N commitments, the SNARK-attested
# newRoot, and the oldRoot / nextLeafIndex they based the proof on.
# The per-leaf Poseidon insertion is inside the SNARK, not on chain.
require cms.length > 0
require oldRoot == roots[currentRootIndex] # stale-state guard
require nextLeafIndex == self.nextLeafIndex # stale-state guard
cmBatchHash = keccak256(abi.encodePacked(cms))
require mintVerifiers[cms.length].verifyMint(
proof, oldRoot, newRoot, nextLeafIndex, totalFace, cmBatchHash)
# The SNARK has proved, for some witness
# (flavor_i, v_i, rho_i, idHash_i, predHash_i, pathSiblings_i)_i:
# - cm_i = Poseidon5(flavor_i, v_i, rho_i, idHash_i, predHash_i)
# - v_i in [0, 2^128), totalFace in [0, 2^128) # Num2Bits(128)
# - sum(v_i) == totalFace
# - folding {cm_i} onto oldRoot at nextLeafIndex using pathSiblings_i
# yields newRoot
# - cmBatchHash == H(cm_0, ..., cm_{N-1})
buck.transferFrom(caller, address(this), totalFace)
# Adopt the SNARK-attested new root and advance the rolling state.
currentRootIndex = (currentRootIndex + 1) % ROOT_HISTORY_SIZE
roots[currentRootIndex] = newRoot
self.nextLeafIndex += cms.length
noteFaceSum += totalFace
emit Minted(caller, totalFace, nextLeafIndex, cms.length, newRoot)
spend (mint-out):
# caller supplies (proof, root, nullifier, face, recipient)
require root in roots[] # any of the last 30 historical roots
require nullifier not in nullifiers
verify SNARK (spend, B-flavor / bearer shape):
- face in [0, 2^128) and face == v # Num2Bits(128) on both
- cm = Poseidon5(flavor, v, rho, idHash, predHash)
- Merkle inclusion of cm under root # Switcher + Poseidon(2) per level
- nullifier == Poseidon3(rho, idHash, 4242)
- ghost-bind public signals (face, recipient, chainId) via x*x
nullifiers[nullifier] = true
noteFaceSum -= face
# The single new BUCK primitive: pay the face out of the pool to
# recipient and merge the pool's demurrage index into recipient's
# weighted-average _indexAtLastTouch. Recipient receives face BUCK
# and inherits the pool's average BUCK-age proportional to their
# delivered share of the new total balance.
buck.transferCarrying(recipient, face)
Full face value is delivered: the recipient's nominal balance goes
up by exactly face. The pool's demurrage cost rides along as a
weighted-merge of the pool's _indexAtLastTouch into the
recipient's index, in proportion to the inflowing share of their
new total balance. The recipient bears that demurrage on their
subsequent outgoing transfers through the ordinary BUCK accounting
path – the same path any holder travels, but on an inherited
index acquired by accepting the note. No Jubilee payment is
emitted from inside spend; the Jubilee grows autonomously per
BUCK's standard _advanceGlobals / _accrueJubilee machinery,
independent of how BUCK is distributed between accounts.
A Note is a Deferred Approve Handshake
The single most useful way to understand BUCK Notes is that /a note
is an approve handshake split across time and mediated by the
commitment pool/. Once this frame is in place, every structural
choice below follows mechanically.
The Regular On-Chain Transfer
A standard BUCK transfer between two registered identities is a synchronous bilateral exchange:
- Alice calls
approve(bob, v, E_alice_for_bob, CP_proof). She re-encrypts her credential under \( pk_{\text{bob}} \) and proves (Chaum-Pedersen) that the re-encryption carries the same \( M_{\text{alice}} \) as her registered credential. - Bob calls
approve(alice, 0, E_bob_for_alice, CP_proof). Same in the other direction. transfer(bob, v)consummates the transfer once both halves are recorded.
All three steps may land in the same block, as long as they're available by transfer(bob, v)-time.
Each party learns the other's \( M \); every on-chain observer sees both addresses, the amount,
and the timing. The transfer edge (alice, bob, v, t) is public and permanent.
The Note is the Same Handshake, Deferred
A Note reorganises the same three messages:
- Mint. Alice performs her half of approve against a pool
commitment rather than directly against Bob. Depending on
whether the depositor is known at mint time, she either encrypts
her credential under the depositor's public key
(
E_alice_for_depositor, identity-bound flavor) or publishes her credential in the clear with a bearer secret \( \rho \) (public-issuer bearer flavor). The commitment is appended tonoteTree; Alice's outgoing BUCKs lands in the pool's balance \( B \). -
Deposit. The eventual depositor submits a SNARK-proved spend predicate that simultaneously:
- opens the commitment and proves nullifier correctness,
- completes their half of approve by attaching
E_depositor_for_issuer(the mirror ElGamal ciphertext) as a deposit-event payload, and - authorises
transferCarrying(recipient, face)out of the pool, weighted-merging the pool's demurrage index into the recipient's_indexAtLastTouch.
- Receipt. The issuer later scans deposit events for the
nullifier of the note she printed and reads
E_depositor_for_issuerto learn who cashed it.
Both parties end up with the same cryptographic knowledge of each other that approve would have
produced. The only difference from the observer's perspective is that mint and deposit are two
independent transactions, and the commitment pool hides which mint corresponds to which deposit;
the demurrage liability transferred with \( v \) is the Note pool average at that
instant11.
Mutual Decryptability: The BUCK Identity Invariant
Every BUCK transfer, note or otherwise, preserves a load-bearing
Identity property: both parties must end up able to decrypt each
other's \( M \). In approve, this is achieved explicitly by
the two re-encryption calls. In a Note, the same property must
still hold:
- At mint time, the issuer has to publish, alongside the commitment, enough material that the eventual depositor can recover \( M_{\text{issuer}} \).
- At deposit time, the depositor has to publish enough material that the issuer (reading chain events) can recover \( M_{\text{depositor}} \).
This invariant is the single strongest constraint on note structure. It is what rules out pure-bearer anonymous notes (neither party learns the other's identity), and what forces the exactly-three-flavor taxonomy below.
What the On-Chain Observer Sees
At mint: a transfer of \( v \) BUCKs from Alice's address to the
contract address, plus a Minted(issuer, totalFace, startIndex,
count, newRoot) event. The commitments themselves live in the
transaction calldata (cms[]); each \( cm_i \) is a Poseidon hash,
so observers learn nothing about the opening, the depositor, the
issuer flavor, or \( \rho \).
At deposit: a transferCarrying of face BUCKs from the Notes
contract address to the depositor's address, plus a
Deposited(nf, E_depositor_for_issuer) event. Observers learn
who the depositor is (standard transfer visibility), but not which
mint this corresponds to. The TransferCarrying event is
distinguishable from a standard Transfer, but only as a generic
pool-egress signal; it does not link mint to spend.
The two transactions are decoupled in time and unlinked in the
chain state. Any mass-harvest analysis that tries to reconstruct
the (issuer, depositor, v, t) edge must either (a) correlate
timing across the whole pool anonymity set, (b) subpoena a party
with direct knowledge, or (c) break the SNARK / Poseidon.
Why This Framing Matters
Almost every downstream design choice is a corollary of "deferred approve handshake":
- Three note flavors correspond to three valid ways to complete the two halves of the approve across time (next section).
- Mutual decryptability is the invariant that kills a fourth flavor (private issuer, unknown depositor).
- Selective disclosure for compliance is the natural consequence
of each party still holding cryptographic receipts of its
counterparty, exactly as in
approve. - Integration with regular transfers requires no new semantics
at the contract boundary: a note deposit is an ERC-20 transfer
from the contract address, and the identity-exchange payload in
the event is structurally identical to the receipt fragment
approvealready stores.
The Surface of a Note: Chain, Message, Paper
A BUCK Note is, fundamentally, a tuple
(flavor, v, rho, id_payload, predicate, merkle_path)
that opens to a commitment \( cm = H_{\text{cm}}(\text{flavor}, v, \rho, \text{id-payload}, \text{predicate}) \) in the on-chain note tree. The tuple can live on any medium capable of storing ~200-500 bytes and being read back faithfully. Three surfaces are supported:
Chain-Only Notes
The opening is transmitted privately from issuer to depositor (for a
self-wormhole A2, both are the same user operating from different
accounts) through an out-of-band encrypted channel – typically the
wallet's internal storage, or a direct peer-to-peer message between
wallets. The note never leaves the issuer's control infrastructure.
The canonical self-wormhole case: Alice mints an A2 note targeting
her own M from a private account and deposits it into a second
unlinkable account.
Message Notes
The opening travels as a digital message: an email, SMS, QR shown on a screen, signal-messenger attachment, NFC handoff. No physical artifact exists, but the recipient can store, forward, or print the opening at their convenience. A1 addressed cheques between parties with reliable digital communication occupy this surface.
Paper Notes
The opening is printed as a QR code on a slip of paper, a card, a steel plate, or a sticker. For addressed notes (A1, A2) – where the cryptography already prevents a photographing observer from spending – no physical seal is required. For bearer B1 cheques – where whoever reads \( \rho \) can spend – the QR must be protected by a tamper-evident seal (hologram, scratch-off panel, or laminated sleeve) so the holder can verify they were the first to expose the secret.
A printed note typically also carries:
- A visible denomination (1, 5, 10, 100, 1,000, 10,000 BUCK) for human convenience. The actual value is what the commitment encodes; the printed face is metadata that a wallet verifies before deposit.
- A human-readable issuer mark, for visual recognition. Cryptographic authenticity comes from the on-chain commitment, not the mark.
- Redundant QRs front and back with Reed-Solomon error correction, plus the secret in base32 digits for manual recovery.
Paper notes are the form most people will think of when they hear "BUCK Note." Physical paper is the surface of last resort: it works offline, without batteries, across borders, through power outages, and past the expiration of any given digital communication channel.
Counterfeiting is Cryptographically Impossible
A "fake" BUCK Note is any opening whose claimed commitment does not appear in the on-chain note tree. The Merkle inclusion proof inside the spend SNARK fails. No mint occurs. No second-guessing is required: there is no paper-inspection threshold to deceive and no "close enough" forgery that a harried cashier might accept.
This is a stronger anti-counterfeit guarantee than the Bank of Canada
provides for physical $20 bills. Polymer banknotes can be counterfeited
(the techniques are well-published; the question is only whether the
counterfeit passes casual inspection). A BUCK Note cannot be
counterfeited at all – the on-chain commitment registry is the
authentic-bill list, and any printed note whose commitment is not in the
tree will produce a FAKE wallet status on scan and nothing more.
Wallet-App Status Codes
A user-facing wallet that scans a BUCK Note (from chain storage, message, or paper QR) displays one of five statuses:
| Display | Meaning |
|---|---|
VALID: 1,000 BUCK |
Commitment in tree, nullifier unspent, spend predicate satisfiable |
DEAD |
Commitment in tree, nullifier already spent |
FAKE |
Commitment not in tree |
EXPIRED |
Predicate includes an expiry that has passed |
NOT FOR YOU |
Addressed (A1/A2) note whose bound M_rec does not match the viewer's Identity |
Casual users do not need to understand the underlying cryptography any
more than they need to understand the security features of a $20 bill.
They scan, see VALID, and accept the note as payment.
On Deposit, the wallet constructs the SNARK locally (or via a delegated prover service for thin clients), submits the transaction, and displays the result. SNARK construction for a single-note deposit is on the order of seconds on a modern smartphone – Aztec's Noir compiler and Zcash's Halo2 prover both run on mobile.
After successful deposit, the note's nullifier is consumed and the QR is permanently dead. A torn-in-half paper note is a human signal of finality, not a cryptographic one – but it's a useful ritual to prevent confused future holders from trying to redeposit a dead QR.
Note Flavors: Depositor Binding x Issuer Visibility
Every note is characterised by two orthogonal choices:
- Depositor M-binding – present or absent. When present, only identities encrypting the same target \( M \) may deposit (the spend predicate is a Chaum-Pedersen equality, Theorem 6). When absent, any registered identity may deposit (the spend predicate is knowledge of a bearer secret \( \rho \) plus a Schnorr PoK of the depositor's registered \( sk \)).
- Issuer M visibility – public or private. The issuer's Identity point \( M_{\text{issuer}} \) is either attached in the clear (plaintext plus Schnorr signature) or encrypted such that only the eventual depositor can recover it (ElGamal under the depositor's \( pk \), re-randomised from the depositor's registered credential).
Crossing the two axes nominally produces four cells, but the mutual decryptability invariant of the previous section immediately rules out one of them:
| Issuer / Depositor | Depositor M-bound (A) | Depositor M-unbound (B) |
|---|---|---|
| Public issuer (1) | A1 – identified cheque to a specific | B1 – bearer cheque from a known issuer |
| registered recipient (payroll; audited | (pre-printed cashier's cheque; any | |
| disbursements; B2C with attribution) | registered identity deposits) | |
| Private issuer (2) | A2 – private cheque to a specific | B2 – impossible: a private issuer with |
| registered recipient (addressed cheque; | no pre-known depositor has no \( pk \) under | |
| self-wormhole is degenerate issuer == recipient) | which to encrypt \( M_{\text{issuer}} \) for | |
| the eventual depositor to recover. |
The three valid flavors – A1, A2, B1 – together cover every legitimate pool-mediated approve handshake on an identity-aware currency. They are not three different cryptographic primitives; they are three compositions of the same two building blocks (Chaum-Pedersen equality and Schnorr PoK), distinguished by which half of the handshake is carried in the commitment.
Flavor A2: Addressed Cheque, Private Issuer
The canonical private-to-private transfer. Subsumes "self-wormhole" (the degenerate case issuer \(\equiv\) recipient, where Alice mints to her own registered \( M \) and later deposits from a different registered credential bound to the same \( M \)).
Mint. The issuer reads the recipient's registered credential \( E_{\text{rec}}^{(\text{reg})} = (R_r, C_r) \) from the IdentityRegistry and re-randomises it with fresh \( r' \):
\[ E_{\text{note}} \;=\; (R_r + r' G,\ C_r + r' \cdot pk_{\text{rec}}) \;=\; \bigl((r_r + r') G,\ M_{\text{rec}} + (r_r + r') pk_{\text{rec}}\bigr). \]
This is a valid ElGamal encryption of \( M_{\text{rec}} \) under \( pk_{\text{rec}} \) with randomness \( r_r + r' \). The issuer never learns \( M_{\text{rec}} \) or \( r_r \) – only the on-chain ciphertext is used as a re-randomisation template. To complete her half of the deferred approve, the issuer also encrypts her own \( M_{\text{issuer}} \) under \( pk_{\text{rec}} \) as \( E_{\text{iss-for-rec}} \) and packs it alongside the commitment.
\[ \text{payload}^{A2} \;=\; \bigl(E_{\text{note}},\ E_{\text{iss-for-rec}}\bigr) \]
Scan. The recipient trial-decrypts each candidate note's \( E_{\text{note}} \) with her own \( sk_{\text{rec}} \) and checks whether the result equals her \( M_{\text{rec}} \) (which she knows). Exactly one ElGamal decrypt and one point-equality per candidate – the same scan cost as a stealth-address scheme.
Spend. The depositor (who must be the recipient – specifically, the holder of \( sk_{\text{rec}} \) paired with the mint-time \( pk_{\text{rec}} \)) produces a SNARK proving:
- Merkle inclusion of \( cm = H_{\text{cm}}(\text{flavor},\ v,\ \rho,\ \text{payload}^{A2}) \) in
noteTree. - Nullifier \( nf = H_{\text{nf}}(\text{A} \| M_{\text{rec}} \| \rho) \), with \( M_{\text{rec}} = C_n - sk_{\text{dep}} \cdot R_n \) computed in-circuit from \( E_{\text{note}} = (R_n, C_n) \). Keying on \( M_{\text{rec}} \) rather than \( sk_{\text{dep}} \) keeps the nullifier value independent of which signing key decrypted \( E_{\text{note}} \) (a privacy property of the hash), but does not enable key-loss recovery: the decryption step itself requires the specific \( sk_{\text{rec}} \) paired with the mint-time \( pk_{\text{rec}} \).
- Chaum-Pedersen equality (Theorem 6) between the depositor's registered \( E_{\text{dep}}^{(\text{reg})} \) and the note's \( E_{\text{note}} \): both decrypt to the same \( M \) under the same \( sk_{\text{dep}} \). The circuit uses a single secret-key witness, so this constraint implicitly forces \( pk_{\text{rec}} = pk_{\text{dep}} \) – the depositor's current registered public key must equal the recipient's mint-time key.
faceValue\( = v \).
Simultaneously, the depositor attaches E_depositor_for_issuer (an
ElGamal re-encryption of their own \( M_{\text{dep}} \) under the
issuer's \( pk_{\text{issuer}} \)) as a deposit-event payload,
completing the approve handshake. The issuer's \( pk_{\text{issuer}} \)
is not in the commitment (privacy!) but is carried inside the
private witness and decrypted by the recipient from
\( E_{\text{iss-for-rec}} \).
Consequences. Only the holder of the mint-time \( sk_{\text{rec}} \) can deposit (CP-soundness under single-key ElGamal). The issuer cannot spend what she printed unless she herself is the recipient. A-notes are bound to the mint-time key pair: Identity re-issuance to a fresh \( (sk', pk') \) on the same \( M \) does not restore spend capability, because \( E_{\text{note}} \) is under \( pk_{\text{rec}} \) and the fresh \( sk' \) cannot decrypt it. Loss of \( sk_{\text{rec}} \) renders the note unspendable; see "Key-Pair Binding and Loss Semantics" below.
Flavor A1: Addressed Cheque, Public Issuer
Identical to A2 except the issuer additionally publishes her own \( M_{\text{issuer}} \) in the clear, with a Schnorr signature binding it to \( cm \):
\[ \text{payload}^{A1} \;=\; \bigl(E_{\text{note}},\ m_{\text{issuer}},\ \sigma_{\text{issuer}}\bigr) \]
The depositor no longer needs E_iss-for-rec – she reads
\( M_{\text{issuer}} \) directly. No privacy loss for the depositor:
E_depositor_for_issuer still conceals who deposited from casual
observers, because the deposit event is only linkable to a specific
note by someone holding \( \rho \) or scanning the commitment pool
exhaustively.
Public issuers are typically institutional (employers, charities, payroll processors). Their identity is already public; baking it into the note adds audit value without changing any cryptography.
Use cases. Payroll from a named employer to an identified employee, charitable disbursement to an identified grantee, attribution-preserving B2C payment where the customer wants a cryptographic record that a specific merchant paid them.
Flavor B1: Bearer Cheque, Public Issuer
The classic cashier's cheque. The issuer does not know the depositor at mint time; the note is bearer, and whoever shows up first with knowledge of \( \rho \) and a valid registered credential deposits.
\[ \text{payload}^{B1} \;=\; \bigl(m_{\text{issuer}},\ \sigma_{\text{issuer}},\ pk_{\text{issuer}}\bigr) \]
No depositor-side ElGamal is pre-encrypted because no depositor is
known. The depositor reads the issuer's identity in the clear; the
issuer reads the depositor's E_depositor_for_issuer from the
deposit event. Mutual decryptability holds – just entirely via
the public-issuer side at mint, and via the deposit-event payload
at deposit.
Spend. The depositor produces a SNARK proving:
- Merkle inclusion of \( cm = H_{\text{cm}}(\text{flavor},\ v,\ \rho,\ \text{payload}^{B1}) \).
- Nullifier \( nf = H_{\text{nf}}(\text{flavor} \| \rho) \) (publicly derivable from \( \rho \); this is the first-come-first-served property of bearer notes).
- Signature-in-SNARK check: \( \sigma_{\text{issuer}} \) verifies against \( pk_{\text{issuer}} \) in IdentityRegistry.
- Schnorr PoK of \( sk_{\text{dep}} \) for registered
\( pk_{\text{dep}} \), Fiat-Shamir bound to
msg.sender,chainid,nullifier. faceValue\( = v \).
No CP-equality is required – the issuer is public, the depositor
is any registered identity, and the approve handshake completes via
plaintext \( M_{\text{issuer}} \) plus E_depositor_for_issuer.
Consequences. The issuer knows \( \rho \) and therefore can race the intended bearer to deposit. But any such deposit attaches the issuer's identity to the deposit event – so an issuer-turned-thief is identified at the moment of theft. This is a civil-trust problem (the issuer breaks a promise to the bearer), not a cryptographic vulnerability. Same trust model as a paper cashier's cheque: the bank can in principle redirect the draft, and the law stops them.
Comparison of the Three Flavors
| Property | A2 Addressed, private issuer | A1 Addressed, public issuer | B1 Bearer, public issuer |
|---|---|---|---|
| Primary use | Private remittances; self-wormhole | Payroll; charity; B2C attribution | Cashier's cheques; pre-printed bearer |
| Issuer known to observers | No (ElGamal; only depositor decrypts) | Yes (plaintext) | Yes (plaintext) |
| Depositor pre-known at mint | Yes (bakes in recipient's \(M\)) | Yes (bakes in recipient's \(M\)) | No (any registered identity) |
| Spend predicate | CP-equality (Theorem 6) | CP-equality (Theorem 6) | Schnorr PoK + signature-in-SNARK |
| Issuer can spend own note | No (CP fails: different \(M\)) | No (CP fails: different \(M\)) | Yes, but identified on deposit |
| Long-term holding safe | Yes cryptographically; sk_rec required | Yes cryptographically; sk_rec required | Yes cryptographically; civil-trust on issuer |
| Mutual decryptability | \(E_{\text{iss-for-rec}}\) at mint | Plaintext \(M_{\text{iss}}\) at mint | Plaintext \(M_{\text{iss}}\) at mint |
| + \(E_{\text{dep-for-iss}}\) at deposit | + \(E_{\text{dep-for-iss}}\) at deposit | + \(E_{\text{dep-for-iss}}\) at deposit |
The cryptographic taxonomy collapses to two spend-circuit shapes: an A-spend (CP-equality, covering A1 and A2) and a B-spend (Schnorr PoK + \( \rho \), covering B1). The public-vs-private issuer distinction is commitment metadata, not a separate circuit.
A fourth flavor – bearer notes with no identity hook on either side – is intentionally absent; see "What This Architecture Rules Out" below.
The Interaction Matrix: Note Flavor x Depositor Account Mode
The Identity system (Identity) gives registered accounts two visibility modes:
- Anonymous-valid. KYC-verified but Identity encrypted. A
counterparty learns
Monly by completing the bilateralapprovehandshake (or being targeted by a note whose payload pre-completes that handshake). - Public.
Mis published in the clear. No handshake is needed to know who the account belongs to.
Permissionless (unregistered) accounts cannot appear on either side of a BUCK transfer – regular or Note – because the mutual-decryptability invariant requires a registered identity at every endpoint.
Crossing the three valid flavors with the two depositor account
modes produces the six operational cells below. Rows are note
flavors (A1 / A2 / B1); columns are the depositor's account
visibility at deposit time. The issuer's account mode is fixed
by the flavor itself: A2 issuers are anonymous-valid (or the
bearer-issuing contract acting as a pseudo-identity), A1 and B1
issuers are public.
| Flavor | Anonymous-valid depositor | Public depositor |
|---|---|---|
| A2 (private cheque) | Private-to-private addressed cheque | Private-to-public addressed cheque |
| Issuer (anon-valid) targets a specific | Issuer (anon-valid) targets a public | |
| anon-valid recipient. No on-chain link | recipient. Recipient deposits to their | |
between them; both learn the other's M |
public account; observers see only that a | |
| at spend. Self-directed wormhole is the | public identity received a pool note. | |
| degenerate subcase (issuer = recipient). | Use: moving private wealth to a public | |
| Use: remittance, inheritance, B2B payments. | persona; donating to a public charity | |
| without a traceable direct transfer. | ||
| A1 (identified | Public-to-private identified cheque | Public-to-public identified cheque |
| cheque) | Public issuer targets an anon-valid | Both parties public; the note adds /timing |
| recipient. On-chain observers see the | indirection/ over a direct transfer: the |
|
issuer's M plus a deposit from some |
cheque can be pre-signed and held. The | |
| anon-valid account; they cannot link the | issuer is already on-chain; the recipient | |
| account to its real Identity. | may choose among their public accounts at | |
| Use: payroll, B2C payments, audit-friendly | deposit time. | |
| disbursements from a public treasury. | Use: pre-signed instruments, escrow | |
| cash-outs. | ||
| B1 (bearer cheque) | Bearer-to-private | Bearer-to-public |
| Public issuer prints an unaddressed | Same, but depositor is public. Observers | |
| cheque; first registered spender to | see a public identity cashed a B1 draft from | |
| publish \( \rho \) wins. Civil-trust | issuer M. Use: redeeming a bearer |
|
| instrument: theft is not cryptographically | instrument received out-of-band into a | |
| prevented, only bilaterally traceable. | publicly attributable account. | |
| Use: cashier's cheques, physical coupons, | ||
| prize vouchers, out-of-band bearer drafts. |
Observations:
- Wormhole functionality – the private same-identity round-trip is the degenerate subcase of
A2 where issuer and depositor share the same
M. It uses the same mint construction, the same spend circuit, and the same pool; no separate instrument is required. - Cashier's cheques are B1 and are the only flavor where the
recipient identity is not determined at mint time. All other
flavors bind a specific recipient via the re-randomized
E_notepayload. This is also the only flavor exposed to issuer race-condition risk – whoever publishes the nullifier \( \rho \) first takes the value. - Public-to-public A1 cells are degenerate in information
content: a direct
transfercarries the same on-chain signal. Their utility is operational (pre-signing, mailing, delayed destination choice), not privacy-structural. - Issuer and depositor account modes are chosen independently, subject only to the flavor's constraint on the issuer side (A2 = private issuer; A1/B1 = public issuer). The depositor's mode affects only what the on-chain observer sees at deposit, never what the counterparties see of each other.
- The B2 cell (private issuer + bearer) does not exist. A
private issuer must re-randomize for a specific recipient's
pk_recso both parties can decrypt each other'sM; there is no recipient to key against in a bearer construction. Attempting a "private bearer" instrument violates the BUCK mutual-decryptability invariant.
Integration with On-Chain Transfers
Notes are not a separate payment system. They are an alternative
framing of a BUCK transfer in which the approve handshake is
mediated asynchronously through the pool instead of being settled
synchronously between two accounts. Everything that is true of a
regular transfer – demurrage accounting, Jubilee conservation,
sanctioned-account blocks, fee and gas mechanics – is also true
of a Note mint or deposit, because both sides of a Note's
lifecycle are regular ERC-20 transfers against the pool's own
account.
The Pool is a Regular Account
The Notes contract's own address is a registered account in the
ordinary sense (system-public in IdentityRegistry). BUCKs flowing
in (mints, donations) is a standard incoming transfer; BUCKs
flowing out (spends) uses transferCarrying. The only
contract-local state not already tracked by the BUCK ledger is the
Merkle-tree root history (roots[], nextLeafIndex), the
nullifier set (nullifiers), and noteFaceSum (aggregate live
face value – an audit scalar, not a liability figure).
Regular Transfer vs. A-Flavor Note
A regular transfer(alice, bob, v) followed (or preceded) by
approve(alice, bob) has the following on-chain signature:
- Alice's account:
facedebited from her balance, plus her accumulated fee burned and_indexAtLastTouch[alice]reset tocumIndex_now. - Bob's account: balance credited by
face, his_indexAtLastTouchweighted-merged towardcumIndex_now. - Edge observable: Alice –> Bob, amount
face, block \( t \).
The A-flavor Note equivalent (A2 between two anon-valid accounts):
- Alice mints: standard ERC-20 transfer of
totalFaceto the Notes contract. Alice pays her own outgoing-transfer fee and resets her index, exactly as in a regular transfer. The pool's balance gainstotalFace; its index weighted-merges forward. - Bob spends at time \( t + \Delta \): the pool's
transferCarryingdeliversfaceto Bob and weighted-merges the pool's stale_indexAtLastTouchinto Bob's index. Bob now bears the pool's averaged demurrage on the inflowing share of his balance. - Edge observable: Alice –> pool at \( t \); pool –> Bob at \( t + \Delta \). The edge connecting them is erased.
Economic outcomes match a regular transfer up to the timing difference: Bob acquires the pool's averaged BUCK-age on the inflow, regardless of how long Bob's specific commitment sat in the tree. This is the key property that makes indefinite holding of A-flavor Notes economically equivalent to holding BUCK – same demurrage rate (averaged over the pool), just with a different edge visible on chain.
Regular Transfer vs. B-Flavor Note
A B1 cashier's cheque replaces the bilateral approve with a
public-issuer signature binding the note to a specific
\( M_{\text{issuer}} \) and leaves the depositor unspecified:
- Issuer mints:
transferfrom issuer to pool. The issuer's \( m_{\text{issuer}} \) is bound into the commitment via the Schnorr signature. - First registered holder to publish \( \rho \) deposits: pool –> depositor at some later time.
- The depositor and issuer end up mutually identified (per the BUCK invariant) through the note's commitment payload plus the on-chain deposit actor; no third party sees the edge.
A B1 Note is the natural digital analogue of a cashier's cheque drawn on a bank: the bank (public issuer) has pre-committed the funds; whoever presents the instrument redeems them.
When to Use Which
| Scenario | Use | Why |
|---|---|---|
| Two parties already mutually approved | transfer |
Simpler, one on-chain call, no SNARK cost |
| Payer wants no on-chain edge to recipient | A2 | Breaks bulk-harvest trace; same demurrage |
| Public issuer paying a specific recipient | A1 | Auditable issuance, recipient visibility hidden |
| Pre-signed instrument, recipient undecided | B1 | Bearer; cash on presentation |
| Self-wormhole across own accounts | A2 (issuer = recipient) | Breaks the edge between own addresses |
| Payroll to many private employees | A1 per employee, or A2 | A1 when attribution required, A2 otherwise |
| One-off payment under surveillance concern | A2 | Cheapest way to erase the direct edge |
Cost and UX Trade-Offs
Relative to a regular transfer, every Note costs additional
gas for the SNARK verifier (mint or spend) and requires wallet
software capable of producing the proof. For routine payments
between counterparties who do not need to defeat chain
analytics, a regular transfer is strictly cheaper and simpler.
Notes are the correct tool when the privacy property – no
on-chain edge between payer and recipient – is worth the
additional gas and proving time, or when the instrument
semantics (deferred recipient choice, pre-signed cheque, paper
distribution) are themselves the point.
Composability
Notes compose transparently with the rest of BUCK:
- Identity Fountain re-issuance applies to Note mints and deposits identically to regular transfers. A-flavor notes do not benefit from re-issuance recovery: they are bound to the recipient's mint-time \( sk_{\text{rec}} \) via single-key ElGamal, so a fresh keypair cannot decrypt an \( E_{\text{note}} \) printed against the previous \( pk_{\text{rec}} \).
- Sanctions and Jubilee operate at the account level and reach the pool through its own account state, requiring no Notes-specific logic.
- Demurrage is accounted on each
B_X, A_Xpair including the pool's; pool-rate demurrage is a consequence of this accounting, not a parallel mechanism. - Wallet UX can expose Notes as an alternative
sendmode in the same UI flow that callstransfer; the difference between "direct send" and "private send" becomes a single toggle.
Demurrage at the Pool Level
The central simplification of this design: the Note Pool is just a regular BUCK account. Specifically, it is the BUCK ERC-20 contract's own balance. BUCKs transferred to the contract's address join the pool; BUCKs transferred out (as note redemptions) leave the pool. The contract account accumulates BUCK-age like every other account and participates in the ordinary demurrage accounting with no special-case code. The only piece of additional state is a single scalar \( F \), the sum of face values of live notes.
Reminder: How BUCK Demurrage Actually Works
BUCK accounts no longer carry an explicit BUCK-age \( A_X \) state.
The implementation uses a global cumulative index, cumIndex,
that grows at a fixed rate BASE_RATE_PER_SEC per second; each
account stores only one extra scalar, _indexAtLastTouch[X], the
value of cumIndex at the account's most recent settlement.
The fee owed by account \( X \) at any moment is
\[
\text{feeOwing}(X) \;=\; B_X \cdot \frac{\text{cumIndex}_{\text{now}} - \text{idx}_X}{\text{SCALE}},
\]
i.e. the account's nominal balance times the slice of cumIndex
accumulated since it last touched. This is mathematically
equivalent to the older \( \kappa A_X \) formulation – BUCK-age
\( A_X = B_X \cdot (\text{cumIndex}_{\text{now}} - \text{idx}_X)/(\text{rate} \cdot \text{SCALE}) \) –
but stores nothing per-account beyond a single index value.
On a standard ERC-20 transfer the sender's accumulated fee is
first burned (its outgoing balance is reduced and totalSupply
drops), the sender's idx resets to cumIndex, and the recipient's
idx is weighted-merged toward cumIndex – the recipient
receives clean BUCK with no inherited age and pays no fee.
Once per touch, the contract also "accrues the Jubilee": the gap
between the Jubilee's required balance (its own accumulated
cumIndex slice times totalSupply) and its actual balance is
minted into the Jubilee account, and its idx is weighted-merged
forward. This keeps the system-wide invariant
\[ \sum_{\text{all accounts } X} B_X \;=\; \text{totalSupply (incl. Jubilee)} \]
automatically preserved across every transfer.
The Pool Account's Demurrage
The Notes pool is an ordinary BUCK account (the Notes contract's own ERC-20 balance). Its demurrage state is therefore exactly two numbers maintained by the BUCK ledger:
- \( B \) =
balanceOf(notes)– BUCK transferred in via mint and donations, minus BUCK transferred out via spend. - \( \text{idx}_{\text{pool}} \) =
_indexAtLastTouch[address(notes)], thecumIndexsnapshot at the pool's most recent touch.
The pool's effective fee-owed at this moment is
\( B \cdot (\text{cumIndex}_{\text{now}} - \text{idx}_{\text{pool}})/\text{SCALE} \).
The Notes contract never reads or writes either value: it lives
inside the BUCK ledger just like every other account. Mints
weighted-merge idx_pool toward the new cumIndex; spends use
the carrying primitive defined next.
The Age-Preserving Redemption
When a note of face \( v \) is spent, the Notes contract calls the
single new BUCK primitive transferCarrying(recipient, v). Unlike
the standard ERC-20 transfer, transferCarrying does not burn
any sender-side fee: the pool's index is left untouched, the full
face value lands in the recipient, and the recipient's
_indexAtLastTouch is weighted-merged toward the pool's index
(which is older than cumIndex_now, hence carries fee owed):
br = balanceOf(recipient) // before transfer
idxFrom = _indexAtLastTouch[pool] // pool's stale index
_indexAtLastTouch[recipient]
= (br * _indexAtLastTouch[recipient] + v * idxFrom)
/ (br + v)
_update(pool, recipient, v) // ordinary balance move
The pool's _indexAtLastTouch is not disturbed – successive
spends from the pool draw against the same shared index, so each
recipient inherits the same per-BUCK age share as long as the pool
keeps minting and spending without an intervening standard
transfer.
The recipient's combined index after the merge corresponds to a
weighted average of the two BUCK-ages: the recipient's prior
holding ages from its prior idx, and the freshly received \( v \)
BUCK ages from the pool's idx. When the recipient next makes a
standard outgoing transfer they pay the (combined) fee out of their
balance, exactly as if they had personally held \( v \) BUCK across
the pool's residence period.
This is the cost of anonymity: the recipient inherits the average pool BUCK-age, which is a net benefit for any note that has been held longer than the pool's average age, and a net cost for notes spent quickly into the pool. In practice, fast-circulating notes subsidise slow ones.
Donations Integrate Smoothly
Any BUCK transferred to the Notes contract without minting a
corresponding note arrives via a standard ERC-20 transfer, which
weighted-merges the pool's _indexAtLastTouch toward the current
cumIndex (i.e. forward in time). The pool's per-BUCK fee owed
drops; subsequent transferCarrying spends therefore deliver
recipients an index closer to cumIndex_now, meaning a smaller
inherited fee-share per face unit. Over a sequence of spends, the
donation is consumed as a demurrage subsidy for live noteholders.
Four origin cases, all handled identically:
- Accidental transfers. A user fat-fingers the Notes contract
as a recipient. Their BUCK is not burned; it freshens
idx_pool, and future redeemers inherit marginally less fee. - Philanthropic donations. A user deliberately sends BUCK to
the pool to subsidise noteholders. The subsidy spreads across
all future redemptions until
idx_poolstaleness rebuilds. - Recovered collateral. Mechanism-level refunds (e.g., an issuer's collateral unlock) sent to the pool address.
- Rounding / dust. Integer-arithmetic residuals. Self-healing.
After all notes are eventually spent, any remaining donation
principal sits at noteFaceSum = 0, balanceOf(notes) > 0 –
unclaimable by spend, but available to subsidise a fresh round of
mints if the pool is used again, or recoverable by governance
sweep (per Notes contract policy).
Conservation is Automatic, and Tight
transferCarrying conserves the pool's and recipient's nominal
balances exactly:
- \( \Delta B_{\text{pool}} + \Delta B_{\text{recipient}} = 0 \).
No fee is burned, no totalSupply movement happens; the
recipient's idx weighted-merge is pure bookkeeping. The next
time the recipient makes a standard transfer, the inherited
fee-share will be paid out of their balance and into the Jubilee
via the ordinary BUCK accounting path.
Globally, the system-wide invariant
\( \sum_X B_X = \text{totalSupply (incl. Jubilee)} \) holds across
every transfer (carrying or standard) by construction. The
Jubilee's required-balance growth is independent of how BUCK is
distributed between accounts; it depends only on cumIndex and
totalSupply. No pool-specific conservation theorem is required.
Numeric Example
Suppose the pool holds \( B = 10\,000\,000 \) BUCK and was last
touched 0.5 yr ago, so the pool's idx_pool lags cumIndex_now
by an amount corresponding to a 1% fee owed (the BUCK base
demurrage rate is 2% per year). The pool currently owes the
Jubilee \( 100\,000 \) BUCK against its \( 10\,000\,000 \) face.
Alice spends a note of face \( v = 1{,}000 \):
- Alice's BUCK balance rises by exactly 1,000.
- Alice's
_indexAtLastTouchweighted-merges towardidx_pool: if she previously held 0 BUCK, her index is set toidx_pooldirectly (1% of fee per BUCK is now attached to her); if she previously held 9,000 BUCK atcumIndex_now, the merge yields an index close tocumIndex_now(only 0.1% of fee per BUCK across her now-10,000 balance). - When Alice next makes a standard outgoing transfer of \( v \),
her accumulated fee on the proportional share is burned out of
her balance and credited to
totalSupplysuch that the Jubilee can mint into balance. Net: she receives 1,000 face value, pays up to \( 1\% \times 1{,}000 = 10 \) BUCK as demurrage when she next spends – same economic outcome as if she had personally held the BUCK during the pool's residency.
Now suppose an anonymous donor sends 500,000 BUCK to the pool via
a standard transfer. idx_pool weighted-merges forward toward
cumIndex_now; the per-BUCK fee owed by the pool drops. Alice's
next spend now inherits a smaller index-gap and therefore pays
less demurrage on her next outgoing transfer – a direct subsidy
from the donor.
The Jubilee's growth schedule is unchanged: it keeps accruing
relative to cumIndex \cdot totalSupply regardless of how BUCK
sloshes between accounts.
Who Bears the Demurrage, Really
The answer is sharply localized: *the Note recipient inherits the pool's accumulated demurrage share on the face value they received and pays it on their next standard outgoing transfer.* The recipient has accepted the note, and with it the demurrage cost of the BUCK sitting in the pool while the note was outstanding.
This is the "price" the recipient pays for accepting a BUCK Note
instead of a direct BUCK transfer: they inherit the average
pool-residence demurrage, weighted across their prior holding.
For notes held longer than the pool's average residence, this is
cheaper than holding the BUCK directly; for notes spent quickly
into the pool, it is more expensive. The trade-off is explicit
in the resulting _indexAtLastTouch on the recipient's account.
Noteholders (while holding) bear no demurrage: they hold a cryptographic commitment, not a BUCK balance, and the BUCK they implicitly own sits in the pool where its accumulated fee is borne collectively until spent. The issuer (at mint time) pays their own outgoing-transfer fee through the standard ERC-20 path to deposit into the pool. Third parties bear nothing. The Jubilee keeps receiving the BUCK-wide demurrage stream regardless of how BUCK sloshes between accounts.
Demurrage Solves the Lost-Cash Problem
This section is about a property that is genuinely novel, with implications well beyond the BUCK system.
The Hidden Inflation of Lost Cash
Every monetary system that uses physical bearer instruments suffers a constant slow loss to unrecoverable currency. Banknotes are lost in fires, dropped down storm drains, forgotten in the pockets of jeans that get washed and shredded, buried in landfills, sealed in walls, hidden by the elderly and forgotten by their heirs.
The Federal Reserve estimates that 5-10% of US paper currency is permanently unrecoverable at any given moment.12 At a US M0 of approximately $2.3 trillion, this represents /$115-230 billion in permanently extracted value/ – seigniorage to the Federal Reserve, since the lost notes never get redeemed but the backing assets remain on the Fed's books.
This is not theft, but it is not neutral either. Lost cash is a regressive transfer: the people most likely to lose cash are the people who use cash most (the elderly, the unbanked, low-income workers paid in cash). The beneficiary is whoever issued the cash, generally the central bank, ultimately the government.
What BUCK Demurrage Does For Lost Notes
A BUCK Note that is lost in a fire, dropped down a storm drain, or
hidden in a wall by a paranoid grandparent is not permanently
extracted from the system. The face value sits in the pool's
ERC-20 balance, with the pool's _indexAtLastTouch drifting
further behind cumIndex_now as the pool sits untouched. No
spend ever happens.
Two effects balance:
- The BUCK backing the lost note stays in the pool indefinitely. It does not vanish.
- Other live-note spenders, through
transferCarrying, inherit a share of the pool's stale index at each spend. Because the lost note's backing weighs onbalanceOf(notes)without a corresponding spend to drain it, the lost-note's implicit demurrage is paid installment-style by subsequent spenders on their next outgoing transfer.
Over decades, the pool's index-gap (cumIndex_now - idx_pool) on
the lost-note backing accumulates the demurrage that would have
been owed had the BUCK been held in a regular account. The
autonomous Jubilee growth continues regardless. Net effect: /the
5-10% of currency that physical cash systems lose forever, BUCK
Notes returns to the commons within a generation/, via the steady
demurrage pressure that the lost face value applies to live
spenders inheriting the pool's stale index.
This has cascading consequences:
- Money supply self-correction. No system-wide accounting tail of "missing" currency that the central authority must track and write off. Lost notes write themselves off through the pool-age mechanism.
- Anti-hoarding incentive matches on-chain balances. A BUCK held in your wallet or in your pocket as paper decays at the same rate (via the age-share that will eventually be absorbed on redemption). There is no advantage to converting on-chain BUCK to paper to evade demurrage; the demurrage clock runs the same way in both forms.
- Inheritance is automatic. A grandparent who hides 100,000 BUCK in paper notes and forgets to tell anyone does not extract 100,000 BUCK from the economy on their death. The value flows back through the Jubilee to BUCK issuers – broadly, back into the same economy where the grandparent originally earned it.
- No central bank profit from currency loss. The seigniorage that accrues to central banks today from unrecoverable cash does not exist in BUCK Notes. Lost value does not benefit the issuer; it benefits the system as a whole.
- Counterfeit recovery is automatic. Even if a note printed years ago were somehow forged (which is cryptographically impossible, but humour the counterfactual), the value at stake is bounded by the demurrage decay. An attacker forging old notes would be forging paper whose backing BUCK has already been largely absorbed by live redemptions.
This is, I believe, the first monetary system in history where lost cash returns to the commons by automatic mechanism rather than by accounting fiat. Physical cash cannot have this property, because physical cash has no clock. It emerges naturally from BUCK's existing demurrage mechanism applied to the note-pool primitive.
The Symmetry With On-Chain Balances
A second elegance worth pointing out: the effective demurrage rate on a BUCK Note – as absorbed by the recipient at deposit – is the same as the demurrage rate on an on-chain BUCK balance that lived in the pool for the same duration. This is by design, and it matters.
If paper BUCK Notes demurraged faster than on-chain BUCK, holders would prefer on-chain (and paper would be discouraged, defeating the design's purpose). If on-chain BUCK demurraged faster than paper notes, holders would race to print all their on-chain balances as physical notes (and the chain would lose its primary use as a settlement layer).
The matching demurrage rate makes the choice between on-chain and paper purely about use case fit: on-chain for routine commerce, automated payments, large transactions; paper for offline payments, gifts, savings under the mattress, disaster preparedness, and so on. Neither form is privileged by the demurrage mechanism.
Long-Term Holding Safety: Addressed vs. Bearer
Pool-rate demurrage makes every flavor equally cheap to hold.
What distinguishes them for long-term storage is whether the spend
predicate binds a specific recipient Identity M_rec or accepts
any registered depositor. Addressed notes (A1, A2) are
cryptographically safe for indefinite holding; bearer notes (B1)
are civil-trust instruments and should be cashed promptly.
What the Issuer Knows
At mint time the issuer holds the full commitment preimage \( (v, \rho, \text{id-payload}, \text{predicate}) \) including any randomness \( r' \) it generated to re-randomize the recipient's encrypted Identity. The question is whether that knowledge, by itself or combined with any later-acquired secret, lets anyone other than the intended recipient spend the note.
A-Flavors (Addressed): Cryptographically Safe
Both A1 and A2 bind a specific recipient at mint time. The note carries the re-randomized ElGamal ciphertext \( E_{\text{note}} = (R_r + r'\cdot G,\; C_r + r'\cdot pk_{\text{rec}}) \) of \( M_{\text{rec}} \) under the recipient's pubkey. The A-spend predicate is a Chaum-Pedersen proof of equality (Theorem 6) that the depositor's registered credential decrypts to the same \( M_{\text{rec}} \) that \( E_{\text{note}} \) encrypts.
The consequence is that no amount of mint-time knowledge helps a non-recipient spend:
- The issuer knows \( r' \) and can re-derive \( E_{\text{note}} \), but cannot produce a CP-equality proof without a registered credential encrypting \( M_{\text{rec}} \).
- An attacker who copies \( \rho \) cannot spend either; the pool contract binds \( \rho \) to the recipient's side of the equality.
A1 and A2 differ only in whether \( M_{\text{issuer}} \) is on-chain in the clear (A1) or encrypted for the recipient (A2). Neither affects who can spend.
Key-Pair Binding and Loss Semantics
A-flavor notes are bound at mint time to a specific \( pk_{\text{rec}} \) – the recipient's registered public key at the moment the issuer re-randomized \( E_r \rightarrow E_{\text{note}} \). The A-spend circuit decrypts \( E_{\text{note}} \) using a witness \( sk_{\text{dep}} \) and the same single witness also decrypts the depositor's currently-registered credential \( E_{\text{dep}}^{(\text{reg})} \). CP-equality between the two decryptions is therefore only satisfiable when \( pk_{\text{rec}} = pk_{\text{dep}} \), i.e. the depositor is registered under the same public key that the issuer used at mint.
BUCK Identity re-issuance does not recover A-notes. The
Identity Fountain allows a user to re-issue their Identity scalar
on a fresh signing keypair \( (sk', pk') \) bound to the same
\( M \). Re-issuance revokes the previous credential
(identity.org, Attack 7): subsequent isVerified calls against
the old entry return false, and A-spend references to the old
depositorRegistryEntry are rejected at the contract boundary
before the circuit runs. Pointing depositorRegistryEntry at
the new entry admits \( sk' \) as the witness, but \( sk' \) does
not decrypt \( E_{\text{note}} \) to \( M \) (the ciphertext is
under the old \( pk_{\text{rec}} \)), so CP-equality fails
in-circuit. In either case the spend proof cannot be produced.
The operational consequence: loss of \( sk_{\text{rec}} \) is terminal for any A-note minted to that credential. This is the same property that governs any ElGamal-encrypted payload under the recipient's key; Notes inherits it directly.
Cold-storage and long-hold implications. A-notes – especially
A2 notes directed to the recipient themselves (the wormhole)
and A1/A2 notes directed to an heir's M (estate planning) –
place a hard key-management obligation on the recipient (or the
designated heir): the mint-time \( sk_{\text{rec}} \) must be
preserved for the full holding period. Proactive key rotation
requires either (a) spending the note first and re-minting under
the new key, or (b) maintaining the old \( sk_{\text{rec}} \) in
cold storage alongside the note itself until all notes bound to
that key have been redeemed. Cryptographic loss of M – the
failure mode the Identity Fountain does recover from, via a
re-attestation on the same scalar – is a separate event from
loss of a note-binding \( sk_{\text{rec}} \), and re-issuance
only addresses the former.
Comparison to cash. Physical cash held in a safe and lost through fire or theft is irrecoverable by its bearer instrument-owner. A-notes under lost \( sk_{\text{rec}} \) have the same property: the holder has irrevocably lost the bearer capability. The BUCK-system-level recovery mechanism is demurrage – unspent BUCK eventually returns to the pool, so economically lost A-notes rejoin the circulating supply over time.
Status (current implementation). The shipped spend.circom
is B-shape only; Phase 8 V2 ships spend_a.circom as the
A-flavor companion via two cooperating components – a SNARK and
an off-chain identity check – glued by Notes.spendACP:
- In-circuit (
spend_a.circomV2): enforces the A-tag nullifier (Poseidon-3 with tag 4243), the flavor-in-{1,2} gate, the Merkle membership proof, and the new binding constraintPoseidon-8(eN.R, eN.C, issuerData[0..3]) === idHash. The Poseidon-8 gate makesE_na public input and binds the publicly-revealed note ciphertextE_n = (R_n, C_n)to the leaf at mint time, so the on-chain identity verifier cannot be played against a substituted ciphertext. - Off-chain (
IdentityRegistry.verifySpendCP): the spender provides a 4-element Chaum-Pedersen DLEQ proof(e, s, T1, T2)showing that their wallet'ssk_depdecrypts bothE_addr[spender]andE_nto the same identity pointM. Verified by Solidity using the EIP-196 BN254 precompiles (~36K gas: 2 ecMul + 2 ecAdd + keccak FS).Notes.spendACPcallsidentityRegistry.verifySpendCP(msg.sender, recipient, E_n, cpProof)after the SNARK verifier passes; both must succeed.
The DLEQ statement was relegated off-chain because its native
BN254 G1 arithmetic would have cost ~+250K R1CS in non-native
circom – prohibitively expensive in-circuit – whereas the
EIP-196 precompiles do the same job in a single transaction at
~36K gas. The Poseidon-8 binding constraint inside the SNARK
(~265 R1CS) is what closes the loop: it forces the spender to
reveal the same E_n the credential was minted against, so a
spender who substitutes a different ciphertext (in order to
satisfy a CP-DLEQ they can satisfy with their own key) fails the
in-circuit check. All identity, security, and privacy
properties enumerated above – including the Theorem 10.1
invariant (re-issuance does not recover A-notes) – are
preserved. See alberta-buck-ethereum.org
Phase 8 for the implementation split.
B1 (Bearer): Civil-Trust, Not Cryptographic
The B-spend predicate is a Schnorr PoK of knowledge of \( \rho \) plus any valid registered depositor credential. There is no recipient binding: whoever publishes the nullifier first wins the deposit. The issuer, having minted the note, knows \( \rho \); so does anyone who later observes \( \rho \) – including anyone the issuer accidentally leaks it to (database row, printed backup, compromised signing device) and anyone who photographs an unsealed physical cheque.
This is not a cryptographic failure; it is the point of a bearer instrument. The B1 flavor replaces cryptographic recipient binding with civil-law recourse:
- The issuer's Identity \( M_{\text{issuer}} \) is public on the note. An issuer who prints a cheque and then races to deposit it is visibly on chain as the double-spender. The registered Identity is subpoena-able and the issuer cannot repudiate having printed the note.
- A holder who discovers their B1 has been cashed by someone else has a named counterparty to pursue in civil or criminal court. The chain proves who deposited; the note's commitment and signature prove who issued it.
The practical rule: treat B1 like a cashier's cheque. Cash within hours to days. Use only issuers whose operational discipline and legal standing you are willing to rely on. Do not use B1 for long-term savings, inheritance, or cold storage; addressed A1 or A2 instruments serve those needs with cryptographic rather than institutional trust.
Summary: Which Flavors Can Be Saved?
| Flavor | Can a non-recipient spend? | Long-term holding safe? | Comparable instrument |
|---|---|---|---|
| A1 | No (CP-equality on \( M \)) | Yes | Registered bond / named cheque |
| A2 | No (CP-equality on \( M \)) | Yes | Named bond, self-wormhole |
| B1 | Yes (anyone who knows \( \rho \)) | No | Cashier's cheque / bearer bond |
The consequence: /addressed (A) notes are cryptographically safe to hold; bearer (B1) notes rely on issuer operational discipline and civil recourse./ Placing an A1 or A2 cheque in cold storage for a decade trusts only the cryptography and the recipient's Identity recovery capability. Placing a B1 in the same vault trusts the issuer not to retain \( \rho \) for ten years.
Mapping to use cases:
- Long-term savings, cold storage, self-wormhole: A2 (you are the recipient).
- Estate, inheritance, named gifts: A1 or A2 – A1 when the recipient and heirs want public attribution of the issuer; A2 when discretion is preferred.
- Payroll, B2C disbursements, audit-visible transfers: A1, cashed at the recipient's pace.
- Bearer instruments – cashier's cheques, physical coupons, prize vouchers: B1, cashed promptly.
Physical Security Model
The cryptography only protects what the cryptography touches. The physical paper itself needs a security model. This section sketches one.
Layered Defense
A printed BUCK Note has three concentric layers of security:
| Layer | What it protects | Mechanism |
|---|---|---|
| Inner: secret | The cryptographic ability to spend | QR code containing \( \rho \) |
| Middle: physical seal | Bearer (B1) publication-exclusivity | Hologram, scratch-off, laminate sleeve |
| Outer: identity binding | Addressed (A1/A2) targeting (only named spender) | CP-equality on the recipient's re-randomized ElGamal credential |
The inner layer is the cryptographic core: as long as \( \rho \) (and
the flavor-specific material packed into id-payload) is unknown, the
note cannot be spent. This is unconditional protection against any
threat that does not include observing those secrets.
The middle layer matters only for bearer B1 notes, where the spend predicate is "any registered holder of \( \rho \)." An unsealed B1 QR photographed by any observer allows that observer to race to spend. Sealing the QR under a tamper-evident covering means the note can be displayed (passed hand-to-hand, stored in a wallet, mailed in an envelope) without exposure. The seal must visibly damage on opening so that recipients can verify they were the first to expose the secret. (This does not rescue B1 from the issuer-race risk – the issuer who printed the note could still have retained \( \rho \) before sealing – which is why B1 remains unsafe for long-term holding. The seal addresses post-printing observation, not issuer trust.)
The outer layer makes addressed A1/A2 notes safe to publicly
distribute. An addressed note can be photographed with no security
implication: the photographer cannot spend it without also holding a
registered credential encrypting the bound M_rec. The targeting
binding is cryptographic, not physical. For addressed flavors, no
physical seal is required.
Recommended Manufacturing Profile
A practical BUCK Note specification, suitable for industrial-scale printing:
- Substrate. Cotton-blend banknote paper or polymer (Bank of Canada-style). Steel or titanium plates for high-denomination "permanent" notes.
- Printing. Standard inkjet or laser printing of QR codes is sufficient for cryptographic correctness. For visual anti-confusion (so people can tell a legitimate note from a printout), use UV-reactive ink, microprinting, or watermarks – the same techniques used for traditional banknotes. These do not add cryptographic security; they add reassurance.
- Seal. Peelable hologram covering the secret QR (bearer B1 only), or scratch-off panel covering a separate code (also B1), or no seal at all (addressed A1/A2, since the cryptography handles exclusivity).
- Redundancy. Print the QR twice (front and back) with Reed-Solomon error correction. A note that loses one QR to wear or damage can still be deposited via the second. For higher-value notes, also print the secret as base32 digits in human-readable form.
- Issuer mark. A non-cryptographic logo identifying the issuer (the Alberta Buck reserve, a credit union, a commercial issuer). This is for visual recognition only; the cryptographic authenticity check is the on-chain commitment.
- Denomination indication. Visible face value for human convenience. The actual value is what the on-chain commitment encodes; the printed face value is metadata. A wallet app that scans an apparent 1,000 BUCK note and reads "actual value: 100 BUCK" from the commitment warns the user before deposit.
Use Cases
The same primitive serves a spectrum of use cases that today require entirely separate financial instruments. Each maps to one of the three realisable flavors (A1, A2, B1) according to whether recipient binding and public issuer attribution are required.
Walking-Around Money
For digital "send at the moment of payment," an A2 note targeted to
the payee's registered M is ideal: the recipient receives a
message-note that only they can deposit, and the issuer's Identity
is exchanged bilaterally through the commitment payload without any
on-chain edge. For truly paper bearer cash – a note that anyone
who holds the paper can spend – a B1 cheque with hologram seal
fills the role, issued by a trusted public party (credit union,
commercial issuer) who publicly warrants erasure of \( \rho \) after
printing.
Most walking-around use cases – paying for a coffee, tipping, splitting a bill with a friend – are better served by A2 message notes exchanged at the moment of payment. The paper B1 form is the right choice when one party has no digital wallet at hand or when strict bearer-on-paper semantics are required. If you are going somewhere that would be best to avoid taking your phone, or just because you want to retain complete anonymity, such a note might be appropriate.
Notes always yield the current pool demurrage rate, so neither encourage nor discourage rapid circulation rather than hoarding. The wallet-app status codes give immediate VALID / DEAD / FAKE feedback on scan. These public issuer / any depositor Notes always bear some non-zero risk of theft or an untrustworthy issuer who retained a copy of the note, so should be deposited promptly.
Cross-Border Remittances
A paper BUCK Note is just paper. It crosses borders in pockets,
envelopes, and parcels at zero marginal cost. An A2 note targeted
to the recipient's registered M makes the transfer useless to
anyone except the intended recipient, so loss in transit is not a
financial risk.
This compares favorably to the existing remittance industry, which extracts roughly 6.5% in fees globally on $700+ billion in annual transfers.13 A paper-note remittance has a fixed cost: print
- mail. The mail might cost $1; print costs fractions of a cent;
deposit gas costs a few dollars at most. At any reasonable remittance value, the fee compression is enormous.
The recipient does not need a smartphone or internet at the moment of receipt – they need them only at the moment they want to convert the note to on-chain BUCK or to local fiat. In countries with intermittent connectivity, this is a major usability improvement over digital remittance services.
Tip Jars and Charitable Donations
A sheet of small-denomination B1 bearer notes, perforated for tear-off, can be left next to a tip jar or a donation box. Patrons take notes (denominated at, say, 2 BUCK each), scan them with their phone, and the value flows to the jar's registered identity.
This works without any intermediary, payment processor fee, or opening of an account. The patron pays in paper; the recipient receives in on-chain BUCK. B1 is appropriate here because the turnaround is fast: the jar's operator empties the day's receipts to their main account nightly.
Cold Storage and Disaster Preparedness
An A2 self-issued note (issuer = recipient, both the same
registered M), stored in a fireproof safe, is a more durable form
of cold storage than a 12-word seed phrase. The note is
self-evidently an instrument of value – a customs officer, a
relative, or your future self immediately recognizes a paper labeled
"1,000 BUCK Note" as something worth keeping safe. A seed phrase,
by contrast, is opaque to anyone who has not been trained to
recognize it.
For disaster preparedness: a small folder of BUCK Notes in a fireproof safe survives infrastructure failures that would render exchange accounts and even hardware wallets unusable. As long as the chain is reachable somewhere in the world, the notes can be deposited. In a true grid-down emergency, the notes circulate hand-to-hand at face value (with the matching pool-rate demurrage clock running uniformly, so prices remain stable in BUCK terms even during a multi-week outage).
A2 (issuer = recipient) is the correct choice for self-directed
cold storage; A2 or A1 targeted to a designated heir's M is the
correct choice for estate-directed cold storage. The cold-storage
bundle must include both the note opening and the mint-time
\( sk_{\text{rec}} \): A-notes are bound to the specific key pair
used at mint and are unspendable under Identity re-issuance alone
(see "Key-Pair Binding and Loss Semantics" above). Practically,
this means the safe-deposit box or heir-accessible vault holds a
sealed record of both the commitment opening and the private key
material that decrypts \( E_{\text{note}} \).
Estate Planning
A2 notes targeted to your heir's registered M, stored in a
safe-deposit box: zero probate process, zero tax-event delay,
zero court intervention. The heir scans on your death, deposits,
the BUCK is theirs. A1 is the same instrument with the issuer
publicly attributable – appropriate where the heir or executors
need the origin on-chain for tax or legal reasons.
For larger estates, additional conditional-spend predicates (time
locks, death-certificate oracle attestation) can be composed into
the commitment's predicate field. The SNARK does not care what
the predicate is as long as it is well-defined at mint time.
Gift Cards Without Issuer Risk
A traditional gift card carries the risk that the issuing merchant goes bankrupt between purchase and redemption (cumulative consumer losses to bankrupt gift-card issuers run into the hundreds of millions annually in North America14). An addressed A1 or A2 BUCK Note carries no issuer risk: the value is on chain in the BUCK reserve, not on the merchant's books.
Specialized merchant gift cards become unnecessary – replaced by BUCK Notes of appropriate denomination, optionally bundled with a paper merchant receipt indicating the intended use.
Tax-Compliant Compensation
An employer paying a contractor in BUCK Notes faces the same tax-reporting obligations as paying in cash: payment is income and must be reported. The on-chain issuance trail makes this easier to comply with than paper cash, not harder – the employer's mint transaction is an auditable record of the payment, even though the contractor's deposit is private.
For employees: employers can issue A1 notes targeted to each employee's registered Identity, automating payroll while preserving employee privacy from external observers.
Underbanked and Cash-Economy Inclusion
This is, perhaps, the most important use case.
The Bank of Canada estimates 1-2% of Canadians are unbanked, with rates an order of magnitude higher in rural and Indigenous communities.15 Globally the World Bank estimates 1.4 billion adults are unbanked.16
For these populations, paper cash is not a privacy preference; it is the only viable financial instrument. A digital-only currency (CBDC, stablecoin, traditional e-payment) excludes them by definition. BUCK Notes includes them: a person without a bank account, without a smartphone, without literacy in the local language, can hold and transfer BUCK Notes by physical handover, exactly as they hold and transfer paper currency today.
When and if they choose to interact with the digital economy, they deposit a note and the value moves on chain. Until then, they participate in the BUCK economy on exactly the terms they participate in the cash economy. The issuer of the paper – a credit union, a reserve-backed issuer like ATB, or a local community organisation – takes on the role that the central bank currently plays for physical fiat, while the recipient retains the anonymity of a cash user.
Privacy: Defeating Mass Harvest, Preserving Bilateral Disclosure
BUCK Notes do not make transactions anonymous. They do not hide
who paid whom from the parties themselves: the mutual-decryptability
invariant means the issuer and the eventual depositor always learn
each other's M. They also do not hide a specific transaction from
a properly targeted investigation: a warrant served on either named
party to a Note compels disclosure of the counterparty's M and
the surrounding payments.
What Notes do is break the on-chain bulk-harvest channel. Aggregate transfer graphs, KYC-provider subpoenas scoped across thousands of clients, and commercial chain-analytics fingerprinting all operate by correlating on-chain addresses into behavioural profiles without a specific target. Notes replace the on-chain address-to-address edge with a mint/deposit pair separated in time and dissociated by the pool, leaving the bulk observer only the deposits made directly to or from that observer's own clients. Everything else becomes a commitment landing in the pool and a nullifier leaving it.
What the On-Chain Observer Loses
Consider an analytics firm that purchases KYC-linked address data from a large wallet provider. Today, such a firm can reconstruct much of a BUCK user's economic life: regular payroll deposits, recurring vendor relationships, counterparties' other clients, timing patterns. Under Notes, the on-chain trace of a typical legitimate transaction is:
- Payer's account transfers BUCK to the Notes contract (mint). The observer sees only that some amount entered the pool.
- Some time later – minutes to months – a recipient deposits a note. The observer sees only that some amount left the pool to some registered account.
There is no observable edge between payer and recipient. The payer's account activity shows only "sent N BUCK to pool." The recipient's account activity shows only "received M BUCK from pool." Correlating the two requires either (i) complicity of one of the two parties, or (ii) subpoenaed disclosure by either party.
What Bilateral Parties Keep
The BUCK Identity invariant – that both endpoints of any value
transfer can decrypt each other's M – is preserved. The payer
learns the recipient's M when they read the recipient's
IdentityRegistry entry to construct \( E_{\text{note}} \). The
recipient learns the payer's M when they verify the note
(from \( m_{\text{issuer}} \) for A1/B1, from the paired
\( E_{\text{issuer-for-rec}} \) ciphertext for A2).
Neither party sees the other's wider on-chain activity from the
Note alone. The payer sees only the specific M of the
recipient, not the recipient's other counterparties or balances.
The recipient sees the same narrow slice of the payer's life.
The Mass-Harvest Threat Model
The threat Notes defeat is undifferentiated bulk observation:
- A KYC-provider subpoena scoped to "all transactions of clients X, Y, Z for the last five years" yields only direct pool-to-client and client-to-pool transfers. It cannot reconstruct who X paid, or who paid Y, or whether X and Y ever transacted.
- A chain-analytics firm selling behavioural fingerprints cannot build the edge graph at all; there are no edges to cluster.
- An insurer, employer, or landlord who gains read access to a counterparty's on-chain address learns that address's pool-inflow and pool-outflow amounts, not its counterparties.
The threat Notes do not defeat is targeted investigation with proper authorization:
- A warrant served on party X to a specific Note compels X to
reveal the counterparty's
Mand the associated context. - A criminal probe that identifies a "mule" account depositing
many Notes can compel that mule to disclose each note's issuer
M(the income source) and each outgoing note's recipientM(the onward payment), walking the graph one cooperating party at a time. - Sanctioned or frozen Identities are blocked at the contract level regardless of Note use.
This is the posture of a bank cheque or personal cheque, not a $20 bill: the parties to any specific instrument are identified to each other and compellable on individual warrant, but no omnibus order reaches across the system.
The Regulatory Audit Path
A regulator investigating illicit flows has a clean single-target path:
- Identify a suspect account (by KYC on a wallet provider, a prior investigation, or a direct complaint).
- Compel the suspect's wallet, via warrant, to disclose the
plaintext
Mof every counterparty the suspect has transacted with via Notes, together with the note metadata (issuer / recipient, amount, time). This is entirely derivable from material the suspect already possesses: their own registry keys and the payloads they decrypted at scan or mint time. - Serve the next warrant on the resulting named counterparty. Repeat.
The audit is depth-first on named parties, not breadth-first across the chain. The origination of any specific note remains traceable through the on-chain mint record plus the issuer's own records; a bearer $20 bill has no analogous trail.
What Compliance Looks Like
A reasonable regulatory regime around BUCK Notes:
- Issuers must be identity-registered and may face reporting obligations on large issuances (analogous to current cash-withdrawal reporting).
- Depositors face the reporting obligations that attach to cash deposits at a bank today.
- Holders who pass notes hand-to-hand have no reporting obligation, the same way there is no obligation to report carrying $200 in a wallet.
- Named parties to a specific note are compellable to disclose that note's counterparty and surrounding context on warrant.
- Pool-rate demurrage makes long-term cash hoarding economically unviable, bounding the value of Notes-as-store-of-wealth for illicit actors.
The regime is strictly more privacy-preserving than the current surveilled-electronic-transfer regime (which exposes every edge to aggregators and KYC providers) and strictly more compliance-friendly than the current paper-cash regime (which exposes no issuance trail at all, regardless of who is investigating).
The CBDC Comparison
China's e-CNY, the European Central Bank's proposed digital euro, the Bank of Canada's CBDC research – all of these designs include either explicit or implicit surveillance capabilities. The central bank can see, freeze, expire, restrict, geofence, or retroactively examine any holder's balance.2
This is not an accident of the technology; it is a design goal. The pitch to governments is precisely that CBDCs give them visibility into civilian payment flows that paper cash denies them.
BUCK Notes is the opposite posture. Visibility is at the edges of a single instrument (the two named parties to a specific note), never across the system. The bearer-circulation phase of B1 notes is private in the way cash is private; the addressed A1/A2 phase is private between the two named parties the way a sealed letter is private. A jurisdiction adopting BUCK Notes gets better per-instrument compliance tools than paper cash provides today without enabling the population-scale surveillance a CBDC would.
Comparison With Prior Art
This section places BUCK Notes in the lineage of digital cash and privacy-preserving pool designs from 1982 to the present, and identifies what each predecessor lacked.
Chaum's E-Cash (1982-1998)
David Chaum's blind-signature scheme4 introduced the core idea: an issuer (a bank) signs a token blinded by the holder so that the bank cannot link the issuance to the redemption. When the holder spends the token, the merchant verifies the signature without revealing who originally received it.
This is a beautiful design and operationally similar to BUCK Notes in spirit. Its failures were institutional, not cryptographic:
- Required a centralized issuer (the bank)
- Required online verification at spend time (no offline transferability)
- Two-sided market never bootstrapped (no merchants accepted, so no consumers held)
- DigiCash (the commercial implementation) went bankrupt in 1998
BUCK Notes has the same privacy properties without the centralized issuer (any identity-registered party can mint notes against their own on-chain BUCK). Spend-time verification is on chain rather than via the issuer (so the issuer cannot selectively block redemptions). The two-sided market problem is mitigated by BUCK's existing on-chain ecosystem – BUCK already exists as a usable currency, so adopting BUCK Notes is a UX upgrade rather than a greenfield bootstrapping.
Brands' Offline Divisible E-Cash (1993)
Stefan Brands' scheme5 addressed the offline-spend problem: a divisible coin can be spent in pieces without contacting the issuer, but double-spending mathematically reveals the spender's identity.
This is the "deterrent rather than prevention" model. It works in theory but has two operational issues:
- The deterrent only deters if identity revelation has consequences (it relied on a legal/social enforcement layer external to the cryptography).
- The complexity of divisible-coin management was substantial and never produced a shipped product.
BUCK Notes handles double-spend by prevention (global nullifier set), not deterrence. No legal layer is required. Divisibility is achieved by issuing multiple notes at mint time rather than by a single divisible coin.
Casascius Coins (2011-2013)
Mike Caldwell's Casascius coins3 were physical Bitcoin: a brass or silver coin with a holographic seal covering a private-key QR code. Snap the seal, scan the QR, the coin's Bitcoin balance was yours.
Casascius coins remain the closest existing analogue to paper BUCK Notes. What they lacked:
- Native integration with the underlying token (the Bitcoin protocol does not understand bearer-coin form; the coin is an aftermarket wrapper).
- Targeting (all coins were pure bearer; no way to issue a coin claimable only by a specific recipient).
- Demurrage (a Casascius coin holds its full Bitcoin balance forever, unrelated to any economic mechanism).
- Programmable predicates (only one mode: bearer).
- Issuer was a single individual, who eventually stopped issuing in 2013 due to FinCEN money-transmitter concerns – an issuance bottleneck that BUCK Notes distributes to all identity-registered participants.
BUCK Notes is, in essence, what Casascius would have been if Bitcoin had been designed with bearer-paper as a first-class instrument from the start, and if the underlying token had a demurrage and identity layer.
BIP-38 Paper Wallets
Encrypted Bitcoin private keys printed on paper, with a passphrase needed to spend. BIP-38 paper wallets are an aftermarket bearer instrument similar to Casascius but without the physical coin form factor.
Same limitations as Casascius (no native integration, no targeting, no demurrage, no predicates), plus the additional UX burden of remembering or transmitting the passphrase.
Zerocash / Zcash (2014-)
Ben-Sasson, Chiesa, Garman, Green, Miers, Tromer, and Virza's Zerocash7 gave us the first scalable on-chain commitment-and-nullifier UTXO model with full zero-knowledge. Zcash deployed it in 2016.
Zcash provides on-chain shielded transactions but does not extend the model to physical bearer instruments, targeted cheques, or identity-linked issuance. All Zcash value lives on chain in shielded notes. No mechanism exists for printing a shielded Zcash note as a paper instrument that someone else could deposit later.
BUCK Notes uses Zerocash's commitment-and-nullifier primitive for its on-chain machinery and extends it with the Identity-binding layer and the physical-paper surface. The contribution is in the extension, not the primitive.
Aztec / Zk.Money
Aztec's predicate-encrypted notes8 generalize Zerocash to
private smart contract calls – a note can encode arbitrary state
operated on by arbitrary predicates. This is the cryptographic
ancestor of the predicate field in the BUCK Note commitment.
Aztec does not have physical bearer instruments either. Its predicates are designed for on-chain DeFi applications (private DEX trades, private lending), not for paper notes or identity-bound cheques. BUCK Notes applies the same predicate machinery to a different problem: specifying spend conditions for a private bearer instrument that is issued against an identity-registered reserve.
Tornado Cash and Privacy Pools
Tornado Cash9 was the simplest possible commitment-and-nullifier mixer: fixed-denomination deposits in, anonymous withdrawals out. Sanctioned by OFAC in 2022 for money-laundering use.
Privacy Pools (Buterin, Schaefer, Tromer, et al., 2023)10 extends Tornado with per-spend "association sets" – a depositor can prove their deposit is in a non-incriminating subset, allowing compliance without identification.
Both are mixer designs, not cash-instrument designs. Their relevance to BUCK Notes is the lineage: the Note Pool is a Tornado-style global anonymity set, but with predicates and Identity bound in. The selective-disclosure compliance story borrows from Privacy Pools' association-set ideas, but with issuer identity substituting for the depositor-declared non-incrimination proof.
Comparison Summary
| System | Bearer paper | Targeting | Demurrage | Predicates | Native | Decentralized | Year |
|---|---|---|---|---|---|---|---|
| Chaum E-Cash | No | No | No | No | - | No | 1982 |
| Brands Offline | No | No | No | No | - | No | 1993 |
| BIP-38 Paper Wallet | Yes | No | No | No | No | Partial | 2010 |
| Casascius Coin | Yes | No | No | No | No | No | 2011 |
| Zerocash / Zcash | No | No | No | No | - | Yes | 2014 |
| Tornado Cash | No | No | No | No | - | Yes | 2019 |
| Aztec | No | No | No | Yes | - | Yes | 2020 |
| Privacy Pools | No | No | No | Limited | - | Yes | 2023 |
| CBDCs (e-CNY, etc.) | No | Yes | Sometimes | No | Yes | No | 2020+ |
| BUCK Notes | Yes | Yes | Yes | Yes | Yes | Yes | 2026? |
The "Native" column captures whether the bearer-paper instrument is a first-class designed primitive of the system (as opposed to an aftermarket wrapper or absent entirely). BUCK Notes is the first design that fills every column. This is not because the prior art was incompetent; it is because the four required pieces (commitment-pool primitive, identity layer, demurrage, jurisdictional reserve) finally converged in one system.
Comparison: Cash, CBDC, BUCK Notes
A more direct comparison aimed at a non-cryptographer reader: how does BUCK Notes stack up against physical cash and central bank digital currencies?
| Property | Physical Cash | CBDC (typical) | BUCK Notes |
|---|---|---|---|
| PRIVACY | |||
| Holder's identity hidden | Yes | No (issuer sees all) | Yes (during circulation) |
| Transaction graph hidden | Yes | No | Yes |
| Issuer's identity hidden | Yes (notes are fungible) | No | Only to bulk observers; visible bilaterally |
| FINALITY | |||
| Settlement is instant | Yes | Yes | Yes (chain finality) |
| Reversible by issuer | No | Yes (CBDC freeze) | No |
| Reversible by holder | No | Yes (chargeback) | No |
| INFRASTRUCTURE | |||
| Works without internet | Yes | No | Yes (transfer); needs net for deposit |
| Works without battery | Yes | No | Yes (paper); needs power for deposit |
| Works without bank account | Yes | No | Yes |
| Cross-border in your pocket | Yes (with declaration) | No (geofenced) | Yes |
| DURABILITY | |||
| Survives infrastructure failure | Yes | No | Yes (paper); chain on recovery |
| Counterfeit-resistant | Partial (printed security) | Yes | Yes (cryptographic) |
| Recoverable if lost | No | Yes (issuer can re-issue) | No; A-notes require mint-time sk_rec |
| ECONOMIC BEHAVIOR | |||
| Lost notes extracted forever | Yes | No | No (returned via demurrage) |
| Inflation tracks issuer policy | Yes | Yes | Yes (tracks BuckK) |
| Holds value over decades | No (inflation) | No (inflation) | No (demurrage) |
| Holds value over years | Approximately | Approximately | Yes (with demurrage discount) |
| PROGRAMMABILITY | |||
| Time-locked spends | No | Possible | Yes |
| Conditional payouts | No | Possible | Yes |
| Multi-signature spending | No | Possible | Yes |
| Issuer can restrict spending | No | Yes | No (issuer relinquishes control at mint) |
| COMPLIANCE | |||
| Issuance is auditable | No | Yes | Yes |
| Circulation is auditable | No | Yes | No (private) |
| Deposit is auditable | Partial (CTR rules) | Yes | Yes |
| Selective disclosure available | No (no records) | No (full disclosure) | Yes |
The dominant insight from this table: /BUCK Notes combines the privacy properties of physical cash with the compliance and durability properties of CBDC, while preserving infrastructure independence that CBDC abandons./
The single property where physical cash is genuinely irreplaceable – "works without internet for deposits" – is moderated for BUCK Notes but not eliminated. Holders can transfer BUCK Notes hand-to-hand offline, indefinitely; they need internet only when they want to convert the bearer instrument to an on-chain balance. In a disaster scenario, BUCK Notes circulate as cash for the duration of the outage, then deposit normally when the chain becomes reachable again.
Required Identity Cryptography
BUCK Notes re-use the existing Identity machinery (Identity) without introducing new hardness assumptions. The whole construction is built from primitives already proved sound in the Proofs document. The only new moving parts are two standard SNARK-side primitives (Poseidon hash, Poseidon-based nullifier PRF) whose role is internal to the circuit.
Components Already Present
The following are unchanged from Identity v1 and are used directly:
- Pointcheval-Sanders issuer signature \( \sigma \) on the Identity scalar \( m \). Re-randomization continues to serve unlinkable credential generation (Identity Fountain). No change.
- ElGamal registered credential \( E = (R, C) = (r G, M + r \cdot pk) \) where \( M = m \cdot G \). Continues to be the on-chain identity witness, re-randomized by the issuer at mint time to produce \( E_{\text{note}} \) bound to a specific recipient. No change.
- Chaum-Pedersen equality of discrete logs (Theorem 6). Used
verbatim by the A-spend predicate to prove that the depositor's
current registered credential decrypts to the same
Mthat \( E_{\text{note}} \) encrypts. This is the same proof theapproveflow produces outside a SNARK; in Notes it is embedded in the spend circuit. - Schnorr signature on \( cm \). Used in the mint circuit to bind A1 and B1 notes to their public issuer. Standard construction.
- Schnorr PoK of \( sk \) for registered \( pk \). Used by the B-spend predicate to bind the depositing account to a registered identity. Single-statement case of CP.
- IdentityRegistry mapping between on-chain addresses and
registered credentials (PS signatures, ElGamal ciphertexts,
isPublicIdentity flags set by
bindContract).
Notably absent: a stealth-address construction is not used by Notes. Recipient binding is handled directly by re-randomizing the recipient's registered ElGamal credential and verifying via CP-equality – the same mechanism Identity already uses to defeat the BUCK mutual-decryptability requirement.
New Primitive: The Note Commitment Hash
A SNARK-friendly commitment hash \( H_{\text{cm}} \) (Poseidon) is needed to compute the commitment inside the spend circuit. The hash is deterministic, collision-resistant over the note's field, and efficient in R1CS; Poseidon over the BN254 scalar field is the natural choice and is already used by the Aztec and Zcash Sapling circuits.
No novel cryptographic construction; only a circuit-level primitive that is standard in modern SNARK systems.
New Primitive: The Nullifier PRF
The nullifier PRF is Poseidon-based, keyed differently per spend shape:
- A-spend: key = \( M_{\text{rec}} \) (the recipient's identity
point, recovered in-circuit by ElGamal decryption of
\( E_{\text{note}} \) under the depositor's witness
\( sk_{\text{dep}} \)). Nullifier =
\( H_{\text{nf}}(\text{A} \| M_{\text{rec}} \| \rho) \). Keying on
\( M_{\text{rec}} \) – not on \( sk_{\text{dep}} \) – makes the
nullifier value independent of which specific signing key performed
the decryption (a hash-determinism property) and precludes a
pathological scenario in which a recipient simultaneously holds
multiple valid credentials for the same
Mfrom yielding distinct nullifiers and double-depositing. This does not provide key-loss recovery: the decryption step itself requires the specific \( sk_{\text{rec}} \) paired with the mint-time \( pk_{\text{rec}} \), so a recipient who loses that key cannot produce the nullifier at all (see "Key-Pair Binding and Loss Semantics" above). The issuer cannot pre-compute \( nf \) because she never decrypts \( E_{\text{note}} \) (no knowledge of \( sk_{\text{rec}} \)); see proofs.org Theorem 10 for the IND-CPA reduction. - B-spend: key = \( \rho \) itself; nullifier = \( H_{\text{nf}}(\text{B} \| \rho) \), publicly computable by anyone who knows \( \rho \). This is the first-come-first-served property of bearer B1 notes.
A domain-separator byte (A vs. B) in the PRF input keeps the nullifier namespaces disjoint across flavors.
Re-Encryption at Mint (A1 and A2)
The issuer looks up the recipient's registered credential \( E_r = (R_r, C_r) \) in IdentityRegistry, picks fresh \( r' \leftarrow \mathbb{Z}_q^\ast \), and computes
\[ E_{\text{note}} \;=\; (R_r + r' G,\; C_r + r' \cdot pk_{\text{rec}}) \;=\; ((r_r + r') G,\; M_{\text{rec}} + (r_r + r')\, pk_{\text{rec}}). \]
This is a single additional ElGamal re-randomization under the recipient's existing \( pk_{\text{rec}} \). The issuer does not learn any additional secret; they compute \( E_{\text{note}} \) from public data (\( E_r \), \( pk_{\text{rec}} \)) and their own chosen \( r' \). Single curve multiplications on BN254 G_1. No pairing, no new hardness assumption.
For A1, the issuer additionally signs \( cm \) under their own
\( sk_{\text{issuer}} \) and embeds \( (m_{\text{issuer}}, \sigma) \)
in the payload. For A2, no such signature; the issuer's M is
instead carried as an encryption for the recipient to satisfy the
mutual-decryptability invariant.
CP-Equality at Spend (A-Spend)
The depositor produces a CP-equality proof (Theorem 6) showing
that \( E_{\text{note}} \) and the depositor's currently
registered credential \( E_{\text{dep}}^{(\text{reg})} \) decrypt
to the same M. The extractable witness is \( sk_{\text{dep}} \);
because \( sk_{\text{dep}} \) is bound (by registration) to M,
the proof establishes the depositor owns the registered credential
encrypting the recipient's M.
This is identical in structure to the CP proof Alice produces
during approve, lifted into the SNARK circuit rather than
verified on-chain as a Fiat-Shamir NIZK. No new assumption.
Schnorr PoK at Spend (B-Spend)
A B-spender produces a Schnorr PoK of \( sk_{\text{dep}} \) for their registered \( pk_{\text{dep}} \), Fiat-Shamir bound to the spend transaction. This anchors the deposit in a registered Identity (so KYC/FINTRAC obligations attach) while leaving the deposit open to any registered holder of \( \rho \). Standard Schnorr; no novelty.
Summary: New Cryptographic Components
| Component | Status | Assumption |
|---|---|---|
| Poseidon commitment hash | New circuit primitive (standard in SNARKs) | ROM-like |
| Poseidon nullifier PRF | New circuit primitive | ROM-like |
| PS signature (issuer) | Re-used from Identity | q-SDH |
| ElGamal credential + re-encryption | Re-used from Identity | DLog |
| Chaum-Pedersen equality (Theorem 6) | Re-used (lifted into SNARK) from Identity | DLog + ROM |
| Schnorr signature + PoK of \( sk \) | Re-used from Identity | DLog + ROM |
| SNARK proof system (Groth16/PLONK) | Standard on BN254 | system-dep |
Only the Poseidon hash family is new, and it is already standard in the SNARK ecosystem. No novel hardness assumption is introduced. The current Notes spend predicates are covered by Theorems 7-11 of the companion Proofs document.
The SNARK Circuits
The Notes implementation uses three BN254 Groth16 circuits:
mint_batch.circom (Phase-7-bis, parameterised by pinned N),
spend.circom (B-shape, flavor-agnostic bearer redemption), and
spend_a.circom V2 (A-shape, with a Poseidon-8 idHash binding
gate that pins E_n to the leaf – the off-chain CP-DLEQ
identity check is verified by IdentityRegistry.verifySpendCP
via EIP-196 BN254 precompiles, called from Notes.spendACP; see
"Phased Rollout" below).
Mint Circuit (circuits/mint_batch.circom)
The per-leaf on-chain Poseidon insertion that Phase 7 shipped was
gas-cost-fatal at realistic batch sizes (~800K gas/leaf; N=16 alone
exceeds the block limit). Phase-7-bis moves the Merkle-tree update
inside the SNARK: the circuit consumes oldRoot as a public
input, folds N commitments onto it using witness sibling paths, and
exposes the resulting newRoot as a public output. On-chain mint
cost becomes essentially constant in N – ~380K + ~500 gas/leaf of
calldata. The design memo is
alberta-buck-notes-rollup-mint.
Public inputs (5 entries, N-independent).
oldRoot– the live note root the prover read from chainnewRoot– the root after foldingcm_1..cm_NnextLeafIndex– the live tree size the prover read from chaintotalFace– \( \sum v_i \), range-bounded to 128 bitscmBatchHash– \( H(\text{cm}_1, \ldots, \text{cm}_N) \), letting the contract bind calldata to the SNARK without making everycm_iits own public input (keccak on chain; Poseidon reserved for a future in-field variant)
Witnesses. For each leaf \( i \): \( (\text{flavor}_i, v_i,
\rho_i, \text{idHash}_i, \text{predHash}_i) \) plus the TREE_DEPTH
sibling hashes pathSiblings_i[0..19] needed to fold \( cm_i \)
into the rolling tree.
Constraints.
totalFace\( = \sum v_i \) (amount conservation).- Each \( cm_i = \text{Poseidon5}(\text{flavor}_i, v_i, \rho_i, \text{idHash}_i, \text{predHash}_i) \) (opening binding).
- Each \( v_i \in [0, 2^{128}) \) and
totalFace\( \in [0, 2^{128}) \) viaNum2Bits(128). - Rolling Merkle insertion: threading
oldRootandnextLeafIndexthrough N successive single-leaf insertions (Switcher + Poseidon-T3 per level, per leaf), the result equalsnewRoot. About 4.3K constraints per leaf; total ~6K R1CS per leaf including the opening. - Calldata binding:
cmBatchHash\( = H(cm_1, \ldots, cm_N) \). - Belt-and-suspenders: \( cm_i \neq 0 \) and \( cm_i \neq \text{ZERO\_VALUE} \) per leaf.
Pinned N set. Each pinned N has its own compiled circuit, trusted
setup, and deployed verifier. Recommended initial set: \{16, 128,
1024\}. The wallet rounds any requested split up to the smallest
pin \( N^* \geq N_\text{requested} \) and pads with v = 0 dummy
openings; dummies are valid commitments in the tree but spendable
for zero BUCK.
Contract side. The Notes contract checks oldRoot and
nextLeafIndex against its live state, recomputes cmBatchHash
from the calldata cms[], dispatches to mintVerifiers[cms.length]
to verify the proof, pulls totalFace BUCK from the caller via the
standard ERC-20 path, writes newRoot into the ring buffer,
advances nextLeafIndex by cms.length, and bumps noteFaceSum by
totalFace. A single Minted event covers the whole batch;
per-leaf Appended events from Phase 7 are gone.
Spend Circuit (circuits/spend.circom, B-flavor / bearer shape)
Public inputs. noteRoot, nullifier, face, recipient,
chainId.
Witnesses. \( (\text{flavor}, v, \rho, \text{idHash}, \text{predHash}, \text{leafIndex}, \text{path}[20]) \).
Constraints. Five groups, mirroring the circuit's section labels:
- (R) Range bounds: \( v \in [0, 2^{128}) \) and
\( \text{face} \in [0, 2^{128}) \) via
Num2Bits(128)on each, and \( \text{face} \equiv v \) (face exposed publicly equals the witness face). - (C) Commitment opening: \( cm = \text{Poseidon5}(\text{flavor}, v, \rho, \text{idHash}, \text{predHash}) \).
- (M) Merkle membership: walk
path[20]withSwitcherselectors and Poseidon-T3 at each level, asserting the result equalsnoteRoot. -
(N) Nullifier: \( \text{nullifier} = \text{Poseidon3}(ρ, \text{idHash},
- \). The constant tag 4242 is the B-spend domain
separator; the same
idHashcan mint an A-flavor note and a B-flavor note without nullifier collision (differentflavorin the commitment), but both today share this circuit and tag. - (B) Ghost binding:
recipientandchainIdare constrained into the witness via \( x \cdot x \) so the proof cannot be replayed against a different recipient or chain (replay protection by Fiat-Shamir on the public inputs).
Contract side. Notes.spend(proof, root, nullifier, face,
recipient) requires root to be in the recent roots ring,
requires nullifier unused, verifies the Groth16 proof through
SpendVerifierAdapter, sets nullifiers[nullifier] = true,
decrements noteFaceSum by face, and finally calls
buck.transferCarrying(recipient, face) to deliver the funds
plus the pool's accumulated demurrage share.
Bearer semantics for B-shape spends. Anyone holding the opening
\( (\rho, \text{idHash}, \text{flavor}, v, \text{predHash}) \) can
produce a valid B-spend proof and direct the proceeds to any
recipient registered (or registered as system-public) in
IdentityRegistry. This is the correct semantics for a B1 bearer
note. A-flavor identity binding is now shipped via the V2
spend_a.circom + Notes.spendACP path: the SNARK enforces a
Poseidon-8 binding gate that pins the publicly-revealed E_n to
the leaf, and IdentityRegistry.verifySpendCP confirms the
spender's sk_dep satisfies the equal-plaintext relation between
E_n and their registered E_reg. See "Phased Rollout" below
and test/SpendAVerifier.t.sol for the end-to-end exercise.
Circuit Engineering Budget
Constraint counts for the Notes circuits (BN254 Groth16):
| Circuit | R1CS (total) | PTAU pow |
|---|---|---|
| #ERROR | ~3,500 (retired) | 215 |
mint_batch.circom (Phase-7-bis; N=1) M |
21,914 | 215 |
mint_batch.circom (Phase-7-bis; N=2) M |
43,701 | 216 |
mint_batch.circom (Phase-7-bis; N=4) M |
87,273 | 217 |
mint_batch.circom (Phase-7-bis; N=8) M |
174,417 | 218 |
mint_batch.circom (Phase-7-bis; N=16) M |
348,705 | 219 |
mint_batch.circom (Phase-7-bis; N=32) M |
697,281 | 220 |
mint_batch.circom (Phase-7-bis; N=128) P |
~2,800,000 | 222 |
mint_batch.circom (Phase-7-bis; N=1024) P |
~22,000,000 | 225 |
spend.circom (B-shape; depth-20 Merkle) |
~12,000 | 215 |
spend_a.circom V2 (A-shape + Poseidon-8 idHash bind) |
~13,300 (6152 nl + 7140 lin) | 215 |
Measured (M) via snarkjs r1cs info build/snark/mint_batch_n${N}.r1cs
on the shipped pinned-N set {1, 2, 4, 8, 16, 32}; projected (P)
linearly from the N=16 / N=32 baseline (~21,800 R1CS per leaf, ~half
of which is the dual Merkle walk that pins oldRoot and advances
newRoot against the same witness siblings). The PTAU power is
the smallest 2^k ceremony whose FFT domain accommodates the circuit
plus snarkjs setup overhead.
The spend circuit is comparable to Zcash Sapling's Spend circuit
(~25,000) and Aztec's basic note-spend circuit; on-chip proving on
a modern smartphone: a few seconds. mint_batch at N=16 is a
~6-second proof on a dev laptop (snarkjs); N=32 is ~12 s; N=128
is minutes (rapidsnark territory); N=1024 requires a beefy machine
and roughly an hour, with the on-chain verification cost still
bounded by a single Groth16 verify regardless of N. The 225
ceremony is the ceiling that fixes the largest pinned N – raising
it would require a fresh trusted setup.
Common Circuit Gadgets
Shared library used by both circuits:
- Poseidon hash (T3 for Merkle pairs; T6/Poseidon5 for commitment opening; T4/Poseidon3 for nullifier)
- Tornado-style Merkle inclusion (Switcher + Poseidon at each level)
Num2Bitsrange proofs on field elements
spend_a.circom V2 adds two extras on top of this base: an A-tag
nullifier domain separator and a Poseidon-8 binding gate that
pins E_n to the committed idHash (~265 R1CS). The
Chaum-Pedersen equality between E_n and the depositor's
registered E_reg is verified off-chain by Notes.spendACP
via IdentityRegistry.verifySpendCP using EIP-196 BN254
precompiles (~36K gas), avoiding the prohibitive ~+250K R1CS
cost of non-native G1 arithmetic in circom.
What This Architecture Rules Out: Pure-Bearer Cryptographic Notes
The design intentionally does not provide a pure-bearer cryptographic note – one whose spend predicate is "anyone who knows the opening can deposit, with no Identity hook at all." This is the closest analogue to a $20 bill (possession is the entirety of ownership, no registration involved), and it is attractive for the same reasons physical cash is attractive. Three properties make it a poor fit for the cryptographic surface:
- Issuer-race is unbounded. A pure-bearer predicate \( \text{know} \rho \) has no cryptographic mechanism preventing a malicious issuer from retaining \( \rho \) and racing the holder to deposit. The physical seal on paper makes the observation of \( \rho \) detectable to the holder, but does not constrain the issuer at mint time.
- Deposit has no Identity binding. BUCK's mutual-decryptability invariant and the regulatory audit path both rely on the depositor being a registered Identity. A pure-bearer deposit with no Identity hook breaks this property and forces the system into one of two uncomfortable corners: accept unregistered deposits (losing all compliance), or reintroduce Identity at deposit time (at which point it is just a B1 note).
- Three alternative routes all collapse into existing flavors. Blind minting (the issuer does not know \( \rho \) at mint time) requires the holder to participate in minting with a blinded commitment – incompatible with "print a stack of notes and hand them out." Trusted printer (HSM-attested erasure of \( \rho \)) works in principle but reintroduces a single-point-of-trust. Short expiry limits the issuer-race window – equivalent to B1 with an additional expiry predicate.
Rather than contort the cryptographic layer to approximate pure bearer, BUCK Notes keeps the physical-world primitive where it belongs: the tamper-evident seal over a B1 note is a physical-exclusivity mechanism, and that is an inherently physical property. Cryptography makes the opening hard to forge; a hologram makes the observation detectable. The two surfaces complement without pretending to be the same primitive.
For use cases that truly require "no identity link at all":
- Short-lived hand-to-hand circulation is served by B1 paper notes with tamper-evident seals, printed by a trusted issuer who publicly warrants that they erased \( \rho \) after printing. This warranty is an off-chain social/legal claim identical in kind to the trust extended to the Bank of Canada when it issues physical polymer banknotes. A credit union or a commercial issuer fills the role of the central bank for this purpose.
- Long-term holding is served by addressed flavors (A1, A2), where
CP-equality binds the note to the recipient's
Mand no hologram seal is needed.
The canonical "walking-around money" digital flow is handled by A2
notes: Alice targets the payee's registered M at the moment of
payment, hands over the opening via message or QR, and the
recipient deposits into their own account. This changes the UX
relative to paper cash – payment now involves a brief digital
handshake – but gains a property physical cash lacks: a dropped or
intercepted A2 note is useless to anyone but the intended recipient.
Security Assumptions and Theorems Used
The unified Notes design rests on the same cryptographic foundations as the existing Identity system, plus one already-proved additional theorem:
| Primitive / Theorem | Usage in Notes | Assumption |
|---|---|---|
| PS signature (issuer credential) | Mint-circuit issuer-binding (all) | q-SDH |
| ElGamal on \( G_1 \) | Recipient payload (A1, A2) | DLog on \( G_1 \) |
| Theorem 6 (CP re-encryption) | A-spend predicate | DLog + ROM |
| Schnorr signature verify | Public-issuer binding (A1, B1) | DLog + ROM |
| Schnorr PoK (sigma protocols) | B-spend depositor binding | DLog + ROM |
| Poseidon hash/PRF (SNARK-side) | Commitments, nullifiers | ROM-like (circuit) |
| SNARK proof system (e.g., PLONK) | Wrapping all of the above | system-specific |
| Merkle tree (noteTree) | Commitment anchor | collision-resistance |
No novel cryptographic assumption is introduced. The only new primitive not already in BUCK is the Poseidon hash family, which is standard in SNARK deployments (Aztec, Zcash Sapling/Orchard, Starknet, Mina) and well-studied.
Demurrage Conservation as a Contract Invariant
Because the pool is a regular BUCK account and transferCarrying
moves only nominal balance (no fee burn, no totalSupply change),
no Notes-specific demurrage invariant is needed. The system-wide
BUCK invariant
\[ \sum_{\text{all accounts}} B_X \;=\; \text{totalSupply (incl. Jubilee)} \]
holds trivially through every spend: transferCarrying moves
exactly face BUCK from pool to recipient, leaving the sum
unchanged. The recipient's _indexAtLastTouch weighted-merge is
pure bookkeeping; no balance sum is touched.
The Notes contract only needs to maintain two auxiliary local invariants:
noteFaceSum\( \geq 0 \) (no negative note face sum).- Every
faceappearing in a spend equals the \( v \) that appeared in the corresponding mint (enforced by the SNARK via the Merkle inclusion of \( cm \) binding \( v \), and the circuit's \( \text{face} \equiv v \) constraint).
Both are trivial. The only new BUCK mechanism is
transferCarrying, itself a simple state-machine operation
weighted-merging the recipient's _indexAtLastTouch toward the
pool's index.
Implementation Scope
Phases 1-3 of the Phased-Rollout table above are shipped and exercised end-to-end in the Alberta Buck repository. This section records the remaining engineering surface and points readers at the live code.
Shipped (Phases 1-3)
| Component | Source |
|---|---|
| Notes contract: roots, nullifiers, mint/spend/spendACP | src/Notes.sol |
transferCarrying primitive in BUCK |
src/Buck.sol (transferCarrying, _indexAtLastTouch merge) |
| Mint Groth16 circuits + per-N verifiers | circuits/mint_batch.circom, src/MintGroth16Verifier_N*.sol |
| Spend Groth16 circuit + verifier (B-shape) | circuits/spend.circom, src/SpendGroth16Verifier.sol |
| Spend_A Groth16 circuit + verifier (V2; Poseidon-8 binding gate) | circuits/spend_a.circom, src/SpendAGroth16Verifier.sol |
| Poseidon-T3 precompile (in-EVM bytecode) | src/PoseidonT3Bytecode.sol |
| Verifier adapters (proof-bytes plumbing, per-N mint dispatch) | src/MintVerifierAdapter.sol, src/SpendVerifierAdapter.sol, src/SpendAVerifierAdapter.sol |
| A-spend identity gate (off-chain CP-DLEQ, EIP-196 precompiles) | alberta_buck.wallet.spend_cp, IdentityRegistry.verifySpendCP, src/ISpendAVerifier.sol |
| End-to-end tests (real Groth16 fixtures) | test/MintVerifier.t.sol, test/MintBatchVerifier.t.sol, test/SpendVerifier.t.sol, test/SpendAVerifier.t.sol |
| Prover scripts (witness gen + ptau ceremony) | scripts/snark/prove_mint_batch.js, scripts/snark/prove_spend.js, scripts/snark/prove_spend_a.js, scripts/snark/setup.sh |
Pending Engineering (Phases 5-8)
spend_a.circomV2 (Phase 4). Shipped. In-circuit Poseidon-8 binding gate that pinsE_nto the leaf, paired with off-chain Chaum-Pedersen DLEQ verified inIdentityRegistry.verifySpendCPvia EIP-196 BN254 precompiles (~36K gas) and called fromNotes.spendACP. Exercised end-to- end bytest/SpendAVerifier.t.sol(26 tests).- A1 issuer-signature-in-payload (Phase 5). Schnorr verification inside the spend circuit and corresponding wallet UX. ~2 weeks.
- Sealed-QR print flow for B1 (Phase 6). Hologram-vendor integration, QR templates, paper-redemption UX. ~2 weeks.
- Programmable predicates (Phase 7). Bounded predicate DSL compiled into the spend circuit. Multi-month engineering; deferred until production demand materialises.
- Off-chain re-targeting via PRE (Phase 8). Identity Guardians coordination; deferred.
Wallet & UX
- Recipient scan loop: trial-decrypt A1/A2 payloads against registry credential; detect B1 broadcasts: ~1 week.
- A2 self-wormhole mint flow (issuer = recipient): ~1 week.
- A1 identified-cheque creation and deposit UX: ~2 weeks.
- A2 addressed-cheque creation and deposit UX: ~1 week (reuses A1 code paths).
- B1 bearer-cheque creation, sealed-QR print flow, redemption UX: ~2 weeks.
- QR-print templates, hologram-seal vendor integration: ~1 week.
- Prover service integration for thin clients: ~2-3 weeks.
Cross-Checks and Audit
- Cryptographic review of the spend circuit (and the forthcoming
spend_a.circom): 4 weeks, external auditor with SNARK-circuit expertise. - Economic model validation (pool-rate demurrage carrying in stress scenarios: low turnover, high turnover, mint/spend mismatch, large accumulated lost-note face sum): 2 weeks.
- End-to-end fuzz and property-based testing: 2 weeks.
Phased Rollout
The engineering work is naturally phaseable:
| Phase | Scope | Status |
|---|---|---|
| 1 | On-chain Notes pool: incremental Merkle tree, nullifiers, Notes |
Shipped (src/Notes.sol) |
| 2 | Mint circuit + on-chain Groth16 verifier (mint.circom, N=2) |
Shipped (historical; superseded by 2-bis) |
| 2-bis | Batch-mint circuit: per-leaf Merkle insertion moved into the | Active implementation work |
SNARK (mint_batch.circom, pinned N set) |
||
| 3 | Spend circuit (B-shape / bearer) + transferCarrying |
Shipped (Phase 7 BUCK Notes) |
| 4 | spend_a.circom V1 (predicate-only A-spend) + V2 (in-circuit EIP-196 precompiles |
V1 Shipped; V2 Shipped; alberta_buck.wallet.spend_cp, |
| Poseidon-8 idHash binding gate; off-chain CP-DLEQ via | IdentityRegistry.verifySpendCP, src/ISpendAVerifier.sol, |
|
in IdentityRegistry.verifySpendCP, called from Notes.spendACP) |
src/SpendAVerifierAdapter.sol |
|
| 5 | A1 public-issuer signature-in-payload + auditable payroll UX | Pending (depends on Phase 4) |
| 6 | Sealed-QR print flow for B1 walking-around notes | Pending (hologram-vendor integration) |
| 7 | Programmable predicate field (bounded predicate DSL) |
Deferred (Aztec Noir / Halo2 toolchain) |
| 8 | Optional: off-chain re-targeting via proxy re-encryption | Deferred (Identity Guardians) |
Phases 1-4 are shipped and exercised end-to-end by the test
suite (test/MintVerifier.t.sol, test/MintBatchVerifier.t.sol,
test/SpendVerifier.t.sol, test/SpendAVerifier.t.sol) on real
Groth16 fixtures. The B-shape spend circuit is a single
flavor-agnostic verifier: any commitment the prover knows the
opening for can be redeemed to any IdentityRegistry-verified or
system-public recipient (the correct semantics for B1 bearer
notes). The A-shape spend_a.circom V2 adds the in-circuit
Poseidon-8 idHash binding gate that pins E_n to the leaf at
mint time, paired with off-chain CP-DLEQ verification in
IdentityRegistry.verifySpendCP, called from Notes.spendACP.
Phase 4 closes the A-flavor gap in two layers, both shipped. V1
ships spend_a.circom (A-tag nullifier, flavor constraint) without
the identity gate. V2 layers the identity binding using two
cooperating components:
- In-circuit Poseidon-8 binding gate (constraint (I) in the
revised
spend_a.circom): the SNARK now publishesE_n.RandE_n.Cas four additional public inputs (the spender's note ciphertext, in BN254 G1 affine coordinates), and enforces \[ \mathsf{Poseidon\text{-}8}(\mathsf{E_n.R.x}, \mathsf{E_n.R.y}, \mathsf{E_n.C.x}, \mathsf{E_n.C.y}, \mathsf{issuerData}[0..3]) \;\equiv\; \mathsf{idHash} \pmod{F_R}. \] This pins the publicly-revealedE_nto the leaf at mint time (~265 R1CS) without requiring any non-native BN254 arithmetic in the circuit. -
Off-chain Chaum-Pedersen DLEQ verification in
IdentityRegistry.verifySpendCP, called fromNotes.spendACPvia the EIP-196 BN254 precompiles (~36K gas). The verifier reads the spender's registered(pk_dep, E_reg)from storage and confirms a singlesk_depsatisfies both ~pk_dep=sk_dep- G~ and the equal-plaintext relation between
E_nandE_reg.
- G~ and the equal-plaintext relation between
This split is forced by the prohibitive cost of non-native BN254
G1 arithmetic in circom (~+250K R1CS per CP constraint set);
moving the DLEQ verification on-chain costs ~36K gas via precompiles
instead. Notes.spendACP(proof, root, nullifier, face, recipient,
E_n, cpProof) calls both the Groth16 verifier (which checks the
binding gate) and IdentityRegistry.verifySpendCP (which checks
the equality of plaintexts) atomically. All A1/A2 identity,
security, and privacy properties documented above – including the
Theorem 10.1 invariant – remain in force; only the verification
location moved (off-chain CP via precompiles, not non-native G1
in circuit). End-to-end exercised by 26 forge tests in
test/SpendAVerifier.t.sol.
Phases 5-8 are optional extensions deferred until the core system is production-proven.
Regulatory and Legal Engagement
In parallel with engineering, the legal and regulatory work:
- Confirm that BUCK Notes falls within Alberta's provincial jurisdiction over property and civil rights (s 92(13)) – the analysis in the Legal Foundation document covers the underlying primitive; bearer notes are an extension that may warrant additional treatment.
- Engage FINTRAC on the issuance-side reporting model.
- Engage the Office of the Superintendent of Financial Institutions (OSFI) on reserve treatment.
- Coordinate with Alberta Treasury Branches (ATB) as a candidate first issuer of paper notes under a public-warranty of \( \rho \)-erasure for the B1 walking-around-cash surface.
Open Questions
The architecture above leaves a handful of economic and cryptographic questions worth sharpening before commitment:
Donation Incidence
Donations to the Notes contract weighted-merge idx_pool forward
toward cumIndex_now, lowering the per-BUCK fee owed by the pool
and therefore reducing the index gap every subsequent redeemer
inherits. The benefit spreads across all future redemptions
rather than accruing to a single lucky first-redeemer. A
donation immediately before a large redemption benefits that
redemption more (because the merge uses the donation's relative
weight against the pool's existing balance), but every subsequent
redemption benefits in proportion to the freshened index. No
special smoothing logic is needed.
Residual donation principal (after all notes drain) is not
lost: it sits in balanceOf(notes) with a _indexAtLastTouch
close to whatever cumIndex it last touched at, available to
subsidise the next generation of mints, or recoverable by
governance sweep per Notes-contract policy.
Stranded Value on Lost Notes
A lost note contributes to noteFaceSum indefinitely. The BUCK
backing that note sits in the pool, where its share of
accumulated demurrage stays attached to idx_pool. Each spend
of a live note inherits a slice of that accumulated index gap on
its delivered face – so over time the lost note's implicit
demurrage is paid instalment-style by subsequent live noteholders
on their next outgoing transfers. At 1%/yr loss and 2%/yr
demurrage, the long-term tendency is that the pool absorbs the
lost-note demurrage as a small pool-wide overhead.
A reclaim path is possible: after a very long period (say 99 years), the contract could allow the issuer to submit a zero-knowledge proof that a specific note commitment remains unspent, and reclaim the residual principal less accrued demurrage. Requires issuer-side recordkeeping; deferred.
Integer-Arithmetic Rounding
The transferCarrying weighted-index merge involves one integer
division
\( ( br \cdot \text{idx}_r + v \cdot \text{idx}_p ) / (br + v) \)
for the recipient's new index. Truncation rounds the recipient's
inherited fee down by at most one cumIndex unit per spend –
trivially small (sub-wei demurrage on any realistic balance) and
not drift-accumulating: the lost fraction never exceeds the
recipient's prior index gap. Floor rounding is fine; no banker's
logic required.
Predicate Programmability vs. Circuit Simplicity
Keeping three fixed flavors simplifies the circuit count. Adding programmable predicates (time locks, oracle conditions, multi-sigs) re-introduces most of the complexity that the fixed flavor scheme was chosen to avoid. A compromise: support a bounded predicate language in the circuit (time-lock + oracle-condition + up-to-3-sig) rather than a fully general one. The bounded language covers 90%+ of the programmable-predicate use cases while keeping the verifier compact.
Universal Spend Circuit vs. A/B Specialization
Phase 4 deployed two distinct spend verifiers: spend.circom
(universal B-shape) and spend_a.circom V2 (A-shape with the
Poseidon-8 idHash binding gate and 9 public inputs). The wallet
selects between Notes.spend and Notes.spendACP based on the
note's flavor field. The alternative – one "super-spend"
verifier branching internally on flavor – was rejected: the
A-shape circuit publishes four extra public inputs (E_n.R/C
coordinates) and an additional binding constraint, and unifying
the two verifiers would force every B-spend proof to carry the
A-only public-input overhead. Two verifiers, two trusted-setup
ceremonies (both pot15), is the shipped configuration.
Regulatory Interaction with transferCarrying
Jurisdictional regulators (FINTRAC, OSFI) have rules around bearer instruments and tax treatment of negative-interest accounts. BUCK's on-chain demurrage was argued through separately, and the Notes contract inherits that treatment with no pool-specific novelty – the contract is just another BUCK account.
The one new wrinkle is the transferCarrying primitive itself:
ordinary BUCK transfers carry only balance (recipient gets "fresh"
BUCK and resets _indexAtLastTouch to cumIndex_now), whereas
Note redemptions weighted-merge the recipient's _indexAtLastTouch
toward the pool's stale index. This means a Note recipient's
post-redemption spendable value is less than their nominal
balance – the difference being the demurrage they will pay on
their next outgoing transfer. For tax and reporting purposes,
whether the "face" or the "spendable" number should be used as
the income figure is a question for tax counsel. The on-chain
state (balanceOf and _indexAtLastTouch) is fully transparent
either way.
Summary
BUCK Notes is the Alberta Buck's native private-bearer primitive. A single Merkle tree of commitments, a single nullifier set, and three realisable flavors – A2 (addressed, private issuer; also self-wormhole), A1 (addressed, public issuer; payroll and audited cheques), and B1 (bearer, public issuer; cashier's cheques) – span every use case the Alberta Buck series needs a bearer instrument to cover, from cold-storage cryptographic self-wormholes to walking-around paper notes to cross-border targeted remittances. The fourth cell, private-bearer, is ruled out by BUCK's mutual-decryptability invariant.
Demurrage needs no note-side machinery: the Notes Pool is the
Notes contract's own ERC-20 balance – a regular BUCK account with
its single _indexAtLastTouch[notes] entry in the BUCK ledger.
The only Note-side state beyond the Merkle tree and nullifier set
is noteFaceSum, the total face value of live notes, kept as an
audit scalar. Spend delivers the full face value to the
recipient via transferCarrying, weighted-merging the recipient's
_indexAtLastTouch toward the pool's stale index. The recipient
inherits the average pool BUCK-age and bears the resulting
demurrage on their next standard outgoing transfer through the
ordinary BUCK accounting path – exactly the demurrage they would
have paid had they held the BUCK personally through the pool's
residence period. The entire mechanism requires a single new
primitive, transferCarrying, localised to the Notes contract's
one egress function. Donations to the pool freshen idx_pool and
cheaply subsidise all subsequent redeemers. Conservation of
nominal balance and Jubilee growth fall out exactly.
The addressed-versus-bearer distinction produces a sharp partition of which flavors are safe for long-term holding: A1 and A2 are cryptographically safe against third-party theft (CP-equality binds the note to the recipient's \( sk_{\text{rec}} \) via single-key ElGamal under \( pk_{\text{rec}} \)), with the key-management corollary that the mint-time \( sk_{\text{rec}} \) itself must be preserved – Identity re-issuance rotates the Identity scalar's keypair but does not recover notes bound to a lost \( sk_{\text{rec}} \). B1 is a civil-trust instrument: the issuer necessarily knows \( \rho \), so B1 cheques are meant to be cashed promptly and backed by the issuer's legal standing rather than by cryptography alone. This is an intrinsic property of the bearer predicate, not a policy choice.
The cryptographic architecture does not attempt to provide a pure-bearer note with no Identity hook. That use case remains the domain of physical trust models: tamper-evident seals over B1 paper notes, issued by a trusted printer with a public warranty that \( \rho \) was erased after printing. This keeps the cryptographic/physical boundary explicit rather than contorting the cryptographic layer to approximate a property that inherently requires physical primitives.
A BUCK Note can live on chain as a commitment-opening pair, travel
between wallets as a digital message, or be printed on paper as a
QR-encoded slip with a hologram seal (for B1) or without one (for
A1, A2). All three surfaces share the same cryptography and the
same on-chain footprint. Counterfeiting is cryptographically
impossible: a "fake" note's commitment is simply absent from the
on-chain tree, the Merkle proof fails, and the wallet displays
FAKE. Lost notes are not extracted as seigniorage: the pool-age
mechanism returns their value to the commons via demurrage pressure
on subsequent live-note redemptions.
Issuance is on chain and identity-bound. Circulation breaks
on-chain bulk traceability (no observable edge between payer and
recipient) while preserving bilateral disclosure (both named
parties always learn each other's M; either is compellable on
warrant). Deposit is identity-bound and auditable. This is
stronger compliance than physical cash provides today, and stronger
privacy than any CBDC has ever proposed.
No novel cryptographic assumption is introduced. Theorem 6 of the Proofs document (Proofs) applies verbatim to the A-spend predicate (CP-equality on the recipient's re-randomized credential); B-spend reduces to Schnorr signature verification plus a Schnorr PoK of the depositor's registered secret. The only new circuit-level primitive is Poseidon, which is already standard across the SNARK ecosystem. Implementation scope for Phases 1-4 (the full A1/A2/B1 production surface) is 5-7 months for a focused team.
BUCK Notes answers the question Chaum was asking in 1982: what does digital cash look like when you take "cash" seriously? The answer, forty years later: it looks like a commitment in an on-chain pool, openable as a message, a QR, or a printed slip, with a value that decays at the same rate your bank balance does, integrated with a complete monetary system that does not require a central bank to function. Alberta has, uniquely in the world, all four pieces required to build this. Whether to assemble them is, as ever, the only question that matters.
Footnotes
Federal Reserve. "Currency in Circulation" (2024). Approximately half of US currency in circulation by value is held outside the United States, providing a global store-of-value function despite zero yield.
Bank for International Settlements. "Rise of the Central Bank Digital Currencies" (2020). Surveys CBDC designs across major central banks; notes that nearly all incorporate explicit issuer-side surveillance and programmability features (spending limits, geofencing, expiration, freezing) that physical cash does not have.
Caldwell, M. "Casascius Physical Bitcoins" (2011-2013). Physical brass and silver coins containing Bitcoin private keys under tamper-evident holographic seals. Production halted in 2013 after FinCEN classified the issuer as a money transmitter requiring federal licensing. Surviving "unpeeled" Casascius coins now trade at substantial premiums above their Bitcoin face value as collectibles.
Chaum, D. "Blind Signatures for Untraceable Payments" (1982). Advances in Cryptology - Crypto '82, pp. 199-203. The foundational paper introducing blind signatures and digital cash. Chaum's DigiCash company commercialized the design from 1989-1998 before bankruptcy.
Brands, S. "Untraceable Off-line Cash in Wallets with Observers" (1993). Advances in Cryptology - Crypto '93, pp. 302-318. Offline divisible e-cash with double-spend identity revelation – a deterrent rather than prevention model.
Camenisch, J., Hohenberger, S., Lysyanskaya, A. "Compact E-Cash" (2005). Advances in Cryptology - Eurocrypt '05, pp. 302-321. Compact divisible e-cash where a single coin can be spent in pieces with O(1) communication and storage per spend.
Ben-Sasson, E., Chiesa, A., Garman, C., Green, M., Miers, I., Tromer, E., Virza, M. "Zerocash: Decentralized Anonymous Payments from Bitcoin" (2014). IEEE S&P 2014. The foundational design for on-chain commitment-and-nullifier UTXO privacy, deployed in production as Zcash since 2016 – the commitment-and-nullifier primitive used by BUCK Notes.
Williamson, Z., et al. "Aztec Protocol"
(2018-). Ethereum L2 rollup providing general-purpose private smart
contracts using PLONK proofs and predicate-encrypted notes. The
cryptographic ancestor of the predicate field in BUCK Note
commitments.
Pertsev, A., Semenov, R., Storm, R. "Tornado Cash Privacy Solution" (2019). Fixed-denomination commitment-and-nullifier mixer on Ethereum. Sanctioned by the US Office of Foreign Assets Control (OFAC) in August 2022 for alleged use in money laundering by North Korean state actors.
Buterin, V., Schaefer, J., Tromer, E., et al. "Blockchain Privacy and Regulatory Compliance: Towards a Practical Equilibrium" (2023). Extends commitment-pool mixers with per-spend "association set" proofs, allowing depositors to demonstrate non-membership in incriminating subsets without revealing their specific deposit.
The astute reader will recognize that this essentially freezes demurrage for BUCK Note amounts while they are in transit; this has beneficial effects for the transmission of large long-term BUCK balances, such as inheritances. The cost of this benefit is effectively amortized across all BUCK Note users; the value of Anonymity for short-term Note users subsidies long-term Note holders, who bear some additional risk that their Notes may be lost]
Federal Reserve Bank of San Francisco. "Diary of Consumer Payment Choice" (2018). Estimates 5-10% of US paper currency by value is permanently unrecoverable. At a US M0 of $2.3 trillion, this represents $115-230 billion in permanently extracted seigniorage.
World Bank. "Remittance Prices Worldwide" (Q4 2024). Average global cost of remitting $200 was approximately 6.5% in 2024. Total global remittance flows estimated at $702 billion in 2024.
Consumer Federation of America. "Gift Cards: A Costly Convenience" (2023). Estimates of cumulative consumer losses to bankrupt gift-card issuers in the United States range from $200M-$1B annually depending on methodology.
Bank of Canada. "2022 Methods-of-Payment Survey" (2023). Approximately 1-2% of Canadians lack bank accounts; rates substantially higher in rural and Indigenous communities.
World Bank. "The Global Findex Database 2021" (2022). An estimated 1.4 billion adults globally remain unbanked, with disproportionate concentrations in low-income countries, women, rural populations, and the elderly.