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