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}