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