plonky2/src/gates/gmimc.rs

78 lines
2.4 KiB
Rust
Raw Normal View History

2021-02-24 12:25:13 -08:00
use std::convert::TryInto;
2021-02-09 21:25:21 -08:00
use crate::circuit_data::CircuitConfig;
use crate::constraint_polynomial::ConstraintPolynomial;
use crate::field::field::Field;
use crate::gates::deterministic_gate::DeterministicGate;
2021-02-24 12:25:13 -08:00
use crate::gates::gate::{Gate, GateRef};
use crate::generator::{SimpleGenerator, WitnessGenerator2};
use crate::gmimc::gmimc_permute;
use crate::target::Target2;
use crate::wire::Wire;
use crate::witness::PartialWitness;
use std::sync::Arc;
2021-02-09 21:25:21 -08:00
2021-02-24 12:25:13 -08:00
/// Evaluates a full GMiMC permutation, and writes the output to the next gate's first `width`
/// wires (which could be the input of another `GMiMCGate`).
2021-02-09 21:25:21 -08:00
#[derive(Debug)]
2021-02-24 12:25:13 -08:00
pub struct GMiMCGate<F: Field, const W: usize, const R: usize> {
round_constants: Arc<[F; R]>,
2021-02-09 21:25:21 -08:00
}
2021-02-24 12:25:13 -08:00
impl<F: Field, const W: usize, const R: usize> GMiMCGate<F, W, R> {
fn new() -> GateRef<F> {
2021-02-09 21:25:21 -08:00
todo!()
}
}
2021-02-24 12:25:13 -08:00
impl<F: Field, const W: usize, const R: usize> Gate<F> for GMiMCGate<F, W, R> {
2021-02-09 21:25:21 -08:00
fn id(&self) -> String {
2021-02-24 12:25:13 -08:00
// TODO: Add W/R
2021-02-09 21:25:21 -08:00
format!("{:?}", self)
}
2021-02-24 12:25:13 -08:00
fn constraints(&self, config: CircuitConfig) -> Vec<ConstraintPolynomial<F>> {
2021-02-09 21:25:21 -08:00
unimplemented!()
}
2021-02-24 12:25:13 -08:00
fn generators(&self, config: CircuitConfig, gate_index: usize, local_constants: Vec<F>, next_constants: Vec<F>) -> Vec<Box<dyn WitnessGenerator2<F>>> {
let generator = GMiMCGenerator::<F, W, R> {
round_constants: self.round_constants.clone(),
gate_index,
};
vec![Box::new(generator)]
}
}
struct GMiMCGenerator<F: Field, const W: usize, const R: usize> {
round_constants: Arc<[F; R]>,
gate_index: usize,
}
impl<F: Field, const W: usize, const R: usize> SimpleGenerator<F> for GMiMCGenerator<F, W, R> {
fn dependencies(&self) -> Vec<Target2> {
(0..W)
.map(|i| Target2::Wire(
Wire { gate: self.gate_index, input: i }))
.collect()
}
fn run_once(&mut self, witness: &PartialWitness<F>) -> PartialWitness<F> {
let mut inputs: [F; W] = [F::ZERO; W];
for i in 0..W {
inputs[i] = witness.get_wire(
Wire { gate: self.gate_index, input: i });
}
let outputs = gmimc_permute::<F, W, R>(inputs, self.round_constants.clone());
let mut result = PartialWitness::new();
for i in 0..W {
result.set_wire(
Wire { gate: self.gate_index + 1, input: i },
outputs[i]);
}
result
}
2021-02-09 21:25:21 -08:00
}