mirror of
https://github.com/logos-storage/plonky2.git
synced 2026-01-05 07:13:08 +00:00
Optional zk (#101)
* Make ZK optional * Remove rate from FriConfig Seems redundant, and we've had some tests break due to the two fields not matching. * zero_knowledge: false in bench
This commit is contained in:
parent
0a5d46bfa9
commit
d11bcd1928
@ -26,9 +26,9 @@ fn bench_prove<F: Field + Extendable<D>, const D: usize>() -> Result<()> {
|
||||
security_bits: 128,
|
||||
rate_bits: 3,
|
||||
num_challenges: 3,
|
||||
zero_knowledge: false,
|
||||
fri_config: FriConfig {
|
||||
proof_of_work_bits: 20,
|
||||
rate_bits: 3,
|
||||
reduction_arity_bits: vec![2, 2, 2, 2, 2, 2],
|
||||
num_query_rounds: 35,
|
||||
},
|
||||
|
||||
@ -333,7 +333,9 @@ impl<F: Extendable<D>, const D: usize> CircuitBuilder<F, D> {
|
||||
let final_poly_coeffs: usize = degree_estimate / arities.iter().product::<usize>();
|
||||
let fri_openings = fri_queries * (1 + D * total_fri_folding_points + D * final_poly_coeffs);
|
||||
|
||||
// We add D for openings at zeta.
|
||||
let regular_poly_openings = D + fri_openings;
|
||||
// We add 2 * D for openings at zeta and g * zeta.
|
||||
let z_openings = 2 * D + fri_openings;
|
||||
|
||||
(regular_poly_openings, z_openings)
|
||||
@ -364,6 +366,16 @@ impl<F: Extendable<D>, const D: usize> CircuitBuilder<F, D> {
|
||||
}
|
||||
|
||||
fn blind_and_pad(&mut self) {
|
||||
if self.config.zero_knowledge {
|
||||
self.blind();
|
||||
}
|
||||
|
||||
while !self.gate_instances.len().is_power_of_two() {
|
||||
self.add_gate_no_constants(NoopGate::get());
|
||||
}
|
||||
}
|
||||
|
||||
fn blind(&mut self) {
|
||||
let (regular_poly_openings, z_openings) = self.blinding_counts();
|
||||
info!(
|
||||
"Adding {} blinding terms for witness polynomials, and {}*2 for Z polynomials",
|
||||
@ -410,10 +422,6 @@ impl<F: Extendable<D>, const D: usize> CircuitBuilder<F, D> {
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
while !self.gate_instances.len().is_power_of_two() {
|
||||
self.add_gate_no_constants(NoopGate::get());
|
||||
}
|
||||
}
|
||||
|
||||
fn constant_polys(
|
||||
@ -508,8 +516,8 @@ impl<F: Extendable<D>, const D: usize> CircuitBuilder<F, D> {
|
||||
let constants_sigmas_vecs = [constant_vecs, sigma_vecs.clone()].concat();
|
||||
let constants_sigmas_commitment = ListPolynomialCommitment::new(
|
||||
constants_sigmas_vecs,
|
||||
self.config.fri_config.rate_bits,
|
||||
PlonkPolynomials::CONSTANTS_SIGMAS.blinding,
|
||||
self.config.rate_bits,
|
||||
self.config.zero_knowledge & PlonkPolynomials::CONSTANTS_SIGMAS.blinding,
|
||||
);
|
||||
|
||||
let constants_sigmas_root = constants_sigmas_commitment.merkle_tree.root;
|
||||
|
||||
@ -24,6 +24,7 @@ pub struct CircuitConfig {
|
||||
/// The number of challenge points to generate, for IOPs that have soundness errors of (roughly)
|
||||
/// `degree / |F|`.
|
||||
pub num_challenges: usize,
|
||||
pub zero_knowledge: bool,
|
||||
|
||||
// TODO: Find a better place for this.
|
||||
pub fri_config: FriConfig,
|
||||
@ -37,9 +38,9 @@ impl Default for CircuitConfig {
|
||||
security_bits: 128,
|
||||
rate_bits: 3,
|
||||
num_challenges: 3,
|
||||
zero_knowledge: true,
|
||||
fri_config: FriConfig {
|
||||
proof_of_work_bits: 1,
|
||||
rate_bits: 3,
|
||||
reduction_arity_bits: vec![1, 1, 1, 1],
|
||||
num_query_rounds: 1,
|
||||
},
|
||||
@ -59,9 +60,9 @@ impl CircuitConfig {
|
||||
security_bits: 128,
|
||||
rate_bits: 3,
|
||||
num_challenges: 3,
|
||||
zero_knowledge: true,
|
||||
fri_config: FriConfig {
|
||||
proof_of_work_bits: 1,
|
||||
rate_bits: 3,
|
||||
reduction_arity_bits: vec![1, 1, 1, 1],
|
||||
num_query_rounds: 1,
|
||||
},
|
||||
|
||||
@ -10,8 +10,6 @@ const EPSILON: f64 = 0.01;
|
||||
pub struct FriConfig {
|
||||
pub proof_of_work_bits: u32,
|
||||
|
||||
pub rate_bits: usize,
|
||||
|
||||
/// The arity of each FRI reduction step, expressed (i.e. the log2 of the actual arity).
|
||||
/// For example, `[3, 2, 1]` would describe a FRI reduction tree with 8-to-1 reduction, then
|
||||
/// a 4-to-1 reduction, then a 2-to-1 reduction. After these reductions, the reduced polynomial
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
use crate::circuit_builder::CircuitBuilder;
|
||||
use crate::circuit_data::CircuitConfig;
|
||||
use crate::circuit_data::CommonCircuitData;
|
||||
use crate::field::extension_field::target::{flatten_target, ExtensionTarget};
|
||||
use crate::field::extension_field::Extendable;
|
||||
@ -75,8 +76,8 @@ impl<F: Extendable<D>, const D: usize> CircuitBuilder<F, D> {
|
||||
challenger: &mut RecursiveChallenger,
|
||||
common_data: &CommonCircuitData<F, D>,
|
||||
) {
|
||||
let config = &common_data.config.fri_config;
|
||||
let total_arities = config.reduction_arity_bits.iter().sum::<usize>();
|
||||
let config = &common_data.config;
|
||||
let total_arities = config.fri_config.reduction_arity_bits.iter().sum::<usize>();
|
||||
debug_assert_eq!(
|
||||
purported_degree_log,
|
||||
log2_strict(proof.final_poly.len()) + total_arities - config.rate_bits,
|
||||
@ -98,16 +99,16 @@ impl<F: Extendable<D>, const D: usize> CircuitBuilder<F, D> {
|
||||
challenger.observe_extension_elements(&proof.final_poly.0);
|
||||
|
||||
self.set_context("Check PoW");
|
||||
self.fri_verify_proof_of_work(proof, challenger, config);
|
||||
self.fri_verify_proof_of_work(proof, challenger, &config.fri_config);
|
||||
|
||||
// Check that parameters are coherent.
|
||||
debug_assert_eq!(
|
||||
config.num_query_rounds,
|
||||
config.fri_config.num_query_rounds,
|
||||
proof.query_round_proofs.len(),
|
||||
"Number of query rounds does not match config."
|
||||
);
|
||||
debug_assert!(
|
||||
!config.reduction_arity_bits.is_empty(),
|
||||
!config.fri_config.reduction_arity_bits.is_empty(),
|
||||
"Number of reductions should be non-zero."
|
||||
);
|
||||
|
||||
@ -154,7 +155,7 @@ impl<F: Extendable<D>, const D: usize> CircuitBuilder<F, D> {
|
||||
common_data: &CommonCircuitData<F, D>,
|
||||
) -> ExtensionTarget<D> {
|
||||
assert!(D > 1, "Not implemented for D=1.");
|
||||
let config = &self.config.fri_config.clone();
|
||||
let config = self.config.clone();
|
||||
let degree_log = proof.evals_proofs[0].1.siblings.len() - config.rate_bits;
|
||||
let subgroup_x = self.convert_to_ext(subgroup_x);
|
||||
let mut alpha = ReducingFactorTarget::new(alpha);
|
||||
@ -171,9 +172,9 @@ impl<F: Extendable<D>, const D: usize> CircuitBuilder<F, D> {
|
||||
PlonkPolynomials::QUOTIENT,
|
||||
]
|
||||
.iter()
|
||||
.flat_map(|&p| proof.unsalted_evals(p))
|
||||
.flat_map(|&p| proof.unsalted_evals(p, config.zero_knowledge))
|
||||
.chain(
|
||||
&proof.unsalted_evals(PlonkPolynomials::ZS_PARTIAL_PRODUCTS)
|
||||
&proof.unsalted_evals(PlonkPolynomials::ZS_PARTIAL_PRODUCTS, config.zero_knowledge)
|
||||
[common_data.partial_products_range()],
|
||||
)
|
||||
.map(|&e| self.convert_to_ext(e))
|
||||
@ -197,7 +198,7 @@ impl<F: Extendable<D>, const D: usize> CircuitBuilder<F, D> {
|
||||
|
||||
// Polynomials opened at `x` and `g x`, i.e., the Zs polynomials.
|
||||
let zs_evals = proof
|
||||
.unsalted_evals(PlonkPolynomials::ZS_PARTIAL_PRODUCTS)
|
||||
.unsalted_evals(PlonkPolynomials::ZS_PARTIAL_PRODUCTS, config.zero_knowledge)
|
||||
.iter()
|
||||
.take(common_data.zs_range().end)
|
||||
.map(|&e| self.convert_to_ext(e))
|
||||
@ -222,7 +223,7 @@ impl<F: Extendable<D>, const D: usize> CircuitBuilder<F, D> {
|
||||
|
||||
// Polynomials opened at `x` and `x.frobenius()`, i.e., the wires polynomials.
|
||||
let wire_evals = proof
|
||||
.unsalted_evals(PlonkPolynomials::WIRES)
|
||||
.unsalted_evals(PlonkPolynomials::WIRES, config.zero_knowledge)
|
||||
.iter()
|
||||
.map(|&e| self.convert_to_ext(e))
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
@ -78,8 +78,8 @@ pub fn verify_fri_proof<F: Field + Extendable<D>, const D: usize>(
|
||||
challenger: &mut Challenger<F>,
|
||||
common_data: &CommonCircuitData<F, D>,
|
||||
) -> Result<()> {
|
||||
let config = &common_data.config.fri_config;
|
||||
let total_arities = config.reduction_arity_bits.iter().sum::<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 - config.rate_bits,
|
||||
@ -101,15 +101,15 @@ pub fn verify_fri_proof<F: Field + Extendable<D>, const D: usize>(
|
||||
challenger.observe_extension_elements(&proof.final_poly.coeffs);
|
||||
|
||||
// Check PoW.
|
||||
fri_verify_proof_of_work(proof, challenger, config)?;
|
||||
fri_verify_proof_of_work(proof, challenger, &config.fri_config)?;
|
||||
|
||||
// Check that parameters are coherent.
|
||||
ensure!(
|
||||
config.num_query_rounds == proof.query_round_proofs.len(),
|
||||
config.fri_config.num_query_rounds == proof.query_round_proofs.len(),
|
||||
"Number of query rounds does not match config."
|
||||
);
|
||||
ensure!(
|
||||
!config.reduction_arity_bits.is_empty(),
|
||||
!config.fri_config.reduction_arity_bits.is_empty(),
|
||||
"Number of reductions should be non-zero."
|
||||
);
|
||||
|
||||
@ -151,7 +151,7 @@ fn fri_combine_initial<F: Field + Extendable<D>, const D: usize>(
|
||||
subgroup_x: F,
|
||||
common_data: &CommonCircuitData<F, D>,
|
||||
) -> F::Extension {
|
||||
let config = &common_data.config.fri_config;
|
||||
let config = &common_data.config;
|
||||
assert!(D > 1, "Not implemented for D=1.");
|
||||
let degree_log = proof.evals_proofs[0].1.siblings.len() - config.rate_bits;
|
||||
let subgroup_x = F::Extension::from_basefield(subgroup_x);
|
||||
@ -169,9 +169,9 @@ fn fri_combine_initial<F: Field + Extendable<D>, const D: usize>(
|
||||
PlonkPolynomials::QUOTIENT,
|
||||
]
|
||||
.iter()
|
||||
.flat_map(|&p| proof.unsalted_evals(p))
|
||||
.flat_map(|&p| proof.unsalted_evals(p, config.zero_knowledge))
|
||||
.chain(
|
||||
&proof.unsalted_evals(PlonkPolynomials::ZS_PARTIAL_PRODUCTS)
|
||||
&proof.unsalted_evals(PlonkPolynomials::ZS_PARTIAL_PRODUCTS, config.zero_knowledge)
|
||||
[common_data.partial_products_range()],
|
||||
)
|
||||
.map(|&e| F::Extension::from_basefield(e));
|
||||
@ -193,7 +193,7 @@ fn fri_combine_initial<F: Field + Extendable<D>, const D: usize>(
|
||||
|
||||
// Polynomials opened at `x` and `g x`, i.e., the Zs polynomials.
|
||||
let zs_evals = proof
|
||||
.unsalted_evals(PlonkPolynomials::ZS_PARTIAL_PRODUCTS)
|
||||
.unsalted_evals(PlonkPolynomials::ZS_PARTIAL_PRODUCTS, config.zero_knowledge)
|
||||
.iter()
|
||||
.map(|&e| F::Extension::from_basefield(e))
|
||||
.take(common_data.zs_range().end);
|
||||
@ -213,7 +213,7 @@ fn fri_combine_initial<F: Field + Extendable<D>, const D: usize>(
|
||||
|
||||
// Polynomials opened at `x` and `x.frobenius()`, i.e., the wires polynomials.
|
||||
let wire_evals = proof
|
||||
.unsalted_evals(PlonkPolynomials::WIRES)
|
||||
.unsalted_evals(PlonkPolynomials::WIRES, config.zero_knowledge)
|
||||
.iter()
|
||||
.map(|&e| F::Extension::from_basefield(e));
|
||||
let wire_composition_eval = alpha.clone().reduce(wire_evals);
|
||||
|
||||
@ -15,8 +15,8 @@ pub struct PolynomialsIndexBlinding {
|
||||
pub(crate) blinding: bool,
|
||||
}
|
||||
impl PolynomialsIndexBlinding {
|
||||
pub fn salt_size(&self) -> usize {
|
||||
if self.blinding {
|
||||
pub fn salt_size(&self, zero_knowledge: bool) -> usize {
|
||||
if zero_knowledge & self.blinding {
|
||||
SALT_SIZE
|
||||
} else {
|
||||
0
|
||||
|
||||
@ -18,6 +18,7 @@ use crate::timed;
|
||||
use crate::util::scaling::ReducingFactor;
|
||||
use crate::util::{log2_ceil, 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;
|
||||
|
||||
pub struct ListPolynomialCommitment<F: Field> {
|
||||
@ -121,7 +122,7 @@ impl<F: Field> ListPolynomialCommitment<F> {
|
||||
where
|
||||
F: Extendable<D>,
|
||||
{
|
||||
let config = &common_data.config.fri_config;
|
||||
let config = &common_data.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);
|
||||
@ -208,7 +209,7 @@ impl<F: Field> ListPolynomialCommitment<F> {
|
||||
&lde_final_poly,
|
||||
&lde_final_values,
|
||||
challenger,
|
||||
&config,
|
||||
&config.fri_config,
|
||||
);
|
||||
|
||||
(
|
||||
@ -351,7 +352,6 @@ mod tests {
|
||||
let degree_log = 11;
|
||||
let fri_config = FriConfig {
|
||||
proof_of_work_bits: 2,
|
||||
rate_bits: 2,
|
||||
reduction_arity_bits: vec![2, 3, 1, 2],
|
||||
num_query_rounds: 3,
|
||||
};
|
||||
@ -376,7 +376,7 @@ mod tests {
|
||||
.map(|i| {
|
||||
ListPolynomialCommitment::<F>::new(
|
||||
gen_random_test_case(ks[i], degree_log),
|
||||
common_data.config.fri_config.rate_bits,
|
||||
common_data.config.rate_bits,
|
||||
PlonkPolynomials::polynomials(i).blinding,
|
||||
)
|
||||
})
|
||||
|
||||
16
src/proof.rs
16
src/proof.rs
@ -110,9 +110,13 @@ pub struct FriInitialTreeProof<F: Field> {
|
||||
}
|
||||
|
||||
impl<F: Field> FriInitialTreeProof<F> {
|
||||
pub(crate) fn unsalted_evals(&self, polynomials: PolynomialsIndexBlinding) -> &[F] {
|
||||
pub(crate) fn unsalted_evals(
|
||||
&self,
|
||||
polynomials: PolynomialsIndexBlinding,
|
||||
zero_knowledge: bool,
|
||||
) -> &[F] {
|
||||
let evals = &self.evals_proofs[polynomials.index].0;
|
||||
&evals[..evals.len() - polynomials.salt_size()]
|
||||
&evals[..evals.len() - polynomials.salt_size(zero_knowledge)]
|
||||
}
|
||||
}
|
||||
|
||||
@ -122,9 +126,13 @@ pub struct FriInitialTreeProofTarget {
|
||||
}
|
||||
|
||||
impl FriInitialTreeProofTarget {
|
||||
pub(crate) fn unsalted_evals(&self, polynomials: PolynomialsIndexBlinding) -> &[Target] {
|
||||
pub(crate) fn unsalted_evals(
|
||||
&self,
|
||||
polynomials: PolynomialsIndexBlinding,
|
||||
zero_knowledge: bool,
|
||||
) -> &[Target] {
|
||||
let evals = &self.evals_proofs[polynomials.index].0;
|
||||
&evals[..evals.len() - polynomials.salt_size()]
|
||||
&evals[..evals.len() - polynomials.salt_size(zero_knowledge)]
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -24,7 +24,6 @@ pub(crate) fn prove<F: Extendable<D>, const D: usize>(
|
||||
common_data: &CommonCircuitData<F, D>,
|
||||
inputs: PartialWitness<F>,
|
||||
) -> Result<Proof<F, D>> {
|
||||
let fri_config = &common_data.config.fri_config;
|
||||
let config = &common_data.config;
|
||||
let num_wires = config.num_wires;
|
||||
let num_challenges = config.num_challenges;
|
||||
@ -70,8 +69,8 @@ pub(crate) fn prove<F: Extendable<D>, const D: usize>(
|
||||
let wires_commitment = timed!(
|
||||
ListPolynomialCommitment::new(
|
||||
wires_values,
|
||||
fri_config.rate_bits,
|
||||
PlonkPolynomials::WIRES.blinding
|
||||
config.rate_bits,
|
||||
config.zero_knowledge & PlonkPolynomials::WIRES.blinding
|
||||
),
|
||||
"to compute wires commitment"
|
||||
);
|
||||
@ -106,8 +105,8 @@ pub(crate) fn prove<F: Extendable<D>, const D: usize>(
|
||||
let zs_partial_products_commitment = timed!(
|
||||
ListPolynomialCommitment::new(
|
||||
zs_partial_products,
|
||||
fri_config.rate_bits,
|
||||
PlonkPolynomials::ZS_PARTIAL_PRODUCTS.blinding
|
||||
config.rate_bits,
|
||||
config.zero_knowledge & PlonkPolynomials::ZS_PARTIAL_PRODUCTS.blinding
|
||||
),
|
||||
"to commit to Z's"
|
||||
);
|
||||
@ -149,8 +148,8 @@ pub(crate) fn prove<F: Extendable<D>, const D: usize>(
|
||||
let quotient_polys_commitment = timed!(
|
||||
ListPolynomialCommitment::new_from_polys(
|
||||
all_quotient_poly_chunks,
|
||||
fri_config.rate_bits,
|
||||
PlonkPolynomials::QUOTIENT.blinding
|
||||
config.rate_bits,
|
||||
config.zero_knowledge & PlonkPolynomials::QUOTIENT.blinding
|
||||
),
|
||||
"to commit to quotient polys"
|
||||
);
|
||||
|
||||
@ -326,9 +326,9 @@ mod tests {
|
||||
security_bits: 128,
|
||||
rate_bits: 3,
|
||||
num_challenges: 3,
|
||||
zero_knowledge: false,
|
||||
fri_config: FriConfig {
|
||||
proof_of_work_bits: 1,
|
||||
rate_bits: 3,
|
||||
reduction_arity_bits: vec![2, 2, 2, 2, 2, 2, 2],
|
||||
num_query_rounds: 40,
|
||||
},
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user