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