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