Semaphore proofs
Once a user joins their Semaphore identity to a Semaphore group, the user can signal anonymously with a zero-knowledge proof that proves the following:
- the user is a member of the group,
- the same user created the signal and the proof.
Developers can use Semaphore for the following:
Generate a proof off-chain​
Use the @semaphore-protocol/proof
library to generate an off-chain proof.
To generate a proof, pass the following parameters to the generateProof
function:
identity
: the Semaphore identity of the user broadcasting the signal and generating the proof;group
: the group to which the user belongs;externalNullifier
: the value that prevents double-signaling;signal
: the signal the user wants to send anonymously;snarkArtifacts
: thezkey
andwasm
trusted setup files.
Install library:​
- npm
- Yarn
- pnpm
npm install @semaphore-protocol/proof@^3
yarn add @semaphore-protocol/proof@^3
pnpm add @semaphore-protocol/proof@^3
In the voting system use case, once all the voters have joined their identities to the ballot group,
a voter can generate a proof to vote for a proposal.
In the call to generateProof
, the voting system passes the unique ballot ID (the Merkle tree root of the group) as the
externalNullifier
to prevent the voter signaling more than once for the ballot.
The following code sample shows how to use generateProof
to generate the voting proof:
import { generateProof } from "@semaphore-protocol/proof"
const externalNullifier = group.root
const signal = 1
const fullProof = await generateProof(identity, group, externalNullifier, signal, {
zkeyFilePath: "./semaphore.zkey",
wasmFilePath: "./semaphore.wasm"
})
If you are generating the proof on the client side, you can avoid adding the snark artifacts because they are fetched automatically:
const fullProof = await generateProof(identity, group, externalNullifier, signal)
Verify a proof off-chain​
Use the @semaphore-protocol/proof
library to verify a Semaphore proof off-chain.
To verify a proof, pass the following to the verifyProof
function:
fullProof
: the Semaphore proof;treeDepth
: the Merkle tree depth.
The following code sample shows how to verify the previously generated proof:
import { verifyProof } from "@semaphore-protocol/proof"
await verifyProof(fullProof, 20) // true or false.
verifyProof
returns a Promise that resolves to true
or false
.
Verify a proof on-chain​
Use the Semaphore.sol
contract to verify proofs on-chain.
See our deployed contracts to find the addresses for your network.
To verify Semaphore proofs in your contract, import ISemaphore.sol
, pass it the Semaphore.sol
address and call the verifyProof
method with following parameters:
groupId
: the identifier of the group;merkleTreeRoot
: the root of the Merkle tree;signal
: the signal the user wants to send anonymously;nullifierHash
: a nullifier hash;externalNullifier
: the value that prevents double-signaling;proof
: a Solidity-compatible Semaphore proof.
You can import ISemaphore.sol
and other Semaphore contracts from the @semaphore-protocol/contracts
NPM module.