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