@@ -177,12 +177,21 @@ impl InnerProductProof {
177177
178178 /// Computes three vectors of verification scalars \\([u\_{i}^{2}]\\), \\([u\_{i}^{-2}]\\) and \\([s\_{i}]\\) for combined multiscalar multiplication
179179 /// in a parent protocol. See [inner product protocol notes](index.html#verification-equation) for details.
180+ /// The verifier must provide the input length \\(n\\) explicitly to avoid unbounded allocation within the inner product proof.
180181 pub ( crate ) fn verification_scalars (
181182 & self ,
183+ n : usize ,
182184 transcript : & mut Transcript ,
183- ) -> ( Vec < Scalar > , Vec < Scalar > , Vec < Scalar > ) {
185+ ) -> Result < ( Vec < Scalar > , Vec < Scalar > , Vec < Scalar > ) , ProofError > {
184186 let lg_n = self . L_vec . len ( ) ;
185- let n = 1 << lg_n;
187+ if lg_n >= 32 {
188+ // 4 billion multiplications should be enough for anyone
189+ // and this check prevents overflow in 1<<lg_n below.
190+ return Err ( ProofError :: VerificationError ) ;
191+ }
192+ if n != ( 1 << lg_n) {
193+ return Err ( ProofError :: VerificationError ) ;
194+ }
186195
187196 transcript. innerproduct_domain_sep ( n as u64 ) ;
188197
@@ -223,7 +232,7 @@ impl InnerProductProof {
223232 s. push ( s[ i - k] * u_lg_i_sq) ;
224233 }
225234
226- ( challenges_sq, challenges_inv_sq, s)
235+ Ok ( ( challenges_sq, challenges_inv_sq, s) )
227236 }
228237
229238 /// This method is for testing that proof generation work,
@@ -233,6 +242,7 @@ impl InnerProductProof {
233242 #[ allow( dead_code) ]
234243 pub fn verify < I > (
235244 & self ,
245+ n : usize ,
236246 transcript : & mut Transcript ,
237247 Hprime_factors : I ,
238248 P : & RistrettoPoint ,
@@ -244,7 +254,7 @@ impl InnerProductProof {
244254 I : IntoIterator ,
245255 I :: Item : Borrow < Scalar > ,
246256 {
247- let ( u_sq, u_inv_sq, s) = self . verification_scalars ( transcript) ;
257+ let ( u_sq, u_inv_sq, s) = self . verification_scalars ( n , transcript) ? ;
248258
249259 let a_times_s = s. iter ( ) . map ( |s_i| self . a * s_i) ;
250260
@@ -430,15 +440,15 @@ mod tests {
430440 let mut verifier = Transcript :: new ( b"innerproducttest" ) ;
431441 assert ! (
432442 proof
433- . verify( & mut verifier, util:: exp_iter( y_inv) , & P , & Q , & G , & H )
443+ . verify( n , & mut verifier, util:: exp_iter( y_inv) , & P , & Q , & G , & H )
434444 . is_ok( )
435445 ) ;
436446
437447 let proof = InnerProductProof :: from_bytes ( proof. to_bytes ( ) . as_slice ( ) ) . unwrap ( ) ;
438448 let mut verifier = Transcript :: new ( b"innerproducttest" ) ;
439449 assert ! (
440450 proof
441- . verify( & mut verifier, util:: exp_iter( y_inv) , & P , & Q , & G , & H )
451+ . verify( n , & mut verifier, util:: exp_iter( y_inv) , & P , & Q , & G , & H )
442452 . is_ok( )
443453 ) ;
444454 }
0 commit comments