@@ -2783,8 +2783,56 @@ void test_ecmult_multi(secp256k1_scratch *scratch, secp256k1_ecmult_multi_func e
2783
2783
}
2784
2784
}
2785
2785
2786
+ void test_secp256k1_pippenger_bucket_window_inv (void ) {
2787
+ int i ;
2788
+
2789
+ CHECK (secp256k1_pippenger_bucket_window_inv (0 ) == 0 );
2790
+ for (i = 1 ; i <= PIPPENGER_MAX_BUCKET_WINDOW ; i ++ ) {
2791
+ #ifdef USE_ENDOMORPHISM
2792
+ /* Bucket_window of 8 is not used with endo */
2793
+ if (i == 8 ) {
2794
+ continue ;
2795
+ }
2796
+ #endif
2797
+ CHECK (secp256k1_pippenger_bucket_window (secp256k1_pippenger_bucket_window_inv (i )) == i );
2798
+ if (i != PIPPENGER_MAX_BUCKET_WINDOW ) {
2799
+ CHECK (secp256k1_pippenger_bucket_window (secp256k1_pippenger_bucket_window_inv (i )+ 1 ) > i );
2800
+ }
2801
+ }
2802
+ }
2803
+
2804
+ /**
2805
+ * Probabilistically test the function returning the maximum number of possible points
2806
+ * for a given scratch space.
2807
+ */
2808
+ void test_ecmult_multi_pippenger_max_points (void ) {
2809
+ size_t scratch_size = secp256k1_rand_int (256 );
2810
+ size_t max_size = secp256k1_pippenger_scratch_size (secp256k1_pippenger_bucket_window_inv (PIPPENGER_MAX_BUCKET_WINDOW - 1 )+ 512 , 12 );
2811
+ secp256k1_scratch * scratch ;
2812
+ size_t n_points_supported ;
2813
+ int bucket_window = 0 ;
2814
+
2815
+ for (; scratch_size < max_size ; scratch_size += 256 ) {
2816
+ scratch = secp256k1_scratch_create (& ctx -> error_callback , 0 , scratch_size );
2817
+ CHECK (scratch != NULL );
2818
+ n_points_supported = secp256k1_pippenger_max_points (scratch );
2819
+ if (n_points_supported == 0 ) {
2820
+ secp256k1_scratch_destroy (scratch );
2821
+ continue ;
2822
+ }
2823
+ bucket_window = secp256k1_pippenger_bucket_window (n_points_supported );
2824
+ CHECK (secp256k1_scratch_resize (scratch , secp256k1_pippenger_scratch_size (n_points_supported , bucket_window ), PIPPENGER_SCRATCH_OBJECTS ));
2825
+ secp256k1_scratch_destroy (scratch );
2826
+ }
2827
+ CHECK (bucket_window == PIPPENGER_MAX_BUCKET_WINDOW );
2828
+ }
2829
+
2830
+ /**
2831
+ * Run secp256k1_ecmult_multi_var with num points and a scratch space restricted to
2832
+ * 1 <= i <= num points.
2833
+ */
2786
2834
void test_ecmult_multi_batching (void ) {
2787
- static const int n_points = 3 * MAX_BATCH_SIZE ;
2835
+ static const int n_points = 2 * ECMULT_PIPPENGER_THRESHOLD ;
2788
2836
secp256k1_scalar scG ;
2789
2837
secp256k1_scalar szero ;
2790
2838
secp256k1_scalar * sc = (secp256k1_scalar * )checked_malloc (& ctx -> error_callback , sizeof (secp256k1_scalar ) * n_points );
@@ -2795,18 +2843,21 @@ void test_ecmult_multi_batching(void) {
2795
2843
int i ;
2796
2844
secp256k1_scratch * scratch ;
2797
2845
2798
- int test_n_points [] = { MAX_BATCH_SIZE , MAX_BATCH_SIZE + 1 , MAX_BATCH_SIZE + 2 , 2 * MAX_BATCH_SIZE , 2 * MAX_BATCH_SIZE + 1 , 3 * MAX_BATCH_SIZE };
2799
2846
secp256k1_gej_set_infinity (& r2 );
2800
2847
secp256k1_scalar_set_int (& szero , 0 );
2801
2848
2802
- /* Get random scalars and group elements */
2849
+ /* Get random scalars and group elements and compute result */
2803
2850
random_scalar_order (& scG );
2804
2851
secp256k1_ecmult (& ctx -> ecmult_ctx , & r2 , & r2 , & szero , & scG );
2805
2852
for (i = 0 ; i < n_points ; i ++ ) {
2806
2853
secp256k1_ge ptg ;
2854
+ secp256k1_gej ptgj ;
2807
2855
random_group_element_test (& ptg );
2856
+ secp256k1_gej_set_ge (& ptgj , & ptg );
2808
2857
pt [i ] = ptg ;
2809
2858
random_scalar_order (& sc [i ]);
2859
+ secp256k1_ecmult (& ctx -> ecmult_ctx , & ptgj , & ptgj , & sc [i ], NULL );
2860
+ secp256k1_gej_add_var (& r2 , & r2 , & ptgj , NULL );
2810
2861
}
2811
2862
data .sc = sc ;
2812
2863
data .pt = pt ;
@@ -2822,10 +2873,8 @@ void test_ecmult_multi_batching(void) {
2822
2873
CHECK (!secp256k1_ecmult_multi_var (& ctx -> ecmult_ctx , scratch , & r , & scG , ecmult_multi_callback , & data , 1 ));
2823
2874
secp256k1_scratch_destroy (scratch );
2824
2875
2825
- /* Run secp256k1_ecmult_multi_var with i points and a scratch space
2826
- * restricted to i points. */
2827
- for (i = 1 ; i <= ECMULT_PIPPENGER_THRESHOLD + 2 ; i ++ ) {
2828
- secp256k1_gej ptgj ;
2876
+ secp256k1_gej_neg (& r2 , & r2 );
2877
+ for (i = 1 ; i <= n_points ; i ++ ) {
2829
2878
if (i > ECMULT_PIPPENGER_THRESHOLD ) {
2830
2879
int bucket_window = secp256k1_pippenger_bucket_window (i );
2831
2880
size_t scratch_size = secp256k1_pippenger_scratch_size (i , bucket_window );
@@ -2834,48 +2883,29 @@ void test_ecmult_multi_batching(void) {
2834
2883
size_t scratch_size = secp256k1_strauss_scratch_size (i );
2835
2884
scratch = secp256k1_scratch_create (& ctx -> error_callback , 0 , scratch_size + STRAUSS_SCRATCH_OBJECTS * ALIGNMENT );
2836
2885
}
2837
- CHECK (secp256k1_ecmult_multi_var (& ctx -> ecmult_ctx , scratch , & r , & scG , ecmult_multi_callback , & data , i ));
2838
-
2839
- /* compute running result */
2840
- secp256k1_gej_set_ge (& ptgj , & pt [i - 1 ]);
2841
- secp256k1_ecmult (& ctx -> ecmult_ctx , & ptgj , & ptgj , & sc [i - 1 ], NULL );
2842
- secp256k1_gej_add_var (& r2 , & r2 , & ptgj , NULL );
2843
-
2844
- secp256k1_gej_neg (& r , & r );
2886
+ CHECK (secp256k1_ecmult_multi_var (& ctx -> ecmult_ctx , scratch , & r , & scG , ecmult_multi_callback , & data , n_points ));
2845
2887
secp256k1_gej_add_var (& r , & r , & r2 , NULL );
2846
2888
CHECK (secp256k1_gej_is_infinity (& r ));
2847
2889
secp256k1_scratch_destroy (scratch );
2848
2890
}
2849
-
2850
- scratch = secp256k1_scratch_create (& ctx -> error_callback , 0 , secp256k1_strauss_scratch_size (n_points ) + STRAUSS_SCRATCH_OBJECTS * ALIGNMENT );
2851
-
2852
- for (i = 0 ; i < (int )(sizeof (test_n_points ) / sizeof (test_n_points [0 ])); i ++ ) {
2853
- secp256k1_gej ptgj ;
2854
- CHECK (secp256k1_ecmult_multi_var (& ctx -> ecmult_ctx , scratch , & r , & scG , ecmult_multi_callback , & data , test_n_points [i ]- 1 ));
2855
- secp256k1_gej_set_infinity (& r2 );
2856
- secp256k1_gej_add_var (& r2 , & r2 , & r , NULL );
2857
- CHECK (secp256k1_ecmult_multi_var (& ctx -> ecmult_ctx , scratch , & r , & scG , ecmult_multi_callback , & data , test_n_points [i ]));
2858
- secp256k1_gej_set_ge (& ptgj , & pt [test_n_points [i ]- 1 ]);
2859
- secp256k1_ecmult (& ctx -> ecmult_ctx , & ptgj , & ptgj , & sc [test_n_points [i ]- 1 ], NULL );
2860
- secp256k1_gej_add_var (& r2 , & r2 , & ptgj , NULL );
2861
-
2862
- secp256k1_gej_neg (& r , & r );
2863
- secp256k1_gej_add_var (& r , & r , & r2 , NULL );
2864
- CHECK (secp256k1_gej_is_infinity (& r ));
2865
- }
2866
-
2867
- secp256k1_scratch_destroy (scratch );
2868
2891
free (sc );
2869
2892
free (pt );
2870
2893
}
2871
2894
2872
2895
void run_ecmult_multi_tests (void ) {
2873
2896
secp256k1_scratch * scratch ;
2874
2897
2898
+ test_secp256k1_pippenger_bucket_window_inv ();
2899
+ test_ecmult_multi_pippenger_max_points ();
2875
2900
scratch = secp256k1_scratch_create (& ctx -> error_callback , 0 , 819200 );
2876
- test_ecmult_multi (scratch , & secp256k1_ecmult_multi_var );
2877
- test_ecmult_multi (scratch , & secp256k1_ecmult_pippenger_batch_single );
2878
- test_ecmult_multi (scratch , & secp256k1_ecmult_strauss_batch_single );
2901
+ test_ecmult_multi (scratch , secp256k1_ecmult_multi_var );
2902
+ test_ecmult_multi (scratch , secp256k1_ecmult_pippenger_batch_single );
2903
+ test_ecmult_multi (scratch , secp256k1_ecmult_strauss_batch_single );
2904
+ secp256k1_scratch_destroy (scratch );
2905
+
2906
+ /* Run test_ecmult_multi with space for exactly one point */
2907
+ scratch = secp256k1_scratch_create (& ctx -> error_callback , 0 , secp256k1_strauss_scratch_size (1 ) + STRAUSS_SCRATCH_OBJECTS * ALIGNMENT );
2908
+ test_ecmult_multi (scratch , secp256k1_ecmult_multi_var );
2879
2909
secp256k1_scratch_destroy (scratch );
2880
2910
2881
2911
test_ecmult_multi_batching ();
0 commit comments