diff --git a/digest/src/lib.rs b/digest/src/lib.rs index 72a7e00a9..21976e663 100644 --- a/digest/src/lib.rs +++ b/digest/src/lib.rs @@ -45,7 +45,7 @@ pub use dyn_digest::DynDigest; use generic_array::{ArrayLength, GenericArray}; #[cfg(feature = "alloc")] -use alloc::vec::Vec; +use alloc::boxed::Box; /// Trait for updating digest state with input data. pub trait Update { @@ -157,12 +157,16 @@ pub trait VariableOutput: core::marker::Sized { /// will be equal to `output_size`. fn finalize_variable(self, f: F); - /// Retrieve result into vector and consume hasher. + /// Retrieve result into a boxed slice and consume hasher. + /// + /// `Box<[u8]>` is used instead of `Vec` to save stack space, since + /// they have size of 2 and 3 words respectively. #[cfg(feature = "alloc")] #[cfg_attr(docsrs, doc(cfg(feature = "alloc")))] - fn finalize_vec(self) -> Vec { - let mut buf = Vec::with_capacity(self.output_size()); - self.finalize_variable(|res| buf.extend_from_slice(res)); + fn finalize_box(self) -> Box<[u8]> { + let n = self.output_size(); + let mut buf = vec![0u8; n].into_boxed_slice(); + self.finalize_variable(|res| buf.copy_from_slice(res)); buf } } @@ -173,13 +177,16 @@ pub trait XofReader { /// Read output into the `buffer`. Can be called an unlimited number of times. fn read(&mut self, buffer: &mut [u8]); - /// Read output into a vector of the specified size. + /// Read output into a boxed slice of the specified size. /// /// Can be called an unlimited number of times in combination with `read`. + /// + /// `Box<[u8]>` is used instead of `Vec` to save stack space, since + /// they have size of 2 and 3 words respectively. #[cfg(feature = "alloc")] #[cfg_attr(docsrs, doc(cfg(feature = "alloc")))] - fn read_vec(&mut self, n: usize) -> Vec { - let mut buf = vec![0u8; n]; + fn read_box(&mut self, n: usize) -> Box<[u8]> { + let mut buf = vec![0u8; n].into_boxed_slice(); self.read(&mut buf); buf } @@ -193,11 +200,14 @@ pub trait ExtendableOutput: core::marker::Sized { /// Retrieve XOF reader and consume hasher instance. fn finalize_xof(self) -> Self::Reader; - /// Retrieve result into vector of specified length. + /// Retrieve result into a boxed slice of the specified size. + /// + /// `Box<[u8]>` is used instead of `Vec` to save stack space, since + /// they have size of 2 and 3 words respectively. #[cfg(feature = "alloc")] #[cfg_attr(docsrs, doc(cfg(feature = "alloc")))] - fn finalize_vec(self, n: usize) -> Vec { - let mut buf = vec![0u8; n]; + fn finalize_box(self, n: usize) -> Box<[u8]> { + let mut buf = vec![0u8; n].into_boxed_slice(); self.finalize_xof().read(&mut buf); buf }