Skip to content

Commit 38544f5

Browse files
committed
add a few helper methods, needs testing
1 parent e0dcc61 commit 38544f5

File tree

1 file changed

+70
-4
lines changed

1 file changed

+70
-4
lines changed

src/polynomial_ring/pr.rs

Lines changed: 70 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,15 @@
33
use fp2::traits::Fp as FpTrait;
44

55
use core::ops::{Add, AddAssign, Mul, MulAssign, Neg, Sub, SubAssign};
6-
use std::{fmt::Display, ops::Index};
6+
use std::{
7+
fmt::Display,
8+
ops::{Index, IndexMut},
9+
};
710

811
/// Trait for arithmetic for univariate polynomials in Fp[X]
912
pub trait Poly:
1013
Index<usize>
14+
+ IndexMut<usize>
1115
+ Sized
1216
+ Neg<Output = Self>
1317
+ Add<Output = Self>
@@ -43,7 +47,19 @@ impl<Fp: FpTrait> Polynomial<Fp> {
4347
}
4448
}
4549

46-
/// Set self to it's negative
50+
/// Reverse the coefficients of self in place.
51+
fn reverse_into(&mut self) {
52+
self.coeffs.reverse();
53+
}
54+
55+
/// Return the polynomial with coefficents reversed.
56+
pub fn reverse(self) -> Polynomial<Fp> {
57+
let mut r = self;
58+
r.reverse_into();
59+
r
60+
}
61+
62+
/// Set self to it's negative.
4763
fn set_neg(&mut self) {
4864
for x in self.coeffs.iter_mut() {
4965
x.set_neg();
@@ -70,8 +86,52 @@ impl<Fp: FpTrait> Polynomial<Fp> {
7086
}
7187
}
7288

73-
fn set_mul(&mut self, _other: &Self) {
74-
todo!()
89+
/// Compute f * g with O(len(f) * len(g)) Fq multiplications using
90+
/// schoolbook multiplication. Assumes that fg has enough space for
91+
/// the result (len(f) + len(g) - 2).
92+
fn schoolbook_multiplication(fg: &mut [Fp], f: &[Fp], g: &[Fp]) {
93+
for i in 0..f.len() {
94+
for j in 0..g.len() {
95+
// TODO: this could be sped up when we know c[i + j] is zero
96+
// which happens when i = 0 or when j + 1 = len(other)
97+
fg[i + j] += f[i] * g[j]
98+
}
99+
}
100+
}
101+
102+
/// Set self <- self * other
103+
fn set_mul(&mut self, other: &Self) {
104+
let mut fg_coeffs = vec![Fp::ZERO; self.len() + other.len() - 2];
105+
Self::schoolbook_multiplication(&mut fg_coeffs, &self.coeffs, &other.coeffs);
106+
self.coeffs = fg_coeffs;
107+
}
108+
109+
/// Multiply all coefficients of the polynomial by a element of the finite field.
110+
pub fn scale_into(&mut self, c: &Fp) {
111+
for x in self.coeffs.iter_mut() {
112+
*x *= *c;
113+
}
114+
}
115+
116+
/// Return c * self for some c in the finite field.
117+
pub fn scale(self, c: &Fp) -> Polynomial<Fp> {
118+
let mut r = self;
119+
r.scale_into(c);
120+
r
121+
}
122+
123+
/// Multiply all coefficients of the polynomial by a small value.
124+
pub fn scale_small_into(&mut self, k: i32) {
125+
for x in self.coeffs.iter_mut() {
126+
x.set_mul_small(k);
127+
}
128+
}
129+
130+
/// Return c * self for some small c
131+
pub fn scale_small(self, k: i32) -> Polynomial<Fp> {
132+
let mut r = self;
133+
r.scale_small_into(k);
134+
r
75135
}
76136
}
77137

@@ -85,6 +145,12 @@ impl<Fp: FpTrait> Index<usize> for Polynomial<Fp> {
85145
}
86146
}
87147

148+
impl<Fp: FpTrait> IndexMut<usize> for Polynomial<Fp> {
149+
fn index_mut(&mut self, index: usize) -> &mut Self::Output {
150+
self.coeffs.get_mut(index).expect("Index out of bounds")
151+
}
152+
}
153+
88154
impl<Fp: FpTrait> Neg for Polynomial<Fp> {
89155
type Output = Polynomial<Fp>;
90156

0 commit comments

Comments
 (0)