arnaucube
arnaucube/sonobePublic Self-hosted repository
Adapt Frontend/Circom for FCircuit Trait (#71)

* initial

* improved z_i

* improved

* Redefined the .circom and the test code for CircomWrapper

* added test function for wrapper_circuit which has circom_fcircuit, but incompatibility error of Pairing and Pallas

* changed the path in the gitignore

* Remove circom generated path

* improved variable vector

* Pallas::Fr

* improved to the primefield

* mentioned the issues:1. extract z_i1(only public output) 2.constraintsSystem and its Ref

* modified

* public input in circom

* generalized; removed the hardcorded value

* Generalization using FpVar::<Fr>::new_input

* initial

* improved z_i

* improved

* Redefined the .circom and the test code for CircomWrapper

* added test function for wrapper_circuit which has circom_fcircuit, but incompatibility error of Pairing and Pallas

* Remove circom generated path

* improved variable vector

* Pallas::Fr

* improved to the primefield

* mentioned the issues:1. extract z_i1(only public output) 2.constraintsSystem and its Ref

* modified

* Small updates:

- update cubic_circuit.circom: remove extra constraint, remove public
  inputs
- remove allocations of inputs in arkworks
- add return of z_{i+1} at the end of CircomtoFCircuit::generate_step_constraints

With this tmp fix the `test_circom_step_constraints` passes, but needs to be iterated and polished.

* Update circom-compat to re-allocate inputs

* update after rebase to latest main: add usage of self.state_len() to circom frontend

* move circom frontend related structs into frontend/circom dir

* clippy lints

* extract_witness

* add comments

* clean

* fmt, lint, and spell

* CI Check trigger

* fmt

* applied the feedback

---------

Co-authored-by: Y5 <76672645+yugonsan@users.noreply.github.com>
Co-authored-by: arnaucube <root@arnaucube.com>
yugocabrio 76672645+yugocabrio@users.noreply.github.com
Mon, 15 Apr 2024 01:58:50 +0900
commit

03f66919a3b1308638ab334caf759314935b7677

parent

4dcb981dd4d2644d3671c4e81080b87e750caa79

M .gitignore → .gitignore

@@ -1,8 +1,8 @@

/target Cargo.lock # Circom generated files -/src/frontend/circom/test_folder/test_circuit.r1cs -/src/frontend/circom/test_folder/test_circuit_js/ +folding-schemes/src/frontend/circom/test_folder/cubic_circuit.r1cs +folding-schemes/src/frontend/circom/test_folder/cubic_circuit_js/ # generated contracts at test time -solidity-verifiers/generated+solidity-verifiers/generated
M folding-schemes/Cargo.toml → folding-schemes/Cargo.toml

@@ -14,7 +14,7 @@ ark-relations = { version = "^0.4.0", default-features = false }

ark-r1cs-std = { version = "0.4.0", default-features = false } # this is patched at the workspace level ark-snark = { version = "^0.4.0"} ark-serialize = "^0.4.0" -ark-circom = { git = "https://github.com/gakonst/ark-circom.git" } +ark-circom = { git = "https://github.com/arnaucube/circom-compat.git" } thiserror = "1.0" rayon = "1.7.0" num-bigint = "0.4"
M folding-schemes/src/frontend/circom/mod.rs → folding-schemes/src/frontend/circom/mod.rs

@@ -1,226 +1,177 @@

-use std::{error::Error, fs::File, io::BufReader, marker::PhantomData, path::PathBuf}; - -use color_eyre::Result; -use num_bigint::BigInt; - -use ark_circom::{circom::r1cs_reader, WitnessCalculator}; -use ark_ec::pairing::Pairing; +use ark_circom::circom::CircomCircuit; use ark_ff::PrimeField; +use ark_r1cs_std::alloc::AllocVar; +use ark_r1cs_std::fields::fp::FpVar; +use ark_r1cs_std::R1CSVar; +use ark_relations::r1cs::{ConstraintSynthesizer, ConstraintSystemRef, SynthesisError}; +use ark_std::fmt::Debug; +use num_bigint::BigInt; +use std::path::PathBuf; -use crate::ccs::r1cs::R1CS; -use crate::utils::vec::SparseMatrix; +use crate::frontend::FCircuit; +use crate::Error; -// Define the sparse matrices on PrimeFiled. -pub type Constraints<F> = (ConstraintVec<F>, ConstraintVec<F>, ConstraintVec<F>); -pub type ConstraintVec<F> = Vec<(usize, F)>; -type ExtractedConstraints<F> = (Vec<Constraints<F>>, usize, usize); -pub type ExtractedConstraintsResult<F> = Result<ExtractedConstraints<F>, Box<dyn Error>>; -pub type R1CSandZ<F> = (R1CS<F>, Vec<F>); +pub mod utils; +use utils::CircomWrapper; -// A struct that wraps Circom functionalities, allowing for extraction of R1CS and witnesses -// based on file paths to Circom's .r1cs and .wasm. -pub struct CircomWrapper<E: Pairing> { - r1cs_filepath: PathBuf, - wasm_filepath: PathBuf, - _marker: PhantomData<E>, +/// Define CircomFCircuit +#[derive(Clone, Debug)] +pub struct CircomFCircuit<F: PrimeField> { + circom_wrapper: CircomWrapper<F>, } -impl<E: Pairing> CircomWrapper<E> { - // Creates a new instance of the CircomWrapper with the file paths. - pub fn new(r1cs_filepath: PathBuf, wasm_filepath: PathBuf) -> Self { - CircomWrapper { - r1cs_filepath, - wasm_filepath, - _marker: PhantomData, - } +impl<F: PrimeField> FCircuit<F> for CircomFCircuit<F> { + type Params = (PathBuf, PathBuf); + + fn new(params: Self::Params) -> Self { + let (r1cs_path, wasm_path) = params; + let circom_wrapper = CircomWrapper::new(r1cs_path, wasm_path); + Self { circom_wrapper } } - // Aggregates multiple functions to obtain R1CS and Z as defined in folding-schemes from Circom. - pub fn extract_r1cs_and_z( - &self, - inputs: &[(String, Vec<BigInt>)], - ) -> Result<R1CSandZ<E::ScalarField>, Box<dyn Error>> { - let (constraints, pub_io_len, num_variables) = self.extract_constraints_from_r1cs()?; - let witness = self.calculate_witness(inputs)?; - self.circom_to_folding_schemes_r1cs_and_z(constraints, &witness, pub_io_len, num_variables) + fn state_len(&self) -> usize { + 1 } - // Extracts constraints from the r1cs file. - pub fn extract_constraints_from_r1cs(&self) -> ExtractedConstraintsResult<E::ScalarField> - where - E: Pairing, - { - // Opens the .r1cs file and create a reader. - let file = File::open(&self.r1cs_filepath)?; - let reader = BufReader::new(file); + fn step_native(&self, _i: usize, z_i: Vec<F>) -> Result<Vec<F>, Error> { + // Converts PrimeField values to BigInt for computing witness. + let input_num_bigint = z_i + .iter() + .map(|val| self.circom_wrapper.ark_primefield_to_num_bigint(*val)) + .collect::<Vec<BigInt>>(); - // Reads the R1CS file and extract the constraints directly. - let r1cs_file = r1cs_reader::R1CSFile::<E>::new(reader)?; - let pub_io_len = (r1cs_file.header.n_pub_in + r1cs_file.header.n_pub_out) as usize; - let r1cs = r1cs_reader::R1CS::<E>::from(r1cs_file); - let num_variables = r1cs.num_variables; - let constraints: Vec<Constraints<E::ScalarField>> = r1cs.constraints; + // Computes witness + let witness = self + .circom_wrapper + .extract_witness(&[("ivc_input".to_string(), input_num_bigint)]) + .map_err(|e| { + Error::WitnessCalculationError(format!("Failed to calculate witness: {}", e)) + })?; - Ok((constraints, pub_io_len, num_variables)) + // Extracts the z_i1(next state) from the witness vector. + let z_i1 = witness[1..1 + self.state_len()].to_vec(); + Ok(z_i1) } - // Converts a set of constraints from ark-circom into R1CS format of folding-schemes. - pub fn convert_to_folding_schemes_r1cs<F>( + fn generate_step_constraints( &self, - constraints: Vec<Constraints<F>>, - pub_io_len: usize, - num_variables: usize, - ) -> R1CS<F> - where - F: PrimeField, - { - let mut a_matrix: Vec<Vec<(F, usize)>> = Vec::new(); - let mut b_matrix: Vec<Vec<(F, usize)>> = Vec::new(); - let mut c_matrix: Vec<Vec<(F, usize)>> = Vec::new(); + cs: ConstraintSystemRef<F>, + _i: usize, + z_i: Vec<FpVar<F>>, + ) -> Result<Vec<FpVar<F>>, SynthesisError> { + let mut input_values = Vec::new(); + // Converts each FpVar to PrimeField value, then to num_bigint::BigInt. + for fp_var in z_i.iter() { + // Extracts the PrimeField value from FpVar. + let primefield_value = fp_var.value()?; + // Converts the PrimeField value to num_bigint::BigInt. + let num_bigint_value = self + .circom_wrapper + .ark_primefield_to_num_bigint(primefield_value); + input_values.push(num_bigint_value); + } - let n_rows = constraints.len(); + let num_bigint_inputs = vec![("ivc_input".to_string(), input_values)]; - for (ai, bi, ci) in constraints { - a_matrix.push( - ai.into_iter() - .map(|(index, scalar)| (scalar, index)) - .collect(), - ); - b_matrix.push( - bi.into_iter() - .map(|(index, scalar)| (scalar, index)) - .collect(), - ); - c_matrix.push( - ci.into_iter() - .map(|(index, scalar)| (scalar, index)) - .collect(), - ); - } + // Extracts R1CS and witness. + let (r1cs, witness) = self + .circom_wrapper + .extract_r1cs_and_witness(&num_bigint_inputs) + .map_err(|_| SynthesisError::AssignmentMissing)?; - let l = pub_io_len; - let n_cols = num_variables; - - let A = SparseMatrix { - n_rows, - n_cols, - coeffs: a_matrix, - }; - let B = SparseMatrix { - n_rows, - n_cols, - coeffs: b_matrix, - }; - let C = SparseMatrix { - n_rows, - n_cols, - coeffs: c_matrix, + // Initializes the CircomCircuit. + let circom_circuit = CircomCircuit { + r1cs, + witness: witness.clone(), + inputs_already_computed: true, }; - R1CS::<F> { l, A, B, C } - } + // Generates the constraints for the circom_circuit. + circom_circuit + .generate_constraints(cs.clone()) + .map_err(|_| SynthesisError::AssignmentMissing)?; - // Calculates the witness given the Wasm filepath and inputs. - pub fn calculate_witness(&self, inputs: &[(String, Vec<BigInt>)]) -> Result<Vec<BigInt>> { - let mut calculator = WitnessCalculator::new(&self.wasm_filepath)?; - calculator.calculate_witness(inputs.iter().cloned(), true) - } + // Checks for constraint satisfaction. + if !cs.is_satisfied().unwrap() { + return Err(SynthesisError::Unsatisfiable); + } - // Converts a num_bigint input to `PrimeField`'s BigInt. - pub fn num_bigint_to_ark_bigint<F: PrimeField>( - &self, - value: &BigInt, - ) -> Result<F::BigInt, Box<dyn Error>> { - let big_uint = value - .to_biguint() - .ok_or_else(|| "BigInt is negative".to_string())?; - F::BigInt::try_from(big_uint).map_err(|_| "BigInt conversion failed".to_string().into()) - } + let w = witness.ok_or(SynthesisError::Unsatisfiable)?; - // Converts R1CS constraints and witness from ark-circom format - // into folding-schemes R1CS and z format. - pub fn circom_to_folding_schemes_r1cs_and_z<F>( - &self, - constraints: Vec<Constraints<F>>, - witness: &[BigInt], - pub_io_len: usize, - num_variables: usize, - ) -> Result<(R1CS<F>, Vec<F>), Box<dyn Error>> - where - F: PrimeField, - { - let folding_schemes_r1cs = - self.convert_to_folding_schemes_r1cs(constraints, pub_io_len, num_variables); + // Extracts the z_i1(next state) from the witness vector. + let z_i1: Vec<FpVar<F>> = + Vec::<FpVar<F>>::new_witness(cs.clone(), || Ok(w[1..1 + self.state_len()].to_vec()))?; - let z: Result<Vec<F>, _> = witness - .iter() - .map(|big_int| { - let ark_big_int = self.num_bigint_to_ark_bigint::<F>(big_int)?; - F::from_bigint(ark_big_int).ok_or_else(|| { - "Failed to convert bigint to field element" - .to_string() - .into() - }) - }) - .collect(); - - z.map(|z| (folding_schemes_r1cs, z)) + Ok(z_i1) } } #[cfg(test)] -mod tests { - use crate::frontend::circom::CircomWrapper; - use ark_bn254::Bn254; - use num_bigint::BigInt; - use std::env; +pub mod tests { + use super::*; + use ark_pallas::Fr; + use ark_r1cs_std::alloc::AllocVar; + use ark_relations::r1cs::{ConstraintSynthesizer, ConstraintSystem}; - /* - test_circuit represents 35 = x^3 + x + 5 in test_folder/test_circuit.circom. - In the test_circom_conversion_success function, x is assigned the value 3, which satisfies the R1CS correctly. - In the test_circom_conversion_failure function, x is assigned the value 6, which doesn't satisfy the R1CS. - */ + // Tests the step_native function of CircomFCircuit. + #[test] + fn test_circom_step_native() { + let r1cs_path = PathBuf::from("./src/frontend/circom/test_folder/cubic_circuit.r1cs"); + let wasm_path = + PathBuf::from("./src/frontend/circom/test_folder/cubic_circuit_js/cubic_circuit.wasm"); - /* - To generate .r1cs and .wasm files, run the below command in the terminal. - bash ./src/frontend/circom/test_folder/compile.sh - */ + let circom_fcircuit = CircomFCircuit::<Fr>::new((r1cs_path, wasm_path)); - fn test_circom_conversion_logic(expect_success: bool, inputs: Vec<(String, Vec<BigInt>)>) { - let current_dir = env::current_dir().unwrap(); - let base_path = current_dir.join("src/frontend/circom/test_folder"); + let z_i = vec![Fr::from(3u32)]; + let z_i1 = circom_fcircuit.step_native(1, z_i).unwrap(); + assert_eq!(z_i1, vec![Fr::from(35u32)]); + } - let r1cs_filepath = base_path.join("test_circuit.r1cs"); - let wasm_filepath = base_path.join("test_circuit_js/test_circuit.wasm"); + // Tests the generate_step_constraints function of CircomFCircuit. + #[test] + fn test_circom_step_constraints() { + let r1cs_path = PathBuf::from("./src/frontend/circom/test_folder/cubic_circuit.r1cs"); + let wasm_path = + PathBuf::from("./src/frontend/circom/test_folder/cubic_circuit_js/cubic_circuit.wasm"); - assert!(r1cs_filepath.exists()); - assert!(wasm_filepath.exists()); + let circom_fcircuit = CircomFCircuit::<Fr>::new((r1cs_path, wasm_path)); - let circom_wrapper = CircomWrapper::<Bn254>::new(r1cs_filepath, wasm_filepath); + let cs = ConstraintSystem::<Fr>::new_ref(); - let (r1cs, z) = circom_wrapper - .extract_r1cs_and_z(&inputs) - .expect("Error processing input"); + let z_i = vec![Fr::from(3u32)]; - // Checks the relationship of R1CS. - let check_result = std::panic::catch_unwind(|| { - r1cs.check_relation(&z).unwrap(); - }); + let z_i_var = Vec::<FpVar<Fr>>::new_witness(cs.clone(), || Ok(z_i)).unwrap(); - match (expect_success, check_result) { - (true, Ok(_)) => {} - (false, Err(_)) => {} - (true, Err(_)) => panic!("Expected success but got a failure."), - (false, Ok(_)) => panic!("Expected a failure but got success."), - } + let cs = ConstraintSystem::<Fr>::new_ref(); + let z_i1_var = circom_fcircuit + .generate_step_constraints(cs.clone(), 1, z_i_var) + .unwrap(); + assert_eq!(z_i1_var.value().unwrap(), vec![Fr::from(35u32)]); } + // Tests the WrapperCircuit with CircomFCircuit. #[test] - fn test_circom_conversion() { - // expect it to pass for correct inputs. - test_circom_conversion_logic(true, vec![("step_in".to_string(), vec![BigInt::from(3)])]); + fn test_wrapper_circomtofcircuit() { + let r1cs_path = PathBuf::from("./src/frontend/circom/test_folder/cubic_circuit.r1cs"); + let wasm_path = + PathBuf::from("./src/frontend/circom/test_folder/cubic_circuit_js/cubic_circuit.wasm"); + + let circom_fcircuit = CircomFCircuit::<Fr>::new((r1cs_path, wasm_path)); + + // Allocates z_i1 by using step_native function. + let z_i = vec![Fr::from(3_u32)]; + let wrapper_circuit = crate::frontend::tests::WrapperCircuit { + FC: circom_fcircuit.clone(), + z_i: Some(z_i.clone()), + z_i1: Some(circom_fcircuit.step_native(0, z_i.clone()).unwrap()), + }; + + let cs = ConstraintSystem::<Fr>::new_ref(); - // expect it to fail for incorrect inputs. - test_circom_conversion_logic(false, vec![("step_in".to_string(), vec![BigInt::from(7)])]); + wrapper_circuit.generate_constraints(cs.clone()).unwrap(); + assert!( + cs.is_satisfied().unwrap(), + "Constraint system is not satisfied" + ); } }
M folding-schemes/src/frontend/circom/test_folder/compile.sh → folding-schemes/src/frontend/circom/test_folder/compile.sh

@@ -1,2 +1,2 @@

#!/bin/bash -circom ./folding-schemes/src/frontend/circom/test_folder/test_circuit.circom --r1cs --wasm --prime bn128 --output ./folding-schemes/src/frontend/circom/test_folder/+circom ./folding-schemes/src/frontend/circom/test_folder/cubic_circuit.circom --r1cs --wasm --prime bn128 --output ./folding-schemes/src/frontend/circom/test_folder/
A folding-schemes/src/frontend/circom/test_folder/cubic_circuit.circom

@@ -0,0 +1,13 @@

+pragma circom 2.0.3; + +template Example () { + signal input ivc_input[1]; + signal output ivc_output[1]; + signal temp; + + temp <== ivc_input[0] * ivc_input[0]; + ivc_output[0] <== temp * ivc_input[0] + ivc_input[0] + 5; +} + +component main {public [ivc_input]} = Example(); +
D folding-schemes/src/frontend/circom/test_folder/test_circuit.circom

@@ -1,13 +0,0 @@

-pragma circom 2.0.3; - -template Example () { - signal input step_in; - signal output step_out; - signal temp; - - temp <== step_in * step_in; - step_out <== temp * step_in + step_in + 5; - step_out === 35; -} - -component main = Example();
A folding-schemes/src/frontend/circom/utils.rs

@@ -0,0 +1,149 @@

+use ark_circom::{ + circom::{r1cs_reader, R1CS}, + WitnessCalculator, +}; +use ark_ff::{BigInteger, PrimeField}; +use color_eyre::Result; +use num_bigint::{BigInt, Sign}; +use std::{fs::File, io::BufReader, marker::PhantomData, path::PathBuf}; + +use crate::Error; + +// A struct that wraps Circom functionalities, allowing for extraction of R1CS and witnesses +// based on file paths to Circom's .r1cs and .wasm. +#[derive(Clone, Debug)] +pub struct CircomWrapper<F: PrimeField> { + r1cs_filepath: PathBuf, + wasm_filepath: PathBuf, + _marker: PhantomData<F>, +} + +impl<F: PrimeField> CircomWrapper<F> { + // Creates a new instance of the CircomWrapper with the file paths. + pub fn new(r1cs_filepath: PathBuf, wasm_filepath: PathBuf) -> Self { + CircomWrapper { + r1cs_filepath, + wasm_filepath, + _marker: PhantomData, + } + } + + // Aggregated function to obtain R1CS and witness from Circom. + pub fn extract_r1cs_and_witness( + &self, + inputs: &[(String, Vec<BigInt>)], + ) -> Result<(R1CS<F>, Option<Vec<F>>), Error> { + // Extracts the R1CS + let file = File::open(&self.r1cs_filepath)?; + let reader = BufReader::new(file); + let r1cs_file = r1cs_reader::R1CSFile::<F>::new(reader)?; + let r1cs = r1cs_reader::R1CS::<F>::from(r1cs_file); + + // Extracts the witness vector + let witness_vec = self.extract_witness(inputs)?; + + Ok((r1cs, Some(witness_vec))) + } + + // Extracts the witness vector as a vector of PrimeField elements. + pub fn extract_witness(&self, inputs: &[(String, Vec<BigInt>)]) -> Result<Vec<F>, Error> { + let witness_bigint = self.calculate_witness(inputs)?; + + witness_bigint + .iter() + .map(|big_int| { + self.num_bigint_to_ark_bigint(big_int) + .and_then(|ark_big_int| { + F::from_bigint(ark_big_int) + .ok_or_else(|| Error::Other("could not get F from bigint".to_string())) + }) + }) + .collect() + } + + // Calculates the witness given the Wasm filepath and inputs. + pub fn calculate_witness( + &self, + inputs: &[(String, Vec<BigInt>)], + ) -> Result<Vec<BigInt>, Error> { + let mut calculator = WitnessCalculator::new(&self.wasm_filepath).map_err(|e| { + Error::WitnessCalculationError(format!("Failed to create WitnessCalculator: {}", e)) + })?; + calculator + .calculate_witness(inputs.iter().cloned(), true) + .map_err(|e| { + Error::WitnessCalculationError(format!("Failed to calculate witness: {}", e)) + }) + } + + // Converts a num_bigint::BigInt to a PrimeField::BigInt. + pub fn num_bigint_to_ark_bigint(&self, value: &BigInt) -> Result<F::BigInt, Error> { + let big_uint = value + .to_biguint() + .ok_or_else(|| Error::BigIntConversionError("BigInt is negative".to_string()))?; + F::BigInt::try_from(big_uint).map_err(|_| { + Error::BigIntConversionError("Failed to convert to PrimeField::BigInt".to_string()) + }) + } + + // Converts a PrimeField element to a num_bigint::BigInt representation. + pub fn ark_primefield_to_num_bigint(&self, value: F) -> BigInt { + let primefield_bigint: F::BigInt = value.into_bigint(); + let bytes = primefield_bigint.to_bytes_be(); + BigInt::from_bytes_be(Sign::Plus, &bytes) + } +} + +#[cfg(test)] +mod tests { + use super::*; + use ark_bn254::Fr; + use ark_circom::circom::{CircomBuilder, CircomConfig}; + use ark_circom::CircomCircuit; + use ark_relations::r1cs::{ConstraintSynthesizer, ConstraintSystem}; + use std::path::PathBuf; + + //To generate .r1cs and .wasm files, run the below command in the terminal. + //bash ./folding-schemes/src/frontend/circom/test_folder/compile.sh + + // Test the satisfication by using the CircomBuilder of circom-compat + #[test] + fn test_circombuilder_satisfied() { + let cfg = CircomConfig::<Fr>::new( + "./src/frontend/circom/test_folder/cubic_circuit_js/cubic_circuit.wasm", + "./src/frontend/circom/test_folder/cubic_circuit.r1cs", + ) + .unwrap(); + let mut builder = CircomBuilder::new(cfg); + builder.push_input("ivc_input", 3); + + let circom = builder.build().unwrap(); + let cs = ConstraintSystem::<Fr>::new_ref(); + circom.generate_constraints(cs.clone()).unwrap(); + assert!(cs.is_satisfied().unwrap()); + } + + // Test the satisfication by using the CircomWrapper + #[test] + fn test_extract_r1cs_and_witness() { + let r1cs_path = PathBuf::from("./src/frontend/circom/test_folder/cubic_circuit.r1cs"); + let wasm_path = + PathBuf::from("./src/frontend/circom/test_folder/cubic_circuit_js/cubic_circuit.wasm"); + + let inputs = vec![("ivc_input".to_string(), vec![BigInt::from(3)])]; + let wrapper = CircomWrapper::<Fr>::new(r1cs_path, wasm_path); + + let (r1cs, witness) = wrapper.extract_r1cs_and_witness(&inputs).unwrap(); + + let cs = ConstraintSystem::<Fr>::new_ref(); + + let circom_circuit = CircomCircuit { + r1cs, + witness, + inputs_already_computed: false, + }; + + circom_circuit.generate_constraints(cs.clone()).unwrap(); + assert!(cs.is_satisfied().unwrap()); + } +}
M folding-schemes/src/frontend/mod.rs → folding-schemes/src/frontend/mod.rs

@@ -1,10 +1,10 @@

-pub mod circom; - use crate::Error; use ark_ff::PrimeField; use ark_r1cs_std::fields::fp::FpVar; use ark_relations::r1cs::{ConstraintSystemRef, SynthesisError}; use ark_std::fmt::Debug; + +pub mod circom; /// FCircuit defines the trait of the circuit of the F function, which is the one being folded (ie. /// inside the agmented F' function).

@@ -44,7 +44,7 @@

#[cfg(test)] pub mod tests { use super::*; - use ark_pallas::Fr; + use ark_bn254::Fr; use ark_r1cs_std::{alloc::AllocVar, eq::EqGadget}; use ark_relations::r1cs::{ ConstraintSynthesizer, ConstraintSystem, ConstraintSystemRef, SynthesisError,
M folding-schemes/src/lib.rs → folding-schemes/src/lib.rs

@@ -32,6 +32,8 @@ #[error("crate::utils::espresso::virtual_polynomial::ArithErrors")]

ArithError(#[from] utils::espresso::virtual_polynomial::ArithErrors), #[error(transparent)] ProtoGalaxy(folding::protogalaxy::ProtoGalaxyError), + #[error("std::io::Error")] + IOError(#[from] std::io::Error), #[error("{0}")] Other(String),

@@ -86,6 +88,10 @@ #[error("Feature '{0}' is not supported and it will not be")]

NotSupported(String), #[error("max i-th step reached (usize limit reached)")] MaxStep, + #[error("Circom Witness calculation error: {0}")] + WitnessCalculationError(String), + #[error("BigInt to PrimeField conversion error: {0}")] + BigIntConversionError(String), } /// FoldingScheme defines trait that is implemented by the diverse folding schemes. It is defined