ps_ecc/polynomial/implementations/
sub.rs1use std::{
2 borrow::Borrow,
3 ops::{BitXor, Sub},
4};
5
6use crate::{error::PolynomialXorError, Polynomial};
7
8impl<B: Borrow<u8>, I: IntoIterator<Item = B>> Sub<I> for Polynomial {
9 type Output = Result<Self, PolynomialXorError>;
10
11 fn sub(self, rhs: I) -> Self::Output {
20 BitXor::bitxor(self, rhs)
21 }
22}
23
24impl<B: Borrow<u8>, I: IntoIterator<Item = B>> Sub<I> for &Polynomial {
25 type Output = Result<Polynomial, PolynomialXorError>;
26
27 fn sub(self, rhs: I) -> Self::Output {
28 BitXor::bitxor(*self, rhs)
29 }
30}
31
32#[cfg(test)]
33#[allow(clippy::expect_used)]
34mod tests {
35 use std::ops::Sub;
36
37 use crate::{error::PolynomialXorError, Polynomial};
38
39 #[test]
40 fn sub_two_polynomials() {
41 let a = Polynomial::try_from(&[1u8, 2, 3][..]).expect("valid polynomial");
42 let b = Polynomial::try_from(&[4u8, 5, 6][..]).expect("valid polynomial");
43
44 let result = a.sub(b).expect("polynomials are bounded");
45
46 assert_eq!(result.coefficients(), &[1 ^ 4, 2 ^ 5, 3 ^ 6]);
47 }
48
49 #[test]
50 fn sub_different_degrees() {
51 let a = Polynomial::try_from(&[1u8, 2][..]).expect("valid polynomial");
52 let b = Polynomial::try_from(&[3u8, 4, 5, 6][..]).expect("valid polynomial");
53
54 let result = a.sub(b).expect("polynomials are bounded");
55
56 assert_eq!(result.coefficients(), &[1 ^ 3, 2 ^ 4, 5, 6]);
57 }
58
59 #[test]
60 fn sub_cancels_to_zero() {
61 let a = Polynomial::try_from(&[1u8, 2, 3][..]).expect("valid polynomial");
62 let b = Polynomial::try_from(&[1u8, 2, 3][..]).expect("valid polynomial");
63
64 let result = a.sub(b).expect("polynomials are bounded");
65
66 assert_eq!(result.degree(), 0);
67 assert_eq!(result.coefficients(), &[0]);
68 }
69
70 #[test]
71 fn sub_with_references() {
72 let a = Polynomial::try_from(&[1u8, 2, 3][..]).expect("valid polynomial");
73 let b = Polynomial::try_from(&[4u8, 5, 6][..]).expect("valid polynomial");
74
75 let result = (&a).sub(&b).expect("polynomials are bounded");
76
77 assert_eq!(result.coefficients(), &[1 ^ 4, 2 ^ 5, 3 ^ 6]);
78 }
79
80 #[test]
81 fn sub_slice_via_iter() {
82 let a = Polynomial::try_from(&[1u8, 2, 3][..]).expect("valid polynomial");
83 let slice: &[u8] = &[4, 5, 6];
84
85 let result = a.sub(slice.iter()).expect("valid slice");
86
87 assert_eq!(result.coefficients(), &[1 ^ 4, 2 ^ 5, 3 ^ 6]);
88 }
89
90 #[test]
91 fn sub_slice_different_lengths() {
92 let a = Polynomial::try_from(&[1u8, 2][..]).expect("valid polynomial");
93 let slice: &[u8] = &[3, 4, 5, 6];
94
95 let result = a.sub(slice.iter()).expect("valid slice");
96
97 assert_eq!(result.coefficients(), &[1 ^ 3, 2 ^ 4, 5, 6]);
98 }
99
100 #[test]
101 fn sub_iterator() {
102 let a = Polynomial::try_from(&[1u8, 2, 3][..]).expect("valid polynomial");
103 let iter = [4u8, 5, 6].into_iter();
104
105 let result = a.sub(iter).expect("valid iterator");
106
107 assert_eq!(result.coefficients(), &[1 ^ 4, 2 ^ 5, 3 ^ 6]);
108 }
109
110 #[test]
111 fn sub_vec() {
112 let a = Polynomial::try_from(&[1u8, 2, 3][..]).expect("valid polynomial");
113 let vec = vec![4u8, 5, 6, 7];
114
115 let result = a.sub(vec).expect("valid vec");
116
117 assert_eq!(result.coefficients(), &[1 ^ 4, 2 ^ 5, 3 ^ 6, 7]);
118 }
119
120 #[test]
121 fn sub_iterator_too_long_returns_error() {
122 let a = Polynomial::default();
123 let iter = std::iter::repeat_n(1u8, 256);
124
125 let result = a.sub(iter);
126
127 assert_eq!(result, Err(PolynomialXorError::TooManyCoefficients));
128 }
129
130 #[test]
131 fn sub_equals_add() {
132 let a = Polynomial::try_from(&[1u8, 2, 3][..]).expect("valid polynomial");
133 let b = Polynomial::try_from(&[4u8, 5, 6][..]).expect("valid polynomial");
134
135 let sub_result = a.sub(&b).expect("polynomials are bounded");
136
137 let a = Polynomial::try_from(&[1u8, 2, 3][..]).expect("valid polynomial");
138
139 let add_result = std::ops::Add::add(a, &b).expect("polynomials are bounded");
140
141 assert_eq!(sub_result, add_result);
142 }
143}