It demonstrates how to integrate zero-knowledge proofs from Circom/snarkjs, Gnark, and Arkworks into Sui using Move verifier packages generated by export-sui-verifier.
The current verifier examples use the Groth16 proving system for on-chain verification.
The generated verifiers use Sui's native sui::groth16 module. Generated packages are stored in verifier-contracts, and manual Sui examples are stored in sui_groth16 and sui_rangeproofs.
For more details, see:
Install the generator and the Sui CLI:
cargo install export-sui-verifier --version 0.3.0 --locked
sui --version
export-sui-verifier --helpThe Gnark examples below require export-sui-verifier 0.3.0 or newer so the
CLI can auto-detect native Gnark JSON and Gnark WriteTo binary artifacts.
Run all commands from the zk-sui-example directory unless a step explicitly changes directories.
The usual workflow is:
- Generate or refresh proof artifacts for the circuit.
- Run
export-sui-verifierwith the matching verification key, proof, and public inputs. - Run
sui move testfor the generated package.
circuits/Multiplier contains a simple Circom circuit where c = a * b.
The repository keeps checked proof artifacts for BN254 and BLS12-381.
cd circuits/Multiplier
mkdir -p build_bn
circom Multiplier.circom --r1cs --wasm --sym --output build_bn
cd ../..cd circuits/Multiplier/build_bn
snarkjs powersoftau new bn128 10 pot10_0000.ptau -v
snarkjs powersoftau contribute pot10_0000.ptau pot10_0001.ptau --name="First contribution" -v -e="seed"
snarkjs powersoftau prepare phase2 pot10_0001.ptau pot10_final.ptau -v
snarkjs groth16 setup Multiplier.r1cs pot10_final.ptau Multiplier_0000.zkey
snarkjs zkey contribute Multiplier_0000.zkey Multiplier_final.zkey --name="1st contributor" -v -e="seed"
snarkjs zkey export verificationkey Multiplier_final.zkey ../verification_key_bn.json
node Multiplier_js/generate_witness.js Multiplier_js/Multiplier.wasm input.json witness.wtns
snarkjs groth16 prove Multiplier_final.zkey witness.wtns ../proof_bn.json ../public.json
snarkjs groth16 verify ../verification_key_bn.json ../public.json ../proof_bn.json
cd ../../..export-sui-verifier --vk circuits/Multiplier/verification_key_bn.json --proof circuits/Multiplier/proof_bn.json --public circuits/Multiplier/public.json --out verifier-contracts/multiplier_bn254 --force --run-sui-test
cd verifier-contracts/multiplier_bn254
sui move testcd circuits/Multiplier
mkdir -p build_bls
circom Multiplier.circom --r1cs --wasm --sym --prime bls12381 --output build_bls
cd ../..cd circuits/Multiplier/build_bls
snarkjs powersoftau new bls12-381 10 pot10_0000.ptau -v
snarkjs powersoftau contribute pot10_0000.ptau pot10_0001.ptau --name="First contribution" -v -e="seed"
snarkjs powersoftau prepare phase2 pot10_0001.ptau pot10_final.ptau -v
snarkjs groth16 setup Multiplier.r1cs pot10_final.ptau Multiplier_0000.zkey
snarkjs zkey contribute Multiplier_0000.zkey Multiplier_final.zkey --name="1st contributor" -v -e="seed"
snarkjs zkey export verificationkey Multiplier_final.zkey ../verification_key_bls.json
node Multiplier_js/generate_witness.js Multiplier_js/Multiplier.wasm input.json witness.wtns
snarkjs groth16 prove Multiplier_final.zkey witness.wtns ../proof_bls.json ../public_bls.json
snarkjs groth16 verify ../verification_key_bls.json ../public_bls.json ../proof_bls.json
cd ../../..export-sui-verifier --vk circuits/Multiplier/verification_key_bls.json --proof circuits/Multiplier/proof_bls.json --public circuits/Multiplier/public_bls.json --out verifier-contracts/multiplier_bls12381 --force --run-sui-test
cd verifier-contracts/multiplier_bls12381
sui move testcircom-compat demonstrates generating a BN254 Groth16 proof for the same
circuits/Multiplier circuit through ark-circom. It expects
circuits/Multiplier/Multiplier.r1cs and
circuits/Multiplier/Multiplier_js/Multiplier.wasm, so compile the circuit
first if those files are missing:
cd circuits/Multiplier
circom Multiplier.circom --r1cs --wasm --sym
cd ../..Run the Rust helper from its own directory:
cd circom-compat
cargo run
cargo test
cd ..cargo run prints the generated verification key, proof, and public inputs,
and writes an Arkworks compact bundle to
circom-compat/artifacts/multiplier_bn254.json.
Then generate and test a Sui verifier package from that bundle:
export-sui-verifier --bundle circom-compat/artifacts/multiplier_bn254.json --out verifier-contracts/multiplier_bn254_circom_compat --force --run-sui-testRun the generated package tests directly if you want to re-check it later:
cd verifier-contracts/multiplier_bn254_circom_compat
sui move test
cd ../..circuits/cubic-gnark contains a Gnark circuit and exports the same BLS12-381
proof artifacts in three formats:
- snarkjs-compatible JSON:
verification_key.json,proof.json - native Gnark JSON from
gnark-to-snarkjs:verification_key_gnark.json,proof_gnark.json,public.json - native Gnark
WriteTobinary fromgnark-to-snarkjs:verification_key.bin,proof.bin,public.json
The native Gnark formats require github.com/mysteryon88/gnark-to-snarkjs
v1.1.0 or newer.
cd circuits/cubic-gnark
go run .
cd ../..export-sui-verifier --vk circuits/cubic-gnark/verification_key.json --proof circuits/cubic-gnark/proof.json --out verifier-contracts/cubic_gnark_bls12381 --force --run-sui-test
cd verifier-contracts/cubic_gnark_bls12381
sui move test
cd ../..export-sui-verifier --vk circuits/cubic-gnark/verification_key_gnark.json --proof circuits/cubic-gnark/proof_gnark.json --public circuits/cubic-gnark/public.json --out verifier-contracts/cubic_gnark_native_json_bls12381 --force --run-sui-test
cd verifier-contracts/cubic_gnark_native_json_bls12381
sui move test
cd ../..export-sui-verifier --vk circuits/cubic-gnark/verification_key.bin --proof circuits/cubic-gnark/proof.bin --public circuits/cubic-gnark/public.json --out verifier-contracts/cubic_gnark_bin_bls12381 --force --run-sui-test
cd verifier-contracts/cubic_gnark_bin_bls12381
sui move test
cd ../..circuits/ark-mimc exports compact Groth16 bundles for BN254 and BLS12-381.
cd circuits/ark-mimc
cargo run -- export bn254 artifacts
cargo run -- export bls12_381 artifacts
cargo test test_mimc_groth16_bn254
cargo test test_mimc_groth16_bls12_381
cd ../..export-sui-verifier --bundle circuits/ark-mimc/artifacts/bn254/groth16_artifacts.json --out verifier-contracts/ark_mimc_bn254 --force --run-sui-test
cd verifier-contracts/ark_mimc_bn254
sui move testexport-sui-verifier --bundle circuits/ark-mimc/artifacts/bls12_381/groth16_artifacts.json --out verifier-contracts/ark_mimc_bls12381 --force --run-sui-test
cd verifier-contracts/ark_mimc_bls12381
sui move testcircuits/MulCircuit exports a BLS12-381 multiplication proof.
cd circuits/MulCircuit
cargo run
cd ../..export-sui-verifier --vk circuits/MulCircuit/artifacts/bls12_381/verification_key.json --proof circuits/MulCircuit/artifacts/bls12_381/proof.json --out verifier-contracts/mul_circuit_bls12381 --force --run-sui-test
cd verifier-contracts/mul_circuit_bls12381
sui move testUse proof-data when you already have a generated verifier package and only need Move helper functions for another proof.
export-sui-verifier proof-data --vk circuits/Multiplier/verification_key_bn.json --proof circuits/Multiplier/proof_bn.json --public circuits/Multiplier/public.jsonexport-sui-verifier proof-data --bundle circuits/ark-mimc/artifacts/bn254/groth16_artifacts.jsonsui_groth16 is a manual reference package that calls Sui Groth16 APIs directly.
cd sui_groth16
sui move test
cd ..sui_rangeproofs is a manual Sui Move example for Bulletproof range proof verification. It is not generated by export-sui-verifier; it calls sui::rangeproofs::verify_bulletproofs_ristretto255 directly and converts compressed commitments with sui::ristretto255::g_from_bytes.
cd sui_rangeproofs
sui move test
cd ..- Generated verifier code is not audited; review it before production use.