The Semaphore circuit is the heart of the protocol and consists of three parts:
The diagram above shows how the input signals are used in the Semaphore circuit and how the outputs are calculated.
Proof of membership
The circuit hashes the hash of the identity nullifier with the identity trapdoor to generate an identity commitment. Then, it verifies the proof of membership against the Merkle root and the identity commitment.
treeSiblings[nLevels]: the values along the Merkle path to the user's identity commitment,
treePathIndices[nLevels]: the direction (0/1) per tree level corresponding to the Merkle path to the user's identity commitment,
identityNullifier: the 32-byte identity secret used as nullifier,
identityTrapdoor: the 32-byte identity secret used as trapdoor.
root: The Merkle root of the tree.
The circuit hashes the identity nullifier with the external nullifier and then checks that the result matches the provided nullifier hash. Nullifier hashes saved in a Semaphore smart contract allow the contract to reject a proof that contains a used nullifier hash.
identityNullifier: the 32-byte identity secret used as a nullifier.
externalNullifier: the 32-byte external nullifier.
nullifierHash: the hash of the identity nullifier and the external nullifier; used to prevent double-signaling.
The circuit calculates a dummy square of the signal hash to prevent any tampering with the proof.
signalHash: the hash of the user's signal.