@@ -163,7 +163,8 @@ typedef struct {
163
163
/* Seed for the random number generator */
164
164
unsigned char chacha_seed [32 ];
165
165
/* Caches randomizers generated by the PRNG which returns two randomizers per call. Caching
166
- * avoids having to call the PRNG twice as often. */
166
+ * avoids having to call the PRNG twice as often. The very first randomizer will be set to 1 and
167
+ * the PRNG is called at every odd indexed schnorrsig to fill the cache. */
167
168
secp256k1_scalar randomizer_cache [2 ];
168
169
/* Signature, message, public key tuples to verify */
169
170
const secp256k1_schnorrsig * const * sig ;
@@ -172,29 +173,19 @@ typedef struct {
172
173
size_t n_sigs ;
173
174
} secp256k1_schnorrsig_verify_ecmult_context ;
174
175
175
- /* Helper function for batch verification.
176
- * One call to the chacha20 returns two random scalars which are returned by this function as r[0]
177
- * and r[1] except for the first randomizer which is set to 1. */
178
- static void secp256k1_schnorrsig_batch_randomizer (secp256k1_scalar * r , const unsigned char * seed , uint64_t idx ) {
179
- secp256k1_scalar_chacha20 (& r [0 ], & r [1 ], seed , idx );
180
- if (idx == 0 ) {
181
- secp256k1_scalar_set_int (& r [0 ], 1 );
182
- }
183
- }
184
-
185
176
/* Callback function which is called by ecmult_multi in order to convert the ecmult_context
186
177
* consisting of signature, message and public key tuples into scalars and points. */
187
178
static int secp256k1_schnorrsig_verify_batch_ecmult_callback (secp256k1_scalar * sc , secp256k1_ge * pt , size_t idx , void * data ) {
188
179
secp256k1_schnorrsig_verify_ecmult_context * ecmult_context = (secp256k1_schnorrsig_verify_ecmult_context * ) data ;
189
180
190
- if (idx % 4 == 0 ) {
191
- /* Every idx corresponds to a (scalar,point)-tuple. So this callback is called on 4
181
+ if (idx % 4 == 2 ) {
182
+ /* Every idx corresponds to a (scalar,point)-tuple. So this callback is called with 4
192
183
* consecutive tuples before we need to call the RNG for new randomizers:
193
184
* (-randomizer_cache[0], R1)
194
185
* (-randomizer_cache[0]*e1, P1)
195
186
* (-randomizer_cache[1], R2)
196
187
* (-randomizer_cache[1]*e2, P2) */
197
- secp256k1_schnorrsig_batch_randomizer ( ecmult_context -> randomizer_cache , ecmult_context -> chacha_seed , idx / 4 );
188
+ secp256k1_scalar_chacha20 ( & ecmult_context -> randomizer_cache [ 0 ], & ecmult_context -> randomizer_cache [ 1 ] , ecmult_context -> chacha_seed , idx / 4 );
198
189
}
199
190
200
191
/* R */
@@ -284,11 +275,12 @@ int secp256k1_schnorrsig_verify_batch_sum_s(secp256k1_scalar *s, unsigned char *
284
275
secp256k1_scalar randomizer_cache [2 ];
285
276
size_t i ;
286
277
278
+ secp256k1_scalar_set_int (& randomizer_cache [0 ], 1 );
287
279
for (i = 0 ; i < n_sigs ; i ++ ) {
288
280
int overflow ;
289
281
secp256k1_scalar term ;
290
- if (i % 2 == 0 ) {
291
- secp256k1_schnorrsig_batch_randomizer ( randomizer_cache , chacha_seed , i / 2 );
282
+ if (i % 2 == 1 ) {
283
+ secp256k1_scalar_chacha20 ( & randomizer_cache [ 0 ], & randomizer_cache [ 1 ] , chacha_seed , i / 2 );
292
284
}
293
285
294
286
secp256k1_scalar_set_b32 (& term , & sig [i ]-> data [32 ], & overflow );
@@ -314,12 +306,19 @@ int secp256k1_schnorrsig_verify_batch(const secp256k1_context *ctx, secp256k1_sc
314
306
VERIFY_CHECK (ctx != NULL );
315
307
ARG_CHECK (secp256k1_ecmult_context_is_built (& ctx -> ecmult_ctx ));
316
308
ARG_CHECK (scratch != NULL );
309
+ /* Check that n_sigs is less than half of the maximum size_t value. This is necessary because
310
+ * the number of points given to ecmult_multi is 2*n_sigs. */
311
+ ARG_CHECK (n_sigs < (size_t )1 << (sizeof (size_t )* 8 - 1 ));
312
+ /* Check that n_sigs is less 2^31 to ensure the same behavior of this function on 32-bit and
313
+ * 64-bit platforms. */
314
+ ARG_CHECK (n_sigs < (size_t )(1 << 31 ));
317
315
318
316
secp256k1_sha256_initialize (& sha );
319
317
if (!secp256k1_schnorrsig_verify_batch_init_randomizer (ctx , & ecmult_context , & sha , sig , msg32 , pk , n_sigs )) {
320
318
return 0 ;
321
319
}
322
320
secp256k1_sha256_finalize (& sha , ecmult_context .chacha_seed );
321
+ secp256k1_scalar_set_int (& ecmult_context .randomizer_cache [0 ], 1 );
323
322
324
323
secp256k1_scalar_clear (& s );
325
324
if (!secp256k1_schnorrsig_verify_batch_sum_s (& s , ecmult_context .chacha_seed , sig , n_sigs )) {
0 commit comments