@@ -648,52 +648,55 @@ static size_t secp256k1_strauss_scratch_size(size_t n_points) {
648
648
return n_points * point_size ;
649
649
}
650
650
651
- static int secp256k1_ecmult_strauss_batch (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_points , size_t cb_offset ) {
651
+ static int secp256k1_ecmult_strauss_batch (const secp256k1_callback * error_callback , 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_points , size_t cb_offset ) {
652
652
secp256k1_gej * points ;
653
653
secp256k1_scalar * scalars ;
654
654
struct secp256k1_strauss_state state ;
655
655
size_t i ;
656
+ const size_t scratch_checkpoint = secp256k1_scratch_checkpoint (error_callback , scratch );
656
657
657
658
secp256k1_gej_set_infinity (r );
658
659
if (inp_g_sc == NULL && n_points == 0 ) {
659
660
return 1 ;
660
661
}
661
662
662
- if (!secp256k1_scratch_allocate_frame (scratch , secp256k1_strauss_scratch_size (n_points ), STRAUSS_SCRATCH_OBJECTS )) {
663
- return 0 ;
664
- }
665
- points = (secp256k1_gej * )secp256k1_scratch_alloc (scratch , n_points * sizeof (secp256k1_gej ));
666
- scalars = (secp256k1_scalar * )secp256k1_scratch_alloc (scratch , n_points * sizeof (secp256k1_scalar ));
667
- state .prej = (secp256k1_gej * )secp256k1_scratch_alloc (scratch , n_points * ECMULT_TABLE_SIZE (WINDOW_A ) * sizeof (secp256k1_gej ));
668
- state .zr = (secp256k1_fe * )secp256k1_scratch_alloc (scratch , n_points * ECMULT_TABLE_SIZE (WINDOW_A ) * sizeof (secp256k1_fe ));
663
+ points = (secp256k1_gej * )secp256k1_scratch_alloc (error_callback , scratch , n_points * sizeof (secp256k1_gej ));
664
+ scalars = (secp256k1_scalar * )secp256k1_scratch_alloc (error_callback , scratch , n_points * sizeof (secp256k1_scalar ));
665
+ state .prej = (secp256k1_gej * )secp256k1_scratch_alloc (error_callback , scratch , n_points * ECMULT_TABLE_SIZE (WINDOW_A ) * sizeof (secp256k1_gej ));
666
+ state .zr = (secp256k1_fe * )secp256k1_scratch_alloc (error_callback , scratch , n_points * ECMULT_TABLE_SIZE (WINDOW_A ) * sizeof (secp256k1_fe ));
669
667
#ifdef USE_ENDOMORPHISM
670
- state .pre_a = (secp256k1_ge * )secp256k1_scratch_alloc (scratch , n_points * 2 * ECMULT_TABLE_SIZE (WINDOW_A ) * sizeof (secp256k1_ge ));
668
+ state .pre_a = (secp256k1_ge * )secp256k1_scratch_alloc (error_callback , scratch , n_points * 2 * ECMULT_TABLE_SIZE (WINDOW_A ) * sizeof (secp256k1_ge ));
671
669
state .pre_a_lam = state .pre_a + n_points * ECMULT_TABLE_SIZE (WINDOW_A );
672
670
#else
673
- state .pre_a = (secp256k1_ge * )secp256k1_scratch_alloc (scratch , n_points * ECMULT_TABLE_SIZE (WINDOW_A ) * sizeof (secp256k1_ge ));
671
+ state .pre_a = (secp256k1_ge * )secp256k1_scratch_alloc (error_callback , scratch , n_points * ECMULT_TABLE_SIZE (WINDOW_A ) * sizeof (secp256k1_ge ));
674
672
#endif
675
- state .ps = (struct secp256k1_strauss_point_state * )secp256k1_scratch_alloc (scratch , n_points * sizeof (struct secp256k1_strauss_point_state ));
673
+ state .ps = (struct secp256k1_strauss_point_state * )secp256k1_scratch_alloc (error_callback , scratch , n_points * sizeof (struct secp256k1_strauss_point_state ));
674
+
675
+ if (points == NULL || scalars == NULL || state .prej == NULL || state .zr == NULL || state .pre_a == NULL ) {
676
+ secp256k1_scratch_apply_checkpoint (error_callback , scratch , scratch_checkpoint );
677
+ return 0 ;
678
+ }
676
679
677
680
for (i = 0 ; i < n_points ; i ++ ) {
678
681
secp256k1_ge point ;
679
682
if (!cb (& scalars [i ], & point , i + cb_offset , cbdata )) {
680
- secp256k1_scratch_deallocate_frame ( scratch );
683
+ secp256k1_scratch_apply_checkpoint ( error_callback , scratch , scratch_checkpoint );
681
684
return 0 ;
682
685
}
683
686
secp256k1_gej_set_ge (& points [i ], & point );
684
687
}
685
688
secp256k1_ecmult_strauss_wnaf (ctx , & state , r , n_points , points , scalars , inp_g_sc );
686
- secp256k1_scratch_deallocate_frame ( scratch );
689
+ secp256k1_scratch_apply_checkpoint ( error_callback , scratch , scratch_checkpoint );
687
690
return 1 ;
688
691
}
689
692
690
693
/* Wrapper for secp256k1_ecmult_multi_func interface */
691
- static int secp256k1_ecmult_strauss_batch_single (const secp256k1_ecmult_context * actx , secp256k1_scratch * scratch , secp256k1_gej * r , const secp256k1_scalar * inp_g_sc , secp256k1_ecmult_multi_callback cb , void * cbdata , size_t n ) {
692
- return secp256k1_ecmult_strauss_batch (actx , scratch , r , inp_g_sc , cb , cbdata , n , 0 );
694
+ static int secp256k1_ecmult_strauss_batch_single (const secp256k1_callback * error_callback , const secp256k1_ecmult_context * actx , secp256k1_scratch * scratch , secp256k1_gej * r , const secp256k1_scalar * inp_g_sc , secp256k1_ecmult_multi_callback cb , void * cbdata , size_t n ) {
695
+ return secp256k1_ecmult_strauss_batch (error_callback , actx , scratch , r , inp_g_sc , cb , cbdata , n , 0 );
693
696
}
694
697
695
- static size_t secp256k1_strauss_max_points (secp256k1_scratch * scratch ) {
696
- return secp256k1_scratch_max_allocation (scratch , STRAUSS_SCRATCH_OBJECTS ) / secp256k1_strauss_scratch_size (1 );
698
+ static size_t secp256k1_strauss_max_points (const secp256k1_callback * error_callback , secp256k1_scratch * scratch ) {
699
+ return secp256k1_scratch_max_allocation (error_callback , scratch , STRAUSS_SCRATCH_OBJECTS ) / secp256k1_strauss_scratch_size (1 );
697
700
}
698
701
699
702
/** Convert a number to WNAF notation.
@@ -985,7 +988,8 @@ static size_t secp256k1_pippenger_scratch_size(size_t n_points, int bucket_windo
985
988
return (sizeof (secp256k1_gej ) << bucket_window ) + sizeof (struct secp256k1_pippenger_state ) + entries * entry_size ;
986
989
}
987
990
988
- static int secp256k1_ecmult_pippenger_batch (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_points , size_t cb_offset ) {
991
+ static int secp256k1_ecmult_pippenger_batch (const secp256k1_callback * error_callback , 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_points , size_t cb_offset ) {
992
+ const size_t scratch_checkpoint = secp256k1_scratch_checkpoint (error_callback , scratch );
989
993
/* Use 2(n+1) with the endomorphism, n+1 without, when calculating batch
990
994
* sizes. The reason for +1 is that we add the G scalar to the list of
991
995
* other scalars. */
@@ -1010,15 +1014,21 @@ static int secp256k1_ecmult_pippenger_batch(const secp256k1_ecmult_context *ctx,
1010
1014
}
1011
1015
1012
1016
bucket_window = secp256k1_pippenger_bucket_window (n_points );
1013
- if (!secp256k1_scratch_allocate_frame (scratch , secp256k1_pippenger_scratch_size (n_points , bucket_window ), PIPPENGER_SCRATCH_OBJECTS )) {
1017
+ points = (secp256k1_ge * ) secp256k1_scratch_alloc (error_callback , scratch , entries * sizeof (* points ));
1018
+ scalars = (secp256k1_scalar * ) secp256k1_scratch_alloc (error_callback , scratch , entries * sizeof (* scalars ));
1019
+ state_space = (struct secp256k1_pippenger_state * ) secp256k1_scratch_alloc (error_callback , scratch , sizeof (* state_space ));
1020
+ if (points == NULL || scalars == NULL || state_space == NULL ) {
1021
+ secp256k1_scratch_apply_checkpoint (error_callback , scratch , scratch_checkpoint );
1022
+ return 0 ;
1023
+ }
1024
+
1025
+ state_space -> ps = (struct secp256k1_pippenger_point_state * ) secp256k1_scratch_alloc (error_callback , scratch , entries * sizeof (* state_space -> ps ));
1026
+ state_space -> wnaf_na = (int * ) secp256k1_scratch_alloc (error_callback , scratch , entries * (WNAF_SIZE (bucket_window + 1 )) * sizeof (int ));
1027
+ buckets = (secp256k1_gej * ) secp256k1_scratch_alloc (error_callback , scratch , (1 <<bucket_window ) * sizeof (* buckets ));
1028
+ if (state_space -> ps == NULL || state_space -> wnaf_na == NULL || buckets == NULL ) {
1029
+ secp256k1_scratch_apply_checkpoint (error_callback , scratch , scratch_checkpoint );
1014
1030
return 0 ;
1015
1031
}
1016
- points = (secp256k1_ge * ) secp256k1_scratch_alloc (scratch , entries * sizeof (* points ));
1017
- scalars = (secp256k1_scalar * ) secp256k1_scratch_alloc (scratch , entries * sizeof (* scalars ));
1018
- state_space = (struct secp256k1_pippenger_state * ) secp256k1_scratch_alloc (scratch , sizeof (* state_space ));
1019
- state_space -> ps = (struct secp256k1_pippenger_point_state * ) secp256k1_scratch_alloc (scratch , entries * sizeof (* state_space -> ps ));
1020
- state_space -> wnaf_na = (int * ) secp256k1_scratch_alloc (scratch , entries * (WNAF_SIZE (bucket_window + 1 )) * sizeof (int ));
1021
- buckets = (secp256k1_gej * ) secp256k1_scratch_alloc (scratch , sizeof (* buckets ) << bucket_window );
1022
1032
1023
1033
if (inp_g_sc != NULL ) {
1024
1034
scalars [0 ] = * inp_g_sc ;
@@ -1032,7 +1042,7 @@ static int secp256k1_ecmult_pippenger_batch(const secp256k1_ecmult_context *ctx,
1032
1042
1033
1043
while (point_idx < n_points ) {
1034
1044
if (!cb (& scalars [idx ], & points [idx ], point_idx + cb_offset , cbdata )) {
1035
- secp256k1_scratch_deallocate_frame ( scratch );
1045
+ secp256k1_scratch_apply_checkpoint ( error_callback , scratch , scratch_checkpoint );
1036
1046
return 0 ;
1037
1047
}
1038
1048
idx ++ ;
@@ -1056,22 +1066,22 @@ static int secp256k1_ecmult_pippenger_batch(const secp256k1_ecmult_context *ctx,
1056
1066
for (i = 0 ; i < 1 <<bucket_window ; i ++ ) {
1057
1067
secp256k1_gej_clear (& buckets [i ]);
1058
1068
}
1059
- secp256k1_scratch_deallocate_frame ( scratch );
1069
+ secp256k1_scratch_apply_checkpoint ( error_callback , scratch , scratch_checkpoint );
1060
1070
return 1 ;
1061
1071
}
1062
1072
1063
1073
/* Wrapper for secp256k1_ecmult_multi_func interface */
1064
- static int secp256k1_ecmult_pippenger_batch_single (const secp256k1_ecmult_context * actx , secp256k1_scratch * scratch , secp256k1_gej * r , const secp256k1_scalar * inp_g_sc , secp256k1_ecmult_multi_callback cb , void * cbdata , size_t n ) {
1065
- return secp256k1_ecmult_pippenger_batch (actx , scratch , r , inp_g_sc , cb , cbdata , n , 0 );
1074
+ static int secp256k1_ecmult_pippenger_batch_single (const secp256k1_callback * error_callback , const secp256k1_ecmult_context * actx , secp256k1_scratch * scratch , secp256k1_gej * r , const secp256k1_scalar * inp_g_sc , secp256k1_ecmult_multi_callback cb , void * cbdata , size_t n ) {
1075
+ return secp256k1_ecmult_pippenger_batch (error_callback , actx , scratch , r , inp_g_sc , cb , cbdata , n , 0 );
1066
1076
}
1067
1077
1068
1078
/**
1069
1079
* Returns the maximum number of points in addition to G that can be used with
1070
1080
* a given scratch space. The function ensures that fewer points may also be
1071
1081
* used.
1072
1082
*/
1073
- static size_t secp256k1_pippenger_max_points (secp256k1_scratch * scratch ) {
1074
- size_t max_alloc = secp256k1_scratch_max_allocation (scratch , PIPPENGER_SCRATCH_OBJECTS );
1083
+ static size_t secp256k1_pippenger_max_points (const secp256k1_callback * error_callback , secp256k1_scratch * scratch ) {
1084
+ size_t max_alloc = secp256k1_scratch_max_allocation (error_callback , scratch , PIPPENGER_SCRATCH_OBJECTS );
1075
1085
int bucket_window ;
1076
1086
size_t res = 0 ;
1077
1087
@@ -1153,11 +1163,11 @@ static int secp256k1_ecmult_multi_batch_size_helper(size_t *n_batches, size_t *n
1153
1163
return 1 ;
1154
1164
}
1155
1165
1156
- 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 );
1157
- 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 ) {
1166
+ typedef int (* secp256k1_ecmult_multi_func )(const secp256k1_callback * error_callback , const secp256k1_ecmult_context * , secp256k1_scratch * , secp256k1_gej * , const secp256k1_scalar * , secp256k1_ecmult_multi_callback cb , void * , size_t );
1167
+ static int secp256k1_ecmult_multi_var (const secp256k1_callback * error_callback , 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 ) {
1158
1168
size_t i ;
1159
1169
1160
- int (* f )(const secp256k1_ecmult_context * , secp256k1_scratch * , secp256k1_gej * , const secp256k1_scalar * , secp256k1_ecmult_multi_callback cb , void * , size_t , size_t );
1170
+ int (* f )(const secp256k1_callback * error_callback , const secp256k1_ecmult_context * , secp256k1_scratch * , secp256k1_gej * , const secp256k1_scalar * , secp256k1_ecmult_multi_callback cb , void * , size_t , size_t );
1161
1171
size_t n_batches ;
1162
1172
size_t n_batch_points ;
1163
1173
@@ -1178,13 +1188,13 @@ static int secp256k1_ecmult_multi_var(const secp256k1_ecmult_context *ctx, secp2
1178
1188
* a threshold use Pippenger's algorithm. Otherwise use Strauss' algorithm.
1179
1189
* As a first step check if there's enough space for Pippenger's algo (which requires less space
1180
1190
* than Strauss' algo) and if not, use the simple algorithm. */
1181
- if (!secp256k1_ecmult_multi_batch_size_helper (& n_batches , & n_batch_points , secp256k1_pippenger_max_points (scratch ), n )) {
1191
+ if (!secp256k1_ecmult_multi_batch_size_helper (& n_batches , & n_batch_points , secp256k1_pippenger_max_points (error_callback , scratch ), n )) {
1182
1192
return secp256k1_ecmult_multi_simple_var (ctx , r , inp_g_sc , cb , cbdata , n );
1183
1193
}
1184
1194
if (n_batch_points >= ECMULT_PIPPENGER_THRESHOLD ) {
1185
1195
f = secp256k1_ecmult_pippenger_batch ;
1186
1196
} else {
1187
- if (!secp256k1_ecmult_multi_batch_size_helper (& n_batches , & n_batch_points , secp256k1_strauss_max_points (scratch ), n )) {
1197
+ if (!secp256k1_ecmult_multi_batch_size_helper (& n_batches , & n_batch_points , secp256k1_strauss_max_points (error_callback , scratch ), n )) {
1188
1198
return secp256k1_ecmult_multi_simple_var (ctx , r , inp_g_sc , cb , cbdata , n );
1189
1199
}
1190
1200
f = secp256k1_ecmult_strauss_batch ;
@@ -1193,7 +1203,7 @@ static int secp256k1_ecmult_multi_var(const secp256k1_ecmult_context *ctx, secp2
1193
1203
size_t nbp = n < n_batch_points ? n : n_batch_points ;
1194
1204
size_t offset = n_batch_points * i ;
1195
1205
secp256k1_gej tmp ;
1196
- if (!f (ctx , scratch , & tmp , i == 0 ? inp_g_sc : NULL , cb , cbdata , nbp , offset )) {
1206
+ if (!f (error_callback , ctx , scratch , & tmp , i == 0 ? inp_g_sc : NULL , cb , cbdata , nbp , offset )) {
1197
1207
return 0 ;
1198
1208
}
1199
1209
secp256k1_gej_add_var (r , r , & tmp , NULL );
0 commit comments