1
1
#![ allow( dead_code) ] // for now
2
2
3
3
use fp2:: traits:: Fp as FpTrait ;
4
+ use rand_core:: { CryptoRng , RngCore } ;
4
5
5
6
use core:: ops:: { Add , AddAssign , Mul , MulAssign , Neg , Sub , SubAssign } ;
6
7
use std:: {
@@ -31,6 +32,16 @@ pub struct Polynomial<Fp: FpTrait> {
31
32
}
32
33
33
34
impl < Fp : FpTrait > Polynomial < Fp > {
35
+ /// Create a polynomial from a finite field element.
36
+ pub fn new_from_ele ( a : & Fp ) -> Self {
37
+ Self { coeffs : vec ! [ * a] }
38
+ }
39
+
40
+ /// Create a polynomial from a slice of finite field elements.
41
+ pub fn new_from_slice ( a : & [ Fp ] ) -> Self {
42
+ Self { coeffs : a. to_vec ( ) }
43
+ }
44
+
34
45
/// The length of the polynomial. TODO: should we trim trailing zeros? If so, how often?
35
46
fn len ( & self ) -> usize {
36
47
self . coeffs . len ( )
@@ -59,6 +70,31 @@ impl<Fp: FpTrait> Polynomial<Fp> {
59
70
r
60
71
}
61
72
73
+ /// Return 0xFFFFFFFF if self and other represent the same polynomial.
74
+ /// Otherwise, return 0x00000000.
75
+ pub fn equals ( & self , other : & Self ) -> u32 {
76
+ // TODO: do I want this constant time?
77
+ // eg: let mut equals = ct_u32_eq(self.len() as u32, other.len() as u32);
78
+ if self . len ( ) != other. len ( ) {
79
+ return 0 ;
80
+ }
81
+
82
+ let mut equals = u32:: MAX ;
83
+ for i in 0 ..self . len ( ) {
84
+ equals &= self . coeffs [ i] . equals ( & other[ i] ) ;
85
+ }
86
+ equals
87
+ }
88
+
89
+ /// Return 0xFFFFFFFF if self is zero, otherwise, return 0x00000000.
90
+ pub fn is_zero ( & self ) -> u32 {
91
+ let mut is_zero = u32:: MAX ;
92
+ for i in 0 ..self . len ( ) {
93
+ is_zero &= self . coeffs [ i] . is_zero ( ) ;
94
+ }
95
+ is_zero
96
+ }
97
+
62
98
/// Set self to it's negative.
63
99
fn set_neg ( & mut self ) {
64
100
for x in self . coeffs . iter_mut ( ) {
@@ -133,6 +169,22 @@ impl<Fp: FpTrait> Polynomial<Fp> {
133
169
r. scale_small_into ( k) ;
134
170
r
135
171
}
172
+
173
+ /// Set self to a random value
174
+ pub fn set_rand < R : CryptoRng + RngCore > ( & mut self , rng : & mut R ) {
175
+ for x in self . coeffs . iter_mut ( ) {
176
+ x. set_rand ( rng) ;
177
+ }
178
+ }
179
+
180
+ /// Return a new random polynomial with length d
181
+ pub fn rand < R : CryptoRng + RngCore > ( rng : & mut R , d : usize ) -> Self {
182
+ let mut r = Self {
183
+ coeffs : vec ! [ Fp :: ZERO ; d] ,
184
+ } ;
185
+ r. set_rand ( rng) ;
186
+ r
187
+ }
136
188
}
137
189
138
190
impl < Fp : FpTrait > Poly for Polynomial < Fp > { }
@@ -173,6 +225,17 @@ impl<Fp: FpTrait> Add for Polynomial<Fp> {
173
225
}
174
226
}
175
227
228
+ impl < Fp : FpTrait > Add for & Polynomial < Fp > {
229
+ type Output = Polynomial < Fp > ;
230
+
231
+ #[ inline( always) ]
232
+ fn add ( self , other : & Polynomial < Fp > ) -> Polynomial < Fp > {
233
+ let mut r = self . clone ( ) ;
234
+ r. set_add ( & other) ;
235
+ r
236
+ }
237
+ }
238
+
176
239
impl < Fp : FpTrait > AddAssign for Polynomial < Fp > {
177
240
#[ inline( always) ]
178
241
fn add_assign ( & mut self , other : Polynomial < Fp > ) {
@@ -191,6 +254,17 @@ impl<Fp: FpTrait> Sub for Polynomial<Fp> {
191
254
}
192
255
}
193
256
257
+ impl < Fp : FpTrait > Sub for & Polynomial < Fp > {
258
+ type Output = Polynomial < Fp > ;
259
+
260
+ #[ inline( always) ]
261
+ fn sub ( self , other : & Polynomial < Fp > ) -> Polynomial < Fp > {
262
+ let mut r = self . clone ( ) ;
263
+ r. set_sub ( & other) ;
264
+ r
265
+ }
266
+ }
267
+
194
268
impl < Fp : FpTrait > SubAssign for Polynomial < Fp > {
195
269
#[ inline( always) ]
196
270
fn sub_assign ( & mut self , other : Polynomial < Fp > ) {
0 commit comments