From f04317df32927771bf788820761eca70a3968875 Mon Sep 17 00:00:00 2001 From: PatStiles Date: Fri, 10 Jan 2025 02:34:51 -0300 Subject: [PATCH 1/3] init --- jolt-core/src/poly/commitment/dory.rs | 111 ++++++++++++++++++++++++++ jolt-core/src/poly/commitment/mod.rs | 1 + 2 files changed, 112 insertions(+) create mode 100644 jolt-core/src/poly/commitment/dory.rs diff --git a/jolt-core/src/poly/commitment/dory.rs b/jolt-core/src/poly/commitment/dory.rs new file mode 100644 index 000000000..e8b0ede24 --- /dev/null +++ b/jolt-core/src/poly/commitment/dory.rs @@ -0,0 +1,111 @@ +#![allow(dead_code)] + +use crate::field::JoltField; +use crate::msm::Icicle; +use crate::poly::commitment::commitment_scheme::BatchType; +use crate::poly::commitment::commitment_scheme::CommitShape; +use crate::poly::commitment::commitment_scheme::CommitmentScheme; +use crate::poly::dense_mlpoly::DensePolynomial; +use crate::utils::errors::ProofVerifyError; +use crate::utils::transcript::{AppendToTranscript, Transcript}; +use ark_ec::CurveGroup; +use ark_serialize::{CanonicalDeserialize, CanonicalSerialize}; +use std::marker::PhantomData; + +#[derive(Clone)] +pub struct DoryScheme { + _phantom: PhantomData<(G, ProofTranscript)>, +} + +#[derive(Default, Debug, PartialEq, CanonicalSerialize, CanonicalDeserialize)] +pub struct DoryCommitment { + pub c: G, + pub d1: G, + pub d2: G +} + +impl AppendToTranscript for DoryCommitment { + fn append_to_transcript(&self, _transcript: &mut ProofTranscript) { + todo!() + } +} + +#[derive(CanonicalSerialize, CanonicalDeserialize)] +pub struct DoryProof {} + +#[derive(CanonicalSerialize, CanonicalDeserialize)] +pub struct DoryBatchedProof {} + +#[derive(Clone)] +pub struct None {} + +impl + Icicle, ProofTranscript: Transcript> CommitmentScheme + for DoryScheme +{ + type Field = G::ScalarField; + type Setup = None; + type Commitment = DoryCommitment; + type Proof = DoryProof; + type BatchedProof = DoryBatchedProof; + + fn setup(_shapes: &[CommitShape]) -> Self::Setup { + None {} + } + fn commit(_poly: &DensePolynomial, _setup: &Self::Setup) -> Self::Commitment { + todo!() + } + fn batch_commit( + _evals: &[&[Self::Field]], + _gens: &Self::Setup, + _batch_type: BatchType, + ) -> Vec { + todo!() + } + fn commit_slice(_evals: &[Self::Field], _setup: &Self::Setup) -> Self::Commitment { + todo!() + } + fn prove( + _none: &Self::Setup, + _poly: &DensePolynomial, + _opening_point: &[Self::Field], + _transcript: &mut ProofTranscript, + ) -> Self::Proof { + todo!() + } + fn batch_prove( + _none: &Self::Setup, + _polynomials: &[&DensePolynomial], + _opening_point: &[Self::Field], + _openings: &[Self::Field], + _batch_type: BatchType, + _transcript: &mut ProofTranscript, + ) -> Self::BatchedProof { + todo!() + } + + fn verify( + _proof: &Self::Proof, + _setup: &Self::Setup, + _transcript: &mut ProofTranscript, + _opening_point: &[Self::Field], + _opening: &Self::Field, + _commitment: &Self::Commitment, + ) -> Result<(), ProofVerifyError> { + todo!() + } + + fn batch_verify( + _batch_proof: &Self::BatchedProof, + _setup: &Self::Setup, + _opening_point: &[Self::Field], + _openings: &[Self::Field], + _commitments: &[&Self::Commitment], + _transcript: &mut ProofTranscript, + ) -> Result<(), ProofVerifyError> { + todo!() + } + + fn protocol_name() -> &'static [u8] { + b"dory_commit" + } +} diff --git a/jolt-core/src/poly/commitment/mod.rs b/jolt-core/src/poly/commitment/mod.rs index 05278ecf2..7eff9e592 100644 --- a/jolt-core/src/poly/commitment/mod.rs +++ b/jolt-core/src/poly/commitment/mod.rs @@ -5,6 +5,7 @@ pub mod hyrax; pub mod kzg; pub mod pedersen; pub mod zeromorph; +pub mod dory; #[cfg(test)] pub mod mock; From b04af9a2a4713fa0fc83a99c25b00d06e5af8ce9 Mon Sep 17 00:00:00 2001 From: PatStiles Date: Fri, 31 Jan 2025 03:47:38 -0300 Subject: [PATCH 2/3] setup + structs --- jolt-core/src/poly/commitment/dory.rs | 184 ++++++++++++++++++++++---- 1 file changed, 158 insertions(+), 26 deletions(-) diff --git a/jolt-core/src/poly/commitment/dory.rs b/jolt-core/src/poly/commitment/dory.rs index e8b0ede24..bc1eeecf5 100644 --- a/jolt-core/src/poly/commitment/dory.rs +++ b/jolt-core/src/poly/commitment/dory.rs @@ -8,52 +8,174 @@ use crate::poly::commitment::commitment_scheme::CommitmentScheme; use crate::poly::dense_mlpoly::DensePolynomial; use crate::utils::errors::ProofVerifyError; use crate::utils::transcript::{AppendToTranscript, Transcript}; -use ark_ec::CurveGroup; +use ark_ec::{CurveGroup, pairnig::Pairing, AffineRepr, CurveGroup}; use ark_serialize::{CanonicalDeserialize, CanonicalSerialize}; use std::marker::PhantomData; -#[derive(Clone)] -pub struct DoryScheme { - _phantom: PhantomData<(G, ProofTranscript)>, + +/// Computes an Inner-Pairing-Product commitment as described in ____: +/// This leverages arkworks Pairing::multi_pairing method. +fn inner_pairing_product(g1: &[P::G1Affine], g2: &[P::G2Affine]) -> P::PairingOutput { + // todo(pat): try to move these checks to a larger context. + if g1.len() != g2.len() { + panic(fmt.Sprintf("length mismatch")) + } + + if g1.len() == 0 || g2.len() == 0 { + panic("empty vectors") + } + + // todo(pat): Confirm this isn't the same as performing a multi_miller_loop. + P::multi_pairing(g1, g2) } #[derive(Default, Debug, PartialEq, CanonicalSerialize, CanonicalDeserialize)] -pub struct DoryCommitment { - pub c: G, - pub d1: G, - pub d2: G +pub struct DoryCommitment { + pub c: P::PairingOutput, + pub d1: P::PairingOutput, + pub d2: P::PairingOutput } -impl AppendToTranscript for DoryCommitment { +impl AppendToTranscript for DoryCommitment

