From d1fe4668128e0ed25afeb101325f9a294e33def5 Mon Sep 17 00:00:00 2001 From: Jack Grigg Date: Fri, 2 Apr 2021 17:03:56 +1300 Subject: [PATCH] Replace PoseidonInstructions::State with PoseidonInstructions::Word --- src/circuit/gadget/poseidon.rs | 16 ++++++---- src/circuit/gadget/poseidon/pow5t3.rs | 43 ++++++++++++++------------- 2 files changed, 33 insertions(+), 26 deletions(-) diff --git a/src/circuit/gadget/poseidon.rs b/src/circuit/gadget/poseidon.rs index 3ea50a74..dcb50822 100644 --- a/src/circuit/gadget/poseidon.rs +++ b/src/circuit/gadget/poseidon.rs @@ -11,15 +11,19 @@ use halo2::{ mod pow5t3; pub use pow5t3::{Pow5T3Chip, Pow5T3Config}; -/// The set of circuit instructions required to use the [`Poseidon`] gadget. -pub trait PoseidonInstructions: Chip { - /// Variable representing the state over which the Poseidon permutation operates. - type State: fmt::Debug; +use crate::primitives::poseidon::{Spec, State}; + +/// The set of circuit instructions required to use the Poseidon permutation. +pub trait PoseidonInstructions, const T: usize, const RATE: usize>: + Chip +{ + /// Variable representing the word over which the Poseidon permutation operates. + type Word: fmt::Debug; /// Applies the Poseidon permutation to the given state. fn permute( &self, layouter: &mut impl Layouter, - initial_state: &Self::State, - ) -> Result; + initial_state: &State, + ) -> Result, Error>; } diff --git a/src/circuit/gadget/poseidon/pow5t3.rs b/src/circuit/gadget/poseidon/pow5t3.rs index ca77a86d..ebd4276e 100644 --- a/src/circuit/gadget/poseidon/pow5t3.rs +++ b/src/circuit/gadget/poseidon/pow5t3.rs @@ -6,7 +6,7 @@ use halo2::{ }; use super::PoseidonInstructions; -use crate::primitives::poseidon::{Mds, Spec}; +use crate::primitives::poseidon::{Mds, Spec, State}; const WIDTH: usize = 3; @@ -186,14 +186,14 @@ impl Chip for Pow5T3Chip { } } -impl PoseidonInstructions for Pow5T3Chip { - type State = Pow5T3State; +impl> PoseidonInstructions for Pow5T3Chip { + type Word = StateWord; fn permute( &self, layouter: &mut impl Layouter, - initial_state: &Self::State, - ) -> Result { + initial_state: &State, + ) -> Result, Error> { let config = self.config(); layouter.assign_region( @@ -217,7 +217,7 @@ impl PoseidonInstructions for Pow5T3Chip { }) })?; - (0..config.half_full_rounds).fold(Ok(state), |res, r| { + let state = (0..config.half_full_rounds).fold(Ok(state), |res, r| { res.and_then(|state| { state.full_round( &mut region, @@ -226,20 +226,22 @@ impl PoseidonInstructions for Pow5T3Chip { config.half_full_rounds + config.half_partial_rounds + r, ) }) - }) + })?; + + Ok(state.0) }, ) } } #[derive(Debug)] -struct StateWord { +pub struct StateWord { var: Cell, value: Option, } #[derive(Debug)] -pub struct Pow5T3State([StateWord; WIDTH]); +struct Pow5T3State([StateWord; WIDTH]); impl Pow5T3State { fn full_round( @@ -352,17 +354,17 @@ impl Pow5T3State { fn load( region: &mut Region, config: &Pow5T3Config, - initial_state: &Self, + initial_state: &State, WIDTH>, ) -> Result { let mut load_state_word = |i: usize| { - let value = initial_state.0[i].value; + let value = initial_state[i].value; let var = region.assign_advice( || format!("load state_{}", i), config.state[i], 0, || value.ok_or(Error::SynthesisError), )?; - region.constrain_equal(&config.state_permutation, initial_state.0[i].var, var)?; + region.constrain_equal(&config.state_permutation, initial_state[i].var, var)?; Ok(StateWord { var, value }) }; @@ -429,7 +431,7 @@ mod tests { plonk::{Assignment, Circuit, ConstraintSystem, Error}, }; - use super::{PoseidonInstructions, Pow5T3Chip, Pow5T3Config, Pow5T3State, StateWord, WIDTH}; + use super::{PoseidonInstructions, Pow5T3Chip, Pow5T3Config, StateWord, WIDTH}; use crate::primitives::poseidon::{self, OrchardNullifier, Spec}; struct MyCircuit {} @@ -468,16 +470,17 @@ mod tests { Ok(StateWord { var, value }) }; - Ok(Pow5T3State([ - state_word(0)?, - state_word(1)?, - state_word(2)?, - ])) + Ok([state_word(0)?, state_word(1)?, state_word(2)?]) }, )?; let chip = Pow5T3Chip::construct(config.clone()); - let final_state = chip.permute(&mut layouter, &initial_state)?; + let final_state = as PoseidonInstructions< + Fp, + OrchardNullifier, + WIDTH, + 2, + >>::permute(&chip, &mut layouter, &initial_state)?; // For the purpose of this test, compute the real final state inline. let mut expected_final_state = [Fp::zero(), Fp::one(), Fp::from_u64(2)]; @@ -498,7 +501,7 @@ mod tests { 0, || Ok(expected_final_state[i]), )?; - region.constrain_equal(&config.state_permutation, final_state.0[i].var, var) + region.constrain_equal(&config.state_permutation, final_state[i].var, var) }; final_state_word(0)?;