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
73 // Commitment errors
74 #[error("Pedersen parameters length is not sufficient (generators.len={0} < vector.len={1} unsatisfied)")]
75 PedersenParamsLen(usize, usize),
76 #[error("Blinding factor not 0 for Commitment without hiding")]
77 BlindingNotZero,
78 #[error("Commitment verification failed")]
79 CommitmentVerificationFail,
80
81 // Other
82 #[error("{0}")]
83 Other(String),
84 #[error("Randomness for blinding not found")]
85 MissingRandomness,
86 #[error("Missing value: {0}")]
87 MissingValue(String),
88 #[error("Feature '{0}' not supported yet")]
89 NotSupportedYet(String),
90 #[error("Feature '{0}' is not supported and it will not be")]
91 NotSupported(String),
92 #[error("max i-th step reached (usize limit reached)")]
93 MaxStep,
94 #[error("Circom Witness calculation error: {0}")]
95 WitnessCalculationError(String),
96 #[error("BigInt to PrimeField conversion error: {0}")]
97 BigIntConversionError(String),
98}
99
100/// FoldingScheme defines trait that is implemented by the diverse folding schemes. It is defined
101/// over a cycle of curves (C1, C2), where:
102/// - C1 is the main curve, which ScalarField we use as our F for all the field operations
103/// - C2 is the auxiliary curve, which we use for the commitments, whose BaseField (for point
104/// coordinates) are in the C1::ScalarField.
105/// In other words, C1.Fq == C2.Fr, and C1.Fr == C2.Fq.
106pub trait FoldingScheme<C1: CurveGroup, C2: CurveGroup, FC>: Clone + Debug
107where
108 C1: CurveGroup<BaseField = C2::ScalarField, ScalarField = C2::BaseField>,
109 C2::BaseField: PrimeField,
110 FC: FCircuit<C1::ScalarField>,
111{
112 type PreprocessorParam: Debug + Clone;
113 type ProverParam: Debug + Clone;
114 type VerifierParam: Debug + Clone;
115 type RunningInstance: Debug; // contains the CommittedInstance + Witness
116 type IncomingInstance: Debug; // contains the CommittedInstance + Witness
117 type CFInstance: Debug; // CycleFold CommittedInstance & Witness
118
119 fn preprocess(
120 rng: impl RngCore,
121 prep_param: &Self::PreprocessorParam,
122 ) -> Result<(Self::ProverParam, Self::VerifierParam), Error>;
123
124 fn init(
125 params: (Self::ProverParam, Self::VerifierParam),
126 step_circuit: FC,
127 z_0: Vec<C1::ScalarField>, // initial state
128 ) -> Result<Self, Error>;
129
130 fn prove_step(
131 &mut self,
132 rng: impl RngCore,
133 external_inputs: Vec<C1::ScalarField>,
134 ) -> Result<(), Error>;
135
136 // returns the state at the current step
137 fn state(&self) -> Vec<C1::ScalarField>;
138
139 // returns the instances at the current step, in the following order:
140 // (running_instance, incoming_instance, cyclefold_instance)
141 fn instances(
142 &self,
143 ) -> (
144 Self::RunningInstance,
145 Self::IncomingInstance,
146 Self::CFInstance,
147 );
148
149 fn verify(
150 vp: Self::VerifierParam,
151 z_0: Vec<C1::ScalarField>, // initial state
152 z_i: Vec<C1::ScalarField>, // last state
153 // number of steps between the initial state and the last state
154 num_steps: C1::ScalarField,
155 running_instance: Self::RunningInstance,
156 incoming_instance: Self::IncomingInstance,
157 cyclefold_instance: Self::CFInstance,
158 ) -> Result<(), Error>;
159}
160
161pub trait Decider<
162 C1: CurveGroup,
163 C2: CurveGroup,
164 FC: FCircuit<C1::ScalarField>,
165 FS: FoldingScheme<C1, C2, FC>,
166> where
167 C1: CurveGroup<BaseField = C2::ScalarField, ScalarField = C2::BaseField>,
168 C2::BaseField: PrimeField,
169{
170 type PreprocessorParam: Debug;
171 type ProverParam: Clone;
172 type Proof;
173 type VerifierParam;
174 type PublicInput: Debug;
175 type CommittedInstance: Clone + Debug;
176
177 fn preprocess(
178 rng: impl RngCore + CryptoRng,
179 prep_param: &Self::PreprocessorParam,
180 fs: FS,
181 ) -> Result<(Self::ProverParam, Self::VerifierParam), Error>;
182
183 fn prove(
184 rng: impl RngCore + CryptoRng,
185 pp: Self::ProverParam,
186 folding_scheme: FS,
187 ) -> Result<Self::Proof, Error>;
188
189 fn verify(
190 vp: Self::VerifierParam,
191 i: C1::ScalarField,
192 z_0: Vec<C1::ScalarField>,
193 z_i: Vec<C1::ScalarField>,
194 running_instance: &Self::CommittedInstance,
195 incoming_instance: &Self::CommittedInstance,
196 proof: &Self::Proof,
197 // returns `Result<bool, Error>` to differentiate between an error occurred while performing
198 // the verification steps, and the verification logic of the scheme not passing.
199 ) -> Result<bool, Error>;
200}
201
202/// DeciderOnchain extends the Decider into preparing the calldata
203pub trait DeciderOnchain<E: Pairing, C1: CurveGroup, C2: CurveGroup>
204where
205 C1: CurveGroup<BaseField = C2::ScalarField, ScalarField = C2::BaseField>,
206 C2::BaseField: PrimeField,
207{
208 type Proof;
209 type CommittedInstance: Clone + Debug;
210
211 fn prepare_calldata(
212 i: C1::ScalarField,
213 z_0: Vec<C1::ScalarField>,
214 z_i: Vec<C1::ScalarField>,
215 running_instance: &Self::CommittedInstance,
216 incoming_instance: &Self::CommittedInstance,
217 proof: Self::Proof,
218 ) -> Result<Vec<u8>, Error>;
219}