#![allow(non_snake_case)] #![allow(non_upper_case_globals)] #![allow(non_camel_case_types)] use ark_ec::{pairing::Pairing, CurveGroup}; use ark_ff::PrimeField; use ark_std::rand::CryptoRng; use ark_std::{fmt::Debug, rand::RngCore}; use thiserror::Error; use crate::frontend::FCircuit; pub mod arith; pub mod commitment; pub mod constants; pub mod folding; pub mod frontend; pub mod transcript; pub mod utils; #[derive(Debug, Error)] pub enum Error { // Wrappers on top of other errors #[error("ark_relations::r1cs::SynthesisError")] SynthesisError(#[from] ark_relations::r1cs::SynthesisError), #[error("ark_serialize::SerializationError")] SerializationError(#[from] ark_serialize::SerializationError), #[error("ark_poly_commit::Error")] PolyCommitError(#[from] ark_poly_commit::Error), #[error("crate::utils::espresso::virtual_polynomial::ArithErrors")] ArithError(#[from] utils::espresso::virtual_polynomial::ArithErrors), #[error(transparent)] ProtoGalaxy(folding::protogalaxy::ProtoGalaxyError), #[error("std::io::Error")] IOError(#[from] std::io::Error), // Relation errors #[error("Relation not satisfied")] NotSatisfied, #[error("SNARK verification failed")] SNARKVerificationFail, #[error("IVC verification failed")] IVCVerificationFail, #[error("zkIVC verification failed")] zkIVCVerificationFail, #[error("R1CS instance is expected to not be relaxed")] R1CSUnrelaxedFail, #[error("Could not find the inner ConstraintSystem")] NoInnerConstraintSystem, #[error("Sum-check prove failed: {0}")] SumCheckProveError(String), #[error("Sum-check verify failed: {0}")] SumCheckVerifyError(String), // Comparators errors #[error("Not equal")] NotEqual, #[error("Vectors should have the same length ({0}: {1}, {2}: {3})")] NotSameLength(String, usize, String, usize), #[error("Vector's length ({0}) is not the expected ({1})")] NotExpectedLength(usize, usize), #[error("Vector ({0}) length ({1}) is not a power of two")] NotPowerOfTwo(String, usize), #[error("Can not be empty")] Empty, #[error("Value out of bounds")] OutOfBounds, #[error("Could not construct the Evaluation Domain")] NewDomainFail, #[error("The number of folded steps must be greater than 1")] NotEnoughSteps, #[error("Evaluation failed")] EvaluationFail, #[error("{0} can not be zero")] CantBeZero(String), // Commitment errors #[error("Pedersen parameters length is not sufficient (generators.len={0} < vector.len={1} unsatisfied)")] PedersenParamsLen(usize, usize), #[error("Blinding factor not 0 for Commitment without hiding")] BlindingNotZero, #[error("Blinding factors incorrect, blinding is set to {0} but blinding values are {1}")] IncorrectBlinding(bool, String), #[error("Commitment verification failed")] CommitmentVerificationFail, // Other #[error("{0}")] Other(String), #[error("Randomness for blinding not found")] MissingRandomness, #[error("Missing value: {0}")] MissingValue(String), #[error("Feature '{0}' not supported yet")] NotSupportedYet(String), #[error("Feature '{0}' is not supported and it will not be")] NotSupported(String), #[error("max i-th step reached (usize limit reached)")] MaxStep, #[error("Witness calculation error: {0}")] WitnessCalculationError(String), #[error("BigInt to PrimeField conversion error: {0}")] BigIntConversionError(String), #[error("Failed to serde: {0}")] JSONSerdeError(String), #[error("Multi instances folding not supported in this scheme")] NoMultiInstances, #[error("Missing 'other' instances, since this is a multi-instances folding scheme")] MissingOtherInstances, } /// FoldingScheme defines trait that is implemented by the diverse folding schemes. It is defined /// over a cycle of curves (C1, C2), where: /// - C1 is the main curve, which ScalarField we use as our F for all the field operations /// - C2 is the auxiliary curve, which we use for the commitments, whose BaseField (for point /// coordinates) are in the C1::ScalarField. /// In other words, C1.Fq == C2.Fr, and C1.Fr == C2.Fq. pub trait FoldingScheme: Clone + Debug where C1: CurveGroup, C2::BaseField: PrimeField, FC: FCircuit, { type PreprocessorParam: Debug + Clone; type ProverParam: Debug + Clone; type VerifierParam: Debug + Clone; type RunningInstance: Debug; // contains the CommittedInstance + Witness type IncomingInstance: Debug; // contains the CommittedInstance + Witness type MultiCommittedInstanceWithWitness: Debug; // type used for the extra instances in the multi-instance folding setting type CFInstance: Debug; // CycleFold CommittedInstance & Witness fn preprocess( rng: impl RngCore, prep_param: &Self::PreprocessorParam, ) -> Result<(Self::ProverParam, Self::VerifierParam), Error>; fn init( params: &(Self::ProverParam, Self::VerifierParam), step_circuit: FC, z_0: Vec, // initial state ) -> Result; fn prove_step( &mut self, rng: impl RngCore, external_inputs: Vec, other_instances: Option, ) -> Result<(), Error>; // returns the state at the current step fn state(&self) -> Vec; // returns the instances at the current step, in the following order: // (running_instance, incoming_instance, cyclefold_instance) fn instances( &self, ) -> ( Self::RunningInstance, Self::IncomingInstance, Self::CFInstance, ); fn verify( vp: Self::VerifierParam, z_0: Vec, // initial state z_i: Vec, // last state // number of steps between the initial state and the last state num_steps: C1::ScalarField, running_instance: Self::RunningInstance, incoming_instance: Self::IncomingInstance, cyclefold_instance: Self::CFInstance, ) -> Result<(), Error>; } /// Trait with auxiliary methods for multi-folding schemes (ie. HyperNova, ProtoGalaxy, etc), /// allowing to create new instances for the multifold. pub trait MultiFolding: Clone + Debug where C1: CurveGroup, C2::BaseField: PrimeField, FC: FCircuit, { type RunningInstance: Debug; type IncomingInstance: Debug; type MultiInstance: Debug; /// Creates a new RunningInstance for the given state, to be folded in the multi-folding step. fn new_running_instance( &self, rng: impl RngCore, state: Vec, external_inputs: Vec, ) -> Result; /// Creates a new IncomingInstance for the given state, to be folded in the multi-folding step. fn new_incoming_instance( &self, rng: impl RngCore, state: Vec, external_inputs: Vec, ) -> Result; } pub trait Decider< C1: CurveGroup, C2: CurveGroup, FC: FCircuit, FS: FoldingScheme, > where C1: CurveGroup, C2::BaseField: PrimeField, { type PreprocessorParam: Debug; type ProverParam: Clone; type Proof; type VerifierParam; type PublicInput: Debug; type CommittedInstance: Clone + Debug; fn preprocess( rng: impl RngCore + CryptoRng, prep_param: Self::PreprocessorParam, fs: FS, ) -> Result<(Self::ProverParam, Self::VerifierParam), Error>; fn prove( rng: impl RngCore + CryptoRng, pp: Self::ProverParam, folding_scheme: FS, ) -> Result; fn verify( vp: Self::VerifierParam, i: C1::ScalarField, z_0: Vec, z_i: Vec, running_instance: &Self::CommittedInstance, incoming_instance: &Self::CommittedInstance, proof: &Self::Proof, // returns `Result` to differentiate between an error occurred while performing // the verification steps, and the verification logic of the scheme not passing. ) -> Result; } /// DeciderOnchain extends the Decider into preparing the calldata pub trait DeciderOnchain where C1: CurveGroup, C2::BaseField: PrimeField, { type Proof; type CommittedInstance: Clone + Debug; fn prepare_calldata( i: C1::ScalarField, z_0: Vec, z_i: Vec, running_instance: &Self::CommittedInstance, incoming_instance: &Self::CommittedInstance, proof: Self::Proof, ) -> Result, Error>; }