A Noir circuit implementing a privacy-preserving nullifier scheme using Poseidon hashing.
This circuit generates deterministic nullifiers from a private secret, allowing anonymous authentication without revealing the underlying secret.
| Input | Visibility | Purpose |
|---|---|---|
secret_base |
Private | User's secret, never revealed |
app_id |
Public | Application identifier |
scope |
Public | Context/action scope |
| Output | Public | Deterministic nullifier |
Install Nargo (Noir's package manager):
curl -L https://raw.githubusercontent.com/noir-lang/noirup/main/install | bash
noirupnargo checknargo compilenargo executeThis will output the nullifier value and save the witness to target/nullifier_circuit.gz.
Noir 1.0 uses external backends for proof generation. Install Barretenberg:
curl -L https://raw.githubusercontent.com/AztecProtocol/aztec-packages/master/barretenberg/cpp/installation/install | bash
source ~/.zshrc # or restart terminal
# Download v3.0.3 manually (bbup may have issues with newer versions)
curl -L "https://github.com/AztecProtocol/aztec-packages/releases/download/v3.0.3/barretenberg-arm64-darwin.tar.gz" -o /tmp/bb.tar.gz
tar -xzf /tmp/bb.tar.gz -C ~/.bb/Then generate and verify proofs:
# Generate proof (with --write_vk to also output verification key)
bb prove -b ./target/nullifier_circuit.json -w ./target/nullifier_circuit.gz -o ./target/proof --write_vk
# Verify proof
bb verify -k ./target/proof/vk -p ./target/proof/proof -i ./target/proof/public_inputsnargo test-
Identity Secret Derivation: Combines
secret_baseandapp_idusing Poseidon hashidentity_secret = poseidon_hash(secret_base, app_id) -
Nullifier Derivation: Combines
identity_secretandscopeusing Poseidon hashnullifier = poseidon_hash(identity_secret, scope)
The nullifier is deterministic (same inputs produce the same output) but reveals nothing about the secret_base, making it useful for:
- Anonymous authentication
- Voting systems (prevent double-voting)
- Token systems (prevent double-spending)
The Prover.toml file contains example inputs for testing:
secret_base = "12345"
app_id = "1"
scope = "100"Modify these values to test different scenarios.