ZK项目中如何将BigInt数组表示转换为单个整数表示?
将Arkworks中的BigInt数组表示转换为单个十进制整数
你遇到的是Arkworks库中BigInt的分段存储特性——它用小端序的u64 limbs数组来存储大整数(每个limb是64位片段,从最低位到最高位排列)。要得到完整的十进制整数,只需将这些limbs拼接成标准大整数即可。
解决方法
利用你已引入的num_bigint库,通过字节转换直接拼接limbs是最高效的方式:
- 新增转换函数,将Arkworks的
BigInt转换为num_bigint::BigUint:
use num_bigint::BigUint; fn ark_bigint_to_biguint(ark_bigint: &ark_ff::BigInt<ark_bn254::FrConfig>) -> BigUint { let mut bytes = Vec::new(); // 遍历每个limb,转换为小端字节并拼接 for &limb in ark_bigint.as_ref() { bytes.extend_from_slice(&limb.to_le_bytes()); } // 从小端字节生成完整BigUint BigUint::from_bytes_le(&bytes) }
- 修改原代码中的打印逻辑:
替换原有的println!("Inputs: {:?}", inputs[0]);为:
let input_full = ark_bigint_to_biguint(&inputs[0]); println!("Inputs: {}", input_full);
修改后的完整代码
use ark_bn254::Bn254; use ark_circom::CircomBuilder; use ark_circom::CircomConfig; use ark_groth16::Groth16; use ark_snark::SNARK; use num_bigint::BigUint; use std::env; fn ark_bigint_to_biguint(ark_bigint: &ark_ff::BigInt<ark_bn254::FrConfig>) -> BigUint { let mut bytes = Vec::new(); for &limb in ark_bigint.as_ref() { bytes.extend_from_slice(&limb.to_le_bytes()); } BigUint::from_bytes_le(&bytes) } 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 mut builder = CircomBuilder::new(cfg); builder.push_input("in", 7); 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); // 转换并打印完整十进制整数 let input_full = ark_bigint_to_biguint(&inputs[0]); println!("Inputs: {}", input_full); assert!(verified); }
执行后,输出就会变成你预期的单个十进制大整数。
内容的提问来源于stack exchange,提问作者Purushotam Sangroula
相关产品推荐
相关产品推荐

