如何使用ark-circom Rust库传入数组类型输入信号?
在ark-circom中传入数组类型输入信号的问题
我需要用基于Rust的ark-circom库传入数组类型的输入信号,但文档里只有简单输入变量的示例,也没找到相关线上资源。多次尝试后确定问题出在数组in的传入方式上,求指导如何在ark-circom中使用数组。
复现错误的Circom代码
pragma circom 2.1.5; include "node_modules/circomlib/circuits/poseidon.circom"; template Main() { component poseidon = Poseidon(2); signal input in[2]; // signal input in1; signal output digest; poseidon.inputs[0] <== in[0]; poseidon.inputs[1] <== in[1]; digest <== poseidon.out; } component main = Main();
无法生成证明的Rust程序
fn main() { let current_dir = env::current_dir().unwrap(); let main_js_path = current_dir.join("circuits/main_js/main.wasm"); let main_r1cs_path = current_dir.join("circuits/main.r1cs"); let cfg = CircomConfig::<Bn254>::new(main_js_path, main_r1cs_path).unwrap(); let vec = vec![1, 2]; // Your vector of integers let s: String = vec.iter().map(|i| i.to_string()).collect(); let big_int = BigInt::parse_bytes(s.as_bytes(), 10).unwrap(); let mut builder = CircomBuilder::new(cfg); builder.push_input("in", big_int); let circom = builder.setup(); let mut rng = rand::thread_rng(); let params = Groth16::<Bn254>::generate_random_parameters_with_reduction(circom, &mut rng).unwrap(); let circom = builder.build().unwrap(); let inputs = circom.get_public_inputs().unwrap(); let proof = Groth16::<Bn254>::prove(¶ms, circom, &mut rng).unwrap(); // Check that the proof is valid let pvk = Groth16::<Bn254>::process_vk(¶ms.vk).unwrap(); let verified = Groth16::<Bn254>::verify_with_processed_vk(&pvk, &inputs, &proof).unwrap(); println!("Verified: {:?}", verified); println!("Inputs: {}", inputs[0]); assert!(verified); }
错误日志
wasm path "/Users/root/Documents/cryptography/groth16_sui_rs/circuits/main_js/main.wasm" r1cs path "/Users/root/Documents/cryptography/groth16_sui_rs/circuits/main_js/main.wasm" Constraint trace requires enabling `ConstraintLayer` Constraint trace requires enabling `ConstraintLayer` Unsatisfied constraint: Some("0") thread 'main' panicked at /Users/root/.cargo/registry/src/index.crates.io-6f17d22bba15001f/ark-circom-0.1.0/src/circom/builder.rs:82:9: assertion failed: { use ark_relations::r1cs::{ConstraintSynthesizer, ConstraintSystem}; let cs = ConstraintSystem::<E::ScalarField>::new_ref(); circom.clone().generate_constraints(cs.clone()).unwrap(); let is_satisfied = cs.is_satisfied().unwrap(); if !is_satisfied { println!("Unsatisfied constraint: {:?}", cs.which_is_unsatisfied().unwrap()); } is_satisfied } stack backtrace: 0: rust_begin_unwind at /rustc/25ef9e3d85d934b27d9dada2f9dd52b1dc63bb04/library/std/src/panicking.rs:647:5 1: core::panicking::panic_fmt at /rustc/25ef9e3d85d934b27d9dada2f9dd52b1dc63bb04/library/core/src/panicking.rs:72:14 2: core::panicking::panic at /rustc/25ef9e3d85d934b27d9dada2f9dd52b1dc63bb04/library/core/src/panicking.rs:144:5 3: ark_circom::circom::builder::CircomBuilder<E>::build at /Users/root/.cargo/registry/src/index.crates.io-6f17d22bba15001f/ark-circom-0.1.0/src/circom/builder.rs:82:9 4: groth16_sui_rs::main at ./src/main.rs:49:18 5: core::ops::function::FnOnce::call_once at /rustc/25ef9e3d85d934b27d9dada2f9dd52b1dc63bb04/library/core/src/ops/function.rs:250:5 note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.
解决方案
你的错误在于把数组元素拼接成单个大整数传入,这不符合ark-circom对数组输入的处理逻辑。正确的做法是为数组的每个索引单独指定输入:
修改后的Rust代码:
fn main() { use ark_bn254::Bn254; use ark_circom::{CircomBuilder, CircomConfig}; use ark_groth16::Groth16; use num_bigint::BigInt; use std::env; use rand; let current_dir = env::current_dir().unwrap(); let main_js_path = current_dir.join("circuits/main_js/main.wasm"); let main_r1cs_path = current_dir.join("circuits/main.r1cs"); let cfg = CircomConfig::<Bn254>::new(main_js_path, main_r1cs_path).unwrap(); let vec = vec![1, 2]; let mut builder = CircomBuilder::new(cfg); // 为数组的每个索引单独传入值 builder.push_input("in[0]", BigInt::from(vec[0])); builder.push_input("in[1]", BigInt::from(vec[1])); let circom = builder.setup(); let mut rng = rand::thread_rng(); let params = Groth16::<Bn254>::generate_random_parameters_with_reduction(circom, &mut rng).unwrap(); let circom = builder.build().unwrap(); let inputs = circom.get_public_inputs().unwrap(); let proof = Groth16::<Bn254>::prove(¶ms, circom, &mut rng).unwrap(); // 验证证明有效性 let pvk = Groth16::<Bn254>::process_vk(¶ms.vk).unwrap(); let verified = Groth16::<Bn254>::verify_with_processed_vk(&pvk, &inputs, &proof).unwrap(); println!("Verified: {:?}", verified); println!("Inputs: {:?}", inputs); assert!(verified); }
关键说明
- ark-circom处理数组输入时,需要通过
数组名[索引]的形式逐个传入元素,而不是将数组拼接成单个值。 - 确保每个数组元素的类型符合要求(这里用
BigInt对应Circom的信号类型)。
内容的提问来源于stack exchange,提问作者Purushotam Sangroula
相关产品推荐
相关产品推荐

