Merge branch 'main' into partial_witness_vec

This commit is contained in:
wborgeaud 2021-08-09 09:23:17 +02:00
commit 4f4839dcbe
8 changed files with 102 additions and 145 deletions

View File

@ -24,6 +24,13 @@ anyhow = "1.0.40"
serde = { version = "1.0", features = ["derive"] }
serde_cbor = "0.11.1"
[dev-dependencies]
criterion = "0.3.5"
[[bench]]
name = "field_arithmetic"
harness = false
[profile.release]
opt-level = 3
#lto = "fat"

View File

@ -0,0 +1,28 @@
use std::any::type_name;
use criterion::{criterion_group, criterion_main, BatchSize, Criterion};
use plonky2::field::crandall_field::CrandallField;
use plonky2::field::extension_field::quartic::QuarticCrandallField;
use plonky2::field::field_types::Field;
pub(crate) fn bench_field<F: Field>(c: &mut Criterion) {
c.bench_function(&format!("{} mul", type_name::<F>()), |b| {
b.iter_batched(
|| (F::rand(), F::rand()),
|(x, y)| x * y,
BatchSize::SmallInput,
)
});
c.bench_function(&format!("{} try_inverse", type_name::<F>()), |b| {
b.iter_batched(|| F::rand(), |x| x.try_inverse(), BatchSize::SmallInput)
});
}
fn criterion_benchmark(c: &mut Criterion) {
bench_field::<CrandallField>(c);
bench_field::<QuarticCrandallField>(c);
}
criterion_group!(benches, criterion_benchmark);
criterion_main!(benches);

View File

