ps_ecc/polynomial/methods/
set_coefficients.rs1use crate::{error::PolynomialSetCoefficientsError, Polynomial};
2
3impl Polynomial {
4 pub fn set_coefficients(
15 &mut self,
16 offset: u8,
17 values: &[u8],
18 ) -> Result<(), PolynomialSetCoefficientsError> {
19 if values.is_empty() {
20 return Ok(());
21 }
22
23 let start = offset as usize;
24 let end = start + values.len();
25
26 if end > Self::MAX_COEFFICIENTS as usize {
27 return Err(PolynomialSetCoefficientsError::OutOfBounds { offset, end });
28 }
29
30 self.coefficients[start..end].copy_from_slice(values);
31
32 #[allow(clippy::cast_possible_truncation)]
33 let last = (end - 1) as u8;
34
35 if last > self.degree {
36 self.degree = last;
37 }
38
39 self.trim_degree();
40
41 Ok(())
42 }
43}
44
45#[cfg(test)]
46#[allow(clippy::expect_used)]
47mod tests {
48 use crate::{error::PolynomialSetCoefficientsError, Polynomial};
49
50 #[test]
51 fn below_degree() {
52 let mut p = Polynomial::try_from(&[1u8, 2, 3, 4, 5][..]).expect("valid polynomial");
53
54 p.set_coefficients(1, &[10, 20]).expect("in bounds");
55
56 assert_eq!(p.coefficients(), &[1, 10, 20, 4, 5]);
57 }
58
59 #[test]
60 fn extends_degree() {
61 let mut p = Polynomial::try_from(&[1u8, 2][..]).expect("valid polynomial");
62
63 p.set_coefficients(2, &[3, 4, 5]).expect("in bounds");
64
65 assert_eq!(p.coefficients(), &[1, 2, 3, 4, 5]);
66 }
67
68 #[test]
69 fn trims_degree() {
70 let mut p = Polynomial::try_from(&[1u8, 2, 3][..]).expect("valid polynomial");
71
72 p.set_coefficients(1, &[0, 0]).expect("in bounds");
73
74 assert_eq!(p.coefficients(), &[1]);
75 assert_eq!(p.degree(), 0);
76 }
77
78 #[test]
79 fn trims_to_zero_polynomial() {
80 let mut p = Polynomial::try_from(&[1u8, 2, 3][..]).expect("valid polynomial");
81
82 p.set_coefficients(0, &[0, 0, 0]).expect("in bounds");
83
84 assert_eq!(p.coefficients(), &[0]);
85 assert_eq!(p.degree(), 0);
86 }
87
88 #[test]
89 fn empty_is_noop() {
90 let mut p = Polynomial::try_from(&[1u8, 2, 3][..]).expect("valid polynomial");
91 let before = p;
92
93 p.set_coefficients(0, &[]).expect("in bounds");
94
95 assert_eq!(p, before);
96 }
97
98 #[test]
99 fn at_offset_zero() {
100 let mut p = Polynomial::try_from(&[0u8, 0, 5][..]).expect("valid polynomial");
101
102 p.set_coefficients(0, &[1, 2]).expect("in bounds");
103
104 assert_eq!(p.coefficients(), &[1, 2, 5]);
105 }
106
107 #[test]
108 fn single_element() {
109 let mut p = Polynomial::try_from(&[1u8, 2, 3][..]).expect("valid polynomial");
110
111 p.set_coefficients(1, &[99]).expect("in bounds");
112
113 assert_eq!(p.coefficients(), &[1, 99, 3]);
114 }
115
116 #[test]
117 fn overwrites_entire_polynomial() {
118 let mut p = Polynomial::try_from(&[1u8, 2, 3][..]).expect("valid polynomial");
119
120 p.set_coefficients(0, &[10, 20, 30]).expect("in bounds");
121
122 assert_eq!(p.coefficients(), &[10, 20, 30]);
123 }
124
125 #[test]
126 fn gap_between_old_and_new() {
127 let mut p = Polynomial::try_from(&[1u8][..]).expect("valid polynomial");
128
129 p.set_coefficients(3, &[5, 6]).expect("in bounds");
130
131 assert_eq!(p.coefficients(), &[1, 0, 0, 5, 6]);
132 }
133
134 #[test]
135 fn extends_with_trailing_zeros() {
136 let mut p = Polynomial::try_from(&[1u8, 2][..]).expect("valid polynomial");
137
138 p.set_coefficients(3, &[5, 0]).expect("in bounds");
139
140 assert_eq!(p.coefficients(), &[1, 2, 0, 5]);
141 assert_eq!(p.degree(), 3);
142 }
143
144 #[test]
145 fn overwrites_leading_coefficient() {
146 let mut p = Polynomial::try_from(&[1u8, 2, 3][..]).expect("valid polynomial");
147
148 p.set_coefficients(2, &[99]).expect("in bounds");
149
150 assert_eq!(p.coefficients(), &[1, 2, 99]);
151 assert_eq!(p.degree(), 2);
152 }
153
154 #[test]
155 fn out_of_bounds_returns_error() {
156 let mut p = Polynomial::default();
157
158 let result = p.set_coefficients(250, &[1, 2, 3, 4, 5, 6]);
159
160 assert_eq!(
161 result,
162 Err(PolynomialSetCoefficientsError::OutOfBounds {
163 offset: 250,
164 end: 256
165 })
166 );
167 }
168}