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