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