@ -3,19 +3,18 @@
use super ::polynomial ::MultilinearPolynomial ;
use crate ::errors ::NovaError ;
use crate ::traits ::{ Group , TranscriptEngineTrait , TranscriptReprTrait } ;
use core ::marker ::PhantomData ;
use ff ::Field ;
use ff ::{ Field , PrimeField } ;
use rayon ::prelude ::* ;
use serde ::{ Deserialize , Serialize } ;
#[ derive(Clone, Debug, Serialize, Deserialize) ]
#[ serde(bound = " " ) ]
pub ( crate ) struct SumcheckProof < G : Group > {
compressed_polys : Vec < CompressedUniPoly < G > > ,
compressed_polys : Vec < CompressedUniPoly < G ::Scalar > > ,
}
impl < G : Group > SumcheckProof < G > {
pub fn new ( compressed_polys : Vec < CompressedUniPoly < G > > ) -> Self {
pub fn new ( compressed_polys : Vec < CompressedUniPoly < G ::Scalar > > ) -> Self {
Self { compressed_polys }
}
@ -101,7 +100,7 @@ impl SumcheckProof {
F : Fn ( & G ::Scalar , & G ::Scalar ) -> G ::Scalar + Sync ,
{
let mut r : Vec < G ::Scalar > = Vec ::new ( ) ;
let mut polys : Vec < CompressedUniPoly < G > > = Vec ::new ( ) ;
let mut polys : Vec < CompressedUniPoly < G ::Scalar > > = Vec ::new ( ) ;
let mut claim_per_round = * claim ;
for _ in 0 . . num_rounds {
let poly = {
@ -150,7 +149,7 @@ impl SumcheckProof {
{
let mut e = * claim ;
let mut r : Vec < G ::Scalar > = Vec ::new ( ) ;
let mut quad_polys : Vec < CompressedUniPoly < G > > = Vec ::new ( ) ;
let mut quad_polys : Vec < CompressedUniPoly < G ::Scalar > > = Vec ::new ( ) ;
for _j in 0 . . num_rounds {
let mut evals : Vec < ( G ::Scalar , G ::Scalar ) > = Vec ::new ( ) ;
@ -204,7 +203,7 @@ impl SumcheckProof {
F : Fn ( & G ::Scalar , & G ::Scalar , & G ::Scalar , & G ::Scalar ) -> G ::Scalar + Sync ,
{
let mut r : Vec < G ::Scalar > = Vec ::new ( ) ;
let mut polys : Vec < CompressedUniPoly < G > > = Vec ::new ( ) ;
let mut polys : Vec < CompressedUniPoly < G ::Scalar > > = Vec ::new ( ) ;
let mut claim_per_round = * claim ;
for _ in 0 . . num_rounds {
@ -288,25 +287,24 @@ impl SumcheckProof {
// ax^2 + bx + c stored as vec![a,b,c]
// ax^3 + bx^2 + cx + d stored as vec![a,b,c,d]
#[ derive(Debug) ]
pub struct UniPoly < G : Group > {
coeffs : Vec < G ::Scalar > ,
pub struct UniPoly < Scalar : PrimeField > {
coeffs : Vec < Scalar > ,
}
// ax^2 + bx + c stored as vec![a,c]
// ax^3 + bx^2 + cx + d stored as vec![a,c,d]
#[ derive(Clone, Debug, Serialize, Deserialize) ]
pub struct CompressedUniPoly < G : Group > {
coeffs_except_linear_term : Vec < G ::Scalar > ,
_p : PhantomData < G > ,
pub struct CompressedUniPoly < Scalar : PrimeField > {
coeffs_except_linear_term : Vec < Scalar > ,
}
impl < G : Group > UniPoly < G > {
pub fn from_evals ( evals : & [ G ::Scalar ] ) -> Self {
impl < Scalar : PrimeField > UniPoly < Scalar > {
pub fn from_evals ( evals : & [ Scalar ] ) -> Self {
// we only support degree-2 or degree-3 univariate polynomials
assert ! ( evals . len ( ) = = 3 | | evals . len ( ) = = 4 ) ;
let coeffs = if evals . len ( ) = = 3 {
// ax^2 + bx + c
let two_inv = G ::Scalar ::from ( 2 ) . invert ( ) . unwrap ( ) ;
let two_inv = Scalar ::from ( 2 ) . invert ( ) . unwrap ( ) ;
let c = evals [ 0 ] ;
let a = two_inv * ( evals [ 2 ] - evals [ 1 ] - evals [ 1 ] + c ) ;
@ -314,8 +312,8 @@ impl UniPoly {
vec ! [ c , b , a ]
} else {
// ax^3 + bx^2 + cx + d
let two_inv = G ::Scalar ::from ( 2 ) . invert ( ) . unwrap ( ) ;
let six_inv = G ::Scalar ::from ( 6 ) . invert ( ) . unwrap ( ) ;
let two_inv = Scalar ::from ( 2 ) . invert ( ) . unwrap ( ) ;
let six_inv = Scalar ::from ( 6 ) . invert ( ) . unwrap ( ) ;
let d = evals [ 0 ] ;
let a = six_inv
@ -338,18 +336,18 @@ impl UniPoly {
self . coeffs . len ( ) - 1
}
pub fn eval_at_zero ( & self ) -> G ::Scalar {
pub fn eval_at_zero ( & self ) -> Scalar {
self . coeffs [ 0 ]
}
pub fn eval_at_one ( & self ) -> G ::Scalar {
pub fn eval_at_one ( & self ) -> Scalar {
( 0 . . self . coeffs . len ( ) )
. into_par_iter ( )
. map ( | i | self . coeffs [ i ] )
. reduce ( | | G ::Scalar ::ZERO , | a , b | a + b )
. reduce ( | | Scalar ::ZERO , | a , b | a + b )
}
pub fn evaluate ( & self , r : & G ::Scalar ) -> G ::Scalar {
pub fn evaluate ( & self , r : & Scalar ) -> Scalar {
let mut eval = self . coeffs [ 0 ] ;
let mut power = * r ;
for coeff in self . coeffs . iter ( ) . skip ( 1 ) {
@ -359,27 +357,26 @@ impl UniPoly {
eval
}
pub fn compress ( & self ) -> CompressedUniPoly < G > {
pub fn compress ( & self ) -> CompressedUniPoly < Scalar > {
let coeffs_except_linear_term = [ & self . coeffs [ 0 . . 1 ] , & self . coeffs [ 2 . . ] ] . concat ( ) ;
assert_eq ! ( coeffs_except_linear_term . len ( ) + 1 , self . coeffs . len ( ) ) ;
CompressedUniPoly {
coeffs_except_linear_term ,
_p : Default ::default ( ) ,
}
}
}
impl < G : Group > CompressedUniPoly < G > {
impl < Scalar : PrimeField > CompressedUniPoly < Scalar > {
// we require eval(0) + eval(1) = hint, so we can solve for the linear term as:
// linear_term = hint - 2 * constant_term - deg2 term - deg3 term
pub fn decompress ( & self , hint : & G ::Scalar ) -> UniPoly < G > {
pub fn decompress ( & self , hint : & Scalar ) -> UniPoly < Scalar > {
let mut linear_term =
* hint - self . coeffs_except_linear_term [ 0 ] - self . coeffs_except_linear_term [ 0 ] ;
for i in 1 . . self . coeffs_except_linear_term . len ( ) {
linear_term - = self . coeffs_except_linear_term [ i ] ;
}
let mut coeffs : Vec < G ::Scalar > = Vec ::new ( ) ;
let mut coeffs : Vec < Scalar > = Vec ::new ( ) ;
coeffs . push ( self . coeffs_except_linear_term [ 0 ] ) ;
coeffs . push ( linear_term ) ;
coeffs . extend ( & self . coeffs_except_linear_term [ 1 . . ] ) ;
@ -388,7 +385,7 @@ impl CompressedUniPoly {
}
}
impl < G : Group > TranscriptReprTrait < G > for UniPoly < G > {
impl < G : Group > TranscriptReprTrait < G > for UniPoly < G ::Scalar > {
fn to_transcript_bytes ( & self ) -> Vec < u8 > {
let coeffs = self . compress ( ) . coeffs_except_linear_term ;
coeffs . as_slice ( ) . to_transcript_bytes ( )