Skip to main content

Nullifiers

A nullifier is what a spend reveals on-chain. It is a one-time proof-of-spend: the chain has never seen it before (if the note is unspent), and it cannot be linked back to the note's commitment. Spending never touches the tree — it only adds a nullifier to the spent set. That is what unlinks a spend from the note it consumes.

The three requirements

RequirementWhy
Deterministicthe same note always yields the same nullifier, so a double-spend is detectable
Unlinkablean observer cannot connect nf to its cm
Key-bindingonly the holder of the spending key can produce a valid nf for a note

The construction

nf=Poseidon2(NF_DOMAIN,nk,ρ,ψ,cm)nf = \text{Poseidon2}(\text{NF\_DOMAIN},\, nk,\, \rho,\, \psi,\, cm)

Each input earns its place:

  • nk: the nullifier-deriving key. Private to the owner ⇒ only they can derive a valid nf (key-binding).
  • ρ: the uniqueness tag. For output notes, ρ_new = nf_old (rho-chaining) ⇒ globally unique across notes.
  • ψ: sender-supplied entropy, sampled fresh per note.
  • cm: binds the nullifier to the exact committed note. This is the Faerie-Gold defense: two notes that differ in any committed field cannot share a nullifier.

Unlinkability

nf is a Poseidon2 output over secret inputs (nk, and the note's ρ/ψ). To anyone without (nk, ρ, ψ, cm) it is indistinguishable from random and reveals nothing about which leaf was spent. The chain stores the spent set but cannot map a nullifier to a commitment.