plonky2/src/gadgets/interpolation.rs

87 lines
3.0 KiB
Rust
Raw Normal View History

2021-06-07 21:24:41 +02:00
use crate::field::extension_field::target::ExtensionTarget;
use crate::field::extension_field::Extendable;
2021-06-11 16:22:29 +02:00
use crate::gates::interpolation::InterpolationGate;
use crate::iop::target::Target;
use crate::plonk::circuit_builder::CircuitBuilder;
2021-06-07 21:24:41 +02:00
impl<F: Extendable<D>, const D: usize> CircuitBuilder<F, D> {
2021-06-11 16:22:29 +02:00
/// Interpolate a list of point/evaluation pairs at a given point.
/// Returns the evaluation of the interpolated polynomial at `evaluation_point`.
pub fn interpolate(
&mut self,
interpolation_points: &[(Target, ExtensionTarget<D>)],
evaluation_point: ExtensionTarget<D>,
) -> ExtensionTarget<D> {
let gate = InterpolationGate::new(interpolation_points.len());
let gate_index = self.add_gate(gate.clone(), vec![]);
2021-06-11 16:22:29 +02:00
for (i, &(p, v)) in interpolation_points.iter().enumerate() {
2021-08-24 08:25:11 +02:00
self.connect(p, Target::wire(gate_index, gate.wire_point(i)));
self.connect_extension(
2021-06-11 16:22:29 +02:00
v,
ExtensionTarget::from_range(gate_index, gate.wires_value(i)),
);
}
2021-08-24 08:25:11 +02:00
self.connect_extension(
2021-06-11 16:22:29 +02:00
evaluation_point,
ExtensionTarget::from_range(gate_index, gate.wires_evaluation_point()),
);
ExtensionTarget::from_range(gate_index, gate.wires_evaluation_value())
}
}
#[cfg(test)]
mod tests {
use anyhow::Result;
2021-06-11 16:22:29 +02:00
use crate::field::crandall_field::CrandallField;
use crate::field::extension_field::quartic::QuarticCrandallField;
use crate::field::extension_field::FieldExtension;
use crate::field::field_types::Field;
2021-07-15 10:39:57 +02:00
use crate::field::interpolation::interpolant;
use crate::iop::witness::PartialWitness;
use crate::plonk::circuit_builder::CircuitBuilder;
use crate::plonk::circuit_data::CircuitConfig;
use crate::plonk::verifier::verify;
2021-06-11 16:22:29 +02:00
#[test]
fn test_interpolate() -> Result<()> {
2021-06-11 16:22:29 +02:00
type F = CrandallField;
type FF = QuarticCrandallField;
let config = CircuitConfig::large_config();
2021-08-20 11:56:57 +02:00
let pw = PartialWitness::new();
2021-06-11 16:22:29 +02:00
let mut builder = CircuitBuilder::<F, 4>::new(config);
let len = 4;
2021-06-11 16:22:29 +02:00
let points = (0..len)
.map(|_| (F::rand(), FF::rand()))
.collect::<Vec<_>>();
let homogeneous_points = points
.iter()
.map(|&(a, b)| (<FF as FieldExtension<4>>::from_basefield(a), b))
.collect::<Vec<_>>();
let true_interpolant = interpolant(&homogeneous_points);
let z = FF::rand();
let true_eval = true_interpolant.eval(z);
let points_target = points
.iter()
.map(|&(p, v)| (builder.constant(p), builder.constant_extension(v)))
.collect::<Vec<_>>();
let zt = builder.constant_extension(z);
let eval = builder.interpolate(&points_target, zt);
let true_eval_target = builder.constant_extension(true_eval);
2021-08-24 08:30:34 +02:00
builder.connect_extension(eval, true_eval_target);
2021-06-11 16:22:29 +02:00
let data = builder.build();
2021-08-06 15:14:38 +02:00
let proof = data.prove(pw)?;
2021-07-08 15:13:29 +02:00
verify(proof, &data.verifier_only, &data.common)
2021-06-07 21:24:41 +02:00
}
}