mirror of
https://github.com/logos-storage/plonky2.git
synced 2026-01-05 23:33:07 +00:00
Update PLONK prover.
This commit is contained in:
parent
0bae47bedb
commit
ea7926bd95
@ -12,7 +12,7 @@ use anyhow::Result;
|
|||||||
|
|
||||||
pub const SALT_SIZE: usize = 2;
|
pub const SALT_SIZE: usize = 2;
|
||||||
|
|
||||||
struct ListPolynomialCommitment<F: Field> {
|
pub struct ListPolynomialCommitment<F: Field> {
|
||||||
pub polynomials: Vec<PolynomialCoeffs<F>>,
|
pub polynomials: Vec<PolynomialCoeffs<F>>,
|
||||||
pub fri_config: FriConfig,
|
pub fri_config: FriConfig,
|
||||||
pub merkle_tree: MerkleTree<F>,
|
pub merkle_tree: MerkleTree<F>,
|
||||||
|
|||||||
@ -26,6 +26,9 @@ impl<F: Field> PolynomialValues<F> {
|
|||||||
self.values.len()
|
self.values.len()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn ifft(self) -> PolynomialCoeffs<F> {
|
||||||
|
ifft(self)
|
||||||
|
}
|
||||||
pub fn lde_multiple(polys: Vec<Self>, rate_bits: usize) -> Vec<Self> {
|
pub fn lde_multiple(polys: Vec<Self>, rate_bits: usize) -> Vec<Self> {
|
||||||
polys.into_iter().map(|p| p.lde(rate_bits)).collect()
|
polys.into_iter().map(|p| p.lde(rate_bits)).collect()
|
||||||
}
|
}
|
||||||
|
|||||||
23
src/proof.rs
23
src/proof.rs
@ -1,5 +1,6 @@
|
|||||||
use crate::field::field::Field;
|
use crate::field::field::Field;
|
||||||
use crate::merkle_proofs::{MerkleProof, MerkleProofTarget};
|
use crate::merkle_proofs::{MerkleProof, MerkleProofTarget};
|
||||||
|
use crate::polynomial::commitment::ListPolynomialCommitment;
|
||||||
use crate::polynomial::polynomial::PolynomialCoeffs;
|
use crate::polynomial::polynomial::PolynomialCoeffs;
|
||||||
use crate::target::Target;
|
use crate::target::Target;
|
||||||
use std::convert::TryInto;
|
use std::convert::TryInto;
|
||||||
@ -136,6 +137,28 @@ pub struct OpeningSet<F: Field> {
|
|||||||
pub quotient_polys: Vec<F>,
|
pub quotient_polys: Vec<F>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<F: Field> OpeningSet<F> {
|
||||||
|
pub fn new(
|
||||||
|
z: F,
|
||||||
|
constant_commitment: &ListPolynomialCommitment<F>,
|
||||||
|
plonk_sigmas_commitment: &ListPolynomialCommitment<F>,
|
||||||
|
wires_commitment: &ListPolynomialCommitment<F>,
|
||||||
|
plonk_zs_commitment: &ListPolynomialCommitment<F>,
|
||||||
|
quotient_polys_commitment: &ListPolynomialCommitment<F>,
|
||||||
|
) -> Self {
|
||||||
|
let eval_commitment = |z: F, c: &ListPolynomialCommitment<F>| {
|
||||||
|
c.polynomials.iter().map(|p| p.eval(z)).collect::<Vec<_>>()
|
||||||
|
};
|
||||||
|
Self {
|
||||||
|
constants: eval_commitment(z, constant_commitment),
|
||||||
|
plonk_sigmas: eval_commitment(z, plonk_sigmas_commitment),
|
||||||
|
wires: eval_commitment(z, wires_commitment),
|
||||||
|
plonk_zs: eval_commitment(z, plonk_zs_commitment),
|
||||||
|
quotient_polys: eval_commitment(z, quotient_polys_commitment),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// The purported values of each polynomial at a single point.
|
/// The purported values of each polynomial at a single point.
|
||||||
pub struct OpeningSetTarget {
|
pub struct OpeningSetTarget {
|
||||||
pub constants: Vec<Target>,
|
pub constants: Vec<Target>,
|
||||||
|
|||||||
122
src/prover.rs
122
src/prover.rs
@ -6,13 +6,15 @@ use rayon::prelude::*;
|
|||||||
use crate::circuit_data::{CommonCircuitData, ProverOnlyCircuitData};
|
use crate::circuit_data::{CommonCircuitData, ProverOnlyCircuitData};
|
||||||
use crate::field::fft::{fft, ifft};
|
use crate::field::fft::{fft, ifft};
|
||||||
use crate::field::field::Field;
|
use crate::field::field::Field;
|
||||||
|
use crate::fri::FriConfig;
|
||||||
use crate::generator::generate_partial_witness;
|
use crate::generator::generate_partial_witness;
|
||||||
use crate::merkle_tree::MerkleTree;
|
use crate::merkle_tree::MerkleTree;
|
||||||
use crate::plonk_challenger::Challenger;
|
use crate::plonk_challenger::Challenger;
|
||||||
use crate::plonk_common::{eval_l_1, evaluate_gate_constraints, reduce_with_powers_multi};
|
use crate::plonk_common::{eval_l_1, evaluate_gate_constraints, reduce_with_powers_multi};
|
||||||
|
use crate::polynomial::commitment::ListPolynomialCommitment;
|
||||||
use crate::polynomial::division::divide_by_z_h;
|
use crate::polynomial::division::divide_by_z_h;
|
||||||
use crate::polynomial::polynomial::{PolynomialCoeffs, PolynomialValues};
|
use crate::polynomial::polynomial::{PolynomialCoeffs, PolynomialValues};
|
||||||
use crate::proof::Proof;
|
use crate::proof::{OpeningSet, Proof};
|
||||||
use crate::util::{transpose, transpose_poly_values};
|
use crate::util::{transpose, transpose_poly_values};
|
||||||
use crate::vars::EvaluationVars;
|
use crate::vars::EvaluationVars;
|
||||||
use crate::wire::Wire;
|
use crate::wire::Wire;
|
||||||
@ -23,6 +25,14 @@ pub(crate) fn prove<F: Field>(
|
|||||||
common_data: &CommonCircuitData<F>,
|
common_data: &CommonCircuitData<F>,
|
||||||
inputs: PartialWitness<F>,
|
inputs: PartialWitness<F>,
|
||||||
) -> Proof<F> {
|
) -> Proof<F> {
|
||||||
|
// TODO: Change this to real values.
|
||||||
|
let fri_config = FriConfig {
|
||||||
|
proof_of_work_bits: 1,
|
||||||
|
rate_bits: 1,
|
||||||
|
reduction_arity_bits: vec![1],
|
||||||
|
num_query_rounds: 1,
|
||||||
|
blinding: true,
|
||||||
|
};
|
||||||
let start_proof_gen = Instant::now();
|
let start_proof_gen = Instant::now();
|
||||||
|
|
||||||
let start_witness = Instant::now();
|
let start_witness = Instant::now();
|
||||||
@ -41,10 +51,10 @@ pub(crate) fn prove<F: Field>(
|
|||||||
|
|
||||||
let start_wire_ldes = Instant::now();
|
let start_wire_ldes = Instant::now();
|
||||||
let degree = common_data.degree();
|
let degree = common_data.degree();
|
||||||
let wire_ldes = (0..num_wires)
|
let wires_polynomials: Vec<PolynomialCoeffs<F>> = (0..num_wires)
|
||||||
.into_par_iter()
|
.into_par_iter()
|
||||||
.map(|i| compute_wire_lde(i, &witness, degree, config.rate_bits))
|
.map(|i| compute_wire_polynomial(i, &witness, degree))
|
||||||
.collect::<Vec<_>>();
|
.collect();
|
||||||
info!(
|
info!(
|
||||||
"{:.3}s to compute wire LDEs",
|
"{:.3}s to compute wire LDEs",
|
||||||
start_wire_ldes.elapsed().as_secs_f32()
|
start_wire_ldes.elapsed().as_secs_f32()
|
||||||
@ -52,19 +62,11 @@ pub(crate) fn prove<F: Field>(
|
|||||||
|
|
||||||
// TODO: Could try parallelizing the transpose, or not doing it explicitly, instead having
|
// TODO: Could try parallelizing the transpose, or not doing it explicitly, instead having
|
||||||
// merkle_root_bit_rev_order do it implicitly.
|
// merkle_root_bit_rev_order do it implicitly.
|
||||||
let start_wire_transpose = Instant::now();
|
let start_wires_commitment = Instant::now();
|
||||||
let wire_ldes_t = transpose_poly_values(wire_ldes);
|
let wires_commitment = ListPolynomialCommitment::new(wires_polynomials, &fri_config);
|
||||||
info!(
|
info!(
|
||||||
"{:.3}s to transpose wire LDEs",
|
"{:.3}s to transpose wire LDEs",
|
||||||
start_wire_transpose.elapsed().as_secs_f32()
|
start_wires_commitment.elapsed().as_secs_f32()
|
||||||
);
|
|
||||||
|
|
||||||
// TODO: Could avoid cloning if it's significant?
|
|
||||||
let start_wires_root = Instant::now();
|
|
||||||
let wires_tree = MerkleTree::new(wire_ldes_t, true);
|
|
||||||
info!(
|
|
||||||
"{:.3}s to Merklize wire LDEs",
|
|
||||||
start_wires_root.elapsed().as_secs_f32()
|
|
||||||
);
|
);
|
||||||
|
|
||||||
let mut challenger = Challenger::new();
|
let mut challenger = Challenger::new();
|
||||||
@ -72,27 +74,25 @@ pub(crate) fn prove<F: Field>(
|
|||||||
// TODO: Need to include public inputs as well.
|
// TODO: Need to include public inputs as well.
|
||||||
challenger.observe_hash(&common_data.circuit_digest);
|
challenger.observe_hash(&common_data.circuit_digest);
|
||||||
|
|
||||||
challenger.observe_hash(&wires_tree.root);
|
challenger.observe_hash(&wires_commitment.merkle_tree.root);
|
||||||
let betas = challenger.get_n_challenges(num_checks);
|
let betas = challenger.get_n_challenges(num_checks);
|
||||||
let gammas = challenger.get_n_challenges(num_checks);
|
let gammas = challenger.get_n_challenges(num_checks);
|
||||||
|
|
||||||
let start_plonk_z = Instant::now();
|
let start_plonk_z = Instant::now();
|
||||||
let plonk_z_vecs = compute_zs(&common_data);
|
let plonk_z_vecs = compute_zs(&common_data);
|
||||||
let plonk_z_ldes = PolynomialValues::lde_multiple(plonk_z_vecs, config.rate_bits);
|
|
||||||
let plonk_z_ldes_t = transpose_poly_values(plonk_z_ldes);
|
|
||||||
info!(
|
info!(
|
||||||
"{:.3}s to compute Z's and their LDEs",
|
"{:.3}s to compute Z's",
|
||||||
start_plonk_z.elapsed().as_secs_f32()
|
start_plonk_z.elapsed().as_secs_f32()
|
||||||
);
|
);
|
||||||
|
|
||||||
let start_plonk_z_root = Instant::now();
|
let start_plonk_z_root = Instant::now();
|
||||||
let plonk_zs_tree = MerkleTree::new(plonk_z_ldes_t, true);
|
let plonk_zs_commitment = ListPolynomialCommitment::new(plonk_z_vecs, &fri_config);
|
||||||
info!(
|
info!(
|
||||||
"{:.3}s to Merklize Z's",
|
"{:.3}s to Merklize Z's",
|
||||||
start_plonk_z_root.elapsed().as_secs_f32()
|
start_plonk_z_root.elapsed().as_secs_f32()
|
||||||
);
|
);
|
||||||
|
|
||||||
challenger.observe_hash(&plonk_zs_tree.root);
|
challenger.observe_hash(&plonk_zs_commitment.merkle_tree.root);
|
||||||
|
|
||||||
let alphas = challenger.get_n_challenges(num_checks);
|
let alphas = challenger.get_n_challenges(num_checks);
|
||||||
|
|
||||||
@ -100,8 +100,8 @@ pub(crate) fn prove<F: Field>(
|
|||||||
let vanishing_polys = compute_vanishing_polys(
|
let vanishing_polys = compute_vanishing_polys(
|
||||||
common_data,
|
common_data,
|
||||||
prover_data,
|
prover_data,
|
||||||
&wires_tree,
|
&wires_commitment.merkle_tree,
|
||||||
&plonk_zs_tree,
|
&plonk_zs_commitment.merkle_tree,
|
||||||
&betas,
|
&betas,
|
||||||
&gammas,
|
&gammas,
|
||||||
&alphas,
|
&alphas,
|
||||||
@ -113,28 +113,53 @@ pub(crate) fn prove<F: Field>(
|
|||||||
|
|
||||||
// Compute the quotient polynomials, aka `t` in the Plonk paper.
|
// Compute the quotient polynomials, aka `t` in the Plonk paper.
|
||||||
let quotient_polys_start = Instant::now();
|
let quotient_polys_start = Instant::now();
|
||||||
let mut all_quotient_poly_chunk_ldes = Vec::with_capacity(num_checks * quotient_degree);
|
let mut all_quotient_poly_chunks = Vec::with_capacity(num_checks * quotient_degree);
|
||||||
for vanishing_poly in vanishing_polys.into_iter() {
|
for vanishing_poly in vanishing_polys.into_iter() {
|
||||||
let vanishing_poly_coeff = ifft(vanishing_poly);
|
let vanishing_poly_coeff = ifft(vanishing_poly);
|
||||||
let quotient_poly_coeff = divide_by_z_h(vanishing_poly_coeff, degree);
|
let quotient_poly_coeff = divide_by_z_h(vanishing_poly_coeff, degree);
|
||||||
// Split t into degree-n chunks.
|
// Split t into degree-n chunks.
|
||||||
let quotient_poly_coeff_chunks = quotient_poly_coeff.chunks(degree);
|
let quotient_poly_coeff_chunks = quotient_poly_coeff.chunks(degree);
|
||||||
let quotient_poly_coeff_ldes =
|
all_quotient_poly_chunks.extend(quotient_poly_coeff_chunks);
|
||||||
PolynomialCoeffs::lde_multiple(quotient_poly_coeff_chunks, config.rate_bits);
|
|
||||||
let quotient_poly_chunk_ldes: Vec<PolynomialValues<F>> =
|
|
||||||
quotient_poly_coeff_ldes.into_par_iter().map(fft).collect();
|
|
||||||
all_quotient_poly_chunk_ldes.extend(quotient_poly_chunk_ldes);
|
|
||||||
}
|
}
|
||||||
let quotient_polys_tree =
|
let quotient_polys_commitment =
|
||||||
MerkleTree::new(transpose_poly_values(all_quotient_poly_chunk_ldes), true);
|
ListPolynomialCommitment::new(all_quotient_poly_chunks, &fri_config);
|
||||||
info!(
|
info!(
|
||||||
"{:.3}s to compute quotient polys and their LDEs",
|
"{:.3}s to compute quotient polys and their LDEs",
|
||||||
quotient_polys_start.elapsed().as_secs_f32()
|
quotient_polys_start.elapsed().as_secs_f32()
|
||||||
);
|
);
|
||||||
|
|
||||||
let openings = Vec::new(); // TODO
|
challenger.observe_hash(&plonk_zs_commitment.merkle_tree.root);
|
||||||
|
|
||||||
let fri_proofs = Vec::new(); // TODO
|
// TODO: How many do we need?
|
||||||
|
let num_zetas = 2;
|
||||||
|
let zetas = challenger.get_n_challenges(num_zetas);
|
||||||
|
|
||||||
|
let openings = zetas
|
||||||
|
.iter()
|
||||||
|
.map(|&z| {
|
||||||
|
OpeningSet::new(
|
||||||
|
z,
|
||||||
|
todo!(),
|
||||||
|
todo!(),
|
||||||
|
&wires_commitment,
|
||||||
|
&plonk_zs_commitment,
|
||||||
|
"ient_polys_commitment,
|
||||||
|
)
|
||||||
|
})
|
||||||
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
|
// TODO: This re-evaluates the polynomial and is thus redundant with the openings above.
|
||||||
|
let fri_proofs = ListPolynomialCommitment::batch_open(
|
||||||
|
&[
|
||||||
|
&todo!(),
|
||||||
|
&todo!(),
|
||||||
|
&wires_commitment,
|
||||||
|
&plonk_zs_commitment,
|
||||||
|
"ient_polys_commitment,
|
||||||
|
],
|
||||||
|
&zetas,
|
||||||
|
&mut challenger,
|
||||||
|
);
|
||||||
|
|
||||||
info!(
|
info!(
|
||||||
"{:.3}s for overall witness & proof generation",
|
"{:.3}s for overall witness & proof generation",
|
||||||
@ -142,22 +167,22 @@ pub(crate) fn prove<F: Field>(
|
|||||||
);
|
);
|
||||||
|
|
||||||
Proof {
|
Proof {
|
||||||
wires_root: wires_tree.root,
|
wires_root: wires_commitment.merkle_tree.root,
|
||||||
plonk_zs_root: plonk_zs_tree.root,
|
plonk_zs_root: plonk_zs_commitment.merkle_tree.root,
|
||||||
quotient_polys_root: quotient_polys_tree.root,
|
quotient_polys_root: quotient_polys_commitment.merkle_tree.root,
|
||||||
openings,
|
openings,
|
||||||
fri_proofs,
|
fri_proofs,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn compute_zs<F: Field>(common_data: &CommonCircuitData<F>) -> Vec<PolynomialValues<F>> {
|
fn compute_zs<F: Field>(common_data: &CommonCircuitData<F>) -> Vec<PolynomialCoeffs<F>> {
|
||||||
(0..common_data.config.num_checks)
|
(0..common_data.config.num_checks)
|
||||||
.map(|i| compute_z(common_data, i))
|
.map(|i| compute_z(common_data, i))
|
||||||
.collect()
|
.collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn compute_z<F: Field>(common_data: &CommonCircuitData<F>, i: usize) -> PolynomialValues<F> {
|
fn compute_z<F: Field>(common_data: &CommonCircuitData<F>, i: usize) -> PolynomialCoeffs<F> {
|
||||||
PolynomialValues::zero(common_data.degree()) // TODO
|
PolynomialCoeffs::zero(common_data.degree()) // TODO
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Parallelize.
|
// TODO: Parallelize.
|
||||||
@ -263,6 +288,25 @@ fn compute_vanishing_poly_entry<F: Field>(
|
|||||||
reduce_with_powers_multi(&vanishing_terms, alphas)
|
reduce_with_powers_multi(&vanishing_terms, alphas)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn compute_wire_polynomial<F: Field>(
|
||||||
|
input: usize,
|
||||||
|
witness: &PartialWitness<F>,
|
||||||
|
degree: usize,
|
||||||
|
) -> PolynomialCoeffs<F> {
|
||||||
|
let wire_values = (0..degree)
|
||||||
|
// Some gates do not use all wires, and we do not require that generators populate unused
|
||||||
|
// wires, so some wire values will not be set. We can set these to any value; here we
|
||||||
|
// arbitrary pick zero. Ideally we would verify that no constraints operate on these unset
|
||||||
|
// wires, but that isn't trivial.
|
||||||
|
.map(|gate| {
|
||||||
|
witness
|
||||||
|
.try_get_wire(Wire { gate, input })
|
||||||
|
.unwrap_or(F::ZERO)
|
||||||
|
})
|
||||||
|
.collect();
|
||||||
|
PolynomialValues::new(wire_values).ifft()
|
||||||
|
}
|
||||||
|
|
||||||
fn compute_wire_lde<F: Field>(
|
fn compute_wire_lde<F: Field>(
|
||||||
input: usize,
|
input: usize,
|
||||||
witness: &PartialWitness<F>,
|
witness: &PartialWitness<F>,
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user