@@ -648,52 +648,55 @@ static size_t secp256k1_strauss_scratch_size(size_t n_points) {
648648 return n_points * point_size ;
649649}
650650
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 ) {
652652 secp256k1_gej * points ;
653653 secp256k1_scalar * scalars ;
654654 struct secp256k1_strauss_state state ;
655655 size_t i ;
656+ const size_t scratch_checkpoint = secp256k1_scratch_checkpoint (error_callback , scratch );
656657
657658 secp256k1_gej_set_infinity (r );
658659 if (inp_g_sc == NULL && n_points == 0 ) {
659660 return 1 ;
660661 }
661662
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 ));
669667#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 ));
671669 state .pre_a_lam = state .pre_a + n_points * ECMULT_TABLE_SIZE (WINDOW_A );
672670#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 ));
674672#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+ }
676679
677680 for (i = 0 ; i < n_points ; i ++ ) {
678681 secp256k1_ge point ;
679682 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 );
681684 return 0 ;
682685 }
683686 secp256k1_gej_set_ge (& points [i ], & point );
684687 }
685688 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 );
687690 return 1 ;
688691}
689692
690693/* 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 );
693696}
694697
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 );
697700}
698701
699702/** Convert a number to WNAF notation.
@@ -985,7 +988,8 @@ static size_t secp256k1_pippenger_scratch_size(size_t n_points, int bucket_windo
985988 return (sizeof (secp256k1_gej ) << bucket_window ) + sizeof (struct secp256k1_pippenger_state ) + entries * entry_size ;
986989}
987990
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 );
989993 /* Use 2(n+1) with the endomorphism, n+1 without, when calculating batch
990994 * sizes. The reason for +1 is that we add the G scalar to the list of
991995 * other scalars. */
@@ -1010,15 +1014,21 @@ static int secp256k1_ecmult_pippenger_batch(const secp256k1_ecmult_context *ctx,
10101014 }
10111015
10121016 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 );
10141030 return 0 ;
10151031 }
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 );
10221032
10231033 if (inp_g_sc != NULL ) {
10241034 scalars [0 ] = * inp_g_sc ;
@@ -1032,7 +1042,7 @@ static int secp256k1_ecmult_pippenger_batch(const secp256k1_ecmult_context *ctx,
10321042
10331043 while (point_idx < n_points ) {
10341044 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 );
10361046 return 0 ;
10371047 }
10381048 idx ++ ;
@@ -1056,22 +1066,22 @@ static int secp256k1_ecmult_pippenger_batch(const secp256k1_ecmult_context *ctx,
10561066 for (i = 0 ; i < 1 <<bucket_window ; i ++ ) {
10571067 secp256k1_gej_clear (& buckets [i ]);
10581068 }
1059- secp256k1_scratch_deallocate_frame ( scratch );
1069+ secp256k1_scratch_apply_checkpoint ( error_callback , scratch , scratch_checkpoint );
10601070 return 1 ;
10611071}
10621072
10631073/* 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 );
10661076}
10671077
10681078/**
10691079 * Returns the maximum number of points in addition to G that can be used with
10701080 * a given scratch space. The function ensures that fewer points may also be
10711081 * used.
10721082 */
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 );
10751085 int bucket_window ;
10761086 size_t res = 0 ;
10771087
@@ -1153,11 +1163,11 @@ static int secp256k1_ecmult_multi_batch_size_helper(size_t *n_batches, size_t *n
11531163 return 1 ;
11541164}
11551165
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 ) {
11581168 size_t i ;
11591169
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 );
11611171 size_t n_batches ;
11621172 size_t n_batch_points ;
11631173
@@ -1178,13 +1188,13 @@ static int secp256k1_ecmult_multi_var(const secp256k1_ecmult_context *ctx, secp2
11781188 * a threshold use Pippenger's algorithm. Otherwise use Strauss' algorithm.
11791189 * As a first step check if there's enough space for Pippenger's algo (which requires less space
11801190 * 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 )) {
11821192 return secp256k1_ecmult_multi_simple_var (ctx , r , inp_g_sc , cb , cbdata , n );
11831193 }
11841194 if (n_batch_points >= ECMULT_PIPPENGER_THRESHOLD ) {
11851195 f = secp256k1_ecmult_pippenger_batch ;
11861196 } 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 )) {
11881198 return secp256k1_ecmult_multi_simple_var (ctx , r , inp_g_sc , cb , cbdata , n );
11891199 }
11901200 f = secp256k1_ecmult_strauss_batch ;
@@ -1193,7 +1203,7 @@ static int secp256k1_ecmult_multi_var(const secp256k1_ecmult_context *ctx, secp2
11931203 size_t nbp = n < n_batch_points ? n : n_batch_points ;
11941204 size_t offset = n_batch_points * i ;
11951205 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 )) {
11971207 return 0 ;
11981208 }
11991209 secp256k1_gej_add_var (r , r , & tmp , NULL );
0 commit comments