cryptoxide/hashing/sha2/
mod.rs

1//! An implementation of the SHA-2 cryptographic hash algorithms.
2//!
3//! There are 6 standard algorithms specified in the SHA-2 standard:
4//!
5//!  * `Sha224`, which is the 32-bit `Sha256` algorithm with the result truncated to 224 bits.
6//!  * `Sha256`, which is the 32-bit `Sha256` algorithm.
7//!  * `Sha384`, which is the 64-bit `Sha512` algorithm with the result truncated to 384 bits.
8//!  * `Sha512`, which is the 64-bit `Sha512` algorithm.
9//!  * `Sha512Trunc224`, which is the 64-bit `Sha512` algorithm with the result truncated to 224 bits.
10//!  * `Sha512Trunc256`, which is the 64-bit `Sha512` algorithm with the result truncated to 256 bits.
11//!
12//! Algorithmically, there are only 2 core algorithms: `Sha256` and `Sha512`.
13//! All other algorithms are just applications of these with different initial hash
14//! values, and truncated to different digest bit lengths.
15//!
16//! # Usage
17//!
18//! An example of using `Sha256` is:
19//!
20//! ```rust
21//! use cryptoxide::hashing::sha2::Sha256;
22//!
23//! // create a Sha256 object
24//! let mut context = Sha256::new();
25//!
26//! // write input message
27//! context.update_mut(b"hello world");
28//!
29//! // read hash digest
30//! let output = context.finalize();
31//! ```
32//!
33//! An example of using `Sha512` is:
34//!
35//! ```rust
36//! use cryptoxide::hashing::sha2::Sha512;
37//!
38//! // create a Sha512 object
39//! let mut context = Sha512::new();
40//!
41//! // write input message
42//! context.update_mut(b"hello world");
43//!
44//! // read hash digest
45//! let output = context.finalize();
46//! ```
47
48mod eng256;
49mod eng512;
50mod impl256;
51mod impl512;
52mod initials;
53
54use crate::cryptoutil::FixedBuffer;
55use initials::*;
56
57macro_rules! digest {
58    (256 $name:ident, $ctxname:ident, $output_fn: ident, $output_bits:expr, $state:ident) => {
59        digest!(
60            @internal
61            $name,
62            $ctxname,
63            Engine256,
64            $output_fn,
65            $output_bits,
66            64,
67            $state
68        );
69    };
70    (512 $name:ident, $ctxname:ident, $output_fn:ident, $output_bits:expr, $state:ident) => {
71        digest!(
72            @internal
73            $name,
74            $ctxname,
75            Engine512,
76            $output_fn,
77            $output_bits,
78            128,
79            $state
80        );
81    };
82    (@internal $name:ident, $ctxname:ident, $init:ident, $output_fn:ident, $output_bits:expr, $block_size:literal, $state: ident) => {
83        /// Hash Algorithm
84        #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
85        pub struct $name;
86
87        impl $name {
88            /// Output of the hashing algorithm in bits
89            pub const OUTPUT_BITS: usize = $output_bits;
90
91            /// The block size in bytes of the algorithm, which is the number of bytes the algorithm typically buffer
92            /// before calling its compression function
93            pub const BLOCK_BYTES: usize = $block_size;
94
95            /// Create a new context for this algorithm
96            pub fn new() -> $ctxname {
97                $ctxname::new()
98            }
99        }
100
101        /// The hash algorithm context
102        #[derive(Clone)]
103        pub struct $ctxname {
104            engine: $init,
105        }
106
107        impl $ctxname {
108            /// Create a new hashing algorithm context
109            pub const fn new() -> Self {
110                Self {
111                    engine: $init::new(&$state),
112                }
113            }
114
115            /// Update in-place the hashing state by adding the input bytes slice into the state
116            ///
117            /// For the immutable version see [`update`]
118            pub fn update_mut(&mut self, input: &[u8]) {
119                self.engine.input(input)
120            }
121
122            /// Update the hashing state by adding the input bytes slice into the state
123            pub fn update(mut self, input: &[u8]) -> Self {
124                self.engine.input(input);
125                self
126            }
127
128            /// Finalize the context and return an array of bytes
129            ///
130            /// The context is consumed by this function, to prevent buggy reuse.
131            ///
132            /// If the context need to be kept before finalizing, the user can clone the Context
133            pub fn finalize(mut self) -> [u8; $output_bits / 8] {
134                let mut out = [0; $output_bits / 8];
135                self.engine.finish();
136                self.engine.state.$output_fn(&mut out);
137                out
138            }
139
140            /// Same as `finalize` but do not consume the context, but instead
141            /// reset it in a ready to use state.
142            pub fn finalize_reset(&mut self) -> [u8; $output_bits / 8] {
143                let mut out = [0; $output_bits / 8];
144                self.engine.finish();
145                self.engine.state.$output_fn(&mut out);
146                self.reset();
147                out
148            }
149
150            /// Reset the context state, as if a new context had been created
151            pub fn reset(&mut self) {
152                self.engine.reset(&$state);
153            }
154        }
155    };
156}
157
158// A structure that keeps track of the state of the Sha-512 operation and contains the logic
159// necessary to perform the final calculations.
160#[derive(Clone)]
161struct Engine512 {
162    processed_bytes: u128,
163    buffer: FixedBuffer<128>,
164    state: eng512::Engine,
165}
166
167impl Engine512 {
168    const fn new(h: &[u64; eng512::STATE_LEN]) -> Engine512 {
169        Engine512 {
170            processed_bytes: 0,
171            buffer: FixedBuffer::new(),
172            state: eng512::Engine::new(h),
173        }
174    }
175
176    fn reset(&mut self, h: &[u64; eng512::STATE_LEN]) {
177        self.processed_bytes = 0;
178        self.buffer.reset();
179        self.state.reset(h);
180    }
181
182    fn input(&mut self, input: &[u8]) {
183        self.processed_bytes += input.len() as u128;
184        let self_state = &mut self.state;
185        self.buffer.input(input, |input| self_state.blocks(input));
186    }
187
188    fn finish(&mut self) {
189        let self_state = &mut self.state;
190        self.buffer
191            .standard_padding(16, |input| self_state.blocks(input));
192        *self.buffer.next::<16>() = (self.processed_bytes << 3).to_be_bytes();
193        self.state.blocks(self.buffer.full_buffer());
194    }
195}
196
197// A structure that keeps track of the state of the Sha-256 operation and contains the logic
198// necessary to perform the final calculations.
199#[derive(Clone)]
200struct Engine256 {
201    processed_bytes: u64,
202    buffer: FixedBuffer<64>,
203    state: eng256::Engine,
204    finished: bool,
205}
206
207impl Engine256 {
208    const fn new(h: &[u32; eng256::STATE_LEN]) -> Engine256 {
209        Engine256 {
210            processed_bytes: 0,
211            buffer: FixedBuffer::new(),
212            state: eng256::Engine::new(h),
213            finished: false,
214        }
215    }
216
217    fn reset(&mut self, h: &[u32; eng256::STATE_LEN]) {
218        self.processed_bytes = 0;
219        self.buffer.reset();
220        self.state.reset(h);
221        self.finished = false;
222    }
223
224    fn input(&mut self, input: &[u8]) {
225        assert!(!self.finished);
226        self.processed_bytes += input.len() as u64;
227        let self_state = &mut self.state;
228        self.buffer.input(input, |input| self_state.blocks(input));
229    }
230
231    fn finish(&mut self) {
232        if self.finished {
233            return;
234        }
235
236        let self_state = &mut self.state;
237        self.buffer
238            .standard_padding(8, |input| self_state.blocks(input));
239        *self.buffer.next::<8>() = (self.processed_bytes << 3).to_be_bytes();
240        self.state.blocks(self.buffer.full_buffer());
241
242        self.finished = true;
243    }
244}
245
246digest!(512 Sha512, Context512, output_512bits_at, 512, H512);
247digest!(512 Sha384, Context384, output_384bits_at, 384, H384);
248digest!(
249    512
250    Sha512Trunc256,
251    Context512_256,
252    output_256bits_at,
253    256,
254    H512_TRUNC_256
255);
256digest!(
257    512
258    Sha512Trunc224,
259    Context512_224,
260    output_224bits_at,
261    224,
262    H512_TRUNC_224
263);
264digest!(256 Sha256, Context256, output_256bits_at, 256, H256);
265digest!(256 Sha224, Context224, output_224bits_at, 224, H224);
266
267#[cfg(test)]
268mod tests {
269    use super::super::tests::{test_hashing, Test};
270    use super::*;
271
272    #[test]
273    fn test_sha512() {
274        // Examples from wikipedia
275        let tests = [
276            Test {
277                input: b"",
278                output: [
279                    0xcf, 0x83, 0xe1, 0x35, 0x7e, 0xef, 0xb8, 0xbd, 0xf1, 0x54, 0x28, 0x50, 0xd6,
280                    0x6d, 0x80, 0x07, 0xd6, 0x20, 0xe4, 0x05, 0x0b, 0x57, 0x15, 0xdc, 0x83, 0xf4,
281                    0xa9, 0x21, 0xd3, 0x6c, 0xe9, 0xce, 0x47, 0xd0, 0xd1, 0x3c, 0x5d, 0x85, 0xf2,
282                    0xb0, 0xff, 0x83, 0x18, 0xd2, 0x87, 0x7e, 0xec, 0x2f, 0x63, 0xb9, 0x31, 0xbd,
283                    0x47, 0x41, 0x7a, 0x81, 0xa5, 0x38, 0x32, 0x7a, 0xf9, 0x27, 0xda, 0x3e,
284                ],
285            },
286            Test {
287                input: b"The quick brown fox jumps over the lazy dog",
288                output: [
289                    0x07, 0xe5, 0x47, 0xd9, 0x58, 0x6f, 0x6a, 0x73, 0xf7, 0x3f, 0xba, 0xc0, 0x43,
290                    0x5e, 0xd7, 0x69, 0x51, 0x21, 0x8f, 0xb7, 0xd0, 0xc8, 0xd7, 0x88, 0xa3, 0x09,
291                    0xd7, 0x85, 0x43, 0x6b, 0xbb, 0x64, 0x2e, 0x93, 0xa2, 0x52, 0xa9, 0x54, 0xf2,
292                    0x39, 0x12, 0x54, 0x7d, 0x1e, 0x8a, 0x3b, 0x5e, 0xd6, 0xe1, 0xbf, 0xd7, 0x09,
293                    0x78, 0x21, 0x23, 0x3f, 0xa0, 0x53, 0x8f, 0x3d, 0xb8, 0x54, 0xfe, 0xe6,
294                ],
295            },
296            Test {
297                input: b"The quick brown fox jumps over the lazy dog.",
298                output: [
299                    0x91, 0xea, 0x12, 0x45, 0xf2, 0x0d, 0x46, 0xae, 0x9a, 0x03, 0x7a, 0x98, 0x9f,
300                    0x54, 0xf1, 0xf7, 0x90, 0xf0, 0xa4, 0x76, 0x07, 0xee, 0xb8, 0xa1, 0x4d, 0x12,
301                    0x89, 0x0c, 0xea, 0x77, 0xa1, 0xbb, 0xc6, 0xc7, 0xed, 0x9c, 0xf2, 0x05, 0xe6,
302                    0x7b, 0x7f, 0x2b, 0x8f, 0xd4, 0xc7, 0xdf, 0xd3, 0xa7, 0xa8, 0x61, 0x7e, 0x45,
303                    0xf3, 0xc4, 0x63, 0xd4, 0x81, 0xc7, 0xe5, 0x86, 0xc3, 0x9a, 0xc1, 0xed,
304                ],
305            },
306        ];
307        test_hashing(
308            &tests,
309            Sha512,
310            |_| Context512::new(),
311            |ctx, input| ctx.update(input),
312            |ctx, input| ctx.update_mut(input),
313            |ctx| ctx.finalize(),
314            |ctx| ctx.finalize_reset(),
315            |ctx| ctx.reset(),
316        )
317    }
318
319    #[test]
320    fn test_sha384() {
321        // Examples from wikipedia
322        let tests = [
323            Test {
324                input: b"",
325                output: [
326                    0x38, 0xb0, 0x60, 0xa7, 0x51, 0xac, 0x96, 0x38, 0x4c, 0xd9, 0x32, 0x7e, 0xb1,
327                    0xb1, 0xe3, 0x6a, 0x21, 0xfd, 0xb7, 0x11, 0x14, 0xbe, 0x07, 0x43, 0x4c, 0x0c,
328                    0xc7, 0xbf, 0x63, 0xf6, 0xe1, 0xda, 0x27, 0x4e, 0xde, 0xbf, 0xe7, 0x6f, 0x65,
329                    0xfb, 0xd5, 0x1a, 0xd2, 0xf1, 0x48, 0x98, 0xb9, 0x5b,
330                ],
331            },
332            Test {
333                input: b"The quick brown fox jumps over the lazy dog",
334                output: [
335                    0xca, 0x73, 0x7f, 0x10, 0x14, 0xa4, 0x8f, 0x4c, 0x0b, 0x6d, 0xd4, 0x3c, 0xb1,
336                    0x77, 0xb0, 0xaf, 0xd9, 0xe5, 0x16, 0x93, 0x67, 0x54, 0x4c, 0x49, 0x40, 0x11,
337                    0xe3, 0x31, 0x7d, 0xbf, 0x9a, 0x50, 0x9c, 0xb1, 0xe5, 0xdc, 0x1e, 0x85, 0xa9,
338                    0x41, 0xbb, 0xee, 0x3d, 0x7f, 0x2a, 0xfb, 0xc9, 0xb1,
339                ],
340            },
341            Test {
342                input: b"The quick brown fox jumps over the lazy dog.",
343                output: [
344                    0xed, 0x89, 0x24, 0x81, 0xd8, 0x27, 0x2c, 0xa6, 0xdf, 0x37, 0x0b, 0xf7, 0x06,
345                    0xe4, 0xd7, 0xbc, 0x1b, 0x57, 0x39, 0xfa, 0x21, 0x77, 0xaa, 0xe6, 0xc5, 0x0e,
346                    0x94, 0x66, 0x78, 0x71, 0x8f, 0xc6, 0x7a, 0x7a, 0xf2, 0x81, 0x9a, 0x02, 0x1c,
347                    0x2f, 0xc3, 0x4e, 0x91, 0xbd, 0xb6, 0x34, 0x09, 0xd7,
348                ],
349            },
350        ];
351        test_hashing(
352            &tests,
353            Sha384,
354            |_| Context384::new(),
355            |ctx, input| ctx.update(input),
356            |ctx, input| ctx.update_mut(input),
357            |ctx| ctx.finalize(),
358            |ctx| ctx.finalize_reset(),
359            |ctx| ctx.reset(),
360        )
361    }
362
363    #[test]
364    fn test_sha512_256() {
365        // Examples from wikipedia
366        let tests = [
367            Test {
368                input: b"",
369                output: [
370                    0xc6, 0x72, 0xb8, 0xd1, 0xef, 0x56, 0xed, 0x28, 0xab, 0x87, 0xc3, 0x62, 0x2c,
371                    0x51, 0x14, 0x06, 0x9b, 0xdd, 0x3a, 0xd7, 0xb8, 0xf9, 0x73, 0x74, 0x98, 0xd0,
372                    0xc0, 0x1e, 0xce, 0xf0, 0x96, 0x7a,
373                ],
374            },
375            Test {
376                input: b"The quick brown fox jumps over the lazy dog",
377                output: [
378                    0xdd, 0x9d, 0x67, 0xb3, 0x71, 0x51, 0x9c, 0x33, 0x9e, 0xd8, 0xdb, 0xd2, 0x5a,
379                    0xf9, 0x0e, 0x97, 0x6a, 0x1e, 0xee, 0xfd, 0x4a, 0xd3, 0xd8, 0x89, 0x00, 0x5e,
380                    0x53, 0x2f, 0xc5, 0xbe, 0xf0, 0x4d,
381                ],
382            },
383            Test {
384                input: b"The quick brown fox jumps over the lazy dog.",
385                output: [
386                    0x15, 0x46, 0x74, 0x18, 0x40, 0xf8, 0xa4, 0x92, 0xb9, 0x59, 0xd9, 0xb8, 0xb2,
387                    0x34, 0x4b, 0x9b, 0x0e, 0xb5, 0x1b, 0x00, 0x4b, 0xba, 0x35, 0xc0, 0xae, 0xba,
388                    0xac, 0x86, 0xd4, 0x52, 0x64, 0xc3,
389                ],
390            },
391        ];
392        test_hashing(
393            &tests,
394            Sha512Trunc256,
395            |_| Context512_256::new(),
396            |ctx, input| ctx.update(input),
397            |ctx, input| ctx.update_mut(input),
398            |ctx| ctx.finalize(),
399            |ctx| ctx.finalize_reset(),
400            |ctx| ctx.reset(),
401        )
402    }
403
404    #[test]
405    fn test_sha512_224() {
406        // Examples from wikipedia
407        let tests = [
408            Test {
409                input: b"",
410                output: [
411                    0x6e, 0xd0, 0xdd, 0x02, 0x80, 0x6f, 0xa8, 0x9e, 0x25, 0xde, 0x06, 0x0c, 0x19,
412                    0xd3, 0xac, 0x86, 0xca, 0xbb, 0x87, 0xd6, 0xa0, 0xdd, 0xd0, 0x5c, 0x33, 0x3b,
413                    0x84, 0xf4,
414                ],
415            },
416            Test {
417                input: b"The quick brown fox jumps over the lazy dog",
418                output: [
419                    0x94, 0x4c, 0xd2, 0x84, 0x7f, 0xb5, 0x45, 0x58, 0xd4, 0x77, 0x5d, 0xb0, 0x48,
420                    0x5a, 0x50, 0x00, 0x31, 0x11, 0xc8, 0xe5, 0xda, 0xa6, 0x3f, 0xe7, 0x22, 0xc6,
421                    0xaa, 0x37,
422                ],
423            },
424            Test {
425                input: b"The quick brown fox jumps over the lazy dog.",
426                output: [
427                    0x6d, 0x6a, 0x92, 0x79, 0x49, 0x5e, 0xc4, 0x06, 0x17, 0x69, 0x75, 0x2e, 0x7f,
428                    0xf9, 0xc6, 0x8b, 0x6b, 0x0b, 0x3c, 0x5a, 0x28, 0x1b, 0x79, 0x17, 0xce, 0x05,
429                    0x72, 0xde,
430                ],
431            },
432        ];
433        test_hashing(
434            &tests,
435            Sha512Trunc224,
436            |_| Context512_224::new(),
437            |ctx, input| ctx.update(input),
438            |ctx, input| ctx.update_mut(input),
439            |ctx| ctx.finalize(),
440            |ctx| ctx.finalize_reset(),
441            |ctx| ctx.reset(),
442        )
443    }
444
445    #[test]
446    fn test_sha256() {
447        // Examples from wikipedia
448        let tests = [
449            Test {
450                input: b"",
451                output: [
452                    0xe3, 0xb0, 0xc4, 0x42, 0x98, 0xfc, 0x1c, 0x14, 0x9a, 0xfb, 0xf4, 0xc8, 0x99,
453                    0x6f, 0xb9, 0x24, 0x27, 0xae, 0x41, 0xe4, 0x64, 0x9b, 0x93, 0x4c, 0xa4, 0x95,
454                    0x99, 0x1b, 0x78, 0x52, 0xb8, 0x55,
455                ],
456            },
457            Test {
458                input: b"The quick brown fox jumps over the lazy dog",
459                output: [
460                    0xd7, 0xa8, 0xfb, 0xb3, 0x07, 0xd7, 0x80, 0x94, 0x69, 0xca, 0x9a, 0xbc, 0xb0,
461                    0x08, 0x2e, 0x4f, 0x8d, 0x56, 0x51, 0xe4, 0x6d, 0x3c, 0xdb, 0x76, 0x2d, 0x02,
462                    0xd0, 0xbf, 0x37, 0xc9, 0xe5, 0x92,
463                ],
464            },
465            Test {
466                input: b"The quick brown fox jumps over the lazy dog.",
467                output: [
468                    0xef, 0x53, 0x7f, 0x25, 0xc8, 0x95, 0xbf, 0xa7, 0x82, 0x52, 0x65, 0x29, 0xa9,
469                    0xb6, 0x3d, 0x97, 0xaa, 0x63, 0x15, 0x64, 0xd5, 0xd7, 0x89, 0xc2, 0xb7, 0x65,
470                    0x44, 0x8c, 0x86, 0x35, 0xfb, 0x6c,
471                ],
472            },
473        ];
474        test_hashing(
475            &tests,
476            Sha256,
477            |_| Context256::new(),
478            |ctx, input| ctx.update(input),
479            |ctx, input| ctx.update_mut(input),
480            |ctx| ctx.finalize(),
481            |ctx| ctx.finalize_reset(),
482            |ctx| ctx.reset(),
483        )
484    }
485
486    #[test]
487    fn test_sha224() {
488        // Examples from wikipedia
489        let tests = [
490            Test {
491                input: b"",
492                output: [
493                    0xd1, 0x4a, 0x02, 0x8c, 0x2a, 0x3a, 0x2b, 0xc9, 0x47, 0x61, 0x02, 0xbb, 0x28,
494                    0x82, 0x34, 0xc4, 0x15, 0xa2, 0xb0, 0x1f, 0x82, 0x8e, 0xa6, 0x2a, 0xc5, 0xb3,
495                    0xe4, 0x2f,
496                ],
497            },
498            Test {
499                input: b"The quick brown fox jumps over the lazy dog",
500                output: [
501                    0x73, 0x0e, 0x10, 0x9b, 0xd7, 0xa8, 0xa3, 0x2b, 0x1c, 0xb9, 0xd9, 0xa0, 0x9a,
502                    0xa2, 0x32, 0x5d, 0x24, 0x30, 0x58, 0x7d, 0xdb, 0xc0, 0xc3, 0x8b, 0xad, 0x91,
503                    0x15, 0x25,
504                ],
505            },
506            Test {
507                input: b"The quick brown fox jumps over the lazy dog.",
508                output: [
509                    0x61, 0x9c, 0xba, 0x8e, 0x8e, 0x05, 0x82, 0x6e, 0x9b, 0x8c, 0x51, 0x9c, 0x0a,
510                    0x5c, 0x68, 0xf4, 0xfb, 0x65, 0x3e, 0x8a, 0x3d, 0x8a, 0xa0, 0x4b, 0xb2, 0xc8,
511                    0xcd, 0x4c,
512                ],
513            },
514        ];
515        test_hashing(
516            &tests,
517            Sha224,
518            |_| Context224::new(),
519            |ctx, input| ctx.update(input),
520            |ctx, input| ctx.update_mut(input),
521            |ctx| ctx.finalize(),
522            |ctx| ctx.finalize_reset(),
523            |ctx| ctx.reset(),
524        )
525    }
526}
527
528#[cfg(all(test, feature = "with-bench"))]
529mod bench {
530    use super::eng256;
531    use super::eng512;
532    use super::{Sha256, Sha512};
533    use test::Bencher;
534
535    #[bench]
536    pub fn sha256_block(bh: &mut Bencher) {
537        let mut state = eng256::Engine::new(&[0u32; eng256::STATE_LEN]);
538        let block = [1u8; 64];
539        bh.iter(|| {
540            state.blocks(&block);
541        });
542        bh.bytes = 64u64;
543    }
544
545    #[bench]
546    pub fn sha512_block(bh: &mut Bencher) {
547        let mut state = eng512::Engine::new(&[0u64; eng512::STATE_LEN]);
548        let block = [1u8; 128];
549        bh.iter(|| {
550            state.blocks(&block);
551        });
552        bh.bytes = 128u64;
553    }
554
555    #[bench]
556    pub fn sha256_10(bh: &mut Bencher) {
557        let mut sh = Sha256::new();
558        let bytes = [1u8; 10];
559        bh.iter(|| {
560            sh.update_mut(&bytes);
561        });
562        bh.bytes = bytes.len() as u64;
563    }
564
565    #[bench]
566    pub fn sha256_1k(bh: &mut Bencher) {
567        let mut sh = Sha256::new();
568        let bytes = [1u8; 1000];
569        bh.iter(|| {
570            sh.update_mut(&bytes);
571        });
572        bh.bytes = bytes.len() as u64;
573    }
574
575    #[bench]
576    pub fn sha256_64k(bh: &mut Bencher) {
577        let mut sh = Sha256::new();
578        let bytes = [1u8; 65536];
579        bh.iter(|| {
580            sh.update_mut(&bytes);
581        });
582        bh.bytes = bytes.len() as u64;
583    }
584
585    #[bench]
586    pub fn sha512_10(bh: &mut Bencher) {
587        let mut sh = Sha512::new();
588        let bytes = [1u8; 10];
589        bh.iter(|| {
590            sh.update_mut(&bytes);
591        });
592        bh.bytes = bytes.len() as u64;
593    }
594
595    #[bench]
596    pub fn sha512_1k(bh: &mut Bencher) {
597        let mut sh = Sha512::new();
598        let bytes = [1u8; 1024];
599        bh.iter(|| {
600            sh.update_mut(&bytes);
601        });
602        bh.bytes = bytes.len() as u64;
603    }
604
605    #[bench]
606    pub fn sha512_64k(bh: &mut Bencher) {
607        let mut sh = Sha512::new();
608        let bytes = [1u8; 65536];
609        bh.iter(|| {
610            sh.update_mut(&bytes);
611        });
612        bh.bytes = bytes.len() as u64;
613    }
614}