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 let _ = w[15]; self.h[0] = self.h[0].wrapping_add(a);
297 self.h[1] = self.h[1].wrapping_add(b);
298 self.h[2] = self.h[2].wrapping_add(c);
299 self.h[3] = self.h[3].wrapping_add(d);
300 self.h[4] = self.h[4].wrapping_add(e);
301 self.h[5] = self.h[5].wrapping_add(f);
302 self.h[6] = self.h[6].wrapping_add(g);
303 self.h[7] = self.h[7].wrapping_add(h);
304 }
305}
306
307#[cfg(test)]
308mod tests {
309 #[test]
310 #[cfg(feature = "alloc")]
311 fn test() {
312 use crate::{sha512, Hash, HashEngine};
313
314 #[derive(Clone)]
315 struct Test {
316 input: &'static str,
317 output: Vec<u8>,
318 output_str: &'static str,
319 }
320
321 #[rustfmt::skip]
322 let tests = vec![
323 Test {
325 input: "",
326 output: vec![
327 0xcf, 0x83, 0xe1, 0x35, 0x7e, 0xef, 0xb8, 0xbd,
328 0xf1, 0x54, 0x28, 0x50, 0xd6, 0x6d, 0x80, 0x07,
329 0xd6, 0x20, 0xe4, 0x05, 0x0b, 0x57, 0x15, 0xdc,
330 0x83, 0xf4, 0xa9, 0x21, 0xd3, 0x6c, 0xe9, 0xce,
331 0x47, 0xd0, 0xd1, 0x3c, 0x5d, 0x85, 0xf2, 0xb0,
332 0xff, 0x83, 0x18, 0xd2, 0x87, 0x7e, 0xec, 0x2f,
333 0x63, 0xb9, 0x31, 0xbd, 0x47, 0x41, 0x7a, 0x81,
334 0xa5, 0x38, 0x32, 0x7a, 0xf9, 0x27, 0xda, 0x3e,
335 ],
336 output_str: "cf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce47d0d13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3e"
337 },
338 Test {
339 input: "The quick brown fox jumps over the lazy dog",
340 output: vec![
341 0x07, 0xe5, 0x47, 0xd9, 0x58, 0x6f, 0x6a, 0x73,
342 0xf7, 0x3f, 0xba, 0xc0, 0x43, 0x5e, 0xd7, 0x69,
343 0x51, 0x21, 0x8f, 0xb7, 0xd0, 0xc8, 0xd7, 0x88,
344 0xa3, 0x09, 0xd7, 0x85, 0x43, 0x6b, 0xbb, 0x64,
345 0x2e, 0x93, 0xa2, 0x52, 0xa9, 0x54, 0xf2, 0x39,
346 0x12, 0x54, 0x7d, 0x1e, 0x8a, 0x3b, 0x5e, 0xd6,
347 0xe1, 0xbf, 0xd7, 0x09, 0x78, 0x21, 0x23, 0x3f,
348 0xa0, 0x53, 0x8f, 0x3d, 0xb8, 0x54, 0xfe, 0xe6,
349 ],
350 output_str: "07e547d9586f6a73f73fbac0435ed76951218fb7d0c8d788a309d785436bbb642e93a252a954f23912547d1e8a3b5ed6e1bfd7097821233fa0538f3db854fee6",
351 },
352 Test {
353 input: "The quick brown fox jumps over the lazy dog.",
354 output: vec![
355 0x91, 0xea, 0x12, 0x45, 0xf2, 0x0d, 0x46, 0xae,
356 0x9a, 0x03, 0x7a, 0x98, 0x9f, 0x54, 0xf1, 0xf7,
357 0x90, 0xf0, 0xa4, 0x76, 0x07, 0xee, 0xb8, 0xa1,
358 0x4d, 0x12, 0x89, 0x0c, 0xea, 0x77, 0xa1, 0xbb,
359 0xc6, 0xc7, 0xed, 0x9c, 0xf2, 0x05, 0xe6, 0x7b,
360 0x7f, 0x2b, 0x8f, 0xd4, 0xc7, 0xdf, 0xd3, 0xa7,
361 0xa8, 0x61, 0x7e, 0x45, 0xf3, 0xc4, 0x63, 0xd4,
362 0x81, 0xc7, 0xe5, 0x86, 0xc3, 0x9a, 0xc1, 0xed,
363 ],
364 output_str: "91ea1245f20d46ae9a037a989f54f1f790f0a47607eeb8a14d12890cea77a1bbc6c7ed9cf205e67b7f2b8fd4c7dfd3a7a8617e45f3c463d481c7e586c39ac1ed",
365 },
366 ];
367
368 for test in tests {
369 let hash = sha512::Hash::hash(test.input.as_bytes());
371 assert_eq!(hash, test.output_str.parse::<sha512::Hash>().expect("parse hex"));
372 assert_eq!(&hash[..], &test.output[..]);
373 assert_eq!(&hash.to_string(), &test.output_str);
374
375 let mut engine = sha512::Hash::engine();
377 for ch in test.input.as_bytes() {
378 engine.input(&[*ch]);
379 }
380 let manual_hash = sha512::Hash::from_engine(engine);
381 assert_eq!(hash, manual_hash);
382 assert_eq!(hash.to_byte_array()[..].as_ref(), test.output.as_slice());
383 }
384 }
385
386 #[cfg(feature = "serde")]
387 #[test]
388 fn sha512_serde() {
389 use serde_test::{assert_tokens, Configure, Token};
390
391 use crate::{sha512, Hash};
392
393 #[rustfmt::skip]
394 static HASH_BYTES: [u8; 64] = [
395 0x8b, 0x41, 0xe1, 0xb7, 0x8a, 0xd1, 0x15, 0x21,
396 0x11, 0x3c, 0x52, 0xff, 0x18, 0x2a, 0x1b, 0x8e,
397 0x0a, 0x19, 0x57, 0x54, 0xaa, 0x52, 0x7f, 0xcd,
398 0x00, 0xa4, 0x11, 0x62, 0x0b, 0x46, 0xf2, 0x0f,
399 0xff, 0xfb, 0x80, 0x88, 0xcc, 0xf8, 0x54, 0x97,
400 0x12, 0x1a, 0xd4, 0x49, 0x9e, 0x08, 0x45, 0xb8,
401 0x76, 0xf6, 0xdd, 0x66, 0x40, 0x08, 0x8a, 0x2f,
402 0x0b, 0x2d, 0x8a, 0x60, 0x0b, 0xdf, 0x4c, 0x0c,
403 ];
404
405 let hash = sha512::Hash::from_slice(&HASH_BYTES).expect("right number of bytes");
406 assert_tokens(&hash.compact(), &[Token::BorrowedBytes(&HASH_BYTES[..])]);
407 assert_tokens(
408 &hash.readable(),
409 &[Token::Str(
410 "8b41e1b78ad11521113c52ff182a1b8e0a195754aa527fcd00a411620b46f20f\
411 fffb8088ccf85497121ad4499e0845b876f6dd6640088a2f0b2d8a600bdf4c0c",
412 )],
413 );
414 }
415}
416
417#[cfg(bench)]
418mod benches {
419 use test::Bencher;
420
421 use crate::{sha512, Hash, HashEngine};
422
423 #[bench]
424 pub fn sha512_10(bh: &mut Bencher) {
425 let mut engine = sha512::Hash::engine();
426 let bytes = [1u8; 10];
427 bh.iter(|| {
428 engine.input(&bytes);
429 });
430 bh.bytes = bytes.len() as u64;
431 }
432
433 #[bench]
434 pub fn sha512_1k(bh: &mut Bencher) {
435 let mut engine = sha512::Hash::engine();
436 let bytes = [1u8; 1024];
437 bh.iter(|| {
438 engine.input(&bytes);
439 });
440 bh.bytes = bytes.len() as u64;
441 }
442
443 #[bench]
444 pub fn sha512_64k(bh: &mut Bencher) {
445 let mut engine = sha512::Hash::engine();
446 let bytes = [1u8; 65536];
447 bh.iter(|| {
448 engine.input(&bytes);
449 });
450 bh.bytes = bytes.len() as u64;
451 }
452}