← JournalPrivacy · 12 min · Apr 12, 2026

Note pools vs. account shielding: why we chose UTXO

There are two fundamentally different approaches to blockchain privacy. We evaluated both carefully before committing to the UTXO note pool model for Sanect's shielded layer. This is that analysis.

in brief12 min read

Compares UTXO-style note pools (Zcash, Penumbra) with Aztec-style account shielding and explains why Sanect chose fixed-denomination notes with a fixed-size encrypted memo.

  • Note-pool anonymity scales with every unspent note across all users; account shielding is scoped to per-contract interaction graphs.
  • Fixed-denomination notes (e.g., 1, 10, 100 SNCT) remove value fingerprints; the wallet composes multiple notes for arbitrary amounts.
  • Memos use X25519 ECDH + ChaCha20-Poly1305 in a fixed 240-byte envelope, 96 bytes reserved for future fuzzy message detection.

Two Models, One Goal

Every blockchain privacy system needs to answer the same question: what exactly is being hidden? The chain must remain auditable by validators (to prevent double-spending), but opaque to observers (to protect user privacy). How you answer that question determines almost everything about your cryptographic circuit design, your UX, and your anonymity set properties.

Two dominant models have emerged from years of applied cryptography research. The first, used by Zcash and Penumbra, treats private value as notes — discrete, immutable objects that are created, transferred, and destroyed. The second, used by Aztec, treats private state as shielded accounts — encrypted account balances that are updated in place through encrypted state transitions. Both achieve privacy. They achieve it differently, and the tradeoffs are significant.

UTXO Note Pools: The Zcash and Penumbra Model

In a note pool system, a deposit into the shielded pool does not add to an account balance. It creates a note. A note is a commitment to a specific value, asset type, and recipient key, stored as a leaf in an append-only Merkle tree. To spend a note, the spender proves (in zero knowledge) that they know the spending key for some note in the tree, reveals a nullifier (a deterministic value derived from the note and key that cannot be linked back to the note without the key), and produces a new commitment for the recipient.

The chain records the nullifier to prevent double-spending and appends the new commitment to the tree. At no point does any on-chain data reveal which note was spent, who sent it, or who received the new one. The anonymity set is the entire pool of unspent notes.

Fixed-Denomination Notes

Sanect uses fixed-denomination notes — a design choice that deserves explicit explanation. Rather than allowing arbitrary value amounts, the shielded pool accepts deposits in fixed sizes (e.g., 1 SNCT, 10 SNCT, 100 SNCT). This is the same approach used by Tornado Cash's circuit design, and the privacy rationale is straightforward: if every note has the same denomination, there is no value fingerprint to use for de-anonymization. A transaction spending a 10 SNCT note is indistinguishable from any other transaction spending a 10 SNCT note, regardless of who the sender or recipient is.

The tradeoff is that sending an arbitrary amount requires composing multiple notes, which adds some complexity to the wallet layer. We consider this acceptable: the wallet handles composition automatically, and the privacy gain is worth the UX cost.

Account Shielding: The Aztec Model

Aztec's approach starts from a different premise. Rather than discrete notes, Aztec maintains encrypted account state: each account has an encrypted balance, and transactions are encrypted state transitions that update that balance. The prover generates a ZK proof that the new encrypted state is a valid update of the old encrypted state, without revealing the values involved.

The appeal of account shielding is its familiarity. Users think of it as "my private balance" — the same mental model as a bank account or an Ethereum address. Smart contracts can also maintain encrypted state, enabling privacy-preserving DeFi without the note-composition complexity.

The cost is circuit complexity and a subtler anonymity model. Account shielding requires proving encrypted state transitions, which involves more constraints than the simpler "note in, nullifier out" model. More critically, the anonymity set is bounded by the number of accounts that have interacted with a given contract — not the total pool of notes. If a private account has only ever interacted with one counterparty, the transaction graph may be more constrained than it appears.

Why Sanect Chose the Note Pool

