1use futures::io::{AsyncRead, AsyncReadExt};
2
3const 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 for chunk_num in 0..(bytes.len() >> 7) {
104 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
115fn 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}