crypto_async_rs/
sha384.rs

1use crate::sha512::{encode_core, get_final_chunks_sha2, process_chunk};
2use futures::io::{AsyncRead, AsyncReadExt};
3
4const H: [u64; 8] = [
5    0xcbbb9d5dc1059ed8,
6    0x629a292a367cd507,
7    0x9159015a3070dd17,
8    0x152fecd8f70e5939,
9    0x67332667ffc00b31,
10    0x8eb44a8768581511,
11    0xdb0c2e0d64f98fa7,
12    0x47b5481dbefa4fa4,
13];
14
15pub fn encode(bytes: &[u8]) -> [u8; 48] {
16    let h: [u64; 8] = encode_core(bytes, H);
17    let mut hh: [u8; 48] = [0; 48];
18    for i in 0..6 {
19        let start_index = i << 3;
20        hh[start_index..start_index + 8].copy_from_slice(&h[i].to_be_bytes());
21    }
22
23    hh
24}
25
26
27pub async fn encode_async<R>(mut reader: R) -> Result<[u8; 48], std::io::Error>
28where
29    R: AsyncRead + Unpin,
30{
31    let mut h = H;
32    let mut buffer = [0u8; 128];
33    let mut buffer_len = 0;
34    let mut total_length = 0;
35
36    loop {
37        let bytes_read = reader.read(&mut buffer[buffer_len..]).await?;
38        if bytes_read == 0 {
39            break;
40        }
41        
42        buffer_len += bytes_read;
43        total_length += bytes_read;
44
45        if buffer_len == 128 {
46            let result = process_chunk(&buffer[..buffer_len], &h);
47            for i in 0..8 {
48                h[i] = h[i].wrapping_add(result[i]);
49            }
50            buffer_len = 0;
51        }
52    }
53
54    let final_chunk2 = 
55        get_final_chunks_sha2(&mut buffer, total_length, buffer_len);
56
57    let result = process_chunk(&buffer, &h);
58    for i in 0..8 {
59        h[i] = h[i].wrapping_add(result[i]);
60    }
61    if let Some(chunk2) = final_chunk2 {
62        let result = process_chunk(&chunk2, &h);
63        for i in 0..8 {
64            h[i] = h[i].wrapping_add(result[i]);
65        }
66    }
67
68    let mut hh = [0u8; 48];
69    for i in 0..6 {
70        let start_index = i << 3;
71        hh[start_index..start_index + 8].copy_from_slice(&h[i].to_be_bytes());
72    }
73
74    Ok(hh)
75}
76
77
78
79
80#[cfg(test)]
81mod tests {
82    use super::*;
83
84    #[test]
85    fn test_encode_empty_string() {
86        let result = encode("".as_bytes());
87        assert_eq!(
88            result,
89            [
90                0x38, 0xb0, 0x60, 0xa7, 0x51, 0xac, 0x96, 0x38, 0x4c, 0xd9, 0x32, 0x7e, 0xb1, 0xb1,
91                0xe3, 0x6a, 0x21, 0xfd, 0xb7, 0x11, 0x14, 0xbe, 0x07, 0x43, 0x4c, 0x0c, 0xc7, 0xbf,
92                0x63, 0xf6, 0xe1, 0xda, 0x27, 0x4e, 0xde, 0xbf, 0xe7, 0x6f, 0x65, 0xfb, 0xd5, 0x1a,
93                0xd2, 0xf1, 0x48, 0x98, 0xb9, 0x5b
94            ]
95        );
96    }
97
98    #[test]
99    fn test_encode_abc() {
100        let result = encode("abc".as_bytes());
101        assert_eq!(
102            result,
103            [
104                0xcb, 0x00, 0x75, 0x3f, 0x45, 0xa3, 0x5e, 0x8b, 0xb5, 0xa0, 0x3d, 0x69, 0x9a, 0xc6,
105                0x50, 0x07, 0x27, 0x2c, 0x32, 0xab, 0x0e, 0xde, 0xd1, 0x63, 0x1a, 0x8b, 0x60, 0x5a,
106                0x43, 0xff, 0x5b, 0xed, 0x80, 0x86, 0x07, 0x2b, 0xa1, 0xe7, 0xcc, 0x23, 0x58, 0xba,
107                0xec, 0xa1, 0x34, 0xc8, 0x25, 0xa7
108            ]
109        );
110    }
111
112    #[test]
113    fn test_encode_message_digest() {
114        let result = encode("message digest".as_bytes());
115        assert_eq!(
116            result,
117            [
118                0x47, 0x3e, 0xd3, 0x51, 0x67, 0xec, 0x1f, 0x5d, 0x8e, 0x55, 0x03, 0x68, 0xa3, 0xdb,
119                0x39, 0xbe, 0x54, 0x63, 0x9f, 0x82, 0x88, 0x68, 0xe9, 0x45, 0x4c, 0x23, 0x9f, 0xc8,
120                0xb5, 0x2e, 0x3c, 0x61, 0xdb, 0xd0, 0xd8, 0xb4, 0xde, 0x13, 0x90, 0xc2, 0x56, 0xdc,
121                0xbb, 0x5d, 0x5f, 0xd9, 0x9c, 0xd5
122            ]
123        );
124    }
125
126    #[test]
127    fn test_encode_abcdefghijklmnopqrstuvwxyz() {
128        let result = encode("abcdefghijklmnopqrstuvwxyz".as_bytes());
129        assert_eq!(
130            result,
131            [
132                0xfe, 0xb6, 0x73, 0x49, 0xdf, 0x3d, 0xb6, 0xf5, 0x92, 0x48, 0x15, 0xd6, 0xc3, 0xdc,
133                0x13, 0x3f, 0x09, 0x18, 0x09, 0x21, 0x37, 0x31, 0xfe, 0x5c, 0x7b, 0x5f, 0x49, 0x99,
134                0xe4, 0x63, 0x47, 0x9f, 0xf2, 0x87, 0x7f, 0x5f, 0x29, 0x36, 0xfa, 0x63, 0xbb, 0x43,
135                0x78, 0x4b, 0x12, 0xf3, 0xeb, 0xb4
136            ]
137        );
138    }
139
140    #[test]
141    fn test_encode_alphanumeric_string() {
142        let result = encode("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789".as_bytes());
143        assert_eq!(
144            result,
145            [
146                0x17, 0x61, 0x33, 0x6e, 0x3f, 0x7c, 0xbf, 0xe5, 0x1d, 0xeb, 0x13, 0x7f, 0x02, 0x6f,
147                0x89, 0xe0, 0x1a, 0x44, 0x8e, 0x3b, 0x1f, 0xaf, 0xa6, 0x40, 0x39, 0xc1, 0x46, 0x4e,
148                0xe8, 0x73, 0x2f, 0x11, 0xa5, 0x34, 0x1a, 0x6f, 0x41, 0xe0, 0xc2, 0x02, 0x29, 0x47,
149                0x36, 0xed, 0x64, 0xdb, 0x1a, 0x84
150            ]
151        );
152    }
153
154    #[test]
155    fn test_encode_12345() {
156        let result = encode("12345".as_bytes());
157        assert_eq!(
158            result,
159            [
160                0x0f, 0xa7, 0x69, 0x55, 0xab, 0xfa, 0x9d, 0xaf, 0xd8, 0x3f, 0xac, 0xca, 0x83, 0x43,
161                0xa9, 0x2a, 0xa0, 0x94, 0x97, 0xf9, 0x81, 0x01, 0x08, 0x66, 0x11, 0xb0, 0xbf, 0xa9,
162                0x5d, 0xbc, 0x0d, 0xcc, 0x66, 0x1d, 0x62, 0xe9, 0x56, 0x8a, 0x5a, 0x03, 0x2b, 0xa8,
163                0x19, 0x60, 0xf3, 0xe5, 0x5d, 0x4a
164            ]
165        );
166    }
167
168    #[test]
169    fn test_encode_long_string() {
170        let result = encode(b"abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu");
171        assert_eq!(
172            result,
173            [
174                0x09, 0x33, 0x0c, 0x33, 0xf7, 0x11, 0x47, 0xe8, 0x3d, 0x19, 0x2f, 0xc7, 0x82, 0xcd,
175                0x1b, 0x47, 0x53, 0x11, 0x1b, 0x17, 0x3b, 0x3b, 0x05, 0xd2, 0x2f, 0xa0, 0x80, 0x86,
176                0xe3, 0xb0, 0xf7, 0x12, 0xfc, 0xc7, 0xc7, 0x1a, 0x55, 0x7e, 0x2d, 0xb9, 0x66, 0xc3,
177                0xe9, 0xfa, 0x91, 0x74, 0x60, 0x39
178            ]
179        );
180    }
181
182    #[test]
183    fn test_encode_million_a() {
184        let result = encode(&vec!["a".as_bytes()[0]; 1000000]);
185        assert_eq!(
186            result,
187            [
188                0x9d, 0x0e, 0x18, 0x09, 0x71, 0x64, 0x74, 0xcb, 0x08, 0x6e, 0x83, 0x4e, 0x31, 0x0a,
189                0x4a, 0x1c, 0xed, 0x14, 0x9e, 0x9c, 0x00, 0xf2, 0x48, 0x52, 0x79, 0x72, 0xce, 0xc5,
190                0x70, 0x4c, 0x2a, 0x5b, 0x07, 0xb8, 0xb3, 0xdc, 0x38, 0xec, 0xc4, 0xeb, 0xae, 0x97,
191                0xdd, 0xd8, 0x7f, 0x3d, 0x89, 0x85
192            ]
193        );
194    }
195
196    #[test]
197    fn test_encode_repeated_pattern() {
198        let result = encode(
199            vec!["01234567012345670123456701234567"; 20]
200                .join("")
201                .as_bytes(),
202        );
203        assert_eq!(
204            result,
205            [
206                0x2f, 0xc6, 0x4a, 0x4f, 0x50, 0x0d, 0xdb, 0x68, 0x28, 0xf6, 0xa3, 0x43, 0x0b, 0x8d,
207                0xd7, 0x2a, 0x36, 0x8e, 0xb7, 0xf3, 0xa8, 0x32, 0x2a, 0x70, 0xbc, 0x84, 0x27, 0x5b,
208                0x9c, 0x0b, 0x3a, 0xb0, 0x0d, 0x27, 0xa5, 0xcc, 0x3c, 0x2d, 0x22, 0x4a, 0xa6, 0xb6,
209                0x1a, 0x0d, 0x79, 0xfb, 0x45, 0x96
210            ]
211        );
212    }
213
214    #[test]
215    fn test_encode_single_byte_b9() {
216        let result = encode(&[0xb9]);
217        assert_eq!(
218            result,
219            [
220                0xbc, 0x80, 0x89, 0xa1, 0x90, 0x07, 0xc0, 0xb1, 0x41, 0x95, 0xf4, 0xec, 0xc7, 0x40,
221                0x94, 0xfe, 0xc6, 0x4f, 0x01, 0xf9, 0x09, 0x29, 0x28, 0x2c, 0x2f, 0xb3, 0x92, 0x88,
222                0x15, 0x78, 0x20, 0x8a, 0xd4, 0x66, 0x82, 0x8b, 0x1c, 0x6c, 0x28, 0x3d, 0x27, 0x22,
223                0xcf, 0x0a, 0xd1, 0xab, 0x69, 0x38
224            ]
225        );
226    }
227
228    #[test]
229    fn test_encode_16_byte_array() {
230        let result = encode(&[
231            0xa4, 0x1c, 0x49, 0x77, 0x79, 0xc0, 0x37, 0x5f, 0xf1, 0x0a, 0x7f, 0x4e, 0x08, 0x59,
232            0x17, 0x39,
233        ]);
234        assert_eq!(
235            result,
236            [
237                0xc9, 0xa6, 0x84, 0x43, 0xa0, 0x05, 0x81, 0x22, 0x56, 0xb8, 0xec, 0x76, 0xb0, 0x05,
238                0x16, 0xf0, 0xdb, 0xb7, 0x4f, 0xab, 0x26, 0xd6, 0x65, 0x91, 0x3f, 0x19, 0x4b, 0x6f,
239                0xfb, 0x0e, 0x91, 0xea, 0x99, 0x67, 0x56, 0x6b, 0x58, 0x10, 0x9c, 0xbc, 0x67, 0x5c,
240                0xc2, 0x08, 0xe4, 0xc8, 0x23, 0xf7
241            ]
242        );
243    }
244
245    #[test]
246    fn test_encode_large_byte_array() {
247        let result = encode(&[
248            0x39, 0x96, 0x69, 0xe2, 0x8f, 0x6b, 0x9c, 0x6d, 0xbc, 0xbb, 0x69, 0x12, 0xec, 0x10,
249            0xff, 0xcf, 0x74, 0x79, 0x03, 0x49, 0xb7, 0xdc, 0x8f, 0xbe, 0x4a, 0x8e, 0x7b, 0x3b,
250            0x56, 0x21, 0xdb, 0x0f, 0x3e, 0x7d, 0xc8, 0x7f, 0x82, 0x32, 0x64, 0xbb, 0xe4, 0x0d,
251            0x18, 0x11, 0xc9, 0xea, 0x20, 0x61, 0xe1, 0xc8, 0x4a, 0xd1, 0x0a, 0x23, 0xfa, 0xc1,
252            0x72, 0x7e, 0x72, 0x02, 0xfc, 0x3f, 0x50, 0x42, 0xe6, 0xbf, 0x58, 0xcb, 0xa8, 0xa2,
253            0x74, 0x6e, 0x1f, 0x64, 0xf9, 0xb9, 0xea, 0x35, 0x2c, 0x71, 0x15, 0x07, 0x05, 0x3c,
254            0xf4, 0xe5, 0x33, 0x9d, 0x52, 0x86, 0x5f, 0x25, 0xcc, 0x22, 0xb5, 0xe8, 0x77, 0x84,
255            0xa1, 0x2f, 0xc9, 0x61, 0xd6, 0x6c, 0xb6, 0xe8, 0x95, 0x73, 0x19, 0x9a, 0x2c, 0xe6,
256            0x56, 0x5c, 0xbd, 0xf1, 0x3d, 0xca, 0x40, 0x38, 0x32, 0xcf, 0xcb, 0x0e, 0x8b, 0x72,
257            0x11, 0xe8, 0x3a, 0xf3, 0x2a, 0x11, 0xac, 0x17, 0x92, 0x9f, 0xf1, 0xc0, 0x73, 0xa5,
258            0x1c, 0xc0, 0x27, 0xaa, 0xed, 0xef, 0xf8, 0x5a, 0xad, 0x7c, 0x2b, 0x7c, 0x5a, 0x80,
259            0x3e, 0x24, 0x04, 0xd9, 0x6d, 0x2a, 0x77, 0x35, 0x7b, 0xda, 0x1a, 0x6d, 0xae, 0xed,
260            0x17, 0x15, 0x1c, 0xb9, 0xbc, 0x51, 0x25, 0xa4, 0x22, 0xe9, 0x41, 0xde, 0x0c, 0xa0,
261            0xfc, 0x50, 0x11, 0xc2, 0x3e, 0xcf, 0xfe, 0xfd, 0xd0, 0x96, 0x76, 0x71, 0x1c, 0xf3,
262            0xdb, 0x0a, 0x34, 0x40, 0x72, 0x0e, 0x16, 0x15, 0xc1, 0xf2, 0x2f, 0xbc, 0x3c, 0x72,
263            0x1d, 0xe5, 0x21, 0xe1, 0xb9, 0x9b, 0xa1, 0xbd, 0x55, 0x77, 0x40, 0x86, 0x42, 0x14,
264            0x7e, 0xd0, 0x96,
265        ]);
266        assert_eq!(
267            result,
268            [
269                0x4f, 0x44, 0x0d, 0xb1, 0xe6, 0xed, 0xd2, 0x89, 0x9f, 0xa3, 0x35, 0xf0, 0x95, 0x15,
270                0xaa, 0x02, 0x5e, 0xe1, 0x77, 0xa7, 0x9f, 0x4b, 0x4a, 0xaf, 0x38, 0xe4, 0x2b, 0x5c,
271                0x4d, 0xe6, 0x60, 0xf5, 0xde, 0x8f, 0xb2, 0xa5, 0xb2, 0xfb, 0xd2, 0xa3, 0xcb, 0xff,
272                0xd2, 0x0c, 0xff, 0x12, 0x88, 0xc0
273            ]
274        );
275    }
276
277    #[tokio::test]
278    async fn test_encode_async() {
279        let data = "The quick brown fox jumps over the lazy dog".as_bytes();
280        let async_result = encode_async(data).await.unwrap();
281        let sync_result = encode(data);
282        assert_eq!(async_result, sync_result);
283    }
284
285}