Privacy design
The cryptographic core
The source of truth: the field, the Poseidon hash, the fixed-depth Merkle tree, and the nothing-up-my-sleeve zero value. Circuits, contracts, and the SDK must all agree with these definitions.
This page fixes every primitive shh is built on. If any of these change, all three layers — circuits, contracts, SDK — change together and the trusted setup is re-run.
Field
Everything lives in the BN254 scalar field F_p. All commitments, nullifiers, and Merkle nodes are elements of it.
p = 21888242871839275222246405745257275088548364400416034343698204186575808495617In the SDK this is the FIELD_SIZE constant; negative external amounts are mapped into the field with ((v % p) + p) % p.
Hash — Poseidon
Hashing is Poseidon with circomlib parameters. The notation H(a, b, …) means Poseidon over those inputs. The on-chain Poseidon is the EVM contract generated by circomlibjs's poseidonContract, matching the circuit's Poseidon exactly; the SDK uses poseidon-lite, verified byte-equal.
Merkle tree
- Depth
LEVELS = 20— 1,048,576 leaves.- Shape
- Binary, with
Poseidon(2)per node. - Node order
parent = H(left, right), where left/right are chosen by the path index bit.- Empty leaf
ZERO = keccak256("shh") mod p— a nothing-up-my-sleeve zero.
Both shh trees — the state tree and the association tree — share this exact configuration. The same ZERO_VALUE, depth, and node ordering appear in the circuit, the on-chain MerkleTreeWithHistory, and the SDK's MerkleTree.
import { FIELD_SIZE, LEVELS, ZERO_VALUE } from "@shh/sdk";
// LEVELS === 20
// ZERO_VALUE === BigInt(keccak256(toUtf8Bytes("shh"))) % FIELD_SIZECross-component invariant checklist
- Poseidon arity and constants identical in circom and the deployed hasher.
LEVELS,ZERO, and node ordering identical in circuit,MerkleTreeWithHistory, and SDK.- Public-signal ordering identical in circuit, exported verifier, and contract call sites.
amountbit-width (248) enforced in the circuit and respected by the SDK.
The two value models built on this core are detailed in Profile A — Shielded and Profile B — Privacy Pool.