diff --git a/CHANGELOG.md b/CHANGELOG.md index 9b23d06..9f06173 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Fixed +- Read the `Sponge::absorb` input through a single `as_ref` call - Wipe old output allocations before growth, including when continuing cloned sponges [#37] - Return an error and invalidate the sponge when output allocation fails [#37] - Wipe encryption/decryption temporary vectors on error and unwinding [#37] diff --git a/src/sponge.rs b/src/sponge.rs index 9f5a433..db4e1f2 100644 --- a/src/sponge.rs +++ b/src/sponge.rs @@ -207,7 +207,8 @@ where return Err(Error::IOPatternViolation); } // Check that input yields enough elements - if input.as_ref().len() < len { + let input = input.as_ref(); + if input.len() < len { self.zeroize(); return Err(Error::TooFewInputElements); } @@ -224,7 +225,7 @@ where // Absorb `len` elements into the state, calling [`permute`] when the // absorb-position reached the rate. - for element in input.as_ref().iter().take(len) { + for element in input.iter().take(len) { if self.pos_absorb == Self::RATE { self.safe.permute(&mut self.state); diff --git a/tests/sponge.rs b/tests/sponge.rs index 9283570..bc208ba 100644 --- a/tests/sponge.rs +++ b/tests/sponge.rs @@ -4,6 +4,8 @@ // // Copyright (c) DUSK NETWORK. All rights reserved. +use core::cell::Cell; + use dusk_bls12_381::BlsScalar; use dusk_safe::{Call, Error, Safe, Sponge}; use zeroize::Zeroize; @@ -41,6 +43,23 @@ impl Rotate { } } +#[test] +fn absorb_uses_the_validated_slice() { + struct Input<'a>(Cell<&'a [BlsScalar]>); + impl AsRef<[BlsScalar]> for Input<'_> { + fn as_ref(&self) -> &[BlsScalar] { + self.0.replace(&[]) + } + } + let input = [BlsScalar::from(7), BlsScalar::from(9)]; + let mut sponge = + Sponge::start(Rotate::new(), [Call::Absorb(2), Call::Squeeze(1)], 0) + .unwrap(); + sponge.absorb(2, Input(Cell::new(&input))).unwrap(); + sponge.squeeze(1).unwrap(); + assert_eq!(sponge.finish().unwrap(), [input[1]]); +} + #[test] fn failures_are_terminal() { for case in 0..9 {