This commit is contained in:
wborgeaud 2021-08-13 20:12:20 +02:00
parent 237ef4d0ec
commit ceae6b9588
6 changed files with 94 additions and 210 deletions

View File

@ -15,51 +15,6 @@ use crate::plonk::circuit_builder::CircuitBuilder;
use crate::util::bits_u64;
impl<F: Extendable<D>, const D: usize> CircuitBuilder<F, D> {
pub fn yo(
&mut self,
gate: usize,
first_multiplicand_0: ExtensionTarget<D>,
first_multiplicand_1: ExtensionTarget<D>,
first_addend: ExtensionTarget<D>,
second_multiplicand_0: ExtensionTarget<D>,
second_multiplicand_1: ExtensionTarget<D>,
second_addend: ExtensionTarget<D>,
) -> (ExtensionTarget<D>, ExtensionTarget<D>) {
let wire_third_multiplicand_0 = ExtensionTarget::from_range(
gate,
ArithmeticExtensionGate::<D>::wires_third_multiplicand_0(),
);
let wire_third_multiplicand_1 = ExtensionTarget::from_range(
gate,
ArithmeticExtensionGate::<D>::wires_third_multiplicand_1(),
);
let wire_third_addend =
ExtensionTarget::from_range(gate, ArithmeticExtensionGate::<D>::wires_third_addend());
let wire_fourth_multiplicand_0 = ExtensionTarget::from_range(
gate,
ArithmeticExtensionGate::<D>::wires_fourth_multiplicand_0(),
);
let wire_fourth_multiplicand_1 = ExtensionTarget::from_range(
gate,
ArithmeticExtensionGate::<D>::wires_fourth_multiplicand_1(),
);
let wire_fourth_addend =
ExtensionTarget::from_range(gate, ArithmeticExtensionGate::<D>::wires_fourth_addend());
let wire_third_output =
ExtensionTarget::from_range(gate, ArithmeticExtensionGate::<D>::wires_third_output());
let wire_fourth_output =
ExtensionTarget::from_range(gate, ArithmeticExtensionGate::<D>::wires_fourth_output());
self.route_extension(first_multiplicand_0, wire_third_multiplicand_0);
self.route_extension(first_multiplicand_1, wire_third_multiplicand_1);
self.route_extension(first_addend, wire_third_addend);
self.route_extension(second_multiplicand_0, wire_fourth_multiplicand_0);
self.route_extension(second_multiplicand_1, wire_fourth_multiplicand_1);
self.route_extension(second_addend, wire_fourth_addend);
self.free_arithmetic = None;
(wire_third_output, wire_fourth_output)
}
pub fn double_arithmetic_extension(
&mut self,
const_0: F,
@ -73,7 +28,7 @@ impl<F: Extendable<D>, const D: usize> CircuitBuilder<F, D> {
) -> (ExtensionTarget<D>, ExtensionTarget<D>) {
if let Some((g, c_0, c_1)) = self.free_arithmetic {
if c_0 == const_0 && c_1 == const_1 {
return self.yo(
return self.arithmetic_reusing_gate(
g,
first_multiplicand_0,
first_multiplicand_1,
@ -121,6 +76,52 @@ impl<F: Extendable<D>, const D: usize> CircuitBuilder<F, D> {
(wire_first_output, wire_second_output)
}
fn arithmetic_reusing_gate(
&mut self,
gate: usize,
first_multiplicand_0: ExtensionTarget<D>,
first_multiplicand_1: ExtensionTarget<D>,
first_addend: ExtensionTarget<D>,
second_multiplicand_0: ExtensionTarget<D>,
second_multiplicand_1: ExtensionTarget<D>,
second_addend: ExtensionTarget<D>,
) -> (ExtensionTarget<D>, ExtensionTarget<D>) {
let wire_third_multiplicand_0 = ExtensionTarget::from_range(
gate,
ArithmeticExtensionGate::<D>::wires_third_multiplicand_0(),
);
let wire_third_multiplicand_1 = ExtensionTarget::from_range(
gate,
ArithmeticExtensionGate::<D>::wires_third_multiplicand_1(),
);
let wire_third_addend =
ExtensionTarget::from_range(gate, ArithmeticExtensionGate::<D>::wires_third_addend());
let wire_fourth_multiplicand_0 = ExtensionTarget::from_range(
gate,
ArithmeticExtensionGate::<D>::wires_fourth_multiplicand_0(),
);
let wire_fourth_multiplicand_1 = ExtensionTarget::from_range(
gate,
ArithmeticExtensionGate::<D>::wires_fourth_multiplicand_1(),
);
let wire_fourth_addend =
ExtensionTarget::from_range(gate, ArithmeticExtensionGate::<D>::wires_fourth_addend());
let wire_third_output =
ExtensionTarget::from_range(gate, ArithmeticExtensionGate::<D>::wires_third_output());
let wire_fourth_output =
ExtensionTarget::from_range(gate, ArithmeticExtensionGate::<D>::wires_fourth_output());
self.route_extension(first_multiplicand_0, wire_third_multiplicand_0);
self.route_extension(first_multiplicand_1, wire_third_multiplicand_1);
self.route_extension(first_addend, wire_third_addend);
self.route_extension(second_multiplicand_0, wire_fourth_multiplicand_0);
self.route_extension(second_multiplicand_1, wire_fourth_multiplicand_1);
self.route_extension(second_addend, wire_fourth_addend);
self.free_arithmetic = None;
(wire_third_output, wire_fourth_output)
}
pub fn arithmetic_extension(
&mut self,
const_0: F,
@ -761,31 +762,6 @@ mod tests {
use crate::plonk::circuit_data::CircuitConfig;
use crate::plonk::verifier::verify;
#[test]
fn test_gaga() -> Result<()> {
type F = CrandallField;
type FF = QuarticCrandallField;
const D: usize = 4;
let config = CircuitConfig {
num_routed_wires: 64,
..CircuitConfig::large_config()
};
let mut pw = PartialWitness::new(config.num_wires);
let mut builder = CircuitBuilder::<F, D>::new(config);
let n = 6;
let vs = FF::rand_vec(n);
let ts = builder.add_virtual_extension_targets(n);
pw.set_extension_targets(&ts, &vs);
let mul0 = builder.mul_many_extension(&ts);
let data = builder.build();
let proof = data.prove(pw)?;
verify(proof, &data.verifier_only, &data.common)
}
#[test]
fn test_mul_many() -> Result<()> {
type F = CrandallField;
@ -823,34 +799,6 @@ mod tests {
verify(proof, &data.verifier_only, &data.common)
}
#[test]
fn test_mul() -> Result<()> {
type F = CrandallField;
type FF = QuarticCrandallField;
const D: usize = 4;
let config = CircuitConfig::large_config();
let pw = PartialWitness::new(config.num_wires);
let mut builder = CircuitBuilder::<F, D>::new(config);
let x = FF::ONE;
let y = FF::TWO;
let z = x * y;
let xt = builder.constant_extension(x);
let yt = builder.constant_extension(y);
let zt = builder.constant_extension(z);
let comp_zt = builder.mul_extension(xt, yt);
builder.add_marked(zt.into(), "yo");
builder.add_marked(comp_zt.into(), "ya");
builder.assert_equal_extension(zt, comp_zt);
let data = builder.build();
let proof = data.prove(pw)?;
verify(proof, &data.verifier_only, &data.common)
}
#[test]
fn test_div_extension() -> Result<()> {
type F = CrandallField;

View File

@ -12,10 +12,9 @@ impl<F: Extendable<D>, const D: usize> CircuitBuilder<F, D> {
interpolation_points: [(ExtensionTarget<D>, ExtensionTarget<D>); 2],
evaluation_point: ExtensionTarget<D>,
) -> ExtensionTarget<D> {
// a0 -> a1 : zeta -> precomp0
// b0 -> b1 : g*zeta -> precomp1
// a0 -> a1
// b0 -> b1
// x -> a1 + (x-a0)*(b1-a1)/(b0-a0)
// x -> precomp0 + (x-zeta)*(precomp1-precomp0)/(g*zeta - zeta)
let (x_m_a0, b1_m_a1) = self.sub_two_extension(
evaluation_point,

View File

@ -39,7 +39,7 @@ pub struct CircuitBuilder<F: Extendable<D>, const D: usize> {
gates: HashSet<GateRef<F, D>>,
/// The concrete placement of each gate.
pub gate_instances: Vec<GateInstance<F, D>>,
gate_instances: Vec<GateInstance<F, D>>,
/// Targets to be made public.
public_inputs: Vec<Target>,

View File

@ -68,26 +68,6 @@ pub(crate) fn prove<F: Extendable<D>, const D: usize>(
partial_witness.full_witness(degree, num_wires)
);
// {
// let mut count = 0;
// let mut count_bad = 0;
// for i in 0..degree {
// if prover_data.gate_instances[i].gate_ref.0.id()
// != "ArithmeticExtensionGate".to_string()
// {
// continue;
// }
// count += 1;
// let row = witness.wire_values.iter().map(|c| c[i]).collect::<Vec<_>>();
// // println!("{} {:?}", i, &row);
// if row[16..].iter().all(|x| x.is_zero()) {
// println!("{} {:?}", i, row);
// count_bad += 1;
// }
// }
// println!("{} {}", count, count_bad);
// }
let wires_values: Vec<PolynomialValues<F>> = timed!(
timing,
"compute wire polynomials",

View File

@ -435,7 +435,7 @@ mod tests {
fri_config: FriConfig {
proof_of_work_bits: 1,
reduction_arity_bits: vec![3, 3, 3],
num_query_rounds: 33,
num_query_rounds: 32,
cap_height: 3,
},
};

View File

@ -165,89 +165,54 @@ impl<const D: usize> ReducingFactorTarget<D> {
where
F: Extendable<D>,
{
let max_coeffs_len = ReducingExtGate::<D>::max_coeffs_len(
builder.config.num_wires,
builder.config.num_routed_wires,
);
self.count += terms.len() as u64;
let zero_ext = builder.zero_extension();
let mut acc = zero_ext;
let mut reversed_terms = terms.to_vec();
while reversed_terms.len() % max_coeffs_len != 0 {
reversed_terms.push(zero_ext);
let zero = builder.zero_extension();
let l = terms.len();
self.count += l as u64;
let mut terms_vec = terms.to_vec();
// If needed, we pad the original vector so that it has even length.
if terms_vec.len().is_odd() {
terms_vec.push(zero);
}
reversed_terms.reverse();
for chunk in reversed_terms.chunks_exact(max_coeffs_len) {
let gate = ReducingExtGate::new(max_coeffs_len);
let gate_index = builder.add_gate(gate.clone(), Vec::new());
terms_vec.reverse();
builder.route_extension(
self.base,
ExtensionTarget::from_range(gate_index, ReducingGate::<D>::wires_alpha()),
);
builder.route_extension(
acc,
ExtensionTarget::from_range(gate_index, ReducingGate::<D>::wires_old_acc()),
);
for (i, &t) in chunk.iter().enumerate() {
builder.route_extension(
t,
ExtensionTarget::from_range(gate_index, ReducingExtGate::<D>::wires_coeff(i)),
);
}
let mut acc = zero;
for pair in terms_vec.chunks(2) {
// We will route the output of the first arithmetic operation to the multiplicand of the
// second, i.e. we compute the following:
// out_0 = alpha acc + pair[0]
// acc' = out_1 = alpha out_0 + pair[1]
acc = ExtensionTarget::from_range(gate_index, ReducingGate::<D>::wires_output());
let (gate, range) = if let Some((g, c_0, c_1)) = builder.free_arithmetic {
if c_0 == F::ONE && c_1 == F::ONE {
(g, ArithmeticExtensionGate::<D>::wires_third_output())
} else {
(
builder.num_gates(),
ArithmeticExtensionGate::<D>::wires_first_output(),
)
}
} else {
(
builder.num_gates(),
ArithmeticExtensionGate::<D>::wires_first_output(),
)
};
let out_0 = ExtensionTarget::from_range(gate, range);
acc = builder
.double_arithmetic_extension(
F::ONE,
F::ONE,
self.base,
acc,
pair[0],
self.base,
out_0,
pair[1],
)
.1;
}
acc
// let zero = builder.zero_extension();
// let l = terms.len();
// self.count += l as u64;
//
// let mut terms_vec = terms.to_vec();
// // If needed, we pad the original vector so that it has even length.
// if terms_vec.len().is_odd() {
// terms_vec.push(zero);
// }
// terms_vec.reverse();
//
// let mut acc = zero;
// for pair in terms_vec.chunks(2) {
// // We will route the output of the first arithmetic operation to the multiplicand of the
// // second, i.e. we compute the following:
// // out_0 = alpha acc + pair[0]
// // acc' = out_1 = alpha out_0 + pair[1]
//
// let (gate, range) = if let Some((g, c_0, c_1)) = builder.free_arithmetic {
// if c_0 == F::ONE && c_1 == F::ONE {
// (g, ArithmeticExtensionGate::<D>::wires_third_output())
// } else {
// (
// builder.num_gates(),
// ArithmeticExtensionGate::<D>::wires_first_output(),
// )
// }
// } else {
// (
// builder.num_gates(),
// ArithmeticExtensionGate::<D>::wires_first_output(),
// )
// };
// let out_0 = ExtensionTarget::from_range(gate, range);
// acc = builder
// .double_arithmetic_extension(
// F::ONE,
// F::ONE,
// self.base,
// acc,
// pair[0],
// self.base,
// out_0,
// pair[1],
// )
// .1;
// }
// acc
}
pub fn shift<F>(
@ -360,9 +325,6 @@ mod tests {
builder.assert_equal_extension(manual_reduce, circuit_reduce);
for g in &builder.gate_instances {
println!("{}", g.gate_ref.0.id());
}
let data = builder.build();
let proof = data.prove(pw)?;
@ -374,11 +336,6 @@ mod tests {
test_reduce_gadget(10)
}
#[test]
fn test_yo() -> Result<()> {
test_reduce_gadget(100)
}
#[test]
fn test_reduce_gadget_odd() -> Result<()> {
test_reduce_gadget(11)