use std::ops::Range; use crate::circuit_builder::CircuitBuilder; use crate::field::extension_field::target::ExtensionTarget; use crate::field::extension_field::Extendable; use crate::gates::gate::{Gate, GateRef}; use crate::generator::WitnessGenerator; use crate::vars::{EvaluationTargets, EvaluationVars, EvaluationVarsBase}; /// A gate whose first four wires will be equal to a hash of public inputs. pub struct PublicInputGate; impl PublicInputGate { pub fn wires_public_inputs_hash() -> Range { 0..4 } } impl, const D: usize> Gate for PublicInputGate { fn id(&self) -> String { "PublicInputGate".into() } fn eval_unfiltered(&self, vars: EvaluationVars) -> Vec { Self::wires_public_inputs_hash() .zip(vars.public_inputs_hash.elements) .map(|(wire, hash_part)| vars.local_wires[wire] - hash_part.into()) .collect() } fn eval_unfiltered_base(&self, vars: EvaluationVarsBase) -> Vec { Self::wires_public_inputs_hash() .zip(vars.public_inputs_hash.elements) .map(|(wire, hash_part)| vars.local_wires[wire] - hash_part) .collect() } fn eval_unfiltered_recursively( &self, builder: &mut CircuitBuilder, vars: EvaluationTargets, ) -> Vec> { Self::wires_public_inputs_hash() .zip(vars.public_inputs_hash.elements) .map(|(wire, hash_part)| { let hash_part_ext = builder.convert_to_ext(hash_part); builder.sub_extension(vars.local_wires[wire], hash_part_ext) }) .collect() } fn generators( &self, _gate_index: usize, _local_constants: &[F], ) -> Vec>> { Vec::new() } fn num_wires(&self) -> usize { 4 } fn num_constants(&self) -> usize { 0 } fn degree(&self) -> usize { 1 } fn num_constraints(&self) -> usize { 4 } } #[cfg(test)] mod tests { use crate::field::crandall_field::CrandallField; use crate::gates::gate_testing::test_low_degree; use crate::gates::public_input::PublicInputGate; #[test] fn low_degree() { test_low_degree::(PublicInputGate) } }