Skip to main content

Appendix A: Cryptographic Proofs

This appendix provides the full cryptographic specifications underlying the Specter Protocol's Ghost Protocol primitive. It covers hash constructions, field arithmetic, proof systems, circuit definitions, nullifier derivation, and the quantum-safe commitment layer.

Poseidon Hash Family

Specter uses the Poseidon algebraic hash function family, chosen for its efficiency inside arithmetic circuits over prime fields. Three width variants are employed, each matched to a specific data shape.

Poseidon2 (2 inputs)

Used wherever exactly two field elements must be compressed:

  • Merkle tree nodes — hashing left and right children at each level.
  • Nullifier derivation — combining secrets with commitment data (see Nullifier Derivation).
  • Access tags — binding a nullifier secret to a session nonce.
  • Token ID computation — domain-separated hashing of token identifiers.

Poseidon4 (4 inputs)

Used for data commitments and Open Ghost commitments:

commitment = Poseidon4(secret, nullifierSecret, dataHash, blinding)

This construction binds the owner's secret, an independent nullifier secret, the hash of the protected data, and a random blinding factor into a single hiding, binding commitment.

Poseidon7 (7 inputs)

Used for token commitments in the Ghost Protocol:

commitment = Poseidon7(secret, nullifierSecret, tokenId, amount, blinding, policyId, policyParamsHash)

This extended preimage binds the full token metadata — denomination, quantity, and policy parameters — into the commitment, enabling the redemption circuit to enforce amount conservation and policy compliance without revealing any field.

On-Chain Deployment

Only PoseidonT3 (the 2-input variant with a width-3 internal state) is deployed on-chain, costing approximately 30,000 gas per invocation. The larger variants (Poseidon4, Poseidon7) are computed exclusively off-chain during witness generation; the circuit proves correctness of those evaluations without replaying them in the EVM.

Field Arithmetic

BN254 Scalar Field

All circuit arithmetic operates over the BN254 scalar field:

p = 21888242871839275222246405745257275088548364400416034343698204186575808495617

This is an approximately 254-bit prime. Every value entering or leaving a Groth16 circuit — public inputs, private witnesses, hash outputs — must be an element of F_p.

keccak256 Reduction

When keccak256 digests (256 bits) are used as circuit inputs (for example, the quantum commitment layer), the raw output is reduced modulo p:

circuitValue = keccak256(preimage) mod p

Because p is close to 2^254, the resulting distribution over F_p has negligible bias (< 2^-128).

Groth16 Proof System

Specter uses the Groth16 zero-knowledge succinct non-interactive argument of knowledge (zk-SNARK) instantiated over the BN254 curve.

PropertyValue
Proof size256 bytes (constant)
On-chain verification gas~220,000
Pairing curveBN254 (alt_bn128)
Pairing precompileEIP-197
Trusted setupPer-circuit ceremony

Verification uses the EIP-197 precompiled contract for optimal ate pairing checks, available on Ethereum and EVM-compatible chains including Specter's own execution layer.

Circuit Specifications

GhostRedemption Circuit

The redemption circuit proves that a party can legitimately withdraw tokens from the Ghost Protocol without revealing the source commitment, the full amount, or any identifying information.

Public inputs (8 field elements):

IndexNameDescription
0rootMerkle tree root at the time of proof generation
1nullifierUnique nullifier preventing double-spend
2withdrawAmountAmount being withdrawn
3recipientAddress receiving the withdrawal
4changeCommitmentNew commitment for any remaining balance
5tokenIdIdentifier of the token being redeemed
6policyIdReveal policy contract address (as field element)
7policyParamsHashHash of the policy parameters bound at commit time

Constraints enforced (via quadratic R1CS):

  1. Knowledge of preimage — The prover knows (secret, nullifierSecret, tokenId, amount, blinding, policyId, policyParamsHash) such that Poseidon7(...) equals the committed leaf.
  2. Merkle membership — The commitment is a leaf of the Merkle tree with the declared root, verified through a 20-level authentication path.
  3. Nullifier correctness — The declared nullifier equals the deterministic derivation from the commitment's nullifier secret and leaf index (see Nullifier Derivation).
  4. Amount conservationwithdrawAmount + changeAmount == amount, where changeAmount is the balance locked into changeCommitment.
  5. Change commitment validitychangeCommitment is a well-formed Poseidon7 commitment over the change amount and fresh blinding, bound to the same token ID and policy.
  6. Policy binding — The policyId and policyParamsHash in the proof match those embedded in the original commitment, ensuring the reveal policy cannot be altered after deposit.

Access Proof Circuit

The access proof circuit enables a commitment holder to prove they control a specific data commitment and to derive a session-bound access tag, without revealing any secret material.

Public inputs (4 field elements):

IndexNameDescription
0rootMerkle tree root
1dataHashHash of the data being accessed
2sessionNonceUnique nonce for this access session
3accessTagDerived tag proving control

Constraints enforced:

  1. Knowledge of Poseidon4 preimage — The prover knows (secret, nullifierSecret, dataHash, blinding) such that Poseidon4(...) equals a committed leaf.
  2. Merkle membership — The commitment exists in the tree under the declared root, verified through 20 levels.
  3. Access tag correctnessaccessTag = Poseidon2(nullifierSecret, sessionNonce). This binds the proof to a specific session while revealing nothing about the underlying secret or nullifier secret.

Nullifier Derivation

Nullifiers prevent double-spending. Specter derives them deterministically from the commitment's nullifier secret and its position in the Merkle tree:

nullifier = Poseidon2(Poseidon2(nullifierSecret, commitment), leafIndex)

Properties:

  • Deterministic — The same commitment at the same leaf index always produces the same nullifier, so the on-chain NullifierRegistry can detect replays.
  • Unlinkable — Without knowledge of nullifierSecret, an observer cannot link a nullifier to its source commitment.
  • Leaf-index binding — Including leafIndex prevents nullifier collisions if the same commitment value appears at multiple tree positions.

Quantum-Safe Commitment Layer

Specter includes a commit-reveal scheme that provides defense-in-depth against future quantum adversaries.

Commit Phase

At deposit time, the user generates a random quantumSecret and publishes:

quantumCommitment = keccak256(quantumSecret)

This value is stored alongside the Poseidon commitment in the on-chain vault.

Reveal Phase

At redemption time, the user reveals quantumSecret in the clear. The contract verifies:

keccak256(quantumSecret) == storedQuantumCommitment

Security Argument

The keccak256 hash function has 256-bit output. Under Grover's algorithm, a quantum adversary requires approximately 2^128 oracle calls to find a preimage — a workload that remains computationally infeasible even with fault-tolerant quantum hardware. This layer ensures that even if the BN254 discrete-log problem is broken by a future quantum computer, an attacker still cannot forge a valid reveal without the original quantum secret.