@@ -972,12 +972,33 @@ static size_t secp256k1_pippenger_max_points(secp256k1_scratch *scratch) {
972972 return res ;
973973}
974974
975+ /* Compute the number and size of batches given the maximum number of points in a batch and the
976+ * total number of points */
977+ static int secp256k1_ecmult_multi_batch_size_helper (size_t * n_batches , size_t * n_batch_points , size_t max_points , size_t n ) {
978+ if (max_points == 0 ) {
979+ return 0 ;
980+ }
981+ if (max_points > ECMULT_MAX_POINTS_PER_BATCH ) {
982+ max_points = ECMULT_MAX_POINTS_PER_BATCH ;
983+ }
984+ /* Check overflow */
985+ if (n > SIZE_MAX - (max_points - 1 )) {
986+ return 0 ;
987+ }
988+ * n_batches = (n + (max_points - 1 )) / max_points ;
989+ /* Check overflow */
990+ if (n_batches == 0 || n > SIZE_MAX - (* n_batches - 1 )) {
991+ return 0 ;
992+ }
993+ * n_batch_points = (n + (* n_batches - 1 )) / * n_batches ;
994+ return 1 ;
995+ }
996+
975997typedef int (* secp256k1_ecmult_multi_func )(const secp256k1_ecmult_context * , secp256k1_scratch * , secp256k1_gej * , const secp256k1_scalar * , secp256k1_ecmult_multi_callback cb , void * , size_t );
976998static int secp256k1_ecmult_multi_var (const secp256k1_ecmult_context * ctx , secp256k1_scratch * scratch , secp256k1_gej * r , const secp256k1_scalar * inp_g_sc , secp256k1_ecmult_multi_callback cb , void * cbdata , size_t n ) {
977999 size_t i ;
9781000
9791001 int (* f )(const secp256k1_ecmult_context * , secp256k1_scratch * , secp256k1_gej * , const secp256k1_scalar * , secp256k1_ecmult_multi_callback cb , void * , size_t , size_t );
980- size_t max_points ;
9811002 size_t n_batches ;
9821003 size_t n_batch_points ;
9831004
@@ -991,24 +1012,17 @@ static int secp256k1_ecmult_multi_var(const secp256k1_ecmult_context *ctx, secp2
9911012 return 1 ;
9921013 }
9931014
994- max_points = secp256k1_pippenger_max_points (scratch );
995- if (max_points == 0 ) {
1015+ /* Compute the batch sizes for pippenger given a scratch space. If it's greater than a threshold
1016+ * use pippenger. Otherwise use strauss */
1017+ if (!secp256k1_ecmult_multi_batch_size_helper (& n_batches , & n_batch_points , secp256k1_pippenger_max_points (scratch ), n )) {
9961018 return 0 ;
997- } else if (max_points > ECMULT_MAX_POINTS_PER_BATCH ) {
998- max_points = ECMULT_MAX_POINTS_PER_BATCH ;
9991019 }
1000- n_batches = (n + max_points - 1 )/max_points ;
1001- n_batch_points = (n + n_batches - 1 )/n_batches ;
1002-
10031020 if (n_batch_points >= ECMULT_PIPPENGER_THRESHOLD ) {
10041021 f = secp256k1_ecmult_pippenger_batch ;
10051022 } else {
1006- max_points = secp256k1_strauss_max_points (scratch );
1007- if (max_points == 0 ) {
1023+ if (!secp256k1_ecmult_multi_batch_size_helper (& n_batches , & n_batch_points , secp256k1_strauss_max_points (scratch ), n )) {
10081024 return 0 ;
10091025 }
1010- n_batches = (n + max_points - 1 )/max_points ;
1011- n_batch_points = (n + n_batches - 1 )/n_batches ;
10121026 f = secp256k1_ecmult_strauss_batch ;
10131027 }
10141028 for (i = 0 ; i < n_batches ; i ++ ) {
0 commit comments