ps_ecc/reed_solomon/methods/
compute_syndromes_detached.rs1use crate::finite_field::ANTILOG_TABLE;
2use crate::{Polynomial, RSConstructorError, ReedSolomon};
3
4impl ReedSolomon {
5 pub fn compute_syndromes_detached(
16 parity: &[u8],
17 data: &[u8],
18 ) -> Result<Polynomial, RSConstructorError> {
19 Self::check_detached_parity(parity)?;
20
21 let syndromes = (0..parity.len())
22 .map(|i| {
23 Polynomial::eval_coefficient_slices_at(&[parity, data], ANTILOG_TABLE[i + 1].get())
24 })
25 .collect();
26
27 Ok(syndromes)
28 }
29}
30
31#[cfg(test)]
32mod tests {
33 use ps_buffer::ToBuffer;
34
35 use crate::{RSConstructorError, ReedSolomon, MAX_PARITY_BYTES};
36
37 type TestError = Box<dyn std::error::Error>;
38
39 #[test]
40 fn test_compute_syndromes_detached_no_errors() -> Result<(), TestError> {
41 let rs = ReedSolomon::new(3)?;
42 let message = b"Detached".to_buffer()?;
43 let parity = rs.generate_parity(&message)?;
44
45 let syndromes = ReedSolomon::compute_syndromes_detached(&parity, &message)?;
46
47 assert!(syndromes.is_zero());
48
49 Ok(())
50 }
51
52 #[test]
53 fn test_compute_syndromes_detached_with_errors() -> Result<(), TestError> {
54 let rs = ReedSolomon::new(3)?;
55 let message = b"Detached".to_buffer()?;
56 let parity = rs.generate_parity(&message)?;
57
58 let mut corrupted = message.clone()?;
59
60 corrupted[2] ^= 2;
61
62 let syndromes = ReedSolomon::compute_syndromes_detached(&parity, &corrupted)?;
63
64 assert!(syndromes.iter().any(|&s| s != 0));
65
66 Ok(())
67 }
68
69 #[test]
70 fn test_compute_syndromes_detached_empty_data() -> Result<(), TestError> {
71 let rs = ReedSolomon::new(2)?;
72 let parity = rs.generate_parity(&[])?;
73
74 let syndromes = ReedSolomon::compute_syndromes_detached(&parity, &[])?;
75
76 assert_eq!(syndromes.degree(), 0);
77 assert!(syndromes.is_zero());
78
79 Ok(())
80 }
81
82 #[test]
83 fn test_compute_syndromes_detached_max_parity_bytes() -> Result<(), TestError> {
84 let parity = [0u8; MAX_PARITY_BYTES as usize];
85
86 let syndromes = ReedSolomon::compute_syndromes_detached(&parity, &[])?;
87
88 assert!(syndromes.is_zero());
89
90 Ok(())
91 }
92
93 #[test]
94 fn test_compute_syndromes_detached_rejects_odd_parity_length() {
95 for parity_len in [1usize, 3, 125] {
100 let parity = vec![0u8; parity_len];
101
102 assert_eq!(
103 ReedSolomon::compute_syndromes_detached(&parity, &[]),
104 Err(RSConstructorError::OddParityLength(parity_len))
105 );
106 }
107 }
108
109 #[test]
110 fn test_compute_syndromes_detached_oversized_wins_over_odd() {
111 let parity = [0u8; 127];
113
114 assert_eq!(
115 ReedSolomon::compute_syndromes_detached(&parity, &[]),
116 Err(RSConstructorError::ParityTooHigh)
117 );
118 }
119
120 #[test]
121 fn test_compute_syndromes_detached_rejects_oversized_parity() {
122 for parity_len in [127usize, 256, 300] {
126 let parity = vec![0u8; parity_len];
127
128 assert_eq!(
129 ReedSolomon::compute_syndromes_detached(&parity, &[]),
130 Err(RSConstructorError::ParityTooHigh)
131 );
132 }
133 }
134}