1use core::cmp;
6
7use crate::{incomplete_block_len, HashEngine as _};
8
9crate::internal_macros::general_hash_type! {
10 512,
11 false,
12 "Output of the SHA512 hash function."
13}
14
15#[cfg(not(hashes_fuzz))]
16pub(crate) fn from_engine(mut e: HashEngine) -> Hash {
17 let n_bytes_hashed = e.bytes_hashed;
19
20 let zeroes = [0; BLOCK_SIZE - 16];
21 e.input(&[0x80]);
22 if incomplete_block_len(&e) > zeroes.len() {
23 e.input(&zeroes);
24 }
25 let pad_length = zeroes.len() - incomplete_block_len(&e);
26 e.input(&zeroes[..pad_length]);
27 debug_assert_eq!(incomplete_block_len(&e), zeroes.len());
28
29 e.input(&[0; 8]);
30 e.input(&(8 * n_bytes_hashed).to_be_bytes());
31 debug_assert_eq!(incomplete_block_len(&e), 0);
32
33 Hash(e.midstate())
34}
35
36#[cfg(hashes_fuzz)]
37pub(crate) fn from_engine(e: HashEngine) -> Hash {
38 let mut hash = e.midstate();
39 hash[0] ^= 0xff; Hash(hash)
41}
42
43pub(crate) const BLOCK_SIZE: usize = 128;
44
45#[derive(Clone)]
47pub struct HashEngine {
48 h: [u64; 8],
49 bytes_hashed: u64,
50 buffer: [u8; BLOCK_SIZE],
51}
52
53impl HashEngine {
54 #[rustfmt::skip]
56 pub const fn new() -> Self {
57 Self {
58 h: [
59 0x6a09e667f3bcc908, 0xbb67ae8584caa73b, 0x3c6ef372fe94f82b, 0xa54ff53a5f1d36f1,
60 0x510e527fade682d1, 0x9b05688c2b3e6c1f, 0x1f83d9abfb41bd6b, 0x5be0cd19137e2179,
61 ],
62 bytes_hashed: 0,
63 buffer: [0; BLOCK_SIZE],
64 }
65 }
66}
67
68impl Default for HashEngine {
69 fn default() -> Self { Self::new() }
70}
71
72impl HashEngine {
73 #[cfg(not(hashes_fuzz))]
74 pub(crate) fn midstate(&self) -> [u8; 64] {
75 let mut ret = [0; 64];
76 for (val, ret_bytes) in self.h.iter().zip(ret.chunks_exact_mut(8)) {
77 ret_bytes.copy_from_slice(&val.to_be_bytes());
78 }
79 ret
80 }
81
82 #[cfg(hashes_fuzz)]
83 pub(crate) fn midstate(&self) -> [u8; 64] {
84 let mut ret = [0; 64];
85 ret.copy_from_slice(&self.buffer[..64]);
86 ret
87 }
88
89 #[rustfmt::skip]
91 pub(crate) const fn sha512_256() -> Self {
92 HashEngine {
93 h: [
94 0x22312194fc2bf72c, 0x9f555fa3c84c64c2, 0x2393b86b6f53b151, 0x963877195940eabd,
95 0x96283ee2a88effe3, 0xbe5e1e2553863992, 0x2b0199fc2c85b8aa, 0x0eb72ddc81c52ca2,
96 ],
97 bytes_hashed: 0,
98 buffer: [0; BLOCK_SIZE],
99 }
100 }
101
102 #[rustfmt::skip]
104 pub(crate) const fn sha384() -> Self {
105 HashEngine {
106 h: [
107 0xcbbb9d5dc1059ed8, 0x629a292a367cd507, 0x9159015a3070dd17, 0x152fecd8f70e5939,
108 0x67332667ffc00b31, 0x8eb44a8768581511, 0xdb0c2e0d64f98fa7, 0x47b5481dbefa4fa4,
109 ],
110 bytes_hashed: 0,
111 buffer: [0; BLOCK_SIZE],
112 }
113 }
114}
115
116impl crate::HashEngine for HashEngine {
117 const BLOCK_SIZE: usize = 128;
118
119 fn n_bytes_hashed(&self) -> u64 { self.bytes_hashed }
120
121 crate::internal_macros::engine_input_impl!();
122}
123
124#[allow(non_snake_case)]
125fn Ch(x: u64, y: u64, z: u64) -> u64 { z ^ (x & (y ^ z)) }
126#[allow(non_snake_case)]
127fn Maj(x: u64, y: u64, z: u64) -> u64 { (x & y) | (z & (x | y)) }
128#[allow(non_snake_case)]
129fn Sigma0(x: u64) -> u64 { x.rotate_left(36) ^ x.rotate_left(30) ^ x.rotate_left(25) }
130#[allow(non_snake_case)]
131fn Sigma1(x: u64) -> u64 { x.rotate_left(50) ^ x.rotate_left(46) ^ x.rotate_left(23) }
132fn sigma0(x: u64) -> u64 { x.rotate_left(63) ^ x.rotate_left(56) ^ (x >> 7) }
133fn sigma1(x: u64) -> u64 { x.rotate_left(45) ^ x.rotate_left(3) ^ (x >> 6) }
134
135#[cfg(feature = "small-hash")]
136#[macro_use]
137mod small_hash {
138 use super::*;
139
140 #[rustfmt::skip]
141 pub(super) fn round(a: u64, b: u64, c: u64, d: &mut u64, e: u64,
142 f: u64, g: u64, h: &mut u64, k: u64, w: u64,
143 ) {
144 let t1 =
145 h.wrapping_add(Sigma1(e)).wrapping_add(Ch(e, f, g)).wrapping_add(k).wrapping_add(w);
146 let t2 = Sigma0(a).wrapping_add(Maj(a, b, c));
147 *d = d.wrapping_add(t1);
148 *h = t1.wrapping_add(t2);
149 }
150 #[rustfmt::skip]
151 pub(super) fn later_round(a: u64, b: u64, c: u64, d: &mut u64, e: u64,
152 f: u64, g: u64, h: &mut u64, k: u64, w: u64,
153 w1: u64, w2: u64, w3: u64,
154 ) -> u64 {
155 let w = w.wrapping_add(sigma1(w1)).wrapping_add(w2).wrapping_add(sigma0(w3));
156 round(a, b, c, d, e, f, g, h, k, w);
157 w
158 }
159
160 macro_rules! round(
161 ($a:expr, $b:expr, $c:expr, $d:expr, $e:expr, $f:expr, $g:expr, $h:expr, $k:expr, $w:expr) => (
163 small_hash::round($a, $b, $c, &mut $d, $e, $f, $g, &mut $h, $k, $w)
164 );
165 ($a:expr, $b:expr, $c:expr, $d:expr, $e:expr, $f:expr, $g:expr, $h:expr, $k:expr, $w:expr, $w1:expr, $w2:expr, $w3:expr) => (
167 $w = small_hash::later_round($a, $b, $c, &mut $d, $e, $f, $g, &mut $h, $k, $w, $w1, $w2, $w3)
168 )
169 );
170}
171
172#[cfg(not(feature = "small-hash"))]
173#[macro_use]
174mod fast_hash {
175 macro_rules! round(
176 ($a:expr, $b:expr, $c:expr, $d:expr, $e:expr, $f:expr, $g:expr, $h:expr, $k:expr, $w:expr) => (
178 let t1 = $h.wrapping_add(Sigma1($e)).wrapping_add(Ch($e, $f, $g)).wrapping_add($k).wrapping_add($w);
179 let t2 = Sigma0($a).wrapping_add(Maj($a, $b, $c));
180 $d = $d.wrapping_add(t1);
181 $h = t1.wrapping_add(t2);
182 );
183 ($a:expr, $b:expr, $c:expr, $d:expr, $e:expr, $f:expr, $g:expr, $h:expr, $k:expr, $w:expr, $w1:expr, $w2:expr, $w3:expr) => (
185 $w = $w.wrapping_add(sigma1($w1)).wrapping_add($w2).wrapping_add(sigma0($w3));
186 round!($a, $b, $c, $d, $e, $f, $g, $h, $k, $w);
187 )
188 );
189}
190
191impl HashEngine {
192 pub(crate) fn process_block(&mut self) {
194 debug_assert_eq!(self.buffer.len(), BLOCK_SIZE);
195
196 let mut w = [0u64; 16];
197 for (w_val, buff_bytes) in w.iter_mut().zip(self.buffer.chunks_exact(8)) {
198 *w_val = u64::from_be_bytes(buff_bytes.try_into().expect("8 byte slice"));
199 }
200
201 let mut a = self.h[0];
202 let mut b = self.h[1];
203 let mut c = self.h[2];
204 let mut d = self.h[3];
205 let mut e = self.h[4];
206 let mut f = self.h[5];
207 let mut g = self.h[6];
208 let mut h = self.h[7];
209
210 round!(a, b, c, d, e, f, g, h, 0x428a2f98d728ae22, w[0]);
211 round!(h, a, b, c, d, e, f, g, 0x7137449123ef65cd, w[1]);
212 round!(g, h, a, b, c, d, e, f, 0xb5c0fbcfec4d3b2f, w[2]);
213 round!(f, g, h, a, b, c, d, e, 0xe9b5dba58189dbbc, w[3]);
214 round!(e, f, g, h, a, b, c, d, 0x3956c25bf348b538, w[4]);
215 round!(d, e, f, g, h, a, b, c, 0x59f111f1b605d019, w[5]);
216 round!(c, d, e, f, g, h, a, b, 0x923f82a4af194f9b, w[6]);
217 round!(b, c, d, e, f, g, h, a, 0xab1c5ed5da6d8118, w[7]);
218 round!(a, b, c, d, e, f, g, h, 0xd807aa98a3030242, w[8]);
219 round!(h, a, b, c, d, e, f, g, 0x12835b0145706fbe, w[9]);
220 round!(g, h, a, b, c, d, e, f, 0x243185be4ee4b28c, w[10]);
221 round!(f, g, h, a, b, c, d, e, 0x550c7dc3d5ffb4e2, w[11]);
222 round!(e, f, g, h, a, b, c, d, 0x72be5d74f27b896f, w[12]);
223 round!(d, e, f, g, h, a, b, c, 0x80deb1fe3b1696b1, w[13]);
224 round!(c, d, e, f, g, h, a, b, 0x9bdc06a725c71235, w[14]);
225 round!(b, c, d, e, f, g, h, a, 0xc19bf174cf692694, w[15]);
226
227 round!(a, b, c, d, e, f, g, h, 0xe49b69c19ef14ad2, w[0], w[14], w[9], w[1]);
228 round!(h, a, b, c, d, e, f, g, 0xefbe4786384f25e3, w[1], w[15], w[10], w[2]);
229 round!(g, h, a, b, c, d, e, f, 0x0fc19dc68b8cd5b5, w[2], w[0], w[11], w[3]);
230 round!(f, g, h, a, b, c, d, e, 0x240ca1cc77ac9c65, w[3], w[1], w[12], w[4]);
231 round!(e, f, g, h, a, b, c, d, 0x2de92c6f592b0275, w[4], w[2], w[13], w[5]);
232 round!(d, e, f, g, h, a, b, c, 0x4a7484aa6ea6e483, w[5], w[3], w[14], w[6]);
233 round!(c, d, e, f, g, h, a, b, 0x5cb0a9dcbd41fbd4, w[6], w[4], w[15], w[7]);
234 round!(b, c, d, e, f, g, h, a, 0x76f988da831153b5, w[7], w[5], w[0], w[8]);
235 round!(a, b, c, d, e, f, g, h, 0x983e5152ee66dfab, w[8], w[6], w[1], w[9]);
236 round!(h, a, b, c, d, e, f, g, 0xa831c66d2db43210, w[9], w[7], w[2], w[10]);
237 round!(g, h, a, b, c, d, e, f, 0xb00327c898fb213f, w[10], w[8], w[3], w[11]);
238 round!(f, g, h, a, b, c, d, e, 0xbf597fc7beef0ee4, w[11], w[9], w[4], w[12]);
239 round!(e, f, g, h, a, b, c, d, 0xc6e00bf33da88fc2, w[12], w[10], w[5], w[13]);
240 round!(d, e, f, g, h, a, b, c, 0xd5a79147930aa725, w[13], w[11], w[6], w[14]);
241 round!(c, d, e, f, g, h, a, b, 0x06ca6351e003826f, w[14], w[12], w[7], w[15]);
242 round!(b, c, d, e, f, g, h, a, 0x142929670a0e6e70, w[15], w[13], w[8], w[0]);
243
244 round!(a, b, c, d, e, f, g, h, 0x27b70a8546d22ffc, w[0], w[14], w[9], w[1]);
245 round!(h, a, b, c, d, e, f, g, 0x2e1b21385c26c926, w[1], w[15], w[10], w[2]);
246 round!(g, h, a, b, c, d, e, f, 0x4d2c6dfc5ac42aed, w[2], w[0], w[11], w[3]);
247 round!(f, g, h, a, b, c, d, e, 0x53380d139d95b3df, w[3], w[1], w[12], w[4]);
248 round!(e, f, g, h, a, b, c, d, 0x650a73548baf63de, w[4], w[2], w[13], w[5]);
249 round!(d, e, f, g, h, a, b, c, 0x766a0abb3c77b2a8, w[5], w[3], w[14], w[6]);
250 round!(c, d, e, f, g, h, a, b, 0x81c2c92e47edaee6, w[6], w[4], w[15], w[7]);
251 round!(b, c, d, e, f, g, h, a, 0x92722c851482353b, w[7], w[5], w[0], w[8]);
252 round!(a, b, c, d, e, f, g, h, 0xa2bfe8a14cf10364, w[8], w[6], w[1], w[9]);
253 round!(h, a, b, c, d, e, f, g, 0xa81a664bbc423001, w[9], w[7], w[2], w[10]);
254 round!(g, h, a, b, c, d, e, f, 0xc24b8b70d0f89791, w[10], w[8], w[3], w[11]);
255 round!(f, g, h, a, b, c, d, e, 0xc76c51a30654be30, w[11], w[9], w[4], w[12]);
256 round!(e, f, g, h, a, b, c, d, 0xd192e819d6ef5218, w[12], w[10], w[5], w[13]);
257 round!(d, e, f, g, h, a, b, c, 0xd69906245565a910, w[13], w[11], w[6], w[14]);
258 round!(c, d, e, f, g, h, a, b, 0xf40e35855771202a, w[14], w[12], w[7], w[15]);
259 round!(b, c, d, e, f, g, h, a, 0x106aa07032bbd1b8, w[15], w[13], w[8], w[0]);
260
261 round!(a, b, c, d, e, f, g, h, 0x19a4c116b8d2d0c8, w[0], w[14], w[9], w[1]);
262 round!(h, a, b, c, d, e, f, g, 0x1e376c085141ab53, w[1], w[15], w[10], w[2]);
263 round!(g, h, a, b, c, d, e, f, 0x2748774cdf8eeb99, w[2], w[0], w[11], w[3]);
264 round!(f, g, h, a, b, c, d, e, 0x34b0bcb5e19b48a8, w[3], w[1], w[12], w[4]);
265 round!(e, f, g, h, a, b, c, d, 0x391c0cb3c5c95a63, w[4], w[2], w[13], w[5]);
266 round!(d, e, f, g, h, a, b, c, 0x4ed8aa4ae3418acb, w[5], w[3], w[14], w[6]);
267 round!(c, d, e, f, g, h, a, b, 0x5b9cca4f7763e373, w[6], w[4], w[15], w[7]);
268 round!(b, c, d, e, f, g, h, a, 0x682e6ff3d6b2b8a3, w[7], w[5], w[0], w[8]);
269 round!(a, b, c, d, e, f, g, h, 0x748f82ee5defb2fc, w[8], w[6], w[1], w[9]);
270 round!(h, a, b, c, d, e, f, g, 0x78a5636f43172f60, w[9], w[7], w[2], w[10]);
271 round!(g, h, a, b, c, d, e, f, 0x84c87814a1f0ab72, w[10], w[8], w[3], w[11]);
272 round!(f, g, h, a, b, c, d, e, 0x8cc702081a6439ec, w[11], w[9], w[4], w[12]);
273 round!(e, f, g, h, a, b, c, d, 0x90befffa23631e28, w[12], w[10], w[5], w[13]);
274 round!(d, e, f, g, h, a, b, c, 0xa4506cebde82bde9, w[13], w[11], w[6], w[14]);
275 round!(c, d, e, f, g, h, a, b, 0xbef9a3f7b2c67915, w[14], w[12], w[7], w[15]);
276 round!(b, c, d, e, f, g, h, a, 0xc67178f2e372532b, w[15], w[13], w[8], w[0]);
277
278 round!(a, b, c, d, e, f, g, h, 0xca273eceea26619c, w[0], w[14], w[9], w[1]);
279 round!(h, a, b, c, d, e, f, g, 0xd186b8c721c0c207, w[1], w[15], w[10], w[2]);
280 round!(g, h, a, b, c, d, e, f, 0xeada7dd6cde0eb1e, w[2], w[0], w[11], w[3]);
281 round!(f, g, h, a, b, c, d, e, 0xf57d4f7fee6ed178, w[3], w[1], w[12], w[4]);
282 round!(e, f, g, h, a, b, c, d, 0x06f067aa72176fba, w[4], w[2], w[13], w[5]);
283 round!(d, e, f, g, h, a, b, c, 0x0a637dc5a2c898a6, w[5], w[3], w[14], w[6]);
284 round!(c, d, e, f, g, h, a, b, 0x113f9804bef90dae, w[6], w[4], w[15], w[7]);
285 round!(b, c, d, e, f, g, h, a, 0x1b710b35131c471b, w[7], w[5], w[0], w[8]);
286 round!(a, b, c, d, e, f, g, h, 0x28db77f523047d84, w[8], w[6], w[1], w[9]);
287 round!(h, a, b, c, d, e, f, g, 0x32caab7b40c72493, w[9], w[7], w[2], w[10]);
288 round!(g, h, a, b, c, d, e, f, 0x3c9ebe0a15c9bebc, w[10], w[8], w[3], w[11]);
289 round!(f, g, h, a, b, c, d, e, 0x431d67c49c100d4c, w[11], w[9], w[4], w[12]);
290 round!(e, f, g, h, a, b, c, d, 0x4cc5d4becb3e42b6, w[12], w[10], w[5], w[13]);
291 round!(d, e, f, g, h, a, b, c, 0x597f299cfc657e2a, w[13], w[11], w[6], w[14]);
292 round!(c, d, e, f, g, h, a, b, 0x5fcb6fab3ad6faec, w[14], w[12], w[7], w[15]);
293 round!(b, c, d, e, f, g, h, a, 0x6c44198c4a475817, w[15], w[13], w[8], w[0]);
294
295 self.h[0] = self.h[0].wrapping_add(a);
296 self.h[1] = self.h[1].wrapping_add(b);
297 self.h[2] = self.h[2].wrapping_add(c);
298 self.h[3] = self.h[3].wrapping_add(d);
299 self.h[4] = self.h[4].wrapping_add(e);
300 self.h[5] = self.h[5].wrapping_add(f);
301 self.h[6] = self.h[6].wrapping_add(g);
302 self.h[7] = self.h[7].wrapping_add(h);
303 }
304}
305
306#[cfg(test)]
307mod tests {
308 #[test]
309 #[cfg(feature = "alloc")]
310 fn test() {
311 use alloc::string::ToString;
312
313 use crate::{sha512, HashEngine};
314
315 #[derive(Clone)]
316 struct Test {
317 input: &'static str,
318 output: [u8; 64],
319 output_str: &'static str,
320 }
321
322 #[rustfmt::skip]
323 let tests = [
324 Test {
326 input: "",
327 output: [
328 0xcf, 0x83, 0xe1, 0x35, 0x7e, 0xef, 0xb8, 0xbd,
329 0xf1, 0x54, 0x28, 0x50, 0xd6, 0x6d, 0x80, 0x07,
330 0xd6, 0x20, 0xe4, 0x05, 0x0b, 0x57, 0x15, 0xdc,
331 0x83, 0xf4, 0xa9, 0x21, 0xd3, 0x6c, 0xe9, 0xce,
332 0x47, 0xd0, 0xd1, 0x3c, 0x5d, 0x85, 0xf2, 0xb0,
333 0xff, 0x83, 0x18, 0xd2, 0x87, 0x7e, 0xec, 0x2f,
334 0x63, 0xb9, 0x31, 0xbd, 0x47, 0x41, 0x7a, 0x81,
335 0xa5, 0x38, 0x32, 0x7a, 0xf9, 0x27, 0xda, 0x3e,
336 ],
337 output_str: "cf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce47d0d13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3e"
338 },
339 Test {
340 input: "The quick brown fox jumps over the lazy dog",
341 output: [
342 0x07, 0xe5, 0x47, 0xd9, 0x58, 0x6f, 0x6a, 0x73,
343 0xf7, 0x3f, 0xba, 0xc0, 0x43, 0x5e, 0xd7, 0x69,
344 0x51, 0x21, 0x8f, 0xb7, 0xd0, 0xc8, 0xd7, 0x88,
345 0xa3, 0x09, 0xd7, 0x85, 0x43, 0x6b, 0xbb, 0x64,
346 0x2e, 0x93, 0xa2, 0x52, 0xa9, 0x54, 0xf2, 0x39,
347 0x12, 0x54, 0x7d, 0x1e, 0x8a, 0x3b, 0x5e, 0xd6,
348 0xe1, 0xbf, 0xd7, 0x09, 0x78, 0x21, 0x23, 0x3f,
349 0xa0, 0x53, 0x8f, 0x3d, 0xb8, 0x54, 0xfe, 0xe6,
350 ],
351 output_str: "07e547d9586f6a73f73fbac0435ed76951218fb7d0c8d788a309d785436bbb642e93a252a954f23912547d1e8a3b5ed6e1bfd7097821233fa0538f3db854fee6",
352 },
353 Test {
354 input: "The quick brown fox jumps over the lazy dog.",
355 output: [
356 0x91, 0xea, 0x12, 0x45, 0xf2, 0x0d, 0x46, 0xae,
357 0x9a, 0x03, 0x7a, 0x98, 0x9f, 0x54, 0xf1, 0xf7,
358 0x90, 0xf0, 0xa4, 0x76, 0x07, 0xee, 0xb8, 0xa1,
359 0x4d, 0x12, 0x89, 0x0c, 0xea, 0x77, 0xa1, 0xbb,
360 0xc6, 0xc7, 0xed, 0x9c, 0xf2, 0x05, 0xe6, 0x7b,
361 0x7f, 0x2b, 0x8f, 0xd4, 0xc7, 0xdf, 0xd3, 0xa7,
362 0xa8, 0x61, 0x7e, 0x45, 0xf3, 0xc4, 0x63, 0xd4,
363 0x81, 0xc7, 0xe5, 0x86, 0xc3, 0x9a, 0xc1, 0xed,
364 ],
365 output_str: "91ea1245f20d46ae9a037a989f54f1f790f0a47607eeb8a14d12890cea77a1bbc6c7ed9cf205e67b7f2b8fd4c7dfd3a7a8617e45f3c463d481c7e586c39ac1ed",
366 },
367 ];
368
369 for test in tests {
370 let hash = sha512::Hash::hash(test.input.as_bytes());
372 assert_eq!(hash, test.output_str.parse::<sha512::Hash>().expect("parse hex"));
373 assert_eq!(hash.as_byte_array(), &test.output);
374 assert_eq!(hash.to_string(), test.output_str);
375
376 let mut engine = sha512::Hash::engine();
378 for ch in test.input.as_bytes() {
379 engine.input(&[*ch]);
380 }
381 let manual_hash = sha512::Hash::from_engine(engine);
382 assert_eq!(hash, manual_hash);
383 assert_eq!(hash.to_byte_array(), test.output);
384 }
385 }
386
387 #[test]
388 #[cfg(feature = "serde")]
389 fn sha512_serde() {
390 use serde_test::{assert_tokens, Configure, Token};
391
392 use crate::sha512;
393
394 #[rustfmt::skip]
395 static HASH_BYTES: [u8; 64] = [
396 0x8b, 0x41, 0xe1, 0xb7, 0x8a, 0xd1, 0x15, 0x21,
397 0x11, 0x3c, 0x52, 0xff, 0x18, 0x2a, 0x1b, 0x8e,
398 0x0a, 0x19, 0x57, 0x54, 0xaa, 0x52, 0x7f, 0xcd,
399 0x00, 0xa4, 0x11, 0x62, 0x0b, 0x46, 0xf2, 0x0f,
400 0xff, 0xfb, 0x80, 0x88, 0xcc, 0xf8, 0x54, 0x97,
401 0x12, 0x1a, 0xd4, 0x49, 0x9e, 0x08, 0x45, 0xb8,
402 0x76, 0xf6, 0xdd, 0x66, 0x40, 0x08, 0x8a, 0x2f,
403 0x0b, 0x2d, 0x8a, 0x60, 0x0b, 0xdf, 0x4c, 0x0c,
404 ];
405
406 let hash = sha512::Hash::from_slice(&HASH_BYTES).expect("right number of bytes");
407 assert_tokens(&hash.compact(), &[Token::BorrowedBytes(&HASH_BYTES[..])]);
408 assert_tokens(
409 &hash.readable(),
410 &[Token::Str(
411 "8b41e1b78ad11521113c52ff182a1b8e0a195754aa527fcd00a411620b46f20f\
412 fffb8088ccf85497121ad4499e0845b876f6dd6640088a2f0b2d8a600bdf4c0c",
413 )],
414 );
415 }
416}
417
418#[cfg(bench)]
419mod benches {
420 use test::Bencher;
421
422 use crate::{sha512, Hash, HashEngine};
423
424 #[bench]
425 pub fn sha512_10(bh: &mut Bencher) {
426 let mut engine = sha512::Hash::engine();
427 let bytes = [1u8; 10];
428 bh.iter(|| {
429 engine.input(&bytes);
430 });
431 bh.bytes = bytes.len() as u64;
432 }
433
434 #[bench]
435 pub fn sha512_1k(bh: &mut Bencher) {
436 let mut engine = sha512::Hash::engine();
437 let bytes = [1u8; 1024];
438 bh.iter(|| {
439 engine.input(&bytes);
440 });
441 bh.bytes = bytes.len() as u64;
442 }
443
444 #[bench]
445 pub fn sha512_64k(bh: &mut Bencher) {
446 let mut engine = sha512::Hash::engine();
447 let bytes = [1u8; 65536];
448 bh.iter(|| {
449 engine.input(&bytes);
450 });
451 bh.bytes = bytes.len() as u64;
452 }
453}