Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 47 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -681,6 +681,30 @@ batcher_send_circom_groth16_bn256_burst: crates/target/release/aligned ## Send a
--rpc_url $(RPC_URL) \
--network $(NETWORK)

batcher_send_circom_groth16_bn256_burst: crates/target/release/aligned ## Send a burst of Circom Groth16 BN256 proofs to Batcher. Parameters: RPC_URL, NETWORK, BURST_SIZE
@echo "Sending Circom Groth16 BN256 proof to Batcher..."
@cd crates/cli/ && cargo run --release -- submit \
--proving_system CircomGroth16Bn256 \
--proof ../../scripts/test_files/circom_groth16_bn256_script/proof.json \
--public_input ../../scripts/test_files/circom_groth16_bn256_script/public.json \
--vk ../../scripts/test_files/circom_groth16_bn256_script/verification_key.json \
--proof_generator_addr 0x66f9664f97F2b50F62D13eA064982f936dE76657 \
--repetitions $(BURST_SIZE) \
--rpc_url $(RPC_URL) \
--network $(NETWORK)

batcher_send_circom_groth16_bn256_no_pub_input_burst: crates/target/release/aligned ## Send a burst of Circom Groth16 BN256 proofs to Batcher. Parameters: RPC_URL, NETWORK, BURST_SIZE
@echo "Sending Circom Groth16 BN256 proof to Batcher..."
@cd crates/cli/ && cargo run --release -- submit \
--proving_system CircomGroth16Bn256 \
--proof ../../scripts/test_files/circom_groth16_bn256_no_pub_input_script/proof.json \
--public_input ../../scripts/test_files/circom_groth16_bn256_no_pub_input_script/public.json \
--vk ../../scripts/test_files/circom_groth16_bn256_no_pub_input_script/verification_key.json \
--proof_generator_addr 0x66f9664f97F2b50F62D13eA064982f936dE76657 \
--repetitions $(BURST_SIZE) \
--rpc_url $(RPC_URL) \
--network $(NETWORK)

batcher_send_proof_with_random_address: ## Send a proof with a random address to Batcher. Parameters: RPC_URL, NETWORK, PROOF_TYPE, REPETITIONS
@cd crates/cli/ && ./send_proof_with_random_address.sh

Expand Down Expand Up @@ -802,6 +826,14 @@ generate_circom_groth16_bn256_setup: ## Run the circom_groth16_bn256_script setu
@echo "Running circom_groth16_bn256 script setup..."
@cd scripts/test_files/circom_groth16_bn256_script && ./generate_setup.sh

generate_circom_groth16_bn256_no_pub_input_proof: ## Run the circom_groth16_bn256_script
@echo "Running circom_groth16_bn256 script..."
@cd scripts/test_files/circom_groth16_bn256_no_pub_input_script && ./generate_proof.sh

generate_circom_groth16_bn256_no_pub_input_setup: ## Run the circom_groth16_bn256_script setup
@echo "Running circom_groth16_bn256_no_pub_input_script setup..."
@cd scripts/test_files/circom_groth16_bn256_no_pub_input_script && ./generate_setup.sh

__CONTRACTS_DEPLOYMENT__: ## ____
deploy_aligned_contracts: ## Deploy Aligned Contracts. Parameters: NETWORK=<mainnet|holesky|sepolia>
@echo "Deploying Aligned Contracts on $(NETWORK) network..."
Expand Down Expand Up @@ -1150,6 +1182,19 @@ docker_batcher_send_circom_groth16_bn256_burst:
--rpc_url $(DOCKER_RPC_URL) \
--max_fee 0.1ether

docker_batcher_send_circom_groth16_bn256_no_pub_input_burst:
@echo "Sending Circom Groth16 BN256 task to Batcher..."
docker exec $(shell docker ps | grep batcher | awk '{print $$1}') aligned submit \
--private_key $(DOCKER_PROOFS_PRIVATE_KEY) \
--proving_system CircomGroth16Bn256 \
--proof ./scripts/test_files/circom_groth16_bn256_no_pub_input_script/proof.json \
--public_input ./scripts/test_files/circom_groth16_bn256_no_pub_input_script/public.json \
--vk ./scripts/test_files/circom_groth16_bn256_no_pub_input_script/verification_key.json \
--proof_generator_addr $(PROOF_GENERATOR_ADDRESS) \
--repetitions $(DOCKER_BURST_SIZE) \
--rpc_url $(DOCKER_RPC_URL) \
--max_fee 0.1ether

