Skip to main content

crypto/sha2/
sha384.rs

1use super::sha512::process_block_scalar;
2#[cfg(target_arch = "x86_64")]
3use super::sha512_amd64;
4#[cfg(target_arch = "aarch64")]
5use super::sha512_arm64;
6use crate::{Bytes, Hash, Hasher};
7
8/// SHA-384 hash function (FIPS 180-4).
9///
10/// SHA-384 is identical to SHA-512 but with a distinct initialization vector
11/// and output truncated to 48 bytes (384 bits).
12///
13/// SHA-384 is provided only for TLS 1.3 support, users should prefer [`super::Sha512`].
14///
15/// # One-shot API
16///
17/// ```ignore
18/// use crypto::{Hasher, sha2::Sha384};
19///
20/// let hash = Sha384::hash(b"hello world");
21/// ```
22///
23/// # Incremental API
24///
25/// ```ignore
26/// use crypto::{Hasher, sha2::Sha384};
27///
28/// let mut hasher = Sha384::new();
29/// hasher.update(b"hello ");
30/// hasher.update(b"world");
31/// let hash = hasher.sum();
32/// ```
33#[derive(Clone)]
34#[cfg_attr(feature = "zeroize", derive(zeroize::Zeroize, zeroize::ZeroizeOnDrop))]
35pub struct Sha384 {
36    state: [u64; 8],
37    buffer: [u8; 128],
38    buffer_len: usize,
39    total_len: u128,
40}
41
42impl Hasher for Sha384 {
43    const BLOCK_SIZE: usize = 128;
44    const OUTPUT_SIZE: usize = 48;
45
46    #[inline]
47    fn new() -> Self {
48        return Sha384 {
49            state: [
50                0xcbbb9d5dc1059ed8,
51                0x629a292a367cd507,
52                0x9159015a3070dd17,
53                0x152fecd8f70e5939,
54                0x67332667ffc00b31,
55                0x8eb44a8768581511,
56                0xdb0c2e0d64f98fa7,
57                0x47b5481dbefa4fa4,
58            ],
59            buffer: [0u8; 128],
60            buffer_len: 0,
61            total_len: 0,
62        };
63    }
64
65    #[inline]
66    fn update(&mut self, mut data: &[u8]) {
67        self.total_len = self.total_len.wrapping_add(data.len() as u128);
68
69        if self.buffer_len > 0 {
70            let to_fill = (128 - self.buffer_len).min(data.len());
71            self.buffer[self.buffer_len..self.buffer_len + to_fill].copy_from_slice(&data[..to_fill]);
72            self.buffer_len += to_fill;
73            data = &data[to_fill..];
74
75            if self.buffer_len == 128 {
76                process_block(&mut self.state, &self.buffer);
77                self.buffer_len = 0;
78            }
79        }
80
81        let mut chunks = data.chunks_exact(128);
82        for chunk in &mut chunks {
83            process_block(&mut self.state, chunk.try_into().unwrap());
84        }
85
86        let remainder = chunks.remainder();
87        if !remainder.is_empty() {
88            self.buffer[..remainder.len()].copy_from_slice(remainder);
89            self.buffer_len = remainder.len();
90        }
91    }
92
93    #[inline]
94    fn sum(mut self) -> Hash {
95        let bit_len = self.total_len.wrapping_mul(8);
96
97        let mut tail = [0u8; 256];
98        tail[..self.buffer_len].copy_from_slice(&self.buffer[..self.buffer_len]);
99        tail[self.buffer_len] = 0x80;
100
101        let padding_len = if self.buffer_len < 112 {
102            112 - self.buffer_len
103        } else {
104            240 - self.buffer_len
105        };
106
107        let length_offset = self.buffer_len + padding_len;
108        tail[length_offset..length_offset + 16].copy_from_slice(&bit_len.to_be_bytes());
109
110        let total_tail_len = length_offset + 16;
111        for chunk in tail[..total_tail_len].chunks_exact(128) {
112            process_block(&mut self.state, chunk.try_into().unwrap());
113        }
114
115        let mut hash = Bytes::<64>::new();
116        for word in self.state.iter().take(6) {
117            hash.append(&word.to_be_bytes());
118        }
119
120        return Hash(hash);
121    }
122}
123
124#[inline(always)]
125#[allow(unreachable_code)]
126fn process_block(state: &mut [u64; 8], block: &[u8; 128]) {
127    #[cfg(target_arch = "x86_64")]
128    {
129        if sha512_amd64::process_block_if_supported(state, block) {
130            return;
131        }
132    }
133
134    #[cfg(target_arch = "aarch64")]
135    {
136        unsafe {
137            sha512_arm64::process_block(state, block);
138        }
139        return;
140    }
141
142    process_block_scalar(state, block);
143}
144
145#[cfg(test)]
146mod tests {
147    use super::Sha384;
148    use crate::Hasher;
149
150    fn vectors_sha384() -> Vec<(Vec<u8>, [u8; 48])> {
151        vec![
152            (
153                b"".to_vec(),
154                hex::decode_array::<48>(b"38b060a751ac96384cd9327eb1b1e36a21fdb71114be07434c0cc7bf63f6e1da274edebfe76f65fbd51ad2f14898b95b").unwrap(),
155            ),
156            (
157                b"a".to_vec(),
158                hex::decode_array::<48>(b"54a59b9f22b0b80880d8427e548b7c23abd873486e1f035dce9cd697e85175033caa88e6d57bc35efae0b5afd3145f31").unwrap(),
159            ),
160            (
161                b"abc".to_vec(),
162                hex::decode_array::<48>(b"cb00753f45a35e8bb5a03d699ac65007272c32ab0eded1631a8b605a43ff5bed8086072ba1e7cc2358baeca134c825a7").unwrap(),
163            ),
164            (
165                b"message digest".to_vec(),
166                hex::decode_array::<48>(b"473ed35167ec1f5d8e550368a3db39be54639f828868e9454c239fc8b52e3c61dbd0d8b4de1390c256dcbb5d5fd99cd5").unwrap(),
167            ),
168            (
169                b"abcdefghijklmnopqrstuvwxyz".to_vec(),
170                hex::decode_array::<48>(b"feb67349df3db6f5924815d6c3dc133f091809213731fe5c7b5f4999e463479ff2877f5f2936fa63bb43784b12f3ebb4").unwrap(),
171            ),
172            (
173                b"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789".to_vec(),
174                hex::decode_array::<48>(b"1761336e3f7cbfe51deb137f026f89e01a448e3b1fafa64039c1464ee8732f11a5341a6f41e0c202294736ed64db1a84").unwrap(),
175            ),
176            (
177                b"12345678901234567890123456789012345678901234567890123456789012345678901234567890"
178                    .to_vec(),
179                hex::decode_array::<48>(b"b12932b0627d1c060942f5447764155655bd4da0c9afa6dd9b9ef53129af1b8fb0195996d2de9ca0df9d821ffee67026").unwrap(),
180            ),
181            (
182                b"abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq".to_vec(),
183                hex::decode_array::<48>(b"3391fdddfc8dc7393707a65b1b4709397cf8b1d162af05abfe8f450de5f36bc6b0455a8520bc4e6f5fe95b1fe3c8452b").unwrap(),
184            ),
185            (
186                b"abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu"
187                    .to_vec(),
188                hex::decode_array::<48>(b"09330c33f71147e83d192fc782cd1b4753111b173b3b05d22fa08086e3b0f712fcc7c71a557e2db966c3e9fa91746039").unwrap(),
189            ),
190            (
191                vec![b'a'; 1_000_000],
192                hex::decode_array::<48>(b"9d0e1809716474cb086e834e310a4a1ced149e9c00f248527972cec5704c2a5b07b8b3dc38ecc4ebae97ddd87f3d8985").unwrap(),
193            ),
194        ]
195    }
196
197    #[test]
198    fn known_vectors_single_update() {
199        for (input, expected) in vectors_sha384() {
200            let mut hasher = Sha384::new();
201            hasher.update(&input);
202            let digest = hasher.sum();
203            assert_eq!(digest.as_ref(), expected);
204        }
205    }
206
207    #[test]
208    fn known_vectors_incremental() {
209        for (bytes, expected) in vectors_sha384() {
210            let mut hasher = Sha384::new();
211            for chunk in bytes.chunks(5) {
212                hasher.update(chunk);
213            }
214            let digest = hasher.sum();
215            assert_eq!(digest.as_ref(), expected);
216        }
217    }
218
219    #[test]
220    fn block_boundary_lengths() {
221        for len in [111usize, 112, 113, 127, 128, 129, 255, 256, 257] {
222            let input = vec![b'a'; len];
223
224            let mut whole = Sha384::new();
225            whole.update(&input);
226            let whole_sum = whole.sum();
227
228            let mut split = Sha384::new();
229            for chunk in input.chunks(11) {
230                split.update(chunk);
231            }
232            let split_sum = split.sum();
233
234            assert_eq!(whole_sum.as_ref(), split_sum.as_ref());
235        }
236    }
237
238    #[test]
239    fn sha384_generated_vectors() {
240        let test_cases: &[(&str, &str)] = &[
241            (
242                "e0c86be8b36dcaf990030f138e8dc6b8cdd2cc7e2bea08abb44ba72b2145b0cb01be4598456dde48b5d0",
243                "7d11ba1c29e567eae7449a2793a5965c9d4808cc618fd1055f2dd66a5d2d90fa7aeda6679702a8c0d87a2cf7fdfd0eaa",
244            ),
245            (
246                "a64f9629603789f5e8065d7b3cc0fff5606ff07ac832fe6a35f4313f2806eaa9d964d8f82ad0ae65f4c1a97fba787aa1571216f50836abd386d3258a9d9bc8",
247                "5d0fe5a43e6b789c4a2b8a11ae489c3db4c0c3f81d72e1a4bdada7ca1027daca249a84603287453bb5b179cab316edb4",
248            ),
249            (
250                "3a8eb71f82407273a35b725937d24b446cd1267c1646",
251                "7917a9485cdfb2d20145e5e46a0e7367815c6725c840f5c36117c33df0adbdf098abc92f7140552af458121a571d641b",
252            ),
253            (
254                "469a8a2dd0e0ef9292874c9077276073",
255                "528b97b621336b33831a7741cd8237cfdb53ed32441aa8179995aa2e08bdbb17309f65c496f0f3f9d512c50e763a0c9f",
256            ),
257            (
258                "3b0acd954e665feb5c870d9eea0221191f4080f2d1d1f3872f322716",
259                "da51a601e9fe6f946a9c2cfe40acb51e09935932ccca0f23d7a3eddbb0ddcd4fd31a7ed467e21f7b4f478090fbd8618f",
260            ),
261            (
262                "e6babd073205da831d670810cf2ee6d462442ad38579739383dd6f5e304583ce",
263                "826fb8047db3e7c2549531bd874c167fa556364b220058058dded144dcb7eebd675c444cb3cf6e21def8b966eb97552c",
264            ),
265            (
266                "5200ed92b4e8ab80a173cf3c573b1c6c034c4df24781772c7f46b1c26b0204e1fbd6400a472f300a",
267                "c821847cb53031ecb786d8a7c856b860315f75ad0a746f71b7ec5568413929327ba72353eb46f4294cfd88427357727a",
268            ),
269            (
270                "06dbf3f418d49dcebf22f5679cb400",
271                "1fcca18e9129fa6180b97926b795a3cb72c6201472282b14a273488b740de316675a7daf0e6ecf376bdeff4fc5f9b709",
272            ),
273            (
274                "3c243121",
275                "4e8274cb0ee451daf788103941bea46dbb544c2b91fdc4ed8a03c1790111ff81f0fbbfc62b0584e19bcf3169f4734b34",
276            ),
277            (
278                "987d5772aa8c2afc0c832e5bea8d43b9a52cd53febaeb2836212677cefba",
279                "c72819682a2ff16afbbd5d15cf66728aaff524c69255f4d85b821c67f523df654d283379a8548f27e91e1c8fcfa8a769",
280            ),
281            (
282                "4063edf941da1bde21192455b847b7ac6512467487be",
283                "a09e84c3b558e2d8c32a91ca865d11dd6b755b903d6f92e238123c3ddbf52cb1bc92550999b728127fdf69a7418eeae7",
284            ),
285            (
286                "b79e43c36fcb7b89bd37db0722221c77bd36e428cb3b7d808c2abfd4311f194a6fc770c20c387129975bb993609fbc6c698c78ae",
287                "5661bc63721b66fb9a2e71cde4015650c99af8e586a596e910144542bc305b0333d9d59cfc364108e5d917e57077e648",
288            ),
289            (
290                "a8607f13fa39c4a5d10abcf30a81c7fc154f3c651566aebeb952c1c7e089e3",
291                "d9bc8e36d3f482aab1b58f3aff007de7047df5ff9173d7d2cab8802dae8741c0a2ae636d341f088c5ce644259b2086bd",
292            ),
293            (
294                "8dc668d568ff75af55d65adc7a50017d3d550a42682902b5c2724e2d9506e29420",
295                "7a318177db70ff79b4cdcbfc956e69b7d4c148c633f75134305bb106de863929be1ac3956bdbd05011fd5808a52cb578",
296            ),
297            (
298                "7c6aef47f9354fb6d48b940a44",
299                "c2e998245f8d24dff3dfc3d08bc7b151deeedd76f605851ac83dcb7647dcc82f26e758cf8e54091dee9b90a6f70f4c63",
300            ),
301            (
302                "cb475978cdf5080ff76f54652d27980736f0edcc619713111c47e2ed6dca79819b8e7b56b567ba0b",
303                "8a562ec8effde193bac7909afd9fba0b6e7479670f31ad335d083e3a4407ed38bc2aa9635b53fecf0f421f300087ddda",
304            ),
305            (
306                "5474a866489959eab74ff8c98923266ba5570658aa0a9068223fecad9ad192944118e4273948642c4a4c22e22fa9410a7eaf227c790d",
307                "7b559f9f7659b5269d712b5c5aa8a9bd23c27fc63fd0f9794b26d3af9b4613077c48c4d8dc5f2145a9fba4fdeedd9c60",
308            ),
309            (
310                "9d0fb8c7b6aeda0623eb0d190c56fa37baab0026689aed5e7dbeafdf2cec0ac8bbdc113c34242e2cc996b48b39",
311                "251d006760791ef8e018359f01663f8bfd5d41b7b0d8971160d49d0f726a3d7706049d36ceb3a00be79c837fb95978a5",
312            ),
313            (
314                "5d98a392cb6ae460af849f3b21368c3befc1647af0ec3156a80d847ca94b76c38cfd92fbdce0f45d66e325a7caecf363be86",
315                "d25976cc5b13502257f45a9708a54fe08bd97f2361bfbed4e895b16245d977b295327b356c51e212b9a4396e23a5a647",
316            ),
317            (
318                "29f129c35b0e411f",
319                "914ae1f26d9a590dbbeee0d0a52ee9644014785d58c5d5137936d4a1282c921dc1a56f35301a80a3e5b2ccd5ab51e3c0",
320            ),
321            (
322                "cf79abfc3bf3831ef5df5629ca57f88d9ce202e3c367ca58d34086cea5165b5e1ce44004fb38462b9098686073160e5b",
323                "c6c64d2dad9c551151744d7c3c95c039e4897c1dfdc54d2b71464982ce5a667fe0b6e3bc123a765dabbb46d305a7f6d4",
324            ),
325            (
326                "55b5a6fd17628e539174fee3eaa0ea9d82517f8be86b03979389805117b9601c",
327                "a343eba6f5f0ea5d5009d26280c625b2c619c5a0960251ae9f18800d873a2f0952b0092bfef0955fdb2ed955f216183c",
328            ),
329            (
330                "b131bbd5a0ed1d7ebaa62700166518e18b5c6196f35940cf01f3a9098d5ac30c714a5b1d879bc8d69a8327",
331                "00bd33548c5baaf82eee69f283203d4d9bc198047fed9893d62ae845b159e8cb67a20933f23f71cf7a4dd9ce43b52c58",
332            ),
333            (
334                "dd6f1f73a7cd8c0f87cba02c197deb790dd5486aff91debb",
335                "c98de06a2b633d493bdaf98c653acf256f2b85772d3327b04496a4e224dbc0e5880e3160c348c1bfa977fc0d3c635e2c",
336            ),
337            (
338                "2774d0cb5a85b3313b0f",
339                "3a9b4d39e686233355f4752947eca23b4b9b54651c3d664bdeb99a04aca920def4f3f908e717763870b64e69eb70bb74",
340            ),
341            (
342                "7e9e2637e7638efe6ed9d3517e22603698255211d6b4ba",
343                "aff5b3e27b1a5d6708c9422991851863ac30d001508e6ac375123b710216bee41d8087511b6afb0c9f9bfb22fb34b35f",
344            ),
345            (
346                "574e",
347                "d5be731e7057d65388d062445d2f6eb1e2cf365bbcb5c174cf1d970ffd06b4c3e6f9c6103faa05c914950205e0e73122",
348            ),
349            (
350                "6342691cf9819f",
351                "17aab1165b438ebbf48a648ff074e90a8e3b1bdcf4b592e8b2d3af22f8f1c14f914be1b8a3e1f7243c0ad21fbf5be4fb",
352            ),
353            (
354                "a4ed28df5afc",
355                "d0f431ca5a09179c0b7f851fe9d64950385e4118574a6bc29f0c2d4262271a2641523ff9665aeccf7c366ca02a16cd5f",
356            ),
357            (
358                "6a625b8c352ca8100506db548928df961b478dfe388f",
359                "1ec2a50d49109a0a51a1eda1d3069633ed9d090fb7ab7ab0e89c84ab99ca2d80e95ffee73a4ca9dc1deee3d41597fda6",
360            ),
361            (
362                "9525e0bc7b581b40bab093e3b5162345d0d722c530fb2ffcd9c962d0a97dc106084a1ed8539a232f7701511f419cb9338cde4201071a502d6a51c78c",
363                "be1892c642690942fa5fa849bea06718d4ca45dcb737563faa818ca57e253ae4444079383103f1141a3cc76f21576081",
364            ),
365            (
366                "bbe2e9342f7b0baa0242e98bbf5b1ba4c20d51ef1f7ed90baa12b78c9ff41d2c7d878d5fa0515c2a22",
367                "e2f6a42324fc4a44485a909f29fc32b79ca4a66de6e1e8dd2a005895d21bb7f6f13551f9088e9e524723c880f094c04d",
368            ),
369            (
370                "cbf7b99de261967bf5f379ee69904de5585c64",
371                "af99fc0dce899135e57fbee1b65a442d374e4f10cb81e96ac71ddc0cbb66903201b79f2bc368b3e3fe737c8220fd0669",
372            ),
373            (
374                "71419b5c02e5d59ac94c9b6d16d2df6f",
375                "1a40a15a448b0d7102905ea9591c0088c530287917b3f0bc73bc6b0ee20311c819a4cd779208ce534c5175b668e78294",
376            ),
377            (
378                "435daa4e",
379                "b06d05a9d2aeb21a50d7756773224b2482b8faa8e7986d5a12081e21cb68f6215c9302a42ff5afaba6a590b951e74045",
380            ),
381            (
382                "34e5cb8d2813e0b79853f1cfe2cd32643209dd51481c0b87860c3cfb519000edad0180109f",
383                "75298bdda0ee189a2a0e65aa1744cc921ec827093d56e83d12aeb1b746336ce7aea4c67c79d96de23e80b3791a499790",
384            ),
385            (
386                "6039de86509cf3d1d62654e502ac68467a43a413b0d647b1feaf01833e8d95a26e79810c15c7",
387                "70d3fd58264cdbb0c3c368e7546f9c6db5cc71cc48073184d5a4669e2b9f4e344835065ad8b95a9235bdba439c63d099",
388            ),
389            (
390                "00945f34019772b167672c148804dd569fcc30d1ad388f331fcc338e361b3a2c7308b1",
391                "def314975b7d7f1d056a40021705a82d28ca7e77ddbb432a1d76305e4fc58ce7ba6ec13cb8194b01e26a239cfb88279a",
392            ),
393            (
394                "86537dbb277a050a36449eb0195d39987af918ad185da233952d9c71284c5c92eb7bb6d0ad72d393ac6a34a03b395afcc10040688c2cb110c44dd119",
395                "cf76ae83dce62363bc9b19c6849407500dbdc590bfa741668ffbf6308eef94cbf0dafcdb79876cde553cc1499f841d46",
396            ),
397            (
398                "eb3c330346ea454fcad8832def54ea5d931dcdc5a3eb76dc5ef11d",
399                "6116b29455b37a6fd971644516e0d039afaacb5155534f350743b28bb3a4a21e49c916486dc6db76cf013c6645ee6ece",
400            ),
401            (
402                "4dc3e8ef5d0aa78160",
403                "92e1c0b03b965fb8e00fec9a106458d505622ec104b9b59316ea82263d76415675fd98633b03d0fd7b03bd4f646c1cd8",
404            ),
405            (
406                "b30b23b6cd6eaca5c72339214c2269c50902ad80db8a67594f882deb",
407                "9e502ca664d74d63a784d33ec776093f5eaded5c29441e5ef003fe0ee590099fe693b93df74a20647bb3c7d740064c2d",
408            ),
409            (
410                "7b",
411                "95ed401953c1d4c284ee689b77a75356c6b92a4095bace5f611aace86c4dc41925fdcf00ce4185354fdbb47d84be3d35",
412            ),
413            (
414                "0c73660105e48707b1754fef814a6c",
415                "d4366e94ec3b5c81afc2c7f02bc0297dc6b1b6cbfb1b7db76b56d9e3b945bf4b06dc262726639e4cdfe5e137bf7cc497",
416            ),
417            (
418                "809e4462475d8dd3a299b2e55a785c263a1ee5c0c745beef1a",
419                "dd37ce3ec7250702d2e977c43590ce1ff16b93ac24796e5fc9cf92c790d2c67c344ef10fedce0484150d03d7166e51b6",
420            ),
421            (
422                "32480a0732cefb5b55398eeb2c",
423                "561c142413041fcbf885d6f6bbfc940559dca0ced64aa71a137742947954a1f346eb336d238eb1e2294788dca69a13bd",
424            ),
425            (
426                "8dd0edd059c3",
427                "0089e8fa7b38a2f4f9e92770eafa27879e3c3f6cf76aba93ab2728d5370233f81ed5e66a44c32981068ccfcb13d62d01",
428            ),
429            (
430                "6c1e61d22f6e9a447b8c5a4dc942862f60afd6d57b5c5320722a86d5881f4ed1820b6bde29547dab330546443ad97d24341128",
431                "e2d9ddc9f8a4fbe6252062b391321e05476b51e71bcd6422a7d11eb53f22fc31ec3f35a8ad7d5b4e60f758e86b4f16dd",
432            ),
433            (
434                "f53f1a4484d379c37b6e5afc058583ba8e6219775441e5d443455c7481a4d470731bd57a4542b0",
435                "b19abebafb0b761b414d8982feb0335d4b1e891258d3d4b21f7421f018b5f1e8cc5f4fca3eec5b6ca4dd7358c1f0b913",
436            ),
437            (
438                "1e78f1e8fbe4acc647b61825865556cfc0c93ca31783673a23d9314f6beda45505c1d6e2211ded0d3696a0c2c96c64da8ebc045250b2fa722a4340fb28b3",
439                "ed03861e9c1ef4d5069d0178ddb90c09a7f8be77dc93bdabc963be2937a3a18f69fca41e087251386353868d83a9c55d",
440            ),
441            (
442                "73cb9f33074abbc9dad9f3db1314f6175027dc1f55349143dde32c00952a67c2a92f8b7262f8a4a8cbce834b8fc8ba8d880f8404c69b50c9b034142ba0da9039",
443                "d7c0b97cdcb713245ff708fdfad811dca4bb1c392e727106404728aa8f60d5129489030b02bf2146cc5ae44e658706e5",
444            ),
445            (
446                "58bf3192b76c22265c903d3722a9a3f642b3a7c8",
447                "be5b4c09441418e51a30d04a513da8566f3762cda9f35fadfe50e37138890d615a27dbc484d7c4ebd5b5d65051e46ce5",
448            ),
449            (
450                "7af57a131341a654ab76e94ff89bfbc99a5f823df4477efc3d6fe751b4",
451                "e9278d958b13dec8fee7ec63a31a80f5007ef7e82000157b4dc9be86bc536206702a595f3a35c7f3d4c32140183b88e7",
452            ),
453            (
454                "962652236b4b3bebe15b2328",
455                "20a9d35c31dae35c78b5a78c152199270a00ed38408e3a610480241a9d9289354a9be6b6987c8469aeb6db36663f719e",
456            ),
457            (
458                "66e9f3ac085177b2b5b852d4a8e055297107380afbb73df3fccdd96866224cddad897973e354812ff147d3d77a",
459                "fd381a1aec5afb531988698c49934de9a0f4c47f6d9b2db13a9eeeeac8faabf98d908d34fcf87885d4432b0790b0466f",
460            ),
461            (
462                "773b743be9ddbb78114b747d18ea",
463                "637843ffa5acaf2555b1cd17851abf5abfb9e3c425df755585b993b0cf1ead7c75c15c0090c8a73d3e25ff073ed2ed4d",
464            ),
465            (
466                "5fbfdf85de807283a5b224e7c8e5946372e4d56d7099c0b5d964be9901303d30e388a6f2b37e975763c5f7afa9356acb229bc2cb21ae2588d2f7eadcd77e4eea",
467                "887ff96fe1bf8c5a99ddd886b54c91c01cd419518d0defe462b3ed60d5364e899b6fa5b4a539f1f6f43860a7073b2ed1",
468            ),
469            (
470                "7db87dfa33a1832437b03a9df22be62c575cb7571eb308ed",
471                "e545cf08a0c4794765edd37cee31d01a1b4f7dc89b24656ed813fd4bd13d7398bf0c2c2a73a87d723a355f5db55ccbaa",
472            ),
473            (
474                "9e9e3798129da97927a0bfd351dd1bdf86093046d69c14683aae240fa297334f3d122a6dd5a01b0efc635806cd969d194fd8862b1a5b",
475                "5a66b233896a5ed12e566a43082a7a402f2324e321040719b9caa76483ea806946c52cf3f1ef36a1bc9dba308c9a5abd",
476            ),
477            (
478                "ebee3aaf36148e74bc4aebd56366791e7dba",
479                "841a5b5159c64e4649f7b50dfc2c4be8db7071b8db862b3ae876357d102bb7c4a3fc64d356c50d01dbcb959e357aca63",
480            ),
481            (
482                "7cee9290a53731e1535f8066f1b1fcde6644994419ebd7a9",
483                "86578f6ae8d3b6fde8dfef676fffe5775fcbbcf235af27a1ee9023c2769a37c0432048006fac2b88d95bd46e15d41217",
484            ),
485            (
486                "28120c8bf844e9e6",
487                "ace3951cb8c6bd47e71bcabb2dede9e56d779d0faeb8bfd4e6ee176f7286702237fba74b4b1763acd180706e0e247f48",
488            ),
489            (
490                "a37220a20f2abe0b5cfdd3c920ac1548be306cfa",
491                "25a84d7f8d0556ef7b18193d9487adf79b620b6e9714efd7dfaa8897d07e54c0b00ee2faee2f538c5913804f4e597290",
492            ),
493            (
494                "697cedd1c68f3f97cfe9eb58f48763fa",
495                "7a5ff69c23cbe0f2beaf10f03a5a7c8e5b8c86492a57befc71068ebfbbf4c0a81b43b2c87fe2ea27ba5f481c6d373303",
496            ),
497            (
498                "481d2728df022dc759ed4e6b2b434a8eee75adb3aa2110",
499                "a2501112baf6cb0bb9650af9b887b881d43630e00cecbd8039f3f429dfe17be50f47525bdd2043b9b2148417f7264309",
500            ),
501            (
502                "f1df8ec7aa",
503                "f9e3e6d050ac88827414170fd03d75e5544871ea376236cd3f5dce946c1c30c02d0e79f024da8c8be0d036fb32e5d549",
504            ),
505            (
506                "47f6f4646c11e634dcd703a00a0d8320381ed9825308b64832270134a852ccad071454c42459daa3d3f63054a61b103a",
507                "01a2ecc83977530134db678e0fe1e3a2b29736632a27f925988906ddec13e2960844e9b3ea21235a1fe7a119c1a7405b",
508            ),
509            (
510                "2dc855f63f4784d34d026254f7cc79b9ca8aa9f649900cda38d40140",
511                "7d74ff17e66781ed63bcc8cddd443c70fd2b8e9bce1ddb463d4f53f9a3ad0aff22a20e40babf6655bd539d23743c3f7f",
512            ),
513            (
514                "a16f173d483cb373bbcba672857e9989fd7316378dfdc19015009c8d78761d361d76f4c5835babcfd1e36f6e8c95b96bba17587f059eff7dd5",
515                "e9ce6872f0d7bceb5348676f1a6480378fac87e37fa3e79c7640604f25ffe8e4205397a229f53435520461d2d2229a95",
516            ),
517            (
518                "e6510eccc564d3d4cd73cc208272ece49a26e67f5dfecd6001a10de0c7f54c21e6b13f6b287ecb8adcec",
519                "ff9fb5f4d74be8fff73e1b42c2daa27d33e37798329a3e82e004d0dbeea5bc4ee8ad511a0372aee34d7f37b11b05663e",
520            ),
521            (
522                "4a5e89554109aafc3892e70b08a68ce09c1e4a0292798a3e519cb9",
523                "d8bfa901bd0403409676e13651726055faff98492b7110c800e08771c90f1045a68a9f336f94f0fa82acb10a851fabff",
524            ),
525            (
526                "fe833fe13255b555718ccce8515a14aa8e626aa4aef586aa493036ae89dae7436ecb6fe4064ce010f5b7869f32",
527                "4a36ec50870b0865d794da0380e8b02f9212c75be51ba3720505b6a5a65c8e8a37342c8adb14a6750bafa8d2429716be",
528            ),
529            (
530                "0291c756ed8679a6ee7fd8ea2eadd3a3f385aa57",
531                "4e491d4681edaceac78a7c5cc7da80ffeaec12e99af3a8293f92a1ffc96561dad65a6b53c1573240e67318fe9f0d0915",
532            ),
533            (
534                "8a75cbd5d73d75c7b6c55bc62bc55f7444dbd28d22d3df20453bc2ad8d0190220fc17aac2e6c06f4",
535                "0f671b9c234b9b5358ce5c689054ecfd48e375ca2d4f2e93097b516d6c4c9c6aadf302669d07b68a42719593ae1a07fd",
536            ),
537            (
538                "326e51b0a90f4f82eb0877e14d2a45d06c2876e1a2ce6faef7c2ac1cb50d5615fe2788",
539                "3ae5102f7b15397aedd9642def10fe9dfeedfc0029077efbab160121afc5b2199bd276a33c913579b85a1a8b6c3924bc",
540            ),
541            (
542                "d400b941ed7ee9d2a1617f7fd2fcbdb947d8d84391906339a26aefb6b493dbdfcdf53e35aca20fa611d452cc86c726",
543                "2a685c4066c9df23989607000eb5053ccb56b08a37cf862584440a1c3f59e648ae10f6932259de8aa4824dab69e13909",
544            ),
545            (
546                "f16eecba457162d015703f61b8597cb89332c743dd79e9a95db881158e599b6d6d022f19d7ab67c5c62279833de3",
547                "9deabf02777ef259a84c8216a8420299e7b5bf227bd4acdd98a15c071ce03511226926a0c23f7dd23144b596ad544894",
548            ),
549            (
550                "e0a0f3320cf6976bee604773c276384293f0e3adf556a8036d542a70095322e8edfc",
551                "e0e5632432477d3dd7dd1bc9083689231625adf622df282787ad1bb5e8a34e40d37107a5a4c19598b583d18e7811d2de",
552            ),
553            (
554                "5a43dd1a51e7444ba0c10f5f865fc6192be4a82e2c642fc7107aa9",
555                "2d69d371e51bf38df2f3415d7b769a867ce095808668de1ac634dd99efe820089d7208fe4e8a9b86c26bfa431b91bdb1",
556            ),
557            (
558                "ad5a02d372fb2aa1889d96e67965b42bdfa9762fdafc3319f573fddec6db9b8ff486b3c74860bd7f4a0d1c90a0bcb7d6039a45651dc850a53b20a285e7",
559                "061b7c9e90c948d247dc03b6455cac89added4ecfe0441f81f405fa778c492a7a318aa8d50a49794aaa77e4cc090dfc8",
560            ),
561            (
562                "d7050b5f94b275afb87e315e70905ce87cda9004c585dae55354d07573ff5de54b9b2fe41b05b3a79fc13f93569257b64a",
563                "c759f49502a6688eb07bdf6f1e330ba9c4b2e9a29348cea1c5e55679d0147b9222987b8f849d16af4b288c34708d3206",
564            ),
565            (
566                "4fe5895e4461b073881d443e7a98f2bcd208cfef0147fe43316a862ea080151933a2cb681157c29c4c20",
567                "1105368a53cae360ba045542f99f12bc83f2e7190c6a5cb26cf77509615ad097eee0b42dfd3208e17d800cc1c83e6f5e",
568            ),
569            (
570                "57925245f09efb390a2e480b7caa31ea823098f2ca29369ac3cbffbebd449e0c42f04a80fadfca7b3263",
571                "a5eb1dad95e527aa3c3a80b1c7503b8dc6bab48136d7493a0fab967d1a8654562b6d1bc43b0e4b5020b023793e973e8b",
572            ),
573            (
574                "cad76754d4054910f04ee80f25469e3bf44d1cd372b8a6b448cf3b7b8264be313355bb40c586b6cdb7602e12ce34c0198a208693a04066c8ff2fe869c27b9f90",
575                "1c443de9078a3f2a7232fc7209151694049f050b8db3778f64d2cbf1de5eadd20a5cb862e2c8f1b3fc62fe48bff679f2",
576            ),
577            (
578                "c28ca4cfef32fcf86c4fcf271ad3629901a1575e9b718bf4d2b9e6c82d12375f5b6955b85b87011d445cf1b9163bd8bcdf0058605dda",
579                "9a7e0607f60f3ec5de56c7cf1358585cbd9de40a9f0d09a5c352bdbbc6687f28160355a7845a0564bca568d5ab04d948",
580            ),
581            (
582                "a86371a54784d45cedeb76149accc7b43f3e23459f8d7be8075c2440e12078b35dcf112665fc",
583                "504b80c08f46474113e5cb9c1f7f7533ec34120ac140bd92b65e5d7b02559056e83797943c262b4975273d0af5164cec",
584            ),
585            (
586                "6e702c9f408d0bc9ca239f94a41054fbd63f717fab59ec012ff8de6d3fd91c48e626b5877b8c8487b45614bd5259ea763890ffc16548ce3cf2ea641d2528bf",
587                "9c8213ffa753dad5cf3f25523ca06059deab42912bde3765e0a5766d9e121ea3f0f7f8090af19837efc9e23a9a54db2b",
588            ),
589            (
590                "dd6be36d77423a83c8b53713575b684d8c2b66",
591                "6db8449d663614a9f317c58208089180a6fbfe172e8c10f54519c02513e948513dfe47484a9e61135dd5046586c23caa",
592            ),
593            (
594                "2901bca38a397df5c444f230a61bc1f2ffda07f375a8202d8ed02ebf17ad604e8e199a7c1a7ae4df8bd6542fc821ef8abd33778bf7",
595                "606faedad8aed4e58085294795b86e488b78319ab88cb1776129d35b5f7526b0564633d34bf3aa3458e74473f15e0ead",
596            ),
597            (
598                "c26c0b70740c00ea2d664690ef01f669cd6c9e31fc2e7e5f967880edbf1883b928bf00fdd9c3b940495a62591b497e75",
599                "ca2a82eb6b5d4b891ad0c613df8ab31f4b3b705689d3e00c3e0dfba019bfcfe6f0caf4207250642b81ca1af73e9f74cd",
600            ),
601            (
602                "d56dd5ef31d54d7c94db62561f1cce670b2f579cf0e9facd30",
603                "3aeccee4f1bb894661d13103b5230066268e061fe1fb163abd6f5171cb0b68c494a8230cb4f4824addcea4182b5cd0bd",
604            ),
605            (
606                "b7ba8bf3b6c164ca9ea4c98ba51d9e56efaab28942e45c9ad36715bdce672f2b896e9db2ce634d",
607                "f20e15cf8bb5d0f6899787b8549fcb03ad64a0ceac93664cdfe060b9ef1dac039ad5335c5482fad9c1d878ed1581fa4c",
608            ),
609            (
610                "331e4806a5902df8527f73be5822d245dd01803a353dbfd016554a701315f629058074aaa426312114864ca533fe9e465d87206597",
611                "526cc2e958b4f7e039b01d352cd178a7c47aebc55aceb162c648fda7aed3fee31fb7f671d1a86eb5384eb7ac74cc51d2",
612            ),
613            (
614                "5808ae13401d01da61e41f75de6b4a924c72e5b9",
615                "d51d9d14a568a6b56b41b47c351577bd464235830de9ba053cccaa884e0d97f8771ebd3f3f5ab396087c1d541cb60eae",
616            ),
617            (
618                "74fc99cb7d6958db460a2c5645195f385271efcf34e0295c",
619                "bc0ad7339fd4cb24229a13d8d2fd03089e24ab0c707ead689390089fe5627d17d9b8a86ee66f2f4237d323ba950c5543",
620            ),
621            (
622                "e8127e4542d8bc9c5ab4fa30634a84e5cb99efebcaa1636ed1004cfd9fcbd15f691c6a2045428d5058240e7701519fea78bee57c7f3b5222b7cb74",
623                "841aa1a4585ef1a49b60a03ded02f77a3d80f62ae14cac448e8cda8052ee9d11d09a981b89e524b15ed1f02ad75eb884",
624            ),
625            (
626                "163c13fb1234d1ebb197dffa0cf5496dd71e3d47e8af53b12e8338e107c11d667aa53c02de1118a3",
627                "e99af20275bd404df2994b71ec87d166bd31cbf30095d0c1a7c71c4fbbb7b3740e9008d1671a16e86e0e75f744a8633c",
628            ),
629            (
630                "e1bd7ba8fc7cbd6caacaf3ab0928d5d21fd8a7b7a836ba134b0692a26d4c1817b096",
631                "f71bc1e6ae5476a2211c55f718f271618761760cea46c63c7603e7acac68cf0df989e7f0293dca0486489cdd8b5b1f94",
632            ),
633            (
634                "c684a2cd0f407780580a502112aba0d7b57932cce836a7b3eb8ee6fc6f",
635                "7c85ccfb4d8fa89e559d51bafca96ae8df180cdf915fbeeab1b16100b5e48d148e75f106c5542edca4f642fcf2f9b77b",
636            ),
637            (
638                "75a6a944bb7afeb34cc8dd7205215ab9e6c4576af3837f8483381d885d067d0e13",
639                "82772b6f56e61cee0e5d3f423641709b186834c1780cebad861ea990b3edb68e205ced49e909539a57e380dfca9a792a",
640            ),
641            (
642                "a527a8d4bf382f5dfc6425e6ca26",
643                "a44145735a61816a9851d9b1962802d90ebaf6cfe14af1f9af095c0423b5f6a82259ce1e2a9abbc43b150d24ba3d34ce",
644            ),
645            (
646                "0dd9b297ff1aa0",
647                "cba588b8b949fe4297a0b61469108e46be8b8ec7fd66f7289de9d6a333b3bc6bfa123e9dd3054abd7314d714a90529ea",
648            ),
649            (
650                "0691455c3850b54944baf2e7739faa9bf568f5a6462bc37cb6f2ccf7ef3979840c9e06",
651                "895afac790deae53a958c9d2b12a80b4f12e398b921f70efe236faf1459196a0509382cc0838f8da76e349986d63dfd4",
652            ),
653            (
654                "15c202646a2147c98a5803b8619f1978592bc7caa5719e8e1b55eeb7898967e5ef578334",
655                "00457a59ca8f04ffa53b9361ff192fc19dd12b6b8647d0e622d6bb0d80d411dfd2a68130560d535625b4431100b6ed55",
656            ),
657            (
658                "f69e8706e6406b7411036a795078cb197a9ec54c16dde378a87e6aa9e1d9317db06bff6c8b2032b2b3d2e3e358ea5832d793",
659                "3c13b3638d17b3afccaf519c5d4be5259df578b934dcc8c01dfec9ec05e58a9a00c6ca183b10ba9a21a8dcecc9923136",
660            ),
661            (
662                "bbbd9a9cb642dbd12ac0fb4ab063b9d0cfe60a13dfe6",
663                "3264d11df16ba58df020d1a77d0dbce4526cb97cfb868edcf12d66a16b7122e5b33bac68c6eb63241740930f6460fd1a",
664            ),
665            (
666                "d13cdd4e1c83eec3159711055212cf033a8784840116e4680fcf9fa1a8573ac196a10b1bfdb9a6198dabdae036edc28bfa0f6996b34ef3f329a768fa25",
667                "99a14c3eb0a0a18db275f7b7a280c354b8b761f19bb31c5311778368b6686745fa72044b3f3fddecab5c8f08df864d9e",
668            ),
669        ];
670
671        for &(input_hex, expected) in test_cases {
672            let input = hex::decode(input_hex).unwrap();
673            let hash = Sha384::hash(&input);
674            assert_eq!(
675                hash.as_ref(),
676                hex::decode_array::<48>(expected.as_bytes()).unwrap(),
677                "mismatch for input \"{}\"",
678                input_hex
679            );
680        }
681    }
682}