@@ -3690,37 +3690,89 @@ void run_wnaf(void) {
36903690    CHECK (secp256k1_scalar_is_zero (& n ));
36913691}
36923692
3693+ static  int  test_ecmult_accumulate_cb (secp256k1_scalar *  sc , secp256k1_ge *  pt , size_t  idx , void *  data ) {
3694+     const  secp256k1_scalar *  indata  =  (const  secp256k1_scalar * )data ;
3695+     * sc  =  * indata ;
3696+     * pt  =  secp256k1_ge_const_g ;
3697+     CHECK (idx  ==  0 );
3698+     return  1 ;
3699+ }
3700+ 
3701+ void  test_ecmult_accumulate (secp256k1_sha256 *  acc , const  secp256k1_scalar *  x , secp256k1_scratch *  scratch ) {
3702+     /* Compute x*G in 6 different ways, serialize it uncompressed, and feed it into acc. */ 
3703+     secp256k1_gej  rj1 , rj2 , rj3 , rj4 , rj5 , rj6 , gj , infj ;
3704+     secp256k1_ge  r ;
3705+     const  secp256k1_scalar  zero  =  SECP256K1_SCALAR_CONST (0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 );
3706+     unsigned char   bytes [65 ];
3707+     size_t  size  =  65 ;
3708+     secp256k1_gej_set_ge (& gj , & secp256k1_ge_const_g );
3709+     secp256k1_gej_set_infinity (& infj );
3710+     secp256k1_ecmult_gen (& ctx -> ecmult_gen_ctx , & rj1 , x );
3711+     secp256k1_ecmult (& ctx -> ecmult_ctx , & rj2 , & gj , x , & zero );
3712+     secp256k1_ecmult (& ctx -> ecmult_ctx , & rj3 , & infj , & zero , x );
3713+     secp256k1_ecmult_multi_var (NULL , & ctx -> ecmult_ctx , scratch , & rj4 , x , NULL , NULL , 0 );
3714+     secp256k1_ecmult_multi_var (NULL , & ctx -> ecmult_ctx , scratch , & rj5 , & zero , test_ecmult_accumulate_cb , (void * )x , 1 );
3715+     secp256k1_ecmult_const (& rj6 , & secp256k1_ge_const_g , x , 256 );
3716+     secp256k1_ge_set_gej_var (& r , & rj1 );
3717+     ge_equals_gej (& r , & rj2 );
3718+     ge_equals_gej (& r , & rj3 );
3719+     ge_equals_gej (& r , & rj4 );
3720+     ge_equals_gej (& r , & rj5 );
3721+     ge_equals_gej (& r , & rj6 );
3722+     if  (secp256k1_ge_is_infinity (& r )) {
3723+         /* Store infinity as 0x00 */ 
3724+         const  unsigned char   zerobyte [1 ] =  {0 };
3725+         secp256k1_sha256_write (acc , zerobyte , 1 );
3726+     } else  {
3727+         /* Store other points using their uncompressed serialization. */ 
3728+         secp256k1_eckey_pubkey_serialize (& r , bytes , & size , 0 );
3729+         CHECK (size  ==  65 );
3730+         secp256k1_sha256_write (acc , bytes , size );
3731+     }
3732+ }
3733+ 
36933734void  test_ecmult_constants (void ) {
3694-     /* Test ecmult_gen() for [0..36) and [order-36..0). */ 
3735+     /* Test ecmult_gen for: 
3736+      * - For i in 0..36: 
3737+      *   - Key i 
3738+      *   - Key -i 
3739+      * - For i in 0..255: 
3740+      *   - For j in 1..255 (only odd values): 
3741+      *     - Key (j*2^i) mod order 
3742+      */ 
36953743    secp256k1_scalar  x ;
3696-     secp256k1_gej  r ;
3697-     secp256k1_ge  ng ;
3698-     int  i ;
3699-     int  j ;
3700-     secp256k1_ge_neg (& ng , & secp256k1_ge_const_g );
3701-     for  (i  =  0 ; i  <  36 ; i ++  ) {
3702-         secp256k1_scalar_set_int (& x , i );
3703-         secp256k1_ecmult_gen (& ctx -> ecmult_gen_ctx , & r , & x );
3704-         for  (j  =  0 ; j  <  i ; j ++ ) {
3705-             if  (j  ==  i  -  1 ) {
3706-                 ge_equals_gej (& secp256k1_ge_const_g , & r );
3707-             }
3708-             secp256k1_gej_add_ge (& r , & r , & ng );
3709-         }
3710-         CHECK (secp256k1_gej_is_infinity (& r ));
3711-     }
3712-     for  (i  =  1 ; i  <= 36 ; i ++  ) {
3744+     secp256k1_sha256  acc ;
3745+     unsigned char   b32 [32 ];
3746+     int  i , j ;
3747+     secp256k1_scratch_space  * scratch  =  secp256k1_scratch_space_create (ctx , 65536 );
3748+ 
3749+     /* Expected hash of all the computed points; created with an independent 
3750+      * implementation. */ 
3751+     static  const  unsigned char   expected32 [32 ] =  {
3752+         0xe4 , 0x71 , 0x1b , 0x4d , 0x14 , 0x1e , 0x68 , 0x48 ,
3753+         0xb7 , 0xaf , 0x47 , 0x2b , 0x4c , 0xd2 , 0x04 , 0x14 ,
3754+         0x3a , 0x75 , 0x87 , 0x60 , 0x1a , 0xf9 , 0x63 , 0x60 ,
3755+         0xd0 , 0xcb , 0x1f , 0xaa , 0x85 , 0x9a , 0xb7 , 0xb4 
3756+     };
3757+     secp256k1_sha256_initialize (& acc );
3758+     for  (i  =  0 ; i  <= 36 ; ++ i ) {
37133759        secp256k1_scalar_set_int (& x , i );
3760+         test_ecmult_accumulate (& acc , & x , scratch );
37143761        secp256k1_scalar_negate (& x , & x );
3715-         secp256k1_ecmult_gen (& ctx -> ecmult_gen_ctx , & r , & x );
3716-         for  (j  =  0 ; j  <  i ; j ++ ) {
3717-             if  (j  ==  i  -  1 ) {
3718-                 ge_equals_gej (& ng , & r );
3719-             }
3720-             secp256k1_gej_add_ge (& r , & r , & secp256k1_ge_const_g );
3762+         test_ecmult_accumulate (& acc , & x , scratch );
3763+     };
3764+     for  (i  =  0 ; i  <  256 ; ++ i ) {
3765+         for  (j  =  1 ; j  <  256 ; j  +=  2 ) {
3766+             int  k ;
3767+             secp256k1_scalar_set_int (& x , j );
3768+             for  (k  =  0 ; k  <  i ; ++ k ) secp256k1_scalar_add (& x , & x , & x );
3769+             test_ecmult_accumulate (& acc , & x , scratch );
37213770        }
3722-         CHECK (secp256k1_gej_is_infinity (& r ));
37233771    }
3772+     secp256k1_sha256_finalize (& acc , b32 );
3773+     CHECK (secp256k1_memcmp_var (b32 , expected32 , 32 ) ==  0 );
3774+ 
3775+     secp256k1_scratch_space_destroy (ctx , scratch );
37243776}
37253777
37263778void  run_ecmult_constants (void ) {
0 commit comments