Skip to main content

Ghost Protocol

The Ghost Protocol is Specter's core privacy primitive — a commit-reveal system that uses zero-knowledge proofs to break the link between depositing and withdrawing value.

How it works

The key insight

Tokens are not transferred or escrowed — they are destroyed on commit and created fresh on reveal. There is no pool, no escrow contract, and no link between the two operations. The only thing connecting them is a zero-knowledge proof that says "I know the preimage of some commitment in the tree."

The flow in detail

Step 1: Commit (burn)

The user calls commit() or commitNative() on the CommitRevealVault. The vault:

  1. Burns the tokens via the Ghostmint precompile (BankKeeper.BurnCoins())
  2. Computes a Poseidon hash commitment from the user's secret inputs
  3. Inserts the commitment into the Merkle tree
  4. Emits a Committed event

Step 2: Root update

The root updater relayer service watches for CommitmentAdded events, rebuilds the off-chain Merkle tree, and submits the new root on-chain. This takes 5–15 seconds.

Step 3: Reveal (mint)

The user generates a Groth16 ZK proof proving they know the preimage of some commitment in the tree — without revealing which one. The vault:

  1. Verifies the proof against the on-chain verifier
  2. Checks the nullifier hasn't been spent (prevents double-reveal)
  3. Registers the nullifier
  4. Mints fresh tokens via the Ghostmint precompile (BankKeeper.MintCoins())

Privacy properties

PropertyHow it's achieved
Sender privacyTokens are burned, not sent. No outgoing transfer to trace.
Receiver privacyTokens are minted fresh. No incoming transfer to trace.
Amount privacyPartial reveals with change commitments obscure amounts.
UnlinkabilityThe ZK proof proves membership in the full tree without revealing which leaf. The anonymity set is all commitments in the tree.
Double-spend preventionNullifiers derived from user secrets are registered on-chain. Same commitment cannot be revealed twice.

What can you commit?

The Ghost Protocol is data-agnostic. The commitment structure stores:

  • secret — user's private key for this commitment
  • nullifierSecret — used to derive the unique nullifier
  • amount — the value being committed
  • tokenId — hash identifying the token type
  • blinding — random blinding factor
  • policyId — optional policy contract address
  • policyParamsHash — optional policy parameters

Any data that fits this structure can be committed. Native GHOST, GhostERC20 tokens, and arbitrary data types all use the same circuit.

Next steps