mirror of https://github.com/zcash/halo2.git
Replace PoseidonInstructions::State with PoseidonInstructions::Word
This commit is contained in:
parent
01eb431f1f
commit
d1fe466812
|
@ -11,15 +11,19 @@ use halo2::{
|
||||||
mod pow5t3;
|
mod pow5t3;
|
||||||
pub use pow5t3::{Pow5T3Chip, Pow5T3Config};
|
pub use pow5t3::{Pow5T3Chip, Pow5T3Config};
|
||||||
|
|
||||||
/// The set of circuit instructions required to use the [`Poseidon`] gadget.
|
use crate::primitives::poseidon::{Spec, State};
|
||||||
pub trait PoseidonInstructions<F: FieldExt>: Chip<F> {
|
|
||||||
/// Variable representing the state over which the Poseidon permutation operates.
|
/// The set of circuit instructions required to use the Poseidon permutation.
|
||||||
type State: fmt::Debug;
|
pub trait PoseidonInstructions<F: FieldExt, S: Spec<F, T, RATE>, const T: usize, const RATE: usize>:
|
||||||
|
Chip<F>
|
||||||
|
{
|
||||||
|
/// Variable representing the word over which the Poseidon permutation operates.
|
||||||
|
type Word: fmt::Debug;
|
||||||
|
|
||||||
/// Applies the Poseidon permutation to the given state.
|
/// Applies the Poseidon permutation to the given state.
|
||||||
fn permute(
|
fn permute(
|
||||||
&self,
|
&self,
|
||||||
layouter: &mut impl Layouter<F>,
|
layouter: &mut impl Layouter<F>,
|
||||||
initial_state: &Self::State,
|
initial_state: &State<Self::Word, T>,
|
||||||
) -> Result<Self::State, Error>;
|
) -> Result<State<Self::Word, T>, Error>;
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,7 +6,7 @@ use halo2::{
|
||||||
};
|
};
|
||||||
|
|
||||||
use super::PoseidonInstructions;
|
use super::PoseidonInstructions;
|
||||||
use crate::primitives::poseidon::{Mds, Spec};
|
use crate::primitives::poseidon::{Mds, Spec, State};
|
||||||
|
|
||||||
const WIDTH: usize = 3;
|
const WIDTH: usize = 3;
|
||||||
|
|
||||||
|
@ -186,14 +186,14 @@ impl<F: FieldExt> Chip<F> for Pow5T3Chip<F> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<F: FieldExt> PoseidonInstructions<F> for Pow5T3Chip<F> {
|
impl<F: FieldExt, S: Spec<F, WIDTH, 2>> PoseidonInstructions<F, S, WIDTH, 2> for Pow5T3Chip<F> {
|
||||||
type State = Pow5T3State<F>;
|
type Word = StateWord<F>;
|
||||||
|
|
||||||
fn permute(
|
fn permute(
|
||||||
&self,
|
&self,
|
||||||
layouter: &mut impl Layouter<F>,
|
layouter: &mut impl Layouter<F>,
|
||||||
initial_state: &Self::State,
|
initial_state: &State<Self::Word, WIDTH>,
|
||||||
) -> Result<Self::State, Error> {
|
) -> Result<State<Self::Word, WIDTH>, Error> {
|
||||||
let config = self.config();
|
let config = self.config();
|
||||||
|
|
||||||
layouter.assign_region(
|
layouter.assign_region(
|
||||||
|
@ -217,7 +217,7 @@ impl<F: FieldExt> PoseidonInstructions<F> for Pow5T3Chip<F> {
|
||||||
})
|
})
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
(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| {
|
res.and_then(|state| {
|
||||||
state.full_round(
|
state.full_round(
|
||||||
&mut region,
|
&mut region,
|
||||||
|
@ -226,20 +226,22 @@ impl<F: FieldExt> PoseidonInstructions<F> for Pow5T3Chip<F> {
|
||||||
config.half_full_rounds + config.half_partial_rounds + r,
|
config.half_full_rounds + config.half_partial_rounds + r,
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
})
|
})?;
|
||||||
|
|
||||||
|
Ok(state.0)
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
struct StateWord<F: FieldExt> {
|
pub struct StateWord<F: FieldExt> {
|
||||||
var: Cell,
|
var: Cell,
|
||||||
value: Option<F>,
|
value: Option<F>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct Pow5T3State<F: FieldExt>([StateWord<F>; WIDTH]);
|
struct Pow5T3State<F: FieldExt>([StateWord<F>; WIDTH]);
|
||||||
|
|
||||||
impl<F: FieldExt> Pow5T3State<F> {
|
impl<F: FieldExt> Pow5T3State<F> {
|
||||||
fn full_round(
|
fn full_round(
|
||||||
|
@ -352,17 +354,17 @@ impl<F: FieldExt> Pow5T3State<F> {
|
||||||
fn load(
|
fn load(
|
||||||
region: &mut Region<F>,
|
region: &mut Region<F>,
|
||||||
config: &Pow5T3Config<F>,
|
config: &Pow5T3Config<F>,
|
||||||
initial_state: &Self,
|
initial_state: &State<StateWord<F>, WIDTH>,
|
||||||
) -> Result<Self, Error> {
|
) -> Result<Self, Error> {
|
||||||
let mut load_state_word = |i: usize| {
|
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(
|
let var = region.assign_advice(
|
||||||
|| format!("load state_{}", i),
|
|| format!("load state_{}", i),
|
||||||
config.state[i],
|
config.state[i],
|
||||||
0,
|
0,
|
||||||
|| value.ok_or(Error::SynthesisError),
|
|| 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 })
|
Ok(StateWord { var, value })
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -429,7 +431,7 @@ mod tests {
|
||||||
plonk::{Assignment, Circuit, ConstraintSystem, Error},
|
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};
|
use crate::primitives::poseidon::{self, OrchardNullifier, Spec};
|
||||||
|
|
||||||
struct MyCircuit {}
|
struct MyCircuit {}
|
||||||
|
@ -468,16 +470,17 @@ mod tests {
|
||||||
Ok(StateWord { var, value })
|
Ok(StateWord { var, value })
|
||||||
};
|
};
|
||||||
|
|
||||||
Ok(Pow5T3State([
|
Ok([state_word(0)?, state_word(1)?, state_word(2)?])
|
||||||
state_word(0)?,
|
|
||||||
state_word(1)?,
|
|
||||||
state_word(2)?,
|
|
||||||
]))
|
|
||||||
},
|
},
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
let chip = Pow5T3Chip::construct(config.clone());
|
let chip = Pow5T3Chip::construct(config.clone());
|
||||||
let final_state = chip.permute(&mut layouter, &initial_state)?;
|
let final_state = <Pow5T3Chip<_> as PoseidonInstructions<
|
||||||
|
Fp,
|
||||||
|
OrchardNullifier,
|
||||||
|
WIDTH,
|
||||||
|
2,
|
||||||
|
>>::permute(&chip, &mut layouter, &initial_state)?;
|
||||||
|
|
||||||
// For the purpose of this test, compute the real final state inline.
|
// 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)];
|
let mut expected_final_state = [Fp::zero(), Fp::one(), Fp::from_u64(2)];
|
||||||
|
@ -498,7 +501,7 @@ mod tests {
|
||||||
0,
|
0,
|
||||||
|| Ok(expected_final_state[i]),
|
|| 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)?;
|
final_state_word(0)?;
|
||||||
|
|
Loading…
Reference in New Issue