Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor(nifs): rm trait FoldingScheme #389

Merged
merged 1 commit into from
Nov 19, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion src/ivc/public_params.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@ use crate::{
accumulator::FoldablePlonkTrace, GetConsistencyMarkers, VanillaFS,
CONSISTENCY_MARKERS_COUNT,
},
FoldingScheme,
},
plonk::PlonkStructure,
poseidon::{random_oracle::ROTrait, ROPair},
Expand Down
5 changes: 2 additions & 3 deletions src/ivc/sangria/incrementally_verifiable_computation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ use crate::{
accumulator::{FoldablePlonkTrace, RelaxedPlonkTrace},
GetConsistencyMarkers, VanillaFS, VerifyError,
},
FoldingScheme, IsSatAccumulator,
},
poseidon::{random_oracle::ROTrait, ROPair},
sps,
Expand Down Expand Up @@ -124,8 +123,8 @@ where
secondary: StepCircuitContext<A2, C2, SC2>,

step: usize,
secondary_nifs_pp: <VanillaFS<C2> as FoldingScheme<C2>>::ProverParam,
primary_nifs_pp: <VanillaFS<C1> as FoldingScheme<C1>>::ProverParam,
secondary_nifs_pp: nifs::sangria::ProverParam<C2>,
primary_nifs_pp: nifs::sangria::ProverParam<C1>,
secondary_trace: [FoldablePlonkTrace<C2>; 1],

debug_mode: bool,
Expand Down
157 changes: 0 additions & 157 deletions src/nifs/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,166 +8,9 @@
//! For more details look at:
//! - Paragraph '3. Folding scheme' at [Nova whitepaper](https://eprint.iacr.org/2021/370)
//! - [nifs module](https://github.com/microsoft/Nova/blob/main/src/nifs.rs) at [Nova codebase](https://github.com/microsoft/Nova)
use halo2_proofs::{arithmetic::CurveAffine, plonk::Error as Halo2Error};
use rayon::prelude::*;

use crate::{
commitment::{self, CommitmentKey},
plonk::{eval::Error as EvalError, PlonkStructure},
poseidon::ROTrait,
sps::Error as SpsError,
};

pub mod protogalaxy;
pub mod sangria;

/// Trait representing the NIFS folding scheme.
pub trait FoldingScheme<C: CurveAffine, const L: usize = 1> {
type Error;

/// Metadata for prover including hash of public params
type ProverParam;

/// Metadata for verifier including hash of public params
type VerifierParam;

/// Type representing the constraint system execution trace
/// By default can use type [`crate::plonk::PlonkTrace`]
type Trace;

/// Type representing the constraint system instance
/// By default can use type [`crate::plonk::PlonkInstance`]
type Instance;

/// Accumulator contains AccumulatorInstance and the corresponding Witness (e.g. [`RelaxedPlonkWitness`])
type Accumulator;

/// The Instance of the Accumulator (e.g. [`RelaxedPlonkInstace`])
type AccumulatorInstance;

/// The proof send from prover to verifier
type Proof;

fn setup_params(
pp_digest: C,
S: PlonkStructure<C::ScalarExt>,
) -> Result<(Self::ProverParam, Self::VerifierParam), Self::Error>;

fn generate_plonk_trace(
ck: &CommitmentKey<C>,
instances: &[Vec<C::ScalarExt>],
witness: &[Vec<C::ScalarExt>],
pp: &Self::ProverParam,
ro_nark: &mut impl ROTrait<C::Base>,
) -> Result<Self::Trace, Self::Error>;

/// Perform the folding operation as a prover.
fn prove(
ck: &CommitmentKey<C>,
pp: &Self::ProverParam,
ro_acc: &mut impl ROTrait<C::Base>,
accumulator: Self::Accumulator,
incoming: &[Self::Trace; L],
) -> Result<(Self::Accumulator, Self::Proof), Self::Error>;

/// Perform the folding operation as a verifier.
fn verify(
vp: &Self::VerifierParam,
ro_nark: &mut impl ROTrait<C::Base>,
ro_acc: &mut impl ROTrait<C::Base>,
accumulator: &Self::AccumulatorInstance,
incoming: &[Self::Instance; L],
proof: &Self::Proof,
) -> Result<Self::AccumulatorInstance, Self::Error>;
}

