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

Feature/sumcheck #40

Merged
merged 37 commits into from
Dec 15, 2023
Merged
Show file tree
Hide file tree
Changes from 15 commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
8e3d35a
feat: init sumcheck.rs
dmpierre Nov 22, 2023
68c6a9c
chore: rename
dmpierre Nov 22, 2023
6a6b5d1
feat: update lib and add trait for transcript with vec storing challe…
dmpierre Nov 24, 2023
e62379e
bugfix: mut self ref of transcript
dmpierre Nov 24, 2023
717da1d
feat: tentative sum-check using poseidon
dmpierre Nov 24, 2023
25126e4
refactor: remove extension trait and use initial trait
dmpierre Nov 28, 2023
6d19ab6
refactor: stop using extension trait, use initial Transcript trait
dmpierre Nov 28, 2023
c64c030
feat: generic over CurveGroup sum-check verifier and algorithm
dmpierre Nov 28, 2023
313fa1b
feat: implement generic sum-check veriy
dmpierre Nov 28, 2023
35e6b1d
bugfix: cargo clippy --fix
dmpierre Nov 28, 2023
d9c9211
chore: cargo fmt
dmpierre Nov 28, 2023
e80bdbd
feat: (unstable) sum-check implementation
dmpierre Dec 1, 2023
a3182bb
feat: start benches
dmpierre Dec 1, 2023
0933937
chore: run clippy
dmpierre Dec 1, 2023
09c627e
chore: run cargo fmt
dmpierre Dec 1, 2023
09c7973
feat: add sum-check tests + benches
dmpierre Dec 5, 2023
e6a3fa9
chore: clippy + fmt
dmpierre Dec 5, 2023
62e89db
chore: remove unstable sumcheck
dmpierre Dec 6, 2023
93d5c23
chore: delete duplicated sum-check code
dmpierre Dec 6, 2023
b4c81b9
chore: remove deleted sum-check code from lib.rs imports
dmpierre Dec 6, 2023
703b2fb
feat: remove non generic traits, implement sum-check with generic tra…
dmpierre Dec 6, 2023
5b992eb
chore: remove non-generic struct
dmpierre Dec 6, 2023
1c8743d
chore: remove non generic verifier
dmpierre Dec 6, 2023
e6ef4f9
feat: make nifms generic over transcript and update to use poseidon t…
dmpierre Dec 6, 2023
6f953c1
chore: cargo fmt
dmpierre Dec 6, 2023
9ef8141
chore: remove tmp benches
dmpierre Dec 6, 2023
c183339
chore: update cargo.toml
dmpierre Dec 6, 2023
748be57
refactor: remove Generic suffix
dmpierre Dec 6, 2023
3b4e70b
feat: prover state generic over CurveGroup
dmpierre Dec 6, 2023
7ac2c75
chore: disable clippy type complexity warning
dmpierre Dec 6, 2023
812d710
refactor: remove Transcript type and espresso transcript dependency
dmpierre Dec 7, 2023
c403591
refactor: SumCheckProver generic over CurveGroup
dmpierre Dec 9, 2023
5c0ff25
chore: add line to eof for `Cargo.toml`
dmpierre Dec 14, 2023
978776a
bugfix: add error handling on sum-check prove and verify
dmpierre Dec 15, 2023
4fa551d
chore: clippy fix
dmpierre Dec 15, 2023
b12397d
chore: add line at eof
dmpierre Dec 15, 2023
59431ec
fix: use `map_err` and call `to_string()` on `PolyIOPErrors`
dmpierre Dec 15, 2023
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
5 changes: 5 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ ark-vesta = {version="0.4.0"}
ark-bn254 = "0.4.0"
tracing = { version = "0.1", default-features = false, features = [ "attributes" ] }
tracing-subscriber = { version = "0.2" }
criterion = "0.5.1"

