OXYGENHUB
◆ bare-hashes oxygen / vendor / crc-fast / src / crc16 / mod.rs
11.2 KiB · Rust · last changed Strata: the cloud stores send through ureq, so every release target links 1 month ago source blame history raw
1
// Copyright 2025 Don MacAskill. Licensed under MIT or Apache-2.0.
2
3
pub(crate) mod algorithm;
4
pub(crate) mod consts;
5
6
#[cfg(test)]
7
mod property_tests {
8
    use crate::crc16::consts::{CRC16_IBM_SDLC, CRC16_T10_DIF};
9
    use crate::test::consts::{RUST_CRC16_IBM_SDLC, RUST_CRC16_T10_DIF};
10
    use crate::test::miri_compatible_proptest_config;
11
    use crate::{
12
        checksum, checksum_combine, checksum_combine_with_params, checksum_with_params,
13
        CrcAlgorithm, CrcParams,
14
    };
15
    use proptest::prelude::*;
16
17
    proptest! {
18
        #![proptest_config(miri_compatible_proptest_config())]
19
20
        /// Feature: crc16-hardware-acceleration, Property 3: CRC-16 computation matches reference
21
        /// *For any* valid CRC-16 parameters (polynomial, init, refin, refout, xorout) and any
22
        /// input byte sequence, the computed CRC-16 checksum SHALL match the result from the
23
        /// `crc` crate reference implementation.
24
        /// **Validates: Requirements 2.1, 2.2, 5.5, 6.1, 6.2, 6.3**
25
        #[test]
26
        fn prop_crc16_ibm_sdlc_matches_reference(data in proptest::collection::vec(any::<u8>(), 0..1024)) {
27
            let our_result = checksum(CrcAlgorithm::Crc16IbmSdlc, &data);
28
            let reference_result = RUST_CRC16_IBM_SDLC.checksum(&data) as u64;
29
            prop_assert_eq!(
30
                our_result, reference_result,
31
                "CRC-16/IBM-SDLC mismatch for {} bytes: our=0x{:04X}, ref=0x{:04X}",
32
                data.len(), our_result, reference_result
33
            );
34
        }
35
36
        /// Feature: crc16-hardware-acceleration, Property 3: CRC-16 computation matches reference
37
        /// *For any* valid CRC-16 parameters (polynomial, init, refin, refout, xorout) and any
38
        /// input byte sequence, the computed CRC-16 checksum SHALL match the result from the
39
        /// `crc` crate reference implementation.
40
        /// **Validates: Requirements 2.1, 2.2, 5.5, 6.1, 6.2, 6.3**
41
        #[test]
42
        fn prop_crc16_t10_dif_matches_reference(data in proptest::collection::vec(any::<u8>(), 0..1024)) {
43
            let our_result = checksum(CrcAlgorithm::Crc16T10Dif, &data);
44
            let reference_result = RUST_CRC16_T10_DIF.checksum(&data) as u64;
45
            prop_assert_eq!(
46
                our_result, reference_result,
47
                "CRC-16/T10-DIF mismatch for {} bytes: our=0x{:04X}, ref=0x{:04X}",
48
                data.len(), our_result, reference_result
49
            );
50
        }
51
52
        /// Feature: crc16-hardware-acceleration, Property 3: CRC-16 computation matches reference
53
        /// Tests checksum_with_params for CRC-16/IBM-SDLC (reflected variant)
54
        /// **Validates: Requirements 5.5, 6.1, 6.2, 6.3**
55
        #[test]
56
        fn prop_crc16_ibm_sdlc_with_params_matches_reference(data in proptest::collection::vec(any::<u8>(), 0..1024)) {
57
            let our_result = checksum_with_params(CRC16_IBM_SDLC, &data);
58
            let reference_result = RUST_CRC16_IBM_SDLC.checksum(&data) as u64;
59
            prop_assert_eq!(
60
                our_result, reference_result,
61
                "CRC-16/IBM-SDLC (with_params) mismatch for {} bytes: our=0x{:04X}, ref=0x{:04X}",
62
                data.len(), our_result, reference_result
63
            );
64
        }
65
66
        /// Feature: crc16-hardware-acceleration, Property 3: CRC-16 computation matches reference
67
        /// Tests checksum_with_params for CRC-16/T10-DIF (forward variant)
68
        /// **Validates: Requirements 5.5, 6.1, 6.2, 6.3**
69
        #[test]
70
        fn prop_crc16_t10_dif_with_params_matches_reference(data in proptest::collection::vec(any::<u8>(), 0..1024)) {
71
            let our_result = checksum_with_params(CRC16_T10_DIF, &data);
72
            let reference_result = RUST_CRC16_T10_DIF.checksum(&data) as u64;
73
            prop_assert_eq!(
74
                our_result, reference_result,
75
                "CRC-16/T10-DIF (with_params) mismatch for {} bytes: our=0x{:04X}, ref=0x{:04X}",
76
                data.len(), our_result, reference_result
77
            );
78
        }
79
80
        /// Feature: crc16-hardware-acceleration, Property 3: CRC-16 computation matches reference
81
        /// Tests custom CRC-16 parameters (equivalent to IBM-SDLC) to validate CrcParams::new()
82
        /// **Validates: Requirements 5.5, 6.1, 6.2, 6.3**
83
        #[test]
84
        fn prop_crc16_custom_reflected_matches_reference(data in proptest::collection::vec(any::<u8>(), 0..1024)) {
85
            // Custom CRC-16 parameters equivalent to CRC-16/IBM-SDLC
86
            let custom_params = CrcParams::new(
87
                "CRC-16/CUSTOM-REFLECTED",
88
                16,
89
                0x1021,
90
                0xFFFF,
91
                true,  // reflected
92
                0xFFFF,
93
                0x906E,
94
            );
95
            let our_result = checksum_with_params(custom_params, &data);
96
            let reference_result = RUST_CRC16_IBM_SDLC.checksum(&data) as u64;
97
            prop_assert_eq!(
98
                our_result, reference_result,
99
                "CRC-16 custom reflected mismatch for {} bytes: our=0x{:04X}, ref=0x{:04X}",
100
                data.len(), our_result, reference_result
101
            );
102
        }
103
104
        /// Feature: crc16-hardware-acceleration, Property 3: CRC-16 computation matches reference
105
        /// Tests custom CRC-16 parameters (equivalent to T10-DIF) to validate CrcParams::new()
106
        /// **Validates: Requirements 5.5, 6.1, 6.2, 6.3**
107
        #[test]
108
        fn prop_crc16_custom_forward_matches_reference(data in proptest::collection::vec(any::<u8>(), 0..1024)) {
109
            // Custom CRC-16 parameters equivalent to CRC-16/T10-DIF
110
            let custom_params = CrcParams::new(
111
                "CRC-16/CUSTOM-FORWARD",
112
                16,
113
                0x8BB7,
114
                0x0000,
115
                false,  // forward (non-reflected)
116
                0x0000,
117
                0xD0DB,
118
            );
119
            let our_result = checksum_with_params(custom_params, &data);
120
            let reference_result = RUST_CRC16_T10_DIF.checksum(&data) as u64;
121
            prop_assert_eq!(
122
                our_result, reference_result,
123
                "CRC-16 custom forward mismatch for {} bytes: our=0x{:04X}, ref=0x{:04X}",
124
                data.len(), our_result, reference_result
125
            );
126
        }
127
128
        /// Feature: crc16-hardware-acceleration, Property 5: CRC-16 checksum combination round-trip
129
        /// *For any* valid CRC-16 parameters and any two input byte sequences A and B,
130
        /// `checksum_combine(checksum(A), checksum(B), len(B))` SHALL equal `checksum(A + B)`.
131
        /// **Validates: Requirements 6.4**
132
        #[test]
133
        fn prop_crc16_ibm_sdlc_checksum_combine_roundtrip(
134
            data_a in proptest::collection::vec(any::<u8>(), 0..512),
135
            data_b in proptest::collection::vec(any::<u8>(), 0..512)
136
        ) {
137
            let checksum_a = checksum(CrcAlgorithm::Crc16IbmSdlc, &data_a);
138
            let checksum_b = checksum(CrcAlgorithm::Crc16IbmSdlc, &data_b);
139
            let combined = checksum_combine(
140
                CrcAlgorithm::Crc16IbmSdlc,
141
                checksum_a,
142
                checksum_b,
143
                data_b.len() as u64,
144
            );
145
146
            let mut concatenated = data_a.clone();
147
            concatenated.extend(&data_b);
148
            let expected = checksum(CrcAlgorithm::Crc16IbmSdlc, &concatenated);
149
150
            prop_assert_eq!(
151
                combined, expected,
152
                "CRC-16/IBM-SDLC combine mismatch: combined=0x{:04X}, expected=0x{:04X}, len_a={}, len_b={}",
153
                combined, expected, data_a.len(), data_b.len()
154
            );
155
        }
156
157
        /// Feature: crc16-hardware-acceleration, Property 5: CRC-16 checksum combination round-trip
158
        /// *For any* valid CRC-16 parameters and any two input byte sequences A and B,
159
        /// `checksum_combine(checksum(A), checksum(B), len(B))` SHALL equal `checksum(A + B)`.
160
        /// **Validates: Requirements 6.4**
161
        #[test]
162
        fn prop_crc16_t10_dif_checksum_combine_roundtrip(
163
            data_a in proptest::collection::vec(any::<u8>(), 0..512),
164
            data_b in proptest::collection::vec(any::<u8>(), 0..512)
165
        ) {
166
            let checksum_a = checksum(CrcAlgorithm::Crc16T10Dif, &data_a);
167
            let checksum_b = checksum(CrcAlgorithm::Crc16T10Dif, &data_b);
168
            let combined = checksum_combine(
169
                CrcAlgorithm::Crc16T10Dif,
170
                checksum_a,
171
                checksum_b,
172
                data_b.len() as u64,
173
            );
174
175
            let mut concatenated = data_a.clone();
176
            concatenated.extend(&data_b);
177
            let expected = checksum(CrcAlgorithm::Crc16T10Dif, &concatenated);
178
179
            prop_assert_eq!(
180
                combined, expected,
181
                "CRC-16/T10-DIF combine mismatch: combined=0x{:04X}, expected=0x{:04X}, len_a={}, len_b={}",
182
                combined, expected, data_a.len(), data_b.len()
183
            );
184
        }
185
186
        /// Feature: crc16-hardware-acceleration, Property 5: CRC-16 checksum combination round-trip
187
        /// Tests checksum_combine_with_params for CRC-16/IBM-SDLC
188
        /// **Validates: Requirements 6.4**
189
        #[test]
190
        fn prop_crc16_ibm_sdlc_checksum_combine_with_params_roundtrip(
191
            data_a in proptest::collection::vec(any::<u8>(), 0..512),
192
            data_b in proptest::collection::vec(any::<u8>(), 0..512)
193
        ) {
194
            let checksum_a = checksum_with_params(CRC16_IBM_SDLC, &data_a);
195
            let checksum_b = checksum_with_params(CRC16_IBM_SDLC, &data_b);
196
            let combined = checksum_combine_with_params(
197
                CRC16_IBM_SDLC,
198
                checksum_a,
199
                checksum_b,
200
                data_b.len() as u64,
201
            );
202
203
            let mut concatenated = data_a.clone();
204
            concatenated.extend(&data_b);
205
            let expected = checksum_with_params(CRC16_IBM_SDLC, &concatenated);
206
207
            prop_assert_eq!(
208
                combined, expected,
209
                "CRC-16/IBM-SDLC combine_with_params mismatch: combined=0x{:04X}, expected=0x{:04X}, len_a={}, len_b={}",
210
                combined, expected, data_a.len(), data_b.len()
211
            );
212
        }
213
214
        /// Feature: crc16-hardware-acceleration, Property 5: CRC-16 checksum combination round-trip
215
        /// Tests checksum_combine_with_params for CRC-16/T10-DIF
216
        /// **Validates: Requirements 6.4**
217
        #[test]
218
        fn prop_crc16_t10_dif_checksum_combine_with_params_roundtrip(
219
            data_a in proptest::collection::vec(any::<u8>(), 0..512),
220
            data_b in proptest::collection::vec(any::<u8>(), 0..512)
221
        ) {
222
            let checksum_a = checksum_with_params(CRC16_T10_DIF, &data_a);
223
            let checksum_b = checksum_with_params(CRC16_T10_DIF, &data_b);
224
            let combined = checksum_combine_with_params(
225
                CRC16_T10_DIF,
226
                checksum_a,
227
                checksum_b,
228
                data_b.len() as u64,
229
            );
230
231
            let mut concatenated = data_a.clone();
232
            concatenated.extend(&data_b);
233
            let expected = checksum_with_params(CRC16_T10_DIF, &concatenated);
234
235
            prop_assert_eq!(
236
                combined, expected,
237
                "CRC-16/T10-DIF combine_with_params mismatch: combined=0x{:04X}, expected=0x{:04X}, len_a={}, len_b={}",
238
                combined, expected, data_a.len(), data_b.len()
239
            );
240
        }
241
    }
242
}