crypto_async_rs/
sha224.rs

1use crate::sha256::{encode_core, get_final_chunks_sha, process_chunk};
2use futures::io::{AsyncRead, AsyncReadExt};
3
4const H: [u32; 8] = [
5    0xc1059ed8, 0x367cd507, 0x3070dd17, 0xf70e5939, 0xffc00b31, 0x68581511, 0x64f98fa7, 0xbefa4fa4,
6];
7
8pub fn encode(bytes: &[u8]) -> [u8; 28] {
9    let h: [u32; 8] = encode_core(bytes, H);
10    let mut hh: [u8; 28] = [0; 28];
11    for i in 0..7 {
12        let start_index = i << 2;
13        hh[start_index..start_index + 4].copy_from_slice(&h[i].to_be_bytes());
14    }
15
16    hh
17}
18
19pub async fn encode_async<R>(mut reader: R) -> Result<[u8; 28], std::io::Error>
20where
21    R: AsyncRead + Unpin,
22{
23    let mut h = H;
24    let mut buffer = [0u8; 64];
25    let mut buffer_len = 0;
26    let mut total_length = 0;
27
28    loop {
29        let bytes_read = reader.read(&mut buffer[buffer_len..]).await?;
30        if bytes_read == 0 {
31            break;
32        }
33        
34        buffer_len += bytes_read;
35        total_length += bytes_read;
36
37        if buffer_len == 64 {
38            let result = 
39                process_chunk(&buffer[..64], &h);
40            for i in 0..8 {
41                h[i] = h[i].wrapping_add(result[i]);
42            }
43            buffer_len = 0;
44        }
45    }
46
47    let final_chunk2 = 
48        get_final_chunks_sha(&mut buffer, total_length, buffer_len);
49    
50    let result = process_chunk(&buffer, &h);
51    for i in 0..8 {
52        h[i] = h[i].wrapping_add(result[i]);
53    }
54    
55    if let Some(chunk2) = final_chunk2 {
56        let result = process_chunk(&chunk2, &h);
57        for i in 0..8 {
58            h[i] = h[i].wrapping_add(result[i]);
59        }
60    }
61
62    let mut hh: [u8; 28] = [0; 28];
63    for i in 0..7 {
64        let start_index = i << 2;
65        hh[start_index..start_index + 4].copy_from_slice(&h[i].to_be_bytes());
66    }
67
68    Ok(hh)
69}
70
71#[cfg(test)]
72mod tests {
73    use super::*;
74
75    #[tokio::test]
76    async fn test_encode_empty_string() {
77        let result = encode_async("".as_bytes()).await.unwrap();
78        assert_eq!(
79            result,
80            [
81                0xd1, 0x4a, 0x02, 0x8c, 0x2a, 0x3a, 0x2b, 0xc9, 0x47, 0x61, 0x02, 0xbb, 0x28, 0x82,
82                0x34, 0xc4, 0x15, 0xa2, 0xb0, 0x1f, 0x82, 0x8e, 0xa6, 0x2a, 0xc5, 0xb3, 0xe4, 0x2f
83            ]
84        );
85    }
86
87    #[tokio::test]
88    async fn test_encode_abc() {
89        let result = encode_async("abc".as_bytes()).await.unwrap();
90        assert_eq!(
91            result,
92            [
93                0x23, 0x09, 0x7D, 0x22, 0x34, 0x05, 0xD8, 0x22, 0x86, 0x42, 0xA4, 0x77, 0xBD, 0xA2,
94                0x55, 0xB3, 0x2A, 0xAD, 0xBC, 0xE4, 0xBD, 0xA0, 0xB3, 0xF7, 0xE3, 0x6C, 0x9D, 0xA7
95            ]
96        );
97    }
98
99    #[tokio::test]
100    async fn test_encode_message_digest() {
101        let result = encode_async("message digest".as_bytes()).await.unwrap();
102        assert_eq!(
103            result,
104            [
105                0x2c, 0xb2, 0x1c, 0x83, 0xae, 0x2f, 0x00, 0x4d, 0xe7, 0xe8, 0x1c, 0x3c, 0x70, 0x19,
106                0xcb, 0xcb, 0x65, 0xb7, 0x1a, 0xb6, 0x56, 0xb2, 0x2d, 0x6d, 0x0c, 0x39, 0xb8, 0xeb
107            ]
108        );
109    }
110
111    #[tokio::test]
112    async fn test_encode_abcdefghijklmnopqrstuvwxyz() {
113        let result = encode_async("abcdefghijklmnopqrstuvwxyz".as_bytes()).await.unwrap();
114        assert_eq!(
115            result,
116            [
117                0x45, 0xa5, 0xf7, 0x2c, 0x39, 0xc5, 0xcf, 0xf2, 0x52, 0x2e, 0xb3, 0x42, 0x97, 0x99,
118                0xe4, 0x9e, 0x5f, 0x44, 0xb3, 0x56, 0xef, 0x92, 0x6b, 0xcf, 0x39, 0x0d, 0xcc, 0xc2
119            ]
120        );
121    }
122
123    #[tokio::test]
124    async fn test_encode_alphanumeric_string() {
125        let result = encode_async("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789".as_bytes()).await.unwrap();
126        assert_eq!(
127            result,
128            [
129                0xbf, 0xf7, 0x2b, 0x4f, 0xcb, 0x7d, 0x75, 0xe5, 0x63, 0x29, 0x00, 0xac, 0x5f, 0x90,
130                0xd2, 0x19, 0xe0, 0x5e, 0x97, 0xa7, 0xbd, 0xe7, 0x2e, 0x74, 0x0d, 0xb3, 0x93, 0xd9
131            ]
132        );
133    }
134
135    #[tokio::test]
136    async fn test_encode_abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq() {
137        let result = encode_async("abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq".as_bytes()).await.unwrap();
138        assert_eq!(
139            result,
140            [
141                0x75, 0x38, 0x8B, 0x16, 0x51, 0x27, 0x76, 0xCC, 0x5D, 0xBA, 0x5D, 0xA1, 0xFD, 0x89,
142                0x01, 0x50, 0xB0, 0xC6, 0x45, 0x5C, 0xB4, 0xF5, 0x8B, 0x19, 0x52, 0x52, 0x25, 0x25
143            ]
144        );
145    }
146
147    #[tokio::test]
148    async fn test_encode_million_a() {
149        let result = encode_async(vec!["a".as_bytes()[0]; 1000000].as_slice()).await.unwrap();
150        assert_eq!(
151            result,
152            [
153                0x20, 0x79, 0x46, 0x55, 0x98, 0x0C, 0x91, 0xD8, 0xBB, 0xB4, 0xC1, 0xEA, 0x97, 0x61,
154                0x8A, 0x4B, 0xF0, 0x3F, 0x42, 0x58, 0x19, 0x48, 0xB2, 0xEE, 0x4E, 0xE7, 0xAD, 0x67
155            ]
156        );
157    }
158
159    #[tokio::test]
160    async fn test_encode_repeated_pattern() {
161        let result = encode_async(
162            vec!["01234567012345670123456701234567"; 20]
163                .join("")
164                .as_bytes(),
165        ).await.unwrap();
166        assert_eq!(
167            result,
168            [
169                0x56, 0x7F, 0x69, 0xF1, 0x68, 0xCD, 0x78, 0x44, 0xE6, 0x52, 0x59, 0xCE, 0x65, 0x8F,
170                0xE7, 0xAA, 0xDF, 0xA2, 0x52, 0x16, 0xE6, 0x8E, 0xCA, 0x0E, 0xB7, 0xAB, 0x82, 0x62
171            ]
172        );
173    }
174
175    #[tokio::test]
176    async fn test_encode_single_byte_07() {
177        let result = encode_async([0x07].as_slice()).await.unwrap();
178        assert_eq!(
179            result,
180            [
181                0x00, 0xEC, 0xD5, 0xF1, 0x38, 0x42, 0x2B, 0x8A, 0xD7, 0x4C, 0x97, 0x99, 0xFD, 0x82,
182                0x6C, 0x53, 0x1B, 0xAD, 0x2F, 0xCA, 0xBC, 0x74, 0x50, 0xBE, 0xE2, 0xAA, 0x8C, 0x2A
183            ]
184        );
185    }
186
187    #[tokio::test]
188    async fn test_encode_16_byte_array() {
189        let result = encode_async([
190            0x18, 0x80, 0x40, 0x05, 0xdd, 0x4f, 0xbd, 0x15, 0x56, 0x29, 0x9d, 0x6f, 0x9d, 0x93,
191            0xdf, 0x62,
192        ].as_slice()).await.unwrap();
193        assert_eq!(
194            result,
195            [
196                0xDF, 0x90, 0xD7, 0x8A, 0xA7, 0x88, 0x21, 0xC9, 0x9B, 0x40, 0xBA, 0x4C, 0x96, 0x69,
197                0x21, 0xAC, 0xCD, 0x8F, 0xFB, 0x1E, 0x98, 0xAC, 0x38, 0x8E, 0x56, 0x19, 0x1D, 0xB1
198            ]
199        );
200    }
201
202    #[tokio::test]
203    async fn test_encode_large_byte_array() {
204        let result = encode_async([
205            0x55, 0xb2, 0x10, 0x07, 0x9c, 0x61, 0xb5, 0x3a, 0xdd, 0x52, 0x06, 0x22, 0xd1, 0xac,
206            0x97, 0xd5, 0xcd, 0xbe, 0x8c, 0xb3, 0x3a, 0xa0, 0xae, 0x34, 0x45, 0x17, 0xbe, 0xe4,
207            0xd7, 0xba, 0x09, 0xab, 0xc8, 0x53, 0x3c, 0x52, 0x50, 0x88, 0x7a, 0x43, 0xbe, 0xbb,
208            0xac, 0x90, 0x6c, 0x2e, 0x18, 0x37, 0xf2, 0x6b, 0x36, 0xa5, 0x9a, 0xe3, 0xbe, 0x78,
209            0x14, 0xd5, 0x06, 0x89, 0x6b, 0x71, 0x8b, 0x2a, 0x38, 0x3e, 0xcd, 0xac, 0x16, 0xb9,
210            0x61, 0x25, 0x55, 0x3f, 0x41, 0x6f, 0xf3, 0x2c, 0x66, 0x74, 0xc7, 0x45, 0x99, 0xa9,
211            0x00, 0x53, 0x86, 0xd9, 0xce, 0x11, 0x12, 0x24, 0x5f, 0x48, 0xee, 0x47, 0x0d, 0x39,
212            0x6c, 0x1e, 0xd6, 0x3b, 0x92, 0x67, 0x0c, 0xa5, 0x6e, 0xc8, 0x4d, 0xee, 0xa8, 0x14,
213            0xb6, 0x13, 0x5e, 0xca, 0x54, 0x39, 0x2b, 0xde, 0xdb, 0x94, 0x89, 0xbc, 0x9b, 0x87,
214            0x5a, 0x8b, 0xaf, 0x0d, 0xc1, 0xae, 0x78, 0x57, 0x36, 0x91, 0x4a, 0xb7, 0xda, 0xa2,
215            0x64, 0xbc, 0x07, 0x9d, 0x26, 0x9f, 0x2c, 0x0d, 0x7e, 0xdd, 0xd8, 0x10, 0xa4, 0x26,
216            0x14, 0x5a, 0x07, 0x76, 0xf6, 0x7c, 0x87, 0x82, 0x73,
217        ].as_slice()).await.unwrap();
218        assert_eq!(
219            result,
220            [
221                0x0B, 0x31, 0x89, 0x4E, 0xC8, 0x93, 0x7A, 0xD9, 0xB9, 0x1B, 0xDF, 0xBC, 0xBA, 0x29,
222                0x4D, 0x9A, 0xDE, 0xFA, 0xA1, 0x8E, 0x09, 0x30, 0x5E, 0x9F, 0x20, 0xD5, 0xC3, 0xA4
223            ]
224        );
225    }
226
227}