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}