1use core::ops::Index;
7use core::slice::SliceIndex;
8use core::{cmp, str};
9
10use crate::{FromSliceError, HashEngine as _};
11
12crate::internal_macros::hash_type! {
13 512,
14 false,
15 "Output of the SHA512 hash function."
16}
17
18#[cfg(not(hashes_fuzz))]
19pub(crate) fn from_engine(mut e: HashEngine) -> Hash {
20 let data_len = e.length as u64;
22
23 let zeroes = [0; BLOCK_SIZE - 16];
24 e.input(&[0x80]);
25 if e.length % BLOCK_SIZE > zeroes.len() {
26 e.input(&zeroes);
27 }
28 let pad_length = zeroes.len() - (e.length % BLOCK_SIZE);
29 e.input(&zeroes[..pad_length]);
30 debug_assert_eq!(e.length % BLOCK_SIZE, zeroes.len());
31
32 e.input(&[0; 8]);
33 e.input(&(8 * data_len).to_be_bytes());
34 debug_assert_eq!(e.length % BLOCK_SIZE, 0);
35
36 Hash(e.midstate())
37}
38
39#[cfg(hashes_fuzz)]
40pub(crate) fn from_engine(e: HashEngine) -> Hash {
41 let mut hash = e.midstate();
42 hash[0] ^= 0xff; Hash(hash)
44}
45
46pub(crate) const BLOCK_SIZE: usize = 128;
47
48#[derive(Clone)]
50pub struct HashEngine {
51 h: [u64; 8],
52 length: usize,
53 buffer: [u8; BLOCK_SIZE],
54}
55
56impl Default for HashEngine {
57 #[rustfmt::skip]
58 fn default() -> Self {
59 HashEngine {
60 h: [
61 0x6a09e667f3bcc908, 0xbb67ae8584caa73b, 0x3c6ef372fe94f82b, 0xa54ff53a5f1d36f1,
62 0x510e527fade682d1, 0x9b05688c2b3e6c1f, 0x1f83d9abfb41bd6b, 0x5be0cd19137e2179,
63 ],
64 length: 0,
65 buffer: [0; BLOCK_SIZE],
66 }
67 }
68}
69
70impl HashEngine {
71 #[rustfmt::skip]
73 pub(crate) fn sha512_256() -> Self {
74 HashEngine {
75 h: [
76 0x22312194fc2bf72c, 0x9f555fa3c84c64c2, 0x2393b86b6f53b151, 0x963877195940eabd,
77 0x96283ee2a88effe3, 0xbe5e1e2553863992, 0x2b0199fc2c85b8aa, 0x0eb72ddc81c52ca2,
78 ],
79 length: 0,
80 buffer: [0; BLOCK_SIZE],
81 }
82 }
83
84 #[rustfmt::skip]
86 pub(crate) fn sha384() -> Self {
87 HashEngine {
88 h: [
89 0xcbbb9d5dc1059ed8, 0x629a292a367cd507, 0x9159015a3070dd17, 0x152fecd8f70e5939,
90 0x67332667ffc00b31, 0x8eb44a8768581511, 0xdb0c2e0d64f98fa7, 0x47b5481dbefa4fa4,
91 ],
92 length: 0,
93 buffer: [0; BLOCK_SIZE],
94 }
95 }
96}
97
98impl crate::HashEngine for HashEngine {
99 type MidState = [u8; 64];
100
101 #[cfg(not(hashes_fuzz))]
102 fn midstate(&self) -> [u8; 64] {
103 let mut ret = [0; 64];
104 for (val, ret_bytes) in self.h.iter().zip(ret.chunks_exact_mut(8)) {
105 ret_bytes.copy_from_slice(&val.to_be_bytes());
106 }
107 ret
108 }
109
110 #[cfg(hashes_fuzz)]
111 fn midstate(&self) -> [u8; 64] {
112 let mut ret = [0; 64];
113 ret.copy_from_slice(&self.buffer[..64]);
114 ret
115 }
116
117 const BLOCK_SIZE: usize = 128;
118
119 fn n_bytes_hashed(&self) -> usize { self.length }
120
121 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 crate::{sha512, Hash, HashEngine};
312
313 #[derive(Clone)]
314 struct Test {
315 input: &'static str,
316 output: Vec<u8>,
317 output_str: &'static str,
318 }
319
320 #[rustfmt::skip]
321 let tests = vec![
322 Test {
324 input: "",
325 output: vec![
326 0xcf, 0x83, 0xe1, 0x35, 0x7e, 0xef, 0xb8, 0xbd,
327 0xf1, 0x54, 0x28, 0x50, 0xd6, 0x6d, 0x80, 0x07,
328 0xd6, 0x20, 0xe4, 0x05, 0x0b, 0x57, 0x15, 0xdc,
329 0x83, 0xf4, 0xa9, 0x21, 0xd3, 0x6c, 0xe9, 0xce,
330 0x47, 0xd0, 0xd1, 0x3c, 0x5d, 0x85, 0xf2, 0xb0,
331 0xff, 0x83, 0x18, 0xd2, 0x87, 0x7e, 0xec, 0x2f,
332 0x63, 0xb9, 0x31, 0xbd, 0x47, 0x41, 0x7a, 0x81,
333 0xa5, 0x38, 0x32, 0x7a, 0xf9, 0x27, 0xda, 0x3e,
334 ],
335 output_str: "cf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce47d0d13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3e"
336 },
337 Test {
338 input: "The quick brown fox jumps over the lazy dog",
339 output: vec![
340 0x07, 0xe5, 0x47, 0xd9, 0x58, 0x6f, 0x6a, 0x73,
341 0xf7, 0x3f, 0xba, 0xc0, 0x43, 0x5e, 0xd7, 0x69,
342 0x51, 0x21, 0x8f, 0xb7, 0xd0, 0xc8, 0xd7, 0x88,
343 0xa3, 0x09, 0xd7, 0x85, 0x43, 0x6b, 0xbb, 0x64,
344 0x2e, 0x93, 0xa2, 0x52, 0xa9, 0x54, 0xf2, 0x39,
345 0x12, 0x54, 0x7d, 0x1e, 0x8a, 0x3b, 0x5e, 0xd6,
346 0xe1, 0xbf, 0xd7, 0x09, 0x78, 0x21, 0x23, 0x3f,
347 0xa0, 0x53, 0x8f, 0x3d, 0xb8, 0x54, 0xfe, 0xe6,
348 ],
349 output_str: "07e547d9586f6a73f73fbac0435ed76951218fb7d0c8d788a309d785436bbb642e93a252a954f23912547d1e8a3b5ed6e1bfd7097821233fa0538f3db854fee6",
350 },
351 Test {
352 input: "The quick brown fox jumps over the lazy dog.",
353 output: vec![
354 0x91, 0xea, 0x12, 0x45, 0xf2, 0x0d, 0x46, 0xae,
355 0x9a, 0x03, 0x7a, 0x98, 0x9f, 0x54, 0xf1, 0xf7,
356 0x90, 0xf0, 0xa4, 0x76, 0x07, 0xee, 0xb8, 0xa1,
357 0x4d, 0x12, 0x89, 0x0c, 0xea, 0x77, 0xa1, 0xbb,
358 0xc6, 0xc7, 0xed, 0x9c, 0xf2, 0x05, 0xe6, 0x7b,
359 0x7f, 0x2b, 0x8f, 0xd4, 0xc7, 0xdf, 0xd3, 0xa7,
360 0xa8, 0x61, 0x7e, 0x45, 0xf3, 0xc4, 0x63, 0xd4,
361 0x81, 0xc7, 0xe5, 0x86, 0xc3, 0x9a, 0xc1, 0xed,
362 ],
363 output_str: "91ea1245f20d46ae9a037a989f54f1f790f0a47607eeb8a14d12890cea77a1bbc6c7ed9cf205e67b7f2b8fd4c7dfd3a7a8617e45f3c463d481c7e586c39ac1ed",
364 },
365 ];
366
367 for test in tests {
368 let hash = sha512::Hash::hash(test.input.as_bytes());
370 assert_eq!(hash, test.output_str.parse::<sha512::Hash>().expect("parse hex"));
371 assert_eq!(&hash[..], &test.output[..]);
372 assert_eq!(&hash.to_string(), &test.output_str);
373
374 let mut engine = sha512::Hash::engine();
376 for ch in test.input.as_bytes() {
377 engine.input(&[*ch]);
378 }
379 let manual_hash = sha512::Hash::from_engine(engine);
380 assert_eq!(hash, manual_hash);
381 assert_eq!(hash.to_byte_array()[..].as_ref(), test.output.as_slice());
382 }
383 }
384
385 #[cfg(feature = "serde")]
386 #[test]
387 fn sha512_serde() {
388 use serde_test::{assert_tokens, Configure, Token};
389
390 use crate::{sha512, Hash};
391
392 #[rustfmt::skip]
393 static HASH_BYTES: [u8; 64] = [
394 0x8b, 0x41, 0xe1, 0xb7, 0x8a, 0xd1, 0x15, 0x21,
395 0x11, 0x3c, 0x52, 0xff, 0x18, 0x2a, 0x1b, 0x8e,
396 0x0a, 0x19, 0x57, 0x54, 0xaa, 0x52, 0x7f, 0xcd,
397 0x00, 0xa4, 0x11, 0x62, 0x0b, 0x46, 0xf2, 0x0f,
398 0xff, 0xfb, 0x80, 0x88, 0xcc, 0xf8, 0x54, 0x97,
399 0x12, 0x1a, 0xd4, 0x49, 0x9e, 0x08, 0x45, 0xb8,
400 0x76, 0xf6, 0xdd, 0x66, 0x40, 0x08, 0x8a, 0x2f,
401 0x0b, 0x2d, 0x8a, 0x60, 0x0b, 0xdf, 0x4c, 0x0c,
402 ];
403
404 let hash = sha512::Hash::from_slice(&HASH_BYTES).expect("right number of bytes");
405 assert_tokens(&hash.compact(), &[Token::BorrowedBytes(&HASH_BYTES[..])]);
406 assert_tokens(
407 &hash.readable(),
408 &[Token::Str(
409 "8b41e1b78ad11521113c52ff182a1b8e0a195754aa527fcd00a411620b46f20f\
410 fffb8088ccf85497121ad4499e0845b876f6dd6640088a2f0b2d8a600bdf4c0c",
411 )],
412 );
413 }
414}
415
416#[cfg(bench)]
417mod benches {
418 use test::Bencher;
419
420 use crate::{sha512, Hash, HashEngine};
421
422 #[bench]
423 pub fn sha512_10(bh: &mut Bencher) {
424 let mut engine = sha512::Hash::engine();
425 let bytes = [1u8; 10];
426 bh.iter(|| {
427 engine.input(&bytes);
428 });
429 bh.bytes = bytes.len() as u64;
430 }
431
432 #[bench]
433 pub fn sha512_1k(bh: &mut Bencher) {
434 let mut engine = sha512::Hash::engine();
435 let bytes = [1u8; 1024];
436 bh.iter(|| {
437 engine.input(&bytes);
438 });
439 bh.bytes = bytes.len() as u64;
440 }
441
442 #[bench]
443 pub fn sha512_64k(bh: &mut Bencher) {
444 let mut engine = sha512::Hash::engine();
445 let bytes = [1u8; 65536];
446 bh.iter(|| {
447 engine.input(&bytes);
448 });
449 bh.bytes = bytes.len() as u64;
450 }
451}