[features]
default = ["parallel", "nova", "hypernova"]
Expand All @@ -47,3 +48,7 @@ parallel = [
# changes done between v0.4.0 and this fix which would break compatibility.
[patch.crates-io]
ark-r1cs-std = { git = "https://github.com/arnaucube/ark-r1cs-std-cherry-picked/" }

[[bench]]
name = "bench_sumcheck"
harness = false
87 changes: 87 additions & 0 deletions benches/bench_sumcheck.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
use ark_crypto_primitives::sponge::poseidon::{find_poseidon_ark_and_mds, PoseidonConfig};
use ark_ff::Field;
use ark_ff::PrimeField;
use ark_pallas::{Fr, Projective};
use ark_poly::{DenseMultilinearExtension, MultilinearExtension};
use folding_schemes::utils::sum_check::SumCheckGeneric;
use folding_schemes::{
sum_check_unstable,
transcript::{poseidon::PoseidonTranscript, Transcript},
utils::virtual_polynomial::VirtualPolynomial,
};
use std::sync::Arc;
use std::time::Duration;

pub fn poseidon_test_config<F: PrimeField>() -> PoseidonConfig<F> {
let full_rounds = 8;
let partial_rounds = 31;
let alpha = 5;
let rate = 2;

let (ark, mds) = find_poseidon_ark_and_mds::<F>(
F::MODULUS_BIT_SIZE as u64,
rate,
full_rounds,
partial_rounds,
0,
);

PoseidonConfig::new(
full_rounds as usize,
partial_rounds as usize,
alpha,
mds,
ark,
rate,
1,
)
}

use criterion::{criterion_group, criterion_main, BenchmarkId, Criterion};

fn criterion_benchmark(c: &mut Criterion) {
let mut rng = ark_std::test_rng();
let transcript_config = poseidon_test_config();
let n_vars = 20;
let poly = DenseMultilinearExtension::<Fr>::rand(n_vars, &mut rng);
let virtual_poly = VirtualPolynomial::new_from_mle(&Arc::new(poly.clone()), Fr::ONE);

c.bench_with_input(
BenchmarkId::new("sumcheck unstable [prove]", "some polynomial"),
&poly,
|b, poly| {
b.iter(|| {
let mut prover_transcript =
PoseidonTranscript::<Projective>::new(&transcript_config);
let mut sumcheck = sum_check_unstable::SumCheck::<Projective>::new(poly);
sumcheck.prove(&mut prover_transcript).unwrap()
})
},
);

c.bench_with_input(
BenchmarkId::new("sumcheck hyperplonk [prove]", "some polynomial"),
&virtual_poly,
|b, virtual_poly| {
b.iter(|| {
let mut poseidon_transcript_prove: PoseidonTranscript<Projective> =
PoseidonTranscript::<Projective>::new(&transcript_config);
let _sum_check =
folding_schemes::sum_check::SumCheck::<
Projective,
PoseidonTranscript<Projective>,
>::prove(virtual_poly, &mut poseidon_transcript_prove)
.unwrap();
})
},
);
}

criterion_group!(
name = benches;
config = Criterion::default()
.measurement_time(Duration::from_secs(30))
.sample_size(100);
targets = criterion_benchmark
);
criterion_main!(benches);
2 changes: 2 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ pub mod decider;
pub mod folding;
pub mod frontend;
pub mod pedersen;
pub mod sum_check;
pub mod sum_check_unstable;
pub mod utils;

#[derive(Debug, Error, PartialEq)]
Expand Down
145 changes: 145 additions & 0 deletions src/sum_check.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
use crate::transcript::Transcript;
use crate::utils::sum_check::structs::{
IOPProof, IOPProverMessage, IOPProverState, IOPVerifierStateGeneric,
};
use crate::utils::sum_check::{
SumCheckGeneric, SumCheckProver, SumCheckSubClaim, SumCheckVerifierGeneric,
};
use crate::utils::virtual_polynomial::{VPAuxInfo, VirtualPolynomial};
use ark_crypto_primitives::sponge::Absorb;
use ark_ec::{CurveGroup, Group};
use ark_poly::DenseMultilinearExtension;
use ark_std::fmt::Debug;
use espresso_subroutines::PolyIOPErrors;
use std::marker::PhantomData;
use std::sync::Arc;

#[derive(Clone, Debug, Default, Copy, PartialEq, Eq)]
pub struct SumCheck<C: CurveGroup, T: Transcript<C>> {
#[doc(hidden)]
phantom: PhantomData<C>,
#[doc(hidden)]
phantom2: PhantomData<T>,
}

impl<C: CurveGroup, T: Transcript<C>> SumCheckGeneric<C> for SumCheck<C, T>
where
<C as ark_ec::Group>::ScalarField: Absorb,
{
type VirtualPolynomial = VirtualPolynomial<C::ScalarField>;
type VPAuxInfo = VPAuxInfo<C::ScalarField>;
type MultilinearExtension = Arc<DenseMultilinearExtension<C::ScalarField>>;
type SumCheckProof = IOPProof<C::ScalarField>;
type SumCheckSubClaim = SumCheckSubClaim<C::ScalarField>;

/// Generate a proof of the sum of polynomial over {0,1}^`num_vars`
/// Mutates the transcript in the process
fn prove(
poly: &VirtualPolynomial<C::ScalarField>,
transcript: &mut impl Transcript<C>,
) -> Result<IOPProof<C::ScalarField>, PolyIOPErrors> {
transcript.absorb(&<C as Group>::ScalarField::from(
poly.aux_info.num_variables as u64,
));
transcript.absorb(&<C as Group>::ScalarField::from(
poly.aux_info.max_degree as u64,
));
let mut prover_state: IOPProverState<C::ScalarField> = IOPProverState::prover_init(poly)?;
let mut challenge: Option<C::ScalarField> = None;
let mut prover_msgs: Vec<IOPProverMessage<C::ScalarField>> =
Vec::with_capacity(poly.aux_info.num_variables);
for _ in 0..poly.aux_info.num_variables {
let prover_msg: IOPProverMessage<C::ScalarField> =
IOPProverState::prove_round_and_update_state(&mut prover_state, &challenge)?;
transcript.absorb_vec(&prover_msg.evaluations);
prover_msgs.push(prover_msg);
challenge = Some(transcript.get_challenge());
}
if let Some(p) = challenge {
prover_state.challenges.push(p)
};
Ok(IOPProof {
point: prover_state.challenges,
proofs: prover_msgs,
})
}

fn verify(
claimed_sum: C::ScalarField,
proof: &IOPProof<C::ScalarField>,
aux_info: &VPAuxInfo<C::ScalarField>,
transcript: &mut impl Transcript<C>,
) -> Result<SumCheckSubClaim<C::ScalarField>, PolyIOPErrors> {
transcript.absorb(&<C as Group>::ScalarField::from(
aux_info.num_variables as u64,
));
transcript.absorb(&<C as Group>::ScalarField::from(aux_info.max_degree as u64));
let mut verifier_state = IOPVerifierStateGeneric::verifier_init(aux_info);
for i in 0..aux_info.num_variables {
let prover_msg = proof.proofs.get(i).expect("proof is incomplete");
transcript.absorb_vec(&prover_msg.evaluations);
IOPVerifierStateGeneric::verify_round_and_update_state(
&mut verifier_state,
prover_msg,
transcript,
)?;
}

IOPVerifierStateGeneric::check_and_generate_subclaim(&verifier_state, &claimed_sum)
}
arnaucube marked this conversation as resolved.
Show resolved Hide resolved

fn extract_sum(proof: &Self::SumCheckProof) -> C::ScalarField {
proof.proofs[0].evaluations[0] + proof.proofs[0].evaluations[1]
}
}

#[cfg(test)]
pub mod tests {
use std::sync::Arc;

use ark_ff::Field;
use ark_pallas::Fr;
use ark_pallas::Projective;
use ark_poly::DenseMultilinearExtension;
use ark_poly::MultilinearExtension;
use ark_std::test_rng;

use crate::transcript::poseidon::tests::poseidon_test_config;
use crate::transcript::poseidon::PoseidonTranscript;
use crate::transcript::Transcript;
use crate::utils::sum_check::SumCheckGeneric;
use crate::utils::virtual_polynomial::VirtualPolynomial;

use super::SumCheck;

#[test]
pub fn sumcheck_poseidon() {
let mut rng = test_rng();
let poly_mle = DenseMultilinearExtension::rand(5, &mut rng);
let virtual_poly = VirtualPolynomial::new_from_mle(&Arc::new(poly_mle), Fr::ONE);
let poseidon_config = poseidon_test_config::<Fr>();

// sum-check prove
let mut poseidon_transcript_prove: PoseidonTranscript<Projective> =
PoseidonTranscript::<Projective>::new(&poseidon_config);
let sum_check = SumCheck::<Projective, PoseidonTranscript<Projective>>::prove(
&virtual_poly,
&mut poseidon_transcript_prove,
)
.unwrap();

// sum-check verify
let claimed_sum =
SumCheck::<Projective, PoseidonTranscript<Projective>>::extract_sum(&sum_check);
let mut poseidon_transcript_verify: PoseidonTranscript<Projective> =
PoseidonTranscript::<Projective>::new(&poseidon_config);
let res_verify = SumCheck::<Projective, PoseidonTranscript<Projective>>::verify(
claimed_sum,
&sum_check,
&virtual_poly.aux_info,
&mut poseidon_transcript_verify,
);

assert!(res_verify.is_ok());
}
}
Loading
Loading