Skip to content

Commit 794087c

Browse files
JuArceMauroToscanomaximopalopoli
authored
feat: integrate circom verifier (#1987)
Co-authored-by: MauroFab <[email protected]> Co-authored-by: maximopalopoli <[email protected]>
1 parent 7b35184 commit 794087c

File tree

35 files changed

+576
-70
lines changed

35 files changed

+576
-70
lines changed

.gitignore

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,3 +21,17 @@ infra/ansible/playbooks/files/**.pem
2121

2222
examples/l2/crates/l2/db
2323
examples/l2/crates/l2/zkvm_programs/sp1/elf/sp1_state_transition_program
24+
25+
# Circom
26+
*.ptau
27+
challenge_0003
28+
response_0003
29+
challenge_phase2_0003
30+
circuit.r1cs
31+
circuit.r1cs.json
32+
circuit.sym
33+
response_phase2_0003
34+
witness.wtns
35+
*.zkey
36+
circuit_cpp/
37+
circuit_js

Makefile

Lines changed: 46 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -653,6 +653,29 @@ batcher_send_groth16_bn254_infinite: crates/target/release/aligned ## Send a dif
653653
@mkdir -p scripts/test_files/gnark_groth16_bn254_infinite_script/infinite_proofs
654654
@./crates/cli/send_burst_tasks.sh $(BURST_SIZE) $(START_COUNTER)
655655

656+
batcher_send_circom_groth16_bn128_task: crates/target/release/aligned ## Send a Circom Groth16 BN128 proof to Batcher. Parameters: RPC_URL, NETWORK
657+
@echo "Sending Circom Groth16 BN128 proof to Batcher..."
658+
@cd crates/cli/ && cargo run --release -- submit \
659+
--proving_system CircomGroth16Bn128 \
660+
--proof ../../scripts/test_files/circom_groth16_bn128_script/proof.json \
661+
--public_input ../../scripts/test_files/circom_groth16_bn128_script/public.json \
662+
--vk ../../scripts/test_files/circom_groth16_bn128_script/verification_key.json \
663+
--proof_generator_addr 0x66f9664f97F2b50F62D13eA064982f936dE76657 \
664+
--rpc_url $(RPC_URL) \
665+
--network $(NETWORK)
666+
667+
batcher_send_circom_groth16_bn128_burst: crates/target/release/aligned ## Send a burst of Circom Groth16 BN128 proofs to Batcher. Parameters: RPC_URL, NETWORK, BURST_SIZE
668+
@echo "Sending Circom Groth16 BN128 proof to Batcher..."
669+
@cd crates/cli/ && cargo run --release -- submit \
670+
--proving_system CircomGroth16Bn128 \
671+
--proof ../../scripts/test_files/circom_groth16_bn128_script/proof.json \
672+
--public_input ../../scripts/test_files/circom_groth16_bn128_script/public.json \
673+
--vk ../../scripts/test_files/circom_groth16_bn128_script/verification_key.json \
674+
--proof_generator_addr 0x66f9664f97F2b50F62D13eA064982f936dE76657 \
675+
--repetitions $(BURST_SIZE) \
676+
--rpc_url $(RPC_URL) \
677+
--network $(NETWORK)
678+
656679
batcher_send_proof_with_random_address: ## Send a proof with a random address to Batcher. Parameters: RPC_URL, NETWORK, PROOF_TYPE, REPETITIONS
657680
@cd crates/cli/ && ./send_proof_with_random_address.sh
658681

@@ -762,6 +785,13 @@ generate_gnark_groth16_bn254_ineq_proof: ## Run the gnark_plonk_bn254_script
762785
@echo "Running gnark_groth_bn254_ineq script..."
763786
@go run scripts/test_files/gnark_groth16_bn254_infinite_script/cmd/main.go 1
764787

788+
generate_circom_groth16_bn128_proof: ## Run the circom_groth16_bn128_script
789+
@echo "Running circom_groth16_bn128 script..."
790+
@cd scripts/test_files/circom_groth16_bn128_script && ./generate_proof.sh
791+
792+
generate_circom_groth16_bn128_setup: ## Run the circom_groth16_bn128_script setup
793+
@echo "Running circom_groth16_bn128 script setup..."
794+
@cd scripts/test_files/circom_groth16_bn128_script && ./generate_setup.sh
765795

766796
__CONTRACTS_DEPLOYMENT__: ## ____
767797
deploy_aligned_contracts: ## Deploy Aligned Contracts. Parameters: NETWORK=<mainnet|holesky|sepolia>
@@ -1097,13 +1127,27 @@ docker_batcher_send_groth16_burst:
10971127
--rpc_url $(DOCKER_RPC_URL) \
10981128
--max_fee 0.1ether
10991129

1130+
docker_batcher_send_circom_groth16_bn128_burst:
1131+
@echo "Sending Circom Groth16 BN128 task to Batcher..."
1132+
docker exec $(shell docker ps | grep batcher | awk '{print $$1}') aligned submit \
1133+
--private_key $(DOCKER_PROOFS_PRIVATE_KEY) \
1134+
--proving_system CircomGroth16Bn128 \
1135+
--proof ./scripts/test_files/circom_groth16_bn128_script/proof.json \
1136+
--public_input ./scripts/test_files/circom_groth16_bn128_script/public.json \
1137+
--vk ./scripts/test_files/circom_groth16_bn128_script/verification_key.json \
1138+
--proof_generator_addr $(PROOF_GENERATOR_ADDRESS) \
1139+
--repetitions $(DOCKER_BURST_SIZE) \
1140+
--rpc_url $(DOCKER_RPC_URL) \
1141+
--max_fee 0.1ether
1142+
11001143
# Update target as new proofs are supported.
11011144
docker_batcher_send_all_proofs_burst:
11021145
@$(MAKE) docker_batcher_send_sp1_burst
11031146
@$(MAKE) docker_batcher_send_risc0_burst
11041147
@$(MAKE) docker_batcher_send_plonk_bn254_burst
11051148
@$(MAKE) docker_batcher_send_plonk_bls12_381_burst
11061149
@$(MAKE) docker_batcher_send_groth16_burst
1150+
@$(MAKE) docker_batcher_send_circom_groth16_bn128_burst
11071151

11081152
docker_batcher_send_infinite_groth16:
11091153
docker exec $(shell docker ps | grep batcher | awk '{print $$1}') \
@@ -1141,6 +1185,7 @@ docker_verify_proofs_onchain:
11411185
'
11421186

11431187
DOCKER_PROOFS_WAIT_TIME=60
1188+
DOCKER_SENT_PROOFS=6
11441189

11451190
docker_verify_proof_submission_success:
11461191
@echo "Verifying proofs were successfully submitted..."
@@ -1169,7 +1214,7 @@ docker_verify_proof_submission_success:
11691214
fi; \
11701215
echo "---------------------------------------------------------------------------------------------------"; \
11711216
done; \
1172-
if [ $$(ls -1 ./aligned_verification_data/*.cbor | wc -l) -ne 5 ]; then \
1217+
if [ $$(ls -1 ./aligned_verification_data/*.cbor | wc -l) -ne $(DOCKER_SENT_PROOFS) ]; then \
11731218
echo "ERROR: Some proofs were verified successfully, but some proofs are missing in the aligned_verification_data/ directory"; \
11741219
exit 1; \
11751220
fi; \

common/proving_systems.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ const (
1616
Groth16Bn254
1717
SP1
1818
Risc0
19+
CircomGroth16Bn128
1920
)
2021

2122
func (t *ProvingSystemId) String() string {
@@ -34,6 +35,8 @@ func ProvingSystemIdFromString(provingSystem string) (ProvingSystemId, error) {
3435
return SP1, nil
3536
case "Risc0":
3637
return Risc0, nil
38+
case "CircomGroth16Bn128":
39+
return CircomGroth16Bn128, nil
3740
}
3841

3942
return 0, fmt.Errorf("unknown proving system: %s", provingSystem)
@@ -51,6 +54,8 @@ func ProvingSystemIdToString(provingSystem ProvingSystemId) (string, error) {
5154
return "SP1", nil
5255
case Risc0:
5356
return "Risc0", nil
57+
case CircomGroth16Bn128:
58+
return "CircomGroth16Bn128", nil
5459
}
5560

5661
return "", fmt.Errorf("unknown proving system: %d", provingSystem)
@@ -105,6 +110,8 @@ func (s *ProvingSystemId) UnmarshalCBOR(data []byte) error {
105110
*s = SP1
106111
case "Risc0":
107112
*s = Risc0
113+
case "CircomGroth16Bn128":
114+
*s = CircomGroth16Bn128
108115
}
109116

110117
return nil

crates/batcher/build.rs

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,20 @@
11
use std::{env, path::PathBuf, process::Command};
22

3-
const GO_SRC: &str = "./gnark/verifier.go";
3+
const GO_SRC: &str = "./go_verifiers_lib/verifier.go";
44
const GO_OUT: &str = "libverifier.a";
55
const GO_LIB: &str = "verifier";
66

77
fn main() {
88
let out_dir = PathBuf::from(env::var("OUT_DIR").unwrap());
9+
10+
// Fix the missing dependency issue
11+
let mut get_cmd = Command::new("go");
12+
get_cmd.arg("get")
13+
.arg("github.com/yetanotherco/go-circom-prover-verifier/[email protected]");
14+
15+
let _ = get_cmd.output(); // Run but don't fail if it has issues
16+
17+
// Build library
918
let mut go_build = Command::new("go");
1019
go_build
1120
.arg("build")
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ go 1.22.3
55
require (
66
github.com/consensys/gnark v0.12.0
77
github.com/consensys/gnark-crypto v0.17.0
8+
github.com/yetanotherco/go-circom-prover-verifier v0.0.0-20250618185957-f01a8a8ec4a6
89
)
910

1011
require (
@@ -25,3 +26,5 @@ require (
2526
golang.org/x/sys v0.30.0 // indirect
2627
rsc.io/tmplfunc v0.0.3 // indirect
2728
)
29+
30+
require github.com/ethereum/go-ethereum v1.14.0 // indirect
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ github.com/consensys/gnark-crypto v0.17.0/go.mod h1:A2URlMHUT81ifJ0UlLzSlm7TmnE3
1111
github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=
1212
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
1313
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
14+
github.com/ethereum/go-ethereum v1.14.0/go.mod h1:1STrq471D0BQbCX9He0hUj4bHxX2k6mt5nOQJhDNOJ8=
1415
github.com/fxamacker/cbor/v2 v2.7.0 h1:iM5WgngdRBanHcxugY4JySA0nk1wZorNOpTgCMedv5E=
1516
github.com/fxamacker/cbor/v2 v2.7.0/go.mod h1:pxXPTn3joSm21Gbwsv0w9OSA2y1HFR9qXEeXQVeNoDQ=
1617
github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
@@ -44,6 +45,7 @@ github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOf
4445
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
4546
github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM=
4647
github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg=
48+
github.com/yetanotherco/go-circom-prover-verifier v0.0.0-20250618185957-f01a8a8ec4a6/go.mod h1:A6TUcQ/lvmwAA/Ir8kRMIX5NcIglk8iNKeHF8Nj6Hu0=
4749
golang.org/x/crypto v0.33.0 h1:IOBPskki6Lysi0lo9qQvbxiQ+FvsCC/YWOecCHAixus=
4850
golang.org/x/crypto v0.33.0/go.mod h1:bVdXmD7IV/4GdElGPozy6U7lWdRXA4qyRVGJV57uQ5M=
4951
golang.org/x/sync v0.11.0 h1:GGz8+XQP4FvTTrjZPzNKTMFtSXH80RAzG+5ghFPgK9w=

crates/batcher/gnark/verifier.go renamed to crates/batcher/go_verifiers_lib/verifier.go

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,13 @@ typedef struct ListRef {
88
const uint8_t *ptr;
99
uintptr_t len;
1010
} ListRef;
11-
12-
1311
*/
1412
import "C"
1513

1614
import (
1715
"bytes"
16+
"github.com/yetanotherco/go-circom-prover-verifier/parsers"
17+
"github.com/yetanotherco/go-circom-prover-verifier/verifier"
1818
"log"
1919
"unsafe"
2020

@@ -119,3 +119,30 @@ func verifyGroth16Proof(proofBytesRef C.ListRef, pubInputBytesRef C.ListRef, ver
119119
err = groth16.Verify(proof, verificationKey, pubInput)
120120
return err == nil
121121
}
122+
123+
//export VerifyCircomGroth16ProofBN128
124+
func VerifyCircomGroth16ProofBN128(proofBytesRef C.ListRef, pubInputBytesRef C.ListRef, verificationKeyBytesRef C.ListRef) bool {
125+
proofBytes := listRefToBytes(proofBytesRef)
126+
pubInputBytes := listRefToBytes(pubInputBytesRef)
127+
verificationKeyBytes := listRefToBytes(verificationKeyBytesRef)
128+
129+
proof, err := parsers.ParseProof(proofBytes)
130+
if err != nil {
131+
log.Printf("Could not parse proof: %v", err)
132+
return false
133+
}
134+
135+
public, err := parsers.ParsePublicSignals(pubInputBytes)
136+
if err != nil {
137+
log.Printf("Could not parse public signals: %v", err)
138+
return false
139+
}
140+
141+
vk, err := parsers.ParseVk(verificationKeyBytes)
142+
if err != nil {
143+
log.Printf("Could not parse verification key: %v", err)
144+
return false
145+
}
146+
147+
return verifier.Verify(vk, proof, public)
148+
}

crates/batcher/src/circom/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
pub mod verifier;
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
use crate::ffi::circom_ffi::VerifyCircomGroth16ProofBN128;
2+
use aligned_sdk::common::types::ProvingSystemId;
3+
4+
pub fn verify_circom(
5+
proving_system: &ProvingSystemId,
6+
proof: &Vec<u8>,
7+
public_input: &Vec<u8>,
8+
verification_key: &Vec<u8>,
9+
) -> bool {
10+
let proof = proof.into();
11+
let public_input = public_input.into();
12+
let verification_key = verification_key.into();
13+
14+
match proving_system {
15+
ProvingSystemId::CircomGroth16Bn128 => unsafe {
16+
VerifyCircomGroth16ProofBN128(proof, public_input, verification_key)
17+
},
18+
_ => false,
19+
}
20+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
use crate::ffi::list_ref::ListRef;
2+
3+
extern "C" {
4+
pub fn VerifyCircomGroth16ProofBN128(
5+
proof: ListRef,
6+
public_input: ListRef,
7+
verification_key: ListRef,
8+
) -> bool;
9+
}

0 commit comments

Comments
 (0)