Skip to main content

ps_ecc/reed_solomon/methods/
generate_parity.rs

1use std::ops::Rem;
2
3use crate::error::RSGenerateParityError;
4use crate::{ParityBytes, Polynomial, ReedSolomon};
5
6use super::super::generator::generator_poly;
7
8impl ReedSolomon {
9    /// Generates parity bytes.
10    /// # Errors
11    /// - [`RSGenerateParityError::SetCoefficients`] is returned if
12    ///   `2 * parity + message.len()` exceeds 255.
13    /// - [`RSGenerateParityError::Division`] is returned if the generator
14    ///   polynomial is zero (not expected to occur).
15    pub fn generate_parity(&self, message: &[u8]) -> Result<ParityBytes, RSGenerateParityError> {
16        let mut p = Polynomial::default();
17
18        p.set_coefficients(self.parity_bytes(), message)?;
19
20        let remainder = p.rem(generator_poly(self.parity()))?;
21
22        Ok(ParityBytes::new(&remainder, self.parity()))
23    }
24}
25
26#[cfg(test)]
27mod tests {
28    use ps_buffer::ToBuffer;
29
30    use crate::ReedSolomon;
31
32    type TestError = Box<dyn std::error::Error>;
33
34    #[test]
35    fn test_generate_parity_no_errors() -> Result<(), TestError> {
36        let rs = ReedSolomon::new(4)?;
37        let message = b"Test".to_buffer()?;
38        let parity = rs.generate_parity(&message)?;
39
40        assert_eq!(parity.len(), 8); // 4 parity * 2 bytes
41
42        Ok(())
43    }
44
45    #[test]
46    fn test_generate_parity_empty_message() -> Result<(), TestError> {
47        let rs = ReedSolomon::new(2)?;
48        let message = b"".to_buffer()?;
49        let parity = rs.generate_parity(&message)?;
50
51        assert_eq!(parity.len(), 4);
52        assert_eq!(parity.as_slice(), &[0, 0, 0, 0]);
53
54        Ok(())
55    }
56
57    #[test]
58    fn test_generate_parity_large_message() -> Result<(), TestError> {
59        let rs = ReedSolomon::new(8)?;
60        let message = vec![42; 200].to_buffer()?;
61        let parity = rs.generate_parity(&message)?;
62
63        assert_eq!(parity.len(), 16); // 8 parity * 2 bytes
64
65        let encoded = rs.encode(&message)?;
66
67        assert_eq!(&encoded[..16], parity.as_slice());
68
69        Ok(())
70    }
71}