Skip to content

Commit

Permalink
feat: change to an Iterator extension trait
Browse files Browse the repository at this point in the history
  • Loading branch information
huitseeker committed Jan 16, 2024
1 parent c46d051 commit 51b3071
Show file tree
Hide file tree
Showing 5 changed files with 34 additions and 29 deletions.
23 changes: 0 additions & 23 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,36 +52,13 @@ use r1cs::{
CommitmentKeyHint, R1CSInstance, R1CSShape, R1CSWitness, RelaxedR1CSInstance, RelaxedR1CSWitness,
};
use serde::{Deserialize, Serialize};
use std::borrow::Borrow;
use std::ops::{AddAssign, MulAssign};
use traits::{
circuit::StepCircuit,
commitment::{CommitmentEngineTrait, CommitmentTrait},
snark::RelaxedR1CSSNARKTrait,
AbsorbInROTrait, Engine, ROConstants, ROConstantsCircuit, ROTrait,
};

/// This function employs Horner's scheme and core traits to create a combination of an iterator input with the powers
/// of a provided coefficient.
pub(crate) fn rlc<T: Clone, F, K: Borrow<T>>(
iter: impl DoubleEndedIterator<Item = K>,
coefficient: &F,
) -> T
where
T: for<'a> MulAssign<&'a F> + for<'r> AddAssign<&'r T>,
{
let mut iter = iter.rev();
let Some(fst) = iter.next() else {
panic!("input iterator should not be empty")
};

iter.fold(fst.borrow().clone(), |mut acc, item| {
acc *= coefficient;
acc += item.borrow();
acc
})
}

/// A type that holds parameters for the primary and secondary circuits of Nova and SuperNova
#[derive(Clone, PartialEq, Eq, Serialize, Deserialize, Abomonation)]
#[serde(bound = "")]
Expand Down
4 changes: 2 additions & 2 deletions src/provider/mlkzg.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,12 @@
use crate::{
errors::NovaError,
provider::{
util::iterators::DoubleEndedIteratorExt as _,
kzg_commitment::KZGCommitmentEngine,
non_hiding_kzg::{KZGProverKey, KZGVerifierKey, UniversalKZGParam},
pedersen::Commitment,
traits::DlogGroup,
},
rlc,
spartan::polys::univariate::UniPoly,
traits::{
commitment::{CommitmentEngineTrait, Len},
Expand Down Expand Up @@ -171,7 +171,7 @@ where
-> (Vec<E::G1Affine>, Vec<Vec<E::Fr>>) {
let kzg_compute_batch_polynomial = |f: Vec<Vec<E::Fr>>, q: E::Fr| -> Vec<E::Fr> {
// Compute B(x) = f_0(x) + q * f_1(x) + ... + q^(k-1) * f_{k-1}(x)
let B: UniPoly<E::Fr> = rlc(f.into_iter().map(UniPoly::new), &q);
let B: UniPoly<E::Fr> = f.into_iter().map(UniPoly::new).rlc(&q);
B.coeffs
};
///////// END kzg_open_batch closure helpers
Expand Down
2 changes: 1 addition & 1 deletion src/provider/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ pub(crate) mod traits;
// a non-hiding variant of {kzg, zeromorph}
mod kzg_commitment;
mod non_hiding_kzg;
mod util;
pub(crate) mod util;

// crate-private modules
mod keccak;
Expand Down
29 changes: 29 additions & 0 deletions src/provider/util/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,35 @@ pub mod msm {
}
}

pub mod iterators {
use std::iter::DoubleEndedIterator;
use std::ops::{MulAssign, AddAssign};
use std::borrow::Borrow;

pub trait DoubleEndedIteratorExt: DoubleEndedIterator {
/// This function employs Horner's scheme and core traits to create a combination of an iterator input with the powers
/// of a provided coefficient.
fn rlc<T, F>(&mut self, coefficient: &F) -> T
where
T: Clone + for<'a> MulAssign<&'a F> + for<'r> AddAssign<&'r T>,
Self::Item: Borrow<T>,
{
let mut iter = self.rev();
let Some(fst) = iter.next() else {
panic!("input iterator should not be empty")
};

iter.fold(fst.borrow().clone(), |mut acc, item| {
acc *= coefficient;
acc += item.borrow();
acc
})
}
}

impl<I: DoubleEndedIterator> DoubleEndedIteratorExt for I {}
}

#[cfg(test)]
pub mod test_utils {
//! Contains utilities for testing and benchmarking.
Expand Down
5 changes: 2 additions & 3 deletions src/spartan/polys/univariate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,7 @@ use ref_cast::RefCast;
use serde::{Deserialize, Serialize};

use crate::{
rlc,
traits::{Group, TranscriptReprTrait},
traits::{Group, TranscriptReprTrait}, provider::util::iterators::DoubleEndedIteratorExt as _,
};

// ax^2 + bx + c stored as vec![c, b, a]
Expand Down Expand Up @@ -134,7 +133,7 @@ impl<Scalar: PrimeField> UniPoly<Scalar> {
}

pub fn evaluate(&self, r: &Scalar) -> Scalar {
rlc(self.coeffs.iter(), r)
self.coeffs.iter().rlc(r)
}

pub fn compress(&self) -> CompressedUniPoly<Scalar> {
Expand Down

0 comments on commit 51b3071

Please sign in to comment.