Noir-Groth16 is a Rust workspace that turns Noir artifacts into deterministic witness and R1CS outputs for Groth16 tooling.
git clone https://github.com/jamesbachini/Noir-Groth16/
cd Noir-Groth16
./scripts/run_circuit.sh
./scripts/verify_stellar.shFull documentation available at: https://jamesbachini.github.io/Noir-Groth16/
Pipeline:
- Parse Noir artifact JSON + ABI metadata.
- Build and solve witnesses with ACVM from ABI-shaped inputs.
- Lower supported ACIR opcodes into R1CS.
- Emit deterministic artifacts (
.r1cs,.wtns, JSON/bin debug outputs).
Prerequisites:
cargo --version
nargo --version
node --version
npm --version- Edit the default circuit and inputs:
circuits/src/main.nrcircuits/inputs.json
- Run the full pipeline from repo root:
./scripts/run_circuit.shThis performs:
nargo compileforcircuits/noir-cli interopto emit.r1cs/.wtnssnarkjswitness check- Groth16 setup, proof generation, and verification
Outputs are written to target/groth16/:
target/groth16/interop/circuit.r1cstarget/groth16/interop/witness.wtnstarget/groth16/proof/proof.jsontarget/groth16/proof/public.jsontarget/groth16/proof/verification_key.json
Optional overrides:
CIRCUIT_DIR=/path/to/circuit OUT_DIR=/path/to/output PTAU_POWER=14 ./scripts/run_circuit.sh- Optional on-chain verification
./scripts/verify_stellar.shThis will use the stellar cli to deploy a verifier contract to testnet. Then invoke it to verify the proof generated by snarkjs.
Build the CLI:
cargo build -p noir-cliParse artifact and write deterministic parse summary JSON.
noir-cli compile-r1cs test-vectors/fixture_artifact.json --out out/parseOutput:
out/parse/parsed.json
Generate witness outputs from artifact + ABI-shaped inputs.
noir-cli witness test-vectors/fixture_artifact.json test-vectors/fixture_inputs.json --out out/witnessPedantic solving is enabled by default. Pass --no-pedantic to disable strict predicate/selector checks.
Outputs:
out/witness/witness_map.jsonout/witness/witness.binout/witness/witness.wtns
Compile supported ACIR into debug R1CS JSON.
noir-cli r1cs-json test-vectors/fixture_artifact.json --out out/circuit.r1cs.jsonOutput:
out/circuit.r1cs.json
Emit snarkjs-friendly iden3 binaries (.r1cs and .wtns).
noir-cli interop test-vectors/fixture_artifact.json test-vectors/fixture_inputs.json --out out/interopPedantic solving is enabled by default. Pass --no-pedantic to disable strict predicate/selector checks.
Outputs:
out/interop/circuit.r1csout/interop/witness.wtns
The code has been tested against a library of generic Noir example circuits. Feel free to add more.
To run the circuits against the backend:
./examples/run_test_suite.shTarget assumptions:
- Field: BN254
- Output format: iden3
.r1csand.wtns
| ACIR opcode | Status | Notes |
|---|---|---|
AssertZero(Expression) |
Supported | Canonical lowering with deterministic row/wire ordering. |
MemoryInit { .. } |
Supported | Deterministic memory block initialization. |
MemoryOp { .. } |
Supported (with checks) | Static/dynamic memory access lowering; invalid block/index forms fail loudly. |
BlackBoxFuncCall(BlackBoxFuncCall) |
Partially supported | Native lowering for AND, XOR, RANGE, Blake2s, Blake3, EcdsaSecp256k1, EcdsaSecp256r1, Poseidon2Permutation, Sha256Compression, MultiScalarMul, and EmbeddedCurveAdd. Other blackboxes are hint-lowered and require downstream constraints on outputs. |
BrilligCall { .. } |
Supported (guarded) | Lowered via hint plumbing; predicates must be boolean and outputs must be transitively constrained by non-hint rows. |
Call { .. } |
Supported (guarded) | Non-recursive nested calls supported with predicate gating and output binding constraints. |
- Predicates for
Call/BrilligCallthat are not 0/1. - Recursive
Calland invalid call targets (including function id 0 / main). - Blackbox or Brillig opcodes that expose no outputs when their predicate is not provably false.
- Hint outputs not constrained by non-hint R1CS rows.
- Strict mode (default): fails immediately on unsupported/underconstrained behavior.
--allow-unsupported: collects unsupported opcode diagnostics and writesunsupported_opcodes.json(forr1cs-jsonandinterop), but still fails and does not emit final.r1cs/.wtns.- Witness solving mode defaults to pedantic predicate/selector validation. Use
--no-pedanticonwitness/interoponly when intentionally matching legacy non-pedantic ACVM behavior.
crates/noir-acir: Noir artifact parsing (including base64/legacy-compatible bytecode decoding), ABI modeling, witness layout helpers.crates/noir-witness: ABI input flattening, pedantic-by-default ACVM witness solving, witness emitters.crates/noir-r1cs: ACIR lowering, strict/diagnostic unsupported handling, and.r1cs/ debug JSON writers.crates/noir-cli: CLI entrypoints.circuits/: default Noir circuit package used by the one-command proof script.scripts/run_circuit.sh: compile + prove + verify runner forcircuits/.examples/: Noir example packages used by compatibility tests.test-vectors/: Fixture artifacts + inputs used by tests.
Run before PRs:
cargo fmt --all
cargo clippy --all-targets --all-features -- -D warnings
cargo test --workspaceOptional interop smoke test:
npm i -g snarkjs
cargo test -p noir-cli --features interop-test -- --ignoredCompatibility corpus differential test (compiles all real Noir projects under examples/, solves via ACVM, lowers to R1CS, checks satisfaction, then tamper-fails constrained wires):
nargo --version
cargo test -p noir-cli compatibility_corpus_differential_checks -- --ignored --nocaptureExperimental software; not currently suitable for production use.
MIT