arnaucube
arnaucube/sonobePublic Self-hosted repository
sonobe/folding-schemes/src/lib.rs
folding-schemes/src/lib.rsRaw
  1#![allow(non_snake_case)]
  2#![allow(non_upper_case_globals)]
  3#![allow(non_camel_case_types)]
  4
  5use ark_ec::{pairing::Pairing, CurveGroup};
  6use ark_ff::PrimeField;
  7use ark_std::rand::CryptoRng;
  8use ark_std::{fmt::Debug, rand::RngCore};
  9use thiserror::Error;
 10
 11use crate::frontend::FCircuit;
 12
 13pub mod arith;
 14pub mod commitment;
 15pub mod constants;
 16pub mod folding;
 17pub mod frontend;
 18pub mod transcript;
 19pub mod utils;
 20
 21#[derive(Debug, Error)]
 22pub enum Error {
 23    // Wrappers on top of other errors
 24    #[error("ark_relations::r1cs::SynthesisError")]
 25    SynthesisError(#[from] ark_relations::r1cs::SynthesisError),
 26    #[error("ark_serialize::SerializationError")]
 27    SerializationError(#[from] ark_serialize::SerializationError),
 28    #[error("ark_poly_commit::Error")]
 29    PolyCommitError(#[from] ark_poly_commit::Error),
 30    #[error("crate::utils::espresso::virtual_polynomial::ArithErrors")]
 31    ArithError(#[from] utils::espresso::virtual_polynomial::ArithErrors),
 32    #[error(transparent)]
 33    ProtoGalaxy(folding::protogalaxy::ProtoGalaxyError),
 34    #[error("std::io::Error")]
 35    IOError(#[from] std::io::Error),
 36
 37    // Relation errors
 38    #[error("Relation not satisfied")]
 39    NotSatisfied,
 40    #[error("SNARK verification failed")]
 41    SNARKVerificationFail,
 42    #[error("IVC verification failed")]
 43    IVCVerificationFail,
 44    #[error("R1CS instance is expected to not be relaxed")]
 45    R1CSUnrelaxedFail,
 46    #[error("Could not find the inner ConstraintSystem")]
 47    NoInnerConstraintSystem,
 48    #[error("Sum-check prove failed: {0}")]
 49    SumCheckProveError(String),
 50    #[error("Sum-check verify failed: {0}")]
 51    SumCheckVerifyError(String),
 52
 53    // Comparators errors
 54    #[error("Not equal")]
 55    NotEqual,
 56    #[error("Vectors should have the same length ({0}: {1}, {2}: {3})")]
 57    NotSameLength(String, usize, String, usize),
 58    #[error("Vector's length ({0}) is not the expected ({1})")]
 59    NotExpectedLength(usize, usize),
 60    #[error("Vector ({0}) length ({1}) is not a power of two")]
 61    NotPowerOfTwo(String, usize),
 62    #[error("Can not be empty")]
 63    Empty,
 64    #[error("Value out of bounds")]
 65    OutOfBounds,
 66    #[error("Could not construct the Evaluation Domain")]
 67    NewDomainFail,
 68    #[error("The number of folded steps must be greater than 1")]
 69    NotEnoughSteps,
 70    #[error("Evaluation failed")]
 71    EvaluationFail,
 72    #[error("{0} can not be zero")]
 73    CantBeZero(String),
 74
 75    // Commitment errors
 76    #[error("Pedersen parameters length is not sufficient (generators.len={0} < vector.len={1} unsatisfied)")]
 77    PedersenParamsLen(usize, usize),
 78    #[error("Blinding factor not 0 for Commitment without hiding")]
 79    BlindingNotZero,
 80    #[error("Blinding factors incorrect, blinding is set to {0} but blinding values are {1}")]
 81    IncorrectBlinding(bool, String),
 82    #[error("Commitment verification failed")]
 83    CommitmentVerificationFail,
 84
 85    // Other
 86    #[error("{0}")]
 87    Other(String),
 88    #[error("Randomness for blinding not found")]
 89    MissingRandomness,
 90    #[error("Missing value: {0}")]
 91    MissingValue(String),
 92    #[error("Feature '{0}' not supported yet")]
 93    NotSupportedYet(String),
 94    #[error("Feature '{0}' is not supported and it will not be")]
 95    NotSupported(String),
 96    #[error("max i-th step reached (usize limit reached)")]
 97    MaxStep,
 98    #[error("Witness calculation error: {0}")]
 99    WitnessCalculationError(String),
100    #[error("BigInt to PrimeField conversion error: {0}")]
101    BigIntConversionError(String),
102    #[error("Failed to serde: {0}")]
103    JSONSerdeError(String),
104    #[error("Multi instances folding not supported in this scheme")]
105    NoMultiInstances,
106    #[error("Missing 'other' instances, since this is a multi-instances folding scheme")]
107    MissingOtherInstances,
108}
109
110/// FoldingScheme defines trait that is implemented by the diverse folding schemes. It is defined
111/// over a cycle of curves (C1, C2), where:
112/// - C1 is the main curve, which ScalarField we use as our F for all the field operations
113/// - C2 is the auxiliary curve, which we use for the commitments, whose BaseField (for point
114/// coordinates) are in the C1::ScalarField.
115/// In other words, C1.Fq == C2.Fr, and C1.Fr == C2.Fq.
116pub trait FoldingScheme<C1: CurveGroup, C2: CurveGroup, FC>: Clone + Debug
117where
118    C1: CurveGroup<BaseField = C2::ScalarField, ScalarField = C2::BaseField>,
119    C2::BaseField: PrimeField,
120    FC: FCircuit<C1::ScalarField>,
121{
122    type PreprocessorParam: Debug + Clone;
123    type ProverParam: Debug + Clone;
124    type VerifierParam: Debug + Clone;
125    type RunningInstance: Debug; // contains the CommittedInstance + Witness
126    type IncomingInstance: Debug; // contains the CommittedInstance + Witness
127    type MultiCommittedInstanceWithWitness: Debug; // type used for the extra instances in the multi-instance folding setting
128    type CFInstance: Debug; // CycleFold CommittedInstance & Witness
129
130    fn preprocess(
131        rng: impl RngCore,
132        prep_param: &Self::PreprocessorParam,
133    ) -> Result<(Self::ProverParam, Self::VerifierParam), Error>;
134
135    fn init(
136        params: &(Self::ProverParam, Self::VerifierParam),
137        step_circuit: FC,
138        z_0: Vec<C1::ScalarField>, // initial state
139    ) -> Result<Self, Error>;
140
141    fn prove_step(
142        &mut self,
143        rng: impl RngCore,
144        external_inputs: Vec<C1::ScalarField>,
145        other_instances: Option<Self::MultiCommittedInstanceWithWitness>,
146    ) -> Result<(), Error>;
147
148    // returns the state at the current step
149    fn state(&self) -> Vec<C1::ScalarField>;
150
151    // returns the instances at the current step, in the following order:
152    // (running_instance, incoming_instance, cyclefold_instance)
153    fn instances(
154        &self,
155    ) -> (
156        Self::RunningInstance,
157        Self::IncomingInstance,
158        Self::CFInstance,
159    );
160
161    fn verify(
162        vp: Self::VerifierParam,
163        z_0: Vec<C1::ScalarField>, // initial state
164        z_i: Vec<C1::ScalarField>, // last state
165        // number of steps between the initial state and the last state
166        num_steps: C1::ScalarField,
167        running_instance: Self::RunningInstance,
168        incoming_instance: Self::IncomingInstance,
169        cyclefold_instance: Self::CFInstance,
170    ) -> Result<(), Error>;
171}
172
173/// Trait with auxiliary methods for multi-folding schemes (ie. HyperNova, ProtoGalaxy, etc),
174/// allowing to create new instances for the multifold.
175pub trait MultiFolding<C1: CurveGroup, C2: CurveGroup, FC>: Clone + Debug
176where
177    C1: CurveGroup<BaseField = C2::ScalarField, ScalarField = C2::BaseField>,
178    C2::BaseField: PrimeField,
179    FC: FCircuit<C1::ScalarField>,
180{
181    type RunningInstance: Debug;
182    type IncomingInstance: Debug;
183    type MultiInstance: Debug;
184
185    /// Creates a new RunningInstance for the given state, to be folded in the multi-folding step.
186    fn new_running_instance(
187        &self,
188        rng: impl RngCore,
189        state: Vec<C1::ScalarField>,
190        external_inputs: Vec<C1::ScalarField>,
191    ) -> Result<Self::RunningInstance, Error>;
192
193    /// Creates a new IncomingInstance for the given state, to be folded in the multi-folding step.
194    fn new_incoming_instance(
195        &self,
196        rng: impl RngCore,
197        state: Vec<C1::ScalarField>,
198        external_inputs: Vec<C1::ScalarField>,
199    ) -> Result<Self::IncomingInstance, Error>;
200}
201
202pub trait Decider<
203    C1: CurveGroup,
204    C2: CurveGroup,
205    FC: FCircuit<C1::ScalarField>,
206    FS: FoldingScheme<C1, C2, FC>,
207> where
208    C1: CurveGroup<BaseField = C2::ScalarField, ScalarField = C2::BaseField>,
209    C2::BaseField: PrimeField,
210{
211    type PreprocessorParam: Debug;
212    type ProverParam: Clone;
213    type Proof;
214    type VerifierParam;
215    type PublicInput: Debug;
216    type CommittedInstance: Clone + Debug;
217
218    fn preprocess(
219        rng: impl RngCore + CryptoRng,
220        prep_param: &Self::PreprocessorParam,
221        fs: FS,
222    ) -> Result<(Self::ProverParam, Self::VerifierParam), Error>;
223
224    fn prove(
225        rng: impl RngCore + CryptoRng,
226        pp: Self::ProverParam,
227        folding_scheme: FS,
228    ) -> Result<Self::Proof, Error>;
229
230    fn verify(
231        vp: Self::VerifierParam,
232        i: C1::ScalarField,
233        z_0: Vec<C1::ScalarField>,
234        z_i: Vec<C1::ScalarField>,
235        running_instance: &Self::CommittedInstance,
236        incoming_instance: &Self::CommittedInstance,
237        proof: &Self::Proof,
238        // returns `Result<bool, Error>` to differentiate between an error occurred while performing
239        // the verification steps, and the verification logic of the scheme not passing.
240    ) -> Result<bool, Error>;
241}
242
243/// DeciderOnchain extends the Decider into preparing the calldata
244pub trait DeciderOnchain<E: Pairing, C1: CurveGroup, C2: CurveGroup>
245where
246    C1: CurveGroup<BaseField = C2::ScalarField, ScalarField = C2::BaseField>,
247    C2::BaseField: PrimeField,
248{
249    type Proof;
250    type CommittedInstance: Clone + Debug;
251
252    fn prepare_calldata(
253        i: C1::ScalarField,
254        z_0: Vec<C1::ScalarField>,
255        z_i: Vec<C1::ScalarField>,
256        running_instance: &Self::CommittedInstance,
257        incoming_instance: &Self::CommittedInstance,
258        proof: Self::Proof,
259    ) -> Result<Vec<u8>, Error>;
260}