@ -1,25 +1,20 @@
use anyhow::Result;
use rayon::prelude::*;
use serde::{Deserialize, Serialize};
use crate::field::extension_field::target::ExtensionTarget;
use crate::field::extension_field::Extendable;
use crate::field::field_types::Field;
use crate::fri::proof::{FriProof, FriProofTarget};
use crate::fri::proof::FriProof;
use crate::fri::{prover::fri_proof, verifier::verify_fri_proof};
use crate::hash::hash_types::{HashOut, HashOutTarget};
use crate::hash::hash_types::HashOut;
use crate::hash::merkle_tree::MerkleTree;
use crate::iop::challenger::{Challenger, RecursiveChallenger};
use crate::plonk::circuit_builder::CircuitBuilder;
use crate::iop::challenger::Challenger;
use crate::plonk::circuit_data::CommonCircuitData;
use crate::plonk::plonk_common::PlonkPolynomials;
use crate::plonk::proof::{OpeningSet, OpeningSetTarget};
use crate::plonk::proof::OpeningSet;
use crate::polynomial::polynomial::{PolynomialCoeffs, PolynomialValues};
use crate::timed;
use crate::util::reducing::ReducingFactor;
use crate::util::timing::TimingTree;
use crate::util::{log2_ceil, log2_strict, reverse_bits, reverse_index_bits_in_place, transpose};
use crate::with_context;
use crate::util::{log2_strict, reverse_bits, reverse_index_bits_in_place, transpose};
/// Two (~64 bit) field elements gives ~128 bit security.
pub const SALT_SIZE: usize = 2;
@ -78,8 +73,6 @@ impl<F: Field> PolynomialBatchCommitment<F> {
blinding: bool,
timing: &mut TimingTree,
) -> Self {
// TODO: Could try parallelizing the transpose, or not doing it explicitly, instead having
// MerkleTree do it implicitly.
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));
@ -131,7 +124,7 @@ impl<F: Field> PolynomialBatchCommitment<F> {
challenger: &mut Challenger<F>,
common_data: &CommonCircuitData<F, D>,
timing: &mut TimingTree,
) -> (OpeningProof<F, D>, OpeningSet<F, D>)
) -> (FriProof<F, D>, OpeningSet<F, D>)
where
F: Extendable<D>,
{
@ -223,13 +216,7 @@ impl<F: Field> PolynomialBatchCommitment<F> {
timing,
);
(
OpeningProof {
fri_proof,
quotient_degree: final_poly.len(),
},
os,
)
(fri_proof, os)
}
/// Given `points=(x_i)`, `evals=(y_i)` and `poly=P` with `P(x_i)=y_i`, computes the polynomial
@ -260,75 +247,6 @@ impl<F: Field> PolynomialBatchCommitment<F> {
}
}
#[derive(Serialize, Deserialize, Clone, Debug)]
#[serde(bound = "")]
pub struct OpeningProof<F: Extendable<D>, const D: usize> {
pub(crate) fri_proof: FriProof<F, D>,
// TODO: Get the degree from `CommonCircuitData` instead.
quotient_degree: usize,
}
impl<F: Extendable<D>, const D: usize> OpeningProof<F, D> {
pub fn verify(
&self,
zeta: F::Extension,
os: &OpeningSet<F, D>,
merkle_roots: &[HashOut<F>],
challenger: &mut Challenger<F>,
common_data: &CommonCircuitData<F, D>,
) -> Result<()> {
challenger.observe_opening_set(os);
let alpha = challenger.get_extension_challenge();
verify_fri_proof(
log2_strict(self.quotient_degree),
&os,
zeta,
alpha,
merkle_roots,
&self.fri_proof,
challenger,
common_data,
)
}
}
pub struct OpeningProofTarget<const D: usize> {
pub(crate) fri_proof: FriProofTarget<D>,
}
impl<const D: usize> OpeningProofTarget<D> {
pub fn verify<F: Extendable<D>>(
&self,
zeta: ExtensionTarget<D>,
os: &OpeningSetTarget<D>,
merkle_roots: &[HashOutTarget],
challenger: &mut RecursiveChallenger,
common_data: &CommonCircuitData<F, D>,
builder: &mut CircuitBuilder<F, D>,
) {
challenger.observe_opening_set(os);
let alpha = challenger.get_extension_challenge(builder);
with_context!(
builder,
"verify FRI proof",
builder.verify_fri_proof(
log2_ceil(common_data.degree()),
&os,
zeta,
alpha,
merkle_roots,
&self.fri_proof,
challenger,
common_data,
)
);
}
}
#[cfg(test)]
mod tests {
use anyhow::Result;
@ -363,7 +281,7 @@ mod tests {
fn check_batch_polynomial_commitment<F: Field + Extendable<D>, const D: usize>() -> Result<()> {
let ks = [10, 2, 10, 8];
let degree_log = 11;
let degree_bits = 11;
let fri_config = FriConfig {
proof_of_work_bits: 2,
reduction_arity_bits: vec![2, 3, 1, 2],
@ -376,7 +294,7 @@ mod tests {
num_routed_wires: 6,
..CircuitConfig::large_config()
},
degree_bits: 0,
degree_bits,
gates: vec![],
quotient_degree_factor: 0,
num_gate_constraints: 0,
@ -389,7 +307,7 @@ mod tests {
let lpcs = (0..4)
.map(|i| {
PolynomialBatchCommitment::<F>::new(
gen_random_test_case(ks[i], degree_log),
gen_random_test_case(ks[i], degree_bits),
common_data.config.rate_bits,
PlonkPolynomials::polynomials(i).blinding,
&mut TimingTree::default(),
@ -397,7 +315,7 @@ mod tests {
})
.collect::<Vec<_>>();
let zeta = gen_random_point::<F, D>(degree_log);
let zeta = gen_random_point::<F, D>(degree_bits);
let (proof, os) = PolynomialBatchCommitment::open_plonk::<D>(
&[&lpcs[0], &lpcs[1], &lpcs[2], &lpcs[3]],
zeta,
@ -406,15 +324,18 @@ mod tests {
&mut TimingTree::default(),
);
proof.verify(
zeta,
let merkle_roots = &[
lpcs[0].merkle_tree.root,
lpcs[1].merkle_tree.root,
lpcs[2].merkle_tree.root,
lpcs[3].merkle_tree.root,
];
verify_fri_proof(
&os,
&[
lpcs[0].merkle_tree.root,
lpcs[1].merkle_tree.root,
lpcs[2].merkle_tree.root,
lpcs[3].merkle_tree.root,
],
zeta,
merkle_roots,
&proof,
&mut Challenger::new(),
&common_data,
)

View File

@ -70,13 +70,10 @@ impl<F: Extendable<D>, const D: usize> CircuitBuilder<F, D> {
pub fn verify_fri_proof(
&mut self,
purported_degree_log: usize,
// Openings of the PLONK polynomials.
os: &OpeningSetTarget<D>,
// Point at which the PLONK polynomials are opened.
zeta: ExtensionTarget<D>,
// Scaling factor to combine polynomials.
alpha: ExtensionTarget<D>,
initial_merkle_roots: &[HashOutTarget],
proof: &FriProofTarget<D>,
challenger: &mut RecursiveChallenger,
@ -85,7 +82,7 @@ impl<F: Extendable<D>, const D: usize> CircuitBuilder<F, D> {
let config = &common_data.config;
let total_arities = config.fri_config.reduction_arity_bits.iter().sum::<usize>();
debug_assert_eq!(
purported_degree_log,
common_data.degree_bits,
log2_strict(proof.final_poly.len()) + total_arities,
"Final polynomial has wrong degree."
);
@ -93,6 +90,11 @@ impl<F: Extendable<D>, const D: usize> CircuitBuilder<F, D> {
// Size of the LDE domain.
let n = proof.final_poly.len() << (total_arities + config.rate_bits);
challenger.observe_opening_set(&os);
// Scaling factor to combine polynomials.
let alpha = challenger.get_extension_challenge(self);
let betas = with_context!(
self,
"recover the random betas used in the FRI reductions.",

View File

@ -69,13 +69,10 @@ fn fri_verify_proof_of_work<F: Field + Extendable<D>, const D: usize>(
}
pub fn verify_fri_proof<F: Field + Extendable<D>, const D: usize>(
purported_degree_log: usize,
// Openings of the PLONK polynomials.
os: &OpeningSet<F, D>,
// Point at which the PLONK polynomials are opened.
zeta: F::Extension,
// Scaling factor to combine polynomials.
alpha: F::Extension,
initial_merkle_roots: &[HashOut<F>],
proof: &FriProof<F, D>,
challenger: &mut Challenger<F>,
@ -84,10 +81,15 @@ pub fn verify_fri_proof<F: Field + Extendable<D>, const D: usize>(
let config = &common_data.config;
let total_arities = config.fri_config.reduction_arity_bits.iter().sum::<usize>();
ensure!(
purported_degree_log == log2_strict(proof.final_poly.len()) + total_arities,
common_data.degree_bits == log2_strict(proof.final_poly.len()) + total_arities,
"Final polynomial has wrong degree."
);
challenger.observe_opening_set(os);
// Scaling factor to combine polynomials.
let alpha = challenger.get_extension_challenge();
// Size of the LDE domain.
let n = proof.final_poly.len() << (total_arities + config.rate_bits);

View File

@ -3,7 +3,8 @@ use serde::{Deserialize, Serialize};
use crate::field::extension_field::target::ExtensionTarget;
use crate::field::extension_field::Extendable;
use crate::fri::commitment::{OpeningProof, OpeningProofTarget, PolynomialBatchCommitment};
use crate::fri::commitment::PolynomialBatchCommitment;
use crate::fri::proof::{FriProof, FriProofTarget};
use crate::hash::hash_types::{HashOut, HashOutTarget};
use crate::iop::target::Target;
use crate::plonk::circuit_data::CommonCircuitData;
@ -19,8 +20,8 @@ pub struct Proof<F: Extendable<D>, const D: usize> {
pub quotient_polys_root: HashOut<F>,
/// Purported values of each polynomial at the challenge point.
pub openings: OpeningSet<F, D>,
/// A FRI argument for each FRI query.
pub opening_proof: OpeningProof<F, D>,
/// A batch FRI argument for all openings.
pub opening_proof: FriProof<F, D>,
}
#[derive(Serialize, Deserialize, Clone, Debug)]
@ -35,7 +36,7 @@ pub struct ProofTarget<const D: usize> {
pub plonk_zs_partial_products_root: HashOutTarget,
pub quotient_polys_root: HashOutTarget,
pub openings: OpeningSetTarget<D>,
pub opening_proof: OpeningProofTarget<D>,
pub opening_proof: FriProofTarget<D>,
}
pub struct ProofWithPublicInputsTarget<const D: usize> {

View File

@ -114,13 +114,17 @@ impl<F: Extendable<D>, const D: usize> CircuitBuilder<F, D> {
proof.quotient_polys_root,
];
proof.opening_proof.verify(
zeta,
&proof.openings,
merkle_roots,
&mut challenger,
inner_common_data,
with_context!(
self,
"verify FRI proof",
self.verify_fri_proof(
&proof.openings,
zeta,
merkle_roots,
&proof.opening_proof,
&mut challenger,
inner_common_data,
)
);
}
}
@ -131,7 +135,6 @@ mod tests {
use super::*;
use crate::field::crandall_field::CrandallField;
use crate::fri::commitment::OpeningProofTarget;
use crate::fri::proof::{
FriInitialTreeProofTarget, FriProofTarget, FriQueryRoundTarget, FriQueryStepTarget,
};
@ -153,7 +156,7 @@ mod tests {
},
steps: vec![],
};
for (v, merkle_proof) in &proof.opening_proof.fri_proof.query_round_proofs[0]
for (v, merkle_proof) in &proof.opening_proof.query_round_proofs[0]
.initial_trees_proof
.evals_proofs
{
@ -164,7 +167,7 @@ mod tests {
},
));
}
for step in &proof.opening_proof.fri_proof.query_round_proofs[0].steps {
for step in &proof.opening_proof.query_round_proofs[0].steps {
query_round.steps.push(FriQueryStepTarget {
evals: builder.add_virtual_extension_targets(step.evals.len()),
merkle_proof: MerkleProofTarget {
@ -201,27 +204,20 @@ mod tests {
quotient_polys: builder
.add_virtual_extension_targets(proof.openings.quotient_polys.len()),
};
let query_round_proofs = (0..proof.opening_proof.fri_proof.query_round_proofs.len())
let query_round_proofs = (0..proof.opening_proof.query_round_proofs.len())
.map(|_| get_fri_query_round(proof, builder))
.collect();
let commit_phase_merkle_roots = (0..proof
.opening_proof
.fri_proof
.commit_phase_merkle_roots
.len())
let commit_phase_merkle_roots = (0..proof.opening_proof.commit_phase_merkle_roots.len())
.map(|_| builder.add_virtual_hash())
.collect();
let opening_proof =
OpeningProofTarget {
fri_proof: FriProofTarget {
commit_phase_merkle_roots,
query_round_proofs,
final_poly: PolynomialCoeffsExtTarget(builder.add_virtual_extension_targets(
proof.opening_proof.fri_proof.final_poly.len(),
)),
pow_witness: builder.add_virtual_target(),
},
};
let opening_proof = FriProofTarget {
commit_phase_merkle_roots,
query_round_proofs,
final_poly: PolynomialCoeffsExtTarget(
builder.add_virtual_extension_targets(proof.opening_proof.final_poly.len()),
),
pow_witness: builder.add_virtual_target(),
};
let proof = ProofTarget {
wires_root,
@ -307,8 +303,8 @@ mod tests {
pw.set_extension_target(t, x);
}
let fri_proof = &proof.opening_proof.fri_proof;
let fpt = &pt.opening_proof.fri_proof;
let fri_proof = &proof.opening_proof;
let fpt = &pt.opening_proof;
pw.set_target(fpt.pow_witness, fri_proof.pow_witness);

View File

@ -2,6 +2,7 @@ use anyhow::{ensure, Result};
use crate::field::extension_field::Extendable;
use crate::field::field_types::Field;
use crate::fri::verifier::verify_fri_proof;
use crate::hash::hashing::hash_n_to_hash;
use crate::iop::challenger::Challenger;
use crate::plonk::circuit_data::{CommonCircuitData, VerifierOnlyCircuitData};
@ -82,8 +83,6 @@ pub(crate) fn verify<F: Extendable<D>, const D: usize>(
ensure!(vanishing_polys_zeta[i] == z_h_zeta * reduce_with_powers(chunk, zeta_pow_deg));
}
let evaluations = proof.openings.clone();
let merkle_roots = &[
verifier_data.constants_sigmas_root,
proof.wires_root,
@ -91,10 +90,11 @@ pub(crate) fn verify<F: Extendable<D>, const D: usize>(
proof.quotient_polys_root,
];
proof.opening_proof.verify(
verify_fri_proof(
&proof.openings,
zeta,
&evaluations,
merkle_roots,
&proof.opening_proof,
&mut challenger,
common_data,
)?;