@@ -7,24 +7,26 @@ use ark_ec::CurveGroup;
77use ark_ff:: { Field , One } ;
88use ark_serialize:: { CanonicalDeserialize , CanonicalSerialize , Read , SerializationError , Write } ;
99use ark_std:: rand:: RngCore ;
10- use ark_std:: Zero ;
11-
10+ use ark_std:: { UniformRand , Zero } ;
11+ use itertools :: iterate ;
1212use crate :: transcript:: CurdleproofsTranscript ;
1313use merlin:: Transcript ;
1414
1515use crate :: errors:: ProofError ;
16- use crate :: inner_product_argument:: InnerProductProof ;
16+ use crate :: inner_product_argument:: { InnerProductProof , WeightedInnerProductProof } ;
1717use crate :: msm_accumulator:: MsmAccumulator ;
18- use crate :: util:: { generate_blinders, inner_product, msm} ;
18+ use crate :: util:: { generate_blinders, inner_product, msm, weighted_inner_product } ;
1919
2020/// A GrandProduct proof object
21- #[ derive( Clone , Debug , CanonicalSerialize , CanonicalDeserialize ) ]
21+ #[ derive( Clone , Debug ) ]
2222pub struct GrandProductProof {
2323 C : G1Projective ,
24+
25+ P : G1Projective ,
2426
2527 r_p : Fr ,
2628
27- ipa_proof : InnerProductProof ,
29+ wipa_proof : WeightedInnerProductProof ,
2830}
2931
3032impl GrandProductProof {
@@ -44,6 +46,7 @@ impl GrandProductProof {
4446 crs_G_vec : & Vec < G1Affine > ,
4547 crs_H_vec : & Vec < G1Affine > ,
4648 crs_U : & G1Projective , // This is actually H in the paper
49+ crs_G : & G1Projective ,
4750
4851 B : G1Projective ,
4952 gprod_result : Fr ,
@@ -73,15 +76,13 @@ impl GrandProductProof {
7376 }
7477
7578 let vec_c_blinders = generate_blinders ( rng, n_blinders) ; // vec_r_c in the paper
76- let C = msm ( crs_G_vec, & vec_c) + msm ( crs_H_vec, & vec_c_blinders) ;
77-
79+
7880 // Compute r_p
7981 let vec_r_b_plus_alpha: Vec < Fr > =
8082 vec_b_blinders. iter ( ) . map ( |r_b_i| * r_b_i + alpha) . collect ( ) ;
8183 let r_p = inner_product ( & vec_r_b_plus_alpha, & vec_c_blinders) ;
82-
83- transcript. append ( b"gprod_step2" , & C ) ;
8484 transcript. append ( b"gprod_step2" , & r_p) ;
85+
8586 let beta = transcript. get_and_append_challenge ( b"gprod_beta" ) ;
8687 let beta_inv = beta. inverse ( ) . expect ( "beta must have an inverse" ) ;
8788
@@ -101,7 +102,7 @@ impl GrandProductProof {
101102 . map ( |H_i | H_i . mul ( beta_inv. pow ( [ ell_plus_one] ) ) . into_affine ( ) )
102103 . collect ( ) ;
103104
104- // Build the new b' and d vectors
105+ // Build b' for the d vector
105106 let mut vec_b_prime: Vec < Fr > = Vec :: with_capacity ( ell) ;
106107 let mut pow_beta = beta;
107108 for b_i in vec_b. into_iter ( ) {
@@ -124,45 +125,63 @@ impl GrandProductProof {
124125 . iter ( )
125126 . map ( |f_i| beta. pow ( [ ell_plus_one] ) * f_i)
126127 . collect ( ) ;
127-
128- // Create D commitment
129- let vec_alphabeta: Vec < Fr > = iter:: repeat ( alpha * ( beta. pow ( [ ell_plus_one] ) ) )
130- . take ( n_blinders)
131- . collect ( ) ;
132- let D = B - msm ( & vec_G_prime, & vec_beta_powers) + msm ( & vec_H_prime, & vec_alphabeta) ;
133-
128+
134129 // Step 4
135130 // Build G
136131 let mut vec_G = crs_G_vec. clone ( ) ;
137132 vec_G. extend ( crs_H_vec) ;
138133 // Build G'
139134 vec_G_prime. extend ( vec_H_prime) ;
140-
141- let inner_prod =
135+
136+ let y = Fr :: one ( ) ;
137+
138+ let weighted_inner_prod =
142139 r_p * beta. pow ( [ ( ell + 1 ) as u64 ] ) + gprod_result * beta. pow ( [ ell as u64 ] ) - Fr :: one ( ) ;
143140
144141 vec_c. extend ( vec_c_blinders) ;
145142 vec_d. extend ( vec_d_blinders) ;
143+
144+ let C = G1Projective :: rand ( rng) ;
145+ let D = G1Projective :: rand ( rng) ;
146+
147+ let wip = weighted_inner_product ( & vec_c, & vec_d, y) ;
148+
149+ let alphawip = transcript. get_and_append_challenge ( b"alphawip" ) ;
150+
151+ // P = <a * G> + <b_L * H_R> + c * g + alpha*h
152+ let g_z: G1Projective = * crs_G * wip;
153+ let h_alpha: G1Projective = * crs_U * alphawip;
154+ let gz_halpha: G1Projective = g_z + h_alpha;
155+ let c_G: G1Projective = ( 0 ..n)
156+ . map ( |i| crs_G_vec[ i] * vec_c[ i] )
157+ . fold ( gz_halpha, |acc, x| acc + x) ;
158+
159+ let P = ( 0 ..n)
160+ . map ( |i| crs_H_vec[ i] * & vec_d[ i] )
161+ . fold ( c_G, |acc, x : G1Projective | acc + x) ;
146162
147163 // Sanity checks
148- debug_assert ! ( inner_product ( & vec_c , & vec_d ) == inner_prod ) ; // check inner product
164+ debug_assert ! ( wip == weighted_inner_prod ) ; // check inner product
149165 debug_assert ! ( ( msm( & vec_G, & vec_c) - C ) . is_zero( ) ) ; // check C commitment
150166 debug_assert ! ( ( msm( & vec_G_prime, & vec_d) - D ) . is_zero( ) ) ; // check D commitment
151167
152- let ipa_proof = InnerProductProof :: new (
168+ let wipa_proof = WeightedInnerProductProof :: new (
153169 vec_G,
154170 vec_G_prime,
171+ crs_G,
155172 crs_U,
156- C ,
157- D ,
158- inner_prod,
173+ P ,
174+ wip,
159175 vec_c,
160176 vec_d,
177+ y,
178+ alphawip,
161179 transcript,
162180 rng,
163181 ) ;
182+
164183
165- GrandProductProof { C , r_p, ipa_proof }
184+ GrandProductProof { C , P , r_p, wipa_proof }
166185 }
167186
168187 /// Verify a GrandProduct proof
@@ -182,9 +201,11 @@ impl GrandProductProof {
182201
183202 crs_G_vec : & Vec < G1Affine > ,
184203 crs_H_vec : & Vec < G1Affine > ,
204+ crs_G : & G1Projective ,
185205 crs_U : & G1Projective , // This is actually H in the paper
186206 crs_G_sum : & G1Affine ,
187207 crs_H_sum : & G1Affine ,
208+ P : & G1Projective ,
188209
189210 B : G1Projective ,
190211 gprod_result : Fr ,
@@ -227,38 +248,26 @@ impl GrandProductProof {
227248 let mut vec_G = crs_G_vec. clone ( ) ;
228249 vec_G. extend ( crs_H_vec) ;
229250
230- let inner_prod =
251+ let weightedInnerProduct =
231252 self . r_p * beta. pow ( [ ell_plus_one] ) + gprod_result * beta. pow ( [ ell as u64 ] ) - Fr :: one ( ) ;
232253
233- self . ipa_proof . verify (
234- & vec_G,
254+ let y = Fr :: one ( ) ;
255+
256+ self . wipa_proof . verify (
257+ crs_G_vec,
258+ crs_H_vec,
259+ crs_G,
235260 crs_U,
236- self . C ,
237- D ,
238- inner_prod,
239- vec_u,
261+ * P ,
262+ weightedInnerProduct,
263+ y,
240264 transcript,
241265 msm_accumulator,
242266 rng,
243267 ) ?;
244268
245269 Ok ( ( ) )
246270 }
247-
248- pub fn serialize < W : Write > ( & self , mut w : W ) -> Result < ( ) , SerializationError > {
249- self . C . serialize_compressed ( & mut w) ?;
250- self . r_p . serialize_compressed ( & mut w) ?;
251- self . ipa_proof . serialize ( & mut w) ?;
252- Ok ( ( ) )
253- }
254-
255- pub fn deserialize < R : Read > ( mut r : R , log2_n : usize ) -> Result < Self , SerializationError > {
256- Ok ( Self {
257- C : G1Projective :: deserialize_compressed ( & mut r) ?,
258- r_p : Fr :: deserialize_compressed ( & mut r) ?,
259- ipa_proof : InnerProductProof :: deserialize ( & mut r, log2_n) ?,
260- } )
261- }
262271}
263272
264273#[ cfg( test) ]
@@ -286,20 +295,25 @@ mod tests {
286295 . take ( n_blinders)
287296 . collect ( ) ;
288297 let crs_U = G1Projective :: rand ( & mut rng) ;
298+ let crs_G = G1Projective :: rand ( & mut rng) ;
289299 let crs_G_sum: G1Affine = sum_affine_points ( & crs_G_vec) ;
290300 let crs_H_sum: G1Affine = sum_affine_points ( & crs_H_vec) ;
291301
292302 let vec_b: Vec < Fr > = iter:: repeat_with ( || rng. gen ( ) ) . take ( ell) . collect ( ) ;
293303 let vec_b_blinders = generate_blinders ( & mut rng, n_blinders) ;
294304
295305 // Compute gprod result without the blinders
296- let gprod_result = vec_b. iter ( ) . product ( ) ;
306+ let mut gprod_result = Fr :: one ( ) ;
307+ for & b in & vec_b {
308+ gprod_result *= b;
309+ }
297310
298311 let B = msm ( & crs_G_vec, & vec_b) + msm ( & crs_H_vec, & vec_b_blinders) ;
299312
300313 let gprod_proof = GrandProductProof :: new (
301314 & crs_G_vec,
302315 & crs_H_vec,
316+ & crs_G,
303317 & crs_U,
304318 B ,
305319 gprod_result,
@@ -317,9 +331,11 @@ mod tests {
317331 . verify(
318332 & crs_G_vec,
319333 & crs_H_vec,
334+ & crs_G,
320335 & crs_U,
321336 & crs_G_sum,
322337 & crs_H_sum,
338+ & gprod_proof. P ,
323339 B ,
324340 gprod_result,
325341 n_blinders,
@@ -339,9 +355,11 @@ mod tests {
339355 . verify(
340356 & crs_G_vec,
341357 & crs_H_vec,
358+ & crs_G,
342359 & crs_U,
343360 & crs_G_sum,
344361 & crs_H_sum,
362+ & gprod_proof. P ,
345363 B ,
346364 gprod_result + Fr :: one( ) ,
347365 n_blinders,
@@ -359,9 +377,11 @@ mod tests {
359377 . verify(
360378 & crs_G_vec,
361379 & crs_H_vec,
380+ & crs_G,
362381 & crs_U,
363382 & crs_G_sum,
364383 & crs_H_sum,
384+ & gprod_proof. P ,
365385 B . mul( Fr :: rand( & mut rng) ) ,
366386 gprod_result,
367387 n_blinders,
0 commit comments