# Update target as new proofs are supported.
docker_batcher_send_all_proofs_burst:
@$(MAKE) docker_batcher_send_sp1_burst
Expand All @@ -1158,6 +1203,7 @@ docker_batcher_send_all_proofs_burst:
@$(MAKE) docker_batcher_send_gnark_plonk_bls12_381_burst
@$(MAKE) docker_batcher_send_gnark_groth16_burst
@$(MAKE) docker_batcher_send_circom_groth16_bn256_burst
@$(MAKE) docker_batcher_send_circom_groth16_bn256_no_pub_input_burst

docker_batcher_send_infinite_groth16:
docker exec $(shell docker ps | grep batcher | awk '{print $$1}') \
Expand Down Expand Up @@ -1195,7 +1241,7 @@ docker_verify_proofs_onchain:
'

DOCKER_PROOFS_WAIT_TIME=60
DOCKER_SENT_PROOFS=6
DOCKER_SENT_PROOFS=7

docker_verify_proof_submission_success:
@echo "Verifying proofs were successfully submitted..."
Expand Down
6 changes: 6 additions & 0 deletions crates/batcher/go_verifiers_lib/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,12 @@ module verifier

go 1.22.3

replace github.com/iden3/go-rapidsnark => github.com/yetanotherco/go-rapidsnark v0.0.0-20250829135025-99f9f6b11ecc

replace github.com/iden3/go-rapidsnark/types => github.com/yetanotherco/go-rapidsnark/types v0.0.0-20250829135025-99f9f6b11ecc

replace github.com/iden3/go-rapidsnark/verifier => github.com/yetanotherco/go-rapidsnark/verifier v0.0.0-20250829135025-99f9f6b11ecc

