crypto_async_rs/
sha512.rs

1use futures::io::{AsyncRead, AsyncReadExt};
2
3//https://tools.ietf.org/html/rfc6234
4const K: [u64; 80] = [
5    0x428a2f98d728ae22,
6    0x7137449123ef65cd,
7    0xb5c0fbcfec4d3b2f,
8    0xe9b5dba58189dbbc,
9    0x3956c25bf348b538,
10    0x59f111f1b605d019,
11    0x923f82a4af194f9b,
12    0xab1c5ed5da6d8118,
13    0xd807aa98a3030242,
14    0x12835b0145706fbe,
15    0x243185be4ee4b28c,
16    0x550c7dc3d5ffb4e2,
17    0x72be5d74f27b896f,
18    0x80deb1fe3b1696b1,
19    0x9bdc06a725c71235,
20    0xc19bf174cf692694,
21    0xe49b69c19ef14ad2,
22    0xefbe4786384f25e3,
23    0x0fc19dc68b8cd5b5,
24    0x240ca1cc77ac9c65,
25    0x2de92c6f592b0275,
26    0x4a7484aa6ea6e483,
27    0x5cb0a9dcbd41fbd4,
28    0x76f988da831153b5,
29    0x983e5152ee66dfab,
30    0xa831c66d2db43210,
31    0xb00327c898fb213f,
32    0xbf597fc7beef0ee4,
33    0xc6e00bf33da88fc2,
34    0xd5a79147930aa725,
35    0x06ca6351e003826f,
36    0x142929670a0e6e70,
37    0x27b70a8546d22ffc,
38    0x2e1b21385c26c926,
39    0x4d2c6dfc5ac42aed,
40    0x53380d139d95b3df,
41    0x650a73548baf63de,
42    0x766a0abb3c77b2a8,
43    0x81c2c92e47edaee6,
44    0x92722c851482353b,
45    0xa2bfe8a14cf10364,
46    0xa81a664bbc423001,
47    0xc24b8b70d0f89791,
48    0xc76c51a30654be30,
49    0xd192e819d6ef5218,
50    0xd69906245565a910,
51    0xf40e35855771202a,
52    0x106aa07032bbd1b8,
53    0x19a4c116b8d2d0c8,
54    0x1e376c085141ab53,
55    0x2748774cdf8eeb99,
56    0x34b0bcb5e19b48a8,
57    0x391c0cb3c5c95a63,
58    0x4ed8aa4ae3418acb,
59    0x5b9cca4f7763e373,
60    0x682e6ff3d6b2b8a3,
61    0x748f82ee5defb2fc,
62    0x78a5636f43172f60,
63    0x84c87814a1f0ab72,
64    0x8cc702081a6439ec,
65    0x90befffa23631e28,
66    0xa4506cebde82bde9,
67    0xbef9a3f7b2c67915,
68    0xc67178f2e372532b,
69    0xca273eceea26619c,
70    0xd186b8c721c0c207,
71    0xeada7dd6cde0eb1e,
72    0xf57d4f7fee6ed178,
73    0x06f067aa72176fba,
74    0x0a637dc5a2c898a6,
75    0x113f9804bef90dae,
76    0x1b710b35131c471b,
77    0x28db77f523047d84,
78    0x32caab7b40c72493,
79    0x3c9ebe0a15c9bebc,
80    0x431d67c49c100d4c,
81    0x4cc5d4becb3e42b6,
82    0x597f299cfc657e2a,
83    0x5fcb6fab3ad6faec,
84    0x6c44198c4a475817,
85];
86
87const H: [u64; 8] = [
88    0x6a09e667f3bcc908,
89    0xbb67ae8584caa73b,
90    0x3c6ef372fe94f82b,
91    0xa54ff53a5f1d36f1,
92    0x510e527fade682d1,
93    0x9b05688c2b3e6c1f,
94    0x1f83d9abfb41bd6b,
95    0x5be0cd19137e2179,
96];
97
98const ZERO_BUFFER: [u8; 128] = [0; 128];
99
100pub fn encode_core(bytes: &[u8], mut h: [u64; 8]) -> [u64; 8] {
101    let bytes = get_normalized_message_bytes(bytes);
102    //break message into 1024 - bit chunks (128 bytes = 2^7)
103    for chunk_num in 0..(bytes.len() >> 7) {
104        //break chunk into sixteen 64 - bit big - endian words
105        let chunk_start_index = chunk_num << 7;
106        let chunk: &[u8] = &bytes[chunk_start_index..chunk_start_index + 128];
107        let result = process_chunk(chunk, &h);
108        for i in 0..8 {
109            h[i] = h[i].wrapping_add(result[i]);
110        }
111    }
112    h
113}
114
115///begin with the original message of length L bits
116///append a single '1' bit
117///append K '0' bits, where K is the minimum number >= 0 such that L + 1 + K + 128 is a multiple of 1024
118///append L as a 128-bit big-endian integer, making the total post-processed length a multiple of 1024 bits
119fn get_normalized_message_bytes(bytes: &[u8]) -> Vec<u8> {
120    let message_length: usize = bytes.len();
121    let message_bit_length: usize = message_length << 3;
122    let zeros = vec![0; (128 - (message_length + 17) % 128) % 128];
123    let mut result: Vec<u8> = Vec::with_capacity(bytes.len() + zeros.len() + 17);
124    result.extend_from_slice(bytes);
125    result.push(0x80);
126    result.extend_from_slice(&zeros);
127    result.extend_from_slice(&(message_bit_length as u128).to_be_bytes());
128    result
129}
130
131pub fn process_chunk(chunk: &[u8], vars: &[u64]) -> [u64; 8] {
132    let mut chunk_u64 = [0u64; 16];
133    for (i, chunk_bytes) in chunk.chunks_exact(8).enumerate() {
134            let chunk: [u8; 8] = chunk_bytes.try_into().unwrap();
135            chunk_u64[i] = u64::from_be_bytes(chunk);
136    }
137    
138    let mut a: u64 = vars[0];
139    let mut b: u64 = vars[1];
140    let mut c: u64 = vars[2];
141    let mut d: u64 = vars[3];
142    let mut e: u64 = vars[4];
143    let mut f: u64 = vars[5];
144    let mut g: u64 = vars[6];
145    let mut h: u64 = vars[7];
146
147    let mut w: [u64; 80] = [0; 80];
148    w[0..16].copy_from_slice(&chunk_u64);
149
150    for num in 16..80 {
151        let s0 = w[num - 15];
152        let s1 = w[num - 2];
153        
154        let sigma0 = s0.rotate_right(1) ^ s0.rotate_right(8) ^ (s0 >> 7);
155        let sigma1 = s1.rotate_right(19) ^ s1.rotate_right(61) ^ (s1 >> 6);
156
157        w[num] = w[num - 16]
158            .wrapping_add(sigma0)
159            .wrapping_add(w[num - 7])
160            .wrapping_add(sigma1);
161    }
162    for num in 0..80 {
163        let ch = g ^ (e & (f ^ g));
164        let sigma1 = e.rotate_right(14) ^ e.rotate_right(18) ^ e.rotate_right(41);
165        let temp1 = h.wrapping_add(sigma1).wrapping_add(ch).wrapping_add(K[num]).wrapping_add(w[num]);
166        let maj = (a & b) ^ (c & (a ^ b));
167        let sigma0 = a.rotate_right(28) ^ a.rotate_right(34) ^ a.rotate_right(39);
168        let temp2 = sigma0.wrapping_add(maj);
169
170        h = g;
171        g = f;
172        f = e;
173        e = d.wrapping_add(temp1);
174        d = c;
175        c = b;
176        b = a;
177        a = temp1.wrapping_add(temp2);
178    }
179    [a, b, c, d, e, f, g, h]
180}
181
182pub fn encode(bytes: &[u8]) -> [u8; 64] {
183    let h = encode_core(bytes, H);
184    let mut hh = [0u8; 64];
185    for i in 0..8 {
186        let start_index = i << 3;
187        hh[start_index..start_index + 8].copy_from_slice(&h[i].to_be_bytes());
188    }
189    hh
190}
191
192
193pub async fn encode_async<R>(mut reader: R) -> Result<[u8; 64], std::io::Error>
194where
195    R: AsyncRead + Unpin,
196{
197    let mut h = H;
198    let mut buffer = [0u8; 128];
199    let mut buffer_len = 0;
200    let mut total_length = 0;
201
202    loop {
203        let bytes_read = reader.read(&mut buffer[buffer_len..]).await?;
204        if bytes_read == 0 {
205            break;
206        }
207        
208        buffer_len += bytes_read;
209        total_length += bytes_read;
210
211        if buffer_len == 128 {
212            let result = process_chunk(&buffer[..buffer_len], &h);
213            for i in 0..8 {
214                h[i] = h[i].wrapping_add(result[i]);
215            }
216            buffer_len = 0;
217        }
218    }
219
220    let final_chunk2 = 
221        get_final_chunks_sha2(&mut buffer, total_length, buffer_len);
222
223    let result = process_chunk(&buffer, &h);
224    for i in 0..8 {
225        h[i] = h[i].wrapping_add(result[i]);
226    }
227    if let Some(chunk2) = final_chunk2 {
228        let result = process_chunk(&chunk2, &h);
229        for i in 0..8 {
230            h[i] = h[i].wrapping_add(result[i]);
231        }
232    }
233
234    let mut hh = [0u8; 64];
235    for i in 0..8 {
236        let start_index = i << 3;
237        hh[start_index..start_index + 8].copy_from_slice(&h[i].to_be_bytes());
238    }
239
240    Ok(hh)
241}
242
243pub(crate) fn get_final_chunks_sha2(chunk1: &mut [u8; 128], total_len: usize, partial_data_len: usize) -> Option<[u8; 128]> {
244    let total_len= total_len << 3;
245    let mut full_padded_length = total_len + 1 + 128;
246    full_padded_length += 1024 - (full_padded_length % 1024);
247    chunk1[partial_data_len] = 0x80;
248    chunk1[partial_data_len + 1..].copy_from_slice(&ZERO_BUFFER[..128 - partial_data_len - 1]);
249    let two_chunks = full_padded_length - total_len > 1024;
250    if two_chunks {
251        let mut chunk2 = [0u8; 128];
252        chunk2[112..].copy_from_slice(&(total_len as u128).to_be_bytes());
253        Some(chunk2)
254    } else {
255        chunk1[112..].copy_from_slice(&(total_len as u128).to_be_bytes());
256        None
257    }
258}
259
260#[cfg(test)]
261mod tests {
262    use super::*;
263    use futures::io::Cursor;
264
265    #[tokio::test]
266    async fn test_encode_empty_string() {
267        let result = encode_async(Cursor::new("".as_bytes())).await.unwrap();
268        assert_eq!(
269            result,
270            [
271                0xcf, 0x83, 0xe1, 0x35, 0x7e, 0xef, 0xb8, 0xbd, 0xf1, 0x54, 0x28, 0x50, 0xd6, 0x6d,
272                0x80, 0x07, 0xd6, 0x20, 0xe4, 0x05, 0x0b, 0x57, 0x15, 0xdc, 0x83, 0xf4, 0xa9, 0x21,
273                0xd3, 0x6c, 0xe9, 0xce, 0x47, 0xd0, 0xd1, 0x3c, 0x5d, 0x85, 0xf2, 0xb0, 0xff, 0x83,
274                0x18, 0xd2, 0x87, 0x7e, 0xec, 0x2f, 0x63, 0xb9, 0x31, 0xbd, 0x47, 0x41, 0x7a, 0x81,
275                0xa5, 0x38, 0x32, 0x7a, 0xf9, 0x27, 0xda, 0x3e
276            ]
277        );
278    }
279
280    #[tokio::test]
281    async fn test_encode_abc() {
282        let result = encode_async(Cursor::new("abc".as_bytes())).await.unwrap();
283        assert_eq!(
284            result,
285            [
286                0xDD, 0xAF, 0x35, 0xA1, 0x93, 0x61, 0x7A, 0xBA, 0xCC, 0x41, 0x73, 0x49, 0xAE, 0x20,
287                0x41, 0x31, 0x12, 0xE6, 0xFA, 0x4E, 0x89, 0xA9, 0x7E, 0xA2, 0x0A, 0x9E, 0xEE, 0xE6,
288                0x4B, 0x55, 0xD3, 0x9A, 0x21, 0x92, 0x99, 0x2A, 0x27, 0x4F, 0xC1, 0xA8, 0x36, 0xBA,
289                0x3C, 0x23, 0xA3, 0xFE, 0xEB, 0xBD, 0x45, 0x4D, 0x44, 0x23, 0x64, 0x3C, 0xE8, 0x0E,
290                0x2A, 0x9A, 0xC9, 0x4F, 0xA5, 0x4C, 0xA4, 0x9F
291            ]
292        );
293    }
294
295    #[tokio::test]
296    async fn test_encode_message_digest() {
297        let result = encode_async(Cursor::new("message digest".as_bytes())).await.unwrap();
298        assert_eq!(
299            result,
300            [
301                0x10, 0x7d, 0xbf, 0x38, 0x9d, 0x9e, 0x9f, 0x71, 0xa3, 0xa9, 0x5f, 0x6c, 0x05, 0x5b,
302                0x92, 0x51, 0xbc, 0x52, 0x68, 0xc2, 0xbe, 0x16, 0xd6, 0xc1, 0x34, 0x92, 0xea, 0x45,
303                0xb0, 0x19, 0x9f, 0x33, 0x09, 0xe1, 0x64, 0x55, 0xab, 0x1e, 0x96, 0x11, 0x8e, 0x8a,
304                0x90, 0x5d, 0x55, 0x97, 0xb7, 0x20, 0x38, 0xdd, 0xb3, 0x72, 0xa8, 0x98, 0x26, 0x04,
305                0x6d, 0xe6, 0x66, 0x87, 0xbb, 0x42, 0x0e, 0x7c
306            ]
307        );
308    }
309
310    #[tokio::test]
311    async fn test_encode_abcdefghijklmnopqrstuvwxyz() {
312        let result = encode_async(Cursor::new("abcdefghijklmnopqrstuvwxyz".as_bytes())).await.unwrap();
313        assert_eq!(
314            result,
315            [
316                0x4d, 0xbf, 0xf8, 0x6c, 0xc2, 0xca, 0x1b, 0xae, 0x1e, 0x16, 0x46, 0x8a, 0x05, 0xcb,
317                0x98, 0x81, 0xc9, 0x7f, 0x17, 0x53, 0xbc, 0xe3, 0x61, 0x90, 0x34, 0x89, 0x8f, 0xaa,
318                0x1a, 0xab, 0xe4, 0x29, 0x95, 0x5a, 0x1b, 0xf8, 0xec, 0x48, 0x3d, 0x74, 0x21, 0xfe,
319                0x3c, 0x16, 0x46, 0x61, 0x3a, 0x59, 0xed, 0x54, 0x41, 0xfb, 0x0f, 0x32, 0x13, 0x89,
320                0xf7, 0x7f, 0x48, 0xa8, 0x79, 0xc7, 0xb1, 0xf1
321            ]
322        );
323    }
324
325    #[tokio::test]
326    async fn test_encode_alphanumeric_string() {
327        let result = encode_async(Cursor::new("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789".as_bytes())).await.unwrap();
328        assert_eq!(
329            result,
330            [
331                0x1e, 0x07, 0xbe, 0x23, 0xc2, 0x6a, 0x86, 0xea, 0x37, 0xea, 0x81, 0x0c, 0x8e, 0xc7,
332                0x80, 0x93, 0x52, 0x51, 0x5a, 0x97, 0x0e, 0x92, 0x53, 0xc2, 0x6f, 0x53, 0x6c, 0xfc,
333                0x7a, 0x99, 0x96, 0xc4, 0x5c, 0x83, 0x70, 0x58, 0x3e, 0x0a, 0x78, 0xfa, 0x4a, 0x90,
334                0x04, 0x1d, 0x71, 0xa4, 0xce, 0xab, 0x74, 0x23, 0xf1, 0x9c, 0x71, 0xb9, 0xd5, 0xa3,
335                0xe0, 0x12, 0x49, 0xf0, 0xbe, 0xbd, 0x58, 0x94
336            ]
337        );
338    }
339
340    #[tokio::test]
341    async fn test_encode_long_string() {
342        let result = encode_async(Cursor::new("abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu".as_bytes())).await.unwrap();
343        assert_eq!(
344            result,
345            [
346                0x8E, 0x95, 0x9B, 0x75, 0xDA, 0xE3, 0x13, 0xDA, 0x8C, 0xF4, 0xF7, 0x28, 0x14, 0xFC,
347                0x14, 0x3F, 0x8F, 0x77, 0x79, 0xC6, 0xEB, 0x9F, 0x7F, 0xA1, 0x72, 0x99, 0xAE, 0xAD,
348                0xB6, 0x88, 0x90, 0x18, 0x50, 0x1D, 0x28, 0x9E, 0x49, 0x00, 0xF7, 0xE4, 0x33, 0x1B,
349                0x99, 0xDE, 0xC4, 0xB5, 0x43, 0x3A, 0xC7, 0xD3, 0x29, 0xEE, 0xB6, 0xDD, 0x26, 0x54,
350                0x5E, 0x96, 0xE5, 0x5B, 0x87, 0x4B, 0xE9, 0x09
351            ]
352        );
353    }
354
355    #[tokio::test]
356    async fn test_encode_million_a() {
357        let result = encode_async(Cursor::new(&vec!["a".as_bytes()[0]; 1000000])).await.unwrap();
358        assert_eq!(
359            result,
360            [
361                0xE7, 0x18, 0x48, 0x3D, 0x0C, 0xE7, 0x69, 0x64, 0x4E, 0x2E, 0x42, 0xC7, 0xBC, 0x15,
362                0xB4, 0x63, 0x8E, 0x1F, 0x98, 0xB1, 0x3B, 0x20, 0x44, 0x28, 0x56, 0x32, 0xA8, 0x03,
363                0xAF, 0xA9, 0x73, 0xEB, 0xDE, 0x0F, 0xF2, 0x44, 0x87, 0x7E, 0xA6, 0x0A, 0x4C, 0xB0,
364                0x43, 0x2C, 0xE5, 0x77, 0xC3, 0x1B, 0xEB, 0x00, 0x9C, 0x5C, 0x2C, 0x49, 0xAA, 0x2E,
365                0x4E, 0xAD, 0xB2, 0x17, 0xAD, 0x8C, 0xC0, 0x9B
366            ]
367        );
368    }
369
370    #[tokio::test]
371    async fn test_encode_repeated_pattern() {
372        let result = encode_async(Cursor::new(
373            vec!["01234567012345670123456701234567"; 20]
374                .join("")
375                .as_bytes(),
376        )).await.unwrap();
377        assert_eq!(
378            result,
379            [
380                0x89, 0xD0, 0x5B, 0xA6, 0x32, 0xC6, 0x99, 0xC3, 0x12, 0x31, 0xDE, 0xD4, 0xFF, 0xC1,
381                0x27, 0xD5, 0xA8, 0x94, 0xDA, 0xD4, 0x12, 0xC0, 0xE0, 0x24, 0xDB, 0x87, 0x2D, 0x1A,
382                0xBD, 0x2B, 0xA8, 0x14, 0x1A, 0x0F, 0x85, 0x07, 0x2A, 0x9B, 0xE1, 0xE2, 0xAA, 0x04,
383                0xCF, 0x33, 0xC7, 0x65, 0xCB, 0x51, 0x08, 0x13, 0xA3, 0x9C, 0xD5, 0xA8, 0x4C, 0x4A,
384                0xCA, 0xA6, 0x4D, 0x3F, 0x3F, 0xB7, 0xBA, 0xE9
385            ]
386        );
387    }
388
389    #[tokio::test]
390    async fn test_encode_single_byte_d0() {
391        let result = encode_async(Cursor::new(&[0xd0])).await.unwrap();
392        assert_eq!(
393            result,
394            [
395                0x99, 0x92, 0x20, 0x29, 0x38, 0xE8, 0x82, 0xE7, 0x3E, 0x20, 0xF6, 0xB6, 0x9E, 0x68,
396                0xA0, 0xA7, 0x14, 0x90, 0x90, 0x42, 0x3D, 0x93, 0xC8, 0x1B, 0xAB, 0x3F, 0x21, 0x67,
397                0x8D, 0x4A, 0xCE, 0xEE, 0xE5, 0x0E, 0x4E, 0x8C, 0xAF, 0xAD, 0xA4, 0xC8, 0x5A, 0x54,
398                0xEA, 0x83, 0x06, 0x82, 0x6C, 0x4A, 0xD6, 0xE7, 0x4C, 0xEC, 0xE9, 0x63, 0x1B, 0xFA,
399                0x8A, 0x54, 0x9B, 0x4A, 0xB3, 0xFB, 0xBA, 0x15
400            ]
401        );
402    }
403
404    #[tokio::test]
405    async fn test_encode_16_byte_array() {
406        let result = encode_async(Cursor::new(&[
407            0x8d, 0x4e, 0x3c, 0x0e, 0x38, 0x89, 0x19, 0x14, 0x91, 0x81, 0x6e, 0x9d, 0x98, 0xbf,
408            0xf0, 0xa0,
409        ])).await.unwrap();
410        assert_eq!(
411            result,
412            [
413                0xCB, 0x0B, 0x67, 0xA4, 0xB8, 0x71, 0x2C, 0xD7, 0x3C, 0x9A, 0xAB, 0xC0, 0xB1, 0x99,
414                0xE9, 0x26, 0x9B, 0x20, 0x84, 0x4A, 0xFB, 0x75, 0xAC, 0xBD, 0xD1, 0xC1, 0x53, 0xC9,
415                0x82, 0x89, 0x24, 0xC3, 0xDD, 0xED, 0xAA, 0xFE, 0x66, 0x9C, 0x5F, 0xDD, 0x0B, 0xC6,
416                0x6F, 0x63, 0x0F, 0x67, 0x73, 0x98, 0x82, 0x13, 0xEB, 0x1B, 0x16, 0xF5, 0x17, 0xAD,
417                0x0D, 0xE4, 0xB2, 0xF0, 0xC9, 0x5C, 0x90, 0xF8
418            ]
419        );
420    }
421
422    #[tokio::test]
423    async fn test_encode_large_byte_array() {
424        let result = encode_async(Cursor::new(&[
425            0xa5, 0x5f, 0x20, 0xc4, 0x11, 0xaa, 0xd1, 0x32, 0x80, 0x7a, 0x50, 0x2d, 0x65, 0x82,
426            0x4e, 0x31, 0xa2, 0x30, 0x54, 0x32, 0xaa, 0x3d, 0x06, 0xd3, 0xe2, 0x82, 0xa8, 0xd8,
427            0x4e, 0x0d, 0xe1, 0xde, 0x69, 0x74, 0xbf, 0x49, 0x54, 0x69, 0xfc, 0x7f, 0x33, 0x8f,
428            0x80, 0x54, 0xd5, 0x8c, 0x26, 0xc4, 0x93, 0x60, 0xc3, 0xe8, 0x7a, 0xf5, 0x65, 0x23,
429            0xac, 0xf6, 0xd8, 0x9d, 0x03, 0xe5, 0x6f, 0xf2, 0xf8, 0x68, 0x00, 0x2b, 0xc3, 0xe4,
430            0x31, 0xed, 0xc4, 0x4d, 0xf2, 0xf0, 0x22, 0x3d, 0x4b, 0xb3, 0xb2, 0x43, 0x58, 0x6e,
431            0x1a, 0x7d, 0x92, 0x49, 0x36, 0x69, 0x4f, 0xcb, 0xba, 0xf8, 0x8d, 0x95, 0x19, 0xe4,
432            0xeb, 0x50, 0xa6, 0x44, 0xf8, 0xe4, 0xf9, 0x5e, 0xb0, 0xea, 0x95, 0xbc, 0x44, 0x65,
433            0xc8, 0x82, 0x1a, 0xac, 0xd2, 0xfe, 0x15, 0xab, 0x49, 0x81, 0x16, 0x4b, 0xbb, 0x6d,
434            0xc3, 0x2f, 0x96, 0x90, 0x87, 0xa1, 0x45, 0xb0, 0xd9, 0xcc, 0x9c, 0x67, 0xc2, 0x2b,
435            0x76, 0x32, 0x99, 0x41, 0x9c, 0xc4, 0x12, 0x8b, 0xe9, 0xa0, 0x77, 0xb3, 0xac, 0xe6,
436            0x34, 0x06, 0x4e, 0x6d, 0x99, 0x28, 0x35, 0x13, 0xdc, 0x06, 0xe7, 0x51, 0x5d, 0x0d,
437            0x73, 0x13, 0x2e, 0x9a, 0x0d, 0xc6, 0xd3, 0xb1, 0xf8, 0xb2, 0x46, 0xf1, 0xa9, 0x8a,
438            0x3f, 0xc7, 0x29, 0x41, 0xb1, 0xe3, 0xbb, 0x20, 0x98, 0xe8, 0xbf, 0x16, 0xf2, 0x68,
439            0xd6, 0x4f, 0x0b, 0x0f, 0x47, 0x07, 0xfe, 0x1e, 0xa1, 0xa1, 0x79, 0x1b, 0xa2, 0xf3,
440            0xc0, 0xc7, 0x58, 0xe5, 0xf5, 0x51, 0x86, 0x3a, 0x96, 0xc9, 0x49, 0xad, 0x47, 0xd7,
441            0xfb, 0x40, 0xd2,
442        ])).await.unwrap();
443        assert_eq!(
444            result,
445            [
446                0xC6, 0x65, 0xBE, 0xFB, 0x36, 0xDA, 0x18, 0x9D, 0x78, 0x82, 0x2D, 0x10, 0x52, 0x8C,
447                0xBF, 0x3B, 0x12, 0xB3, 0xEE, 0xF7, 0x26, 0x03, 0x99, 0x09, 0xC1, 0xA1, 0x6A, 0x27,
448                0x0D, 0x48, 0x71, 0x93, 0x77, 0x96, 0x6B, 0x95, 0x7A, 0x87, 0x8E, 0x72, 0x05, 0x84,
449                0x77, 0x9A, 0x62, 0x82, 0x5C, 0x18, 0xDA, 0x26, 0x41, 0x5E, 0x49, 0xA7, 0x17, 0x6A,
450                0x89, 0x4E, 0x75, 0x10, 0xFD, 0x14, 0x51, 0xF5
451            ]
452        );
453    }
454
455}