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