The Commit/Reveal Mechanism
The Ghost Protocol's commit/reveal mechanism has two phases: Vanish (commit) and Summon (reveal). These names reflect the user experience — data or value "vanishes" from public view and is later "summoned" back into existence with a proof. The two operations are cryptographically unlinkable.
This page describes both phases in detail, shows how they work for general data and for tokens side by side, and explains why the burn/mint model is superior to deposit/withdraw for token privacy.
Phase 1: Vanish (Commit)
The Vanish operation takes private data and seals it on-chain as an irreversible commitment. After Vanish completes, the data exists on-chain only as a Poseidon hash inside a Merkle tree. The original data, the sender's relationship to the commitment, and the timing of insertion are all hidden from future observers once the anonymity set grows.
General Data Flow
For arbitrary data (credentials, images, API keys, encryption keys), the Vanish operation proceeds as follows:
- Generate secrets: The user generates a random
secret, anullifierSecret, and ablindingfactor. These are stored locally and never transmitted. - Compute data hash: The user computes
dataHash = Poseidon(data)wheredatais the credential, key, image hash, or other payload. - Compute commitment: The commitment is
Poseidon4(secret, nullifierSecret, dataHash, blinding). - Submit Vanish transaction: The commitment (a single field element) is submitted to the chain.
- Merkle insertion: The
x/ghostmintmodule inserts the commitment as the next leaf in the Merkle tree and updates the path from the leaf to the root.
The original data is never transmitted to the chain. Only the 256-bit commitment is stored on-chain.
Token Flow
For GHOST tokens (or any supported token), the Vanish operation additionally destroys the tokens:
- Generate secrets: Same as general data —
secret,nullifierSecret, andblinding. - Compute commitment: The token commitment uses a 7-input Poseidon hash:
Poseidon7(secret, nullifierSecret, tokenId, amount, blinding, policyId, policyParamsHash). - Submit Vanish transaction: The commitment is submitted along with the token amount and token ID.
- Token burn: The
x/ghostmintmodule burns the specified tokens from the sender's account. The tokens are destroyed — they no longer exist in any account, pool, or contract. - Merkle insertion: The commitment is inserted into the Merkle tree, exactly as with general data.
The key difference: when tokens are vanished, they are burned, not deposited. There is no pool. There is no contract holding funds. The tokens cease to exist.
Phase 2: Summon (Reveal)
The Summon operation proves knowledge of a commitment without identifying which commitment. It generates a Groth16 zero-knowledge proof and submits it to the chain for verification. If the proof is valid and the nullifier has not been used, the reveal succeeds.
General Data Flow
For arbitrary data, the Summon operation verifies and returns the data hash:
- Fetch Merkle proof: The client retrieves the authentication path for the commitment's leaf position from the chain.
- Compute nullifier:
nullifier = Poseidon(nullifierSecret, leafIndex). - Generate ZK proof: The client generates a Groth16 proof with the following structure:
- Private inputs:
secret,nullifierSecret,dataHash,blinding,leafIndex, Merkle authentication path - Public inputs:
root,nullifierHash,dataHash,accessTag
- Private inputs:
- Submit Summon transaction: The proof and public inputs are submitted to the chain.
- On-chain verification:
- The Groth16 verifier checks the proof against the verification key
- The
rootis checked against the set of recognized Merkle roots - The
nullifierHashis checked against the nullifier registry
- Nullifier recording: The nullifier is added to the registry, preventing replay.
- Data hash returned: The verified
dataHashis emitted as an event or returned to the calling contract.
Token Flow
For tokens, the Summon operation mints fresh tokens:
- Fetch Merkle proof: Same as general data.
- Compute nullifier: Same as general data.
- Generate ZK proof: The proof uses the 7-input token circuit:
- Private inputs:
secret,nullifierSecret,tokenId,amount,blinding,policyId,policyParamsHash,leafIndex, Merkle authentication path - Public inputs:
root,nullifierHash,recipient,amount
- Private inputs:
- Submit Summon transaction: The proof, public inputs, and recipient address are submitted.
- On-chain verification: Same checks as general data — valid proof, recognized root, unused nullifier.
- Nullifier recording: Same as general data.
- Token mint: The
x/ghostmintmodule mints fresh tokens to the specified recipient address. These are new tokens, not transfers from a pool.
Why Burn/Mint Is Superior to Deposit/Withdraw
Traditional privacy protocols (Tornado Cash, Railgun, etc.) use a deposit/withdraw model: tokens are deposited into a smart contract pool, and later withdrawn from that pool with a ZK proof. This creates a custodial intermediary — the pool contract — that holds all deposited funds.
Specter's burn/mint model eliminates the pool entirely. Tokens are destroyed on Vanish and created on Summon. There is no intermediate state where tokens exist in a contract.
| Property | Deposit/Withdraw (Pool) | Burn/Mint (Specter) |
|---|---|---|
| Custodial risk | Pool contract holds all funds | No pool — tokens do not exist between commit and reveal |
| Regulatory surface | Pool can be sanctioned, blocked, or frozen | No entity or contract to target — burn and mint are protocol operations |
| Smart contract risk | Pool contract is a high-value exploit target | No pool contract to exploit |
| Frozen funds | If pool is compromised or sanctioned, all deposited funds are at risk | Tokens do not exist between operations — nothing to freeze |
| Supply integrity | Total supply is unchanged (tokens are in the pool) | Total supply temporarily decreases on Vanish and restores on Summon |
| Implementation | Requires a custodial contract with deposit/withdraw logic | Integrated into the consensus layer — burn and mint are native operations |
No Custodial Pool
In a pool-based system, every deposited token sits in a contract. That contract is a single point of failure. If the contract has a bug, an attacker can drain all deposits. If a government sanctions the contract address, all deposited funds are effectively frozen. If the contract is upgradeable, the upgrade authority can potentially steal funds.
Specter has no pool. After Vanish, the tokens do not exist anywhere — they have been burned by the consensus layer. After Summon, fresh tokens are minted by the consensus layer. The only entity that can burn or mint tokens is the protocol itself, governed by the validator set and the ZK verification logic.
No Frozen Funds
When OFAC sanctioned the Tornado Cash contract addresses in August 2022, any tokens deposited in those contracts became effectively inaccessible through compliant front-ends and RPC providers. The tokens still existed on-chain but could not be withdrawn without interacting with a sanctioned address.
In Specter's burn/mint model, there is no contract address to sanction. The burn operation removes tokens from the sender's account via the consensus layer. The mint operation creates tokens in the recipient's account via the consensus layer. There is no intermediate address, no pool, and no contract. The regulatory surface is fundamentally different.
Supply Accounting
In a pool model, the total token supply remains constant — tokens simply move from user accounts to the pool contract and back. In Specter's burn/mint model, the total supply temporarily decreases when tokens are Vanished and returns to its previous level when tokens are Summoned. This is by design: the commitment in the Merkle tree represents a claim on future minting, not a balance in a pool. The protocol ensures that total minting never exceeds total burning through the nullifier registry (each commitment can only be revealed once).
The Generality Principle
Both flows — general data and token — share the same cryptographic foundation:
- Poseidon commitment inserted into a Merkle tree
- Groth16 proof of preimage knowledge and Merkle membership
- Nullifier to prevent replay
The difference is what happens at the application layer:
- General data: The verified
dataHashis returned or emitted - Tokens: The
x/ghostmintmodule burns on Vanish and mints on Summon
This means every improvement to the proof system, Merkle tree management, or nullifier registry benefits all data types simultaneously. A credential commitment and a token commitment use the same tree, the same verifier, and the same nullifier set. The protocol is general; the applications are specific.