mirror of
https://github.com/logos-storage/plonky2.git
synced 2026-01-07 16:23:12 +00:00
Merge pull request #75 from mir-protocol/merge_constant_sigma_commitments
Merge constant and sigma commitments
This commit is contained in:
commit
4649c9b72c
@ -17,6 +17,7 @@ use crate::gates::noop::NoopGate;
|
||||
use crate::generator::{CopyGenerator, WitnessGenerator};
|
||||
use crate::hash::hash_n_to_hash;
|
||||
use crate::permutation_argument::TargetPartitions;
|
||||
use crate::plonk_common::PlonkPolynomials;
|
||||
use crate::polynomial::commitment::ListPolynomialCommitment;
|
||||
use crate::polynomial::polynomial::PolynomialValues;
|
||||
use crate::target::Target;
|
||||
@ -301,25 +302,26 @@ impl<F: Extendable<D>, const D: usize> CircuitBuilder<F, D> {
|
||||
let subgroup = F::two_adic_subgroup(degree_bits);
|
||||
|
||||
let constant_vecs = self.constant_polys(&prefixed_gates);
|
||||
let constants_commitment =
|
||||
ListPolynomialCommitment::new(constant_vecs, self.config.fri_config.rate_bits, false);
|
||||
let num_constants = constant_vecs.len();
|
||||
|
||||
let k_is = get_unique_coset_shifts(degree, self.config.num_routed_wires);
|
||||
let sigma_vecs = self.sigma_vecs(&k_is, &subgroup);
|
||||
let sigmas_commitment =
|
||||
ListPolynomialCommitment::new(sigma_vecs, self.config.fri_config.rate_bits, false);
|
||||
|
||||
let constants_root = constants_commitment.merkle_tree.root;
|
||||
let sigmas_root = sigmas_commitment.merkle_tree.root;
|
||||
let constants_sigmas_vecs = [constant_vecs, sigma_vecs].concat();
|
||||
let constants_sigmas_commitment = ListPolynomialCommitment::new(
|
||||
constants_sigmas_vecs,
|
||||
self.config.fri_config.rate_bits,
|
||||
PlonkPolynomials::CONSTANTS_SIGMAS.blinding,
|
||||
);
|
||||
|
||||
let constants_sigmas_root = constants_sigmas_commitment.merkle_tree.root;
|
||||
let verifier_only = VerifierOnlyCircuitData {
|
||||
constants_root,
|
||||
sigmas_root,
|
||||
constants_sigmas_root,
|
||||
};
|
||||
|
||||
let prover_only = ProverOnlyCircuitData {
|
||||
generators: self.generators,
|
||||
constants_commitment,
|
||||
sigmas_commitment,
|
||||
constants_sigmas_commitment,
|
||||
subgroup,
|
||||
copy_constraints: self.copy_constraints,
|
||||
gate_instances: self.gate_instances,
|
||||
@ -337,7 +339,10 @@ impl<F: Extendable<D>, const D: usize> CircuitBuilder<F, D> {
|
||||
.expect("No gates?");
|
||||
|
||||
// TODO: This should also include an encoding of gate constraints.
|
||||
let circuit_digest_parts = [constants_root.elements, sigmas_root.elements];
|
||||
let circuit_digest_parts = [
|
||||
constants_sigmas_root.elements.to_vec(),
|
||||
vec![/* Add other circuit data here */],
|
||||
];
|
||||
let circuit_digest = hash_n_to_hash(circuit_digest_parts.concat(), false);
|
||||
|
||||
let common = CommonCircuitData {
|
||||
@ -346,6 +351,7 @@ impl<F: Extendable<D>, const D: usize> CircuitBuilder<F, D> {
|
||||
gates: prefixed_gates,
|
||||
max_filtered_constraint_degree_bits: 3, // TODO: compute this correctly once filters land.
|
||||
num_gate_constraints,
|
||||
num_constants,
|
||||
k_is,
|
||||
circuit_digest,
|
||||
};
|
||||
|
||||
@ -1,3 +1,5 @@
|
||||
use std::ops::Range;
|
||||
|
||||
use anyhow::Result;
|
||||
|
||||
use crate::field::extension_field::Extendable;
|
||||
@ -116,10 +118,8 @@ impl<F: Extendable<D>, const D: usize> VerifierCircuitData<F, D> {
|
||||
/// Circuit data required by the prover, but not the verifier.
|
||||
pub(crate) struct ProverOnlyCircuitData<F: Extendable<D>, const D: usize> {
|
||||
pub generators: Vec<Box<dyn WitnessGenerator<F>>>,
|
||||
/// Commitments to the constants polynomial.
|
||||
pub constants_commitment: ListPolynomialCommitment<F>,
|
||||
/// Commitments to the sigma polynomial.
|
||||
pub sigmas_commitment: ListPolynomialCommitment<F>,
|
||||
/// Commitments to the constants polynomials and sigma polynomials.
|
||||
pub constants_sigmas_commitment: ListPolynomialCommitment<F>,
|
||||
/// Subgroup of order `degree`.
|
||||
pub subgroup: Vec<F>,
|
||||
/// The circuit's copy constraints.
|
||||
@ -130,15 +130,12 @@ pub(crate) struct ProverOnlyCircuitData<F: Extendable<D>, const D: usize> {
|
||||
|
||||
/// Circuit data required by the verifier, but not the prover.
|
||||
pub(crate) struct VerifierOnlyCircuitData<F: Field> {
|
||||
/// A commitment to each constant polynomial.
|
||||
pub(crate) constants_root: Hash<F>,
|
||||
|
||||
/// A commitment to each permutation polynomial.
|
||||
pub(crate) sigmas_root: Hash<F>,
|
||||
/// A commitment to each constant polynomial and each permutation polynomial.
|
||||
pub(crate) constants_sigmas_root: Hash<F>,
|
||||
}
|
||||
|
||||
/// Circuit data required by both the prover and the verifier.
|
||||
pub(crate) struct CommonCircuitData<F: Extendable<D>, const D: usize> {
|
||||
pub struct CommonCircuitData<F: Extendable<D>, const D: usize> {
|
||||
pub(crate) config: CircuitConfig,
|
||||
|
||||
pub(crate) degree_bits: usize,
|
||||
@ -152,6 +149,9 @@ pub(crate) struct CommonCircuitData<F: Extendable<D>, const D: usize> {
|
||||
/// The largest number of constraints imposed by any gate.
|
||||
pub(crate) num_gate_constraints: usize,
|
||||
|
||||
/// The number of constant wires.
|
||||
pub(crate) num_constants: usize,
|
||||
|
||||
/// The `{k_i}` valued used in `S_ID_i` in Plonk's permutation argument.
|
||||
pub(crate) k_is: Vec<F>,
|
||||
|
||||
@ -189,6 +189,16 @@ impl<F: Extendable<D>, const D: usize> CommonCircuitData<F, D> {
|
||||
// 2 constraints for each Z check.
|
||||
self.config.num_challenges * 2 + self.num_gate_constraints
|
||||
}
|
||||
|
||||
/// Range of the constants polynomials in the `constants_sigmas_commitment`.
|
||||
pub fn constants_range(&self) -> Range<usize> {
|
||||
0..self.num_constants
|
||||
}
|
||||
|
||||
/// Range of the sigma polynomials in the `constants_sigmas_commitment`.
|
||||
pub fn sigmas_range(&self) -> Range<usize> {
|
||||
self.num_constants..self.num_constants + self.config.num_routed_wires
|
||||
}
|
||||
}
|
||||
|
||||
/// The `Target` version of `VerifierCircuitData`, for use inside recursive circuits. Note that this
|
||||
|
||||
@ -159,8 +159,7 @@ impl<F: Extendable<D>, const D: usize> CircuitBuilder<F, D> {
|
||||
|
||||
// Polynomials opened at `x`, i.e., the constants, sigmas and quotient polynomials.
|
||||
let single_evals = [
|
||||
PlonkPolynomials::CONSTANTS,
|
||||
PlonkPolynomials::SIGMAS,
|
||||
PlonkPolynomials::CONSTANTS_SIGMAS,
|
||||
PlonkPolynomials::QUOTIENT,
|
||||
]
|
||||
.iter()
|
||||
|
||||
@ -162,8 +162,7 @@ fn fri_combine_initial<F: Field + Extendable<D>, const D: usize>(
|
||||
|
||||
// Polynomials opened at `x`, i.e., the constants, sigmas and quotient polynomials.
|
||||
let single_evals = [
|
||||
PlonkPolynomials::CONSTANTS,
|
||||
PlonkPolynomials::SIGMAS,
|
||||
PlonkPolynomials::CONSTANTS_SIGMAS,
|
||||
PlonkPolynomials::QUOTIENT,
|
||||
]
|
||||
.iter()
|
||||
|
||||
@ -29,35 +29,30 @@ impl PolynomialsIndexBlinding {
|
||||
/// Holds the indices and blinding flags of the Plonk polynomials.
|
||||
pub struct PlonkPolynomials;
|
||||
impl PlonkPolynomials {
|
||||
pub const CONSTANTS: PolynomialsIndexBlinding = PolynomialsIndexBlinding {
|
||||
pub const CONSTANTS_SIGMAS: PolynomialsIndexBlinding = PolynomialsIndexBlinding {
|
||||
index: 0,
|
||||
blinding: false,
|
||||
};
|
||||
pub const SIGMAS: PolynomialsIndexBlinding = PolynomialsIndexBlinding {
|
||||
index: 1,
|
||||
blinding: false,
|
||||
};
|
||||
pub const WIRES: PolynomialsIndexBlinding = PolynomialsIndexBlinding {
|
||||
index: 2,
|
||||
index: 1,
|
||||
blinding: true,
|
||||
};
|
||||
pub const ZS: PolynomialsIndexBlinding = PolynomialsIndexBlinding {
|
||||
index: 3,
|
||||
index: 2,
|
||||
blinding: true,
|
||||
};
|
||||
pub const QUOTIENT: PolynomialsIndexBlinding = PolynomialsIndexBlinding {
|
||||
index: 4,
|
||||
index: 3,
|
||||
blinding: true,
|
||||
};
|
||||
|
||||
pub fn polynomials(i: usize) -> PolynomialsIndexBlinding {
|
||||
match i {
|
||||
0 => Self::CONSTANTS,
|
||||
1 => Self::SIGMAS,
|
||||
2 => Self::WIRES,
|
||||
3 => Self::ZS,
|
||||
4 => Self::QUOTIENT,
|
||||
_ => panic!("There are only 5 sets of polynomials in Plonk."),
|
||||
0 => Self::CONSTANTS_SIGMAS,
|
||||
1 => Self::WIRES,
|
||||
2 => Self::ZS,
|
||||
3 => Self::QUOTIENT,
|
||||
_ => panic!("There are only 4 sets of polynomials in Plonk."),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
use anyhow::Result;
|
||||
use rayon::prelude::*;
|
||||
|
||||
use crate::circuit_data::CommonCircuitData;
|
||||
use crate::field::extension_field::Extendable;
|
||||
use crate::field::extension_field::{FieldExtension, Frobenius};
|
||||
use crate::field::field::Field;
|
||||
@ -119,14 +120,15 @@ impl<F: Field> ListPolynomialCommitment<F> {
|
||||
/// Takes the commitments to the constants - sigmas - wires - zs - quotient — polynomials,
|
||||
/// and an opening point `zeta` and produces a batched opening proof + opening set.
|
||||
pub fn open_plonk<const D: usize>(
|
||||
commitments: &[&Self; 5],
|
||||
commitments: &[&Self; 4],
|
||||
zeta: F::Extension,
|
||||
challenger: &mut Challenger<F>,
|
||||
config: &FriConfig,
|
||||
common_data: &CommonCircuitData<F, D>,
|
||||
) -> (OpeningProof<F, D>, OpeningSet<F, D>)
|
||||
where
|
||||
F: Extendable<D>,
|
||||
{
|
||||
let config = &common_data.config.fri_config;
|
||||
assert!(D > 1, "Not implemented for D=1.");
|
||||
let degree_log = commitments[0].degree_log;
|
||||
let g = F::Extension::primitive_root_of_unity(degree_log);
|
||||
@ -145,7 +147,7 @@ impl<F: Field> ListPolynomialCommitment<F> {
|
||||
commitments[1],
|
||||
commitments[2],
|
||||
commitments[3],
|
||||
commitments[4],
|
||||
common_data,
|
||||
);
|
||||
challenger.observe_opening_set(&os);
|
||||
|
||||
@ -157,8 +159,7 @@ impl<F: Field> ListPolynomialCommitment<F> {
|
||||
|
||||
// Polynomials opened at a single point.
|
||||
let single_polys = [
|
||||
PlonkPolynomials::CONSTANTS,
|
||||
PlonkPolynomials::SIGMAS,
|
||||
PlonkPolynomials::CONSTANTS_SIGMAS,
|
||||
PlonkPolynomials::QUOTIENT,
|
||||
]
|
||||
.iter()
|
||||
@ -291,6 +292,7 @@ mod tests {
|
||||
use anyhow::Result;
|
||||
|
||||
use super::*;
|
||||
use crate::circuit_data::CircuitConfig;
|
||||
use crate::plonk_common::PlonkPolynomials;
|
||||
|
||||
fn gen_random_test_case<F: Field + Extendable<D>, const D: usize>(
|
||||
@ -318,7 +320,7 @@ mod tests {
|
||||
}
|
||||
|
||||
fn check_batch_polynomial_commitment<F: Field + Extendable<D>, const D: usize>() -> Result<()> {
|
||||
let ks = [1, 2, 3, 5, 8];
|
||||
let ks = [10, 2, 3, 8];
|
||||
let degree_log = 11;
|
||||
let fri_config = FriConfig {
|
||||
proof_of_work_bits: 2,
|
||||
@ -326,12 +328,27 @@ mod tests {
|
||||
reduction_arity_bits: vec![2, 3, 1, 2],
|
||||
num_query_rounds: 3,
|
||||
};
|
||||
// We only care about `fri_config, num_constants`, and `num_routed_wires` here.
|
||||
let common_data = CommonCircuitData {
|
||||
config: CircuitConfig {
|
||||
fri_config,
|
||||
num_routed_wires: 6,
|
||||
..CircuitConfig::large_config()
|
||||
},
|
||||
degree_bits: 0,
|
||||
gates: vec![],
|
||||
max_filtered_constraint_degree_bits: 0,
|
||||
num_gate_constraints: 0,
|
||||
num_constants: 4,
|
||||
k_is: vec![F::ONE; 6],
|
||||
circuit_digest: Hash::from_partial(vec![]),
|
||||
};
|
||||
|
||||
let lpcs = (0..5)
|
||||
let lpcs = (0..4)
|
||||
.map(|i| {
|
||||
ListPolynomialCommitment::<F>::new(
|
||||
gen_random_test_case(ks[i], degree_log),
|
||||
fri_config.rate_bits,
|
||||
common_data.config.fri_config.rate_bits,
|
||||
PlonkPolynomials::polynomials(i).blinding,
|
||||
)
|
||||
})
|
||||
@ -339,10 +356,10 @@ mod tests {
|
||||
|
||||
let zeta = gen_random_point::<F, D>(degree_log);
|
||||
let (proof, os) = ListPolynomialCommitment::open_plonk::<D>(
|
||||
&[&lpcs[0], &lpcs[1], &lpcs[2], &lpcs[3], &lpcs[4]],
|
||||
&[&lpcs[0], &lpcs[1], &lpcs[2], &lpcs[3]],
|
||||
zeta,
|
||||
&mut Challenger::new(),
|
||||
&fri_config,
|
||||
&common_data,
|
||||
);
|
||||
|
||||
proof.verify(
|
||||
@ -353,10 +370,9 @@ mod tests {
|
||||
lpcs[1].merkle_tree.root,
|
||||
lpcs[2].merkle_tree.root,
|
||||
lpcs[3].merkle_tree.root,
|
||||
lpcs[4].merkle_tree.root,
|
||||
],
|
||||
&mut Challenger::new(),
|
||||
&fri_config,
|
||||
&common_data.config.fri_config,
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
10
src/proof.rs
10
src/proof.rs
@ -1,5 +1,6 @@
|
||||
use std::convert::TryInto;
|
||||
|
||||
use crate::circuit_data::CommonCircuitData;
|
||||
use crate::field::extension_field::target::ExtensionTarget;
|
||||
use crate::field::extension_field::Extendable;
|
||||
use crate::field::field::Field;
|
||||
@ -160,11 +161,11 @@ impl<F: Field + Extendable<D>, const D: usize> OpeningSet<F, D> {
|
||||
pub fn new(
|
||||
z: F::Extension,
|
||||
g: F::Extension,
|
||||
constant_commitment: &ListPolynomialCommitment<F>,
|
||||
plonk_sigmas_commitment: &ListPolynomialCommitment<F>,
|
||||
constants_sigmas_commitment: &ListPolynomialCommitment<F>,
|
||||
wires_commitment: &ListPolynomialCommitment<F>,
|
||||
plonk_zs_commitment: &ListPolynomialCommitment<F>,
|
||||
quotient_polys_commitment: &ListPolynomialCommitment<F>,
|
||||
common_data: &CommonCircuitData<F, D>,
|
||||
) -> Self {
|
||||
let eval_commitment = |z: F::Extension, c: &ListPolynomialCommitment<F>| {
|
||||
c.polynomials
|
||||
@ -172,9 +173,10 @@ impl<F: Field + Extendable<D>, const D: usize> OpeningSet<F, D> {
|
||||
.map(|p| p.to_extension().eval(z))
|
||||
.collect::<Vec<_>>()
|
||||
};
|
||||
let constants_sigmas_eval = eval_commitment(z, constants_sigmas_commitment);
|
||||
Self {
|
||||
constants: eval_commitment(z, constant_commitment),
|
||||
plonk_s_sigmas: eval_commitment(z, plonk_sigmas_commitment),
|
||||
constants: constants_sigmas_eval[common_data.constants_range()].to_vec(),
|
||||
plonk_s_sigmas: constants_sigmas_eval[common_data.sigmas_range()].to_vec(),
|
||||
wires: eval_commitment(z, wires_commitment),
|
||||
plonk_zs: eval_commitment(z, plonk_zs_commitment),
|
||||
plonk_zs_right: eval_commitment(g * z, plonk_zs_commitment),
|
||||
|
||||
@ -7,7 +7,7 @@ use crate::circuit_data::{CommonCircuitData, ProverOnlyCircuitData};
|
||||
use crate::field::extension_field::Extendable;
|
||||
use crate::generator::generate_partial_witness;
|
||||
use crate::plonk_challenger::Challenger;
|
||||
use crate::plonk_common::{eval_vanishing_poly_base, ZeroPolyOnCoset};
|
||||
use crate::plonk_common::{eval_vanishing_poly_base, PlonkPolynomials, ZeroPolyOnCoset};
|
||||
use crate::polynomial::commitment::ListPolynomialCommitment;
|
||||
use crate::polynomial::polynomial::{PolynomialCoeffs, PolynomialValues};
|
||||
use crate::proof::Proof;
|
||||
@ -61,7 +61,11 @@ pub(crate) fn prove<F: Extendable<D>, const D: usize>(
|
||||
// TODO: Could try parallelizing the transpose, or not doing it explicitly, instead having
|
||||
// merkle_root_bit_rev_order do it implicitly.
|
||||
let wires_commitment = timed!(
|
||||
ListPolynomialCommitment::new(wires_values, fri_config.rate_bits, true),
|
||||
ListPolynomialCommitment::new(
|
||||
wires_values,
|
||||
fri_config.rate_bits,
|
||||
PlonkPolynomials::WIRES.blinding
|
||||
),
|
||||
"to compute wires commitment"
|
||||
);
|
||||
|
||||
@ -80,7 +84,11 @@ pub(crate) fn prove<F: Extendable<D>, const D: usize>(
|
||||
);
|
||||
|
||||
let plonk_zs_commitment = timed!(
|
||||
ListPolynomialCommitment::new(plonk_z_vecs, fri_config.rate_bits, true),
|
||||
ListPolynomialCommitment::new(
|
||||
plonk_z_vecs,
|
||||
fri_config.rate_bits,
|
||||
PlonkPolynomials::ZS.blinding
|
||||
),
|
||||
"to commit to Z's"
|
||||
);
|
||||
|
||||
@ -122,7 +130,7 @@ pub(crate) fn prove<F: Extendable<D>, const D: usize>(
|
||||
ListPolynomialCommitment::new_from_polys(
|
||||
all_quotient_poly_chunks,
|
||||
fri_config.rate_bits,
|
||||
true
|
||||
PlonkPolynomials::QUOTIENT.blinding
|
||||
),
|
||||
"to commit to quotient polys"
|
||||
);
|
||||
@ -134,15 +142,14 @@ pub(crate) fn prove<F: Extendable<D>, const D: usize>(
|
||||
let (opening_proof, openings) = timed!(
|
||||
ListPolynomialCommitment::open_plonk(
|
||||
&[
|
||||
&prover_data.constants_commitment,
|
||||
&prover_data.sigmas_commitment,
|
||||
&prover_data.constants_sigmas_commitment,
|
||||
&wires_commitment,
|
||||
&plonk_zs_commitment,
|
||||
"ient_polys_commitment,
|
||||
],
|
||||
zeta,
|
||||
&mut challenger,
|
||||
&common_data.config.fri_config
|
||||
common_data,
|
||||
),
|
||||
"to compute opening proofs"
|
||||
);
|
||||
@ -187,7 +194,9 @@ fn compute_z<F: Extendable<D>, const D: usize>(
|
||||
let x = subgroup[i - 1];
|
||||
let mut numerator = F::ONE;
|
||||
let mut denominator = F::ONE;
|
||||
let s_sigmas = prover_data.sigmas_commitment.original_values(i - 1);
|
||||
let s_sigmas = &prover_data
|
||||
.constants_sigmas_commitment
|
||||
.original_values(i - 1)[common_data.sigmas_range()];
|
||||
for j in 0..common_data.config.num_routed_wires {
|
||||
let wire_value = witness.get_wire(i - 1, j);
|
||||
let k_i = k_is[j];
|
||||
@ -247,8 +256,9 @@ fn compute_quotient_polys<'a, F: Extendable<D>, const D: usize>(
|
||||
.map(|(i, x)| {
|
||||
let shifted_x = F::coset_shift() * x;
|
||||
let i_next = (i + next_step) % lde_size;
|
||||
let local_constants = get_at_index(&prover_data.constants_commitment, i);
|
||||
let s_sigmas = get_at_index(&prover_data.sigmas_commitment, i);
|
||||
let local_constants_sigmas = get_at_index(&prover_data.constants_sigmas_commitment, i);
|
||||
let local_constants = &local_constants_sigmas[common_data.constants_range()];
|
||||
let s_sigmas = &local_constants_sigmas[common_data.sigmas_range()];
|
||||
let local_wires = get_at_index(wires_commitment, i);
|
||||
let local_plonk_zs = get_at_index(plonk_zs_commitment, i);
|
||||
let next_plonk_zs = get_at_index(plonk_zs_commitment, i_next);
|
||||
|
||||
@ -64,8 +64,7 @@ pub(crate) fn verify<F: Extendable<D>, const D: usize>(
|
||||
let evaluations = proof.openings.clone();
|
||||
|
||||
let merkle_roots = &[
|
||||
verifier_data.constants_root,
|
||||
verifier_data.sigmas_root,
|
||||
verifier_data.constants_sigmas_root,
|
||||
proof.wires_root,
|
||||
proof.plonk_zs_root,
|
||||
proof.quotient_polys_root,
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user