@@ -972,12 +972,33 @@ static size_t secp256k1_pippenger_max_points(secp256k1_scratch *scratch) {
972
972
return res ;
973
973
}
974
974
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_t )-1 - (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_t )-1 - (* n_batches - 1 )) {
991
+ return 0 ;
992
+ }
993
+ * n_batch_points = (n + (* n_batches - 1 )) / * n_batches ;
994
+ return 1 ;
995
+ }
996
+
975
997
typedef int (* secp256k1_ecmult_multi_func )(const secp256k1_ecmult_context * , secp256k1_scratch * , secp256k1_gej * , const secp256k1_scalar * , secp256k1_ecmult_multi_callback cb , void * , size_t );
976
998
static 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 ) {
977
999
size_t i ;
978
1000
979
1001
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 ;
981
1002
size_t n_batches ;
982
1003
size_t n_batch_points ;
983
1004
@@ -991,24 +1012,17 @@ static int secp256k1_ecmult_multi_var(const secp256k1_ecmult_context *ctx, secp2
991
1012
return 1 ;
992
1013
}
993
1014
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 )) {
996
1018
return 0 ;
997
- } else if (max_points > ECMULT_MAX_POINTS_PER_BATCH ) {
998
- max_points = ECMULT_MAX_POINTS_PER_BATCH ;
999
1019
}
1000
- n_batches = (n + max_points - 1 )/max_points ;
1001
- n_batch_points = (n + n_batches - 1 )/n_batches ;
1002
-
1003
1020
if (n_batch_points >= ECMULT_PIPPENGER_THRESHOLD ) {
1004
1021
f = secp256k1_ecmult_pippenger_batch ;
1005
1022
} 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 )) {
1008
1024
return 0 ;
1009
1025
}
1010
- n_batches = (n + max_points - 1 )/max_points ;
1011
- n_batch_points = (n + n_batches - 1 )/n_batches ;
1012
1026
f = secp256k1_ecmult_strauss_batch ;
1013
1027
}
1014
1028
for (i = 0 ; i < n_batches ; i ++ ) {
0 commit comments