/// Trait representing the requirements for checking the satisfaction of
/// accumulation relations in a Non-Interactive Folding Scheme (NIFS).
pub trait VerifyAccumulation<C: CurveAffine, const L: usize = 1>: FoldingScheme<C, L> {
type VerifyError;

/// Checks if the given accumulator satisfies the specified polynomial
/// relations.
///
/// This method verifies the accumulation of polynomial relations to ensure
/// they adhere to the constraints defined in the folding scheme.
fn is_sat_accumulation(
S: &PlonkStructure<C::ScalarExt>,
acc: &<Self as FoldingScheme<C, L>>::Accumulator,
) -> Result<(), Self::VerifyError>;

/// Checks if the permutation relations in the accumulator are satisfied.
///
/// This method ensures that the permutation relations, which could
/// originate from copy constraints in the PLONK protocol, are correctly
/// enforced in the accumulator.
fn is_sat_permutation(
S: &PlonkStructure<C::ScalarExt>,
acc: &<Self as FoldingScheme<C, L>>::Accumulator,
) -> Result<(), Self::VerifyError>;

/// Checks if the witness commitments in the accumulator are satisfied.
///
/// This method ensures that the commitments to the witness data are
/// correctly enforced in the accumulator.
fn is_sat_witness_commit(
ck: &CommitmentKey<C>,
acc: &<Self as FoldingScheme<C, L>>::Accumulator,
) -> Result<(), Self::VerifyError>;

/// Checks that the accumulator for instance columns (public input) is correct
///
/// This method ensure that the instance accumulator in `acc` really contains these public
/// inputs
fn is_sat_pub_instances(
acc: &<Self as FoldingScheme<C, L>>::Accumulator,
pub_instances: &[Vec<Vec<C::ScalarExt>>],
) -> Result<(), Self::VerifyError>;
}

/// Trait defining a complete satisfaction check for accumulators
///
/// This trait combines multiple specific satisfaction checks into one method
/// for comprehensive verification of accumulators.
pub trait IsSatAccumulator<C: CurveAffine, const L: usize = 1>: VerifyAccumulation<C, L> {
/// Comprehensive satisfaction check for an accumulator.
///
/// This method runs multiple checks ([`IsSatAccumulation::is_sat_accumulation`],
/// [`IsSatAccumulation::is_sat_permutation`], [`IsSatAccumulation::is_sat_witness_commit`]) to
/// ensure that all required constraints are satisfied in the accumulator.
fn is_sat(
ck: &CommitmentKey<C>,
S: &PlonkStructure<C::ScalarExt>,
acc: &<Self as FoldingScheme<C, L>>::Accumulator,
pub_instances: &[Vec<Vec<C::ScalarExt>>],
) -> Result<(), Vec<Self::VerifyError>> {
let mut errors = vec![];

if let Err(err) = Self::is_sat_accumulation(S, acc) {
errors.push(err);
}

if let Err(err) = Self::is_sat_permutation(S, acc) {
errors.push(err);
}

if let Err(err) = Self::is_sat_witness_commit(ck, acc) {
errors.push(err);
}

if let Err(err) = Self::is_sat_pub_instances(acc, pub_instances) {
errors.push(err);
}

if errors.is_empty() {
Ok(())
} else {
Err(errors)
}
}
}

impl<C: CurveAffine, const L: usize, F: VerifyAccumulation<C, L>> IsSatAccumulator<C, L> for F {}

