@@ -32,11 +32,43 @@ static int COUNT = 64;
3232static secp256k1_context * CTX = NULL ;
3333static secp256k1_context * STATIC_CTX = NULL ;
3434
35+ static int all_bytes_equal (const void * s , unsigned char value , size_t n ) {
36+ const unsigned char * p = s ;
37+ size_t i ;
38+
39+ for (i = 0 ; i < n ; i ++ ) {
40+ if (p [i ] != value ) {
41+ return 0 ;
42+ }
43+ }
44+ return 1 ;
45+ }
46+
47+ /* TODO Use CHECK_ILLEGAL(_VOID) everywhere and get rid of the uncounting callback */
48+ /* CHECK that expr_or_stmt calls the illegal callback of ctx exactly once
49+ *
50+ * For checking functions that use ARG_CHECK_VOID */
51+ #define CHECK_ILLEGAL_VOID (ctx , expr_or_stmt ) do { \
52+ int32_t _calls_to_illegal_callback = 0; \
53+ secp256k1_callback _saved_illegal_cb = ctx->illegal_callback; \
54+ secp256k1_context_set_illegal_callback(ctx, \
55+ counting_illegal_callback_fn, &_calls_to_illegal_callback); \
56+ { expr_or_stmt; } \
57+ ctx->illegal_callback = _saved_illegal_cb; \
58+ CHECK(_calls_to_illegal_callback == 1); \
59+ } while(0);
60+
61+ /* CHECK that expr calls the illegal callback of ctx exactly once and that expr == 0
62+ *
63+ * For checking functions that use ARG_CHECK */
64+ #define CHECK_ILLEGAL (ctx , expr ) CHECK_ILLEGAL_VOID(ctx, CHECK((expr) == 0))
65+
3566static void counting_illegal_callback_fn (const char * str , void * data ) {
3667 /* Dummy callback function that just counts. */
3768 int32_t * p ;
3869 (void )str ;
3970 p = data ;
71+ CHECK (* p != INT32_MAX );
4072 (* p )++ ;
4173}
4274
@@ -45,6 +77,7 @@ static void uncounting_illegal_callback_fn(const char* str, void* data) {
4577 int32_t * p ;
4678 (void )str ;
4779 p = data ;
80+ CHECK (* p != INT32_MIN );
4881 (* p )-- ;
4982}
5083
@@ -229,31 +262,61 @@ static void run_ec_illegal_argument_tests(void) {
229262 secp256k1_context_set_illegal_callback (CTX , NULL , NULL );
230263}
231264
232- static void run_static_context_tests (void ) {
233- int32_t dummy = 0 ;
234-
265+ static void run_static_context_tests (int use_prealloc ) {
235266 /* Check that deprecated secp256k1_context_no_precomp is an alias to secp256k1_context_static. */
236267 CHECK (secp256k1_context_no_precomp == secp256k1_context_static );
237268
238- /* check if sizes for cloning are consistent */
239- CHECK ( secp256k1_context_preallocated_clone_size ( STATIC_CTX ) >= sizeof ( secp256k1_context )) ;
269+ {
270+ unsigned char seed [ 32 ] = { 0x17 } ;
240271
241- /* Verify that setting and resetting illegal callback works */
242- secp256k1_context_set_illegal_callback (STATIC_CTX , counting_illegal_callback_fn , & dummy );
243- CHECK (STATIC_CTX -> illegal_callback .fn == counting_illegal_callback_fn );
244- secp256k1_context_set_illegal_callback (STATIC_CTX , NULL , NULL );
245- CHECK (STATIC_CTX -> illegal_callback .fn == secp256k1_default_illegal_callback_fn );
272+ /* Randomizing secp256k1_context_static is not supported. */
273+ CHECK_ILLEGAL (STATIC_CTX , secp256k1_context_randomize (STATIC_CTX , seed ));
274+ CHECK_ILLEGAL (STATIC_CTX , secp256k1_context_randomize (STATIC_CTX , NULL ));
275+
276+ /* Destroying or cloning secp256k1_context_static is not supported. */
277+ if (use_prealloc ) {
278+ CHECK_ILLEGAL (STATIC_CTX , secp256k1_context_preallocated_clone_size (STATIC_CTX ));
279+ {
280+ secp256k1_context * my_static_ctx = malloc (sizeof (* STATIC_CTX ));
281+ CHECK (my_static_ctx != NULL );
282+ memset (my_static_ctx , 0x2a , sizeof (* my_static_ctx ));
283+ CHECK_ILLEGAL (STATIC_CTX , secp256k1_context_preallocated_clone (STATIC_CTX , my_static_ctx ));
284+ CHECK (all_bytes_equal (my_static_ctx , 0x2a , sizeof (* my_static_ctx )));
285+ free (my_static_ctx );
286+ }
287+ CHECK_ILLEGAL_VOID (STATIC_CTX , secp256k1_context_preallocated_destroy (STATIC_CTX ));
288+ } else {
289+ CHECK_ILLEGAL (STATIC_CTX , secp256k1_context_clone (STATIC_CTX ));
290+ CHECK_ILLEGAL_VOID (STATIC_CTX , secp256k1_context_destroy (STATIC_CTX ));
291+ }
292+ }
293+
294+ {
295+ /* Verify that setting and resetting illegal callback works */
296+ int32_t dummy = 0 ;
297+ secp256k1_context_set_illegal_callback (STATIC_CTX , counting_illegal_callback_fn , & dummy );
298+ CHECK (STATIC_CTX -> illegal_callback .fn == counting_illegal_callback_fn );
299+ CHECK (STATIC_CTX -> illegal_callback .data == & dummy );
300+ secp256k1_context_set_illegal_callback (STATIC_CTX , NULL , NULL );
301+ CHECK (STATIC_CTX -> illegal_callback .fn == secp256k1_default_illegal_callback_fn );
302+ CHECK (STATIC_CTX -> illegal_callback .data == NULL );
303+ }
246304}
247305
248306static void run_proper_context_tests (int use_prealloc ) {
249307 int32_t dummy = 0 ;
250- secp256k1_context * my_ctx ;
308+ secp256k1_context * my_ctx , * my_ctx_fresh ;
251309 void * my_ctx_prealloc = NULL ;
310+ unsigned char seed [32 ] = {0x17 };
252311
253312 secp256k1_gej pubj ;
254313 secp256k1_ge pub ;
255314 secp256k1_scalar msg , key , nonce ;
256315 secp256k1_scalar sigr , sigs ;
316+
317+ /* Fresh reference context for comparison */
318+ my_ctx_fresh = secp256k1_context_create (SECP256K1_CONTEXT_NONE );
319+
257320 if (use_prealloc ) {
258321 my_ctx_prealloc = malloc (secp256k1_context_preallocated_size (SECP256K1_CONTEXT_NONE ));
259322 CHECK (my_ctx_prealloc != NULL );
@@ -262,6 +325,13 @@ static void run_proper_context_tests(int use_prealloc) {
262325 my_ctx = secp256k1_context_create (SECP256K1_CONTEXT_NONE );
263326 }
264327
328+ /* Randomize and reset randomization */
329+ CHECK (context_eq (my_ctx , my_ctx_fresh ));
330+ CHECK (secp256k1_context_randomize (my_ctx , seed ) == 1 );
331+ CHECK (!context_eq (my_ctx , my_ctx_fresh ));
332+ CHECK (secp256k1_context_randomize (my_ctx , NULL ) == 1 );
333+ CHECK (context_eq (my_ctx , my_ctx_fresh ));
334+
265335 /* set error callback (to a function that still aborts in case malloc() fails in secp256k1_context_clone() below) */
266336 secp256k1_context_set_error_callback (my_ctx , secp256k1_default_illegal_callback_fn , NULL );
267337 CHECK (my_ctx -> error_callback .fn != secp256k1_default_error_callback_fn );
@@ -276,16 +346,33 @@ static void run_proper_context_tests(int use_prealloc) {
276346
277347 if (use_prealloc ) {
278348 /* clone into a non-preallocated context and then again into a new preallocated one. */
279- ctx_tmp = my_ctx ; my_ctx = secp256k1_context_clone (my_ctx ); secp256k1_context_preallocated_destroy (ctx_tmp );
280- free (my_ctx_prealloc ); my_ctx_prealloc = malloc (secp256k1_context_preallocated_size (SECP256K1_CONTEXT_NONE )); CHECK (my_ctx_prealloc != NULL );
281- ctx_tmp = my_ctx ; my_ctx = secp256k1_context_preallocated_clone (my_ctx , my_ctx_prealloc ); secp256k1_context_destroy (ctx_tmp );
349+ ctx_tmp = my_ctx ;
350+ my_ctx = secp256k1_context_clone (my_ctx );
351+ CHECK (context_eq (ctx_tmp , my_ctx ));
352+ secp256k1_context_preallocated_destroy (ctx_tmp );
353+
354+ free (my_ctx_prealloc );
355+ my_ctx_prealloc = malloc (secp256k1_context_preallocated_size (SECP256K1_CONTEXT_NONE ));
356+ CHECK (my_ctx_prealloc != NULL );
357+ ctx_tmp = my_ctx ;
358+ my_ctx = secp256k1_context_preallocated_clone (my_ctx , my_ctx_prealloc );
359+ CHECK (context_eq (ctx_tmp , my_ctx ));
360+ secp256k1_context_destroy (ctx_tmp );
282361 } else {
283362 /* clone into a preallocated context and then again into a new non-preallocated one. */
284363 void * prealloc_tmp ;
285364
286- prealloc_tmp = malloc (secp256k1_context_preallocated_size (SECP256K1_CONTEXT_NONE )); CHECK (prealloc_tmp != NULL );
287- ctx_tmp = my_ctx ; my_ctx = secp256k1_context_preallocated_clone (my_ctx , prealloc_tmp ); secp256k1_context_destroy (ctx_tmp );
288- ctx_tmp = my_ctx ; my_ctx = secp256k1_context_clone (my_ctx ); secp256k1_context_preallocated_destroy (ctx_tmp );
365+ prealloc_tmp = malloc (secp256k1_context_preallocated_size (SECP256K1_CONTEXT_NONE ));
366+ CHECK (prealloc_tmp != NULL );
367+ ctx_tmp = my_ctx ;
368+ my_ctx = secp256k1_context_preallocated_clone (my_ctx , prealloc_tmp );
369+ CHECK (context_eq (ctx_tmp , my_ctx ));
370+ secp256k1_context_destroy (ctx_tmp );
371+
372+ ctx_tmp = my_ctx ;
373+ my_ctx = secp256k1_context_clone (my_ctx );
374+ CHECK (context_eq (ctx_tmp , my_ctx ));
375+ secp256k1_context_preallocated_destroy (ctx_tmp );
289376 free (prealloc_tmp );
290377 }
291378 }
@@ -296,12 +383,16 @@ static void run_proper_context_tests(int use_prealloc) {
296383 /* And that it resets back to default. */
297384 secp256k1_context_set_error_callback (my_ctx , NULL , NULL );
298385 CHECK (my_ctx -> error_callback .fn == secp256k1_default_error_callback_fn );
386+ CHECK (context_eq (my_ctx , my_ctx_fresh ));
299387
300388 /* Verify that setting and resetting illegal callback works */
301389 secp256k1_context_set_illegal_callback (my_ctx , counting_illegal_callback_fn , & dummy );
302390 CHECK (my_ctx -> illegal_callback .fn == counting_illegal_callback_fn );
391+ CHECK (my_ctx -> illegal_callback .data == & dummy );
303392 secp256k1_context_set_illegal_callback (my_ctx , NULL , NULL );
304393 CHECK (my_ctx -> illegal_callback .fn == secp256k1_default_illegal_callback_fn );
394+ CHECK (my_ctx -> illegal_callback .data == NULL );
395+ CHECK (context_eq (my_ctx , my_ctx_fresh ));
305396
306397 /*** attempt to use them ***/
307398 random_scalar_order_test (& msg );
@@ -327,6 +418,8 @@ static void run_proper_context_tests(int use_prealloc) {
327418 } else {
328419 secp256k1_context_destroy (my_ctx );
329420 }
421+ secp256k1_context_destroy (my_ctx_fresh );
422+
330423 /* Defined as no-op. */
331424 secp256k1_context_destroy (NULL );
332425 secp256k1_context_preallocated_destroy (NULL );
@@ -7389,9 +7482,8 @@ int main(int argc, char **argv) {
73897482 run_selftest_tests ();
73907483
73917484 /* context tests */
7392- run_proper_context_tests (0 );
7393- run_proper_context_tests (1 );
7394- run_static_context_tests ();
7485+ run_proper_context_tests (0 ); run_proper_context_tests (1 );
7486+ run_static_context_tests (0 ); run_static_context_tests (1 );
73957487 run_deprecated_context_flags_test ();
73967488
73977489 /* scratch tests */
0 commit comments