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