@@ -2287,6 +2287,111 @@ void run_ec_combine(void) {
2287
2287
}
2288
2288
}
2289
2289
2290
+ int test_ec_commit_seckey (unsigned char * seckey , secp256k1_pubkey * commitment ) {
2291
+ /* Return if seckey is the discrete log of commitment */
2292
+ secp256k1_pubkey pubkey_tmp ;
2293
+ return secp256k1_ec_pubkey_create (ctx , & pubkey_tmp , seckey ) == 1
2294
+ && memcmp (& pubkey_tmp , commitment , sizeof (pubkey_tmp )) == 0 ;
2295
+ }
2296
+
2297
+ void test_ec_commit (void ) {
2298
+ unsigned char seckey [32 ];
2299
+ secp256k1_pubkey pubkey ;
2300
+ secp256k1_pubkey commitment ;
2301
+ unsigned char data [32 ];
2302
+
2303
+ /* Create random keypair */
2304
+ secp256k1_rand256 (seckey );
2305
+ CHECK (secp256k1_ec_pubkey_create (ctx , & pubkey , seckey ));
2306
+ /* Create random data */
2307
+ {
2308
+ secp256k1_scalar d ;
2309
+ random_scalar_order_test (& d );
2310
+ secp256k1_scalar_get_b32 (data , & d );
2311
+ }
2312
+ /* Commit to data and verify */
2313
+ CHECK (secp256k1_ec_commit (ctx , & commitment , & pubkey , data , 32 ));
2314
+ CHECK (secp256k1_ec_commit_verify (ctx , & commitment , & pubkey , data , 32 ));
2315
+ CHECK (secp256k1_ec_commit_seckey (ctx , seckey , & pubkey , data , 32 ));
2316
+ CHECK (test_ec_commit_seckey (seckey , & commitment ) == 1 );
2317
+
2318
+ /* Check that verification fails with different data */
2319
+ CHECK (secp256k1_ec_commit_verify (ctx , & commitment , & pubkey , data , 31 ) == 0 );
2320
+ }
2321
+
2322
+ void test_ec_commit_api (void ) {
2323
+ unsigned char seckey [32 ];
2324
+ secp256k1_pubkey pubkey ;
2325
+ secp256k1_pubkey commitment ;
2326
+ unsigned char data [32 ];
2327
+ int32_t ecount ;
2328
+
2329
+ memset (data , 23 , sizeof (data ));
2330
+ secp256k1_context_set_illegal_callback (ctx , counting_illegal_callback_fn , & ecount );
2331
+
2332
+ /* Create random keypair */
2333
+ secp256k1_rand256 (seckey );
2334
+ CHECK (secp256k1_ec_pubkey_create (ctx , & pubkey , seckey ));
2335
+
2336
+ ecount = 0 ;
2337
+ CHECK (secp256k1_ec_commit (ctx , NULL , & pubkey , data , 1 ) == 0 );
2338
+ CHECK (ecount == 1 );
2339
+ CHECK (secp256k1_ec_commit (ctx , & commitment , NULL , data , 1 ) == 0 );
2340
+ CHECK (ecount == 2 );
2341
+ CHECK (secp256k1_ec_commit (ctx , & commitment , & pubkey , NULL , 1 ) == 0 );
2342
+ CHECK (ecount == 3 );
2343
+ CHECK (secp256k1_ec_commit (ctx , & commitment , & pubkey , data , 1 ) == 1 );
2344
+ /* The same pubkey can be both input and output of the function */
2345
+ {
2346
+ secp256k1_pubkey pubkey_tmp = pubkey ;
2347
+ CHECK (secp256k1_ec_commit (ctx , & pubkey_tmp , & pubkey_tmp , data , 1 ) == 1 );
2348
+ CHECK (memcmp (commitment .data , pubkey_tmp .data , sizeof (commitment .data )) == 0 );
2349
+ }
2350
+
2351
+ ecount = 0 ;
2352
+ CHECK (secp256k1_ec_commit_seckey (ctx , NULL , & pubkey , data , 1 ) == 0 );
2353
+ CHECK (ecount == 1 );
2354
+ /* If the pubkey is not provided it will be computed from seckey */
2355
+ CHECK (secp256k1_ec_commit_seckey (ctx , seckey , NULL , data , 1 ) == 1 );
2356
+ CHECK (test_ec_commit_seckey (seckey , & commitment ) == 1 );
2357
+ /* pubkey is not provided but seckey overflows */
2358
+ {
2359
+ unsigned char overflowed_seckey [32 ];
2360
+ memset (overflowed_seckey , 0xFF , sizeof (overflowed_seckey ));
2361
+ CHECK (secp256k1_ec_commit_seckey (ctx , overflowed_seckey , NULL , data , 1 ) == 0 );
2362
+ }
2363
+ CHECK (secp256k1_ec_commit_seckey (ctx , seckey , & pubkey , NULL , 1 ) == 0 );
2364
+ CHECK (ecount == 2 );
2365
+
2366
+ ecount = 0 ;
2367
+ CHECK (secp256k1_ec_commit_verify (ctx , & commitment , & pubkey , data , 1 ) == 1 );
2368
+ CHECK (secp256k1_ec_commit_verify (ctx , NULL , & pubkey , data , 1 ) == 0 );
2369
+ CHECK (ecount == 1 );
2370
+ CHECK (secp256k1_ec_commit_verify (ctx , & commitment , NULL , data , 1 ) == 0 );
2371
+ CHECK (ecount == 2 );
2372
+ CHECK (secp256k1_ec_commit_verify (ctx , & commitment , & pubkey , NULL , 1 ) == 0 );
2373
+ CHECK (ecount == 3 );
2374
+
2375
+ /* Commitment to 0-len data should not modify secret or public key */
2376
+ CHECK (secp256k1_ec_commit (ctx , & commitment , & pubkey , data , 0 ));
2377
+ CHECK (secp256k1_ec_commit_verify (ctx , & commitment , & pubkey , data , 0 ));
2378
+ CHECK (memcmp (& pubkey .data , & commitment .data , sizeof (pubkey .data )) == 0 );
2379
+ {
2380
+ unsigned char seckey_tmp [32 ];
2381
+ memcpy (seckey_tmp , seckey , 32 );
2382
+ CHECK (secp256k1_ec_commit_seckey (ctx , seckey_tmp , & pubkey , data , 0 ));
2383
+ CHECK (memcmp (seckey , seckey_tmp , sizeof (seckey )) == 0 );
2384
+ }
2385
+ }
2386
+
2387
+ void run_ec_commit (void ) {
2388
+ int i ;
2389
+ for (i = 0 ; i < count * 8 ; i ++ ) {
2390
+ test_ec_commit ();
2391
+ }
2392
+ test_ec_commit_api ();
2393
+ }
2394
+
2290
2395
void test_group_decompress (const secp256k1_fe * x ) {
2291
2396
/* The input itself, normalized. */
2292
2397
secp256k1_fe fex = * x ;
@@ -5106,6 +5211,7 @@ int main(int argc, char **argv) {
5106
5211
run_ecmult_const_tests ();
5107
5212
run_ecmult_multi_tests ();
5108
5213
run_ec_combine ();
5214
+ run_ec_commit ();
5109
5215
5110
5216
/* endomorphism tests */
5111
5217
#ifdef USE_ENDOMORPHISM
0 commit comments