mirror of
https://github.com/logos-storage/plonky2.git
synced 2026-01-06 07:43:10 +00:00
Merge pull request #80 from mir-protocol/blinding_factors
Blinding factors
This commit is contained in:
commit
46ff079674
@ -14,14 +14,14 @@ use crate::gates::constant::ConstantGate;
|
||||
use crate::gates::gate::{GateInstance, GateRef, PrefixedGate};
|
||||
use crate::gates::gate_tree::Tree;
|
||||
use crate::gates::noop::NoopGate;
|
||||
use crate::generator::{CopyGenerator, WitnessGenerator};
|
||||
use crate::generator::{CopyGenerator, RandomValueGenerator, 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;
|
||||
use crate::util::{log2_strict, transpose, transpose_poly_values};
|
||||
use crate::util::{log2_ceil, log2_strict, transpose, transpose_poly_values};
|
||||
use crate::wire::Wire;
|
||||
|
||||
pub struct CircuitBuilder<F: Extendable<D>, const D: usize> {
|
||||
@ -223,8 +223,96 @@ impl<F: Extendable<D>, const D: usize> CircuitBuilder<F, D> {
|
||||
self.targets_to_constants.get(&target).cloned()
|
||||
}
|
||||
|
||||
/// The number of polynomial values that will be revealed per opening, both for the "regular"
|
||||
/// polynomials and for the Z polynomials. Because calculating these values involves a recursive
|
||||
/// dependence (the amount of blinding depends on the degree, which depends on the blinding),
|
||||
/// this function takes in an estimate of the degree.
|
||||
fn num_blinding_gates(&self, degree_estimate: usize) -> (usize, usize) {
|
||||
let fri_queries = self.config.fri_config.num_query_rounds;
|
||||
let arities: Vec<usize> = self
|
||||
.config
|
||||
.fri_config
|
||||
.reduction_arity_bits
|
||||
.iter()
|
||||
.map(|x| 1 << x)
|
||||
.collect();
|
||||
let total_fri_folding_points: usize = arities.iter().map(|x| x - 1).sum::<usize>();
|
||||
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);
|
||||
|
||||
let regular_poly_openings = D + fri_openings;
|
||||
let z_openings = 2 * D + fri_openings;
|
||||
|
||||
(regular_poly_openings, z_openings)
|
||||
}
|
||||
|
||||
/// The number of polynomial values that will be revealed per opening, both for the "regular"
|
||||
/// polynomials (which are opened at only one location) and for the Z polynomials (which are
|
||||
/// opened at two).
|
||||
fn blinding_counts(&self) -> (usize, usize) {
|
||||
let num_gates = self.gates.len();
|
||||
let mut degree_estimate = 1 << log2_ceil(num_gates);
|
||||
|
||||
loop {
|
||||
let (regular_poly_openings, z_openings) = self.num_blinding_gates(degree_estimate);
|
||||
|
||||
// For most polynomials, we add one random element to offset each opened value.
|
||||
// But blinding Z is separate. For that, we add two random elements with a copy
|
||||
// constraint between them.
|
||||
let total_blinding_count = regular_poly_openings + 2 * z_openings;
|
||||
|
||||
if num_gates + total_blinding_count <= degree_estimate {
|
||||
return (regular_poly_openings, z_openings);
|
||||
}
|
||||
|
||||
// The blinding gates do not fit within our estimated degree; increase our estimate.
|
||||
degree_estimate *= 2;
|
||||
}
|
||||
}
|
||||
|
||||
fn blind_and_pad(&mut self) {
|
||||
// TODO: Blind.
|
||||
let (regular_poly_openings, z_openings) = self.blinding_counts();
|
||||
|
||||
let num_routed_wires = self.config.num_routed_wires;
|
||||
let num_wires = self.config.num_wires;
|
||||
|
||||
// For each "regular" blinding factor, we simply add a no-op gate, and insert a random value
|
||||
// for each wire.
|
||||
for _ in 0..regular_poly_openings {
|
||||
let gate = self.add_gate_no_constants(NoopGate::get());
|
||||
for w in 0..num_wires {
|
||||
self.add_generator(RandomValueGenerator {
|
||||
target: Target::Wire(Wire { gate, input: w }),
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// For each z poly blinding factor, we add two new gates with the same random value, and
|
||||
// enforce a copy constraint between them.
|
||||
// See https://mirprotocol.org/blog/Adding-zero-knowledge-to-Plonk-Halo
|
||||
for _ in 0..z_openings {
|
||||
let gate_1 = self.add_gate_no_constants(NoopGate::get());
|
||||
let gate_2 = self.add_gate_no_constants(NoopGate::get());
|
||||
|
||||
for w in 0..num_routed_wires {
|
||||
self.add_generator(RandomValueGenerator {
|
||||
target: Target::Wire(Wire {
|
||||
gate: gate_1,
|
||||
input: w,
|
||||
}),
|
||||
});
|
||||
self.add_generator(CopyGenerator {
|
||||
src: Target::Wire(Wire {
|
||||
gate: gate_1,
|
||||
input: w,
|
||||
}),
|
||||
dst: Target::Wire(Wire {
|
||||
gate: gate_2,
|
||||
input: w,
|
||||
}),
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
while !self.gate_instances.len().is_power_of_two() {
|
||||
self.add_gate_no_constants(NoopGate::get());
|
||||
|
||||
@ -113,3 +113,20 @@ impl<F: Field> SimpleGenerator<F> for CopyGenerator {
|
||||
PartialWitness::singleton_target(self.dst, value)
|
||||
}
|
||||
}
|
||||
|
||||
/// A generator for including a random value
|
||||
pub(crate) struct RandomValueGenerator {
|
||||
pub(crate) target: Target,
|
||||
}
|
||||
|
||||
impl<F: Field> SimpleGenerator<F> for RandomValueGenerator {
|
||||
fn dependencies(&self) -> Vec<Target> {
|
||||
Vec::new()
|
||||
}
|
||||
|
||||
fn run_once(&self, _witness: &PartialWitness<F>) -> PartialWitness<F> {
|
||||
let random_value = F::rand();
|
||||
|
||||
PartialWitness::singleton_target(self.target, random_value)
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user