PolynomialBatchCommitment tweaks (#164)

Very minor things:
- A few renames
- Instead of having two constructors call a third constructor, just have one constructor call the other.
- Invoke FFT with the option that specifies the inputs are mostly zero, as a (minor) optimization
- Remove unused field
This commit is contained in:
Daniel Lubarov 2021-08-09 10:11:35 -07:00 committed by GitHub
parent 898caa2bb0
commit 3eacd53b30
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 46 additions and 39 deletions

View File

@ -13,7 +13,7 @@ enum FftStrategy {
const FFT_STRATEGY: FftStrategy = FftStrategy::Classic;
type FftRootTable<F> = Vec<Vec<F>>;
pub(crate) type FftRootTable<F> = Vec<Vec<F>>;
fn fft_classic_root_table<F: Field>(n: usize) -> FftRootTable<F> {
let lg_n = log2_strict(n);

View File

@ -23,7 +23,6 @@ pub const SALT_SIZE: usize = 2;
pub struct PolynomialBatchCommitment<F: Field> {
pub polynomials: Vec<PolynomialCoeffs<F>>,
pub merkle_tree: MerkleTree<F>,
pub degree: usize,
pub degree_log: usize,
pub rate_bits: usize,
pub blinding: bool,
@ -31,25 +30,23 @@ pub struct PolynomialBatchCommitment<F: Field> {
impl<F: Field> PolynomialBatchCommitment<F> {
/// Creates a list polynomial commitment for the polynomials interpolating the values in `values`.
pub(crate) fn new(
pub(crate) fn from_values(
values: Vec<PolynomialValues<F>>,
rate_bits: usize,
blinding: bool,
timing: &mut TimingTree,
) -> Self {
let degree = values[0].len();
let polynomials = values.par_iter().map(|v| v.ifft()).collect::<Vec<_>>();
let lde_values = timed!(
let coeffs = timed!(
timing,
"compute LDE",
Self::lde_values(&polynomials, rate_bits, blinding)
"IFFT",
values.par_iter().map(|v| v.ifft()).collect::<Vec<_>>()
);
Self::new_from_data(polynomials, lde_values, degree, rate_bits, blinding, timing)
Self::from_coeffs(coeffs, rate_bits, blinding, timing)
}
/// Creates a list polynomial commitment for the polynomials `polynomials`.
pub(crate) fn new_from_polys(
pub(crate) fn from_coeffs(
polynomials: Vec<PolynomialCoeffs<F>>,
rate_bits: usize,
blinding: bool,
@ -58,21 +55,10 @@ impl<F: Field> PolynomialBatchCommitment<F> {
let degree = polynomials[0].len();
let lde_values = timed!(
timing,
"compute LDE",
"FFT + blinding",
Self::lde_values(&polynomials, rate_bits, blinding)
);
Self::new_from_data(polynomials, lde_values, degree, rate_bits, blinding, timing)
}
fn new_from_data(
polynomials: Vec<PolynomialCoeffs<F>>,
lde_values: Vec<Vec<F>>,
degree: usize,
rate_bits: usize,
blinding: bool,
timing: &mut TimingTree,
) -> Self {
let mut leaves = timed!(timing, "transpose LDEs", transpose(&lde_values));
reverse_index_bits_in_place(&mut leaves);
let merkle_tree = timed!(timing, "build Merkle tree", MerkleTree::new(leaves, false));
@ -80,7 +66,6 @@ impl<F: Field> PolynomialBatchCommitment<F> {
Self {
polynomials,
merkle_tree,
degree,
degree_log: log2_strict(degree),
rate_bits,
blinding,
@ -93,20 +78,23 @@ impl<F: Field> PolynomialBatchCommitment<F> {
blinding: bool,
) -> Vec<Vec<F>> {
let degree = polynomials[0].len();
// If blinding, salt with two random elements to each leaf vector.
let salt_size = if blinding { SALT_SIZE } else { 0 };
polynomials
.par_iter()
.map(|p| {
assert_eq!(p.len(), degree, "Polynomial degree invalid.");
p.lde(rate_bits).coset_fft(F::coset_shift()).values
})
.chain(if blinding {
// If blinding, salt with two random elements to each leaf vector.
(0..SALT_SIZE)
.map(|_| F::rand_vec(degree << rate_bits))
.collect()
} else {
Vec::new()
assert_eq!(p.len(), degree, "Polynomial degrees inconsistent");
p.lde(rate_bits)
.coset_fft_with_options(F::coset_shift(), Some(rate_bits), None)
.values
})
.chain(
(0..salt_size)
.into_par_iter()
.map(|_| F::rand_vec(degree << rate_bits)),
)
.collect()
}
@ -306,7 +294,7 @@ mod tests {
let lpcs = (0..4)
.map(|i| {
PolynomialBatchCommitment::<F>::new(
PolynomialBatchCommitment::<F>::from_values(
gen_random_test_case(ks[i], degree_bits),
common_data.config.rate_bits,
PlonkPolynomials::polynomials(i).blinding,

View File

@ -555,7 +555,7 @@ impl<F: Extendable<D>, const D: usize> CircuitBuilder<F, D> {
let sigma_vecs = self.sigma_vecs(&k_is, &subgroup);
let constants_sigmas_vecs = [constant_vecs, sigma_vecs.clone()].concat();
let constants_sigmas_commitment = PolynomialBatchCommitment::new(
let constants_sigmas_commitment = PolynomialBatchCommitment::from_values(
constants_sigmas_vecs,
self.config.rate_bits,
self.config.zero_knowledge & PlonkPolynomials::CONSTANTS_SIGMAS.blinding,

View File

@ -81,7 +81,7 @@ pub(crate) fn prove<F: Extendable<D>, const D: usize>(
let wires_commitment = timed!(
timing,
"compute wires commitment",
PolynomialBatchCommitment::new(
PolynomialBatchCommitment::from_values(
wires_values,
config.rate_bits,
config.zero_knowledge & PlonkPolynomials::WIRES.blinding,
@ -125,7 +125,7 @@ pub(crate) fn prove<F: Extendable<D>, const D: usize>(
let zs_partial_products_commitment = timed!(
timing,
"commit to Z's",
PolynomialBatchCommitment::new(
PolynomialBatchCommitment::from_values(
zs_partial_products,
config.rate_bits,
config.zero_knowledge & PlonkPolynomials::ZS_PARTIAL_PRODUCTS.blinding,
@ -173,7 +173,7 @@ pub(crate) fn prove<F: Extendable<D>, const D: usize>(
let quotient_polys_commitment = timed!(
timing,
"commit to quotient polys",
PolynomialBatchCommitment::new_from_polys(
PolynomialBatchCommitment::from_coeffs(
all_quotient_poly_chunks,
config.rate_bits,
config.zero_knowledge & PlonkPolynomials::QUOTIENT.blinding,

View File

@ -6,6 +6,7 @@ use anyhow::{ensure, Result};
use serde::{Deserialize, Serialize};
use crate::field::extension_field::{Extendable, FieldExtension};
use crate::field::fft::FftRootTable;
use crate::field::fft::{fft, fft_with_options, ifft};
use crate::field::field_types::Field;
use crate::util::log2_strict;
@ -198,15 +199,33 @@ impl<F: Field> PolynomialCoeffs<F> {
fft(self)
}
pub fn fft_with_options(
&self,
zero_factor: Option<usize>,
root_table: Option<FftRootTable<F>>,
) -> PolynomialValues<F> {
fft_with_options(self, zero_factor, root_table)
}
/// Returns the evaluation of the polynomial on the coset `shift*H`.
pub fn coset_fft(&self, shift: F) -> PolynomialValues<F> {
self.coset_fft_with_options(shift, None, None)
}
/// Returns the evaluation of the polynomial on the coset `shift*H`.
pub fn coset_fft_with_options(
&self,
shift: F,
zero_factor: Option<usize>,
root_table: Option<FftRootTable<F>>,
) -> PolynomialValues<F> {
let modified_poly: Self = shift
.powers()
.zip(&self.coeffs)
.map(|(r, &c)| r * c)
.collect::<Vec<_>>()
.into();
modified_poly.fft()
modified_poly.fft_with_options(zero_factor, root_table)
}
pub fn to_extension<const D: usize>(&self) -> PolynomialCoeffs<F::Extension>