The Ghost Protocol
The Ghost Protocol is Specter's core primitive. It is a commit/reveal system for any data. A user hashes data into a Poseidon commitment, inserts that commitment into an on-chain Merkle tree, and later proves knowledge of the committed data using a Groth16 zero-knowledge proof. The commit and reveal operations are cryptographically unlinkable — no observer can determine which commitment corresponds to which reveal.
This is not a token mixer. It is not a payment privacy scheme. It is a general-purpose data commitment and verification protocol that happens to also support private token operations as one of its use cases.
Core Primitive
The fundamental operation of the Ghost Protocol is:
- Hash any data into a Poseidon commitment
- Insert the commitment into an on-chain Merkle tree
- Reveal by generating a ZK proof of knowledge of the commitment preimage and Merkle tree membership
- Verify the proof on-chain and record a nullifier to prevent replay
That is the entire protocol at its most abstract level. Everything else — token transfers, credential verification, key distribution, access proofs — is a specialization of this pattern applied to different data types.
Data-Agnostic by Design
The Ghost Protocol does not care what dataHash represents. At the commitment layer, the protocol sees only a field element — the output of a Poseidon hash. The semantics of the data are determined by the application layer, not the protocol layer. This means the same infrastructure supports:
Credentials
A university hashes a degree attestation. The graduate commits it. Later, the graduate proves they hold a valid degree to an employer — without revealing the university, the degree specifics, or any link to the original issuance.
Images
A photographer hashes an original image. The hash is committed on-chain as a provenance record. Later, the photographer can prove they are the original creator without revealing the image, the timestamp of the commitment, or any identifying metadata.
API Keys
A service provider generates an API key and commits its hash on-chain. A client proves they hold a valid key without revealing the key itself. Key rotation creates a new commitment; the old key's nullifier is spent, making it invalid.
Encryption Keys
A user commits the hash of a public encryption key. Recipients can verify the key's authenticity by checking the commitment against the Merkle tree, and the key holder can prove ownership without exposing the key to the chain.
Tokens (GHOST)
A user burns GHOST tokens by committing the token amount, token ID, and associated metadata into the Merkle tree. Later, the user mints fresh tokens by proving knowledge of the commitment. The burn and mint are unlinkable — this is a private transfer.
Bearer Instruments
An entity creates a digital bearer instrument (a ticket, a coupon, a one-time access pass) by committing its hash. The holder proves possession and redeems it by revealing with a ZK proof. The nullifier prevents double-spending.
Key Properties
Unlinkability
The commit (Vanish) and reveal (Summon) transactions cannot be connected by any observer. The ZK proof demonstrates knowledge of a commitment in the Merkle tree without identifying which commitment. The anonymity set is the entire set of commitments in the tree — up to approximately 1 million entries at Merkle depth 20.
Unlinkability holds even against a fully cooperating set of validators. The proof reveals nothing about the index, position, or insertion time of the commitment.
Unforgeability
A valid reveal requires a Groth16 proof that the prover knows the preimage of a commitment that exists in the Merkle tree. Without knowledge of the secret values (secret, nullifier secret, and blinding factor), it is computationally infeasible to generate a valid proof. The soundness of Groth16 on the BN254 curve guarantees this property under standard cryptographic assumptions.
Non-Replayability
Every reveal produces a nullifier — a deterministic value derived from the commitment's secret inputs. The nullifier is recorded on-chain in a registry. If the same commitment is revealed a second time, the nullifier will already exist in the registry, and the transaction will be rejected. This prevents double-spending of tokens, double-use of credentials, and replay of any other commitment type.
The nullifier is derived as:
This formulation ensures that the nullifier is deterministic (the same commitment always produces the same nullifier) but unlinkable (the nullifier cannot be traced back to the commitment without knowing the nullifier secret).
Data Confidentiality
The original data never appears on-chain. Only its Poseidon hash is committed, and the ZK proof reveals only the public outputs defined by the circuit (root, nullifier hash, data hash or recipient, and access tag). The chain stores commitments and nullifiers — never plaintext data.
The Token Flow Is a Special Case
Private token transfers on Specter follow the exact same commit/reveal pattern described above, with one specialization: the dataHash encodes a token amount, token ID, and policy parameters. When a token commitment is revealed, the protocol mints fresh tokens to the specified recipient. When a token commitment is created, the protocol burns the corresponding tokens.
This burn/mint model means there is no custodial pool, no locked funds, and no contract that can be sanctioned or frozen. Tokens are destroyed on commit and created on reveal. The only link between the two operations is the ZK proof — which reveals nothing about the original transaction.
The implications of this design — and the contrast with pool-based approaches like Tornado Cash — are explored in detail in the Commit/Reveal Mechanism section.
Protocol Layers
The Ghost Protocol operates across three layers:
| Layer | Responsibility | Components |
|---|---|---|
| Cryptographic | Commitment generation, proof creation, nullifier derivation | Poseidon hash, Groth16 prover, BN254 curve arithmetic |
| Consensus | Merkle tree management, nullifier registry, proof verification | CometBFT validators, Cosmos SDK modules (x/ghostmint) |
| Application | Data type semantics, policy enforcement, user interaction | EVM smart contracts, GhostMint precompile, client SDKs |
The cryptographic layer is constant across all data types. The consensus layer manages the shared state (Merkle trees and nullifier sets). The application layer determines what happens when a commitment is created or revealed — whether tokens are burned/minted, credentials are verified, or access is granted.
This separation of concerns is what makes the protocol extensible. Supporting a new data type does not require changes to the ZK circuits or the consensus layer. It requires only a new dataHash computation at the application layer and, optionally, a new policy type at the policy layer.