@@ -4489,37 +4489,89 @@ void run_wnaf(void) {
44894489 CHECK (secp256k1_scalar_is_zero (& n ));
44904490}
44914491
4492+ static int test_ecmult_accumulate_cb (secp256k1_scalar * sc , secp256k1_ge * pt , size_t idx , void * data ) {
4493+ const secp256k1_scalar * indata = (const secp256k1_scalar * )data ;
4494+ * sc = * indata ;
4495+ * pt = secp256k1_ge_const_g ;
4496+ CHECK (idx == 0 );
4497+ return 1 ;
4498+ }
4499+
4500+ void test_ecmult_accumulate (secp256k1_sha256 * acc , const secp256k1_scalar * x , secp256k1_scratch * scratch ) {
4501+ /* Compute x*G in 6 different ways, serialize it uncompressed, and feed it into acc. */
4502+ secp256k1_gej rj1 , rj2 , rj3 , rj4 , rj5 , rj6 , gj , infj ;
4503+ secp256k1_ge r ;
4504+ const secp256k1_scalar zero = SECP256K1_SCALAR_CONST (0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 );
4505+ unsigned char bytes [65 ];
4506+ size_t size = 65 ;
4507+ secp256k1_gej_set_ge (& gj , & secp256k1_ge_const_g );
4508+ secp256k1_gej_set_infinity (& infj );
4509+ secp256k1_ecmult_gen (& ctx -> ecmult_gen_ctx , & rj1 , x );
4510+ secp256k1_ecmult (& rj2 , & gj , x , & zero );
4511+ secp256k1_ecmult (& rj3 , & infj , & zero , x );
4512+ secp256k1_ecmult_multi_var (NULL , scratch , & rj4 , x , NULL , NULL , 0 );
4513+ secp256k1_ecmult_multi_var (NULL , scratch , & rj5 , & zero , test_ecmult_accumulate_cb , (void * )x , 1 );
4514+ secp256k1_ecmult_const (& rj6 , & secp256k1_ge_const_g , x , 256 );
4515+ secp256k1_ge_set_gej_var (& r , & rj1 );
4516+ ge_equals_gej (& r , & rj2 );
4517+ ge_equals_gej (& r , & rj3 );
4518+ ge_equals_gej (& r , & rj4 );
4519+ ge_equals_gej (& r , & rj5 );
4520+ ge_equals_gej (& r , & rj6 );
4521+ if (secp256k1_ge_is_infinity (& r )) {
4522+ /* Store infinity as 0x00 */
4523+ const unsigned char zerobyte [1 ] = {0 };
4524+ secp256k1_sha256_write (acc , zerobyte , 1 );
4525+ } else {
4526+ /* Store other points using their uncompressed serialization. */
4527+ secp256k1_eckey_pubkey_serialize (& r , bytes , & size , 0 );
4528+ CHECK (size == 65 );
4529+ secp256k1_sha256_write (acc , bytes , size );
4530+ }
4531+ }
4532+
44924533void test_ecmult_constants (void ) {
4493- /* Test ecmult_gen() for [0..36) and [order-36..0). */
4534+ /* Test ecmult_gen for:
4535+ * - For i in 0..36:
4536+ * - Key i
4537+ * - Key -i
4538+ * - For i in 0..255:
4539+ * - For j in 1..255 (only odd values):
4540+ * - Key (j*2^i) mod order
4541+ */
44944542 secp256k1_scalar x ;
4495- secp256k1_gej r ;
4496- secp256k1_ge ng ;
4497- int i ;
4498- int j ;
4499- secp256k1_ge_neg (& ng , & secp256k1_ge_const_g );
4500- for (i = 0 ; i < 36 ; i ++ ) {
4501- secp256k1_scalar_set_int (& x , i );
4502- secp256k1_ecmult_gen (& ctx -> ecmult_gen_ctx , & r , & x );
4503- for (j = 0 ; j < i ; j ++ ) {
4504- if (j == i - 1 ) {
4505- ge_equals_gej (& secp256k1_ge_const_g , & r );
4506- }
4507- secp256k1_gej_add_ge (& r , & r , & ng );
4508- }
4509- CHECK (secp256k1_gej_is_infinity (& r ));
4510- }
4511- for (i = 1 ; i <= 36 ; i ++ ) {
4543+ secp256k1_sha256 acc ;
4544+ unsigned char b32 [32 ];
4545+ int i , j ;
4546+ secp256k1_scratch_space * scratch = secp256k1_scratch_space_create (ctx , 65536 );
4547+
4548+ /* Expected hash of all the computed points; created with an independent
4549+ * implementation. */
4550+ static const unsigned char expected32 [32 ] = {
4551+ 0xe4 , 0x71 , 0x1b , 0x4d , 0x14 , 0x1e , 0x68 , 0x48 ,
4552+ 0xb7 , 0xaf , 0x47 , 0x2b , 0x4c , 0xd2 , 0x04 , 0x14 ,
4553+ 0x3a , 0x75 , 0x87 , 0x60 , 0x1a , 0xf9 , 0x63 , 0x60 ,
4554+ 0xd0 , 0xcb , 0x1f , 0xaa , 0x85 , 0x9a , 0xb7 , 0xb4
4555+ };
4556+ secp256k1_sha256_initialize (& acc );
4557+ for (i = 0 ; i <= 36 ; ++ i ) {
45124558 secp256k1_scalar_set_int (& x , i );
4559+ test_ecmult_accumulate (& acc , & x , scratch );
45134560 secp256k1_scalar_negate (& x , & x );
4514- secp256k1_ecmult_gen (& ctx -> ecmult_gen_ctx , & r , & x );
4515- for (j = 0 ; j < i ; j ++ ) {
4516- if (j == i - 1 ) {
4517- ge_equals_gej (& ng , & r );
4518- }
4519- secp256k1_gej_add_ge (& r , & r , & secp256k1_ge_const_g );
4561+ test_ecmult_accumulate (& acc , & x , scratch );
4562+ };
4563+ for (i = 0 ; i < 256 ; ++ i ) {
4564+ for (j = 1 ; j < 256 ; j += 2 ) {
4565+ int k ;
4566+ secp256k1_scalar_set_int (& x , j );
4567+ for (k = 0 ; k < i ; ++ k ) secp256k1_scalar_add (& x , & x , & x );
4568+ test_ecmult_accumulate (& acc , & x , scratch );
45204569 }
4521- CHECK (secp256k1_gej_is_infinity (& r ));
45224570 }
4571+ secp256k1_sha256_finalize (& acc , b32 );
4572+ CHECK (secp256k1_memcmp_var (b32 , expected32 , 32 ) == 0 );
4573+
4574+ secp256k1_scratch_space_destroy (ctx , scratch );
45234575}
45244576
45254577void run_ecmult_constants (void ) {
0 commit comments