@@ -45,7 +45,7 @@ pub use dyn_digest::DynDigest;
45
45
use generic_array:: { ArrayLength , GenericArray } ;
46
46
47
47
#[ cfg( feature = "alloc" ) ]
48
- use alloc:: vec :: Vec ;
48
+ use alloc:: boxed :: Box ;
49
49
50
50
/// Trait for updating digest state with input data.
51
51
pub trait Update {
@@ -157,12 +157,16 @@ pub trait VariableOutput: core::marker::Sized {
157
157
/// will be equal to `output_size`.
158
158
fn finalize_variable < F : FnOnce ( & [ u8 ] ) > ( self , f : F ) ;
159
159
160
- /// Retrieve result into vector and consume hasher.
160
+ /// Retrieve result into a boxed slice and consume hasher.
161
+ ///
162
+ /// `Box<[u8]>` is used instead of `Vec<u8>` to save stack space, since
163
+ /// they have size of 2 and 3 words respectively.
161
164
#[ cfg( feature = "alloc" ) ]
162
165
#[ cfg_attr( docsrs, doc( cfg( feature = "alloc" ) ) ) ]
163
- fn finalize_vec ( self ) -> Vec < u8 > {
164
- let mut buf = Vec :: with_capacity ( self . output_size ( ) ) ;
165
- self . finalize_variable ( |res| buf. extend_from_slice ( res) ) ;
166
+ fn finalize_box ( self ) -> Box < [ u8 ] > {
167
+ let n = self . output_size ( ) ;
168
+ let mut buf = vec ! [ 0u8 ; n] . into_boxed_slice ( ) ;
169
+ self . finalize_variable ( |res| buf. copy_from_slice ( res) ) ;
166
170
buf
167
171
}
168
172
}
@@ -173,13 +177,16 @@ pub trait XofReader {
173
177
/// Read output into the `buffer`. Can be called an unlimited number of times.
174
178
fn read ( & mut self , buffer : & mut [ u8 ] ) ;
175
179
176
- /// Read output into a vector of the specified size.
180
+ /// Read output into a boxed slice of the specified size.
177
181
///
178
182
/// Can be called an unlimited number of times in combination with `read`.
183
+ ///
184
+ /// `Box<[u8]>` is used instead of `Vec<u8>` to save stack space, since
185
+ /// they have size of 2 and 3 words respectively.
179
186
#[ cfg( feature = "alloc" ) ]
180
187
#[ cfg_attr( docsrs, doc( cfg( feature = "alloc" ) ) ) ]
181
- fn read_vec ( & mut self , n : usize ) -> Vec < u8 > {
182
- let mut buf = vec ! [ 0u8 ; n] ;
188
+ fn read_box ( & mut self , n : usize ) -> Box < [ u8 ] > {
189
+ let mut buf = vec ! [ 0u8 ; n] . into_boxed_slice ( ) ;
183
190
self . read ( & mut buf) ;
184
191
buf
185
192
}
@@ -193,11 +200,14 @@ pub trait ExtendableOutput: core::marker::Sized {
193
200
/// Retrieve XOF reader and consume hasher instance.
194
201
fn finalize_xof ( self ) -> Self :: Reader ;
195
202
196
- /// Retrieve result into vector of specified length.
203
+ /// Retrieve result into a boxed slice of the specified size.
204
+ ///
205
+ /// `Box<[u8]>` is used instead of `Vec<u8>` to save stack space, since
206
+ /// they have size of 2 and 3 words respectively.
197
207
#[ cfg( feature = "alloc" ) ]
198
208
#[ cfg_attr( docsrs, doc( cfg( feature = "alloc" ) ) ) ]
199
- fn finalize_vec ( self , n : usize ) -> Vec < u8 > {
200
- let mut buf = vec ! [ 0u8 ; n] ;
209
+ fn finalize_box ( self , n : usize ) -> Box < [ u8 ] > {
210
+ let mut buf = vec ! [ 0u8 ; n] . into_boxed_slice ( ) ;
201
211
self . finalize_xof ( ) . read ( & mut buf) ;
202
212
buf
203
213
}
0 commit comments