mirror of
https://github.com/logos-storage/plonky2.git
synced 2026-01-09 09:13:09 +00:00
Check copy constraints in PartialWitness
This commit is contained in:
parent
c3d53392c4
commit
dcdbb6be33
176
src/prover.rs
176
src/prover.rs
@ -45,6 +45,13 @@ pub(crate) fn prove<F: Extendable<D>, const D: usize>(
|
||||
"to generate witness"
|
||||
);
|
||||
|
||||
timed!(
|
||||
partial_witness
|
||||
.check_copy_constraints(&prover_data.copy_constraints, &prover_data.gate_instances)
|
||||
.unwrap(), // TODO: Change return value to `Result` and use `?` here.
|
||||
"to check copy constraints"
|
||||
);
|
||||
|
||||
let witness = timed!(
|
||||
partial_witness.full_witness(degree, num_wires),
|
||||
"to compute full witness"
|
||||
@ -53,12 +60,6 @@ pub(crate) fn prove<F: Extendable<D>, const D: usize>(
|
||||
for m in marked {
|
||||
m.display(&witness);
|
||||
}
|
||||
timed!(
|
||||
witness
|
||||
.check_copy_constraints(&prover_data.copy_constraints, &prover_data.gate_instances)
|
||||
.unwrap(), // TODO: Change return value to `Result` and use `?` here.
|
||||
"to check copy constraints"
|
||||
);
|
||||
|
||||
let wires_values: Vec<PolynomialValues<F>> = timed!(
|
||||
witness
|
||||
@ -120,169 +121,6 @@ pub(crate) fn prove<F: Extendable<D>, const D: usize>(
|
||||
|
||||
let alphas = challenger.get_n_challenges(num_challenges);
|
||||
|
||||
{
|
||||
let get_at_index = |comm: &ListPolynomialCommitment<F>, i: usize| -> Vec<F> {
|
||||
comm.original_values
|
||||
.iter()
|
||||
.map(|v| v.values[i])
|
||||
.collect::<Vec<_>>()
|
||||
};
|
||||
let mut nums = HashMap::<F, usize>::new();
|
||||
let mut dens = HashMap::<F, usize>::new();
|
||||
let points = F::two_adic_subgroup(common_data.degree_bits);
|
||||
for i in 0..degree {
|
||||
let x = points[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 vars = EvaluationVarsBase {
|
||||
local_constants,
|
||||
local_wires: &local_wires,
|
||||
};
|
||||
let numerator_values = (0..common_data.config.num_routed_wires).for_each(|j| {
|
||||
let wire_value = vars.local_wires[j];
|
||||
let k_i = common_data.k_is[j];
|
||||
let s_id = k_i * x;
|
||||
*nums
|
||||
.entry(wire_value + betas[0] * s_id + gammas[0])
|
||||
.or_default() += 1;
|
||||
});
|
||||
let denominator_values = (0..common_data.config.num_routed_wires).for_each(|j| {
|
||||
let wire_value = vars.local_wires[j];
|
||||
let s_sigma = s_sigmas[j];
|
||||
*dens
|
||||
.entry(wire_value + betas[0] * s_sigma + gammas[0])
|
||||
.or_default() += 1;
|
||||
});
|
||||
}
|
||||
println!("yo");
|
||||
for (k, v) in nums.iter() {
|
||||
if let Some(w) = dens.get(&k) {
|
||||
if *v != *w {
|
||||
println!("Bad: {} {} {}", *k, *v, *w);
|
||||
}
|
||||
} else {
|
||||
println!("Bad: {} {}", *k, *v);
|
||||
}
|
||||
}
|
||||
println!("ya");
|
||||
for (k, v) in dens.iter() {
|
||||
if let Some(w) = nums.get(&k) {
|
||||
if *v != *w {
|
||||
println!("Bad: {} {} {}", *k, *v, *w);
|
||||
}
|
||||
} else {
|
||||
println!("Bad: {} {}", *k, *v);
|
||||
}
|
||||
}
|
||||
println!("yu");
|
||||
|
||||
let mut bam = F::ONE;
|
||||
for (k, v) in nums.iter() {
|
||||
bam *= k.exp(*v as u64);
|
||||
}
|
||||
dbg!(bam);
|
||||
let mut boom = F::ONE;
|
||||
for (k, v) in dens.iter() {
|
||||
boom *= k.exp(*v as u64);
|
||||
}
|
||||
dbg!(boom);
|
||||
}
|
||||
{
|
||||
let get_at_index = |comm: &ListPolynomialCommitment<F>, i: usize| -> Vec<F> {
|
||||
comm.original_values
|
||||
.iter()
|
||||
.map(|v| v.values[i])
|
||||
.collect::<Vec<_>>()
|
||||
};
|
||||
let mut nums = vec![F::ONE; common_data.config.num_challenges];
|
||||
let mut dens = vec![F::ONE; common_data.config.num_challenges];
|
||||
let points = F::two_adic_subgroup(common_data.degree_bits);
|
||||
for i in 0..degree {
|
||||
let x = points[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 vars = EvaluationVarsBase {
|
||||
local_constants,
|
||||
local_wires: &local_wires,
|
||||
};
|
||||
for ii in 0..common_data.config.num_challenges {
|
||||
let numerator_values = (0..common_data.config.num_routed_wires)
|
||||
.map(|j| {
|
||||
let wire_value = vars.local_wires[j];
|
||||
let k_i = common_data.k_is[j];
|
||||
let s_id = k_i * x;
|
||||
wire_value + betas[ii] * s_id + gammas[ii]
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
let denominator_values = (0..common_data.config.num_routed_wires)
|
||||
.map(|j| {
|
||||
let wire_value = vars.local_wires[j];
|
||||
let s_sigma = s_sigmas[j];
|
||||
wire_value + betas[ii] * s_sigma + gammas[ii]
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
nums[ii] *= numerator_values.into_iter().product();
|
||||
dens[ii] *= denominator_values.into_iter().product();
|
||||
}
|
||||
}
|
||||
dbg!(nums, dens);
|
||||
}
|
||||
{
|
||||
let get_at_index = |comm: &ListPolynomialCommitment<F>, i: usize| -> Vec<F> {
|
||||
comm.original_values
|
||||
.iter()
|
||||
.map(|v| v.values[i])
|
||||
.collect::<Vec<_>>()
|
||||
};
|
||||
let points = F::two_adic_subgroup(common_data.degree_bits);
|
||||
for i in 0..degree {
|
||||
let x = points[i];
|
||||
let i_next = (i + 1) % degree;
|
||||
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_zs_partial_products = get_at_index(&zs_partial_products_commitment, i);
|
||||
let local_zs = &local_zs_partial_products[common_data.zs_range()];
|
||||
let next_zs =
|
||||
&get_at_index(&zs_partial_products_commitment, i_next)[common_data.zs_range()];
|
||||
let partial_products = &local_zs_partial_products[common_data.partial_products_range()];
|
||||
|
||||
debug_assert_eq!(local_wires.len(), common_data.config.num_wires);
|
||||
debug_assert_eq!(local_zs.len(), num_challenges);
|
||||
|
||||
let vars = EvaluationVarsBase {
|
||||
local_constants,
|
||||
local_wires: &local_wires,
|
||||
};
|
||||
let mut quotient_values = yoba(
|
||||
common_data,
|
||||
i,
|
||||
x,
|
||||
vars,
|
||||
local_zs,
|
||||
next_zs,
|
||||
partial_products,
|
||||
s_sigmas,
|
||||
&betas,
|
||||
&gammas,
|
||||
&alphas,
|
||||
);
|
||||
assert!(
|
||||
quotient_values.iter().all(|yy| yy.is_zero()),
|
||||
"{}-th gate ({}) constraints not satisfied.\n {:?}",
|
||||
i,
|
||||
prover_data.gate_instances[i].gate_type.0.id(),
|
||||
quotient_values
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
let quotient_polys = timed!(
|
||||
compute_quotient_polys(
|
||||
common_data,
|
||||
|
||||
@ -20,41 +20,6 @@ impl<F: Field> Witness<F> {
|
||||
pub fn get_wire(&self, gate: usize, input: usize) -> F {
|
||||
self.wire_values[input][gate]
|
||||
}
|
||||
|
||||
/// Checks that the copy constraints are satisfied in the witness.
|
||||
pub fn check_copy_constraints<const D: usize>(
|
||||
&self,
|
||||
copy_constraints: &[(Target, Target)],
|
||||
gate_instances: &[GateInstance<F, D>],
|
||||
) -> Result<()>
|
||||
where
|
||||
F: Extendable<D>,
|
||||
{
|
||||
for &(a, b) in copy_constraints {
|
||||
// TODO: Take care of public inputs once they land, and virtual targets.
|
||||
if let (
|
||||
Target::Wire(Wire {
|
||||
gate: a_gate,
|
||||
input: a_input,
|
||||
}),
|
||||
Target::Wire(Wire {
|
||||
gate: b_gate,
|
||||
input: b_input,
|
||||
}),
|
||||
) = (a, b)
|
||||
{
|
||||
let va = self.get_wire(a_gate, a_input);
|
||||
let vb = self.get_wire(b_gate, b_input);
|
||||
ensure!(
|
||||
va == vb,
|
||||
"Copy constraint between wire {} of gate #{} (`{}`) and wire {} of gate #{} (`{}`) is not satisfied. \
|
||||
Got values of {} and {} respectively.",
|
||||
a_input, a_gate, gate_instances[a_gate].gate_type.0.id(), b_input, b_gate,
|
||||
gate_instances[b_gate].gate_type.0.id(), va, vb);
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
@ -200,6 +165,44 @@ impl<F: Field> PartialWitness<F> {
|
||||
});
|
||||
Witness { wire_values }
|
||||
}
|
||||
|
||||
/// Checks that the copy constraints are satisfied in the witness.
|
||||
pub fn check_copy_constraints<const D: usize>(
|
||||
&self,
|
||||
copy_constraints: &[(Target, Target)],
|
||||
gate_instances: &[GateInstance<F, D>],
|
||||
) -> Result<()>
|
||||
where
|
||||
F: Extendable<D>,
|
||||
{
|
||||
for &(a, b) in copy_constraints {
|
||||
// TODO: Take care of public inputs once they land.
|
||||
let va = self.try_get_target(a).unwrap_or(F::ZERO);
|
||||
let vb = self.try_get_target(b).unwrap_or(F::ZERO);
|
||||
let desc = |t: Target| -> String {
|
||||
match t {
|
||||
Target::Wire(Wire { gate, input }) => format!(
|
||||
"wire {} of gate #{} (`{}`)",
|
||||
input,
|
||||
gate,
|
||||
gate_instances[gate].gate_type.0.id()
|
||||
),
|
||||
Target::PublicInput { index } => format!("{}-th public input", index),
|
||||
Target::VirtualTarget { index } => format!("{}-th virtual target", index),
|
||||
}
|
||||
};
|
||||
ensure!(
|
||||
va == vb,
|
||||
"Copy constraint between {} and {} is not satisfied. \
|
||||
Got values of {} and {} respectively.",
|
||||
desc(a),
|
||||
desc(b),
|
||||
va,
|
||||
vb
|
||||
);
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl<F: Field> Default for PartialWitness<F> {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user