#[cfg(test)]
pub(crate) mod tests;
86 changes: 55 additions & 31 deletions src/nifs/protogalaxy/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ use std::{iter, marker::PhantomData};
use itertools::Itertools;
use tracing::{debug, instrument, warn};

use super::*;
use crate::{
commitment::CommitmentKey,
constants::MAX_BITS,
Expand All @@ -12,7 +11,7 @@ use crate::{
nifs::protogalaxy::poly::PolyContext,
plonk::{self, PlonkInstance, PlonkStructure, PlonkTrace, PlonkWitness},
polynomial::{lagrange, sparse, univariate::UnivariatePoly},
poseidon::AbsorbInRO,
poseidon::{AbsorbInRO, ROTrait},
sps::{self, SpecialSoundnessVerifier},
util::ScalarToBase,
};
Expand Down Expand Up @@ -275,28 +274,19 @@ pub enum Error {
VerifySps(Box<[(usize, sps::Error)]>),
}

impl<C: CurveAffine, const L: usize> FoldingScheme<C, L> for ProtoGalaxy<C, L> {
type Error = Error;
type ProverParam = ProverParam<C>;
type VerifierParam = VerifierParam<C>;
type Trace = PlonkTrace<C>;
type Instance = PlonkInstance<C>;
type Accumulator = Accumulator<C>;
type AccumulatorInstance = AccumulatorInstance<C>;
type Proof = Proof<C::ScalarExt>;

impl<C: CurveAffine, const L: usize> ProtoGalaxy<C, L> {
fn setup_params(
pp_digest: C,
S: PlonkStructure<C::ScalarExt>,
) -> Result<(Self::ProverParam, Self::VerifierParam), Error> {
) -> Result<(ProverParam<C>, VerifierParam<C>), Error> {
Ok((ProverParam { S, pp_digest }, VerifierParam { pp_digest }))
}

fn generate_plonk_trace(
ck: &CommitmentKey<C>,
instances: &[Vec<C::ScalarExt>],
witness: &[Vec<C::ScalarExt>],
pp: &Self::ProverParam,
pp: &ProverParam<C>,
ro_nark: &mut impl ROTrait<C::Base>,
) -> Result<PlonkTrace<C>, Error> {
Ok(pp
Expand Down Expand Up @@ -336,11 +326,11 @@ impl<C: CurveAffine, const L: usize> FoldingScheme<C, L> for ProtoGalaxy<C, L> {
/// - [`ProtoGalaxy::fold_witness`] & [`ProtoGalaxy::fold_instance`]
fn prove(
_ck: &CommitmentKey<C>,
pp: &Self::ProverParam,
pp: &ProverParam<C>,
ro_acc: &mut impl ROTrait<C::Base>,
accumulator: Self::Accumulator,
accumulator: Accumulator<C>,
incoming: &[PlonkTrace<C>; L],
) -> Result<(Self::Accumulator, Self::Proof), Error> {
) -> Result<(Accumulator<C>, Proof<C::ScalarExt>), Error> {
let ctx = PolyContext::new(&pp.S, incoming);

let delta = Challenges::generate_one::<_, C>(
Expand Down Expand Up @@ -448,13 +438,13 @@ impl<C: CurveAffine, const L: usize> FoldingScheme<C, L> for ProtoGalaxy<C, L> {
/// 6. **Fold the Instance:**
/// - [`ProtoGalaxy::fold_instance`]
fn verify(
vp: &Self::VerifierParam,
vp: &VerifierParam<C>,
ro_nark: &mut impl ROTrait<C::Base>,
ro_acc: &mut impl ROTrait<C::Base>,
accumulator: &Self::AccumulatorInstance,
accumulator: &AccumulatorInstance<C>,
incoming: &[PlonkInstance<C>; L],
proof: &Self::Proof,
) -> Result<Self::AccumulatorInstance, Error> {
proof: &Proof<C::ScalarExt>,
) -> Result<AccumulatorInstance<C>, Error> {
let lagrange_domain = PolyContext::<C::Base>::get_lagrange_domain::<L>();

Self::verify_sps(incoming.iter(), ro_nark)?;
Expand Down Expand Up @@ -504,13 +494,11 @@ pub enum VerifyError<F: PrimeField> {
WitnessCommitmentMismatch(Box<[usize]>),
}

impl<C: CurveAffine, const L: usize> VerifyAccumulation<C, L> for ProtoGalaxy<C, L> {
type VerifyError = VerifyError<C::ScalarExt>;

impl<C: CurveAffine, const L: usize> ProtoGalaxy<C, L> {
fn is_sat_accumulation(
S: &PlonkStructure<C::ScalarExt>,
acc: &Accumulator<C>,
) -> Result<(), Self::VerifyError> {
) -> Result<(), VerifyError<C::ScalarExt>> {
struct Node<F: PrimeField> {
value: F,
height: usize,
Expand Down Expand Up @@ -556,7 +544,7 @@ impl<C: CurveAffine, const L: usize> VerifyAccumulation<C, L> for ProtoGalaxy<C,
fn is_sat_permutation(
S: &PlonkStructure<<C as CurveAffine>::ScalarExt>,
acc: &Accumulator<C>,
) -> Result<(), Self::VerifyError> {
) -> Result<(), VerifyError<C::ScalarExt>> {
let PlonkTrace { u, w } = &acc.trace;

let Z = u
Expand All @@ -580,14 +568,14 @@ impl<C: CurveAffine, const L: usize> VerifyAccumulation<C, L> for ProtoGalaxy<C,
if mismatch_count == 0 {
Ok(())
} else {
Err(Self::VerifyError::PermCheckFailed { mismatch_count })
Err(VerifyError::PermCheckFailed { mismatch_count })
}
}

fn is_sat_witness_commit(
ck: &CommitmentKey<C>,
acc: &<Self as FoldingScheme<C, L>>::Accumulator,
) -> Result<(), Self::VerifyError> {
acc: &Accumulator<C>,
) -> Result<(), VerifyError<C::ScalarExt>> {
let Accumulator {
trace: PlonkTrace { u, w },
..
Expand All @@ -609,11 +597,47 @@ impl<C: CurveAffine, const L: usize> VerifyAccumulation<C, L> for ProtoGalaxy<C,
}

fn is_sat_pub_instances(
_acc: &<Self as FoldingScheme<C, L>>::Accumulator,
_acc: &Accumulator<C>,
_pub_instances: &[Vec<Vec<<C as CurveAffine>::ScalarExt>>],
) -> Result<(), Self::VerifyError> {
) -> Result<(), VerifyError<C::ScalarExt>> {
Ok(())
}

/// Comprehensive satisfaction check for an accumulator.
///
/// This method runs multiple checks ([`IsSatAccumulation::is_sat_accumulation`],
/// [`IsSatAccumulation::is_sat_permutation`], [`IsSatAccumulation::is_sat_witness_commit`]) to
/// ensure that all required constraints are satisfied in the accumulator.
pub fn is_sat(
ck: &CommitmentKey<C>,
S: &PlonkStructure<C::ScalarExt>,
acc: &Accumulator<C>,
pub_instances: &[Vec<Vec<C::ScalarExt>>],
) -> Result<(), Vec<VerifyError<C::ScalarExt>>> {
let mut errors = vec![];

if let Err(err) = Self::is_sat_accumulation(S, acc) {
errors.push(err);
}

if let Err(err) = Self::is_sat_permutation(S, acc) {
errors.push(err);
}

if let Err(err) = Self::is_sat_witness_commit(ck, acc) {
errors.push(err);
}

if let Err(err) = Self::is_sat_pub_instances(acc, pub_instances) {
errors.push(err);
}

if errors.is_empty() {
Ok(())
} else {
Err(errors)
}
}
}

// F(alpha) * L(gamma) + Z(gamma) * K(gamma)
Expand Down
Loading
Loading