Remove "final" round logic from poseidon::Pow5T3Chip

This was a bug in the Poseidon reference implementation, fixed in v1.1.
This commit is contained in:
Jack Grigg 2021-03-13 17:32:11 +13:00 committed by Jack Grigg
parent 40a19b429c
commit 01eb431f1f
1 changed files with 6 additions and 71 deletions

View File

@ -20,7 +20,6 @@ pub struct Pow5T3Config<F: FieldExt> {
rc_b: [Column<Fixed>; WIDTH],
s_full: Selector,
s_partial: Selector,
s_final: Selector,
half_full_rounds: usize,
half_partial_rounds: usize,
@ -73,7 +72,6 @@ impl<F: FieldExt> Pow5T3Chip<F> {
let s_full = meta.selector();
let s_partial = meta.selector();
let s_final = meta.selector();
let alpha = [5, 0, 0, 0];
let pow_5 = |v: Expression<F>| {
@ -153,34 +151,6 @@ impl<F: FieldExt> Pow5T3Chip<F> {
]
});
meta.create_gate("final full round", |meta| {
let cur = [
meta.query_advice(state[0], Rotation::cur()),
meta.query_advice(state[1], Rotation::cur()),
meta.query_advice(state[2], Rotation::cur()),
];
let next = [
meta.query_advice(state[0], Rotation::next()),
meta.query_advice(state[1], Rotation::next()),
meta.query_advice(state[2], Rotation::next()),
];
let rc = [
meta.query_fixed(rc_a[0], Rotation::cur()),
meta.query_fixed(rc_a[1], Rotation::cur()),
meta.query_fixed(rc_a[2], Rotation::cur()),
];
let s_final = meta.query_selector(s_final, Rotation::cur());
let final_full_round = |idx: usize| {
s_final.clone() * (pow_5(cur[idx].clone() + rc[idx].clone()) - next[idx].clone())
};
vec![
final_full_round(0),
final_full_round(1),
final_full_round(2),
]
});
Pow5T3Config {
state,
state_permutation,
@ -189,7 +159,6 @@ impl<F: FieldExt> Pow5T3Chip<F> {
rc_b,
s_full,
s_partial,
s_final,
half_full_rounds,
half_partial_rounds,
alpha,
@ -250,21 +219,12 @@ impl<F: FieldExt> PoseidonInstructions<F> for Pow5T3Chip<F> {
(0..config.half_full_rounds).fold(Ok(state), |res, r| {
res.and_then(|state| {
if r < config.half_full_rounds - 1 {
state.full_round(
&mut region,
&config,
config.half_full_rounds + 2 * config.half_partial_rounds + r,
config.half_full_rounds + config.half_partial_rounds + r,
)
} else {
state.final_round(
&mut region,
&config,
config.half_full_rounds + 2 * config.half_partial_rounds + r,
config.half_full_rounds + config.half_partial_rounds + r,
)
}
state.full_round(
&mut region,
&config,
config.half_full_rounds + 2 * config.half_partial_rounds + r,
config.half_full_rounds + config.half_partial_rounds + r,
)
})
})
},
@ -389,31 +349,6 @@ impl<F: FieldExt> Pow5T3State<F> {
})
}
fn final_round(
self,
region: &mut Region<F>,
config: &Pow5T3Config<F>,
round: usize,
offset: usize,
) -> Result<Self, Error> {
Self::round(region, config, round, offset, config.s_final, |_| {
let mut new_state = self
.0
.iter()
.zip(config.round_constants[round].iter())
.map(|(word, rc)| word.value.map(|v| (v + rc).pow(&config.alpha)));
Ok((
round + 1,
[
new_state.next().unwrap(),
new_state.next().unwrap(),
new_state.next().unwrap(),
],
))
})
}
fn load(
region: &mut Region<F>,
config: &Pow5T3Config<F>,