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