Expand description
This module implements Nova’s evaluation engine using This module implements Nova’s evaluation engine using TODO: write docHyperKZG
, a KZG-based polynomial commitment for multilinear polynomials
+ Expand description
HyperKZG
, a KZG-based polynomial commitment for multilinear polynomials
HyperKZG is based on the transformation from univariate PCS to multilinear PCS in the Gemini paper (section 2.4.2 in <https://eprint.iacr.org/2022/420.pdf>
).
However, there are some key differences:
(1) HyperKZG works with multilinear polynomials represented in evaluation form (rather than in coefficient form in Gemini’s transformation).
diff --git a/docs/arecibo/provider/hyperkzg/struct.EvaluationEngine.html b/docs/arecibo/provider/hyperkzg/struct.EvaluationEngine.html
index cac310c3f..7af325002 100644
--- a/docs/arecibo/provider/hyperkzg/struct.EvaluationEngine.html
+++ b/docs/arecibo/provider/hyperkzg/struct.EvaluationEngine.html
@@ -18,14 +18,14 @@
W: &[E::G1Affine],
transcript: &mut impl TranscriptEngineTrait<NE>
) -> E::FrTrait Implementations§
impl<E: Clone, NE: Clone> Clone for EvaluationEngine<E, NE>
fn clone(&self) -> EvaluationEngine<E, NE>
fn clone_from(&mut self, source: &Self)
source
. Read moreimpl<E, NE> EvaluationEngineTrait<NE> for EvaluationEngine<E, NE>
Trait Implementations§
source§impl<E: Clone, NE: Clone> Clone for EvaluationEngine<E, NE>
impl<E: Clone, NE: Clone> Clone for EvaluationEngine<E, NE>
source§fn clone(&self) -> EvaluationEngine<E, NE>
fn clone(&self) -> EvaluationEngine<E, NE>
1.0.0 · source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source
. Read moresource§impl<E, NE> EvaluationEngineTrait<NE> for EvaluationEngine<E, NE>where
E: MultiMillerLoop,
NE: NovaEngine<GE = E::G1, Scalar = E::Fr, CE = KZGCommitmentEngine<E>>,
E::Fr: Serialize + DeserializeOwned + PrimeFieldBits + TranscriptReprTrait<E::G1>,
E::G1Affine: Serialize + DeserializeOwned + TranscriptReprTrait<E::G1>,
E::G2Affine: Serialize + DeserializeOwned,
E::G1: DlogGroup<ScalarExt = E::Fr, AffineExt = E::G1Affine>,
- <E::G1 as Group>::Base: TranscriptReprTrait<E::G1>,
impl<E, NE> EvaluationEngineTrait<NE> for EvaluationEngine<E, NE>where
E: MultiMillerLoop,
NE: NovaEngine<GE = E::G1, Scalar = E::Fr, CE = KZGCommitmentEngine<E>>,
E::Fr: Serialize + DeserializeOwned + PrimeFieldBits + TranscriptReprTrait<E::G1>,
E::G1Affine: Serialize + DeserializeOwned + TranscriptReprTrait<E::G1>,
E::G2Affine: Serialize + DeserializeOwned,
E::G1: DlogGroup<ScalarExt = E::Fr, AffineExt = E::G1Affine>,
- <E::G1 as Group>::Base: TranscriptReprTrait<E::G1>,
source§fn verify(
vk: &Self::VerifierKey,
transcript: &mut <NE as NovaEngine>::TE,
C: &Commitment<NE>,
@@ -33,7 +33,7 @@
P_of_x: &E::Fr,
pi: &Self::EvaluationArgument
) -> Result<(), NovaError>
fn verify( vk: &Self::VerifierKey, transcript: &mut <NE as NovaEngine>::TE, C: &Commitment<NE>, @@ -33,7 +33,7 @@ P_of_x: &E::Fr, pi: &Self::EvaluationArgument ) -> Result<(), NovaError>
A method to verify purported evaluations of a batch of polynomials
-§type EvaluationArgument = EvaluationArgument<E>
type EvaluationArgument = EvaluationArgument<E>
§type VerifierKey = KZGVerifierKey<E>
type VerifierKey = KZGVerifierKey<E>
§type EvaluationArgument = EvaluationArgument<E>
type EvaluationArgument = EvaluationArgument<E>
§type VerifierKey = KZGVerifierKey<E>
type VerifierKey = KZGVerifierKey<E>
source§fn setup(ck: Arc<UniversalKZGParam<E>>) -> (Self::ProverKey, Self::VerifierKey)
fn setup(ck: Arc<UniversalKZGParam<E>>) -> (Self::ProverKey, Self::VerifierKey)
source§fn prove(
ck: &UniversalKZGParam<E>,
_pk: &Self::ProverKey,
transcript: &mut <NE as NovaEngine>::TE,
diff --git a/docs/arecibo/provider/ipa_pc/index.html b/docs/arecibo/provider/ipa_pc/index.html
index f83fc3546..a0c3b8ace 100644
--- a/docs/arecibo/provider/ipa_pc/index.html
+++ b/docs/arecibo/provider/ipa_pc/index.html
@@ -1,3 +1,3 @@
arecibo::provider::ipa_pc - Rust
- Expand description
This module implements EvaluationEngine
using an IPA-based polynomial commitment scheme
+ Expand description
This module implements EvaluationEngine
using an IPA-based polynomial commitment scheme
Structs
- Provides an implementation of a polynomial evaluation engine using IPA
- An inner product argument
- Provides an implementation of the prover key
- Provides an implementation of the verifier key
\ No newline at end of file
diff --git a/docs/arecibo/traits/evaluation/trait.EvaluationEngineTrait.html b/docs/arecibo/traits/evaluation/trait.EvaluationEngineTrait.html
index 1d7ff89cf..272dd3ef7 100644
--- a/docs/arecibo/traits/evaluation/trait.EvaluationEngineTrait.html
+++ b/docs/arecibo/traits/evaluation/trait.EvaluationEngineTrait.html
@@ -54,7 +54,7 @@
Object Safety§
This trait is not object safe.Implementors§
source§impl<E> EvaluationEngineTrait<E> for arecibo::provider::ipa_pc::EvaluationEngine<E>where
E: Engine,
E::GE: DlogGroup,
- <<E as Engine>::CE as CommitmentEngineTrait<E>>::CommitmentKey: CommitmentKeyExtTrait<E>,
§type ProverKey = ProverKey<E>
§type VerifierKey = VerifierKey<E>
§type EvaluationArgument = InnerProductArgument<E>
source§impl<E, NE> EvaluationEngineTrait<NE> for arecibo::provider::hyperkzg::EvaluationEngine<E, NE>
§type ProverKey = ProverKey<E>
§type VerifierKey = VerifierKey<E>
§type EvaluationArgument = InnerProductArgument<E>
source§impl<E, NE> EvaluationEngineTrait<NE> for arecibo::provider::hyperkzg::EvaluationEngine<E, NE>where
E: MultiMillerLoop,
NE: NovaEngine<GE = E::G1, Scalar = E::Fr, CE = KZGCommitmentEngine<E>>,
E::Fr: Serialize + DeserializeOwned + PrimeFieldBits + TranscriptReprTrait<E::G1>,
diff --git a/docs/src/arecibo/provider/hyperkzg.rs.html b/docs/src/arecibo/provider/hyperkzg.rs.html
index 343f86441..57eb3724c 100644
--- a/docs/src/arecibo/provider/hyperkzg.rs.html
+++ b/docs/src/arecibo/provider/hyperkzg.rs.html
@@ -608,6 +608,7 @@
607
608
609
+610
//! This module implements Nova's evaluation engine using `HyperKZG`, a KZG-based polynomial commitment for multilinear polynomials
//! HyperKZG is based on the transformation from univariate PCS to multilinear PCS in the Gemini paper (section 2.4.2 in `<https://eprint.iacr.org/2022/420.pdf>`).
//! However, there are some key differences:
@@ -634,7 +635,7 @@
};
use core::marker::PhantomData;
use ff::{Field, PrimeFieldBits};
-use group::{Curve, Group as _};
+use group::{prime::PrimeCurveAffine as _, Curve, Group as _};
use itertools::Itertools as _;
use pairing::{Engine, MillerLoopResult, MultiMillerLoop};
use rayon::prelude::*;
@@ -851,14 +852,15 @@
// We do not need to commit to the first polynomial as it is already committed.
// Compute commitments in parallel
- let comms: Vec<E::G1Affine> = (1..polys.len())
- .into_par_iter()
- .map(|i| {
- <NE::CE as CommitmentEngineTrait<NE>>::commit(ck, &polys[i])
- .comm
- .to_affine()
- })
- .collect();
+ let comms = {
+ let mut comms = vec![E::G1Affine::identity(); polys.len() - 1];
+ let comms_proj: Vec<E::G1> = (1..polys.len())
+ .into_par_iter()
+ .map(|i| <NE::CE as CommitmentEngineTrait<NE>>::commit(ck, &polys[i]).comm)
+ .collect();
+ Curve::batch_normalize(&comms_proj, &mut comms);
+ comms
+ };
// Phase 2
// We do not need to add x to the transcript, because in our context x was obtained from the transcript.
diff --git a/docs/src/arecibo/provider/ipa_pc.rs.html b/docs/src/arecibo/provider/ipa_pc.rs.html
index 725480755..991b618b4 100644
--- a/docs/src/arecibo/provider/ipa_pc.rs.html
+++ b/docs/src/arecibo/provider/ipa_pc.rs.html
@@ -389,34 +389,11 @@
388
389
390
-391
-392
-393
-394
-395
-396
-397
-398
-399
-400
-401
-402
-403
-404
-405
-406
-407
-408
-409
-410
-411
-412
-413
//! This module implements `EvaluationEngine` using an IPA-based polynomial commitment scheme
use crate::{
digest::SimpleDigestible,
errors::{NovaError, PCSError},
- provider::{pedersen::CommitmentKeyExtTrait, traits::DlogGroup},
+ provider::{pedersen::CommitmentKeyExtTrait, traits::DlogGroup, util::field::batch_invert},
spartan::polys::eq::EqPolynomial,
traits::{
commitment::{CommitmentEngineTrait, CommitmentTrait},
@@ -718,29 +695,6 @@
let P = U.comm_a_vec + CE::<E>::commit(&ck_c, &[U.c]);
- let batch_invert = |v: &[E::Scalar]| -> Result<Vec<E::Scalar>, NovaError> {
- let mut products = vec![E::Scalar::ZERO; v.len()];
- let mut acc = E::Scalar::ONE;
-
- for i in 0..v.len() {
- products[i] = acc;
- acc *= v[i];
- }
-
- // return error if acc is zero
- acc = Option::from(acc.invert()).ok_or(NovaError::InternalError)?;
-
- // compute the inverse once for all entries
- let mut inv = vec![E::Scalar::ZERO; v.len()];
- for i in (0..v.len()).rev() {
- let tmp = acc * v[i];
- inv[i] = products[i] * acc;
- acc = tmp;
- }
-
- Ok(inv)
- };
-
// compute a vector of public coins using self.L_vec and self.R_vec
let r = (0..self.L_vec.len())
.map(|i| {
@@ -755,7 +709,7 @@
.into_par_iter()
.map(|i| r[i] * r[i])
.collect();
- let r_inverse = batch_invert(&r)?;
+ let r_inverse = batch_invert(r.clone())?;
let r_inverse_square: Vec<E::Scalar> = (0..self.L_vec.len())
.into_par_iter()
.map(|i| r_inverse[i] * r_inverse[i])
diff --git a/docs/src/arecibo/provider/util/mod.rs.html b/docs/src/arecibo/provider/util/mod.rs.html
index 7cd11f521..1e6ed9c7c 100644
--- a/docs/src/arecibo/provider/util/mod.rs.html
+++ b/docs/src/arecibo/provider/util/mod.rs.html
@@ -206,6 +206,28 @@
205
206
207
+208
+209
+210
+211
+212
+213
+214
+215
+216
+217
+218
+219
+220
+221
+222
+223
+224
+225
+226
+227
+228
+229
fn prove(
ck: &UniversalKZGParam<E>,
_pk: &Self::ProverKey,
transcript: &mut <NE as NovaEngine>::TE,
diff --git a/docs/arecibo/provider/ipa_pc/index.html b/docs/arecibo/provider/ipa_pc/index.html
index f83fc3546..a0c3b8ace 100644
--- a/docs/arecibo/provider/ipa_pc/index.html
+++ b/docs/arecibo/provider/ipa_pc/index.html
@@ -1,3 +1,3 @@
arecibo::provider::ipa_pc - Rust
- Expand description
This module implements EvaluationEngine
using an IPA-based polynomial commitment scheme
+ Expand description
This module implements EvaluationEngine
using an IPA-based polynomial commitment scheme
Structs
- Provides an implementation of a polynomial evaluation engine using IPA
- An inner product argument
- Provides an implementation of the prover key
- Provides an implementation of the verifier key
\ No newline at end of file
diff --git a/docs/arecibo/traits/evaluation/trait.EvaluationEngineTrait.html b/docs/arecibo/traits/evaluation/trait.EvaluationEngineTrait.html
index 1d7ff89cf..272dd3ef7 100644
--- a/docs/arecibo/traits/evaluation/trait.EvaluationEngineTrait.html
+++ b/docs/arecibo/traits/evaluation/trait.EvaluationEngineTrait.html
@@ -54,7 +54,7 @@
Object Safety§
This trait is not object safe.Implementors§
source§impl<E> EvaluationEngineTrait<E> for arecibo::provider::ipa_pc::EvaluationEngine<E>where
E: Engine,
E::GE: DlogGroup,
- <<E as Engine>::CE as CommitmentEngineTrait<E>>::CommitmentKey: CommitmentKeyExtTrait<E>,
§type ProverKey = ProverKey<E>
§type VerifierKey = VerifierKey<E>
§type EvaluationArgument = InnerProductArgument<E>
source§impl<E, NE> EvaluationEngineTrait<NE> for arecibo::provider::hyperkzg::EvaluationEngine<E, NE>
§type ProverKey = ProverKey<E>
§type VerifierKey = VerifierKey<E>
§type EvaluationArgument = InnerProductArgument<E>
source§impl<E, NE> EvaluationEngineTrait<NE> for arecibo::provider::hyperkzg::EvaluationEngine<E, NE>where
E: MultiMillerLoop,
NE: NovaEngine<GE = E::G1, Scalar = E::Fr, CE = KZGCommitmentEngine<E>>,
E::Fr: Serialize + DeserializeOwned + PrimeFieldBits + TranscriptReprTrait<E::G1>,
diff --git a/docs/src/arecibo/provider/hyperkzg.rs.html b/docs/src/arecibo/provider/hyperkzg.rs.html
index 343f86441..57eb3724c 100644
--- a/docs/src/arecibo/provider/hyperkzg.rs.html
+++ b/docs/src/arecibo/provider/hyperkzg.rs.html
@@ -608,6 +608,7 @@
607
608
609
+610
//! This module implements Nova's evaluation engine using `HyperKZG`, a KZG-based polynomial commitment for multilinear polynomials
//! HyperKZG is based on the transformation from univariate PCS to multilinear PCS in the Gemini paper (section 2.4.2 in `<https://eprint.iacr.org/2022/420.pdf>`).
//! However, there are some key differences:
@@ -634,7 +635,7 @@
};
use core::marker::PhantomData;
use ff::{Field, PrimeFieldBits};
-use group::{Curve, Group as _};
+use group::{prime::PrimeCurveAffine as _, Curve, Group as _};
use itertools::Itertools as _;
use pairing::{Engine, MillerLoopResult, MultiMillerLoop};
use rayon::prelude::*;
@@ -851,14 +852,15 @@
// We do not need to commit to the first polynomial as it is already committed.
// Compute commitments in parallel
- let comms: Vec<E::G1Affine> = (1..polys.len())
- .into_par_iter()
- .map(|i| {
- <NE::CE as CommitmentEngineTrait<NE>>::commit(ck, &polys[i])
- .comm
- .to_affine()
- })
- .collect();
+ let comms = {
+ let mut comms = vec![E::G1Affine::identity(); polys.len() - 1];
+ let comms_proj: Vec<E::G1> = (1..polys.len())
+ .into_par_iter()
+ .map(|i| <NE::CE as CommitmentEngineTrait<NE>>::commit(ck, &polys[i]).comm)
+ .collect();
+ Curve::batch_normalize(&comms_proj, &mut comms);
+ comms
+ };
// Phase 2
// We do not need to add x to the transcript, because in our context x was obtained from the transcript.
diff --git a/docs/src/arecibo/provider/ipa_pc.rs.html b/docs/src/arecibo/provider/ipa_pc.rs.html
index 725480755..991b618b4 100644
--- a/docs/src/arecibo/provider/ipa_pc.rs.html
+++ b/docs/src/arecibo/provider/ipa_pc.rs.html
@@ -389,34 +389,11 @@
388
389
390
-391
-392
-393
-394
-395
-396
-397
-398
-399
-400
-401
-402
-403
-404
-405
-406
-407
-408
-409
-410
-411
-412
-413
//! This module implements `EvaluationEngine` using an IPA-based polynomial commitment scheme
use crate::{
digest::SimpleDigestible,
errors::{NovaError, PCSError},
- provider::{pedersen::CommitmentKeyExtTrait, traits::DlogGroup},
+ provider::{pedersen::CommitmentKeyExtTrait, traits::DlogGroup, util::field::batch_invert},
spartan::polys::eq::EqPolynomial,
traits::{
commitment::{CommitmentEngineTrait, CommitmentTrait},
@@ -718,29 +695,6 @@
let P = U.comm_a_vec + CE::<E>::commit(&ck_c, &[U.c]);
- let batch_invert = |v: &[E::Scalar]| -> Result<Vec<E::Scalar>, NovaError> {
- let mut products = vec![E::Scalar::ZERO; v.len()];
- let mut acc = E::Scalar::ONE;
-
- for i in 0..v.len() {
- products[i] = acc;
- acc *= v[i];
- }
-
- // return error if acc is zero
- acc = Option::from(acc.invert()).ok_or(NovaError::InternalError)?;
-
- // compute the inverse once for all entries
- let mut inv = vec![E::Scalar::ZERO; v.len()];
- for i in (0..v.len()).rev() {
- let tmp = acc * v[i];
- inv[i] = products[i] * acc;
- acc = tmp;
- }
-
- Ok(inv)
- };
-
// compute a vector of public coins using self.L_vec and self.R_vec
let r = (0..self.L_vec.len())
.map(|i| {
@@ -755,7 +709,7 @@
.into_par_iter()
.map(|i| r[i] * r[i])
.collect();
- let r_inverse = batch_invert(&r)?;
+ let r_inverse = batch_invert(r.clone())?;
let r_inverse_square: Vec<E::Scalar> = (0..self.L_vec.len())
.into_par_iter()
.map(|i| r_inverse[i] * r_inverse[i])
diff --git a/docs/src/arecibo/provider/util/mod.rs.html b/docs/src/arecibo/provider/util/mod.rs.html
index 7cd11f521..1e6ed9c7c 100644
--- a/docs/src/arecibo/provider/util/mod.rs.html
+++ b/docs/src/arecibo/provider/util/mod.rs.html
@@ -206,6 +206,28 @@
205
206
207
+208
+209
+210
+211
+212
+213
+214
+215
+216
+217
+218
+219
+220
+221
+222
+223
+224
+225
+226
+227
+228
+229
Expand description
This module implements EvaluationEngine
using an IPA-based polynomial commitment scheme
Expand description
This module implements EvaluationEngine
using an IPA-based polynomial commitment scheme
Structs
- Provides an implementation of a polynomial evaluation engine using IPA
- An inner product argument
- Provides an implementation of the prover key
- Provides an implementation of the verifier key
Object Safety§
Implementors§
source§impl<E> EvaluationEngineTrait<E> for arecibo::provider::ipa_pc::EvaluationEngine<E>where
E: Engine,
E::GE: DlogGroup,
- <<E as Engine>::CE as CommitmentEngineTrait<E>>::CommitmentKey: CommitmentKeyExtTrait<E>,
impl<E> EvaluationEngineTrait<E> for arecibo::provider::ipa_pc::EvaluationEngine<E>where
E: Engine,
E::GE: DlogGroup,
- <<E as Engine>::CE as CommitmentEngineTrait<E>>::CommitmentKey: CommitmentKeyExtTrait<E>,
type ProverKey = ProverKey<E>
type VerifierKey = VerifierKey<E>
type EvaluationArgument = InnerProductArgument<E>
source§impl<E, NE> EvaluationEngineTrait<NE> for arecibo::provider::hyperkzg::EvaluationEngine<E, NE>
impl<E, NE> EvaluationEngineTrait<NE> for arecibo::provider::hyperkzg::EvaluationEngine<E, NE>
type ProverKey = ProverKey<E>
type VerifierKey = VerifierKey<E>
type EvaluationArgument = InnerProductArgument<E>
source§impl<E, NE> EvaluationEngineTrait<NE> for arecibo::provider::hyperkzg::EvaluationEngine<E, NE>where
E: MultiMillerLoop,
NE: NovaEngine<GE = E::G1, Scalar = E::Fr, CE = KZGCommitmentEngine<E>>,
E::Fr: Serialize + DeserializeOwned + PrimeFieldBits + TranscriptReprTrait<E::G1>,
diff --git a/docs/src/arecibo/provider/hyperkzg.rs.html b/docs/src/arecibo/provider/hyperkzg.rs.html
index 343f86441..57eb3724c 100644
--- a/docs/src/arecibo/provider/hyperkzg.rs.html
+++ b/docs/src/arecibo/provider/hyperkzg.rs.html
@@ -608,6 +608,7 @@
607
608
609
+610
//! This module implements Nova's evaluation engine using `HyperKZG`, a KZG-based polynomial commitment for multilinear polynomials
//! HyperKZG is based on the transformation from univariate PCS to multilinear PCS in the Gemini paper (section 2.4.2 in `<https://eprint.iacr.org/2022/420.pdf>`).
//! However, there are some key differences:
@@ -634,7 +635,7 @@
};
use core::marker::PhantomData;
use ff::{Field, PrimeFieldBits};
-use group::{Curve, Group as _};
+use group::{prime::PrimeCurveAffine as _, Curve, Group as _};
use itertools::Itertools as _;
use pairing::{Engine, MillerLoopResult, MultiMillerLoop};
use rayon::prelude::*;
@@ -851,14 +852,15 @@
// We do not need to commit to the first polynomial as it is already committed.
// Compute commitments in parallel
- let comms: Vec<E::G1Affine> = (1..polys.len())
- .into_par_iter()
- .map(|i| {
- <NE::CE as CommitmentEngineTrait<NE>>::commit(ck, &polys[i])
- .comm
- .to_affine()
- })
- .collect();
+ let comms = {
+ let mut comms = vec![E::G1Affine::identity(); polys.len() - 1];
+ let comms_proj: Vec<E::G1> = (1..polys.len())
+ .into_par_iter()
+ .map(|i| <NE::CE as CommitmentEngineTrait<NE>>::commit(ck, &polys[i]).comm)
+ .collect();
+ Curve::batch_normalize(&comms_proj, &mut comms);
+ comms
+ };
// Phase 2
// We do not need to add x to the transcript, because in our context x was obtained from the transcript.
diff --git a/docs/src/arecibo/provider/ipa_pc.rs.html b/docs/src/arecibo/provider/ipa_pc.rs.html
index 725480755..991b618b4 100644
--- a/docs/src/arecibo/provider/ipa_pc.rs.html
+++ b/docs/src/arecibo/provider/ipa_pc.rs.html
@@ -389,34 +389,11 @@
388
389
390
-391
-392
-393
-394
-395
-396
-397
-398
-399
-400
-401
-402
-403
-404
-405
-406
-407
-408
-409
-410
-411
-412
-413
impl<E, NE> EvaluationEngineTrait<NE> for arecibo::provider::hyperkzg::EvaluationEngine<E, NE>where
E: MultiMillerLoop,
NE: NovaEngine<GE = E::G1, Scalar = E::Fr, CE = KZGCommitmentEngine<E>>,
E::Fr: Serialize + DeserializeOwned + PrimeFieldBits + TranscriptReprTrait<E::G1>,
diff --git a/docs/src/arecibo/provider/hyperkzg.rs.html b/docs/src/arecibo/provider/hyperkzg.rs.html
index 343f86441..57eb3724c 100644
--- a/docs/src/arecibo/provider/hyperkzg.rs.html
+++ b/docs/src/arecibo/provider/hyperkzg.rs.html
@@ -608,6 +608,7 @@
607
608
609
+610
//! This module implements Nova's evaluation engine using `HyperKZG`, a KZG-based polynomial commitment for multilinear polynomials
//! HyperKZG is based on the transformation from univariate PCS to multilinear PCS in the Gemini paper (section 2.4.2 in `<https://eprint.iacr.org/2022/420.pdf>`).
//! However, there are some key differences:
@@ -634,7 +635,7 @@
};
use core::marker::PhantomData;
use ff::{Field, PrimeFieldBits};
-use group::{Curve, Group as _};
+use group::{prime::PrimeCurveAffine as _, Curve, Group as _};
use itertools::Itertools as _;
use pairing::{Engine, MillerLoopResult, MultiMillerLoop};
use rayon::prelude::*;
@@ -851,14 +852,15 @@
// We do not need to commit to the first polynomial as it is already committed.
// Compute commitments in parallel
- let comms: Vec<E::G1Affine> = (1..polys.len())
- .into_par_iter()
- .map(|i| {
- <NE::CE as CommitmentEngineTrait<NE>>::commit(ck, &polys[i])
- .comm
- .to_affine()
- })
- .collect();
+ let comms = {
+ let mut comms = vec![E::G1Affine::identity(); polys.len() - 1];
+ let comms_proj: Vec<E::G1> = (1..polys.len())
+ .into_par_iter()
+ .map(|i| <NE::CE as CommitmentEngineTrait<NE>>::commit(ck, &polys[i]).comm)
+ .collect();
+ Curve::batch_normalize(&comms_proj, &mut comms);
+ comms
+ };
// Phase 2
// We do not need to add x to the transcript, because in our context x was obtained from the transcript.
diff --git a/docs/src/arecibo/provider/ipa_pc.rs.html b/docs/src/arecibo/provider/ipa_pc.rs.html
index 725480755..991b618b4 100644
--- a/docs/src/arecibo/provider/ipa_pc.rs.html
+++ b/docs/src/arecibo/provider/ipa_pc.rs.html
@@ -389,34 +389,11 @@
388
389
390
-391
-392
-393
-394
-395
-396
-397
-398
-399
-400
-401
-402
-403
-404
-405
-406
-407
-408
-409
-410
-411
-412
-413
//! This module implements Nova's evaluation engine using `HyperKZG`, a KZG-based polynomial commitment for multilinear polynomials
//! HyperKZG is based on the transformation from univariate PCS to multilinear PCS in the Gemini paper (section 2.4.2 in `<https://eprint.iacr.org/2022/420.pdf>`).
//! However, there are some key differences:
@@ -634,7 +635,7 @@
};
use core::marker::PhantomData;
use ff::{Field, PrimeFieldBits};
-use group::{Curve, Group as _};
+use group::{prime::PrimeCurveAffine as _, Curve, Group as _};
use itertools::Itertools as _;
use pairing::{Engine, MillerLoopResult, MultiMillerLoop};
use rayon::prelude::*;
@@ -851,14 +852,15 @@
// We do not need to commit to the first polynomial as it is already committed.
// Compute commitments in parallel
- let comms: Vec<E::G1Affine> = (1..polys.len())
- .into_par_iter()
- .map(|i| {
- <NE::CE as CommitmentEngineTrait<NE>>::commit(ck, &polys[i])
- .comm
- .to_affine()
- })
- .collect();
+ let comms = {
+ let mut comms = vec![E::G1Affine::identity(); polys.len() - 1];
+ let comms_proj: Vec<E::G1> = (1..polys.len())
+ .into_par_iter()
+ .map(|i| <NE::CE as CommitmentEngineTrait<NE>>::commit(ck, &polys[i]).comm)
+ .collect();
+ Curve::batch_normalize(&comms_proj, &mut comms);
+ comms
+ };
// Phase 2
// We do not need to add x to the transcript, because in our context x was obtained from the transcript.
diff --git a/docs/src/arecibo/provider/ipa_pc.rs.html b/docs/src/arecibo/provider/ipa_pc.rs.html
index 725480755..991b618b4 100644
--- a/docs/src/arecibo/provider/ipa_pc.rs.html
+++ b/docs/src/arecibo/provider/ipa_pc.rs.html
@@ -389,34 +389,11 @@
388
389
390
-391
-392
-393
-394
-395
-396
-397
-398
-399
-400
-401
-402
-403
-404
-405
-406
-407
-408
-409
-410
-411
-412
-413
//! This module implements `EvaluationEngine` using an IPA-based polynomial commitment scheme
use crate::{
digest::SimpleDigestible,
errors::{NovaError, PCSError},
- provider::{pedersen::CommitmentKeyExtTrait, traits::DlogGroup},
+ provider::{pedersen::CommitmentKeyExtTrait, traits::DlogGroup, util::field::batch_invert},
spartan::polys::eq::EqPolynomial,
traits::{
commitment::{CommitmentEngineTrait, CommitmentTrait},
@@ -718,29 +695,6 @@
let P = U.comm_a_vec + CE::<E>::commit(&ck_c, &[U.c]);
- let batch_invert = |v: &[E::Scalar]| -> Result<Vec<E::Scalar>, NovaError> {
- let mut products = vec![E::Scalar::ZERO; v.len()];
- let mut acc = E::Scalar::ONE;
-
- for i in 0..v.len() {
- products[i] = acc;
- acc *= v[i];
- }
-
- // return error if acc is zero
- acc = Option::from(acc.invert()).ok_or(NovaError::InternalError)?;
-
- // compute the inverse once for all entries
- let mut inv = vec![E::Scalar::ZERO; v.len()];
- for i in (0..v.len()).rev() {
- let tmp = acc * v[i];
- inv[i] = products[i] * acc;
- acc = tmp;
- }
-
- Ok(inv)
- };
-
// compute a vector of public coins using self.L_vec and self.R_vec
let r = (0..self.L_vec.len())
.map(|i| {
@@ -755,7 +709,7 @@
.into_par_iter()
.map(|i| r[i] * r[i])
.collect();
- let r_inverse = batch_invert(&r)?;
+ let r_inverse = batch_invert(r.clone())?;
let r_inverse_square: Vec<E::Scalar> = (0..self.L_vec.len())
.into_par_iter()
.map(|i| r_inverse[i] * r_inverse[i])
diff --git a/docs/src/arecibo/provider/util/mod.rs.html b/docs/src/arecibo/provider/util/mod.rs.html
index 7cd11f521..1e6ed9c7c 100644
--- a/docs/src/arecibo/provider/util/mod.rs.html
+++ b/docs/src/arecibo/provider/util/mod.rs.html
@@ -206,6 +206,28 @@
205
206
207
+208
+209
+210
+211
+212
+213
+214
+215
+216
+217
+218
+219
+220
+221
+222
+223
+224
+225
+226
+227
+228
+229
//! Utilities for provider module.
pub(in crate::provider) mod fb_msm;
pub mod msm {
@@ -219,6 +241,28 @@
}
}
+pub mod field {
+ use crate::errors::NovaError;
+ use ff::{BatchInverter, Field};
+
+ #[inline]
+ pub fn batch_invert<F: Field>(mut v: Vec<F>) -> Result<Vec<F>, NovaError> {
+ // we only allocate the scratch space if every element of v is nonzero
+ let mut scratch_space = v
+ .iter()
+ .map(|x| {
+ if !x.is_zero_vartime() {
+ Ok(*x)
+ } else {
+ Err(NovaError::InternalError)
+ }
+ })
+ .collect::<Result<Vec<_>, _>>()?;
+ let _ = BatchInverter::invert_with_external_scratch(&mut v, &mut scratch_space[..]);
+ Ok(v)
+ }
+}
+
pub mod iterators {
use ff::Field;
use rayon::iter::{IndexedParallelIterator, IntoParallelIterator, ParallelIterator};
diff --git a/docs/src/arecibo/spartan/sumcheck/engine.rs.html b/docs/src/arecibo/spartan/sumcheck/engine.rs.html
index 99ba3982c..c1c1cd4af 100644
--- a/docs/src/arecibo/spartan/sumcheck/engine.rs.html
+++ b/docs/src/arecibo/spartan/sumcheck/engine.rs.html
@@ -616,35 +616,10 @@
615
616
617
-618
-619
-620
-621
-622
-623
-624
-625
-626
-627
-628
-629
-630
-631
-632
-633
-634
-635
-636
-637
-638
-639
-640
-641
-642
-643