plonky2/src/iop/generator.rs

281 lines
8.6 KiB
Rust
Raw Normal View History

2021-03-25 15:20:14 -07:00
use std::fmt::Debug;
2021-09-02 15:03:03 -07:00
use std::marker::PhantomData;
2021-03-01 13:40:05 -08:00
use crate::field::extension_field::target::ExtensionTarget;
use crate::field::extension_field::{Extendable, FieldExtension};
use crate::field::field_types::{Field, RichField};
2021-08-20 11:13:40 +02:00
use crate::hash::hash_types::{HashOut, HashOutTarget};
use crate::iop::target::Target;
use crate::iop::wire::Wire;
use crate::iop::witness::{PartialWitness, PartitionWitness, Witness};
use crate::plonk::circuit_data::ProverOnlyCircuitData;
2021-02-09 21:25:21 -08:00
2021-08-20 11:03:55 +02:00
/// Given a `PartitionWitness` that has only inputs set, populates the rest of the witness using the
2021-03-21 11:17:00 -07:00
/// given set of generators.
pub(crate) fn generate_partial_witness<F: RichField + Extendable<D>, const D: usize>(
inputs: PartialWitness<F>,
prover_data: &ProverOnlyCircuitData<F, D>,
) -> PartitionWitness<F> {
let generators = &prover_data.generators;
let generator_indices_by_watches = &prover_data.generator_indices_by_watches;
let mut witness = prover_data.partition_witness.clone();
for (t, v) in inputs.target_values.into_iter() {
witness.set_target(t, v);
}
2021-03-01 13:40:05 -08:00
// Build a list of "pending" generators which are queued to be run. Initially, all generators
// are queued.
let mut pending_generator_indices: Vec<_> = (0..generators.len()).collect();
2021-03-01 13:40:05 -08:00
// We also track a list of "expired" generators which have already returned false.
let mut generator_is_expired = vec![false; generators.len()];
2021-08-20 11:03:55 +02:00
let mut remaining_generators = generators.len();
2021-03-01 13:40:05 -08:00
let mut buffer = GeneratedValues::empty();
// Keep running generators until we fail to make progress.
while !pending_generator_indices.is_empty() {
let mut next_pending_generator_indices = Vec::new();
2021-03-01 13:40:05 -08:00
for &generator_idx in &pending_generator_indices {
if generator_is_expired[generator_idx] {
continue;
}
let finished = generators[generator_idx].run(&witness, &mut buffer);
2021-03-01 13:40:05 -08:00
if finished {
generator_is_expired[generator_idx] = true;
2021-08-20 11:03:55 +02:00
remaining_generators -= 1;
2021-03-01 13:40:05 -08:00
}
// Enqueue unfinished generators that were watching one of the newly populated targets.
for &(watch, _) in &buffer.target_values {
let opt_watchers = generator_indices_by_watches.get(&witness.target_index(watch));
if let Some(watchers) = opt_watchers {
for &watching_generator_idx in watchers {
if !generator_is_expired[watching_generator_idx] {
next_pending_generator_indices.push(watching_generator_idx);
}
2021-08-19 15:59:05 +02:00
}
2021-03-01 13:40:05 -08:00
}
}
witness.extend(buffer.target_values.drain(..));
2021-03-01 13:40:05 -08:00
}
pending_generator_indices = next_pending_generator_indices;
2021-03-01 13:40:05 -08:00
}
assert_eq!(
remaining_generators, 0,
"{} generators weren't run",
remaining_generators
);
witness
2021-03-01 13:40:05 -08:00
}
2021-02-09 21:25:21 -08:00
/// A generator participates in the generation of the witness.
2021-08-19 14:54:11 +02:00
pub trait WitnessGenerator<F: Field>: 'static + Send + Sync + Debug {
2021-02-09 21:25:21 -08:00
/// Targets to be "watched" by this generator. Whenever a target in the watch list is populated,
/// the generator will be queued to run.
2021-02-26 13:18:41 -08:00
fn watch_list(&self) -> Vec<Target>;
2021-02-09 21:25:21 -08:00
/// Run this generator, returning a flag indicating whether the generator is finished. If the
/// flag is true, the generator will never be run again, otherwise it will be queued for another
/// run next time a target in its watch list is populated.
2021-08-20 09:55:49 +02:00
fn run(&self, witness: &PartitionWitness<F>, out_buffer: &mut GeneratedValues<F>) -> bool;
}
/// Values generated by a generator invocation.
2021-08-19 15:59:05 +02:00
#[derive(Debug)]
pub struct GeneratedValues<F: Field> {
pub(crate) target_values: Vec<(Target, F)>,
}
impl<F: Field> From<Vec<(Target, F)>> for GeneratedValues<F> {
fn from(target_values: Vec<(Target, F)>) -> Self {
Self { target_values }
}
}
impl<F: Field> GeneratedValues<F> {
pub fn with_capacity(capacity: usize) -> Self {
Vec::with_capacity(capacity).into()
}
pub fn empty() -> Self {
Vec::new().into()
}
pub fn singleton_wire(wire: Wire, value: F) -> Self {
Self::singleton_target(Target::Wire(wire), value)
}
pub fn singleton_target(target: Target, value: F) -> Self {
vec![(target, value)].into()
}
pub fn clear(&mut self) {
self.target_values.clear();
}
pub fn singleton_extension_target<const D: usize>(
et: ExtensionTarget<D>,
value: F::Extension,
) -> Self
where
F: Extendable<D>,
{
let mut witness = Self::with_capacity(D);
witness.set_extension_target(et, value);
witness
}
pub fn set_target(&mut self, target: Target, value: F) {
self.target_values.push((target, value))
}
pub fn set_hash_target(&mut self, ht: HashOutTarget, value: HashOut<F>) {
ht.elements
.iter()
.zip(value.elements)
.for_each(|(&t, x)| self.set_target(t, x));
}
pub fn set_extension_target<const D: usize>(
&mut self,
et: ExtensionTarget<D>,
value: F::Extension,
) where
F: Extendable<D>,
{
let limbs = value.to_basefield_array();
(0..D).for_each(|i| {
self.set_target(et.0[i], limbs[i]);
});
}
pub fn set_wire(&mut self, wire: Wire, value: F) {
self.set_target(Target::Wire(wire), value)
}
pub fn set_wires<W>(&mut self, wires: W, values: &[F])
where
W: IntoIterator<Item = Wire>,
{
// If we used itertools, we could use zip_eq for extra safety.
for (wire, &value) in wires.into_iter().zip(values) {
self.set_wire(wire, value);
}
}
pub fn set_ext_wires<W, const D: usize>(&mut self, wires: W, value: F::Extension)
where
F: Extendable<D>,
W: IntoIterator<Item = Wire>,
{
self.set_wires(wires, &value.to_basefield_array());
}
2021-02-09 21:25:21 -08:00
}
/// A generator which runs once after a list of dependencies is present in the witness.
2021-08-19 14:54:11 +02:00
pub trait SimpleGenerator<F: Field>: 'static + Send + Sync + Debug {
2021-02-26 13:18:41 -08:00
fn dependencies(&self) -> Vec<Target>;
2021-02-09 21:25:21 -08:00
2021-08-20 09:55:49 +02:00
fn run_once(&self, witness: &PartitionWitness<F>, out_buffer: &mut GeneratedValues<F>);
2021-09-02 15:03:03 -07:00
fn adapter(self) -> SimpleGeneratorAdapter<F, Self>
where
Self: Sized,
{
SimpleGeneratorAdapter {
inner: self,
_phantom: PhantomData,
}
}
}
#[derive(Debug)]
pub struct SimpleGeneratorAdapter<F: Field, SG: SimpleGenerator<F> + ?Sized> {
_phantom: PhantomData<F>,
inner: SG,
2021-02-09 21:25:21 -08:00
}
2021-09-02 15:03:03 -07:00
impl<F: Field, SG: SimpleGenerator<F>> WitnessGenerator<F> for SimpleGeneratorAdapter<F, SG> {
2021-02-26 13:18:41 -08:00
fn watch_list(&self) -> Vec<Target> {
2021-09-02 15:03:03 -07:00
self.inner.dependencies()
2021-02-09 21:25:21 -08:00
}
2021-08-20 09:55:49 +02:00
fn run(&self, witness: &PartitionWitness<F>, out_buffer: &mut GeneratedValues<F>) -> bool {
2021-09-02 15:03:03 -07:00
if witness.contains_all(&self.inner.dependencies()) {
self.inner.run_once(witness, out_buffer);
true
2021-02-09 21:25:21 -08:00
} else {
false
2021-02-09 21:25:21 -08:00
}
}
}
/// A generator which copies one wire to another.
2021-03-25 15:20:14 -07:00
#[derive(Debug)]
2021-02-09 21:25:21 -08:00
pub(crate) struct CopyGenerator {
2021-02-26 13:18:41 -08:00
pub(crate) src: Target,
pub(crate) dst: Target,
2021-02-09 21:25:21 -08:00
}
impl<F: Field> SimpleGenerator<F> for CopyGenerator {
2021-02-26 13:18:41 -08:00
fn dependencies(&self) -> Vec<Target> {
2021-02-09 21:25:21 -08:00
vec![self.src]
}
2021-08-20 09:55:49 +02:00
fn run_once(&self, witness: &PartitionWitness<F>, out_buffer: &mut GeneratedValues<F>) {
2021-02-09 21:25:21 -08:00
let value = witness.get_target(self.src);
out_buffer.set_target(self.dst, value);
2021-02-09 21:25:21 -08:00
}
}
2021-06-28 09:45:56 -07:00
/// A generator for including a random value
2021-08-19 14:54:11 +02:00
#[derive(Debug)]
2021-06-28 11:34:30 -07:00
pub(crate) struct RandomValueGenerator {
2021-06-28 09:45:56 -07:00
pub(crate) target: Target,
}
impl<F: Field> SimpleGenerator<F> for RandomValueGenerator {
fn dependencies(&self) -> Vec<Target> {
Vec::new()
}
2021-08-20 09:55:49 +02:00
fn run_once(&self, _witness: &PartitionWitness<F>, out_buffer: &mut GeneratedValues<F>) {
2021-06-28 09:45:56 -07:00
let random_value = F::rand();
2021-06-28 17:07:27 -07:00
out_buffer.set_target(self.target, random_value);
2021-06-28 09:45:56 -07:00
}
}
2021-06-30 16:57:37 -07:00
2021-07-01 10:35:41 -07:00
/// A generator for testing if a value equals zero
2021-08-19 14:54:11 +02:00
#[derive(Debug)]
pub(crate) struct NonzeroTestGenerator {
2021-07-01 10:35:41 -07:00
pub(crate) to_test: Target,
pub(crate) dummy: Target,
2021-06-30 16:57:37 -07:00
}
impl<F: Field> SimpleGenerator<F> for NonzeroTestGenerator {
2021-06-30 16:57:37 -07:00
fn dependencies(&self) -> Vec<Target> {
2021-07-01 10:35:41 -07:00
vec![self.to_test]
2021-06-30 16:57:37 -07:00
}
2021-08-20 09:55:49 +02:00
fn run_once(&self, witness: &PartitionWitness<F>, out_buffer: &mut GeneratedValues<F>) {
2021-07-01 10:35:41 -07:00
let to_test_value = witness.get_target(self.to_test);
2021-06-30 16:57:37 -07:00
2021-07-01 10:35:41 -07:00
let dummy_value = if to_test_value == F::ZERO {
2021-06-30 16:57:37 -07:00
F::ONE
} else {
2021-07-01 10:35:41 -07:00
to_test_value.inverse()
2021-06-30 16:57:37 -07:00
};
out_buffer.set_target(self.dummy, dummy_value);
2021-06-30 16:57:37 -07:00
}
}