We evaluated both models against four criteria: anonymity set size, circuit complexity, auditability surface area, and alignment with the Noir/UltraHonk proving stack. The note pool wins on every axis except UX familiarity.

  • Anonymity set: Note pool anonymity scales with the number of unspent notes across all users. Every deposit by every user increases the anonymity set for every other user. Account shielding anonymity is scoped to per-contract interaction graphs — structurally smaller.
  • Circuit simplicity: The spend circuit for a fixed-denomination note is significantly simpler than an encrypted state transition circuit. Simpler circuits mean faster proving, smaller proof sizes, and a smaller attack surface in the cryptographic layer.
  • No account state leakage: In account shielding, the fact that an account exists and has been updated is always public — only the value is encrypted. In a note pool, the existence of a transaction is known but nothing about its parties or structure is revealed beyond the denomination.
  • Noir/UltraHonk alignment: Sanect's custom 2-in/2-out Noir circuit compiles to UltraHonk proofs via Barretenberg's universal SRS. The note pool model maps cleanly to Noir's constraint system — input notes, nullifiers, output commitments, and value conservation are all expressible as straightforward circuit assertions.

The Memo Protocol

Sending a note to a recipient requires a secure out-of-band channel to communicate the note details. Sanect uses an encrypted memo field in each shielded transaction: a fixed-size envelope attached to the note commitment that can only be decrypted by the intended recipient's viewing key.

The encryption scheme is X25519 ECDH + ChaCha20-Poly1305. The sender generates a fresh ephemeral X25519 keypair for every transaction, derives a shared secret with the recipient's viewing public key, and uses HKDF-SHA256 to derive a 32-byte ChaCha20 key and a 12-byte nonce. The ephemeral public key is included in the memo as additional authenticated data (AAD), binding it to the MAC and preventing substitution attacks.

The Fixed-Size Memo Structure

The fixed memo size is not arbitrary. It is the minimum size that accommodates:

  • 32 bytes — ephemeral X25519 public key
  • 96 bytes — encrypted note plaintext (value, asset ID, diversifier, memo data)
  • 16 bytes — Poly1305 authentication tag

Fixing the memo size to exactly the same number of bytes (240 today, of which 96 are reserved for future fuzzy message detection flags) means all memos are indistinguishable in length on-chain. A variable-length memo would leak information about the note's content even without decryption. The memo plaintext packs the 96 bytes tightly: 8 bytes for value, 32 bytes for asset ID, 11 bytes for the note's diversifier, and 45 bytes of free memo data for applications to use.

Every shielded transaction on Sanect produces a 240-byte memo (with 96 of those bytes reserved for future privacy-preserving fuzzy message detection flags). You cannot tell from the on-chain data whether two memos are from the same sender, the same recipient, or carry the same value. That uniformity is not a side effect — it is a design constraint.

The UX Tradeoff

The honest answer is that note pools are harder to explain than account balances. "You have 3 unspent notes worth 10 SNCT each" is less intuitive than "your shielded balance is 30 SNCT." Sanect's wallet layer abstracts this: the interface displays a balance, not a note count, and handles note selection and composition automatically. But the underlying model is notes, and sophisticated users should understand that — both to reason about their privacy properties and to understand why some transactions require multiple proofs.

We made this tradeoff deliberately. The privacy model is the product. UX complexity that serves stronger privacy is worth the investment in wallet engineering.

Questions this answers3 · straight from the article
What is the difference between a note pool and account shielding?

A note pool treats private value as discrete notes created, spent via nullifiers, and destroyed. Account shielding keeps encrypted balances updated in place through proven encrypted state transitions.

Why does Sanect use fixed-denomination notes?

If every note has the same denomination there is no value fingerprint for de-anonymization; a transaction spending a 10 SNCT note is indistinguishable from any other 10 SNCT spend.

How is a Sanect shielded memo encrypted?

The sender creates a fresh ephemeral X25519 keypair, derives a shared secret with the recipient's viewing public key, and uses HKDF-SHA256 to derive a ChaCha20-Poly1305 key and nonce.

— end · last updated —
Share on X ↗ Discuss on Telegram ↗