require (
github.com/consensys/gnark v0.12.0
github.com/consensys/gnark-crypto v0.17.0
Expand Down
8 changes: 4 additions & 4 deletions crates/batcher/go_verifiers_lib/go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,6 @@ github.com/google/pprof v0.0.0-20240727154555-813a5fbdbec8/go.mod h1:K1liHPHnj73
github.com/google/subcommands v1.2.0/go.mod h1:ZjhPrFU+Olkh9WazFPsl27BQ4UPiG37m3yTrtFlrHVk=
github.com/iden3/go-iden3-crypto v0.0.17 h1:NdkceRLJo/pI4UpcjVah4lN/a3yzxRUGXqxbWcYh9mY=
github.com/iden3/go-iden3-crypto v0.0.17/go.mod h1:dLpM4vEPJ3nDHzhWFXDjzkn1qHoBeOT/3UEhXsEsP3E=
github.com/iden3/go-rapidsnark/types v0.0.3 h1:f0s1Qdut1qHe1O67+m+xUVRBPwSXnq5j0xSrBi0jqM4=
github.com/iden3/go-rapidsnark/types v0.0.3/go.mod h1:ApgcaUxKIgSRA6fAeFxK7p+lgXXfG4oA2HN5DhFlfF4=
github.com/iden3/go-rapidsnark/verifier v0.0.5 h1:J7y0ovrEjDQoWtZmlrp4tgGng1A9faMeYsQH4igAEqA=
github.com/iden3/go-rapidsnark/verifier v0.0.5/go.mod h1:KgL3Yr9NehlFDI4EIWVLE3UDUi8ulyjbp7HcXSBfiGI=
github.com/ingonyama-zk/icicle/v3 v3.1.1-0.20241118092657-fccdb2f0921b h1:AvQTK7l0PTHODD06PVQX1Tn2o29sRIaKIDOvTJmKurY=
github.com/ingonyama-zk/icicle/v3 v3.1.1-0.20241118092657-fccdb2f0921b/go.mod h1:e0JHb27/P6WorCJS3YolbY5XffS4PGBuoW38OthLkDs=
github.com/leanovate/gopter v0.2.11 h1:vRjThO1EKPb/1NsDXuDrzldR28RLkBflWYcU9CvzWu4=
Expand All @@ -50,6 +46,10 @@ github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOf
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM=
github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg=
github.com/yetanotherco/go-rapidsnark/types v0.0.0-20250829135025-99f9f6b11ecc h1:9d0e1bmYz6pv0p1V8zrx7jALDdgAIZ8bZWSCDxemgE4=
github.com/yetanotherco/go-rapidsnark/types v0.0.0-20250829135025-99f9f6b11ecc/go.mod h1:ApgcaUxKIgSRA6fAeFxK7p+lgXXfG4oA2HN5DhFlfF4=
github.com/yetanotherco/go-rapidsnark/verifier v0.0.0-20250829135025-99f9f6b11ecc h1:JLSkcXpSuKb4fzYMF1qNM0nO2oysvOkpNeCSQunTtUA=
github.com/yetanotherco/go-rapidsnark/verifier v0.0.0-20250829135025-99f9f6b11ecc/go.mod h1:KgL3Yr9NehlFDI4EIWVLE3UDUi8ulyjbp7HcXSBfiGI=
golang.org/x/crypto v0.33.0 h1:IOBPskki6Lysi0lo9qQvbxiQ+FvsCC/YWOecCHAixus=
golang.org/x/crypto v0.33.0/go.mod h1:bVdXmD7IV/4GdElGPozy6U7lWdRXA4qyRVGJV57uQ5M=
golang.org/x/sync v0.11.0 h1:GGz8+XQP4FvTTrjZPzNKTMFtSXH80RAzG+5ghFPgK9w=
Expand Down
50 changes: 40 additions & 10 deletions crates/batcher/go_verifiers_lib/verifier.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@ import "C"
import (
"bytes"
"encoding/json"
"github.com/iden3/go-rapidsnark/types"
"github.com/iden3/go-rapidsnark/verifier"
"fmt"
"math/big"

"log"
"unsafe"
Expand All @@ -24,6 +24,8 @@ import (
"github.com/consensys/gnark/backend/groth16"
"github.com/consensys/gnark/backend/plonk"
"github.com/consensys/gnark/backend/witness"
"github.com/iden3/go-rapidsnark/types"
"github.com/iden3/go-rapidsnark/verifier"
)

func listRefToBytes(listRef C.ListRef) []byte {
Expand Down Expand Up @@ -122,6 +124,20 @@ func verifyGnarkGroth16Proof(proofBytesRef C.ListRef, pubInputBytesRef C.ListRef
return err == nil
}

func bytesToBigInts32(b []byte) ([]*big.Int, error) {
if len(b)%32 != 0 {
return nil, fmt.Errorf("invalid length")
}

inputs := make([]*big.Int, 0, len(b)/32)
for i := 0; i < len(b); i += 32 {
chunk := b[i : i+32]
bi := new(big.Int).SetBytes(chunk)
inputs = append(inputs, bi)
}
return inputs, nil
}

//export VerifyCircomGroth16ProofBN256
func VerifyCircomGroth16ProofBN256(proofBytesRef C.ListRef, pubInputBytesRef C.ListRef, verificationKeyBytesRef C.ListRef) bool {
proofBytes := listRefToBytes(proofBytesRef)
Expand All @@ -131,26 +147,40 @@ func VerifyCircomGroth16ProofBN256(proofBytesRef C.ListRef, pubInputBytesRef C.L
proofData := &types.ProofData{}
err := json.Unmarshal(proofBytes, proofData)
if err != nil {
log.Printf("Could not marshal proof: %v", err)
log.Printf("Could not unmarshal proof: %v", err)
return false
}

parsedProofData, err := verifier.ParseProofData(*proofData)
if err != nil {
log.Printf("Could not parse proof: %v", err)
return false
}

var vkStr verifier.VkJSON
err = json.Unmarshal(verificationKeyBytes, &vkStr)
if err != nil {
log.Printf("Could not unmarshal vk: %v", err)
return false
}

var pubSignals []string
err = json.Unmarshal(pubInputBytes, &pubSignals)
vk, err := verifier.ParseVK(vkStr)
if err != nil {
log.Printf("Error unmarshaling JSON: %v", err)
log.Printf("Could not parse vk: %v", err)
return false
}

zkProof := types.ZKProof{
Proof: proofData,
PubSignals: pubSignals,
inputs, err := bytesToBigInts32(pubInputBytes)
if err != nil {
log.Printf("Could not parse pub inputs: %v", err)
return false
}

err = verifier.VerifyGroth16(zkProof, verificationKeyBytes)
err = verifier.VerifyRaw(vk, parsedProofData, inputs)
if err != nil {
log.Printf("Could not verify Groth16 proof: %v", err)
return false
}

return true
}
15 changes: 11 additions & 4 deletions crates/cli/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -926,10 +926,17 @@ fn verification_data_from_args(args: &SubmitArgs) -> Result<VerificationData, Su
"--vk",
args.verification_key_file_name.clone(),
)?);
pub_input = Some(read_file_option(
"--public_input",
args.pub_input_file_name.clone(),
)?);
let pub_input_file =
read_file_option("--public_input", args.pub_input_file_name.clone())?;
let pub_inputs: Vec<String> = serde_json::from_slice(&pub_input_file)
.map_err(|e| SubmitError::MissingRequiredParameter(e.to_string()))?;

let decode_inputs = aligned_sdk::common::utils::encode_circom_pub_inputs(&pub_inputs)
.map_err(|_| {
SubmitError::MissingRequiredParameter("Invalid public inputs".into())
})?;

pub_input = Some(decode_inputs);
}
}

Expand Down
1 change: 1 addition & 0 deletions crates/sdk/src/common/mod.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
pub mod constants;
pub mod errors;
pub mod types;
pub mod utils;
32 changes: 32 additions & 0 deletions crates/sdk/src/common/utils.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
use ethers::{abi::ethereum_types::FromDecStrErr, types::U256};

/// Encodes Circom public inputs into a single byte vector.
///
/// Circom normally outputs public inputs as a JSON array of strings, where each
/// entry is actually a big integer represented in decimal. For example:
///
/// ```json
/// { "pubInputs": ["123", "456", "789"] }
/// ```
///
/// For on-chain usage (e.g. in Solidity), working with JSON is inefficient.
/// Instead, we prefer the **raw form**: each input is converted to a 32-byte
/// big-endian encoding of the integer, concatenated together. This makes it
/// simple to compute commitments and verify proofs on-chain, since the contract
/// receives a compact `bytes` array rather than parsing JSON.
///
/// Each input must fit in 32 bytes (i.e. < 2^256).
pub fn encode_circom_pub_inputs(input: &[String]) -> Result<Vec<u8>, FromDecStrErr> {
let mut out = Vec::with_capacity(input.len() * 32);

for s in input {
// parse as decimal (base 10). Use from_str_radix(s, 16) if they're hex.
let n = U256::from_dec_str(s)?;
let mut bytes = [0u8; 32];
n.to_big_endian(&mut bytes);

out.extend_from_slice(&bytes);
}

Ok(out)
}
9 changes: 9 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,15 @@ go 1.22.3

toolchain go1.23.4

// Replace with fork that exposes VerifyRaw function for raw byte public inputs.
// The official iden3/go-rapidsnark only provides VerifyGroth16 which expects JSON string
// public inputs, but we need to commit to the raw bytes and VerifyRaw simplifies this work.
replace github.com/iden3/go-rapidsnark => github.com/yetanotherco/go-rapidsnark v0.0.0-20250829135025-99f9f6b11ecc

replace github.com/iden3/go-rapidsnark/types => github.com/yetanotherco/go-rapidsnark/types v0.0.0-20250829135025-99f9f6b11ecc

replace github.com/iden3/go-rapidsnark/verifier => github.com/yetanotherco/go-rapidsnark/verifier v0.0.0-20250829135025-99f9f6b11ecc

require (
github.com/Layr-Labs/eigensdk-go v0.2.0-beta.1
github.com/ethereum/go-ethereum v1.14.0
Expand Down
8 changes: 4 additions & 4 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -192,10 +192,6 @@ github.com/huin/goupnp v1.3.0/go.mod h1:gnGPsThkYa7bFi/KWmEysQRf48l2dvR5bxr2OFck
github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
github.com/iden3/go-iden3-crypto v0.0.17 h1:NdkceRLJo/pI4UpcjVah4lN/a3yzxRUGXqxbWcYh9mY=
github.com/iden3/go-iden3-crypto v0.0.17/go.mod h1:dLpM4vEPJ3nDHzhWFXDjzkn1qHoBeOT/3UEhXsEsP3E=
github.com/iden3/go-rapidsnark/types v0.0.3 h1:f0s1Qdut1qHe1O67+m+xUVRBPwSXnq5j0xSrBi0jqM4=
github.com/iden3/go-rapidsnark/types v0.0.3/go.mod h1:ApgcaUxKIgSRA6fAeFxK7p+lgXXfG4oA2HN5DhFlfF4=
github.com/iden3/go-rapidsnark/verifier v0.0.5 h1:J7y0ovrEjDQoWtZmlrp4tgGng1A9faMeYsQH4igAEqA=
github.com/iden3/go-rapidsnark/verifier v0.0.5/go.mod h1:KgL3Yr9NehlFDI4EIWVLE3UDUi8ulyjbp7HcXSBfiGI=
github.com/ingonyama-zk/icicle/v3 v3.1.1-0.20241118092657-fccdb2f0921b h1:AvQTK7l0PTHODD06PVQX1Tn2o29sRIaKIDOvTJmKurY=
github.com/ingonyama-zk/icicle/v3 v3.1.1-0.20241118092657-fccdb2f0921b/go.mod h1:e0JHb27/P6WorCJS3YolbY5XffS4PGBuoW38OthLkDs=
github.com/jackpal/go-nat-pmp v1.0.2 h1:KzKSgb7qkJvOUTqYl9/Hg/me3pWgBmERKrTGD7BdWus=
Expand Down Expand Up @@ -323,6 +319,10 @@ github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM=
github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg=
github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1 h1:gEOO8jv9F4OT7lGCjxCBTO/36wtF6j2nSip77qHd4x4=
github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1/go.mod h1:Ohn+xnUBiLI6FVj/9LpzZWtj1/D6lUovWYBkxHVV3aM=
github.com/yetanotherco/go-rapidsnark/types v0.0.0-20250829135025-99f9f6b11ecc h1:9d0e1bmYz6pv0p1V8zrx7jALDdgAIZ8bZWSCDxemgE4=
github.com/yetanotherco/go-rapidsnark/types v0.0.0-20250829135025-99f9f6b11ecc/go.mod h1:ApgcaUxKIgSRA6fAeFxK7p+lgXXfG4oA2HN5DhFlfF4=
github.com/yetanotherco/go-rapidsnark/verifier v0.0.0-20250829135025-99f9f6b11ecc h1:JLSkcXpSuKb4fzYMF1qNM0nO2oysvOkpNeCSQunTtUA=
github.com/yetanotherco/go-rapidsnark/verifier v0.0.0-20250829135025-99f9f6b11ecc/go.mod h1:KgL3Yr9NehlFDI4EIWVLE3UDUi8ulyjbp7HcXSBfiGI=
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yusufpapurcu/wmi v1.2.3 h1:E1ctvB7uKFMOJw3fdOW32DwGE9I7t++CRUEMKvFoFiw=
github.com/yusufpapurcu/wmi v1.2.3/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0=
Expand Down
48 changes: 38 additions & 10 deletions operator/pkg/operator.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import (
"time"

rapidsnark_types "github.com/iden3/go-rapidsnark/types"
"github.com/iden3/go-rapidsnark/verifier"
rapidsnark_verifier "github.com/iden3/go-rapidsnark/verifier"

"github.com/ethereum/go-ethereum/crypto"
"github.com/urfave/cli/v2"
Expand Down Expand Up @@ -621,30 +621,58 @@ func (o *Operator) verifyGnarkGroth16Proof(proofBytes []byte, pubInputBytes []by

// verifyCircomGroth16Bn256Proof verifies a Circom Groth16 proof using BN256 curve.
func (o *Operator) verifyCircomGroth16Bn256Proof(proofBytes []byte, pubInputBytes []byte, verificationKeyBytes []byte) bool {
bytesToBigInts32 := func(b []byte) ([]*big.Int, error) {
if len(b)%32 != 0 {
return nil, fmt.Errorf("invalid length")
}

inputs := make([]*big.Int, 0, len(b)/32)
for i := 0; i < len(b); i += 32 {
chunk := b[i : i+32]
bi := new(big.Int).SetBytes(chunk)
inputs = append(inputs, bi)
}
return inputs, nil
}

proofData := &rapidsnark_types.ProofData{}
err := json.Unmarshal(proofBytes, proofData)
if err != nil {
o.Logger.Infof("Could not marshal proof: %v", err)
log.Printf("Could not unmarshal proof: %v", err)
return false
}

parsedProofData, err := rapidsnark_verifier.ParseProofData(*proofData)
if err != nil {
log.Printf("Could not parse proof: %v", err)
return false
}

var vkStr rapidsnark_verifier.VkJSON
err = json.Unmarshal(verificationKeyBytes, &vkStr)
if err != nil {
log.Printf("Could not unmarshal vk: %v", err)
return false
}

var pubSignals []string
err = json.Unmarshal(pubInputBytes, &pubSignals)
vk, err := rapidsnark_verifier.ParseVK(vkStr)
if err != nil {
o.Logger.Infof("Could not marshal public signals: %v", err)
log.Printf("Could not parse vk: %v", err)
return false
}

zkProof := rapidsnark_types.ZKProof{
Proof: proofData,
PubSignals: pubSignals,
inputs, err := bytesToBigInts32(pubInputBytes)
if err != nil {
log.Printf("Could not parse pub inputs: %v", err)
return false
}

err = verifier.VerifyGroth16(zkProof, verificationKeyBytes)
err = rapidsnark_verifier.VerifyRaw(vk, parsedProofData, inputs)
if err != nil {
o.Logger.Infof("Could not verify Circom Groth16 BN256 proof: %v", err)
log.Printf("Could not verify Groth16 proof: %v", err)
return false
}

return true
}

Expand Down
Loading
Loading