ps_ecc/polynomial/implementations/
mul_assign.rs1use std::ops::MulAssign;
2
3use crate::{finite_field::mul, Polynomial};
4
5impl MulAssign<u8> for Polynomial {
6 fn mul_assign(&mut self, scalar: u8) {
11 if scalar == 0 {
12 self.coefficients.fill(0);
13 self.degree = 0;
14
15 return;
16 }
17
18 for coef in &mut self.coefficients[..=self.degree as usize] {
19 *coef = mul(*coef, scalar);
20 }
21 }
22}
23
24#[cfg(test)]
25#[allow(clippy::expect_used)]
26mod tests {
27 use crate::Polynomial;
28
29 #[test]
30 fn mul_assign_by_one() {
31 let mut p = Polynomial::try_from(&[5u8, 10, 15][..]).expect("valid polynomial");
32 let original = p;
33
34 p *= 1;
35
36 assert_eq!(p, original);
37 }
38
39 #[test]
40 fn mul_assign_by_zero() {
41 let mut p = Polynomial::try_from(&[5u8, 10, 15][..]).expect("valid polynomial");
42
43 p *= 0;
44
45 assert_eq!(p.degree(), 0);
46 assert_eq!(p.coefficients(), &[0]);
47 }
48
49 #[test]
50 fn mul_assign_by_two() {
51 let mut p = Polynomial::try_from(&[1u8, 2, 3][..]).expect("valid polynomial");
53
54 p *= 2;
55
56 assert_eq!(p.coefficients(), &[2, 4, 6]);
58 }
59
60 #[test]
61 fn mul_assign_preserves_degree() {
62 let mut p = Polynomial::try_from(&[1u8, 0, 0, 5][..]).expect("valid polynomial");
63
64 assert_eq!(p.degree(), 3);
65
66 p *= 7;
67
68 assert_eq!(p.degree(), 3);
69 }
70
71 #[test]
72 fn mul_assign_zero_polynomial() {
73 let mut p = Polynomial::default();
74
75 p *= 42;
76
77 assert_eq!(p.degree(), 0);
78 assert_eq!(p.coefficients(), &[0]);
79 }
80
81 #[test]
82 fn mul_assign_by_inverse_roundtrip() {
83 use crate::finite_field::inv;
84
85 let original = Polynomial::try_from(&[3u8, 7, 11][..]).expect("valid polynomial");
86 let mut p = original;
87
88 let scale = 5u8;
89 let scale_inv = inv(scale).expect("5 is invertible").get();
90
91 p *= scale;
92 p *= scale_inv;
93
94 assert_eq!(p, original);
95 }
96
97 #[test]
98 fn mul_assign_distributive() {
99 let a = Polynomial::try_from(&[1u8, 2][..]).expect("valid polynomial");
101 let b = Polynomial::try_from(&[3u8, 4][..]).expect("valid polynomial");
102 let c = 5u8;
103
104 let mut sum = (a + b).expect("addition succeeds");
105
106 sum *= c;
107
108 let mut a_scaled = a;
109
110 a_scaled *= c;
111
112 let mut b_scaled = b;
113
114 b_scaled *= c;
115
116 let sum_of_scaled = (a_scaled + b_scaled).expect("addition succeeds");
117
118 assert_eq!(sum, sum_of_scaled);
119 }
120
121 #[test]
122 fn mul_assign_associative_with_field() {
123 use crate::finite_field::mul;
125
126 let original = Polynomial::try_from(&[2u8, 4, 6][..]).expect("valid polynomial");
127 let a = 3u8;
128 let b = 7u8;
129
130 let mut left = original;
131
132 left *= a;
133 left *= b;
134
135 let mut right = original;
136
137 right *= mul(a, b);
138
139 assert_eq!(left, right);
140 }
141
142 #[test]
143 fn mul_assign_high_degree() {
144 let mut coeffs = [0u8; 255];
145
146 coeffs[0] = 1;
147 coeffs[254] = 1;
148
149 let mut p = Polynomial::try_from(&coeffs[..]).expect("valid polynomial");
150
151 assert_eq!(p.degree(), 254);
152
153 p *= 3;
154
155 assert_eq!(p.degree(), 254);
156 assert_eq!(p[0u8], 3);
157 assert_eq!(p[254u8], 3);
158 }
159
160 #[test]
161 fn mul_assign_idempotent_with_one() {
162 let mut p = Polynomial::try_from(&[7u8, 13, 19][..]).expect("valid polynomial");
163
164 p *= 1;
165 p *= 1;
166 p *= 1;
167
168 assert_eq!(p.coefficients(), &[7, 13, 19]);
169 }
170}