1use crate::utils;
2use anyhow::{Context, Result, anyhow};
3use ff::PrimeField;
4use starkom_bluesky::ThreeAdicField;
5use std::ops::{Add, AddAssign, Mul, MulAssign, Neg, Sub, SubAssign};
6
7#[derive(Debug, Default, Clone, PartialEq, Eq)]
10pub struct Polynomial<F: PrimeField + Ord> {
11 coefficients: Vec<F>,
12}
13
14impl<F: PrimeField + Ord> Polynomial<F> {
15 pub fn with_coefficients(coefficients: Vec<F>) -> Self {
18 Self { coefficients }
19 }
20
21 pub fn constant(y: F) -> Self {
23 Self {
24 coefficients: vec![y],
25 }
26 }
27
28 pub fn interpolate(points: &[(F, F)]) -> Result<Self> {
34 let k = points.len();
35 let x = points.iter().map(|(x, _)| *x).collect::<Vec<F>>();
36 let l = Self::from_roots(x.as_slice(), 1.into()).context("duplicate X-coordinates")?;
37 let w = {
38 let one = F::ONE;
39 let mut weights = vec![one; k];
40 for i in 0..k {
41 for j in 0..k {
42 if i != j {
43 weights[i] *= x[i] - x[j];
44 }
45 }
46 weights[i] = weights[i]
47 .invert()
48 .into_option()
49 .context("duplicate X-coordinates")?;
50 }
51 weights
52 };
53 let mut result = Self {
54 coefficients: Vec::with_capacity(points.len()),
55 };
56 for i in 0..k {
57 let (basis, remainder) = l.horner(x[i]);
58 assert_eq!(remainder, F::ZERO);
59 let (_, y) = points[i];
60 result += basis * w[i] * y;
61 }
62 Ok(result)
63 }
64
65 pub fn from_roots(roots: &[F], blinding_factor: F) -> Result<Self> {
75 let mut roots = roots.to_vec();
76 roots.sort();
77 for i in 1..roots.len() {
78 if roots[i] == roots[i - 1] {
79 return Err(anyhow!("duplicate roots"));
80 }
81 }
82 let n = roots.len() + 1;
83 let mut coefficients = vec![F::ZERO; n];
84 coefficients[0] = blinding_factor;
85 for i in 1..n {
86 for j in (0..i).rev() {
87 let c = coefficients[j];
88 coefficients[j + 1] -= c * roots[i - 1];
89 }
90 }
91 coefficients.reverse();
92 Ok(Self { coefficients })
93 }
94
95 fn fft2(data: &mut [F], omega: F) {
102 let n = data.len();
103 assert!(n.is_power_of_two());
104
105 let log_n = n.trailing_zeros();
106 assert!(log_n <= F::S);
107
108 for i in 0..n {
109 let (j, _) = i.reverse_bits().overflowing_shr(usize::BITS - log_n);
110 if i < j {
111 data.swap(i, j);
112 }
113 }
114
115 let mut m = 1;
116 for _ in 0..log_n {
117 let step = m * 2;
118 let wm = omega.pow_vartime([(n / step) as u64, 0, 0, 0]);
119 let mut w = F::ONE;
120 for k in 0..m {
121 for j in (k..n).step_by(step) {
122 let t = w * data[j + m];
123 let u = data[j];
124 data[j] = u + t;
125 data[j + m] = u - t;
126 }
127 w *= wm;
128 }
129 m = step;
130 }
131 }
132
133 fn ifft2(data: &mut [F], omega: F) {
140 Self::fft2(data, omega.invert().into_option().unwrap());
141 let n_inv = F::from(data.len() as u64).invert().unwrap();
142 for v in data.iter_mut() {
143 *v *= n_inv;
144 }
145 }
146
147 fn two_adic_root_of_unity(n: usize) -> F {
149 assert!(n.is_power_of_two());
150 let k = n.trailing_zeros();
151 assert!(k <= F::S);
152 let exponent = 1u64 << (F::S - k);
153 F::ROOT_OF_UNITY.pow_vartime([exponent, 0, 0, 0])
154 }
155
156 pub fn encode2(mut values: Vec<F>) -> Self {
174 assert!(!values.is_empty());
175 let n = values.len().next_power_of_two();
176 assert!(n.trailing_zeros() <= F::S);
177 values.resize(n, F::ZERO);
178 let omega = Self::two_adic_root_of_unity(values.len());
179 Self::ifft2(values.as_mut_slice(), omega);
180 let mut polynomial = Polynomial {
181 coefficients: values,
182 };
183 polynomial.trim();
184 polynomial
185 }
186
187 pub fn decode2(self) -> Vec<F> {
199 let mut data = self.coefficients;
200 let n = data.len().next_power_of_two();
201 data.resize(n, F::ZERO);
202 let omega = Self::two_adic_root_of_unity(n);
203 Self::fft2(&mut data, omega);
204 data
205 }
206
207 pub fn len(&self) -> usize {
209 self.coefficients.len()
210 }
211
212 pub fn coefficients(&self) -> &[F] {
214 self.coefficients.as_slice()
215 }
216
217 fn degree_bound_of(coefficients: &[F]) -> usize {
218 for (i, &coefficient) in coefficients.iter().enumerate().rev() {
219 if coefficient != F::ZERO {
220 return i + 1;
221 }
222 }
223 0
224 }
225
226 pub fn degree_bound(&self) -> usize {
233 Self::degree_bound_of(self.coefficients.as_slice())
234 }
235
236 pub fn trim(&mut self) {
243 if let Some(i) = self
244 .coefficients
245 .iter()
246 .rposition(|value| *value != F::ZERO)
247 {
248 self.coefficients.truncate(i + 1);
249 } else {
250 self.coefficients.clear();
251 }
252 }
253
254 pub fn pad(&mut self, min_degree_bound: usize) {
257 let new_length = std::cmp::max(min_degree_bound, self.coefficients.len());
258 self.coefficients.resize(new_length, F::ZERO);
259 }
260
261 pub fn take(self) -> Vec<F> {
266 return self.coefficients;
267 }
268
269 pub fn multiply(mut self, mut other: Self) -> Self {
272 self.trim();
273 other.trim();
274
275 let mut lhs = self.coefficients;
276 let mut rhs = other.coefficients;
277
278 if lhs.is_empty() || rhs.is_empty() {
279 return Polynomial {
280 coefficients: vec![],
281 };
282 }
283 if lhs.len() == 1 {
284 return Polynomial { coefficients: rhs } * lhs[0];
285 }
286 if rhs.len() == 1 {
287 return Polynomial { coefficients: lhs } * rhs[0];
288 }
289
290 let n = (lhs.len() + rhs.len() - 1).next_power_of_two();
291
292 lhs.resize(n, F::ZERO);
293 rhs.resize(n, F::ZERO);
294
295 let omega = Self::two_adic_root_of_unity(n);
296 Self::fft2(lhs.as_mut_slice(), omega);
297 Self::fft2(rhs.as_mut_slice(), omega);
298
299 for i in 0..n {
300 lhs[i] *= rhs[i];
301 }
302
303 Self::ifft2(lhs.as_mut_slice(), omega);
304
305 let mut result = Polynomial { coefficients: lhs };
306 result.trim();
307 result
308 }
309
310 fn multiply_many_impl(polynomials: &mut [Self]) -> Self {
312 match polynomials.len() {
313 0 => Polynomial {
314 coefficients: vec![],
315 },
316 1 => std::mem::take(&mut polynomials[0]),
317 2 => {
318 let lhs = std::mem::take(&mut polynomials[0]);
319 let rhs = std::mem::take(&mut polynomials[1]);
320 lhs.multiply(rhs)
321 }
322 n => {
323 let (left, right) = polynomials.split_at_mut(n / 2);
324 let left = Self::multiply_many_impl(left);
325 let right = Self::multiply_many_impl(right);
326 left.multiply(right)
327 }
328 }
329 }
330
331 pub fn multiply_many<const N: usize>(mut polynomials: [Self; N]) -> Self {
337 assert!(N > 0);
338 Self::multiply_many_impl(&mut polynomials)
339 }
340
341 pub fn multiply_values2(mut lhs: Vec<F>, mut rhs: Vec<F>) -> Vec<F> {
350 let n = lhs.len();
351 assert!(n.is_power_of_two());
352 assert!(n.trailing_zeros() + 1 <= F::S);
353 assert_eq!(rhs.len(), n);
354 let omega = Self::two_adic_root_of_unity(n);
355 Self::ifft2(&mut lhs, omega);
356 Self::ifft2(&mut rhs, omega);
357 let lhs_len = Self::degree_bound_of(lhs.as_slice());
358 let rhs_len = Self::degree_bound_of(rhs.as_slice());
359 let m = (lhs_len + rhs_len - 1).next_power_of_two();
360 lhs.resize(m, F::ZERO);
361 rhs.resize(m, F::ZERO);
362 let omega = Self::two_adic_root_of_unity(m);
363 Self::fft2(&mut lhs, omega);
364 Self::fft2(&mut rhs, omega);
365 for i in 0..m {
366 lhs[i] *= rhs[i];
367 }
368 lhs
369 }
370
371 pub fn horner(&self, z: F) -> (Self, F) {
376 if self.coefficients.is_empty() {
377 return (Polynomial::default(), F::ZERO);
378 }
379 let n = self.len() - 1;
380 let mut coefficients = vec![F::ZERO; n];
381 if n < 1 {
382 return (Polynomial { coefficients }, self.coefficients[0]);
383 }
384 coefficients[n - 1] = self.coefficients[n];
385 for i in (1..n).rev() {
386 coefficients[i - 1] = self.coefficients[i] + z * coefficients[i];
387 }
388 let remainder = self.coefficients[0] + z * coefficients[0];
389 (Polynomial { coefficients }, remainder)
390 }
391
392 pub fn divide_by_zero(&self, n: usize) -> Result<Self> {
405 let mut data = self.coefficients.clone();
406 if data.len() < n {
407 data.resize(n, F::ZERO);
408 }
409
410 let degree = data.len() - n;
411 let mut quotient = vec![F::ZERO; degree];
412
413 let neg_one = F::ZERO - F::ONE;
414 for i in 0..degree {
415 let c = data[i] * neg_one;
416 quotient[i] = c;
417 data[i] += c;
418 data[i + n] -= c;
419 }
420
421 let remainder = &data[degree..];
422 if remainder.iter().any(|c| *c != F::ZERO) {
423 return Err(anyhow!("non-zero remainder in division by (x^n - 1)"));
424 }
425
426 if let Some(i) = quotient.iter().rposition(|c| *c != F::ZERO) {
427 quotient.truncate(i + 1);
428 }
429 Ok(Polynomial {
430 coefficients: quotient,
431 })
432 }
433
434 pub fn evaluate(&self, x: F) -> F {
442 let mut y = F::ZERO;
443 for coefficient in self.coefficients.iter().rev() {
444 y = y * x + *coefficient;
445 }
446 y
447 }
448
449 pub fn domain_element2(index: usize, domain_size: usize) -> F {
459 let omega = Self::two_adic_root_of_unity(domain_size.next_power_of_two());
460 omega.pow_vartime([index as u64, 0, 0, 0])
461 }
462
463 pub fn coset_element2(index: usize, domain_size: usize) -> F {
469 F::MULTIPLICATIVE_GENERATOR * Self::domain_element2(index, domain_size)
470 }
471
472 pub fn evaluate_on_two_adic_domain(&self, index: usize, domain_size: usize) -> F {
476 self.evaluate(Self::domain_element2(index, domain_size))
477 }
478
479 pub fn evaluate_on_two_adic_coset(&self, index: usize, domain_size: usize) -> F {
483 self.evaluate(Self::coset_element2(index, domain_size))
484 }
485
486 pub fn shifted_lde2(self, m: usize) -> Vec<F> {
501 assert!(m.is_power_of_two());
502 assert!(m.trailing_zeros() <= F::S);
503 assert!(self.coefficients.len() <= m);
504 let mut data = self.coefficients;
505 data.resize(m, F::ZERO);
506 let mut shift_pow = F::ONE;
507 for c in data.iter_mut() {
508 *c *= shift_pow;
509 shift_pow *= F::MULTIPLICATIVE_GENERATOR;
510 }
511 let omega = Self::two_adic_root_of_unity(m);
512 Self::fft2(&mut data, omega);
513 data
514 }
515}
516
517impl<F: PrimeField + Ord + ThreeAdicField> Polynomial<F> {
518 fn fft3(data: &mut [F], omega: F) {
525 let n = data.len();
526 assert!(utils::is_power_of_three(n));
527
528 let log_n = utils::ilog3(n);
529
530 for i in 0..n {
531 let mut j = 0;
532 let mut tmp = i;
533 for _ in 0..log_n {
534 j = j * 3 + tmp % 3;
535 tmp /= 3;
536 }
537 if i < j {
538 data.swap(i, j);
539 }
540 }
541
542 let omega3 = omega.pow_vartime([(n / 3) as u64, 0, 0, 0]);
543 let omega3_sq = omega3 * omega3;
544
545 let mut m = 1;
546 for _ in 0..log_n {
547 let step = m * 3;
548 let wm = omega.pow_vartime([(n / step) as u64, 0, 0, 0]);
549 let mut w = F::ONE;
550 let mut w2 = F::ONE;
551 for k in 0..m {
552 for j in (k..n).step_by(step) {
553 let t0 = data[j];
554 let t1 = w * data[j + m];
555 let t2 = w2 * data[j + 2 * m];
556 data[j] = t0 + t1 + t2;
557 data[j + m] = t0 + omega3 * t1 + omega3_sq * t2;
558 data[j + 2 * m] = t0 + omega3_sq * t1 + omega3 * t2;
559 }
560 w *= wm;
561 w2 = w * w;
562 }
563 m = step;
564 }
565 }
566
567 fn ifft3(data: &mut [F], omega: F) {
574 Self::fft3(data, omega.invert().into_option().unwrap());
575 let n_inv = F::from(data.len() as u64).invert().unwrap();
576 for v in data.iter_mut() {
577 *v *= n_inv;
578 }
579 }
580
581 fn three_adic_root_of_unity(n: usize) -> F {
583 assert!(utils::is_power_of_three(n));
584 let k = utils::ilog3(n) as u32;
585 assert!(k <= F::T);
586 let exponent = 3u64.pow(F::T - k);
587 F::THREE_ADIC_ROOT_OF_UNITY.pow_vartime([exponent, 0, 0, 0])
588 }
589
590 pub fn encode3(mut values: Vec<F>) -> Self {
609 assert!(!values.is_empty());
610 let n = utils::next_power_of_three(values.len());
611 assert!(utils::ilog3(n) <= F::T as usize);
612 values.resize(n, F::ZERO);
613 let omega = Self::three_adic_root_of_unity(values.len());
614 Self::ifft3(values.as_mut_slice(), omega);
615 let mut polynomial = Polynomial {
616 coefficients: values,
617 };
618 polynomial.trim();
619 polynomial
620 }
621
622 pub fn decode3(self) -> Vec<F> {
634 let mut data = self.coefficients;
635 let n = utils::next_power_of_three(data.len());
636 data.resize(n, F::ZERO);
637 let omega = Self::three_adic_root_of_unity(n);
638 Self::fft3(&mut data, omega);
639 data
640 }
641
642 pub fn domain_element3(index: usize, domain_size: usize) -> F {
652 let omega = Self::three_adic_root_of_unity(utils::next_power_of_three(domain_size));
653 omega.pow_vartime([index as u64, 0, 0, 0])
654 }
655
656 pub fn coset_element3(index: usize, domain_size: usize) -> F {
662 F::MULTIPLICATIVE_GENERATOR * Self::domain_element3(index, domain_size)
663 }
664
665 pub fn evaluate_on_three_adic_domain(&self, index: usize, domain_size: usize) -> F {
669 self.evaluate(Self::domain_element3(index, domain_size))
670 }
671
672 pub fn evaluate_on_three_adic_coset(&self, index: usize, domain_size: usize) -> F {
676 self.evaluate(Self::coset_element3(index, domain_size))
677 }
678
679 pub fn shifted_lde3(self, m: usize) -> Vec<F> {
694 assert!(utils::is_power_of_three(m));
695 assert!(utils::ilog3(m) as u32 <= F::T);
696 assert!(self.coefficients.len() <= m);
697 let mut data = self.coefficients;
698 data.resize(m, F::ZERO);
699 let mut shift_pow = F::ONE;
700 for c in data.iter_mut() {
701 *c *= shift_pow;
702 shift_pow *= F::MULTIPLICATIVE_GENERATOR;
703 }
704 let omega = Self::three_adic_root_of_unity(m);
705 Self::fft3(&mut data, omega);
706 data
707 }
708
709 pub fn multiply_values3(mut lhs: Vec<F>, mut rhs: Vec<F>) -> Vec<F> {
718 let n = lhs.len();
719 assert!(utils::is_power_of_three(n));
720 assert!(utils::ilog3(n) as u32 + 1 <= F::T);
721 assert_eq!(rhs.len(), n);
722 let omega = Self::three_adic_root_of_unity(n);
723 Self::ifft3(&mut lhs, omega);
724 Self::ifft3(&mut rhs, omega);
725 let lhs_len = Self::degree_bound_of(lhs.as_slice());
726 let rhs_len = Self::degree_bound_of(rhs.as_slice());
727 let m = utils::next_power_of_three(lhs_len + rhs_len - 1);
728 lhs.resize(m, F::ZERO);
729 rhs.resize(m, F::ZERO);
730 let omega = Self::three_adic_root_of_unity(m);
731 Self::fft3(&mut lhs, omega);
732 Self::fft3(&mut rhs, omega);
733 for i in 0..m {
734 lhs[i] *= rhs[i];
735 }
736 lhs
737 }
738}
739
740impl<F: PrimeField + Ord> Neg for Polynomial<F> {
741 type Output = Self;
742
743 fn neg(mut self) -> Self::Output {
744 for coefficient in &mut self.coefficients {
745 *coefficient = -*coefficient;
746 }
747 self
748 }
749}
750
751impl<F: PrimeField + Ord> Add<Polynomial<F>> for Polynomial<F> {
752 type Output = Self;
753
754 fn add(mut self, rhs: Self) -> Self::Output {
755 if rhs.len() > self.len() {
756 return rhs + self;
757 }
758 for i in 0..rhs.len() {
759 self.coefficients[i] += rhs.coefficients[i];
760 }
761 self
762 }
763}
764
765impl<F: PrimeField + Ord> AddAssign<Polynomial<F>> for Polynomial<F> {
766 fn add_assign(&mut self, mut rhs: Self) {
767 if rhs.len() > self.len() {
768 for i in 0..self.len() {
769 rhs.coefficients[i] += self.coefficients[i];
770 }
771 self.coefficients = rhs.coefficients;
772 } else {
773 for i in 0..rhs.len() {
774 self.coefficients[i] += rhs.coefficients[i];
775 }
776 }
777 }
778}
779
780impl<F: PrimeField + Ord> Add<F> for Polynomial<F> {
781 type Output = Self;
782
783 fn add(mut self, rhs: F) -> Self::Output {
784 if self.coefficients.is_empty() {
785 self.coefficients.push(rhs);
786 } else {
787 self.coefficients[0] += rhs;
788 }
789 self
790 }
791}
792
793impl<F: PrimeField + Ord> AddAssign<F> for Polynomial<F> {
794 fn add_assign(&mut self, rhs: F) {
795 if self.coefficients.is_empty() {
796 self.coefficients.push(rhs);
797 } else {
798 self.coefficients[0] += rhs;
799 }
800 }
801}
802
803impl<F: PrimeField + Ord> Sub<Polynomial<F>> for Polynomial<F> {
804 type Output = Self;
805
806 fn sub(mut self, rhs: Self) -> Self::Output {
807 if rhs.len() > self.len() {
808 return -(rhs - self);
809 }
810 for i in 0..rhs.len() {
811 self.coefficients[i] -= rhs.coefficients[i];
812 }
813 self
814 }
815}
816
817impl<F: PrimeField + Ord> SubAssign<Polynomial<F>> for Polynomial<F> {
818 fn sub_assign(&mut self, mut rhs: Self) {
819 if rhs.len() > self.len() {
820 for i in 0..self.len() {
821 rhs.coefficients[i] -= self.coefficients[i];
822 }
823 self.coefficients = rhs.coefficients;
824 for i in 0..self.len() {
825 self.coefficients[i] = -self.coefficients[i];
826 }
827 } else {
828 for i in 0..rhs.len() {
829 self.coefficients[i] -= rhs.coefficients[i];
830 }
831 }
832 }
833}
834
835impl<F: PrimeField + Ord> Sub<F> for Polynomial<F> {
836 type Output = Self;
837
838 fn sub(mut self, rhs: F) -> Self::Output {
839 if self.coefficients.is_empty() {
840 self.coefficients.push(-rhs);
841 } else {
842 self.coefficients[0] -= rhs;
843 }
844 self
845 }
846}
847
848impl<F: PrimeField + Ord> SubAssign<F> for Polynomial<F> {
849 fn sub_assign(&mut self, rhs: F) {
850 if self.coefficients.is_empty() {
851 self.coefficients.push(-rhs);
852 } else {
853 self.coefficients[0] -= rhs;
854 }
855 }
856}
857
858impl<F: PrimeField + Ord> Mul<F> for Polynomial<F> {
859 type Output = Self;
860
861 fn mul(mut self, rhs: F) -> Self::Output {
862 for i in 0..self.len() {
863 self.coefficients[i] *= rhs;
864 }
865 self
866 }
867}
868
869impl<F: PrimeField + Ord> MulAssign<F> for Polynomial<F> {
870 fn mul_assign(&mut self, rhs: F) {
871 for i in 0..self.len() {
872 self.coefficients[i] *= rhs;
873 }
874 }
875}
876
877impl<F: PrimeField + Ord> Mul<Polynomial<F>> for Polynomial<F> {
878 type Output = Self;
879
880 fn mul(self, rhs: Self) -> Self::Output {
881 self.multiply(rhs)
882 }
883}
884
885impl<F: PrimeField + Ord> MulAssign<Polynomial<F>> for Polynomial<F> {
886 fn mul_assign(&mut self, rhs: Self) {
887 *self = std::mem::take(self).multiply(rhs);
888 }
889}
890
891#[cfg(test)]
892mod tests {
893 use ff::Field;
894 use starkom_bluesky::Scalar;
895
896 type Polynomial = super::Polynomial<Scalar>;
897
898 fn get_random_scalar() -> Scalar {
899 Scalar::random(rand_core::OsRng)
900 }
901
902 fn from_roots(roots: &[Scalar]) -> Polynomial {
903 Polynomial::from_roots(roots, get_random_scalar()).unwrap()
904 }
905
906 #[test]
907 fn test_constant() {
908 let p = Polynomial::constant(42.into());
909 assert_eq!(p.evaluate(12.into()), 42.into());
910 assert_eq!(p.evaluate(34.into()), 42.into());
911 assert_eq!(p.evaluate(42.into()), 42.into());
912 }
913
914 #[test]
915 fn test_zero() {
916 let p = Polynomial::with_coefficients(vec![]);
917 assert_eq!(p, Polynomial::default());
918 assert_eq!(p.len(), 0);
919 assert_eq!(p.degree_bound(), 0);
920 assert_eq!(p.evaluate(42.into()), 0.into());
921 }
922
923 #[test]
924 fn test_with_coefficients() {
925 let p = Polynomial::with_coefficients(vec![12.into(), 34.into(), 56.into()]);
926 assert_eq!(p.len(), 3);
927 assert_eq!(p.degree_bound(), 3);
928 assert_eq!(p.take(), vec![12.into(), 34.into(), 56.into()]);
929 }
930
931 #[test]
932 fn test_low_degree() {
933 let p = Polynomial::with_coefficients(vec![
934 12.into(),
935 34.into(),
936 56.into(),
937 0.into(),
938 0.into(),
939 ]);
940 assert_eq!(p.len(), 5);
941 assert_eq!(p.degree_bound(), 3);
942 }
943
944 #[test]
945 fn test_skip_degree() {
946 let p = Polynomial::with_coefficients(vec![
947 0.into(),
948 0.into(),
949 12.into(),
950 34.into(),
951 56.into(),
952 ]);
953 assert_eq!(p.len(), 5);
954 assert_eq!(p.degree_bound(), 5);
955 }
956
957 #[test]
958 fn test_trim_degree() {
959 let mut p = Polynomial::with_coefficients(vec![
960 12.into(),
961 34.into(),
962 56.into(),
963 0.into(),
964 0.into(),
965 ]);
966 p.trim();
967 assert_eq!(p.len(), 3);
968 assert_eq!(p.degree_bound(), 3);
969 }
970
971 #[test]
972 fn test_no_trim() {
973 let mut p = Polynomial::with_coefficients(vec![
974 0.into(),
975 0.into(),
976 12.into(),
977 34.into(),
978 56.into(),
979 ]);
980 p.trim();
981 assert_eq!(p.len(), 5);
982 assert_eq!(p.degree_bound(), 5);
983 }
984
985 #[test]
986 fn test_trim_all_zero() {
987 let mut p = Polynomial::with_coefficients(vec![0.into(), 0.into(), 0.into()]);
988 p.trim();
989 assert_eq!(p.len(), p.degree_bound());
990 assert_eq!(p, Polynomial::default());
991 }
992
993 #[test]
994 fn test_pad_extends() {
995 let mut p = Polynomial::with_coefficients(vec![12.into(), 34.into()]);
996 p.pad(5);
997 assert_eq!(p.len(), 5);
998 assert_eq!(
999 p.take(),
1000 vec![12.into(), 34.into(), 0.into(), 0.into(), 0.into()]
1001 );
1002 }
1003
1004 #[test]
1005 fn test_pad_exact() {
1006 let mut p = Polynomial::with_coefficients(vec![12.into(), 34.into(), 56.into()]);
1007 p.pad(3);
1008 assert_eq!(p.len(), 3);
1009 assert_eq!(p.take(), vec![12.into(), 34.into(), 56.into()]);
1010 }
1011
1012 #[test]
1013 fn test_pad_no_shrink() {
1014 let mut p = Polynomial::with_coefficients(vec![12.into(), 34.into(), 56.into(), 78.into()]);
1015 p.pad(2);
1016 assert_eq!(p.len(), 4);
1017 assert_eq!(p.take(), vec![12.into(), 34.into(), 56.into(), 78.into()]);
1018 }
1019
1020 #[test]
1021 fn test_pad_empty() {
1022 let mut p = Polynomial::default();
1023 p.pad(3);
1024 assert_eq!(p.len(), 3);
1025 assert_eq!(p.take(), vec![0.into(), 0.into(), 0.into()]);
1026 }
1027
1028 #[test]
1029 fn test_pad_zero_bound() {
1030 let mut p = Polynomial::with_coefficients(vec![12.into(), 34.into()]);
1031 p.pad(0);
1032 assert_eq!(p.len(), 2);
1033 assert_eq!(p.take(), vec![12.into(), 34.into()]);
1034 }
1035
1036 #[test]
1037 fn test_pad_preserves_evaluation() {
1038 let mut p = Polynomial::with_coefficients(vec![1.into(), 2.into(), 3.into()]);
1039 let before = p.evaluate(7.into());
1040 p.pad(6);
1041 assert_eq!(p.evaluate(7.into()), before);
1042 }
1043
1044 #[test]
1045 fn test_no_roots() {
1046 let p = from_roots(&[]);
1047 assert_eq!(p.len(), 1);
1048 assert_eq!(p.degree_bound(), 1);
1049 assert_ne!(p.evaluate(12.into()), 0.into());
1050 assert_ne!(p.evaluate(34.into()), 0.into());
1051 assert_ne!(p.evaluate(56.into()), 0.into());
1052 assert_ne!(p.evaluate(78.into()), 0.into());
1053 assert_ne!(p.evaluate(90.into()), 0.into());
1054 assert_ne!(p.evaluate(13.into()), 0.into());
1055 assert_ne!(p.evaluate(57.into()), 0.into());
1056 assert_ne!(p.evaluate(92.into()), 0.into());
1057 assert_ne!(p.evaluate(46.into()), 0.into());
1058 assert_ne!(p.evaluate(80.into()), 0.into());
1059 }
1060
1061 #[test]
1062 fn test_one_root() {
1063 let p = from_roots(&[12.into()]);
1064 assert_eq!(p.len(), 2);
1065 assert_eq!(p.degree_bound(), 2);
1066 assert_eq!(p.evaluate(12.into()), 0.into());
1067 assert_ne!(p.evaluate(34.into()), 0.into());
1068 assert_ne!(p.evaluate(56.into()), 0.into());
1069 assert_ne!(p.evaluate(78.into()), 0.into());
1070 assert_ne!(p.evaluate(90.into()), 0.into());
1071 assert_ne!(p.evaluate(13.into()), 0.into());
1072 assert_ne!(p.evaluate(57.into()), 0.into());
1073 assert_ne!(p.evaluate(92.into()), 0.into());
1074 assert_ne!(p.evaluate(46.into()), 0.into());
1075 assert_ne!(p.evaluate(80.into()), 0.into());
1076 let (q, v) = p.horner(12.into());
1077 assert_eq!(q.len(), 1);
1078 assert_eq!(q.degree_bound(), 1);
1079 assert_eq!(v, 0.into());
1080 let (q, v) = p.horner(34.into());
1081 assert_eq!(q.len(), 1);
1082 assert_eq!(q.degree_bound(), 1);
1083 assert_ne!(v, 0.into());
1084 }
1085
1086 #[test]
1087 fn test_three_roots() {
1088 let p = from_roots(&[12.into(), 34.into(), 56.into()]);
1089 assert_eq!(p.len(), 4);
1090 assert_eq!(p.degree_bound(), 4);
1091 assert_eq!(p.evaluate(12.into()), 0.into());
1092 assert_eq!(p.evaluate(34.into()), 0.into());
1093 assert_eq!(p.evaluate(56.into()), 0.into());
1094 assert_ne!(p.evaluate(78.into()), 0.into());
1095 assert_ne!(p.evaluate(90.into()), 0.into());
1096 assert_ne!(p.evaluate(13.into()), 0.into());
1097 assert_ne!(p.evaluate(57.into()), 0.into());
1098 assert_ne!(p.evaluate(92.into()), 0.into());
1099 assert_ne!(p.evaluate(46.into()), 0.into());
1100 assert_ne!(p.evaluate(80.into()), 0.into());
1101 let (q, v) = p.horner(12.into());
1102 assert_eq!(q.len(), 3);
1103 assert_eq!(q.degree_bound(), 3);
1104 assert_eq!(v, 0.into());
1105 let (q, v) = q.horner(34.into());
1106 assert_eq!(q.len(), 2);
1107 assert_eq!(q.degree_bound(), 2);
1108 assert_eq!(v, 0.into());
1109 let (q, v) = q.horner(56.into());
1110 assert_eq!(q.len(), 1);
1111 assert_eq!(q.degree_bound(), 1);
1112 assert_eq!(v, 0.into());
1113 let (q, v) = p.horner(78.into());
1114 assert_eq!(q.len(), 3);
1115 assert_eq!(q.degree_bound(), 3);
1116 assert_ne!(v, 0.into());
1117 let (q, v) = p.horner(90.into());
1118 assert_eq!(q.len(), 3);
1119 assert_eq!(q.degree_bound(), 3);
1120 assert_ne!(v, 0.into());
1121 }
1122
1123 #[test]
1124 fn test_three_roots_reverse_order() {
1125 let p = from_roots(&[56.into(), 34.into(), 12.into()]);
1126 assert_eq!(p.len(), 4);
1127 assert_eq!(p.degree_bound(), 4);
1128 assert_eq!(p.evaluate(12.into()), 0.into());
1129 assert_eq!(p.evaluate(34.into()), 0.into());
1130 assert_eq!(p.evaluate(56.into()), 0.into());
1131 assert_ne!(p.evaluate(78.into()), 0.into());
1132 assert_ne!(p.evaluate(90.into()), 0.into());
1133 assert_ne!(p.evaluate(13.into()), 0.into());
1134 assert_ne!(p.evaluate(57.into()), 0.into());
1135 assert_ne!(p.evaluate(92.into()), 0.into());
1136 assert_ne!(p.evaluate(46.into()), 0.into());
1137 assert_ne!(p.evaluate(80.into()), 0.into());
1138 let (q, v) = p.horner(12.into());
1139 assert_eq!(q.len(), 3);
1140 assert_eq!(q.degree_bound(), 3);
1141 assert_eq!(v, 0.into());
1142 let (q, v) = q.horner(34.into());
1143 assert_eq!(q.len(), 2);
1144 assert_eq!(q.degree_bound(), 2);
1145 assert_eq!(v, 0.into());
1146 let (q, v) = q.horner(56.into());
1147 assert_eq!(q.len(), 1);
1148 assert_eq!(q.degree_bound(), 1);
1149 assert_eq!(v, 0.into());
1150 let (q, v) = p.horner(78.into());
1151 assert_eq!(q.len(), 3);
1152 assert_eq!(q.degree_bound(), 3);
1153 assert_ne!(v, 0.into());
1154 let (q, v) = p.horner(90.into());
1155 assert_eq!(q.len(), 3);
1156 assert_eq!(q.degree_bound(), 3);
1157 assert_ne!(v, 0.into());
1158 }
1159
1160 #[test]
1161 fn test_seven_roots() {
1162 let p = from_roots(&[
1163 12.into(),
1164 34.into(),
1165 56.into(),
1166 78.into(),
1167 90.into(),
1168 13.into(),
1169 57.into(),
1170 ]);
1171 assert_eq!(p.len(), 8);
1172 assert_eq!(p.degree_bound(), 8);
1173 assert_eq!(p.evaluate(12.into()), 0.into());
1174 assert_eq!(p.evaluate(34.into()), 0.into());
1175 assert_eq!(p.evaluate(56.into()), 0.into());
1176 assert_eq!(p.evaluate(78.into()), 0.into());
1177 assert_eq!(p.evaluate(90.into()), 0.into());
1178 assert_eq!(p.evaluate(13.into()), 0.into());
1179 assert_eq!(p.evaluate(57.into()), 0.into());
1180 assert_ne!(p.evaluate(92.into()), 0.into());
1181 assert_ne!(p.evaluate(46.into()), 0.into());
1182 assert_ne!(p.evaluate(80.into()), 0.into());
1183 }
1184
1185 #[test]
1186 fn test_seven_roots_reverse_order() {
1187 let p = from_roots(&[
1188 57.into(),
1189 13.into(),
1190 90.into(),
1191 78.into(),
1192 56.into(),
1193 34.into(),
1194 12.into(),
1195 ]);
1196 assert_eq!(p.len(), 8);
1197 assert_eq!(p.degree_bound(), 8);
1198 assert_eq!(p.evaluate(12.into()), 0.into());
1199 assert_eq!(p.evaluate(34.into()), 0.into());
1200 assert_eq!(p.evaluate(56.into()), 0.into());
1201 assert_eq!(p.evaluate(78.into()), 0.into());
1202 assert_eq!(p.evaluate(90.into()), 0.into());
1203 assert_eq!(p.evaluate(13.into()), 0.into());
1204 assert_eq!(p.evaluate(57.into()), 0.into());
1205 assert_ne!(p.evaluate(92.into()), 0.into());
1206 assert_ne!(p.evaluate(46.into()), 0.into());
1207 assert_ne!(p.evaluate(80.into()), 0.into());
1208 }
1209
1210 #[test]
1211 fn test_duplicate_roots() {
1212 assert!(
1213 Polynomial::from_roots(
1214 &[
1215 12.into(),
1216 34.into(),
1217 56.into(),
1218 12.into(),
1219 90.into(),
1220 12.into(),
1221 57.into(),
1222 ],
1223 get_random_scalar()
1224 )
1225 .is_err()
1226 );
1227 }
1228
1229 #[test]
1230 fn test_interpolate_zero_points() {
1231 let p = Polynomial::interpolate(&[]).unwrap();
1232 assert_eq!(p, Polynomial::default());
1233 }
1234
1235 #[test]
1236 fn test_interpolate_one_point1() {
1237 let p = Polynomial::interpolate(&[(12.into(), 34.into())]).unwrap();
1238 assert_eq!(p.len(), 1);
1239 assert_eq!(p.degree_bound(), 1);
1240 assert_eq!(p.evaluate(12.into()), 34.into());
1241 }
1242
1243 #[test]
1244 fn test_interpolate_one_point2() {
1245 let p = Polynomial::interpolate(&[(34.into(), 56.into())]).unwrap();
1246 assert_eq!(p.len(), 1);
1247 assert_eq!(p.degree_bound(), 1);
1248 assert_eq!(p.evaluate(34.into()), 56.into());
1249 }
1250
1251 #[test]
1252 fn test_interpolate_two_points1() {
1253 let p = Polynomial::interpolate(&[(12.into(), 34.into()), (56.into(), 78.into())]).unwrap();
1254 assert_eq!(p.len(), 2);
1255 assert_eq!(p.degree_bound(), 2);
1256 assert_eq!(p.evaluate(12.into()), 34.into());
1257 assert_eq!(p.evaluate(56.into()), 78.into());
1258 }
1259
1260 #[test]
1261 fn test_interpolate_two_points2() {
1262 let p = Polynomial::interpolate(&[(34.into(), 12.into()), (78.into(), 56.into())]).unwrap();
1263 assert_eq!(p.len(), 2);
1264 assert_eq!(p.degree_bound(), 2);
1265 assert_eq!(p.evaluate(34.into()), 12.into());
1266 assert_eq!(p.evaluate(78.into()), 56.into());
1267 }
1268
1269 #[test]
1270 fn test_interpolate_three_points1() {
1271 let p = Polynomial::interpolate(&[
1272 (12.into(), 34.into()),
1273 (56.into(), 78.into()),
1274 (90.into(), 12.into()),
1275 ])
1276 .unwrap();
1277 assert_eq!(p.len(), 3);
1278 assert_eq!(p.degree_bound(), 3);
1279 assert_eq!(p.evaluate(12.into()), 34.into());
1280 assert_eq!(p.evaluate(56.into()), 78.into());
1281 assert_eq!(p.evaluate(90.into()), 12.into());
1282 }
1283
1284 #[test]
1285 fn test_interpolate_three_points2() {
1286 let p = Polynomial::interpolate(&[
1287 (34.into(), 12.into()),
1288 (78.into(), 56.into()),
1289 (12.into(), 90.into()),
1290 ])
1291 .unwrap();
1292 assert_eq!(p.len(), 3);
1293 assert_eq!(p.degree_bound(), 3);
1294 assert_eq!(p.evaluate(34.into()), 12.into());
1295 assert_eq!(p.evaluate(78.into()), 56.into());
1296 assert_eq!(p.evaluate(12.into()), 90.into());
1297 }
1298
1299 #[test]
1300 fn test_duplicate_coordinates() {
1301 assert!(
1302 Polynomial::interpolate(&[
1303 (12.into(), 34.into()),
1304 (56.into(), 78.into()),
1305 (12.into(), 90.into()),
1306 ])
1307 .is_err()
1308 );
1309 }
1310
1311 #[test]
1312 fn test_encode2_one_value_1() {
1313 let p1 = Polynomial::encode2(vec![42.into()]);
1314 let p2 = Polynomial::encode2(vec![42.into()]);
1315 assert_eq!(p1, p2);
1316 assert_eq!(p1.len(), 1);
1317 assert_eq!(p1.degree_bound(), 1);
1318 assert_eq!(p2.len(), 1);
1319 assert_eq!(p2.degree_bound(), 1);
1320 assert_eq!(p1.evaluate(Polynomial::domain_element2(0, 1)), 42.into());
1321 assert_eq!(p1.evaluate_on_two_adic_domain(0, 1), 42.into());
1322 assert_eq!(p2.evaluate(Polynomial::domain_element2(0, 1)), 42.into());
1323 assert_eq!(p2.evaluate_on_two_adic_domain(0, 1), 42.into());
1324 }
1325
1326 #[test]
1327 fn test_encode2_one_value_2() {
1328 let p1 = Polynomial::encode2(vec![42.into()]);
1329 let p2 = Polynomial::encode2(vec![123.into()]);
1330 assert_eq!(p2.len(), 1);
1331 assert_eq!(p2.degree_bound(), 1);
1332 assert_ne!(p1, p2);
1333 assert_eq!(p2.evaluate(Polynomial::domain_element2(0, 1)), 123.into());
1334 assert_eq!(p2.evaluate_on_two_adic_domain(0, 1), 123.into());
1335 }
1336
1337 #[test]
1338 fn test_encode2_two_values_1() {
1339 let p1 = Polynomial::encode2(vec![12.into(), 34.into()]);
1340 let p2 = Polynomial::encode2(vec![12.into(), 34.into()]);
1341 assert_eq!(p1, p2);
1342 assert_eq!(p1.len(), 2);
1343 assert_eq!(p1.degree_bound(), 2);
1344 assert_eq!(p2.len(), 2);
1345 assert_eq!(p2.degree_bound(), 2);
1346 assert_eq!(p1.evaluate(Polynomial::domain_element2(0, 2)), 12.into());
1347 assert_eq!(p1.evaluate_on_two_adic_domain(0, 2), 12.into());
1348 assert_eq!(p1.evaluate(Polynomial::domain_element2(1, 2)), 34.into());
1349 assert_eq!(p1.evaluate_on_two_adic_domain(1, 2), 34.into());
1350 assert_eq!(p2.evaluate(Polynomial::domain_element2(0, 2)), 12.into());
1351 assert_eq!(p2.evaluate_on_two_adic_domain(0, 2), 12.into());
1352 assert_eq!(p2.evaluate(Polynomial::domain_element2(1, 2)), 34.into());
1353 assert_eq!(p2.evaluate_on_two_adic_domain(1, 2), 34.into());
1354 }
1355
1356 #[test]
1357 fn test_encode2_two_values_2() {
1358 let p1 = Polynomial::encode2(vec![12.into(), 34.into()]);
1359 let p2 = Polynomial::encode2(vec![78.into(), 56.into()]);
1360 assert_eq!(p1.len(), 2);
1361 assert_eq!(p1.degree_bound(), 2);
1362 assert_eq!(p2.len(), 2);
1363 assert_eq!(p2.degree_bound(), 2);
1364 assert_ne!(p1, p2);
1365 assert_eq!(p2.evaluate(Polynomial::domain_element2(0, 2)), 78.into());
1366 assert_eq!(p2.evaluate_on_two_adic_domain(0, 2), 78.into());
1367 assert_eq!(p2.evaluate(Polynomial::domain_element2(1, 2)), 56.into());
1368 assert_eq!(p2.evaluate_on_two_adic_domain(1, 2), 56.into());
1369 }
1370
1371 #[test]
1372 fn test_encode2_three_values_1() {
1373 let p1 = Polynomial::encode2(vec![12.into(), 34.into(), 56.into()]);
1374 let p2 = Polynomial::encode2(vec![12.into(), 34.into(), 56.into()]);
1375 assert_eq!(p1, p2);
1376 assert_eq!(p1.len(), 4);
1377 assert_eq!(p1.degree_bound(), 4);
1378 assert_eq!(p2.len(), 4);
1379 assert_eq!(p2.degree_bound(), 4);
1380 assert_eq!(p1.evaluate(Polynomial::domain_element2(0, 3)), 12.into());
1381 assert_eq!(p1.evaluate_on_two_adic_domain(0, 3), 12.into());
1382 assert_eq!(p1.evaluate(Polynomial::domain_element2(0, 4)), 12.into());
1383 assert_eq!(p1.evaluate_on_two_adic_domain(0, 4), 12.into());
1384 assert_eq!(p1.evaluate(Polynomial::domain_element2(1, 3)), 34.into());
1385 assert_eq!(p1.evaluate_on_two_adic_domain(1, 3), 34.into());
1386 assert_eq!(p1.evaluate(Polynomial::domain_element2(1, 4)), 34.into());
1387 assert_eq!(p1.evaluate_on_two_adic_domain(1, 4), 34.into());
1388 assert_eq!(p1.evaluate(Polynomial::domain_element2(2, 3)), 56.into());
1389 assert_eq!(p1.evaluate_on_two_adic_domain(2, 3), 56.into());
1390 assert_eq!(p1.evaluate(Polynomial::domain_element2(2, 4)), 56.into());
1391 assert_eq!(p1.evaluate_on_two_adic_domain(2, 4), 56.into());
1392 assert_eq!(p1.evaluate(Polynomial::domain_element2(3, 4)), 0.into());
1393 assert_eq!(p1.evaluate_on_two_adic_domain(3, 4), 0.into());
1394 assert_eq!(p2.evaluate(Polynomial::domain_element2(0, 3)), 12.into());
1395 assert_eq!(p2.evaluate_on_two_adic_domain(0, 3), 12.into());
1396 assert_eq!(p2.evaluate(Polynomial::domain_element2(0, 4)), 12.into());
1397 assert_eq!(p2.evaluate_on_two_adic_domain(0, 4), 12.into());
1398 assert_eq!(p2.evaluate(Polynomial::domain_element2(1, 3)), 34.into());
1399 assert_eq!(p2.evaluate_on_two_adic_domain(1, 3), 34.into());
1400 assert_eq!(p2.evaluate(Polynomial::domain_element2(1, 4)), 34.into());
1401 assert_eq!(p2.evaluate_on_two_adic_domain(1, 4), 34.into());
1402 assert_eq!(p2.evaluate(Polynomial::domain_element2(2, 3)), 56.into());
1403 assert_eq!(p2.evaluate_on_two_adic_domain(2, 3), 56.into());
1404 assert_eq!(p2.evaluate(Polynomial::domain_element2(2, 4)), 56.into());
1405 assert_eq!(p2.evaluate_on_two_adic_domain(2, 4), 56.into());
1406 assert_eq!(p2.evaluate(Polynomial::domain_element2(3, 4)), 0.into());
1407 assert_eq!(p2.evaluate_on_two_adic_domain(3, 4), 0.into());
1408 }
1409
1410 #[test]
1411 fn test_encode2_three_values_2() {
1412 let p1 = Polynomial::encode2(vec![12.into(), 34.into(), 56.into()]);
1413 let p2 = Polynomial::encode2(vec![90.into(), 78.into(), 34.into()]);
1414 assert_eq!(p1.len(), 4);
1415 assert_eq!(p1.degree_bound(), 4);
1416 assert_eq!(p2.len(), 4);
1417 assert_eq!(p2.degree_bound(), 4);
1418 assert_ne!(p1, p2);
1419 assert_eq!(p2.evaluate(Polynomial::domain_element2(0, 3)), 90.into());
1420 assert_eq!(p2.evaluate_on_two_adic_domain(0, 3), 90.into());
1421 assert_eq!(p2.evaluate(Polynomial::domain_element2(0, 4)), 90.into());
1422 assert_eq!(p2.evaluate_on_two_adic_domain(0, 4), 90.into());
1423 assert_eq!(p2.evaluate(Polynomial::domain_element2(1, 3)), 78.into());
1424 assert_eq!(p2.evaluate_on_two_adic_domain(1, 3), 78.into());
1425 assert_eq!(p2.evaluate(Polynomial::domain_element2(1, 4)), 78.into());
1426 assert_eq!(p2.evaluate_on_two_adic_domain(1, 4), 78.into());
1427 assert_eq!(p2.evaluate(Polynomial::domain_element2(2, 3)), 34.into());
1428 assert_eq!(p2.evaluate_on_two_adic_domain(2, 3), 34.into());
1429 assert_eq!(p2.evaluate(Polynomial::domain_element2(2, 4)), 34.into());
1430 assert_eq!(p2.evaluate_on_two_adic_domain(2, 4), 34.into());
1431 assert_eq!(p2.evaluate(Polynomial::domain_element2(3, 4)), 0.into());
1432 assert_eq!(p2.evaluate_on_two_adic_domain(3, 4), 0.into());
1433 }
1434
1435 #[test]
1436 fn test_encode2_four_values() {
1437 let p = Polynomial::encode2(vec![12.into(), 34.into(), 56.into(), 78.into()]);
1438 assert_eq!(p.len(), 4);
1439 assert_eq!(p.degree_bound(), 4);
1440 assert_eq!(p.evaluate(Polynomial::domain_element2(0, 4)), 12.into());
1441 assert_eq!(p.evaluate_on_two_adic_domain(0, 4), 12.into());
1442 assert_eq!(p.evaluate(Polynomial::domain_element2(1, 4)), 34.into());
1443 assert_eq!(p.evaluate_on_two_adic_domain(1, 4), 34.into());
1444 assert_eq!(p.evaluate(Polynomial::domain_element2(2, 4)), 56.into());
1445 assert_eq!(p.evaluate_on_two_adic_domain(2, 4), 56.into());
1446 assert_eq!(p.evaluate(Polynomial::domain_element2(3, 4)), 78.into());
1447 assert_eq!(p.evaluate_on_two_adic_domain(3, 4), 78.into());
1448 }
1449
1450 #[test]
1451 fn test_decode2_one_value() {
1452 let values = vec![42.into()];
1453 let polynomial = Polynomial::encode2(values.clone());
1454 assert_eq!(polynomial.decode2(), values);
1455 }
1456
1457 #[test]
1458 fn test_decode2_two_values() {
1459 let values = vec![12.into(), 34.into()];
1460 let polynomial = Polynomial::encode2(values.clone());
1461 assert_eq!(polynomial.decode2(), values);
1462 }
1463
1464 #[test]
1465 fn test_decode2_three_values() {
1466 let polynomial = Polynomial::encode2(vec![12.into(), 34.into(), 56.into()]);
1467 assert_eq!(
1468 polynomial.decode2(),
1469 vec![12.into(), 34.into(), 56.into(), 0.into()]
1470 );
1471 }
1472
1473 #[test]
1474 fn test_decode2_four_values() {
1475 let values = vec![12.into(), 34.into(), 56.into(), 78.into()];
1476 let polynomial = Polynomial::encode2(values.clone());
1477 assert_eq!(polynomial.decode2(), values);
1478 }
1479
1480 #[test]
1481 fn test_encode3_one_value_1() {
1482 let p1 = Polynomial::encode3(vec![42.into()]);
1483 let p2 = Polynomial::encode3(vec![42.into()]);
1484 assert_eq!(p1, p2);
1485 assert_eq!(p1.len(), 1);
1486 assert_eq!(p1.degree_bound(), 1);
1487 assert_eq!(p2.len(), 1);
1488 assert_eq!(p2.degree_bound(), 1);
1489 assert_eq!(p1.evaluate(Polynomial::domain_element3(0, 1)), 42.into());
1490 assert_eq!(p1.evaluate_on_three_adic_domain(0, 1), 42.into());
1491 assert_eq!(p2.evaluate(Polynomial::domain_element3(0, 1)), 42.into());
1492 assert_eq!(p2.evaluate_on_three_adic_domain(0, 1), 42.into());
1493 }
1494
1495 #[test]
1496 fn test_encode3_one_value_2() {
1497 let p1 = Polynomial::encode3(vec![42.into()]);
1498 let p2 = Polynomial::encode3(vec![123.into()]);
1499 assert_eq!(p2.len(), 1);
1500 assert_eq!(p2.degree_bound(), 1);
1501 assert_ne!(p1, p2);
1502 assert_eq!(p2.evaluate(Polynomial::domain_element3(0, 1)), 123.into());
1503 assert_eq!(p2.evaluate_on_three_adic_domain(0, 1), 123.into());
1504 }
1505
1506 #[test]
1507 fn test_encode3_two_values_1() {
1508 let p1 = Polynomial::encode3(vec![12.into(), 34.into()]);
1509 let p2 = Polynomial::encode3(vec![12.into(), 34.into()]);
1510 assert_eq!(p1, p2);
1511 assert_eq!(p1.len(), 3);
1512 assert_eq!(p1.degree_bound(), 3);
1513 assert_eq!(p2.len(), 3);
1514 assert_eq!(p2.degree_bound(), 3);
1515 assert_eq!(p1.evaluate(Polynomial::domain_element3(0, 2)), 12.into());
1516 assert_eq!(p1.evaluate_on_three_adic_domain(0, 2), 12.into());
1517 assert_eq!(p1.evaluate(Polynomial::domain_element3(0, 3)), 12.into());
1518 assert_eq!(p1.evaluate_on_three_adic_domain(0, 3), 12.into());
1519 assert_eq!(p1.evaluate(Polynomial::domain_element3(1, 2)), 34.into());
1520 assert_eq!(p1.evaluate_on_three_adic_domain(1, 2), 34.into());
1521 assert_eq!(p1.evaluate(Polynomial::domain_element3(1, 3)), 34.into());
1522 assert_eq!(p1.evaluate_on_three_adic_domain(1, 3), 34.into());
1523 assert_eq!(p1.evaluate(Polynomial::domain_element3(2, 3)), 0.into());
1524 assert_eq!(p1.evaluate_on_three_adic_domain(2, 3), 0.into());
1525 assert_eq!(p2.evaluate(Polynomial::domain_element3(0, 2)), 12.into());
1526 assert_eq!(p2.evaluate_on_three_adic_domain(0, 2), 12.into());
1527 assert_eq!(p2.evaluate(Polynomial::domain_element3(0, 3)), 12.into());
1528 assert_eq!(p2.evaluate_on_three_adic_domain(0, 3), 12.into());
1529 assert_eq!(p2.evaluate(Polynomial::domain_element3(1, 2)), 34.into());
1530 assert_eq!(p2.evaluate_on_three_adic_domain(1, 2), 34.into());
1531 assert_eq!(p2.evaluate(Polynomial::domain_element3(1, 3)), 34.into());
1532 assert_eq!(p2.evaluate_on_three_adic_domain(1, 3), 34.into());
1533 assert_eq!(p2.evaluate(Polynomial::domain_element3(2, 3)), 0.into());
1534 assert_eq!(p2.evaluate_on_three_adic_domain(2, 3), 0.into());
1535 }
1536
1537 #[test]
1538 fn test_encode3_two_values_2() {
1539 let p1 = Polynomial::encode3(vec![12.into(), 34.into()]);
1540 let p2 = Polynomial::encode3(vec![78.into(), 56.into()]);
1541 assert_eq!(p1.len(), 3);
1542 assert_eq!(p1.degree_bound(), 3);
1543 assert_eq!(p2.len(), 3);
1544 assert_eq!(p2.degree_bound(), 3);
1545 assert_ne!(p1, p2);
1546 assert_eq!(p2.evaluate(Polynomial::domain_element3(0, 2)), 78.into());
1547 assert_eq!(p2.evaluate_on_three_adic_domain(0, 2), 78.into());
1548 assert_eq!(p2.evaluate(Polynomial::domain_element3(1, 2)), 56.into());
1549 assert_eq!(p2.evaluate_on_three_adic_domain(1, 2), 56.into());
1550 assert_eq!(p2.evaluate(Polynomial::domain_element3(2, 3)), 0.into());
1551 assert_eq!(p2.evaluate_on_three_adic_domain(2, 3), 0.into());
1552 }
1553
1554 #[test]
1555 fn test_encode3_three_values_1() {
1556 let p1 = Polynomial::encode3(vec![12.into(), 34.into(), 56.into()]);
1557 let p2 = Polynomial::encode3(vec![12.into(), 34.into(), 56.into()]);
1558 assert_eq!(p1, p2);
1559 assert_eq!(p1.len(), 3);
1560 assert_eq!(p1.degree_bound(), 3);
1561 assert_eq!(p2.len(), 3);
1562 assert_eq!(p2.degree_bound(), 3);
1563 assert_eq!(p1.evaluate(Polynomial::domain_element3(0, 3)), 12.into());
1564 assert_eq!(p1.evaluate_on_three_adic_domain(0, 3), 12.into());
1565 assert_eq!(p1.evaluate(Polynomial::domain_element3(1, 3)), 34.into());
1566 assert_eq!(p1.evaluate_on_three_adic_domain(1, 3), 34.into());
1567 assert_eq!(p1.evaluate(Polynomial::domain_element3(2, 3)), 56.into());
1568 assert_eq!(p1.evaluate_on_three_adic_domain(2, 3), 56.into());
1569 assert_eq!(p2.evaluate(Polynomial::domain_element3(0, 3)), 12.into());
1570 assert_eq!(p2.evaluate_on_three_adic_domain(0, 3), 12.into());
1571 assert_eq!(p2.evaluate(Polynomial::domain_element3(1, 3)), 34.into());
1572 assert_eq!(p2.evaluate_on_three_adic_domain(1, 3), 34.into());
1573 assert_eq!(p2.evaluate(Polynomial::domain_element3(2, 3)), 56.into());
1574 assert_eq!(p2.evaluate_on_three_adic_domain(2, 3), 56.into());
1575 }
1576
1577 #[test]
1578 fn test_encode3_three_values_2() {
1579 let p1 = Polynomial::encode3(vec![12.into(), 34.into(), 56.into()]);
1580 let p2 = Polynomial::encode3(vec![90.into(), 78.into(), 34.into()]);
1581 assert_eq!(p1.len(), 3);
1582 assert_eq!(p1.degree_bound(), 3);
1583 assert_eq!(p2.len(), 3);
1584 assert_eq!(p2.degree_bound(), 3);
1585 assert_ne!(p1, p2);
1586 assert_eq!(p2.evaluate(Polynomial::domain_element3(0, 3)), 90.into());
1587 assert_eq!(p2.evaluate_on_three_adic_domain(0, 3), 90.into());
1588 assert_eq!(p2.evaluate(Polynomial::domain_element3(1, 3)), 78.into());
1589 assert_eq!(p2.evaluate_on_three_adic_domain(1, 3), 78.into());
1590 assert_eq!(p2.evaluate(Polynomial::domain_element3(2, 3)), 34.into());
1591 assert_eq!(p2.evaluate_on_three_adic_domain(2, 3), 34.into());
1592 }
1593
1594 #[test]
1595 fn test_encode3_nine_values3() {
1596 let p = Polynomial::encode3(vec![
1597 12.into(),
1598 34.into(),
1599 56.into(),
1600 78.into(),
1601 90.into(),
1602 11.into(),
1603 22.into(),
1604 33.into(),
1605 44.into(),
1606 ]);
1607 assert_eq!(p.len(), 9);
1608 assert_eq!(p.degree_bound(), 9);
1609 assert_eq!(p.evaluate(Polynomial::domain_element3(0, 9)), 12.into());
1610 assert_eq!(p.evaluate_on_three_adic_domain(0, 9), 12.into());
1611 assert_eq!(p.evaluate(Polynomial::domain_element3(1, 9)), 34.into());
1612 assert_eq!(p.evaluate_on_three_adic_domain(1, 9), 34.into());
1613 assert_eq!(p.evaluate(Polynomial::domain_element3(2, 9)), 56.into());
1614 assert_eq!(p.evaluate_on_three_adic_domain(2, 9), 56.into());
1615 assert_eq!(p.evaluate(Polynomial::domain_element3(3, 9)), 78.into());
1616 assert_eq!(p.evaluate_on_three_adic_domain(3, 9), 78.into());
1617 assert_eq!(p.evaluate(Polynomial::domain_element3(4, 9)), 90.into());
1618 assert_eq!(p.evaluate_on_three_adic_domain(4, 9), 90.into());
1619 assert_eq!(p.evaluate(Polynomial::domain_element3(5, 9)), 11.into());
1620 assert_eq!(p.evaluate_on_three_adic_domain(5, 9), 11.into());
1621 assert_eq!(p.evaluate(Polynomial::domain_element3(6, 9)), 22.into());
1622 assert_eq!(p.evaluate_on_three_adic_domain(6, 9), 22.into());
1623 assert_eq!(p.evaluate(Polynomial::domain_element3(7, 9)), 33.into());
1624 assert_eq!(p.evaluate_on_three_adic_domain(7, 9), 33.into());
1625 assert_eq!(p.evaluate(Polynomial::domain_element3(8, 9)), 44.into());
1626 assert_eq!(p.evaluate_on_three_adic_domain(8, 9), 44.into());
1627 }
1628
1629 #[test]
1630 fn test_decode3_one_value() {
1631 let values = vec![42.into()];
1632 let polynomial = Polynomial::encode3(values.clone());
1633 assert_eq!(polynomial.decode3(), values);
1634 }
1635
1636 #[test]
1637 fn test_decode3_two_values() {
1638 let values = vec![12.into(), 34.into()];
1639 let polynomial = Polynomial::encode3(values.clone());
1640 assert_eq!(polynomial.decode3(), vec![12.into(), 34.into(), 0.into()]);
1641 }
1642
1643 #[test]
1644 fn test_decode3_three_values() {
1645 let values = vec![12.into(), 34.into(), 56.into()];
1646 let polynomial = Polynomial::encode3(values.clone());
1647 assert_eq!(polynomial.decode3(), values);
1648 }
1649
1650 #[test]
1651 fn test_decode3_nine_values() {
1652 let values = vec![
1653 12.into(),
1654 34.into(),
1655 56.into(),
1656 78.into(),
1657 90.into(),
1658 11.into(),
1659 22.into(),
1660 33.into(),
1661 44.into(),
1662 ];
1663 let polynomial = Polynomial::encode3(values.clone());
1664 assert_eq!(polynomial.decode3(), values);
1665 }
1666
1667 #[test]
1668 fn test_add_same_length() {
1669 let p1 = Polynomial::with_coefficients(vec![1.into(), 2.into(), 3.into()]);
1670 let p2 = Polynomial::with_coefficients(vec![10.into(), 20.into(), 30.into()]);
1671 assert_eq!(
1672 p1 + p2,
1673 Polynomial::with_coefficients(vec![11.into(), 22.into(), 33.into()])
1674 );
1675 }
1676
1677 #[test]
1678 fn test_add_lhs_longer() {
1679 let p1 = Polynomial::with_coefficients(vec![1.into(), 2.into(), 3.into()]);
1680 let p2 = Polynomial::with_coefficients(vec![10.into(), 20.into()]);
1681 assert_eq!(
1682 p1 + p2,
1683 Polynomial::with_coefficients(vec![11.into(), 22.into(), 3.into()])
1684 );
1685 }
1686
1687 #[test]
1688 fn test_add_rhs_longer() {
1689 let p1 = Polynomial::with_coefficients(vec![1.into(), 2.into()]);
1690 let p2 = Polynomial::with_coefficients(vec![10.into(), 20.into(), 30.into()]);
1691 assert_eq!(
1692 p1 + p2,
1693 Polynomial::with_coefficients(vec![11.into(), 22.into(), 30.into()])
1694 );
1695 }
1696
1697 #[test]
1698 fn test_add_commutative() {
1699 let p1 = Polynomial::with_coefficients(vec![1.into(), 2.into()]);
1700 let p2 = Polynomial::with_coefficients(vec![10.into(), 20.into(), 30.into()]);
1701 assert_eq!(p1.clone() + p2.clone(), p2 + p1);
1702 }
1703
1704 #[test]
1705 fn test_add_assign_same_length() {
1706 let mut p1 = Polynomial::with_coefficients(vec![1.into(), 2.into(), 3.into()]);
1707 let p2 = Polynomial::with_coefficients(vec![10.into(), 20.into(), 30.into()]);
1708 p1 += p2;
1709 assert_eq!(
1710 p1,
1711 Polynomial::with_coefficients(vec![11.into(), 22.into(), 33.into()])
1712 );
1713 }
1714
1715 #[test]
1716 fn test_add_assign_lhs_longer() {
1717 let mut p1 = Polynomial::with_coefficients(vec![1.into(), 2.into(), 3.into()]);
1718 let p2 = Polynomial::with_coefficients(vec![10.into(), 20.into()]);
1719 p1 += p2;
1720 assert_eq!(
1721 p1,
1722 Polynomial::with_coefficients(vec![11.into(), 22.into(), 3.into()])
1723 );
1724 }
1725
1726 #[test]
1727 fn test_add_assign_rhs_longer() {
1728 let mut p1 = Polynomial::with_coefficients(vec![1.into(), 2.into()]);
1729 let p2 = Polynomial::with_coefficients(vec![10.into(), 20.into(), 30.into()]);
1730 p1 += p2;
1731 assert_eq!(
1732 p1,
1733 Polynomial::with_coefficients(vec![11.into(), 22.into(), 30.into()])
1734 );
1735 }
1736
1737 #[test]
1738 fn test_add_assign_consistent_with_add() {
1739 let p1 = Polynomial::with_coefficients(vec![1.into(), 2.into()]);
1740 let p2 = Polynomial::with_coefficients(vec![10.into(), 20.into(), 30.into()]);
1741 let mut p1_assign = p1.clone();
1742 p1_assign += p2.clone();
1743 assert_eq!(p1_assign, p1 + p2);
1744 }
1745
1746 #[test]
1747 fn test_sub_same_length() {
1748 let p1 = Polynomial::with_coefficients(vec![10.into(), 20.into(), 30.into()]);
1749 let p2 = Polynomial::with_coefficients(vec![1.into(), 2.into(), 3.into()]);
1750 assert_eq!(
1751 p1 - p2,
1752 Polynomial::with_coefficients(vec![9.into(), 18.into(), 27.into()])
1753 );
1754 }
1755
1756 #[test]
1757 fn test_sub_lhs_longer() {
1758 let p1 = Polynomial::with_coefficients(vec![10.into(), 20.into(), 30.into()]);
1759 let p2 = Polynomial::with_coefficients(vec![1.into(), 2.into()]);
1760 assert_eq!(
1761 p1 - p2,
1762 Polynomial::with_coefficients(vec![9.into(), 18.into(), 30.into()])
1763 );
1764 }
1765
1766 #[test]
1767 fn test_sub_rhs_longer() {
1768 let p1 = Polynomial::with_coefficients(vec![10.into(), 20.into()]);
1769 let p2 = Polynomial::with_coefficients(vec![1.into(), 2.into(), 3.into()]);
1770 assert_eq!(
1771 p1 - p2,
1772 Polynomial::with_coefficients(vec![9.into(), 18.into(), -Scalar::from(3)])
1773 );
1774 }
1775
1776 #[test]
1777 fn test_sub_anticommutative() {
1778 let p1 = Polynomial::with_coefficients(vec![10.into(), 20.into()]);
1779 let p2 = Polynomial::with_coefficients(vec![1.into(), 2.into(), 3.into()]);
1780 assert_eq!(p1.clone() - p2.clone(), -(p2 - p1));
1781 }
1782
1783 #[test]
1784 fn test_sub_assign_same_length() {
1785 let mut p1 = Polynomial::with_coefficients(vec![10.into(), 20.into(), 30.into()]);
1786 let p2 = Polynomial::with_coefficients(vec![1.into(), 2.into(), 3.into()]);
1787 p1 -= p2;
1788 assert_eq!(
1789 p1,
1790 Polynomial::with_coefficients(vec![9.into(), 18.into(), 27.into()])
1791 );
1792 }
1793
1794 #[test]
1795 fn test_sub_assign_lhs_longer() {
1796 let mut p1 = Polynomial::with_coefficients(vec![10.into(), 20.into(), 30.into()]);
1797 let p2 = Polynomial::with_coefficients(vec![1.into(), 2.into()]);
1798 p1 -= p2;
1799 assert_eq!(
1800 p1,
1801 Polynomial::with_coefficients(vec![9.into(), 18.into(), 30.into()])
1802 );
1803 }
1804
1805 #[test]
1806 fn test_sub_assign_rhs_longer() {
1807 let mut p1 = Polynomial::with_coefficients(vec![10.into(), 20.into()]);
1808 let p2 = Polynomial::with_coefficients(vec![1.into(), 2.into(), 3.into()]);
1809 p1 -= p2;
1810 assert_eq!(
1811 p1,
1812 Polynomial::with_coefficients(vec![9.into(), 18.into(), -Scalar::from(3)])
1813 );
1814 }
1815
1816 #[test]
1817 fn test_sub_assign_consistent_with_sub() {
1818 let p1 = Polynomial::with_coefficients(vec![10.into(), 20.into()]);
1819 let p2 = Polynomial::with_coefficients(vec![1.into(), 2.into(), 3.into()]);
1820 let mut p1_assign = p1.clone();
1821 p1_assign -= p2.clone();
1822 assert_eq!(p1_assign, p1 - p2);
1823 }
1824
1825 #[test]
1826 fn test_multiply_empty() {
1827 let p1 = Polynomial::default();
1828 let p2 = Polynomial::default();
1829 assert_eq!(p1.multiply(p2), Polynomial::default());
1830 }
1831
1832 #[test]
1833 fn test_multiply_empty_by_non_empty() {
1834 let p1 = Polynomial::default();
1835 let p2 = Polynomial {
1836 coefficients: vec![12.into(), 34.into()],
1837 };
1838 assert_eq!(p1.multiply(p2), Polynomial::default());
1839 }
1840
1841 #[test]
1842 fn test_multiply_non_empty_by_empty() {
1843 let p1 = Polynomial {
1844 coefficients: vec![56.into(), 78.into()],
1845 };
1846 let p2 = Polynomial::default();
1847 assert_eq!(p1.multiply(p2), Polynomial::default());
1848 }
1849
1850 #[test]
1851 fn test_multiply_constant() {
1852 let p1 = Polynomial {
1853 coefficients: vec![3.into()],
1854 };
1855 let p2 = Polynomial {
1856 coefficients: vec![12.into(), 34.into(), 56.into()],
1857 };
1858 assert_eq!(
1859 p1.multiply(p2),
1860 Polynomial {
1861 coefficients: vec![36.into(), 102.into(), 168.into()]
1862 }
1863 );
1864 }
1865
1866 #[test]
1867 fn test_multiply_by_constant() {
1868 let p1 = Polynomial {
1869 coefficients: vec![12.into(), 34.into(), 56.into()],
1870 };
1871 let p2 = Polynomial {
1872 coefficients: vec![3.into()],
1873 };
1874 assert_eq!(
1875 p1.multiply(p2),
1876 Polynomial {
1877 coefficients: vec![36.into(), 102.into(), 168.into()]
1878 }
1879 );
1880 }
1881
1882 #[test]
1883 fn test_multiply_constant_by_constant() {
1884 let p1 = Polynomial {
1885 coefficients: vec![12.into()],
1886 };
1887 let p2 = Polynomial {
1888 coefficients: vec![34.into()],
1889 };
1890 assert_eq!(
1891 p1.multiply(p2),
1892 Polynomial {
1893 coefficients: vec![408.into()]
1894 }
1895 );
1896 }
1897
1898 #[test]
1899 fn test_multiply_polynomials1() {
1900 let p1 = Polynomial {
1901 coefficients: vec![1.into(), 2.into()],
1902 };
1903 let p2 = Polynomial {
1904 coefficients: vec![3.into(), 4.into()],
1905 };
1906 let result = Polynomial {
1907 coefficients: vec![3.into(), 10.into(), 8.into()],
1908 };
1909 assert_eq!(p1.clone().multiply(p2.clone()), result);
1910 assert_eq!(p2.multiply(p1), result);
1911 }
1912
1913 #[test]
1914 fn test_multiply_polynomials2() {
1915 let p1 = Polynomial {
1916 coefficients: vec![1.into(), 2.into()],
1917 };
1918 let p2 = Polynomial {
1919 coefficients: vec![3.into(), 4.into(), 5.into()],
1920 };
1921 let result = Polynomial {
1922 coefficients: vec![3.into(), 10.into(), 13.into(), 10.into()],
1923 };
1924 assert_eq!(p1.clone().multiply(p2.clone()), result);
1925 assert_eq!(p2.multiply(p1), result);
1926 }
1927
1928 #[test]
1929 fn test_polynomial_mul_op() {
1930 let p1 = Polynomial {
1931 coefficients: vec![1.into(), 2.into()],
1932 };
1933 let p2 = Polynomial {
1934 coefficients: vec![3.into(), 4.into(), 5.into()],
1935 };
1936 let result = Polynomial {
1937 coefficients: vec![3.into(), 10.into(), 13.into(), 10.into()],
1938 };
1939 assert_eq!(p1.clone() * p2.clone(), result);
1940 assert_eq!(p2 * p1, result);
1941 }
1942
1943 #[test]
1944 fn test_polynomial_mul_assign() {
1945 let mut p1 = Polynomial {
1946 coefficients: vec![1.into(), 2.into()],
1947 };
1948 let p2 = Polynomial {
1949 coefficients: vec![3.into(), 4.into(), 5.into()],
1950 };
1951 p1 *= p2;
1952 assert_eq!(
1953 p1,
1954 Polynomial {
1955 coefficients: vec![3.into(), 10.into(), 13.into(), 10.into()],
1956 }
1957 );
1958 }
1959
1960 #[test]
1961 fn test_multiply_one_polynomial() {
1962 let p = Polynomial {
1963 coefficients: vec![12.into(), 34.into()],
1964 };
1965 assert_eq!(Polynomial::multiply_many([p.clone()]), p);
1966 }
1967
1968 #[test]
1969 fn test_multiply_two_polynomials() {
1970 let p1 = Polynomial {
1971 coefficients: vec![1.into(), 2.into()],
1972 };
1973 let p2 = Polynomial {
1974 coefficients: vec![3.into(), 4.into(), 5.into()],
1975 };
1976 let result = Polynomial {
1977 coefficients: vec![3.into(), 10.into(), 13.into(), 10.into()],
1978 };
1979 assert_eq!(Polynomial::multiply_many([p1.clone(), p2.clone()]), result);
1980 assert_eq!(Polynomial::multiply_many([p2, p1]), result);
1981 }
1982
1983 #[test]
1984 fn test_multiply_three_polynomials() {
1985 let p1 = Polynomial {
1986 coefficients: vec![1.into(), 2.into()],
1987 };
1988 let p2 = Polynomial {
1989 coefficients: vec![3.into(), 4.into(), 5.into()],
1990 };
1991 let p3 = Polynomial {
1992 coefficients: vec![6.into(), 7.into(), 8.into(), 9.into()],
1993 };
1994 let result = Polynomial {
1995 coefficients: vec![
1996 18.into(),
1997 81.into(),
1998 172.into(),
1999 258.into(),
2000 264.into(),
2001 197.into(),
2002 90.into(),
2003 ],
2004 };
2005 assert_eq!(
2006 Polynomial::multiply_many([p1.clone(), p2.clone(), p3.clone()]),
2007 result
2008 );
2009 assert_eq!(
2010 Polynomial::multiply_many([p1.clone(), p3.clone(), p2.clone()]),
2011 result
2012 );
2013 assert_eq!(
2014 Polynomial::multiply_many([p2.clone(), p1.clone(), p3.clone()]),
2015 result
2016 );
2017 assert_eq!(
2018 Polynomial::multiply_many([p2.clone(), p3.clone(), p1.clone()]),
2019 result
2020 );
2021 assert_eq!(
2022 Polynomial::multiply_many([p3.clone(), p1.clone(), p2.clone()]),
2023 result
2024 );
2025 assert_eq!(
2026 Polynomial::multiply_many([p3.clone(), p2.clone(), p1.clone()]),
2027 result
2028 );
2029 }
2030
2031 #[test]
2032 fn test_multiply_four_polynomials() {
2033 let p1 = Polynomial {
2034 coefficients: vec![1.into(), 2.into()],
2035 };
2036 let p2 = Polynomial {
2037 coefficients: vec![3.into(), 4.into()],
2038 };
2039 let p3 = Polynomial {
2040 coefficients: vec![5.into(), 6.into()],
2041 };
2042 let p4 = Polynomial {
2043 coefficients: vec![7.into(), 8.into()],
2044 };
2045 let result = Polynomial {
2046 coefficients: vec![105.into(), 596.into(), 1244.into(), 1136.into(), 384.into()],
2047 };
2048 assert_eq!(
2049 Polynomial::multiply_many([p1.clone(), p2.clone(), p3.clone(), p4.clone()]),
2050 result
2051 );
2052 assert_eq!(
2053 Polynomial::multiply_many([p1.clone(), p2.clone(), p4.clone(), p3.clone()]),
2054 result
2055 );
2056 assert_eq!(
2057 Polynomial::multiply_many([p1.clone(), p3.clone(), p2.clone(), p4.clone()]),
2058 result
2059 );
2060 assert_eq!(
2061 Polynomial::multiply_many([p1.clone(), p3.clone(), p4.clone(), p2.clone()]),
2062 result
2063 );
2064 }
2066
2067 #[test]
2068 fn test_divide_zero_by_zero() {
2069 let z = Polynomial {
2070 coefficients: vec![-Scalar::from(1), 0.into(), 0.into(), 0.into(), 1.into()],
2071 };
2072 assert_eq!(
2073 z.divide_by_zero(4).unwrap(),
2074 Polynomial {
2075 coefficients: vec![1.into()]
2076 }
2077 );
2078 }
2079
2080 #[test]
2081 fn test_non_trivial_quotient1() {
2082 let ql = Polynomial::encode2(vec![0.into(), 0.into(), 1.into(), 1.into()]);
2083 let qr = Polynomial::encode2(vec![0.into(), 0.into(), 1.into(), 1.into()]);
2084 let qo = Polynomial::encode2(vec![-Scalar::from(1); 4]);
2085 let qm = Polynomial::encode2(vec![1.into(), 1.into(), 0.into(), 0.into()]);
2086 let qc = Polynomial::encode2(vec![0.into(); 4]);
2087 let l = Polynomial::encode2(vec![3.into(), 9.into(), 3.into(), 30.into()]);
2088 let r = Polynomial::encode2(vec![3.into(), 3.into(), 27.into(), 5.into()]);
2089 let o = Polynomial::encode2(vec![9.into(), 27.into(), 30.into(), 35.into()]);
2090 let lr = l.clone().multiply(r.clone());
2091 let p = ql.multiply(l) + qr.multiply(r) + qo.multiply(o) + qm.multiply(lr) + qc;
2092 let q = p.divide_by_zero(4).unwrap();
2093 assert_eq!(q.len(), 6);
2094 assert_eq!(q.degree_bound(), 6);
2095 }
2096
2097 #[test]
2098 fn test_non_trivial_quotient2() {
2099 let ql = Polynomial::encode2(vec![0.into(), 0.into(), 1.into(), 1.into()]);
2100 let qr = Polynomial::encode2(vec![0.into(), 0.into(), 1.into(), 5.into()]);
2101 let qo = Polynomial::encode2(vec![-Scalar::from(1); 4]);
2102 let qm = Polynomial::encode2(vec![1.into(), 1.into(), 0.into(), 0.into()]);
2103 let qc = Polynomial::encode2(vec![0.into(); 4]);
2104 let l = Polynomial::encode2(vec![3.into(), 9.into(), 3.into(), 30.into()]);
2105 let r = Polynomial::encode2(vec![3.into(), 3.into(), 27.into(), 1.into()]);
2106 let o = Polynomial::encode2(vec![9.into(), 27.into(), 30.into(), 35.into()]);
2107 let lr = l.clone().multiply(r.clone());
2108 let p = ql.multiply(l) + qr.multiply(r) + qo.multiply(o) + qm.multiply(lr) + qc;
2109 let q = p.divide_by_zero(4).unwrap();
2110 assert_eq!(q.len(), 6);
2111 assert_eq!(q.degree_bound(), 6);
2112 }
2113
2114 #[test]
2115 fn test_lde2_same_size() {
2116 let values = vec![12.into(), 34.into(), 56.into(), 78.into()];
2117 let p = Polynomial::encode2(values);
2118 let lde = p.clone().shifted_lde2(4);
2119 assert_eq!(
2120 lde,
2121 vec![
2122 p.evaluate_on_two_adic_coset(0, 4),
2123 p.evaluate_on_two_adic_coset(1, 4),
2124 p.evaluate_on_two_adic_coset(2, 4),
2125 p.evaluate_on_two_adic_coset(3, 4),
2126 ]
2127 );
2128 }
2129
2130 #[test]
2131 fn test_lde2_blowup2() {
2132 let values = vec![12.into(), 34.into(), 56.into(), 78.into()];
2133 let p = Polynomial::encode2(values);
2134 let lde = p.clone().shifted_lde2(8);
2135 assert_eq!(
2136 lde,
2137 vec![
2138 p.evaluate_on_two_adic_coset(0, 8),
2139 p.evaluate_on_two_adic_coset(1, 8),
2140 p.evaluate_on_two_adic_coset(2, 8),
2141 p.evaluate_on_two_adic_coset(3, 8),
2142 p.evaluate_on_two_adic_coset(4, 8),
2143 p.evaluate_on_two_adic_coset(5, 8),
2144 p.evaluate_on_two_adic_coset(6, 8),
2145 p.evaluate_on_two_adic_coset(7, 8),
2146 ]
2147 );
2148 }
2149
2150 #[test]
2151 fn test_lde2_blowup4() {
2152 let values = vec![1.into(), 2.into(), 3.into(), 4.into()];
2153 let p = Polynomial::encode2(values);
2154 let lde = p.clone().shifted_lde2(16);
2155 assert_eq!(
2156 lde,
2157 vec![
2158 p.evaluate_on_two_adic_coset(0, 16),
2159 p.evaluate_on_two_adic_coset(1, 16),
2160 p.evaluate_on_two_adic_coset(2, 16),
2161 p.evaluate_on_two_adic_coset(3, 16),
2162 p.evaluate_on_two_adic_coset(4, 16),
2163 p.evaluate_on_two_adic_coset(5, 16),
2164 p.evaluate_on_two_adic_coset(6, 16),
2165 p.evaluate_on_two_adic_coset(7, 16),
2166 p.evaluate_on_two_adic_coset(8, 16),
2167 p.evaluate_on_two_adic_coset(9, 16),
2168 p.evaluate_on_two_adic_coset(10, 16),
2169 p.evaluate_on_two_adic_coset(11, 16),
2170 p.evaluate_on_two_adic_coset(12, 16),
2171 p.evaluate_on_two_adic_coset(13, 16),
2172 p.evaluate_on_two_adic_coset(14, 16),
2173 p.evaluate_on_two_adic_coset(15, 16),
2174 ]
2175 );
2176 }
2177
2178 #[test]
2179 fn test_lde2_shorter_polynomial() {
2180 let values = vec![42.into(), 42.into()];
2181 let p = Polynomial::encode2(values);
2182 assert_eq!(p.len(), 1);
2183 assert_eq!(p.degree_bound(), 1);
2184 let lde = p.clone().shifted_lde2(4);
2185 assert_eq!(
2186 lde,
2187 vec![
2188 p.evaluate_on_two_adic_coset(0, 4),
2189 p.evaluate_on_two_adic_coset(1, 4),
2190 p.evaluate_on_two_adic_coset(2, 4),
2191 p.evaluate_on_two_adic_coset(3, 4),
2192 ]
2193 );
2194 }
2195
2196 #[test]
2197 fn test_lde3_same_size() {
2198 let values = vec![12.into(), 34.into(), 56.into()];
2199 let p = Polynomial::encode3(values.clone());
2200 let lde = p.clone().shifted_lde3(3);
2201 assert_eq!(
2202 lde,
2203 vec![
2204 p.evaluate_on_three_adic_coset(0, 3),
2205 p.evaluate_on_three_adic_coset(1, 3),
2206 p.evaluate_on_three_adic_coset(2, 3),
2207 ]
2208 );
2209 }
2210
2211 #[test]
2212 fn test_lde3_blowup3() {
2213 let values = vec![12.into(), 34.into(), 56.into()];
2214 let p = Polynomial::encode3(values);
2215 let lde = p.clone().shifted_lde3(9);
2216 assert_eq!(
2217 lde,
2218 vec![
2219 p.evaluate_on_three_adic_coset(0, 9),
2220 p.evaluate_on_three_adic_coset(1, 9),
2221 p.evaluate_on_three_adic_coset(2, 9),
2222 p.evaluate_on_three_adic_coset(3, 9),
2223 p.evaluate_on_three_adic_coset(4, 9),
2224 p.evaluate_on_three_adic_coset(5, 9),
2225 p.evaluate_on_three_adic_coset(6, 9),
2226 p.evaluate_on_three_adic_coset(7, 9),
2227 p.evaluate_on_three_adic_coset(8, 9),
2228 ]
2229 );
2230 }
2231
2232 #[test]
2233 fn test_lde3_blowup9() {
2234 let values = vec![1.into(), 2.into(), 3.into()];
2235 let p = Polynomial::encode3(values);
2236 let lde = p.clone().shifted_lde3(27);
2237 assert_eq!(
2238 lde,
2239 vec![
2240 p.evaluate_on_three_adic_coset(0, 27),
2241 p.evaluate_on_three_adic_coset(1, 27),
2242 p.evaluate_on_three_adic_coset(2, 27),
2243 p.evaluate_on_three_adic_coset(3, 27),
2244 p.evaluate_on_three_adic_coset(4, 27),
2245 p.evaluate_on_three_adic_coset(5, 27),
2246 p.evaluate_on_three_adic_coset(6, 27),
2247 p.evaluate_on_three_adic_coset(7, 27),
2248 p.evaluate_on_three_adic_coset(8, 27),
2249 p.evaluate_on_three_adic_coset(9, 27),
2250 p.evaluate_on_three_adic_coset(10, 27),
2251 p.evaluate_on_three_adic_coset(11, 27),
2252 p.evaluate_on_three_adic_coset(12, 27),
2253 p.evaluate_on_three_adic_coset(13, 27),
2254 p.evaluate_on_three_adic_coset(14, 27),
2255 p.evaluate_on_three_adic_coset(15, 27),
2256 p.evaluate_on_three_adic_coset(16, 27),
2257 p.evaluate_on_three_adic_coset(17, 27),
2258 p.evaluate_on_three_adic_coset(18, 27),
2259 p.evaluate_on_three_adic_coset(19, 27),
2260 p.evaluate_on_three_adic_coset(20, 27),
2261 p.evaluate_on_three_adic_coset(21, 27),
2262 p.evaluate_on_three_adic_coset(22, 27),
2263 p.evaluate_on_three_adic_coset(23, 27),
2264 p.evaluate_on_three_adic_coset(24, 27),
2265 p.evaluate_on_three_adic_coset(25, 27),
2266 p.evaluate_on_three_adic_coset(26, 27),
2267 ]
2268 );
2269 }
2270
2271 #[test]
2272 fn test_lde3_nine_values_blowup3() {
2273 let values = (1u64..=9).map(Scalar::from).collect();
2274 let p = Polynomial::encode3(values);
2275 let lde = p.clone().shifted_lde3(27);
2276 assert_eq!(
2277 lde,
2278 vec![
2279 p.evaluate_on_three_adic_coset(0, 27),
2280 p.evaluate_on_three_adic_coset(1, 27),
2281 p.evaluate_on_three_adic_coset(2, 27),
2282 p.evaluate_on_three_adic_coset(3, 27),
2283 p.evaluate_on_three_adic_coset(4, 27),
2284 p.evaluate_on_three_adic_coset(5, 27),
2285 p.evaluate_on_three_adic_coset(6, 27),
2286 p.evaluate_on_three_adic_coset(7, 27),
2287 p.evaluate_on_three_adic_coset(8, 27),
2288 p.evaluate_on_three_adic_coset(9, 27),
2289 p.evaluate_on_three_adic_coset(10, 27),
2290 p.evaluate_on_three_adic_coset(11, 27),
2291 p.evaluate_on_three_adic_coset(12, 27),
2292 p.evaluate_on_three_adic_coset(13, 27),
2293 p.evaluate_on_three_adic_coset(14, 27),
2294 p.evaluate_on_three_adic_coset(15, 27),
2295 p.evaluate_on_three_adic_coset(16, 27),
2296 p.evaluate_on_three_adic_coset(17, 27),
2297 p.evaluate_on_three_adic_coset(18, 27),
2298 p.evaluate_on_three_adic_coset(19, 27),
2299 p.evaluate_on_three_adic_coset(20, 27),
2300 p.evaluate_on_three_adic_coset(21, 27),
2301 p.evaluate_on_three_adic_coset(22, 27),
2302 p.evaluate_on_three_adic_coset(23, 27),
2303 p.evaluate_on_three_adic_coset(24, 27),
2304 p.evaluate_on_three_adic_coset(25, 27),
2305 p.evaluate_on_three_adic_coset(26, 27),
2306 ]
2307 );
2308 }
2309
2310 #[test]
2311 fn test_lde3_shorter_poly() {
2312 let values = vec![7.into(), 7.into(), 7.into()];
2313 let p = Polynomial::encode3(values);
2314 assert_eq!(p.len(), 1);
2315 assert_eq!(p.degree_bound(), 1);
2316 let lde = p.clone().shifted_lde3(9);
2317 assert_eq!(
2318 lde,
2319 vec![
2320 p.evaluate_on_three_adic_domain(0, 9),
2321 p.evaluate_on_three_adic_domain(1, 9),
2322 p.evaluate_on_three_adic_domain(2, 9),
2323 p.evaluate_on_three_adic_domain(3, 9),
2324 p.evaluate_on_three_adic_domain(4, 9),
2325 p.evaluate_on_three_adic_domain(5, 9),
2326 p.evaluate_on_three_adic_domain(6, 9),
2327 p.evaluate_on_three_adic_domain(7, 9),
2328 p.evaluate_on_three_adic_domain(8, 9),
2329 ]
2330 );
2331 }
2332
2333 #[test]
2334 fn test_multiply_values2_same_constant() {
2335 let lhs = vec![42.into(), 42.into()];
2336 let rhs = vec![42.into(), 42.into()];
2337 let result = Polynomial::multiply_values2(lhs, rhs);
2338 assert_eq!(result, vec![1764.into()]);
2339 }
2340
2341 #[test]
2342 fn test_multiply_values2_different_constants() {
2343 let lhs = vec![3.into(), 3.into()];
2344 let rhs = vec![7.into(), 7.into()];
2345 let result = Polynomial::multiply_values2(lhs, rhs);
2346 assert_eq!(result, vec![21.into()]);
2347 }
2348
2349 #[test]
2350 fn test_multiply_values2_two_linear_polynomials() {
2351 let p = Polynomial::with_coefficients(vec![1.into(), 2.into()]);
2352 let q = Polynomial::with_coefficients(vec![3.into(), 4.into()]);
2353 let lhs = vec![
2354 p.evaluate_on_two_adic_domain(0, 2),
2355 p.evaluate_on_two_adic_domain(1, 2),
2356 ];
2357 let rhs = vec![
2358 q.evaluate_on_two_adic_domain(0, 2),
2359 q.evaluate_on_two_adic_domain(1, 2),
2360 ];
2361 let product = p.multiply(q);
2362 let result = Polynomial::multiply_values2(lhs, rhs);
2363 assert_eq!(
2364 result,
2365 vec![
2366 product.evaluate_on_two_adic_domain(0, 4),
2367 product.evaluate_on_two_adic_domain(1, 4),
2368 product.evaluate_on_two_adic_domain(2, 4),
2369 product.evaluate_on_two_adic_domain(3, 4),
2370 ]
2371 );
2372 }
2373
2374 #[test]
2375 fn test_multiply_values2_four_values() {
2376 let p = Polynomial::with_coefficients(vec![1.into(), 2.into(), 3.into(), 4.into()]);
2377 let q = Polynomial::with_coefficients(vec![5.into(), 6.into(), 7.into(), 8.into()]);
2378 let lhs = vec![
2379 p.evaluate_on_two_adic_domain(0, 4),
2380 p.evaluate_on_two_adic_domain(1, 4),
2381 p.evaluate_on_two_adic_domain(2, 4),
2382 p.evaluate_on_two_adic_domain(3, 4),
2383 ];
2384 let rhs = vec![
2385 q.evaluate_on_two_adic_domain(0, 4),
2386 q.evaluate_on_two_adic_domain(1, 4),
2387 q.evaluate_on_two_adic_domain(2, 4),
2388 q.evaluate_on_two_adic_domain(3, 4),
2389 ];
2390 let product = p.multiply(q);
2391 let result = Polynomial::multiply_values2(lhs, rhs);
2392 assert_eq!(
2393 result,
2394 vec![
2395 product.evaluate_on_two_adic_domain(0, 8),
2396 product.evaluate_on_two_adic_domain(1, 8),
2397 product.evaluate_on_two_adic_domain(2, 8),
2398 product.evaluate_on_two_adic_domain(3, 8),
2399 product.evaluate_on_two_adic_domain(4, 8),
2400 product.evaluate_on_two_adic_domain(5, 8),
2401 product.evaluate_on_two_adic_domain(6, 8),
2402 product.evaluate_on_two_adic_domain(7, 8),
2403 ]
2404 );
2405 }
2406
2407 #[test]
2408 fn test_multiply_values2_commutative() {
2409 let p = Polynomial::with_coefficients(vec![1.into(), 2.into()]);
2410 let q = Polynomial::with_coefficients(vec![3.into(), 4.into()]);
2411 let values_p = vec![
2412 p.evaluate_on_two_adic_domain(0, 2),
2413 p.evaluate_on_two_adic_domain(1, 2),
2414 ];
2415 let values_q = vec![
2416 q.evaluate_on_two_adic_domain(0, 2),
2417 q.evaluate_on_two_adic_domain(1, 2),
2418 ];
2419 let result_pq = Polynomial::multiply_values2(values_p.clone(), values_q.clone());
2420 let result_qp = Polynomial::multiply_values2(values_q, values_p);
2421 assert_eq!(result_pq, result_qp);
2422 }
2423
2424 #[test]
2425 fn test_multiply_values2_round_trip() {
2426 let p = Polynomial::with_coefficients(vec![1.into(), 2.into(), 3.into(), 4.into()]);
2427 let q = Polynomial::with_coefficients(vec![5.into(), 6.into(), 7.into(), 8.into()]);
2428 let lhs = vec![
2429 p.evaluate_on_two_adic_domain(0, 4),
2430 p.evaluate_on_two_adic_domain(1, 4),
2431 p.evaluate_on_two_adic_domain(2, 4),
2432 p.evaluate_on_two_adic_domain(3, 4),
2433 ];
2434 let rhs = vec![
2435 q.evaluate_on_two_adic_domain(0, 4),
2436 q.evaluate_on_two_adic_domain(1, 4),
2437 q.evaluate_on_two_adic_domain(2, 4),
2438 q.evaluate_on_two_adic_domain(3, 4),
2439 ];
2440 let product = p.clone().multiply(q.clone());
2441 let result = Polynomial::encode2(Polynomial::multiply_values2(lhs, rhs));
2442 assert_eq!(result, product);
2443 }
2444
2445 #[test]
2446 fn test_multiply_values3_same_constant() {
2447 let lhs = vec![42.into(), 42.into(), 42.into()];
2448 let rhs = vec![42.into(), 42.into(), 42.into()];
2449 let result = Polynomial::multiply_values3(lhs, rhs);
2450 assert_eq!(result, vec![1764.into()]);
2451 }
2452
2453 #[test]
2454 fn test_multiply_values3_different_constants() {
2455 let lhs = vec![3.into(), 3.into(), 3.into()];
2456 let rhs = vec![7.into(), 7.into(), 7.into()];
2457 let result = Polynomial::multiply_values3(lhs, rhs);
2458 assert_eq!(result, vec![21.into()]);
2459 }
2460
2461 #[test]
2462 fn test_multiply_values3_two_linear_polynomials() {
2463 let p = Polynomial::with_coefficients(vec![1.into(), 2.into()]);
2464 let q = Polynomial::with_coefficients(vec![3.into(), 4.into()]);
2465 let lhs = vec![
2466 p.evaluate_on_three_adic_domain(0, 3),
2467 p.evaluate_on_three_adic_domain(1, 3),
2468 p.evaluate_on_three_adic_domain(2, 3),
2469 ];
2470 let rhs = vec![
2471 q.evaluate_on_three_adic_domain(0, 3),
2472 q.evaluate_on_three_adic_domain(1, 3),
2473 q.evaluate_on_three_adic_domain(2, 3),
2474 ];
2475 let product = p.multiply(q);
2476 let result = Polynomial::multiply_values3(lhs, rhs);
2477 assert_eq!(
2478 result,
2479 vec![
2480 product.evaluate_on_three_adic_domain(0, 3),
2481 product.evaluate_on_three_adic_domain(1, 3),
2482 product.evaluate_on_three_adic_domain(2, 3),
2483 ]
2484 );
2485 }
2486
2487 #[test]
2488 fn test_multiply_values3_nine_values() {
2489 let p = Polynomial::with_coefficients(vec![
2490 1.into(),
2491 2.into(),
2492 3.into(),
2493 4.into(),
2494 5.into(),
2495 6.into(),
2496 7.into(),
2497 8.into(),
2498 9.into(),
2499 ]);
2500 let q = Polynomial::with_coefficients(vec![
2501 10.into(),
2502 11.into(),
2503 12.into(),
2504 13.into(),
2505 14.into(),
2506 15.into(),
2507 16.into(),
2508 17.into(),
2509 18.into(),
2510 ]);
2511 let lhs = vec![
2512 p.evaluate_on_three_adic_domain(0, 9),
2513 p.evaluate_on_three_adic_domain(1, 9),
2514 p.evaluate_on_three_adic_domain(2, 9),
2515 p.evaluate_on_three_adic_domain(3, 9),
2516 p.evaluate_on_three_adic_domain(4, 9),
2517 p.evaluate_on_three_adic_domain(5, 9),
2518 p.evaluate_on_three_adic_domain(6, 9),
2519 p.evaluate_on_three_adic_domain(7, 9),
2520 p.evaluate_on_three_adic_domain(8, 9),
2521 ];
2522 let rhs = vec![
2523 q.evaluate_on_three_adic_domain(0, 9),
2524 q.evaluate_on_three_adic_domain(1, 9),
2525 q.evaluate_on_three_adic_domain(2, 9),
2526 q.evaluate_on_three_adic_domain(3, 9),
2527 q.evaluate_on_three_adic_domain(4, 9),
2528 q.evaluate_on_three_adic_domain(5, 9),
2529 q.evaluate_on_three_adic_domain(6, 9),
2530 q.evaluate_on_three_adic_domain(7, 9),
2531 q.evaluate_on_three_adic_domain(8, 9),
2532 ];
2533 let product = p.multiply(q);
2534 let result = Polynomial::multiply_values3(lhs, rhs);
2535 assert_eq!(
2536 result,
2537 vec![
2538 product.evaluate_on_three_adic_domain(0, 27),
2539 product.evaluate_on_three_adic_domain(1, 27),
2540 product.evaluate_on_three_adic_domain(2, 27),
2541 product.evaluate_on_three_adic_domain(3, 27),
2542 product.evaluate_on_three_adic_domain(4, 27),
2543 product.evaluate_on_three_adic_domain(5, 27),
2544 product.evaluate_on_three_adic_domain(6, 27),
2545 product.evaluate_on_three_adic_domain(7, 27),
2546 product.evaluate_on_three_adic_domain(8, 27),
2547 product.evaluate_on_three_adic_domain(9, 27),
2548 product.evaluate_on_three_adic_domain(10, 27),
2549 product.evaluate_on_three_adic_domain(11, 27),
2550 product.evaluate_on_three_adic_domain(12, 27),
2551 product.evaluate_on_three_adic_domain(13, 27),
2552 product.evaluate_on_three_adic_domain(14, 27),
2553 product.evaluate_on_three_adic_domain(15, 27),
2554 product.evaluate_on_three_adic_domain(16, 27),
2555 product.evaluate_on_three_adic_domain(17, 27),
2556 product.evaluate_on_three_adic_domain(18, 27),
2557 product.evaluate_on_three_adic_domain(19, 27),
2558 product.evaluate_on_three_adic_domain(20, 27),
2559 product.evaluate_on_three_adic_domain(21, 27),
2560 product.evaluate_on_three_adic_domain(22, 27),
2561 product.evaluate_on_three_adic_domain(23, 27),
2562 product.evaluate_on_three_adic_domain(24, 27),
2563 product.evaluate_on_three_adic_domain(25, 27),
2564 product.evaluate_on_three_adic_domain(26, 27),
2565 ]
2566 );
2567 }
2568
2569 #[test]
2570 fn test_multiply_values3_commutative() {
2571 let p = Polynomial::with_coefficients(vec![1.into(), 2.into()]);
2572 let q = Polynomial::with_coefficients(vec![3.into(), 4.into()]);
2573 let values_p = vec![
2574 p.evaluate_on_three_adic_domain(0, 3),
2575 p.evaluate_on_three_adic_domain(1, 3),
2576 p.evaluate_on_three_adic_domain(2, 3),
2577 ];
2578 let values_q = vec![
2579 q.evaluate_on_three_adic_domain(0, 3),
2580 q.evaluate_on_three_adic_domain(1, 3),
2581 q.evaluate_on_three_adic_domain(2, 3),
2582 ];
2583 let result_pq = Polynomial::multiply_values3(values_p.clone(), values_q.clone());
2584 let result_qp = Polynomial::multiply_values3(values_q, values_p);
2585 assert_eq!(result_pq, result_qp);
2586 }
2587
2588 #[test]
2589 fn test_multiply_values3_round_trip() {
2590 let p = Polynomial::with_coefficients(vec![1.into(), 2.into(), 3.into()]);
2591 let q = Polynomial::with_coefficients(vec![4.into(), 5.into(), 6.into()]);
2592 let lhs = vec![
2593 p.evaluate_on_three_adic_domain(0, 3),
2594 p.evaluate_on_three_adic_domain(1, 3),
2595 p.evaluate_on_three_adic_domain(2, 3),
2596 ];
2597 let rhs = vec![
2598 q.evaluate_on_three_adic_domain(0, 3),
2599 q.evaluate_on_three_adic_domain(1, 3),
2600 q.evaluate_on_three_adic_domain(2, 3),
2601 ];
2602 let product = p.clone().multiply(q.clone());
2603 let result = Polynomial::encode3(Polynomial::multiply_values3(lhs, rhs));
2604 assert_eq!(result, product);
2605 }
2606}