diff --git a/src/poseidon2.nr b/src/poseidon2.nr index 74ef78d..d152ab2 100644 --- a/src/poseidon2.nr +++ b/src/poseidon2.nr @@ -25,9 +25,9 @@ impl Poseidon2 { fn perform_duplex(&mut self) { // add the cache into sponge state - self.state[0] += self.cache[0]; - self.state[1] += self.cache[1]; - self.state[2] += self.cache[2]; + self.state[0] += self.cache[0] * ((0 < self.cache_size) as Field); + self.state[1] += self.cache[1] * ((1 < self.cache_size) as Field); + self.state[2] += self.cache[2] * ((2 < self.cache_size) as Field); self.state = crate::poseidon2_permutation(self.state); } diff --git a/src/tests.nr b/src/tests.nr index 49f0d73..d57916b 100644 --- a/src/tests.nr +++ b/src/tests.nr @@ -1,4 +1,7 @@ use super::{poseidon, poseidon2}; +use super::poseidon2::{Poseidon2, Poseidon2Hasher}; +use std::default::Default; +use std::hash::Hasher; #[test] fn reference_impl_test_vectors() { @@ -89,3 +92,15 @@ fn test_poseidon2_3() { let expected = 0x0f1badcd0d52ced816fb6e6826fdf66ada038135d53cbb993f320ca6529223cd; assert_eq(hash, expected); } + +#[test] +fn test_regression_perform_duplex_stale_cache() { + let a = [1, 2, 3, 4]; + let h_hash = Poseidon2::hash(a, 4); + let mut hasher: Poseidon2Hasher = Default::default(); + for x in a { + hasher.write(x); + } + let h_finish = hasher.finish(); + assert_eq(h_hash, h_finish); +}