{ fn append_to_transcript(&self, _transcript: &mut ProofTranscript) { todo!() } } #[derive(CanonicalSerialize, CanonicalDeserialize)] -pub struct DoryProof {} +pub struct DoryPublicParameters(Vec>); + +#[derive(CanonicalSerialize, CanonicalDeserialize, Default)] +pub struct PublicParameters { + pub reducePP: ReducePublicParams

, + pub Γ1: Vec, + pub Γ2: Vec, + pub χ: P::PairingOutput +} + +impl PublicParameters

{ + pub fn new(n: usize) -> Self { + if self.Γ1.len() != 2 * n || self.Γ2.len() != 2 * n { + panic("recursive public parameters should be twice as the public parameters it is derived from") + } + + let χ = inner_pairing_product(self.reducePP.Γ1Prime, self.reduce.Γ2Prime); + let reducePP = Self::reducePP(self.Γ1, self.Γ2, n); + + Self { + reducePP, + Γ1: self.reducePP.Γ1Prime, + Γ2: self.reduce.Γ2Prime, + χ + } + } + + pub fn reducePP(Γ1: &[P::G1], Γ2: &[P::G2], n: usize) -> ReducePublicParams

{ + if n == 1 { + return ReducePP::Default() + } + let m = n / 2; + + let Γ1L = &Γ1[..m]; + let Γ1R = &Γ1[m..]; + let Γ2L = &Γ2[..m]; + let Γ2R = &Γ2[m..]; + + // TODO(pat): make the seed phrases depend on m so they are random per reduction. + let Γ1Prime = PedersenGenerators::::new(m, b"Jolt v1 Dory Public Parameters r1Prime").generators; + let Γ2Prime = PedersenGenerators::::new(m, b"Jolt Dory Public Paramerets r2Prime").generators; + let Δ1L = inner_pairing_product(Γ1L, Γ2Prime); + let Δ1R = inner_pairing_product(Γ1R,Γ2Prime); + let Δ2L = inner_pairing_product(Γ1Prime, Γ2L); + let Δ2R = inner_pairing_product(Γ1Prime,Γ2R); + + ReducePublicParams { + Γ1Prime, + Γ2Prime, + Δ1R, + Δ1L, + Δ2R, + Δ2L, + } + } +} + +// Parameters used within the reduction +#[derive(CanonicalSerialize, CanonicalDeserialize)] +pub struct ReducePublicParams { + pub Γ1Prime: Vec, + pub Γ2Prime: Vec, + pub Δ1R: P::PairingOutput, + pub Δ1L: P::PairingOutput, + pub Δ2R: P::PairingOutput, + pub Δ2L: P::PairingOutput +} + +#[derive(CanonicalSerialize, CanonicalDeserialize)] +pub struct DoryProof { + +} #[derive(CanonicalSerialize, CanonicalDeserialize)] -pub struct DoryBatchedProof {} +pub struct DoryBatchedProof {} #[derive(Clone)] -pub struct None {} +pub struct DoryScheme { + _phantom: PhantomData<(P, ProofTranscript)>, +} -impl + Icicle, ProofTranscript: Transcript> CommitmentScheme - for DoryScheme +impl CommitmentScheme + for DoryScheme +where +

::ScalarField: JoltField, +

::G1: Icicle, { - type Field = G::ScalarField; - type Setup = None; - type Commitment = DoryCommitment; - type Proof = DoryProof; - type BatchedProof = DoryBatchedProof; - - fn setup(_shapes: &[CommitShape]) -> Self::Setup { - None {} + type Field = P::ScalarField; + type Setup = DoryPublicParams

; + type Commitment = DoryCommitment

; + type Proof = DoryProof

; + type BatchedProof = DoryBatchedProof

; + + fn setup(shapes: &[CommitShape]) -> Self::Setup { + let res = Vec::new(); + + // Dory's setup procedure initializes + let mut max_len: usize = 0; + for shape in shapes { + let len = shape.input_length.log_2(); + if len > max_len { + max_len = len; + } + } + + let Γ1 = PedersenGenerators::::new(max_len, b"Jolt v1 Dory G1 generators").generators; + let Γ2 = PedersenGenerators::::new(max_len, b"Jolt v1 Dory G2 generators").generators; + + let χ = inner_pairing_product(g1, g2); + let reducePP = PublicParameters::reducePP(Γ1, Γ2, max_len); + + let mut pp = DoryPublicParams { + reducePP, + Γ1, + Γ2, + χ + }; + + while max_len > 0 { + res.append(pp); + if n/2 == 0 { + break; + } + pp = pp.new(max_len / 2); + max_len /= 2; + } + + return res } - fn commit(_poly: &DensePolynomial, _setup: &Self::Setup) -> Self::Commitment { - todo!() + + fn commit(poly: &DensePolynomial, setup: &Self::Setup) -> Self::Commitment { } + fn batch_commit( _evals: &[&[Self::Field]], _gens: &Self::Setup, @@ -61,9 +183,11 @@ impl + Icicle, ProofTranscript: Tra ) -> Vec { todo!() } + fn commit_slice(_evals: &[Self::Field], _setup: &Self::Setup) -> Self::Commitment { todo!() } + fn prove( _none: &Self::Setup, _poly: &DensePolynomial, @@ -86,11 +210,19 @@ impl + Icicle, ProofTranscript: Tra fn verify( _proof: &Self::Proof, _setup: &Self::Setup, - _transcript: &mut ProofTranscript, + transcript: &mut ProofTranscript, _opening_point: &[Self::Field], _opening: &Self::Field, _commitment: &Self::Commitment, ) -> Result<(), ProofVerifyError> { + + // Final Pairing Verification + /* + let d = transcript.challenge_scalar(); + let dInv = d.inv(); + + let left = P::multi_pairing(); + */ todo!() } @@ -106,6 +238,6 @@ impl + Icicle, ProofTranscript: Tra } fn protocol_name() -> &'static [u8] { - b"dory_commit" + b"dory" } } From 73894b268a38249989737999eb27189675c454ef Mon Sep 17 00:00:00 2001 From: PatStiles Date: Fri, 31 Jan 2025 10:30:32 -0500 Subject: [PATCH 3/3] add commitment --- jolt-core/src/poly/commitment/dory.rs | 32 +++++++++++++++++++++++---- 1 file changed, 28 insertions(+), 4 deletions(-) diff --git a/jolt-core/src/poly/commitment/dory.rs b/jolt-core/src/poly/commitment/dory.rs index bc1eeecf5..13c31677e 100644 --- a/jolt-core/src/poly/commitment/dory.rs +++ b/jolt-core/src/poly/commitment/dory.rs @@ -43,7 +43,11 @@ impl AppendToTranscript for DoryCommitment

{ } #[derive(CanonicalSerialize, CanonicalDeserialize)] -pub struct DoryPublicParameters(Vec>); +pub struct DoryPublicParameters { + pub h: P::G1, + pub pp: Vec>, + pub gens: PedersenGenerators // todo(pat): these should be generated at each instance of the protocol I believe. They are just pedersen generators needed for the inner-product opposite the h^a_i points. +} #[derive(CanonicalSerialize, CanonicalDeserialize, Default)] pub struct PublicParameters { @@ -170,10 +174,16 @@ where max_len /= 2; } - return res + let h = Γ1[0]; + + Self::Setup { + h, + pp: res + } } fn commit(poly: &DensePolynomial, setup: &Self::Setup) -> Self::Commitment { + Self::commit_slice(poly.evals_ref(), setup) } fn batch_commit( @@ -184,8 +194,22 @@ where todo!() } - fn commit_slice(_evals: &[Self::Field], _setup: &Self::Setup) -> Self::Commitment { - todo!() + fn commit_slice(evals_slice: &[Self::Field], setup: &Self::Setup) -> Self::Commitment { + let v1 = eval_slice + .par_iter + .map(|eval| + setup.h * eval + ).collect(); + let d1 = P::multi_pairing(v1, setup.Γ2); + //todo(pat): We can precompute this I think? Hard to distinguish between inner product protocol and Multilinear PCS. Follow up with Micheal. + let d2 = P::multi_pairing(setup.gens, setup.Γ1); + let c = P::multi_pairing(v2, setup.gens); + + Self::Commitment { + d1, + d2, + c + } } fn prove(