1+ use super :: ring:: Ring ;
2+ use crate :: math:: field:: FiniteField ;
3+ use crypto_bigint:: rand_core:: RngCore ;
4+ use serde:: Serialize ;
15use std:: {
26 collections:: HashSet ,
37 ops:: { Index , IndexMut } ,
48} ;
5-
6- use crate :: math:: field:: FiniteField ;
7- use crypto_bigint:: rand_core:: RngCore ;
89use thiserror:: Error ;
910
10- use super :: ring:: Ring ;
11-
1211/// Errors for all the polynomial operations.
1312#[ derive( Debug , Error ) ]
1413pub enum Error < T >
2827pub type Result < T , R > = std:: result:: Result < T , Error < R > > ;
2928
3029/// Represents a polynomial whose coefficients are elements in a finite field.
31- #[ derive( PartialEq , Eq , Debug ) ]
30+ #[ derive( PartialEq , Eq , Debug , Serialize ) ]
3231pub struct Polynomial < const LIMBS : usize , T : FiniteField < LIMBS > > ( Vec < T > ) ;
3332
3433impl < const LIMBS : usize , T : FiniteField < LIMBS > > Polynomial < LIMBS , T > {
@@ -41,6 +40,14 @@ impl<const LIMBS: usize, T: FiniteField<LIMBS>> Polynomial<LIMBS, T> {
4140 result
4241 }
4342
43+ pub fn coefficients ( & self ) -> & [ T ] {
44+ & self . 0
45+ }
46+
47+ pub fn degree ( & self ) -> usize {
48+ self . 0 . len ( ) - 1
49+ }
50+
4451 /// Generates a random polynomial of a given degree using a given pseudo-random generator.
4552 pub fn random < R : RngCore > ( degree : usize , rng : & mut R ) -> Self {
4653 let mut coefficients = Vec :: with_capacity ( degree + 1 ) ;
@@ -50,6 +57,10 @@ impl<const LIMBS: usize, T: FiniteField<LIMBS>> Polynomial<LIMBS, T> {
5057 Self ( coefficients)
5158 }
5259
60+ pub fn set_constant_coeff ( & mut self , value : T ) {
61+ self [ 0 ] = value;
62+ }
63+
5364 pub fn new ( coef : Vec < T > ) -> Result < Self , T > {
5465 if coef. len ( ) == 0 {
5566 Err ( Error :: EmptyCoefficients )
@@ -82,12 +93,12 @@ impl<const LIMBS: usize, const N: usize, T: FiniteField<LIMBS>> From<[T; N]>
8293}
8394
8495/// Computes the lagrange basis evaluated at `x`
85- pub ( crate ) fn compute_lagrange_basis < const LIMBS : usize , T : FiniteField < LIMBS > > (
86- nodes : Vec < T > ,
96+ pub fn compute_lagrange_basis < const LIMBS : usize , T : FiniteField < LIMBS > > (
97+ nodes : & [ T ] ,
8798 x : & T ,
8899) -> Result < Vec < T > , T > {
89- if !all_different ( & nodes) {
90- return Err ( Error :: NotAllDifferentInterpolation ( nodes) ) ;
100+ if !all_different ( nodes) {
101+ return Err ( Error :: NotAllDifferentInterpolation ( nodes. to_vec ( ) ) ) ;
91102 }
92103 let mut lagrange_basis = Vec :: with_capacity ( nodes. len ( ) ) ;
93104 for j in 0 ..nodes. len ( ) {
@@ -125,15 +136,15 @@ fn all_different<T: Ring>(list: &[T]) -> bool {
125136
126137/// Computes the evaluation of the interpolated polynomial at `x`.
127138pub fn interpolate_polynomial_at < const LIMBS : usize , T : FiniteField < LIMBS > > (
128- evaluations : Vec < T > ,
129- alphas : Vec < T > ,
139+ evaluations : & [ T ] ,
140+ alphas : & [ T ] ,
130141 x : & T ,
131142) -> Result < T , T > {
132143 assert ! ( alphas. len( ) > 0 ) ;
133144 assert ! ( alphas. len( ) == evaluations. len( ) ) ;
134145 let lagrange_basis = compute_lagrange_basis ( alphas, x) ?;
135146 let mut interpolation = T :: ZERO ;
136- for ( eval, basis) in evaluations. into_iter ( ) . zip ( lagrange_basis) {
147+ for ( eval, basis) in evaluations. iter ( ) . zip ( lagrange_basis) {
137148 interpolation = interpolation. add ( & eval. mul ( & basis) ) ;
138149 }
139150 Ok ( interpolation)
0 commit comments