1use crate::utils;
2use anyhow::{Context, Result, anyhow};
3use starkom_bluesky::ThreeAdicField;
4use starkom_ff::PrimeField;
5use std::any::{Any, TypeId};
6use std::collections::BTreeMap;
7use std::ops::{Add, AddAssign, Mul, MulAssign, Neg, Sub, SubAssign};
8use std::sync::{Mutex, OnceLock};
9
10fn make_lagrange0<F: PrimeField>(n: usize) -> Polynomial<F> {
14 let mut coefficients = vec![F::ZERO; n + 1];
15 coefficients[0] = -F::ONE;
16 coefficients[n] = F::ONE;
17 let zero = Polynomial { coefficients };
18 let (quotient, remainder) = zero.horner(F::ONE);
19 assert_eq!(remainder, F::ZERO);
20 quotient * F::try_from(n).unwrap().invert().into_option().unwrap()
21}
22
23#[derive(Debug, Default, Clone, PartialEq, Eq)]
26pub struct Polynomial<F: PrimeField> {
27 coefficients: Vec<F>,
28}
29
30impl<F: PrimeField> Polynomial<F> {
31 pub fn with_coefficients(coefficients: Vec<F>) -> Self {
34 Self { coefficients }
35 }
36
37 pub fn constant(y: F) -> Self {
39 Self {
40 coefficients: vec![y],
41 }
42 }
43
44 pub fn interpolate(points: &[(F, F)]) -> Result<Self> {
50 let k = points.len();
51 let x = points.iter().map(|(x, _)| *x).collect::<Vec<F>>();
52 let l = Self::from_roots(x.as_slice(), F::ONE).context("duplicate X-coordinates")?;
53 let w = {
54 let one = F::ONE;
55 let mut weights = vec![one; k];
56 for i in 0..k {
57 for j in 0..k {
58 if i != j {
59 weights[i] *= x[i] - x[j];
60 }
61 }
62 weights[i] = weights[i]
63 .invert()
64 .into_option()
65 .context("duplicate X-coordinates")?;
66 }
67 weights
68 };
69 let mut result = Self {
70 coefficients: Vec::with_capacity(points.len()),
71 };
72 for i in 0..k {
73 let (basis, remainder) = l.horner(x[i]);
74 assert_eq!(remainder, F::ZERO);
75 let (_, y) = points[i];
76 result += basis * w[i] * y;
77 }
78 Ok(result)
79 }
80
81 pub fn from_roots(roots: &[F], blinding_factor: F) -> Result<Self> {
91 let mut roots = roots.to_vec();
92 roots.sort();
93 for i in 1..roots.len() {
94 if roots[i] == roots[i - 1] {
95 return Err(anyhow!("duplicate roots"));
96 }
97 }
98 let n = roots.len() + 1;
99 let mut coefficients = vec![F::ZERO; n];
100 coefficients[0] = blinding_factor;
101 for i in 1..n {
102 for j in (0..i).rev() {
103 let c = coefficients[j];
104 coefficients[j + 1] -= c * roots[i - 1];
105 }
106 }
107 coefficients.reverse();
108 Ok(Self { coefficients })
109 }
110
111 fn fft2(data: &mut [F], omega: F) {
118 let n = data.len();
119 assert!(n.is_power_of_two());
120
121 let log_n = n.trailing_zeros();
122 assert!(log_n as usize <= F::S);
123
124 for i in 0..n {
125 let (j, _) = i.reverse_bits().overflowing_shr(usize::BITS - log_n);
126 if i < j {
127 data.swap(i, j);
128 }
129 }
130
131 let mut m = 1;
132 for _ in 0..log_n {
133 let step = m * 2;
134 let wm = omega.pow_small(n / step);
135 let mut w = F::ONE;
136 for k in 0..m {
137 for j in (k..n).step_by(step) {
138 let t = w * data[j + m];
139 let u = data[j];
140 data[j] = u + t;
141 data[j + m] = u - t;
142 }
143 w *= wm;
144 }
145 m = step;
146 }
147 }
148
149 fn ifft2(data: &mut [F], omega: F) {
156 Self::fft2(data, omega.invert().into_option().unwrap());
157 let n_inv = F::try_from(data.len()).unwrap().invert().unwrap();
158 for v in data.iter_mut() {
159 *v *= n_inv;
160 }
161 }
162
163 fn two_adic_root_of_unity(n: usize) -> F {
165 assert!(n.is_power_of_two());
166 let k = n.trailing_zeros() as usize;
167 assert!(k <= F::S);
168 let exponent = 1u64 << (F::S - k);
169 F::ROOT_OF_UNITY.pow_u64(exponent)
170 }
171
172 pub fn encode2(mut values: Vec<F>) -> Self {
191 assert!(!values.is_empty());
192 let n = values.len().next_power_of_two();
193 assert!(n.trailing_zeros() as usize <= F::S);
194 values.resize(n, F::ZERO);
195 let omega = Self::two_adic_root_of_unity(values.len());
196 Self::ifft2(values.as_mut_slice(), omega);
197 let mut polynomial = Polynomial {
198 coefficients: values,
199 };
200 polynomial.trim();
201 polynomial
202 }
203
204 pub fn decode2(self) -> Vec<F> {
216 let mut data = self.coefficients;
217 let n = data.len().next_power_of_two();
218 data.resize(n, F::ZERO);
219 let omega = Self::two_adic_root_of_unity(n);
220 Self::fft2(&mut data, omega);
221 data
222 }
223
224 pub fn len(&self) -> usize {
226 self.coefficients.len()
227 }
228
229 pub fn coefficients(&self) -> &[F] {
231 self.coefficients.as_slice()
232 }
233
234 fn degree_bound_of(coefficients: &[F]) -> usize {
235 for (i, &coefficient) in coefficients.iter().enumerate().rev() {
236 if coefficient != F::ZERO {
237 return i + 1;
238 }
239 }
240 0
241 }
242
243 pub fn degree_bound(&self) -> usize {
250 Self::degree_bound_of(self.coefficients.as_slice())
251 }
252
253 pub fn trim(&mut self) {
261 if let Some(i) = self
262 .coefficients
263 .iter()
264 .rposition(|value| *value != F::ZERO)
265 {
266 self.coefficients.truncate(i + 1);
267 } else {
268 self.coefficients.clear();
269 }
270 }
271
272 pub fn pad(&mut self, min_degree_bound: usize) {
275 let new_length = std::cmp::max(min_degree_bound, self.coefficients.len());
276 self.coefficients.resize(new_length, F::ZERO);
277 }
278
279 pub fn take(self) -> Vec<F> {
284 return self.coefficients;
285 }
286
287 pub fn multiply(mut self, mut other: Self) -> Self {
290 self.trim();
291 other.trim();
292
293 let mut lhs = self.coefficients;
294 let mut rhs = other.coefficients;
295
296 if lhs.is_empty() || rhs.is_empty() {
297 return Polynomial {
298 coefficients: vec![],
299 };
300 }
301 if lhs.len() == 1 {
302 return Polynomial { coefficients: rhs } * lhs[0];
303 }
304 if rhs.len() == 1 {
305 return Polynomial { coefficients: lhs } * rhs[0];
306 }
307
308 let n = (lhs.len() + rhs.len() - 1).next_power_of_two();
309
310 lhs.resize(n, F::ZERO);
311 rhs.resize(n, F::ZERO);
312
313 let omega = Self::two_adic_root_of_unity(n);
314 Self::fft2(lhs.as_mut_slice(), omega);
315 Self::fft2(rhs.as_mut_slice(), omega);
316
317 for i in 0..n {
318 lhs[i] *= rhs[i];
319 }
320
321 Self::ifft2(lhs.as_mut_slice(), omega);
322
323 let mut result = Polynomial { coefficients: lhs };
324 result.trim();
325 result
326 }
327
328 fn multiply_many_impl(polynomials: &mut [Self]) -> Self {
330 match polynomials.len() {
331 0 => Polynomial {
332 coefficients: vec![],
333 },
334 1 => std::mem::take(&mut polynomials[0]),
335 2 => {
336 let lhs = std::mem::take(&mut polynomials[0]);
337 let rhs = std::mem::take(&mut polynomials[1]);
338 lhs.multiply(rhs)
339 }
340 n => {
341 let (left, right) = polynomials.split_at_mut(n / 2);
342 let left = Self::multiply_many_impl(left);
343 let right = Self::multiply_many_impl(right);
344 left.multiply(right)
345 }
346 }
347 }
348
349 pub fn multiply_many<const N: usize>(mut polynomials: [Self; N]) -> Self {
355 assert!(N > 0);
356 Self::multiply_many_impl(&mut polynomials)
357 }
358
359 pub fn multiply_values2(mut lhs: Vec<F>, mut rhs: Vec<F>) -> Vec<F> {
368 let n = lhs.len();
369 assert!(n.is_power_of_two());
370 assert!(n.trailing_zeros() as usize + 1 <= F::S);
371 assert_eq!(rhs.len(), n);
372 let omega = Self::two_adic_root_of_unity(n);
373 Self::ifft2(&mut lhs, omega);
374 Self::ifft2(&mut rhs, omega);
375 let lhs_len = Self::degree_bound_of(lhs.as_slice());
376 let rhs_len = Self::degree_bound_of(rhs.as_slice());
377 let m = (lhs_len + rhs_len - 1).next_power_of_two();
378 lhs.resize(m, F::ZERO);
379 rhs.resize(m, F::ZERO);
380 let omega = Self::two_adic_root_of_unity(m);
381 Self::fft2(&mut lhs, omega);
382 Self::fft2(&mut rhs, omega);
383 for i in 0..m {
384 lhs[i] *= rhs[i];
385 }
386 lhs
387 }
388
389 pub fn horner(&self, z: F) -> (Self, F) {
394 if self.coefficients.is_empty() {
395 return (Polynomial::default(), F::ZERO);
396 }
397 let n = self.len() - 1;
398 let mut coefficients = vec![F::ZERO; n];
399 if n < 1 {
400 return (Polynomial { coefficients }, self.coefficients[0]);
401 }
402 coefficients[n - 1] = self.coefficients[n];
403 for i in (1..n).rev() {
404 coefficients[i - 1] = self.coefficients[i] + z * coefficients[i];
405 }
406 let remainder = self.coefficients[0] + z * coefficients[0];
407 (Polynomial { coefficients }, remainder)
408 }
409
410 pub fn divide_by_zero(&self, n: usize) -> Result<Self> {
423 let mut data = self.coefficients.clone();
424 if data.len() < n {
425 data.resize(n, F::ZERO);
426 }
427
428 let degree = data.len() - n;
429 let mut quotient = vec![F::ZERO; degree];
430
431 let neg_one = F::ZERO - F::ONE;
432 for i in 0..degree {
433 let c = data[i] * neg_one;
434 quotient[i] = c;
435 data[i] += c;
436 data[i + n] -= c;
437 }
438
439 let remainder = &data[degree..];
440 if remainder.iter().any(|c| *c != F::ZERO) {
441 return Err(anyhow!("non-zero remainder in division by (x^n - 1)"));
442 }
443
444 if let Some(i) = quotient.iter().rposition(|c| *c != F::ZERO) {
445 quotient.truncate(i + 1);
446 }
447 Ok(Polynomial {
448 coefficients: quotient,
449 })
450 }
451
452 pub fn evaluate(&self, x: F) -> F {
460 let mut y = F::ZERO;
461 for coefficient in self.coefficients.iter().rev() {
462 y = y * x + *coefficient;
463 }
464 y
465 }
466
467 pub fn shift_domain(self) -> Self {
475 let mut coefficients = self.coefficients;
476 let mut shift_pow = F::ONE;
477 for c in coefficients.iter_mut() {
478 *c *= shift_pow;
479 shift_pow *= F::MULTIPLICATIVE_GENERATOR;
480 }
481 Self { coefficients }
482 }
483
484 pub fn domain_element2(index: usize, domain_size: usize) -> F {
494 let omega = Self::two_adic_root_of_unity(domain_size.next_power_of_two());
495 omega.pow_small(index)
496 }
497
498 pub fn coset_element2(index: usize, domain_size: usize) -> F {
505 F::MULTIPLICATIVE_GENERATOR * Self::domain_element2(index, domain_size)
506 }
507
508 pub fn evaluate_on_two_adic_domain(&self, index: usize, domain_size: usize) -> F {
512 self.evaluate(Self::domain_element2(index, domain_size))
513 }
514
515 pub fn evaluate_on_two_adic_coset(&self, index: usize, domain_size: usize) -> F {
519 self.evaluate(Self::coset_element2(index, domain_size))
520 }
521
522 pub fn lde2(self, m: usize) -> Vec<F> {
532 assert!(m.is_power_of_two());
533 assert!(m.trailing_zeros() as usize <= F::S);
534 assert!(self.coefficients.len() < m);
535 let mut data = self.coefficients;
536 data.resize(m, F::ZERO);
537 let omega = Self::two_adic_root_of_unity(m);
538 Self::fft2(&mut data, omega);
539 data
540 }
541
542 pub fn fold2(self, alpha: F) -> Self {
546 let coefficients = self.coefficients();
547 let m = (coefficients.len() + 1) / 2;
548 let new_coefficients = (0..m)
549 .map(|i| {
550 coefficients[2 * i]
551 + alpha * coefficients.get(2 * i + 1).copied().unwrap_or(F::ZERO)
552 })
553 .collect();
554 Self::with_coefficients(new_coefficients)
555 }
556}
557
558impl<F: PrimeField + ThreeAdicField> Polynomial<F> {
559 fn fft3(data: &mut [F], omega: F) {
566 let n = data.len();
567 assert!(utils::is_power_of_three(n));
568
569 let log_n = utils::ilog3(n);
570
571 for i in 0..n {
572 let mut j = 0;
573 let mut tmp = i;
574 for _ in 0..log_n {
575 j = j * 3 + tmp % 3;
576 tmp /= 3;
577 }
578 if i < j {
579 data.swap(i, j);
580 }
581 }
582
583 let omega3 = omega.pow_small(n / 3);
584 let omega3_sq = omega3 * omega3;
585
586 let mut m = 1;
587 for _ in 0..log_n {
588 let step = m * 3;
589 let wm = omega.pow_small(n / step);
590 let mut w = F::ONE;
591 let mut w2 = F::ONE;
592 for k in 0..m {
593 for j in (k..n).step_by(step) {
594 let t0 = data[j];
595 let t1 = w * data[j + m];
596 let t2 = w2 * data[j + 2 * m];
597 data[j] = t0 + t1 + t2;
598 data[j + m] = t0 + omega3 * t1 + omega3_sq * t2;
599 data[j + 2 * m] = t0 + omega3_sq * t1 + omega3 * t2;
600 }
601 w *= wm;
602 w2 = w * w;
603 }
604 m = step;
605 }
606 }
607
608 fn ifft3(data: &mut [F], omega: F) {
615 Self::fft3(data, omega.invert().into_option().unwrap());
616 let n_inv = F::try_from(data.len()).unwrap().invert().unwrap();
617 for v in data.iter_mut() {
618 *v *= n_inv;
619 }
620 }
621
622 fn three_adic_root_of_unity(n: usize) -> F {
624 assert!(utils::is_power_of_three(n));
625 let k = utils::ilog3(n) as u32;
626 assert!(k <= F::T);
627 let exponent = 3u64.pow(F::T - k);
628 F::THREE_ADIC_ROOT_OF_UNITY.pow_u64(exponent)
629 }
630
631 pub fn encode3(mut values: Vec<F>) -> Self {
650 assert!(!values.is_empty());
651 let n = utils::next_power_of_three(values.len());
652 assert!(utils::ilog3(n) <= F::T as usize);
653 values.resize(n, F::ZERO);
654 let omega = Self::three_adic_root_of_unity(values.len());
655 Self::ifft3(values.as_mut_slice(), omega);
656 let mut polynomial = Polynomial {
657 coefficients: values,
658 };
659 polynomial.trim();
660 polynomial
661 }
662
663 pub fn decode3(self) -> Vec<F> {
675 let mut data = self.coefficients;
676 let n = utils::next_power_of_three(data.len());
677 data.resize(n, F::ZERO);
678 let omega = Self::three_adic_root_of_unity(n);
679 Self::fft3(&mut data, omega);
680 data
681 }
682
683 pub fn domain_element3(index: usize, domain_size: usize) -> F {
693 let omega = Self::three_adic_root_of_unity(utils::next_power_of_three(domain_size));
694 omega.pow_small(index)
695 }
696
697 pub fn coset_element3(index: usize, domain_size: usize) -> F {
704 F::MULTIPLICATIVE_GENERATOR * Self::domain_element3(index, domain_size)
705 }
706
707 pub fn evaluate_on_three_adic_domain(&self, index: usize, domain_size: usize) -> F {
711 self.evaluate(Self::domain_element3(index, domain_size))
712 }
713
714 pub fn evaluate_on_three_adic_coset(&self, index: usize, domain_size: usize) -> F {
718 self.evaluate(Self::coset_element3(index, domain_size))
719 }
720
721 pub fn lde3(self, m: usize) -> Vec<F> {
732 assert!(utils::is_power_of_three(m));
733 assert!(utils::ilog3(m) as u32 <= F::T);
734 assert!(self.coefficients.len() < m);
735 let mut data = self.coefficients;
736 data.resize(m, F::ZERO);
737 let omega = Self::three_adic_root_of_unity(m);
738 Self::fft3(&mut data, omega);
739 data
740 }
741
742 pub fn fold3(self, alpha: F) -> Self {
746 let coefficients = self.coefficients();
747 let m = (coefficients.len() + 2) / 3;
748 let alpha_square = alpha * alpha;
749 let new_coefficients = (0..m)
750 .map(|i| {
751 coefficients[3 * i]
752 + alpha * coefficients.get(3 * i + 1).copied().unwrap_or(F::ZERO)
753 + alpha_square * coefficients.get(3 * i + 2).copied().unwrap_or(F::ZERO)
754 })
755 .collect();
756 Self::with_coefficients(new_coefficients)
757 }
758
759 pub fn multiply_values3(mut lhs: Vec<F>, mut rhs: Vec<F>) -> Vec<F> {
768 let n = lhs.len();
769 assert!(utils::is_power_of_three(n));
770 assert!(utils::ilog3(n) as u32 + 1 <= F::T);
771 assert_eq!(rhs.len(), n);
772 let omega = Self::three_adic_root_of_unity(n);
773 Self::ifft3(&mut lhs, omega);
774 Self::ifft3(&mut rhs, omega);
775 let lhs_len = Self::degree_bound_of(lhs.as_slice());
776 let rhs_len = Self::degree_bound_of(rhs.as_slice());
777 let m = utils::next_power_of_three(lhs_len + rhs_len - 1);
778 lhs.resize(m, F::ZERO);
779 rhs.resize(m, F::ZERO);
780 let omega = Self::three_adic_root_of_unity(m);
781 Self::fft3(&mut lhs, omega);
782 Self::fft3(&mut rhs, omega);
783 for i in 0..m {
784 lhs[i] *= rhs[i];
785 }
786 lhs
787 }
788
789 pub fn lagrange0(n: usize) -> &'static Self {
805 assert!(n.is_power_of_two());
806 let k = n.trailing_zeros() as usize;
807 assert!(k <= F::S);
808
809 static CACHE: OnceLock<Mutex<BTreeMap<(TypeId, usize), &'static (dyn Any + Send + Sync)>>> =
810 OnceLock::new();
811 let cache = CACHE.get_or_init(|| Mutex::new(BTreeMap::new()));
812
813 let polynomial = {
814 let mut map = cache.lock().unwrap();
815 *map.entry((TypeId::of::<F>(), k)).or_insert_with(|| {
816 Box::leak(Box::new(make_lagrange0::<F>(1 << k))) as &'static (dyn Any + Send + Sync)
817 })
818 };
819
820 polynomial.downcast_ref::<Polynomial<F>>().unwrap()
821 }
822}
823
824impl<F: PrimeField> Neg for Polynomial<F> {
825 type Output = Self;
826
827 fn neg(mut self) -> Self::Output {
828 for coefficient in &mut self.coefficients {
829 *coefficient = -*coefficient;
830 }
831 self
832 }
833}
834
835impl<F: PrimeField> Add<Polynomial<F>> for Polynomial<F> {
836 type Output = Self;
837
838 fn add(mut self, rhs: Self) -> Self::Output {
839 if rhs.len() > self.len() {
840 return rhs + self;
841 }
842 for i in 0..rhs.len() {
843 self.coefficients[i] += rhs.coefficients[i];
844 }
845 self
846 }
847}
848
849impl<F: PrimeField> AddAssign<Polynomial<F>> for Polynomial<F> {
850 fn add_assign(&mut self, mut rhs: Self) {
851 if rhs.len() > self.len() {
852 for i in 0..self.len() {
853 rhs.coefficients[i] += self.coefficients[i];
854 }
855 self.coefficients = rhs.coefficients;
856 } else {
857 for i in 0..rhs.len() {
858 self.coefficients[i] += rhs.coefficients[i];
859 }
860 }
861 }
862}
863
864impl<F: PrimeField> Add<F> for Polynomial<F> {
865 type Output = Self;
866
867 fn add(mut self, rhs: F) -> Self::Output {
868 if self.coefficients.is_empty() {
869 self.coefficients.push(rhs);
870 } else {
871 self.coefficients[0] += rhs;
872 }
873 self
874 }
875}
876
877impl<F: PrimeField> AddAssign<F> for Polynomial<F> {
878 fn add_assign(&mut self, rhs: F) {
879 if self.coefficients.is_empty() {
880 self.coefficients.push(rhs);
881 } else {
882 self.coefficients[0] += rhs;
883 }
884 }
885}
886
887impl<F: PrimeField> Sub<Polynomial<F>> for Polynomial<F> {
888 type Output = Self;
889
890 fn sub(mut self, rhs: Self) -> Self::Output {
891 if rhs.len() > self.len() {
892 return -(rhs - self);
893 }
894 for i in 0..rhs.len() {
895 self.coefficients[i] -= rhs.coefficients[i];
896 }
897 self
898 }
899}
900
901impl<F: PrimeField> SubAssign<Polynomial<F>> for Polynomial<F> {
902 fn sub_assign(&mut self, mut rhs: Self) {
903 if rhs.len() > self.len() {
904 for i in 0..self.len() {
905 rhs.coefficients[i] -= self.coefficients[i];
906 }
907 self.coefficients = rhs.coefficients;
908 for i in 0..self.len() {
909 self.coefficients[i] = -self.coefficients[i];
910 }
911 } else {
912 for i in 0..rhs.len() {
913 self.coefficients[i] -= rhs.coefficients[i];
914 }
915 }
916 }
917}
918
919impl<F: PrimeField> Sub<F> for Polynomial<F> {
920 type Output = Self;
921
922 fn sub(mut self, rhs: F) -> Self::Output {
923 if self.coefficients.is_empty() {
924 self.coefficients.push(-rhs);
925 } else {
926 self.coefficients[0] -= rhs;
927 }
928 self
929 }
930}
931
932impl<F: PrimeField> SubAssign<F> for Polynomial<F> {
933 fn sub_assign(&mut self, rhs: F) {
934 if self.coefficients.is_empty() {
935 self.coefficients.push(-rhs);
936 } else {
937 self.coefficients[0] -= rhs;
938 }
939 }
940}
941
942impl<F: PrimeField> Mul<F> for Polynomial<F> {
943 type Output = Self;
944
945 fn mul(mut self, rhs: F) -> Self::Output {
946 for i in 0..self.len() {
947 self.coefficients[i] *= rhs;
948 }
949 self
950 }
951}
952
953impl<F: PrimeField> MulAssign<F> for Polynomial<F> {
954 fn mul_assign(&mut self, rhs: F) {
955 for i in 0..self.len() {
956 self.coefficients[i] *= rhs;
957 }
958 }
959}
960
961impl<F: PrimeField> Mul<Polynomial<F>> for Polynomial<F> {
962 type Output = Self;
963
964 fn mul(self, rhs: Self) -> Self::Output {
965 self.multiply(rhs)
966 }
967}
968
969impl<F: PrimeField> MulAssign<Polynomial<F>> for Polynomial<F> {
970 fn mul_assign(&mut self, rhs: Self) {
971 *self = std::mem::take(self).multiply(rhs);
972 }
973}
974
975#[cfg(test)]
976mod tests {
977 use starkom_bluesky::Scalar;
978 use starkom_ff::Field;
979
980 type Polynomial = super::Polynomial<Scalar>;
981
982 #[inline(always)]
983 const fn from_const(value: u64) -> Scalar {
984 Scalar::from_const(value)
985 }
986
987 #[inline(always)]
988 fn get_random_scalar() -> Scalar {
989 Scalar::random_default()
990 }
991
992 fn from_roots(roots: &[Scalar]) -> Polynomial {
993 Polynomial::from_roots(roots, get_random_scalar()).unwrap()
994 }
995
996 #[test]
997 fn test_constant() {
998 let p = Polynomial::constant(from_const(42));
999 assert_eq!(p.evaluate(from_const(12)), from_const(42));
1000 assert_eq!(p.evaluate(from_const(34)), from_const(42));
1001 assert_eq!(p.evaluate(from_const(42)), from_const(42));
1002 }
1003
1004 #[test]
1005 fn test_zero() {
1006 let p = Polynomial::with_coefficients(vec![]);
1007 assert_eq!(p, Polynomial::default());
1008 assert_eq!(p.len(), 0);
1009 assert_eq!(p.degree_bound(), 0);
1010 assert_eq!(p.evaluate(from_const(42)), from_const(0));
1011 }
1012
1013 #[test]
1014 fn test_with_coefficients() {
1015 let p = Polynomial::with_coefficients(vec![from_const(12), from_const(34), from_const(56)]);
1016 assert_eq!(p.len(), 3);
1017 assert_eq!(p.degree_bound(), 3);
1018 assert_eq!(
1019 p.take(),
1020 vec![from_const(12), from_const(34), from_const(56)]
1021 );
1022 }
1023
1024 #[test]
1025 fn test_low_degree() {
1026 let p = Polynomial::with_coefficients(vec![
1027 from_const(12),
1028 from_const(34),
1029 from_const(56),
1030 from_const(0),
1031 from_const(0),
1032 ]);
1033 assert_eq!(p.len(), 5);
1034 assert_eq!(p.degree_bound(), 3);
1035 }
1036
1037 #[test]
1038 fn test_skip_degree() {
1039 let p = Polynomial::with_coefficients(vec![
1040 from_const(0),
1041 from_const(0),
1042 from_const(12),
1043 from_const(34),
1044 from_const(56),
1045 ]);
1046 assert_eq!(p.len(), 5);
1047 assert_eq!(p.degree_bound(), 5);
1048 }
1049
1050 #[test]
1051 fn test_trim_degree() {
1052 let mut p = Polynomial::with_coefficients(vec![
1053 from_const(12),
1054 from_const(34),
1055 from_const(56),
1056 from_const(0),
1057 from_const(0),
1058 ]);
1059 p.trim();
1060 assert_eq!(p.len(), 3);
1061 assert_eq!(p.degree_bound(), 3);
1062 }
1063
1064 #[test]
1065 fn test_no_trim() {
1066 let mut p = Polynomial::with_coefficients(vec![
1067 from_const(0),
1068 from_const(0),
1069 from_const(12),
1070 from_const(34),
1071 from_const(56),
1072 ]);
1073 p.trim();
1074 assert_eq!(p.len(), 5);
1075 assert_eq!(p.degree_bound(), 5);
1076 }
1077
1078 #[test]
1079 fn test_trim_all_zero() {
1080 let mut p =
1081 Polynomial::with_coefficients(vec![from_const(0), from_const(0), from_const(0)]);
1082 p.trim();
1083 assert_eq!(p.len(), p.degree_bound());
1084 assert_eq!(p, Polynomial::default());
1085 }
1086
1087 #[test]
1088 fn test_pad_extends() {
1089 let mut p = Polynomial::with_coefficients(vec![from_const(12), from_const(34)]);
1090 p.pad(5);
1091 assert_eq!(p.len(), 5);
1092 assert_eq!(
1093 p.take(),
1094 vec![
1095 from_const(12),
1096 from_const(34),
1097 from_const(0),
1098 from_const(0),
1099 from_const(0)
1100 ]
1101 );
1102 }
1103
1104 #[test]
1105 fn test_pad_exact() {
1106 let mut p =
1107 Polynomial::with_coefficients(vec![from_const(12), from_const(34), from_const(56)]);
1108 p.pad(3);
1109 assert_eq!(p.len(), 3);
1110 assert_eq!(
1111 p.take(),
1112 vec![from_const(12), from_const(34), from_const(56)]
1113 );
1114 }
1115
1116 #[test]
1117 fn test_pad_no_shrink() {
1118 let mut p = Polynomial::with_coefficients(vec![
1119 from_const(12),
1120 from_const(34),
1121 from_const(56),
1122 from_const(78),
1123 ]);
1124 p.pad(2);
1125 assert_eq!(p.len(), 4);
1126 assert_eq!(
1127 p.take(),
1128 vec![
1129 from_const(12),
1130 from_const(34),
1131 from_const(56),
1132 from_const(78)
1133 ]
1134 );
1135 }
1136
1137 #[test]
1138 fn test_pad_empty() {
1139 let mut p = Polynomial::default();
1140 p.pad(3);
1141 assert_eq!(p.len(), 3);
1142 assert_eq!(p.take(), vec![from_const(0), from_const(0), from_const(0)]);
1143 }
1144
1145 #[test]
1146 fn test_pad_zero_bound() {
1147 let mut p = Polynomial::with_coefficients(vec![from_const(12), from_const(34)]);
1148 p.pad(0);
1149 assert_eq!(p.len(), 2);
1150 assert_eq!(p.take(), vec![from_const(12), from_const(34)]);
1151 }
1152
1153 #[test]
1154 fn test_pad_preserves_evaluation() {
1155 let mut p =
1156 Polynomial::with_coefficients(vec![from_const(1), from_const(2), from_const(3)]);
1157 let before = p.evaluate(from_const(7));
1158 p.pad(6);
1159 assert_eq!(p.evaluate(from_const(7)), before);
1160 }
1161
1162 #[test]
1163 fn test_no_roots() {
1164 let p = from_roots(&[]);
1165 assert_eq!(p.len(), 1);
1166 assert_eq!(p.degree_bound(), 1);
1167 assert_ne!(p.evaluate(from_const(12)), from_const(0));
1168 assert_ne!(p.evaluate(from_const(34)), from_const(0));
1169 assert_ne!(p.evaluate(from_const(56)), from_const(0));
1170 assert_ne!(p.evaluate(from_const(78)), from_const(0));
1171 assert_ne!(p.evaluate(from_const(90)), from_const(0));
1172 assert_ne!(p.evaluate(from_const(13)), from_const(0));
1173 assert_ne!(p.evaluate(from_const(57)), from_const(0));
1174 assert_ne!(p.evaluate(from_const(92)), from_const(0));
1175 assert_ne!(p.evaluate(from_const(46)), from_const(0));
1176 assert_ne!(p.evaluate(from_const(80)), from_const(0));
1177 }
1178
1179 #[test]
1180 fn test_one_root() {
1181 let p = from_roots(&[from_const(12)]);
1182 assert_eq!(p.len(), 2);
1183 assert_eq!(p.degree_bound(), 2);
1184 assert_eq!(p.evaluate(from_const(12)), from_const(0));
1185 assert_ne!(p.evaluate(from_const(34)), from_const(0));
1186 assert_ne!(p.evaluate(from_const(56)), from_const(0));
1187 assert_ne!(p.evaluate(from_const(78)), from_const(0));
1188 assert_ne!(p.evaluate(from_const(90)), from_const(0));
1189 assert_ne!(p.evaluate(from_const(13)), from_const(0));
1190 assert_ne!(p.evaluate(from_const(57)), from_const(0));
1191 assert_ne!(p.evaluate(from_const(92)), from_const(0));
1192 assert_ne!(p.evaluate(from_const(46)), from_const(0));
1193 assert_ne!(p.evaluate(from_const(80)), from_const(0));
1194 let (q, v) = p.horner(from_const(12));
1195 assert_eq!(q.len(), 1);
1196 assert_eq!(q.degree_bound(), 1);
1197 assert_eq!(v, from_const(0));
1198 let (q, v) = p.horner(from_const(34));
1199 assert_eq!(q.len(), 1);
1200 assert_eq!(q.degree_bound(), 1);
1201 assert_ne!(v, from_const(0));
1202 }
1203
1204 #[test]
1205 fn test_three_roots() {
1206 let p = from_roots(&[from_const(12), from_const(34), from_const(56)]);
1207 assert_eq!(p.len(), 4);
1208 assert_eq!(p.degree_bound(), 4);
1209 assert_eq!(p.evaluate(from_const(12)), from_const(0));
1210 assert_eq!(p.evaluate(from_const(34)), from_const(0));
1211 assert_eq!(p.evaluate(from_const(56)), from_const(0));
1212 assert_ne!(p.evaluate(from_const(78)), from_const(0));
1213 assert_ne!(p.evaluate(from_const(90)), from_const(0));
1214 assert_ne!(p.evaluate(from_const(13)), from_const(0));
1215 assert_ne!(p.evaluate(from_const(57)), from_const(0));
1216 assert_ne!(p.evaluate(from_const(92)), from_const(0));
1217 assert_ne!(p.evaluate(from_const(46)), from_const(0));
1218 assert_ne!(p.evaluate(from_const(80)), from_const(0));
1219 let (q, v) = p.horner(from_const(12));
1220 assert_eq!(q.len(), 3);
1221 assert_eq!(q.degree_bound(), 3);
1222 assert_eq!(v, from_const(0));
1223 let (q, v) = q.horner(from_const(34));
1224 assert_eq!(q.len(), 2);
1225 assert_eq!(q.degree_bound(), 2);
1226 assert_eq!(v, from_const(0));
1227 let (q, v) = q.horner(from_const(56));
1228 assert_eq!(q.len(), 1);
1229 assert_eq!(q.degree_bound(), 1);
1230 assert_eq!(v, from_const(0));
1231 let (q, v) = p.horner(from_const(78));
1232 assert_eq!(q.len(), 3);
1233 assert_eq!(q.degree_bound(), 3);
1234 assert_ne!(v, from_const(0));
1235 let (q, v) = p.horner(from_const(90));
1236 assert_eq!(q.len(), 3);
1237 assert_eq!(q.degree_bound(), 3);
1238 assert_ne!(v, from_const(0));
1239 }
1240
1241 #[test]
1242 fn test_three_roots_reverse_order() {
1243 let p = from_roots(&[from_const(56), from_const(34), from_const(12)]);
1244 assert_eq!(p.len(), 4);
1245 assert_eq!(p.degree_bound(), 4);
1246 assert_eq!(p.evaluate(from_const(12)), from_const(0));
1247 assert_eq!(p.evaluate(from_const(34)), from_const(0));
1248 assert_eq!(p.evaluate(from_const(56)), from_const(0));
1249 assert_ne!(p.evaluate(from_const(78)), from_const(0));
1250 assert_ne!(p.evaluate(from_const(90)), from_const(0));
1251 assert_ne!(p.evaluate(from_const(13)), from_const(0));
1252 assert_ne!(p.evaluate(from_const(57)), from_const(0));
1253 assert_ne!(p.evaluate(from_const(92)), from_const(0));
1254 assert_ne!(p.evaluate(from_const(46)), from_const(0));
1255 assert_ne!(p.evaluate(from_const(80)), from_const(0));
1256 let (q, v) = p.horner(from_const(12));
1257 assert_eq!(q.len(), 3);
1258 assert_eq!(q.degree_bound(), 3);
1259 assert_eq!(v, from_const(0));
1260 let (q, v) = q.horner(from_const(34));
1261 assert_eq!(q.len(), 2);
1262 assert_eq!(q.degree_bound(), 2);
1263 assert_eq!(v, from_const(0));
1264 let (q, v) = q.horner(from_const(56));
1265 assert_eq!(q.len(), 1);
1266 assert_eq!(q.degree_bound(), 1);
1267 assert_eq!(v, from_const(0));
1268 let (q, v) = p.horner(from_const(78));
1269 assert_eq!(q.len(), 3);
1270 assert_eq!(q.degree_bound(), 3);
1271 assert_ne!(v, from_const(0));
1272 let (q, v) = p.horner(from_const(90));
1273 assert_eq!(q.len(), 3);
1274 assert_eq!(q.degree_bound(), 3);
1275 assert_ne!(v, from_const(0));
1276 }
1277
1278 #[test]
1279 fn test_seven_roots() {
1280 let p = from_roots(&[
1281 from_const(12),
1282 from_const(34),
1283 from_const(56),
1284 from_const(78),
1285 from_const(90),
1286 from_const(13),
1287 from_const(57),
1288 ]);
1289 assert_eq!(p.len(), 8);
1290 assert_eq!(p.degree_bound(), 8);
1291 assert_eq!(p.evaluate(from_const(12)), from_const(0));
1292 assert_eq!(p.evaluate(from_const(34)), from_const(0));
1293 assert_eq!(p.evaluate(from_const(56)), from_const(0));
1294 assert_eq!(p.evaluate(from_const(78)), from_const(0));
1295 assert_eq!(p.evaluate(from_const(90)), from_const(0));
1296 assert_eq!(p.evaluate(from_const(13)), from_const(0));
1297 assert_eq!(p.evaluate(from_const(57)), from_const(0));
1298 assert_ne!(p.evaluate(from_const(92)), from_const(0));
1299 assert_ne!(p.evaluate(from_const(46)), from_const(0));
1300 assert_ne!(p.evaluate(from_const(80)), from_const(0));
1301 }
1302
1303 #[test]
1304 fn test_seven_roots_reverse_order() {
1305 let p = from_roots(&[
1306 from_const(57),
1307 from_const(13),
1308 from_const(90),
1309 from_const(78),
1310 from_const(56),
1311 from_const(34),
1312 from_const(12),
1313 ]);
1314 assert_eq!(p.len(), 8);
1315 assert_eq!(p.degree_bound(), 8);
1316 assert_eq!(p.evaluate(from_const(12)), from_const(0));
1317 assert_eq!(p.evaluate(from_const(34)), from_const(0));
1318 assert_eq!(p.evaluate(from_const(56)), from_const(0));
1319 assert_eq!(p.evaluate(from_const(78)), from_const(0));
1320 assert_eq!(p.evaluate(from_const(90)), from_const(0));
1321 assert_eq!(p.evaluate(from_const(13)), from_const(0));
1322 assert_eq!(p.evaluate(from_const(57)), from_const(0));
1323 assert_ne!(p.evaluate(from_const(92)), from_const(0));
1324 assert_ne!(p.evaluate(from_const(46)), from_const(0));
1325 assert_ne!(p.evaluate(from_const(80)), from_const(0));
1326 }
1327
1328 #[test]
1329 fn test_duplicate_roots() {
1330 assert!(
1331 Polynomial::from_roots(
1332 &[
1333 from_const(12),
1334 from_const(34),
1335 from_const(56),
1336 from_const(12),
1337 from_const(90),
1338 from_const(12),
1339 from_const(57),
1340 ],
1341 get_random_scalar()
1342 )
1343 .is_err()
1344 );
1345 }
1346
1347 #[test]
1348 fn test_interpolate_zero_points() {
1349 let p = Polynomial::interpolate(&[]).unwrap();
1350 assert_eq!(p, Polynomial::default());
1351 }
1352
1353 #[test]
1354 fn test_interpolate_one_point1() {
1355 let p = Polynomial::interpolate(&[(from_const(12), from_const(34))]).unwrap();
1356 assert_eq!(p.len(), 1);
1357 assert_eq!(p.degree_bound(), 1);
1358 assert_eq!(p.evaluate(from_const(12)), from_const(34));
1359 }
1360
1361 #[test]
1362 fn test_interpolate_one_point2() {
1363 let p = Polynomial::interpolate(&[(from_const(34), from_const(56))]).unwrap();
1364 assert_eq!(p.len(), 1);
1365 assert_eq!(p.degree_bound(), 1);
1366 assert_eq!(p.evaluate(from_const(34)), from_const(56));
1367 }
1368
1369 #[test]
1370 fn test_interpolate_two_points1() {
1371 let p = Polynomial::interpolate(&[
1372 (from_const(12), from_const(34)),
1373 (from_const(56), from_const(78)),
1374 ])
1375 .unwrap();
1376 assert_eq!(p.len(), 2);
1377 assert_eq!(p.degree_bound(), 2);
1378 assert_eq!(p.evaluate(from_const(12)), from_const(34));
1379 assert_eq!(p.evaluate(from_const(56)), from_const(78));
1380 }
1381
1382 #[test]
1383 fn test_interpolate_two_points2() {
1384 let p = Polynomial::interpolate(&[
1385 (from_const(34), from_const(12)),
1386 (from_const(78), from_const(56)),
1387 ])
1388 .unwrap();
1389 assert_eq!(p.len(), 2);
1390 assert_eq!(p.degree_bound(), 2);
1391 assert_eq!(p.evaluate(from_const(34)), from_const(12));
1392 assert_eq!(p.evaluate(from_const(78)), from_const(56));
1393 }
1394
1395 #[test]
1396 fn test_interpolate_three_points1() {
1397 let p = Polynomial::interpolate(&[
1398 (from_const(12), from_const(34)),
1399 (from_const(56), from_const(78)),
1400 (from_const(90), from_const(12)),
1401 ])
1402 .unwrap();
1403 assert_eq!(p.len(), 3);
1404 assert_eq!(p.degree_bound(), 3);
1405 assert_eq!(p.evaluate(from_const(12)), from_const(34));
1406 assert_eq!(p.evaluate(from_const(56)), from_const(78));
1407 assert_eq!(p.evaluate(from_const(90)), from_const(12));
1408 }
1409
1410 #[test]
1411 fn test_interpolate_three_points2() {
1412 let p = Polynomial::interpolate(&[
1413 (from_const(34), from_const(12)),
1414 (from_const(78), from_const(56)),
1415 (from_const(12), from_const(90)),
1416 ])
1417 .unwrap();
1418 assert_eq!(p.len(), 3);
1419 assert_eq!(p.degree_bound(), 3);
1420 assert_eq!(p.evaluate(from_const(34)), from_const(12));
1421 assert_eq!(p.evaluate(from_const(78)), from_const(56));
1422 assert_eq!(p.evaluate(from_const(12)), from_const(90));
1423 }
1424
1425 #[test]
1426 fn test_duplicate_coordinates() {
1427 assert!(
1428 Polynomial::interpolate(&[
1429 (from_const(12), from_const(34)),
1430 (from_const(56), from_const(78)),
1431 (from_const(12), from_const(90)),
1432 ])
1433 .is_err()
1434 );
1435 }
1436
1437 #[test]
1438 fn test_encode2_one_value_1() {
1439 let p1 = Polynomial::encode2(vec![from_const(42)]);
1440 let p2 = Polynomial::encode2(vec![from_const(42)]);
1441 assert_eq!(p1, p2);
1442 assert_eq!(p1.len(), 1);
1443 assert_eq!(p1.degree_bound(), 1);
1444 assert_eq!(p2.len(), 1);
1445 assert_eq!(p2.degree_bound(), 1);
1446 assert_eq!(
1447 p1.evaluate(Polynomial::domain_element2(0, 1)),
1448 from_const(42)
1449 );
1450 assert_eq!(p1.evaluate_on_two_adic_domain(0, 1), from_const(42));
1451 assert_eq!(
1452 p2.evaluate(Polynomial::domain_element2(0, 1)),
1453 from_const(42)
1454 );
1455 assert_eq!(p2.evaluate_on_two_adic_domain(0, 1), from_const(42));
1456 }
1457
1458 #[test]
1459 fn test_encode2_one_value_2() {
1460 let p1 = Polynomial::encode2(vec![from_const(42)]);
1461 let p2 = Polynomial::encode2(vec![from_const(123)]);
1462 assert_eq!(p2.len(), 1);
1463 assert_eq!(p2.degree_bound(), 1);
1464 assert_ne!(p1, p2);
1465 assert_eq!(
1466 p2.evaluate(Polynomial::domain_element2(0, 1)),
1467 from_const(123)
1468 );
1469 assert_eq!(p2.evaluate_on_two_adic_domain(0, 1), from_const(123));
1470 }
1471
1472 #[test]
1473 fn test_encode2_two_values_1() {
1474 let p1 = Polynomial::encode2(vec![from_const(12), from_const(34)]);
1475 let p2 = Polynomial::encode2(vec![from_const(12), from_const(34)]);
1476 assert_eq!(p1, p2);
1477 assert_eq!(p1.len(), 2);
1478 assert_eq!(p1.degree_bound(), 2);
1479 assert_eq!(p2.len(), 2);
1480 assert_eq!(p2.degree_bound(), 2);
1481 assert_eq!(
1482 p1.evaluate(Polynomial::domain_element2(0, 2)),
1483 from_const(12)
1484 );
1485 assert_eq!(p1.evaluate_on_two_adic_domain(0, 2), from_const(12));
1486 assert_eq!(
1487 p1.evaluate(Polynomial::domain_element2(1, 2)),
1488 from_const(34)
1489 );
1490 assert_eq!(p1.evaluate_on_two_adic_domain(1, 2), from_const(34));
1491 assert_eq!(
1492 p2.evaluate(Polynomial::domain_element2(0, 2)),
1493 from_const(12)
1494 );
1495 assert_eq!(p2.evaluate_on_two_adic_domain(0, 2), from_const(12));
1496 assert_eq!(
1497 p2.evaluate(Polynomial::domain_element2(1, 2)),
1498 from_const(34)
1499 );
1500 assert_eq!(p2.evaluate_on_two_adic_domain(1, 2), from_const(34));
1501 }
1502
1503 #[test]
1504 fn test_encode2_two_values_2() {
1505 let p1 = Polynomial::encode2(vec![from_const(12), from_const(34)]);
1506 let p2 = Polynomial::encode2(vec![from_const(78), from_const(56)]);
1507 assert_eq!(p1.len(), 2);
1508 assert_eq!(p1.degree_bound(), 2);
1509 assert_eq!(p2.len(), 2);
1510 assert_eq!(p2.degree_bound(), 2);
1511 assert_ne!(p1, p2);
1512 assert_eq!(
1513 p2.evaluate(Polynomial::domain_element2(0, 2)),
1514 from_const(78)
1515 );
1516 assert_eq!(p2.evaluate_on_two_adic_domain(0, 2), from_const(78));
1517 assert_eq!(
1518 p2.evaluate(Polynomial::domain_element2(1, 2)),
1519 from_const(56)
1520 );
1521 assert_eq!(p2.evaluate_on_two_adic_domain(1, 2), from_const(56));
1522 }
1523
1524 #[test]
1525 fn test_encode2_three_values_1() {
1526 let p1 = Polynomial::encode2(vec![from_const(12), from_const(34), from_const(56)]);
1527 let p2 = Polynomial::encode2(vec![from_const(12), from_const(34), from_const(56)]);
1528 assert_eq!(p1, p2);
1529 assert_eq!(p1.len(), 4);
1530 assert_eq!(p1.degree_bound(), 4);
1531 assert_eq!(p2.len(), 4);
1532 assert_eq!(p2.degree_bound(), 4);
1533 assert_eq!(
1534 p1.evaluate(Polynomial::domain_element2(0, 3)),
1535 from_const(12)
1536 );
1537 assert_eq!(p1.evaluate_on_two_adic_domain(0, 3), from_const(12));
1538 assert_eq!(
1539 p1.evaluate(Polynomial::domain_element2(0, 4)),
1540 from_const(12)
1541 );
1542 assert_eq!(p1.evaluate_on_two_adic_domain(0, 4), from_const(12));
1543 assert_eq!(
1544 p1.evaluate(Polynomial::domain_element2(1, 3)),
1545 from_const(34)
1546 );
1547 assert_eq!(p1.evaluate_on_two_adic_domain(1, 3), from_const(34));
1548 assert_eq!(
1549 p1.evaluate(Polynomial::domain_element2(1, 4)),
1550 from_const(34)
1551 );
1552 assert_eq!(p1.evaluate_on_two_adic_domain(1, 4), from_const(34));
1553 assert_eq!(
1554 p1.evaluate(Polynomial::domain_element2(2, 3)),
1555 from_const(56)
1556 );
1557 assert_eq!(p1.evaluate_on_two_adic_domain(2, 3), from_const(56));
1558 assert_eq!(
1559 p1.evaluate(Polynomial::domain_element2(2, 4)),
1560 from_const(56)
1561 );
1562 assert_eq!(p1.evaluate_on_two_adic_domain(2, 4), from_const(56));
1563 assert_eq!(
1564 p1.evaluate(Polynomial::domain_element2(3, 4)),
1565 from_const(0)
1566 );
1567 assert_eq!(p1.evaluate_on_two_adic_domain(3, 4), from_const(0));
1568 assert_eq!(
1569 p2.evaluate(Polynomial::domain_element2(0, 3)),
1570 from_const(12)
1571 );
1572 assert_eq!(p2.evaluate_on_two_adic_domain(0, 3), from_const(12));
1573 assert_eq!(
1574 p2.evaluate(Polynomial::domain_element2(0, 4)),
1575 from_const(12)
1576 );
1577 assert_eq!(p2.evaluate_on_two_adic_domain(0, 4), from_const(12));
1578 assert_eq!(
1579 p2.evaluate(Polynomial::domain_element2(1, 3)),
1580 from_const(34)
1581 );
1582 assert_eq!(p2.evaluate_on_two_adic_domain(1, 3), from_const(34));
1583 assert_eq!(
1584 p2.evaluate(Polynomial::domain_element2(1, 4)),
1585 from_const(34)
1586 );
1587 assert_eq!(p2.evaluate_on_two_adic_domain(1, 4), from_const(34));
1588 assert_eq!(
1589 p2.evaluate(Polynomial::domain_element2(2, 3)),
1590 from_const(56)
1591 );
1592 assert_eq!(p2.evaluate_on_two_adic_domain(2, 3), from_const(56));
1593 assert_eq!(
1594 p2.evaluate(Polynomial::domain_element2(2, 4)),
1595 from_const(56)
1596 );
1597 assert_eq!(p2.evaluate_on_two_adic_domain(2, 4), from_const(56));
1598 assert_eq!(
1599 p2.evaluate(Polynomial::domain_element2(3, 4)),
1600 from_const(0)
1601 );
1602 assert_eq!(p2.evaluate_on_two_adic_domain(3, 4), from_const(0));
1603 }
1604
1605 #[test]
1606 fn test_encode2_three_values_2() {
1607 let p1 = Polynomial::encode2(vec![from_const(12), from_const(34), from_const(56)]);
1608 let p2 = Polynomial::encode2(vec![from_const(90), from_const(78), from_const(34)]);
1609 assert_eq!(p1.len(), 4);
1610 assert_eq!(p1.degree_bound(), 4);
1611 assert_eq!(p2.len(), 4);
1612 assert_eq!(p2.degree_bound(), 4);
1613 assert_ne!(p1, p2);
1614 assert_eq!(
1615 p2.evaluate(Polynomial::domain_element2(0, 3)),
1616 from_const(90)
1617 );
1618 assert_eq!(p2.evaluate_on_two_adic_domain(0, 3), from_const(90));
1619 assert_eq!(
1620 p2.evaluate(Polynomial::domain_element2(0, 4)),
1621 from_const(90)
1622 );
1623 assert_eq!(p2.evaluate_on_two_adic_domain(0, 4), from_const(90));
1624 assert_eq!(
1625 p2.evaluate(Polynomial::domain_element2(1, 3)),
1626 from_const(78)
1627 );
1628 assert_eq!(p2.evaluate_on_two_adic_domain(1, 3), from_const(78));
1629 assert_eq!(
1630 p2.evaluate(Polynomial::domain_element2(1, 4)),
1631 from_const(78)
1632 );
1633 assert_eq!(p2.evaluate_on_two_adic_domain(1, 4), from_const(78));
1634 assert_eq!(
1635 p2.evaluate(Polynomial::domain_element2(2, 3)),
1636 from_const(34)
1637 );
1638 assert_eq!(p2.evaluate_on_two_adic_domain(2, 3), from_const(34));
1639 assert_eq!(
1640 p2.evaluate(Polynomial::domain_element2(2, 4)),
1641 from_const(34)
1642 );
1643 assert_eq!(p2.evaluate_on_two_adic_domain(2, 4), from_const(34));
1644 assert_eq!(
1645 p2.evaluate(Polynomial::domain_element2(3, 4)),
1646 from_const(0)
1647 );
1648 assert_eq!(p2.evaluate_on_two_adic_domain(3, 4), from_const(0));
1649 }
1650
1651 #[test]
1652 fn test_encode2_four_values() {
1653 let p = Polynomial::encode2(vec![
1654 from_const(12),
1655 from_const(34),
1656 from_const(56),
1657 from_const(78),
1658 ]);
1659 assert_eq!(p.len(), 4);
1660 assert_eq!(p.degree_bound(), 4);
1661 assert_eq!(
1662 p.evaluate(Polynomial::domain_element2(0, 4)),
1663 from_const(12)
1664 );
1665 assert_eq!(p.evaluate_on_two_adic_domain(0, 4), from_const(12));
1666 assert_eq!(
1667 p.evaluate(Polynomial::domain_element2(1, 4)),
1668 from_const(34)
1669 );
1670 assert_eq!(p.evaluate_on_two_adic_domain(1, 4), from_const(34));
1671 assert_eq!(
1672 p.evaluate(Polynomial::domain_element2(2, 4)),
1673 from_const(56)
1674 );
1675 assert_eq!(p.evaluate_on_two_adic_domain(2, 4), from_const(56));
1676 assert_eq!(
1677 p.evaluate(Polynomial::domain_element2(3, 4)),
1678 from_const(78)
1679 );
1680 assert_eq!(p.evaluate_on_two_adic_domain(3, 4), from_const(78));
1681 }
1682
1683 #[test]
1684 fn test_decode2_one_value() {
1685 let values = vec![from_const(42)];
1686 let polynomial = Polynomial::encode2(values.clone());
1687 assert_eq!(polynomial.decode2(), values);
1688 }
1689
1690 #[test]
1691 fn test_decode2_two_values() {
1692 let values = vec![from_const(12), from_const(34)];
1693 let polynomial = Polynomial::encode2(values.clone());
1694 assert_eq!(polynomial.decode2(), values);
1695 }
1696
1697 #[test]
1698 fn test_decode2_three_values() {
1699 let polynomial = Polynomial::encode2(vec![from_const(12), from_const(34), from_const(56)]);
1700 assert_eq!(
1701 polynomial.decode2(),
1702 vec![
1703 from_const(12),
1704 from_const(34),
1705 from_const(56),
1706 from_const(0)
1707 ]
1708 );
1709 }
1710
1711 #[test]
1712 fn test_decode2_four_values() {
1713 let values = vec![
1714 from_const(12),
1715 from_const(34),
1716 from_const(56),
1717 from_const(78),
1718 ];
1719 let polynomial = Polynomial::encode2(values.clone());
1720 assert_eq!(polynomial.decode2(), values);
1721 }
1722
1723 #[test]
1724 fn test_encode3_one_value_1() {
1725 let p1 = Polynomial::encode3(vec![from_const(42)]);
1726 let p2 = Polynomial::encode3(vec![from_const(42)]);
1727 assert_eq!(p1, p2);
1728 assert_eq!(p1.len(), 1);
1729 assert_eq!(p1.degree_bound(), 1);
1730 assert_eq!(p2.len(), 1);
1731 assert_eq!(p2.degree_bound(), 1);
1732 assert_eq!(
1733 p1.evaluate(Polynomial::domain_element3(0, 1)),
1734 from_const(42)
1735 );
1736 assert_eq!(p1.evaluate_on_three_adic_domain(0, 1), from_const(42));
1737 assert_eq!(
1738 p2.evaluate(Polynomial::domain_element3(0, 1)),
1739 from_const(42)
1740 );
1741 assert_eq!(p2.evaluate_on_three_adic_domain(0, 1), from_const(42));
1742 }
1743
1744 #[test]
1745 fn test_encode3_one_value_2() {
1746 let p1 = Polynomial::encode3(vec![from_const(42)]);
1747 let p2 = Polynomial::encode3(vec![from_const(123)]);
1748 assert_eq!(p2.len(), 1);
1749 assert_eq!(p2.degree_bound(), 1);
1750 assert_ne!(p1, p2);
1751 assert_eq!(
1752 p2.evaluate(Polynomial::domain_element3(0, 1)),
1753 from_const(123)
1754 );
1755 assert_eq!(p2.evaluate_on_three_adic_domain(0, 1), from_const(123));
1756 }
1757
1758 #[test]
1759 fn test_encode3_two_values_1() {
1760 let p1 = Polynomial::encode3(vec![from_const(12), from_const(34)]);
1761 let p2 = Polynomial::encode3(vec![from_const(12), from_const(34)]);
1762 assert_eq!(p1, p2);
1763 assert_eq!(p1.len(), 3);
1764 assert_eq!(p1.degree_bound(), 3);
1765 assert_eq!(p2.len(), 3);
1766 assert_eq!(p2.degree_bound(), 3);
1767 assert_eq!(
1768 p1.evaluate(Polynomial::domain_element3(0, 2)),
1769 from_const(12)
1770 );
1771 assert_eq!(p1.evaluate_on_three_adic_domain(0, 2), from_const(12));
1772 assert_eq!(
1773 p1.evaluate(Polynomial::domain_element3(0, 3)),
1774 from_const(12)
1775 );
1776 assert_eq!(p1.evaluate_on_three_adic_domain(0, 3), from_const(12));
1777 assert_eq!(
1778 p1.evaluate(Polynomial::domain_element3(1, 2)),
1779 from_const(34)
1780 );
1781 assert_eq!(p1.evaluate_on_three_adic_domain(1, 2), from_const(34));
1782 assert_eq!(
1783 p1.evaluate(Polynomial::domain_element3(1, 3)),
1784 from_const(34)
1785 );
1786 assert_eq!(p1.evaluate_on_three_adic_domain(1, 3), from_const(34));
1787 assert_eq!(
1788 p1.evaluate(Polynomial::domain_element3(2, 3)),
1789 from_const(0)
1790 );
1791 assert_eq!(p1.evaluate_on_three_adic_domain(2, 3), from_const(0));
1792 assert_eq!(
1793 p2.evaluate(Polynomial::domain_element3(0, 2)),
1794 from_const(12)
1795 );
1796 assert_eq!(p2.evaluate_on_three_adic_domain(0, 2), from_const(12));
1797 assert_eq!(
1798 p2.evaluate(Polynomial::domain_element3(0, 3)),
1799 from_const(12)
1800 );
1801 assert_eq!(p2.evaluate_on_three_adic_domain(0, 3), from_const(12));
1802 assert_eq!(
1803 p2.evaluate(Polynomial::domain_element3(1, 2)),
1804 from_const(34)
1805 );
1806 assert_eq!(p2.evaluate_on_three_adic_domain(1, 2), from_const(34));
1807 assert_eq!(
1808 p2.evaluate(Polynomial::domain_element3(1, 3)),
1809 from_const(34)
1810 );
1811 assert_eq!(p2.evaluate_on_three_adic_domain(1, 3), from_const(34));
1812 assert_eq!(
1813 p2.evaluate(Polynomial::domain_element3(2, 3)),
1814 from_const(0)
1815 );
1816 assert_eq!(p2.evaluate_on_three_adic_domain(2, 3), from_const(0));
1817 }
1818
1819 #[test]
1820 fn test_encode3_two_values_2() {
1821 let p1 = Polynomial::encode3(vec![from_const(12), from_const(34)]);
1822 let p2 = Polynomial::encode3(vec![from_const(78), from_const(56)]);
1823 assert_eq!(p1.len(), 3);
1824 assert_eq!(p1.degree_bound(), 3);
1825 assert_eq!(p2.len(), 3);
1826 assert_eq!(p2.degree_bound(), 3);
1827 assert_ne!(p1, p2);
1828 assert_eq!(
1829 p2.evaluate(Polynomial::domain_element3(0, 2)),
1830 from_const(78)
1831 );
1832 assert_eq!(p2.evaluate_on_three_adic_domain(0, 2), from_const(78));
1833 assert_eq!(
1834 p2.evaluate(Polynomial::domain_element3(1, 2)),
1835 from_const(56)
1836 );
1837 assert_eq!(p2.evaluate_on_three_adic_domain(1, 2), from_const(56));
1838 assert_eq!(
1839 p2.evaluate(Polynomial::domain_element3(2, 3)),
1840 from_const(0)
1841 );
1842 assert_eq!(p2.evaluate_on_three_adic_domain(2, 3), from_const(0));
1843 }
1844
1845 #[test]
1846 fn test_encode3_three_values_1() {
1847 let p1 = Polynomial::encode3(vec![from_const(12), from_const(34), from_const(56)]);
1848 let p2 = Polynomial::encode3(vec![from_const(12), from_const(34), from_const(56)]);
1849 assert_eq!(p1, p2);
1850 assert_eq!(p1.len(), 3);
1851 assert_eq!(p1.degree_bound(), 3);
1852 assert_eq!(p2.len(), 3);
1853 assert_eq!(p2.degree_bound(), 3);
1854 assert_eq!(
1855 p1.evaluate(Polynomial::domain_element3(0, 3)),
1856 from_const(12)
1857 );
1858 assert_eq!(p1.evaluate_on_three_adic_domain(0, 3), from_const(12));
1859 assert_eq!(
1860 p1.evaluate(Polynomial::domain_element3(1, 3)),
1861 from_const(34)
1862 );
1863 assert_eq!(p1.evaluate_on_three_adic_domain(1, 3), from_const(34));
1864 assert_eq!(
1865 p1.evaluate(Polynomial::domain_element3(2, 3)),
1866 from_const(56)
1867 );
1868 assert_eq!(p1.evaluate_on_three_adic_domain(2, 3), from_const(56));
1869 assert_eq!(
1870 p2.evaluate(Polynomial::domain_element3(0, 3)),
1871 from_const(12)
1872 );
1873 assert_eq!(p2.evaluate_on_three_adic_domain(0, 3), from_const(12));
1874 assert_eq!(
1875 p2.evaluate(Polynomial::domain_element3(1, 3)),
1876 from_const(34)
1877 );
1878 assert_eq!(p2.evaluate_on_three_adic_domain(1, 3), from_const(34));
1879 assert_eq!(
1880 p2.evaluate(Polynomial::domain_element3(2, 3)),
1881 from_const(56)
1882 );
1883 assert_eq!(p2.evaluate_on_three_adic_domain(2, 3), from_const(56));
1884 }
1885
1886 #[test]
1887 fn test_encode3_three_values_2() {
1888 let p1 = Polynomial::encode3(vec![from_const(12), from_const(34), from_const(56)]);
1889 let p2 = Polynomial::encode3(vec![from_const(90), from_const(78), from_const(34)]);
1890 assert_eq!(p1.len(), 3);
1891 assert_eq!(p1.degree_bound(), 3);
1892 assert_eq!(p2.len(), 3);
1893 assert_eq!(p2.degree_bound(), 3);
1894 assert_ne!(p1, p2);
1895 assert_eq!(
1896 p2.evaluate(Polynomial::domain_element3(0, 3)),
1897 from_const(90)
1898 );
1899 assert_eq!(p2.evaluate_on_three_adic_domain(0, 3), from_const(90));
1900 assert_eq!(
1901 p2.evaluate(Polynomial::domain_element3(1, 3)),
1902 from_const(78)
1903 );
1904 assert_eq!(p2.evaluate_on_three_adic_domain(1, 3), from_const(78));
1905 assert_eq!(
1906 p2.evaluate(Polynomial::domain_element3(2, 3)),
1907 from_const(34)
1908 );
1909 assert_eq!(p2.evaluate_on_three_adic_domain(2, 3), from_const(34));
1910 }
1911
1912 #[test]
1913 fn test_encode3_nine_values3() {
1914 let p = Polynomial::encode3(vec![
1915 from_const(12),
1916 from_const(34),
1917 from_const(56),
1918 from_const(78),
1919 from_const(90),
1920 from_const(11),
1921 from_const(22),
1922 from_const(33),
1923 from_const(44),
1924 ]);
1925 assert_eq!(p.len(), 9);
1926 assert_eq!(p.degree_bound(), 9);
1927 assert_eq!(
1928 p.evaluate(Polynomial::domain_element3(0, 9)),
1929 from_const(12)
1930 );
1931 assert_eq!(p.evaluate_on_three_adic_domain(0, 9), from_const(12));
1932 assert_eq!(
1933 p.evaluate(Polynomial::domain_element3(1, 9)),
1934 from_const(34)
1935 );
1936 assert_eq!(p.evaluate_on_three_adic_domain(1, 9), from_const(34));
1937 assert_eq!(
1938 p.evaluate(Polynomial::domain_element3(2, 9)),
1939 from_const(56)
1940 );
1941 assert_eq!(p.evaluate_on_three_adic_domain(2, 9), from_const(56));
1942 assert_eq!(
1943 p.evaluate(Polynomial::domain_element3(3, 9)),
1944 from_const(78)
1945 );
1946 assert_eq!(p.evaluate_on_three_adic_domain(3, 9), from_const(78));
1947 assert_eq!(
1948 p.evaluate(Polynomial::domain_element3(4, 9)),
1949 from_const(90)
1950 );
1951 assert_eq!(p.evaluate_on_three_adic_domain(4, 9), from_const(90));
1952 assert_eq!(
1953 p.evaluate(Polynomial::domain_element3(5, 9)),
1954 from_const(11)
1955 );
1956 assert_eq!(p.evaluate_on_three_adic_domain(5, 9), from_const(11));
1957 assert_eq!(
1958 p.evaluate(Polynomial::domain_element3(6, 9)),
1959 from_const(22)
1960 );
1961 assert_eq!(p.evaluate_on_three_adic_domain(6, 9), from_const(22));
1962 assert_eq!(
1963 p.evaluate(Polynomial::domain_element3(7, 9)),
1964 from_const(33)
1965 );
1966 assert_eq!(p.evaluate_on_three_adic_domain(7, 9), from_const(33));
1967 assert_eq!(
1968 p.evaluate(Polynomial::domain_element3(8, 9)),
1969 from_const(44)
1970 );
1971 assert_eq!(p.evaluate_on_three_adic_domain(8, 9), from_const(44));
1972 }
1973
1974 #[test]
1975 fn test_decode3_one_value() {
1976 let values = vec![from_const(42)];
1977 let polynomial = Polynomial::encode3(values.clone());
1978 assert_eq!(polynomial.decode3(), values);
1979 }
1980
1981 #[test]
1982 fn test_decode3_two_values() {
1983 let values = vec![from_const(12), from_const(34)];
1984 let polynomial = Polynomial::encode3(values.clone());
1985 assert_eq!(
1986 polynomial.decode3(),
1987 vec![from_const(12), from_const(34), from_const(0)]
1988 );
1989 }
1990
1991 #[test]
1992 fn test_decode3_three_values() {
1993 let values = vec![from_const(12), from_const(34), from_const(56)];
1994 let polynomial = Polynomial::encode3(values.clone());
1995 assert_eq!(polynomial.decode3(), values);
1996 }
1997
1998 #[test]
1999 fn test_decode3_nine_values() {
2000 let values = vec![
2001 from_const(12),
2002 from_const(34),
2003 from_const(56),
2004 from_const(78),
2005 from_const(90),
2006 from_const(11),
2007 from_const(22),
2008 from_const(33),
2009 from_const(44),
2010 ];
2011 let polynomial = Polynomial::encode3(values.clone());
2012 assert_eq!(polynomial.decode3(), values);
2013 }
2014
2015 #[test]
2016 fn test_add_same_length() {
2017 let p1 = Polynomial::with_coefficients(vec![from_const(1), from_const(2), from_const(3)]);
2018 let p2 =
2019 Polynomial::with_coefficients(vec![from_const(10), from_const(20), from_const(30)]);
2020 assert_eq!(
2021 p1 + p2,
2022 Polynomial::with_coefficients(vec![from_const(11), from_const(22), from_const(33)])
2023 );
2024 }
2025
2026 #[test]
2027 fn test_add_lhs_longer() {
2028 let p1 = Polynomial::with_coefficients(vec![from_const(1), from_const(2), from_const(3)]);
2029 let p2 = Polynomial::with_coefficients(vec![from_const(10), from_const(20)]);
2030 assert_eq!(
2031 p1 + p2,
2032 Polynomial::with_coefficients(vec![from_const(11), from_const(22), from_const(3)])
2033 );
2034 }
2035
2036 #[test]
2037 fn test_add_rhs_longer() {
2038 let p1 = Polynomial::with_coefficients(vec![from_const(1), from_const(2)]);
2039 let p2 =
2040 Polynomial::with_coefficients(vec![from_const(10), from_const(20), from_const(30)]);
2041 assert_eq!(
2042 p1 + p2,
2043 Polynomial::with_coefficients(vec![from_const(11), from_const(22), from_const(30)])
2044 );
2045 }
2046
2047 #[test]
2048 fn test_add_commutative() {
2049 let p1 = Polynomial::with_coefficients(vec![from_const(1), from_const(2)]);
2050 let p2 =
2051 Polynomial::with_coefficients(vec![from_const(10), from_const(20), from_const(30)]);
2052 assert_eq!(p1.clone() + p2.clone(), p2 + p1);
2053 }
2054
2055 #[test]
2056 fn test_add_assign_same_length() {
2057 let mut p1 =
2058 Polynomial::with_coefficients(vec![from_const(1), from_const(2), from_const(3)]);
2059 let p2 =
2060 Polynomial::with_coefficients(vec![from_const(10), from_const(20), from_const(30)]);
2061 p1 += p2;
2062 assert_eq!(
2063 p1,
2064 Polynomial::with_coefficients(vec![from_const(11), from_const(22), from_const(33)])
2065 );
2066 }
2067
2068 #[test]
2069 fn test_add_assign_lhs_longer() {
2070 let mut p1 =
2071 Polynomial::with_coefficients(vec![from_const(1), from_const(2), from_const(3)]);
2072 let p2 = Polynomial::with_coefficients(vec![from_const(10), from_const(20)]);
2073 p1 += p2;
2074 assert_eq!(
2075 p1,
2076 Polynomial::with_coefficients(vec![from_const(11), from_const(22), from_const(3)])
2077 );
2078 }
2079
2080 #[test]
2081 fn test_add_assign_rhs_longer() {
2082 let mut p1 = Polynomial::with_coefficients(vec![from_const(1), from_const(2)]);
2083 let p2 =
2084 Polynomial::with_coefficients(vec![from_const(10), from_const(20), from_const(30)]);
2085 p1 += p2;
2086 assert_eq!(
2087 p1,
2088 Polynomial::with_coefficients(vec![from_const(11), from_const(22), from_const(30)])
2089 );
2090 }
2091
2092 #[test]
2093 fn test_add_assign_consistent_with_add() {
2094 let p1 = Polynomial::with_coefficients(vec![from_const(1), from_const(2)]);
2095 let p2 =
2096 Polynomial::with_coefficients(vec![from_const(10), from_const(20), from_const(30)]);
2097 let mut p1_assign = p1.clone();
2098 p1_assign += p2.clone();
2099 assert_eq!(p1_assign, p1 + p2);
2100 }
2101
2102 #[test]
2103 fn test_sub_same_length() {
2104 let p1 =
2105 Polynomial::with_coefficients(vec![from_const(10), from_const(20), from_const(30)]);
2106 let p2 = Polynomial::with_coefficients(vec![from_const(1), from_const(2), from_const(3)]);
2107 assert_eq!(
2108 p1 - p2,
2109 Polynomial::with_coefficients(vec![from_const(9), from_const(18), from_const(27)])
2110 );
2111 }
2112
2113 #[test]
2114 fn test_sub_lhs_longer() {
2115 let p1 =
2116 Polynomial::with_coefficients(vec![from_const(10), from_const(20), from_const(30)]);
2117 let p2 = Polynomial::with_coefficients(vec![from_const(1), from_const(2)]);
2118 assert_eq!(
2119 p1 - p2,
2120 Polynomial::with_coefficients(vec![from_const(9), from_const(18), from_const(30)])
2121 );
2122 }
2123
2124 #[test]
2125 fn test_sub_rhs_longer() {
2126 let p1 = Polynomial::with_coefficients(vec![from_const(10), from_const(20)]);
2127 let p2 = Polynomial::with_coefficients(vec![from_const(1), from_const(2), from_const(3)]);
2128 assert_eq!(
2129 p1 - p2,
2130 Polynomial::with_coefficients(vec![from_const(9), from_const(18), -from_const(3)])
2131 );
2132 }
2133
2134 #[test]
2135 fn test_sub_anticommutative() {
2136 let p1 = Polynomial::with_coefficients(vec![from_const(10), from_const(20)]);
2137 let p2 = Polynomial::with_coefficients(vec![from_const(1), from_const(2), from_const(3)]);
2138 assert_eq!(p1.clone() - p2.clone(), -(p2 - p1));
2139 }
2140
2141 #[test]
2142 fn test_sub_assign_same_length() {
2143 let mut p1 =
2144 Polynomial::with_coefficients(vec![from_const(10), from_const(20), from_const(30)]);
2145 let p2 = Polynomial::with_coefficients(vec![from_const(1), from_const(2), from_const(3)]);
2146 p1 -= p2;
2147 assert_eq!(
2148 p1,
2149 Polynomial::with_coefficients(vec![from_const(9), from_const(18), from_const(27)])
2150 );
2151 }
2152
2153 #[test]
2154 fn test_sub_assign_lhs_longer() {
2155 let mut p1 =
2156 Polynomial::with_coefficients(vec![from_const(10), from_const(20), from_const(30)]);
2157 let p2 = Polynomial::with_coefficients(vec![from_const(1), from_const(2)]);
2158 p1 -= p2;
2159 assert_eq!(
2160 p1,
2161 Polynomial::with_coefficients(vec![from_const(9), from_const(18), from_const(30)])
2162 );
2163 }
2164
2165 #[test]
2166 fn test_sub_assign_rhs_longer() {
2167 let mut p1 = Polynomial::with_coefficients(vec![from_const(10), from_const(20)]);
2168 let p2 = Polynomial::with_coefficients(vec![from_const(1), from_const(2), from_const(3)]);
2169 p1 -= p2;
2170 assert_eq!(
2171 p1,
2172 Polynomial::with_coefficients(vec![from_const(9), from_const(18), -from_const(3)])
2173 );
2174 }
2175
2176 #[test]
2177 fn test_sub_assign_consistent_with_sub() {
2178 let p1 = Polynomial::with_coefficients(vec![from_const(10), from_const(20)]);
2179 let p2 = Polynomial::with_coefficients(vec![from_const(1), from_const(2), from_const(3)]);
2180 let mut p1_assign = p1.clone();
2181 p1_assign -= p2.clone();
2182 assert_eq!(p1_assign, p1 - p2);
2183 }
2184
2185 #[test]
2186 fn test_multiply_empty() {
2187 let p1 = Polynomial::default();
2188 let p2 = Polynomial::default();
2189 assert_eq!(p1.multiply(p2), Polynomial::default());
2190 }
2191
2192 #[test]
2193 fn test_multiply_empty_by_non_empty() {
2194 let p1 = Polynomial::default();
2195 let p2 = Polynomial {
2196 coefficients: vec![from_const(12), from_const(34)],
2197 };
2198 assert_eq!(p1.multiply(p2), Polynomial::default());
2199 }
2200
2201 #[test]
2202 fn test_multiply_non_empty_by_empty() {
2203 let p1 = Polynomial {
2204 coefficients: vec![from_const(56), from_const(78)],
2205 };
2206 let p2 = Polynomial::default();
2207 assert_eq!(p1.multiply(p2), Polynomial::default());
2208 }
2209
2210 #[test]
2211 fn test_multiply_constant() {
2212 let p1 = Polynomial {
2213 coefficients: vec![from_const(3)],
2214 };
2215 let p2 = Polynomial {
2216 coefficients: vec![from_const(12), from_const(34), from_const(56)],
2217 };
2218 assert_eq!(
2219 p1.multiply(p2),
2220 Polynomial {
2221 coefficients: vec![from_const(36), from_const(102), from_const(168)]
2222 }
2223 );
2224 }
2225
2226 #[test]
2227 fn test_multiply_by_constant() {
2228 let p1 = Polynomial {
2229 coefficients: vec![from_const(12), from_const(34), from_const(56)],
2230 };
2231 let p2 = Polynomial {
2232 coefficients: vec![from_const(3)],
2233 };
2234 assert_eq!(
2235 p1.multiply(p2),
2236 Polynomial {
2237 coefficients: vec![from_const(36), from_const(102), from_const(168)]
2238 }
2239 );
2240 }
2241
2242 #[test]
2243 fn test_multiply_constant_by_constant() {
2244 let p1 = Polynomial {
2245 coefficients: vec![from_const(12)],
2246 };
2247 let p2 = Polynomial {
2248 coefficients: vec![from_const(34)],
2249 };
2250 assert_eq!(
2251 p1.multiply(p2),
2252 Polynomial {
2253 coefficients: vec![from_const(408)]
2254 }
2255 );
2256 }
2257
2258 #[test]
2259 fn test_multiply_polynomials1() {
2260 let p1 = Polynomial {
2261 coefficients: vec![from_const(1), from_const(2)],
2262 };
2263 let p2 = Polynomial {
2264 coefficients: vec![from_const(3), from_const(4)],
2265 };
2266 let result = Polynomial {
2267 coefficients: vec![from_const(3), from_const(10), from_const(8)],
2268 };
2269 assert_eq!(p1.clone().multiply(p2.clone()), result);
2270 assert_eq!(p2.multiply(p1), result);
2271 }
2272
2273 #[test]
2274 fn test_multiply_polynomials2() {
2275 let p1 = Polynomial {
2276 coefficients: vec![from_const(1), from_const(2)],
2277 };
2278 let p2 = Polynomial {
2279 coefficients: vec![from_const(3), from_const(4), from_const(5)],
2280 };
2281 let result = Polynomial {
2282 coefficients: vec![
2283 from_const(3),
2284 from_const(10),
2285 from_const(13),
2286 from_const(10),
2287 ],
2288 };
2289 assert_eq!(p1.clone().multiply(p2.clone()), result);
2290 assert_eq!(p2.multiply(p1), result);
2291 }
2292
2293 #[test]
2294 fn test_polynomial_mul_op() {
2295 let p1 = Polynomial {
2296 coefficients: vec![from_const(1), from_const(2)],
2297 };
2298 let p2 = Polynomial {
2299 coefficients: vec![from_const(3), from_const(4), from_const(5)],
2300 };
2301 let result = Polynomial {
2302 coefficients: vec![
2303 from_const(3),
2304 from_const(10),
2305 from_const(13),
2306 from_const(10),
2307 ],
2308 };
2309 assert_eq!(p1.clone() * p2.clone(), result);
2310 assert_eq!(p2 * p1, result);
2311 }
2312
2313 #[test]
2314 fn test_polynomial_mul_assign() {
2315 let mut p1 = Polynomial {
2316 coefficients: vec![from_const(1), from_const(2)],
2317 };
2318 let p2 = Polynomial {
2319 coefficients: vec![from_const(3), from_const(4), from_const(5)],
2320 };
2321 p1 *= p2;
2322 assert_eq!(
2323 p1,
2324 Polynomial {
2325 coefficients: vec![
2326 from_const(3),
2327 from_const(10),
2328 from_const(13),
2329 from_const(10)
2330 ],
2331 }
2332 );
2333 }
2334
2335 #[test]
2336 fn test_multiply_one_polynomial() {
2337 let p = Polynomial {
2338 coefficients: vec![from_const(12), from_const(34)],
2339 };
2340 assert_eq!(Polynomial::multiply_many([p.clone()]), p);
2341 }
2342
2343 #[test]
2344 fn test_multiply_two_polynomials() {
2345 let p1 = Polynomial {
2346 coefficients: vec![from_const(1), from_const(2)],
2347 };
2348 let p2 = Polynomial {
2349 coefficients: vec![from_const(3), from_const(4), from_const(5)],
2350 };
2351 let result = Polynomial {
2352 coefficients: vec![
2353 from_const(3),
2354 from_const(10),
2355 from_const(13),
2356 from_const(10),
2357 ],
2358 };
2359 assert_eq!(Polynomial::multiply_many([p1.clone(), p2.clone()]), result);
2360 assert_eq!(Polynomial::multiply_many([p2, p1]), result);
2361 }
2362
2363 #[test]
2364 fn test_multiply_three_polynomials() {
2365 let p1 = Polynomial {
2366 coefficients: vec![from_const(1), from_const(2)],
2367 };
2368 let p2 = Polynomial {
2369 coefficients: vec![from_const(3), from_const(4), from_const(5)],
2370 };
2371 let p3 = Polynomial {
2372 coefficients: vec![from_const(6), from_const(7), from_const(8), from_const(9)],
2373 };
2374 let result = Polynomial {
2375 coefficients: vec![
2376 from_const(18),
2377 from_const(81),
2378 from_const(172),
2379 from_const(258),
2380 from_const(264),
2381 from_const(197),
2382 from_const(90),
2383 ],
2384 };
2385 assert_eq!(
2386 Polynomial::multiply_many([p1.clone(), p2.clone(), p3.clone()]),
2387 result
2388 );
2389 assert_eq!(
2390 Polynomial::multiply_many([p1.clone(), p3.clone(), p2.clone()]),
2391 result
2392 );
2393 assert_eq!(
2394 Polynomial::multiply_many([p2.clone(), p1.clone(), p3.clone()]),
2395 result
2396 );
2397 assert_eq!(
2398 Polynomial::multiply_many([p2.clone(), p3.clone(), p1.clone()]),
2399 result
2400 );
2401 assert_eq!(
2402 Polynomial::multiply_many([p3.clone(), p1.clone(), p2.clone()]),
2403 result
2404 );
2405 assert_eq!(
2406 Polynomial::multiply_many([p3.clone(), p2.clone(), p1.clone()]),
2407 result
2408 );
2409 }
2410
2411 #[test]
2412 fn test_multiply_four_polynomials() {
2413 let p1 = Polynomial {
2414 coefficients: vec![from_const(1), from_const(2)],
2415 };
2416 let p2 = Polynomial {
2417 coefficients: vec![from_const(3), from_const(4)],
2418 };
2419 let p3 = Polynomial {
2420 coefficients: vec![from_const(5), from_const(6)],
2421 };
2422 let p4 = Polynomial {
2423 coefficients: vec![from_const(7), from_const(8)],
2424 };
2425 let result = Polynomial {
2426 coefficients: vec![
2427 from_const(105),
2428 from_const(596),
2429 from_const(1244),
2430 from_const(1136),
2431 from_const(384),
2432 ],
2433 };
2434 assert_eq!(
2435 Polynomial::multiply_many([p1.clone(), p2.clone(), p3.clone(), p4.clone()]),
2436 result
2437 );
2438 assert_eq!(
2439 Polynomial::multiply_many([p1.clone(), p2.clone(), p4.clone(), p3.clone()]),
2440 result
2441 );
2442 assert_eq!(
2443 Polynomial::multiply_many([p1.clone(), p3.clone(), p2.clone(), p4.clone()]),
2444 result
2445 );
2446 assert_eq!(
2447 Polynomial::multiply_many([p1.clone(), p3.clone(), p4.clone(), p2.clone()]),
2448 result
2449 );
2450 }
2452
2453 #[test]
2454 fn test_divide_zero_by_zero() {
2455 let z = Polynomial {
2456 coefficients: vec![
2457 -from_const(1),
2458 from_const(0),
2459 from_const(0),
2460 from_const(0),
2461 from_const(1),
2462 ],
2463 };
2464 assert_eq!(
2465 z.divide_by_zero(4).unwrap(),
2466 Polynomial {
2467 coefficients: vec![from_const(1)]
2468 }
2469 );
2470 }
2471
2472 #[test]
2473 fn test_non_trivial_quotient1() {
2474 let ql = Polynomial::encode2(vec![
2475 from_const(0),
2476 from_const(0),
2477 from_const(1),
2478 from_const(1),
2479 ]);
2480 let qr = Polynomial::encode2(vec![
2481 from_const(0),
2482 from_const(0),
2483 from_const(1),
2484 from_const(1),
2485 ]);
2486 let qo = Polynomial::encode2(vec![-from_const(1); 4]);
2487 let qm = Polynomial::encode2(vec![
2488 from_const(1),
2489 from_const(1),
2490 from_const(0),
2491 from_const(0),
2492 ]);
2493 let qc = Polynomial::encode2(vec![from_const(0); 4]);
2494 let l = Polynomial::encode2(vec![
2495 from_const(3),
2496 from_const(9),
2497 from_const(3),
2498 from_const(30),
2499 ]);
2500 let r = Polynomial::encode2(vec![
2501 from_const(3),
2502 from_const(3),
2503 from_const(27),
2504 from_const(5),
2505 ]);
2506 let o = Polynomial::encode2(vec![
2507 from_const(9),
2508 from_const(27),
2509 from_const(30),
2510 from_const(35),
2511 ]);
2512 let lr = l.clone().multiply(r.clone());
2513 let p = ql.multiply(l) + qr.multiply(r) + qo.multiply(o) + qm.multiply(lr) + qc;
2514 let q = p.divide_by_zero(4).unwrap();
2515 assert_eq!(q.len(), 6);
2516 assert_eq!(q.degree_bound(), 6);
2517 }
2518
2519 #[test]
2520 fn test_non_trivial_quotient2() {
2521 let ql = Polynomial::encode2(vec![
2522 from_const(0),
2523 from_const(0),
2524 from_const(1),
2525 from_const(1),
2526 ]);
2527 let qr = Polynomial::encode2(vec![
2528 from_const(0),
2529 from_const(0),
2530 from_const(1),
2531 from_const(5),
2532 ]);
2533 let qo = Polynomial::encode2(vec![-from_const(1); 4]);
2534 let qm = Polynomial::encode2(vec![
2535 from_const(1),
2536 from_const(1),
2537 from_const(0),
2538 from_const(0),
2539 ]);
2540 let qc = Polynomial::encode2(vec![from_const(0); 4]);
2541 let l = Polynomial::encode2(vec![
2542 from_const(3),
2543 from_const(9),
2544 from_const(3),
2545 from_const(30),
2546 ]);
2547 let r = Polynomial::encode2(vec![
2548 from_const(3),
2549 from_const(3),
2550 from_const(27),
2551 from_const(1),
2552 ]);
2553 let o = Polynomial::encode2(vec![
2554 from_const(9),
2555 from_const(27),
2556 from_const(30),
2557 from_const(35),
2558 ]);
2559 let lr = l.clone().multiply(r.clone());
2560 let p = ql.multiply(l) + qr.multiply(r) + qo.multiply(o) + qm.multiply(lr) + qc;
2561 let q = p.divide_by_zero(4).unwrap();
2562 assert_eq!(q.len(), 6);
2563 assert_eq!(q.degree_bound(), 6);
2564 }
2565
2566 #[test]
2567 fn test_shift_domain2() {
2568 let values = vec![
2569 from_const(12),
2570 from_const(34),
2571 from_const(56),
2572 from_const(78),
2573 ];
2574 let p = Polynomial::encode2(values);
2575 let shifted = p.clone().shift_domain();
2576 assert_eq!(
2577 shifted.evaluate_on_two_adic_domain(0, 4),
2578 p.evaluate_on_two_adic_coset(0, 4)
2579 );
2580 assert_eq!(
2581 shifted.evaluate_on_two_adic_domain(1, 4),
2582 p.evaluate_on_two_adic_coset(1, 4)
2583 );
2584 assert_eq!(
2585 shifted.evaluate_on_two_adic_domain(2, 4),
2586 p.evaluate_on_two_adic_coset(2, 4)
2587 );
2588 assert_eq!(
2589 shifted.evaluate_on_two_adic_domain(3, 4),
2590 p.evaluate_on_two_adic_coset(3, 4)
2591 );
2592 }
2593
2594 #[test]
2595 fn test_shift_domain3() {
2596 let values = vec![from_const(12), from_const(34), from_const(56)];
2597 let p = Polynomial::encode3(values);
2598 let shifted = p.clone().shift_domain();
2599 assert_eq!(
2600 shifted.evaluate_on_three_adic_domain(0, 3),
2601 p.evaluate_on_three_adic_coset(0, 3)
2602 );
2603 assert_eq!(
2604 shifted.evaluate_on_three_adic_domain(1, 3),
2605 p.evaluate_on_three_adic_coset(1, 3)
2606 );
2607 assert_eq!(
2608 shifted.evaluate_on_three_adic_domain(2, 3),
2609 p.evaluate_on_three_adic_coset(2, 3)
2610 );
2611 }
2612
2613 #[test]
2614 fn test_lde2_blowup2() {
2615 let values = vec![
2616 from_const(12),
2617 from_const(34),
2618 from_const(56),
2619 from_const(78),
2620 ];
2621 let p = Polynomial::encode2(values);
2622 let lde = p.clone().lde2(8);
2623 assert_eq!(
2624 lde,
2625 vec![
2626 p.evaluate_on_two_adic_domain(0, 8),
2627 p.evaluate_on_two_adic_domain(1, 8),
2628 p.evaluate_on_two_adic_domain(2, 8),
2629 p.evaluate_on_two_adic_domain(3, 8),
2630 p.evaluate_on_two_adic_domain(4, 8),
2631 p.evaluate_on_two_adic_domain(5, 8),
2632 p.evaluate_on_two_adic_domain(6, 8),
2633 p.evaluate_on_two_adic_domain(7, 8),
2634 ]
2635 );
2636 }
2637
2638 #[test]
2639 fn test_lde2_blowup4() {
2640 let values = vec![from_const(1), from_const(2), from_const(3), from_const(4)];
2641 let p = Polynomial::encode2(values);
2642 let lde = p.clone().lde2(16);
2643 assert_eq!(
2644 lde,
2645 vec![
2646 p.evaluate_on_two_adic_domain(0, 16),
2647 p.evaluate_on_two_adic_domain(1, 16),
2648 p.evaluate_on_two_adic_domain(2, 16),
2649 p.evaluate_on_two_adic_domain(3, 16),
2650 p.evaluate_on_two_adic_domain(4, 16),
2651 p.evaluate_on_two_adic_domain(5, 16),
2652 p.evaluate_on_two_adic_domain(6, 16),
2653 p.evaluate_on_two_adic_domain(7, 16),
2654 p.evaluate_on_two_adic_domain(8, 16),
2655 p.evaluate_on_two_adic_domain(9, 16),
2656 p.evaluate_on_two_adic_domain(10, 16),
2657 p.evaluate_on_two_adic_domain(11, 16),
2658 p.evaluate_on_two_adic_domain(12, 16),
2659 p.evaluate_on_two_adic_domain(13, 16),
2660 p.evaluate_on_two_adic_domain(14, 16),
2661 p.evaluate_on_two_adic_domain(15, 16),
2662 ]
2663 );
2664 }
2665
2666 #[test]
2667 fn test_lde2_shorter_polynomial() {
2668 let values = vec![from_const(42), from_const(42)];
2669 let p = Polynomial::encode2(values);
2670 assert_eq!(p.len(), 1);
2671 assert_eq!(p.degree_bound(), 1);
2672 let lde = p.clone().lde2(4);
2673 assert_eq!(
2674 lde,
2675 vec![
2676 p.evaluate_on_two_adic_domain(0, 4),
2677 p.evaluate_on_two_adic_domain(1, 4),
2678 p.evaluate_on_two_adic_domain(2, 4),
2679 p.evaluate_on_two_adic_domain(3, 4),
2680 ]
2681 );
2682 }
2683
2684 #[test]
2685 fn test_lde3_blowup3() {
2686 let values = vec![from_const(12), from_const(34), from_const(56)];
2687 let p = Polynomial::encode3(values);
2688 let lde = p.clone().lde3(9);
2689 assert_eq!(
2690 lde,
2691 vec![
2692 p.evaluate_on_three_adic_domain(0, 9),
2693 p.evaluate_on_three_adic_domain(1, 9),
2694 p.evaluate_on_three_adic_domain(2, 9),
2695 p.evaluate_on_three_adic_domain(3, 9),
2696 p.evaluate_on_three_adic_domain(4, 9),
2697 p.evaluate_on_three_adic_domain(5, 9),
2698 p.evaluate_on_three_adic_domain(6, 9),
2699 p.evaluate_on_three_adic_domain(7, 9),
2700 p.evaluate_on_three_adic_domain(8, 9),
2701 ]
2702 );
2703 }
2704
2705 #[test]
2706 fn test_lde3_blowup9() {
2707 let values = vec![from_const(1), from_const(2), from_const(3)];
2708 let p = Polynomial::encode3(values);
2709 let lde = p.clone().lde3(27);
2710 assert_eq!(
2711 lde,
2712 vec![
2713 p.evaluate_on_three_adic_domain(0, 27),
2714 p.evaluate_on_three_adic_domain(1, 27),
2715 p.evaluate_on_three_adic_domain(2, 27),
2716 p.evaluate_on_three_adic_domain(3, 27),
2717 p.evaluate_on_three_adic_domain(4, 27),
2718 p.evaluate_on_three_adic_domain(5, 27),
2719 p.evaluate_on_three_adic_domain(6, 27),
2720 p.evaluate_on_three_adic_domain(7, 27),
2721 p.evaluate_on_three_adic_domain(8, 27),
2722 p.evaluate_on_three_adic_domain(9, 27),
2723 p.evaluate_on_three_adic_domain(10, 27),
2724 p.evaluate_on_three_adic_domain(11, 27),
2725 p.evaluate_on_three_adic_domain(12, 27),
2726 p.evaluate_on_three_adic_domain(13, 27),
2727 p.evaluate_on_three_adic_domain(14, 27),
2728 p.evaluate_on_three_adic_domain(15, 27),
2729 p.evaluate_on_three_adic_domain(16, 27),
2730 p.evaluate_on_three_adic_domain(17, 27),
2731 p.evaluate_on_three_adic_domain(18, 27),
2732 p.evaluate_on_three_adic_domain(19, 27),
2733 p.evaluate_on_three_adic_domain(20, 27),
2734 p.evaluate_on_three_adic_domain(21, 27),
2735 p.evaluate_on_three_adic_domain(22, 27),
2736 p.evaluate_on_three_adic_domain(23, 27),
2737 p.evaluate_on_three_adic_domain(24, 27),
2738 p.evaluate_on_three_adic_domain(25, 27),
2739 p.evaluate_on_three_adic_domain(26, 27),
2740 ]
2741 );
2742 }
2743
2744 #[test]
2745 fn test_lde3_nine_values_blowup3() {
2746 let values = (1u64..=9).map(Scalar::from).collect();
2747 let p = Polynomial::encode3(values);
2748 let lde = p.clone().lde3(27);
2749 assert_eq!(
2750 lde,
2751 vec![
2752 p.evaluate_on_three_adic_domain(0, 27),
2753 p.evaluate_on_three_adic_domain(1, 27),
2754 p.evaluate_on_three_adic_domain(2, 27),
2755 p.evaluate_on_three_adic_domain(3, 27),
2756 p.evaluate_on_three_adic_domain(4, 27),
2757 p.evaluate_on_three_adic_domain(5, 27),
2758 p.evaluate_on_three_adic_domain(6, 27),
2759 p.evaluate_on_three_adic_domain(7, 27),
2760 p.evaluate_on_three_adic_domain(8, 27),
2761 p.evaluate_on_three_adic_domain(9, 27),
2762 p.evaluate_on_three_adic_domain(10, 27),
2763 p.evaluate_on_three_adic_domain(11, 27),
2764 p.evaluate_on_three_adic_domain(12, 27),
2765 p.evaluate_on_three_adic_domain(13, 27),
2766 p.evaluate_on_three_adic_domain(14, 27),
2767 p.evaluate_on_three_adic_domain(15, 27),
2768 p.evaluate_on_three_adic_domain(16, 27),
2769 p.evaluate_on_three_adic_domain(17, 27),
2770 p.evaluate_on_three_adic_domain(18, 27),
2771 p.evaluate_on_three_adic_domain(19, 27),
2772 p.evaluate_on_three_adic_domain(20, 27),
2773 p.evaluate_on_three_adic_domain(21, 27),
2774 p.evaluate_on_three_adic_domain(22, 27),
2775 p.evaluate_on_three_adic_domain(23, 27),
2776 p.evaluate_on_three_adic_domain(24, 27),
2777 p.evaluate_on_three_adic_domain(25, 27),
2778 p.evaluate_on_three_adic_domain(26, 27),
2779 ]
2780 );
2781 }
2782
2783 #[test]
2784 fn test_lde3_shorter_poly() {
2785 let values = vec![from_const(7), from_const(7), from_const(7)];
2786 let p = Polynomial::encode3(values);
2787 assert_eq!(p.len(), 1);
2788 assert_eq!(p.degree_bound(), 1);
2789 let lde = p.clone().lde3(9);
2790 assert_eq!(
2791 lde,
2792 vec![
2793 p.evaluate_on_three_adic_domain(0, 9),
2794 p.evaluate_on_three_adic_domain(1, 9),
2795 p.evaluate_on_three_adic_domain(2, 9),
2796 p.evaluate_on_three_adic_domain(3, 9),
2797 p.evaluate_on_three_adic_domain(4, 9),
2798 p.evaluate_on_three_adic_domain(5, 9),
2799 p.evaluate_on_three_adic_domain(6, 9),
2800 p.evaluate_on_three_adic_domain(7, 9),
2801 p.evaluate_on_three_adic_domain(8, 9),
2802 ]
2803 );
2804 }
2805
2806 #[test]
2807 fn test_fold2_degree_zero() {
2808 let p = Polynomial::with_coefficients(vec![from_const(5)]);
2809 assert_eq!(p.clone().fold2(from_const(2)).take(), vec![from_const(5)]);
2810 assert_eq!(p.fold2(from_const(3)).take(), vec![from_const(5)]);
2811 }
2812
2813 #[test]
2814 fn test_fold2_degree_one() {
2815 let p = Polynomial::with_coefficients(vec![from_const(2), from_const(3)]);
2816 assert_eq!(p.clone().fold2(from_const(2)).take(), vec![from_const(8)]);
2817 assert_eq!(p.fold2(from_const(3)).take(), vec![from_const(11)]);
2818 }
2819
2820 #[test]
2821 fn test_fold2_degree_two() {
2822 let p = Polynomial::with_coefficients(vec![from_const(1), from_const(2), from_const(3)]);
2823 assert_eq!(
2824 p.clone().fold2(from_const(2)).take(),
2825 vec![from_const(5), from_const(3)],
2826 );
2827 assert_eq!(
2828 p.fold2(from_const(3)).take(),
2829 vec![from_const(7), from_const(3)],
2830 );
2831 }
2832
2833 #[test]
2834 fn test_fold2_degree_three() {
2835 let p = Polynomial::with_coefficients(vec![
2836 from_const(1),
2837 from_const(2),
2838 from_const(3),
2839 from_const(4),
2840 ]);
2841 assert_eq!(
2842 p.clone().fold2(from_const(2)).take(),
2843 vec![from_const(5), from_const(11)],
2844 );
2845 assert_eq!(
2846 p.fold2(from_const(3)).take(),
2847 vec![from_const(7), from_const(15)],
2848 );
2849 }
2850
2851 #[test]
2852 fn test_fold3_degree_zero() {
2853 let p = Polynomial::with_coefficients(vec![from_const(5)]);
2854 assert_eq!(p.clone().fold3(from_const(2)).take(), vec![from_const(5)]);
2855 assert_eq!(p.fold3(from_const(3)).take(), vec![from_const(5)]);
2856 }
2857
2858 #[test]
2859 fn test_fold3_degree_two() {
2860 let p = Polynomial::with_coefficients(vec![from_const(1), from_const(2), from_const(3)]);
2861 assert_eq!(p.clone().fold3(from_const(2)).take(), vec![from_const(17)]);
2862 assert_eq!(p.fold3(from_const(3)).take(), vec![from_const(34)]);
2863 }
2864
2865 #[test]
2866 fn test_fold3_degree_three() {
2867 let p = Polynomial::with_coefficients(vec![
2868 from_const(1),
2869 from_const(2),
2870 from_const(3),
2871 from_const(4),
2872 ]);
2873 assert_eq!(
2874 p.clone().fold3(from_const(2)).take(),
2875 vec![from_const(17), from_const(4)],
2876 );
2877 assert_eq!(
2878 p.fold3(from_const(3)).take(),
2879 vec![from_const(34), from_const(4)],
2880 );
2881 }
2882
2883 #[test]
2884 fn test_fold3_degree_five() {
2885 let p = Polynomial::with_coefficients(vec![
2886 from_const(1),
2887 from_const(2),
2888 from_const(3),
2889 from_const(4),
2890 from_const(5),
2891 from_const(6),
2892 ]);
2893 assert_eq!(
2894 p.clone().fold3(from_const(2)).take(),
2895 vec![from_const(17), from_const(38)],
2896 );
2897 assert_eq!(
2898 p.fold3(from_const(3)).take(),
2899 vec![from_const(34), from_const(73)],
2900 );
2901 }
2902
2903 #[test]
2904 fn test_multiply_values2_same_constant() {
2905 let lhs = vec![from_const(42), from_const(42)];
2906 let rhs = vec![from_const(42), from_const(42)];
2907 let result = Polynomial::multiply_values2(lhs, rhs);
2908 assert_eq!(result, vec![from_const(1764)]);
2909 }
2910
2911 #[test]
2912 fn test_multiply_values2_different_constants() {
2913 let lhs = vec![from_const(3), from_const(3)];
2914 let rhs = vec![from_const(7), from_const(7)];
2915 let result = Polynomial::multiply_values2(lhs, rhs);
2916 assert_eq!(result, vec![from_const(21)]);
2917 }
2918
2919 #[test]
2920 fn test_multiply_values2_two_linear_polynomials() {
2921 let p = Polynomial::with_coefficients(vec![from_const(1), from_const(2)]);
2922 let q = Polynomial::with_coefficients(vec![from_const(3), from_const(4)]);
2923 let lhs = vec![
2924 p.evaluate_on_two_adic_domain(0, 2),
2925 p.evaluate_on_two_adic_domain(1, 2),
2926 ];
2927 let rhs = vec![
2928 q.evaluate_on_two_adic_domain(0, 2),
2929 q.evaluate_on_two_adic_domain(1, 2),
2930 ];
2931 let product = p.multiply(q);
2932 let result = Polynomial::multiply_values2(lhs, rhs);
2933 assert_eq!(
2934 result,
2935 vec![
2936 product.evaluate_on_two_adic_domain(0, 4),
2937 product.evaluate_on_two_adic_domain(1, 4),
2938 product.evaluate_on_two_adic_domain(2, 4),
2939 product.evaluate_on_two_adic_domain(3, 4),
2940 ]
2941 );
2942 }
2943
2944 #[test]
2945 fn test_multiply_values2_four_values() {
2946 let p = Polynomial::with_coefficients(vec![
2947 from_const(1),
2948 from_const(2),
2949 from_const(3),
2950 from_const(4),
2951 ]);
2952 let q = Polynomial::with_coefficients(vec![
2953 from_const(5),
2954 from_const(6),
2955 from_const(7),
2956 from_const(8),
2957 ]);
2958 let lhs = vec![
2959 p.evaluate_on_two_adic_domain(0, 4),
2960 p.evaluate_on_two_adic_domain(1, 4),
2961 p.evaluate_on_two_adic_domain(2, 4),
2962 p.evaluate_on_two_adic_domain(3, 4),
2963 ];
2964 let rhs = vec![
2965 q.evaluate_on_two_adic_domain(0, 4),
2966 q.evaluate_on_two_adic_domain(1, 4),
2967 q.evaluate_on_two_adic_domain(2, 4),
2968 q.evaluate_on_two_adic_domain(3, 4),
2969 ];
2970 let product = p.multiply(q);
2971 let result = Polynomial::multiply_values2(lhs, rhs);
2972 assert_eq!(
2973 result,
2974 vec![
2975 product.evaluate_on_two_adic_domain(0, 8),
2976 product.evaluate_on_two_adic_domain(1, 8),
2977 product.evaluate_on_two_adic_domain(2, 8),
2978 product.evaluate_on_two_adic_domain(3, 8),
2979 product.evaluate_on_two_adic_domain(4, 8),
2980 product.evaluate_on_two_adic_domain(5, 8),
2981 product.evaluate_on_two_adic_domain(6, 8),
2982 product.evaluate_on_two_adic_domain(7, 8),
2983 ]
2984 );
2985 }
2986
2987 #[test]
2988 fn test_multiply_values2_commutative() {
2989 let p = Polynomial::with_coefficients(vec![from_const(1), from_const(2)]);
2990 let q = Polynomial::with_coefficients(vec![from_const(3), from_const(4)]);
2991 let values_p = vec![
2992 p.evaluate_on_two_adic_domain(0, 2),
2993 p.evaluate_on_two_adic_domain(1, 2),
2994 ];
2995 let values_q = vec![
2996 q.evaluate_on_two_adic_domain(0, 2),
2997 q.evaluate_on_two_adic_domain(1, 2),
2998 ];
2999 let result_pq = Polynomial::multiply_values2(values_p.clone(), values_q.clone());
3000 let result_qp = Polynomial::multiply_values2(values_q, values_p);
3001 assert_eq!(result_pq, result_qp);
3002 }
3003
3004 #[test]
3005 fn test_multiply_values2_round_trip() {
3006 let p = Polynomial::with_coefficients(vec![
3007 from_const(1),
3008 from_const(2),
3009 from_const(3),
3010 from_const(4),
3011 ]);
3012 let q = Polynomial::with_coefficients(vec![
3013 from_const(5),
3014 from_const(6),
3015 from_const(7),
3016 from_const(8),
3017 ]);
3018 let lhs = vec![
3019 p.evaluate_on_two_adic_domain(0, 4),
3020 p.evaluate_on_two_adic_domain(1, 4),
3021 p.evaluate_on_two_adic_domain(2, 4),
3022 p.evaluate_on_two_adic_domain(3, 4),
3023 ];
3024 let rhs = vec![
3025 q.evaluate_on_two_adic_domain(0, 4),
3026 q.evaluate_on_two_adic_domain(1, 4),
3027 q.evaluate_on_two_adic_domain(2, 4),
3028 q.evaluate_on_two_adic_domain(3, 4),
3029 ];
3030 let product = p.clone().multiply(q.clone());
3031 let result = Polynomial::encode2(Polynomial::multiply_values2(lhs, rhs));
3032 assert_eq!(result, product);
3033 }
3034
3035 #[test]
3036 fn test_multiply_values3_same_constant() {
3037 let lhs = vec![from_const(42), from_const(42), from_const(42)];
3038 let rhs = vec![from_const(42), from_const(42), from_const(42)];
3039 let result = Polynomial::multiply_values3(lhs, rhs);
3040 assert_eq!(result, vec![from_const(1764)]);
3041 }
3042
3043 #[test]
3044 fn test_multiply_values3_different_constants() {
3045 let lhs = vec![from_const(3), from_const(3), from_const(3)];
3046 let rhs = vec![from_const(7), from_const(7), from_const(7)];
3047 let result = Polynomial::multiply_values3(lhs, rhs);
3048 assert_eq!(result, vec![from_const(21)]);
3049 }
3050
3051 #[test]
3052 fn test_multiply_values3_two_linear_polynomials() {
3053 let p = Polynomial::with_coefficients(vec![from_const(1), from_const(2)]);
3054 let q = Polynomial::with_coefficients(vec![from_const(3), from_const(4)]);
3055 let lhs = vec![
3056 p.evaluate_on_three_adic_domain(0, 3),
3057 p.evaluate_on_three_adic_domain(1, 3),
3058 p.evaluate_on_three_adic_domain(2, 3),
3059 ];
3060 let rhs = vec![
3061 q.evaluate_on_three_adic_domain(0, 3),
3062 q.evaluate_on_three_adic_domain(1, 3),
3063 q.evaluate_on_three_adic_domain(2, 3),
3064 ];
3065 let product = p.multiply(q);
3066 let result = Polynomial::multiply_values3(lhs, rhs);
3067 assert_eq!(
3068 result,
3069 vec![
3070 product.evaluate_on_three_adic_domain(0, 3),
3071 product.evaluate_on_three_adic_domain(1, 3),
3072 product.evaluate_on_three_adic_domain(2, 3),
3073 ]
3074 );
3075 }
3076
3077 #[test]
3078 fn test_multiply_values3_nine_values() {
3079 let p = Polynomial::with_coefficients(vec![
3080 from_const(1),
3081 from_const(2),
3082 from_const(3),
3083 from_const(4),
3084 from_const(5),
3085 from_const(6),
3086 from_const(7),
3087 from_const(8),
3088 from_const(9),
3089 ]);
3090 let q = Polynomial::with_coefficients(vec![
3091 from_const(10),
3092 from_const(11),
3093 from_const(12),
3094 from_const(13),
3095 from_const(14),
3096 from_const(15),
3097 from_const(16),
3098 from_const(17),
3099 from_const(18),
3100 ]);
3101 let lhs = vec![
3102 p.evaluate_on_three_adic_domain(0, 9),
3103 p.evaluate_on_three_adic_domain(1, 9),
3104 p.evaluate_on_three_adic_domain(2, 9),
3105 p.evaluate_on_three_adic_domain(3, 9),
3106 p.evaluate_on_three_adic_domain(4, 9),
3107 p.evaluate_on_three_adic_domain(5, 9),
3108 p.evaluate_on_three_adic_domain(6, 9),
3109 p.evaluate_on_three_adic_domain(7, 9),
3110 p.evaluate_on_three_adic_domain(8, 9),
3111 ];
3112 let rhs = vec![
3113 q.evaluate_on_three_adic_domain(0, 9),
3114 q.evaluate_on_three_adic_domain(1, 9),
3115 q.evaluate_on_three_adic_domain(2, 9),
3116 q.evaluate_on_three_adic_domain(3, 9),
3117 q.evaluate_on_three_adic_domain(4, 9),
3118 q.evaluate_on_three_adic_domain(5, 9),
3119 q.evaluate_on_three_adic_domain(6, 9),
3120 q.evaluate_on_three_adic_domain(7, 9),
3121 q.evaluate_on_three_adic_domain(8, 9),
3122 ];
3123 let product = p.multiply(q);
3124 let result = Polynomial::multiply_values3(lhs, rhs);
3125 assert_eq!(
3126 result,
3127 vec![
3128 product.evaluate_on_three_adic_domain(0, 27),
3129 product.evaluate_on_three_adic_domain(1, 27),
3130 product.evaluate_on_three_adic_domain(2, 27),
3131 product.evaluate_on_three_adic_domain(3, 27),
3132 product.evaluate_on_three_adic_domain(4, 27),
3133 product.evaluate_on_three_adic_domain(5, 27),
3134 product.evaluate_on_three_adic_domain(6, 27),
3135 product.evaluate_on_three_adic_domain(7, 27),
3136 product.evaluate_on_three_adic_domain(8, 27),
3137 product.evaluate_on_three_adic_domain(9, 27),
3138 product.evaluate_on_three_adic_domain(10, 27),
3139 product.evaluate_on_three_adic_domain(11, 27),
3140 product.evaluate_on_three_adic_domain(12, 27),
3141 product.evaluate_on_three_adic_domain(13, 27),
3142 product.evaluate_on_three_adic_domain(14, 27),
3143 product.evaluate_on_three_adic_domain(15, 27),
3144 product.evaluate_on_three_adic_domain(16, 27),
3145 product.evaluate_on_three_adic_domain(17, 27),
3146 product.evaluate_on_three_adic_domain(18, 27),
3147 product.evaluate_on_three_adic_domain(19, 27),
3148 product.evaluate_on_three_adic_domain(20, 27),
3149 product.evaluate_on_three_adic_domain(21, 27),
3150 product.evaluate_on_three_adic_domain(22, 27),
3151 product.evaluate_on_three_adic_domain(23, 27),
3152 product.evaluate_on_three_adic_domain(24, 27),
3153 product.evaluate_on_three_adic_domain(25, 27),
3154 product.evaluate_on_three_adic_domain(26, 27),
3155 ]
3156 );
3157 }
3158
3159 #[test]
3160 fn test_multiply_values3_commutative() {
3161 let p = Polynomial::with_coefficients(vec![from_const(1), from_const(2)]);
3162 let q = Polynomial::with_coefficients(vec![from_const(3), from_const(4)]);
3163 let values_p = vec![
3164 p.evaluate_on_three_adic_domain(0, 3),
3165 p.evaluate_on_three_adic_domain(1, 3),
3166 p.evaluate_on_three_adic_domain(2, 3),
3167 ];
3168 let values_q = vec![
3169 q.evaluate_on_three_adic_domain(0, 3),
3170 q.evaluate_on_three_adic_domain(1, 3),
3171 q.evaluate_on_three_adic_domain(2, 3),
3172 ];
3173 let result_pq = Polynomial::multiply_values3(values_p.clone(), values_q.clone());
3174 let result_qp = Polynomial::multiply_values3(values_q, values_p);
3175 assert_eq!(result_pq, result_qp);
3176 }
3177
3178 #[test]
3179 fn test_multiply_values3_round_trip() {
3180 let p = Polynomial::with_coefficients(vec![from_const(1), from_const(2), from_const(3)]);
3181 let q = Polynomial::with_coefficients(vec![from_const(4), from_const(5), from_const(6)]);
3182 let lhs = vec![
3183 p.evaluate_on_three_adic_domain(0, 3),
3184 p.evaluate_on_three_adic_domain(1, 3),
3185 p.evaluate_on_three_adic_domain(2, 3),
3186 ];
3187 let rhs = vec![
3188 q.evaluate_on_three_adic_domain(0, 3),
3189 q.evaluate_on_three_adic_domain(1, 3),
3190 q.evaluate_on_three_adic_domain(2, 3),
3191 ];
3192 let product = p.clone().multiply(q.clone());
3193 let result = Polynomial::encode3(Polynomial::multiply_values3(lhs, rhs));
3194 assert_eq!(result, product);
3195 }
3196
3197 #[test]
3198 fn test_lagrange0_1() {
3199 let n = 1;
3200 let l0 = Polynomial::lagrange0(n);
3201 assert_eq!(l0.evaluate(from_const(1)), from_const(1));
3202 }
3203
3204 #[test]
3205 fn test_lagrange0_2() {
3206 let n = 2;
3207 let omega = Polynomial::domain_element2(1, n);
3208 let l0 = Polynomial::lagrange0(n);
3209 assert_eq!(l0.evaluate(from_const(1)), from_const(1));
3210 assert_eq!(l0.evaluate(omega), from_const(0));
3211 }
3212
3213 #[test]
3214 fn test_lagrange0_4() {
3215 let n = 4;
3216 let omega = Polynomial::domain_element2(1, n);
3217 let l0 = Polynomial::lagrange0(n);
3218 assert_eq!(l0.evaluate(from_const(1)), from_const(1));
3219 assert_eq!(l0.evaluate(omega), from_const(0));
3220 assert_eq!(l0.evaluate(omega.square()), from_const(0));
3221 assert_eq!(l0.evaluate(omega.cube()), from_const(0));
3222 }
3223
3224 #[test]
3225 fn test_lagrange0_8() {
3226 let n = 8;
3227 let omega = Polynomial::domain_element2(1, n);
3228 let l0 = Polynomial::lagrange0(n);
3229 assert_eq!(l0.evaluate(from_const(1)), from_const(1));
3230 assert_eq!(l0.evaluate(omega), from_const(0));
3231 assert_eq!(l0.evaluate(omega.pow_small(2)), from_const(0));
3232 assert_eq!(l0.evaluate(omega.pow_small(3)), from_const(0));
3233 assert_eq!(l0.evaluate(omega.pow_small(4)), from_const(0));
3234 assert_eq!(l0.evaluate(omega.pow_small(5)), from_const(0));
3235 assert_eq!(l0.evaluate(omega.pow_small(6)), from_const(0));
3236 assert_eq!(l0.evaluate(omega.pow_small(7)), from_const(0));
3237 }
3238}