@@ -137,23 +137,47 @@ void random_scalar_order(secp256k1_scalar *num) {
137137 } while (1 );
138138}
139139
140- void run_context_tests (void ) {
140+ void run_context_tests (int use_prealloc ) {
141141 secp256k1_pubkey pubkey ;
142142 secp256k1_pubkey zero_pubkey ;
143143 secp256k1_ecdsa_signature sig ;
144144 unsigned char ctmp [32 ];
145145 int32_t ecount ;
146146 int32_t ecount2 ;
147- secp256k1_context * none = secp256k1_context_create (SECP256K1_CONTEXT_NONE );
148- secp256k1_context * sign = secp256k1_context_create (SECP256K1_CONTEXT_SIGN );
149- secp256k1_context * vrfy = secp256k1_context_create (SECP256K1_CONTEXT_VERIFY );
150- secp256k1_context * both = secp256k1_context_create (SECP256K1_CONTEXT_SIGN | SECP256K1_CONTEXT_VERIFY );
147+ secp256k1_context * none ;
148+ secp256k1_context * sign ;
149+ secp256k1_context * vrfy ;
150+ secp256k1_context * both ;
151+ void * none_prealloc = NULL ;
152+ void * sign_prealloc = NULL ;
153+ void * vrfy_prealloc = NULL ;
154+ void * both_prealloc = NULL ;
151155
152156 secp256k1_gej pubj ;
153157 secp256k1_ge pub ;
154158 secp256k1_scalar msg , key , nonce ;
155159 secp256k1_scalar sigr , sigs ;
156160
161+ if (use_prealloc ) {
162+ none_prealloc = malloc (secp256k1_context_preallocated_size (SECP256K1_CONTEXT_NONE ));
163+ sign_prealloc = malloc (secp256k1_context_preallocated_size (SECP256K1_CONTEXT_SIGN ));
164+ vrfy_prealloc = malloc (secp256k1_context_preallocated_size (SECP256K1_CONTEXT_VERIFY ));
165+ both_prealloc = malloc (secp256k1_context_preallocated_size (SECP256K1_CONTEXT_SIGN | SECP256K1_CONTEXT_VERIFY ));
166+ CHECK (none_prealloc != NULL );
167+ CHECK (sign_prealloc != NULL );
168+ CHECK (vrfy_prealloc != NULL );
169+ CHECK (both_prealloc != NULL );
170+ none = secp256k1_context_preallocated_create (none_prealloc , SECP256K1_CONTEXT_NONE );
171+ sign = secp256k1_context_preallocated_create (sign_prealloc , SECP256K1_CONTEXT_SIGN );
172+ vrfy = secp256k1_context_preallocated_create (vrfy_prealloc , SECP256K1_CONTEXT_VERIFY );
173+ both = secp256k1_context_preallocated_create (both_prealloc , SECP256K1_CONTEXT_SIGN | SECP256K1_CONTEXT_VERIFY );
174+ } else {
175+ none = secp256k1_context_create (SECP256K1_CONTEXT_NONE );
176+ sign = secp256k1_context_create (SECP256K1_CONTEXT_SIGN );
177+ vrfy = secp256k1_context_create (SECP256K1_CONTEXT_VERIFY );
178+ both = secp256k1_context_create (SECP256K1_CONTEXT_SIGN | SECP256K1_CONTEXT_VERIFY );
179+ }
180+
157181 memset (& zero_pubkey , 0 , sizeof (zero_pubkey ));
158182
159183 ecount = 0 ;
@@ -163,14 +187,57 @@ void run_context_tests(void) {
163187 secp256k1_context_set_error_callback (sign , counting_illegal_callback_fn , NULL );
164188 CHECK (vrfy -> error_callback .fn != sign -> error_callback .fn );
165189
190+ /* check if sizes for cloning are consistent */
191+ CHECK (secp256k1_context_preallocated_clone_size (none ) == secp256k1_context_preallocated_size (SECP256K1_CONTEXT_NONE ));
192+ CHECK (secp256k1_context_preallocated_clone_size (sign ) == secp256k1_context_preallocated_size (SECP256K1_CONTEXT_SIGN ));
193+ CHECK (secp256k1_context_preallocated_clone_size (vrfy ) == secp256k1_context_preallocated_size (SECP256K1_CONTEXT_VERIFY ));
194+ CHECK (secp256k1_context_preallocated_clone_size (both ) == secp256k1_context_preallocated_size (SECP256K1_CONTEXT_SIGN | SECP256K1_CONTEXT_VERIFY ));
195+
166196 /*** clone and destroy all of them to make sure cloning was complete ***/
167197 {
168198 secp256k1_context * ctx_tmp ;
169199
170- ctx_tmp = none ; none = secp256k1_context_clone (none ); secp256k1_context_destroy (ctx_tmp );
171- ctx_tmp = sign ; sign = secp256k1_context_clone (sign ); secp256k1_context_destroy (ctx_tmp );
172- ctx_tmp = vrfy ; vrfy = secp256k1_context_clone (vrfy ); secp256k1_context_destroy (ctx_tmp );
173- ctx_tmp = both ; both = secp256k1_context_clone (both ); secp256k1_context_destroy (ctx_tmp );
200+ if (use_prealloc ) {
201+ /* clone into a non-preallocated context and then again into a new preallocated one. */
202+ ctx_tmp = none ; none = secp256k1_context_clone (none ); secp256k1_context_preallocated_destroy (ctx_tmp );
203+ free (none_prealloc ); none_prealloc = malloc (secp256k1_context_preallocated_size (SECP256K1_CONTEXT_NONE )); CHECK (none_prealloc != NULL );
204+ ctx_tmp = none ; none = secp256k1_context_preallocated_clone (none , none_prealloc ); secp256k1_context_destroy (ctx_tmp );
205+
206+ ctx_tmp = sign ; sign = secp256k1_context_clone (sign ); secp256k1_context_preallocated_destroy (ctx_tmp );
207+ free (sign_prealloc ); sign_prealloc = malloc (secp256k1_context_preallocated_size (SECP256K1_CONTEXT_SIGN )); CHECK (sign_prealloc != NULL );
208+ ctx_tmp = sign ; sign = secp256k1_context_preallocated_clone (sign , sign_prealloc ); secp256k1_context_destroy (ctx_tmp );
209+
210+ ctx_tmp = vrfy ; vrfy = secp256k1_context_clone (vrfy ); secp256k1_context_preallocated_destroy (ctx_tmp );
211+ free (vrfy_prealloc ); vrfy_prealloc = malloc (secp256k1_context_preallocated_size (SECP256K1_CONTEXT_VERIFY )); CHECK (vrfy_prealloc != NULL );
212+ ctx_tmp = vrfy ; vrfy = secp256k1_context_preallocated_clone (vrfy , vrfy_prealloc ); secp256k1_context_destroy (ctx_tmp );
213+
214+ ctx_tmp = both ; both = secp256k1_context_clone (both ); secp256k1_context_preallocated_destroy (ctx_tmp );
215+ free (both_prealloc ); both_prealloc = malloc (secp256k1_context_preallocated_size (SECP256K1_CONTEXT_SIGN | SECP256K1_CONTEXT_VERIFY )); CHECK (both_prealloc != NULL );
216+ ctx_tmp = both ; both = secp256k1_context_preallocated_clone (both , both_prealloc ); secp256k1_context_destroy (ctx_tmp );
217+ } else {
218+ /* clone into a preallocated context and then again into a new non-preallocated one. */
219+ void * prealloc_tmp ;
220+
221+ prealloc_tmp = malloc (secp256k1_context_preallocated_size (SECP256K1_CONTEXT_NONE )); CHECK (prealloc_tmp != NULL );
222+ ctx_tmp = none ; none = secp256k1_context_preallocated_clone (none , prealloc_tmp ); secp256k1_context_destroy (ctx_tmp );
223+ ctx_tmp = none ; none = secp256k1_context_clone (none ); secp256k1_context_preallocated_destroy (ctx_tmp );
224+ free (prealloc_tmp );
225+
226+ prealloc_tmp = malloc (secp256k1_context_preallocated_size (SECP256K1_CONTEXT_SIGN )); CHECK (prealloc_tmp != NULL );
227+ ctx_tmp = sign ; sign = secp256k1_context_preallocated_clone (sign , prealloc_tmp ); secp256k1_context_destroy (ctx_tmp );
228+ ctx_tmp = sign ; sign = secp256k1_context_clone (sign ); secp256k1_context_preallocated_destroy (ctx_tmp );
229+ free (prealloc_tmp );
230+
231+ prealloc_tmp = malloc (secp256k1_context_preallocated_size (SECP256K1_CONTEXT_VERIFY )); CHECK (prealloc_tmp != NULL );
232+ ctx_tmp = vrfy ; vrfy = secp256k1_context_preallocated_clone (vrfy , prealloc_tmp ); secp256k1_context_destroy (ctx_tmp );
233+ ctx_tmp = vrfy ; vrfy = secp256k1_context_clone (vrfy ); secp256k1_context_preallocated_destroy (ctx_tmp );
234+ free (prealloc_tmp );
235+
236+ prealloc_tmp = malloc (secp256k1_context_preallocated_size (SECP256K1_CONTEXT_SIGN | SECP256K1_CONTEXT_VERIFY )); CHECK (prealloc_tmp != NULL );
237+ ctx_tmp = both ; both = secp256k1_context_preallocated_clone (both , prealloc_tmp ); secp256k1_context_destroy (ctx_tmp );
238+ ctx_tmp = both ; both = secp256k1_context_clone (both ); secp256k1_context_preallocated_destroy (ctx_tmp );
239+ free (prealloc_tmp );
240+ }
174241 }
175242
176243 /* Verify that the error callback makes it across the clone. */
@@ -243,12 +310,25 @@ void run_context_tests(void) {
243310 CHECK (secp256k1_ecdsa_sig_verify (& both -> ecmult_ctx , & sigr , & sigs , & pub , & msg ));
244311
245312 /* cleanup */
246- secp256k1_context_destroy (none );
247- secp256k1_context_destroy (sign );
248- secp256k1_context_destroy (vrfy );
249- secp256k1_context_destroy (both );
313+ if (use_prealloc ) {
314+ secp256k1_context_preallocated_destroy (none );
315+ secp256k1_context_preallocated_destroy (sign );
316+ secp256k1_context_preallocated_destroy (vrfy );
317+ secp256k1_context_preallocated_destroy (both );
318+ free (none_prealloc );
319+ free (sign_prealloc );
320+ free (vrfy_prealloc );
321+ free (both_prealloc );
322+ } else {
323+ secp256k1_context_destroy (none );
324+ secp256k1_context_destroy (sign );
325+ secp256k1_context_destroy (vrfy );
326+ secp256k1_context_destroy (both );
327+ }
250328 /* Defined as no-op. */
251329 secp256k1_context_destroy (NULL );
330+ secp256k1_context_preallocated_destroy (NULL );
331+
252332}
253333
254334void run_scratch_tests (void ) {
@@ -5058,7 +5138,8 @@ int main(int argc, char **argv) {
50585138 printf ("random seed = %02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x\n" , seed16 [0 ], seed16 [1 ], seed16 [2 ], seed16 [3 ], seed16 [4 ], seed16 [5 ], seed16 [6 ], seed16 [7 ], seed16 [8 ], seed16 [9 ], seed16 [10 ], seed16 [11 ], seed16 [12 ], seed16 [13 ], seed16 [14 ], seed16 [15 ]);
50595139
50605140 /* initialize */
5061- run_context_tests ();
5141+ run_context_tests (0 );
5142+ run_context_tests (1 );
50625143 run_scratch_tests ();
50635144 ctx = secp256k1_context_create (SECP256K1_CONTEXT_SIGN | SECP256K1_CONTEXT_VERIFY );
50645145 if (secp256k1_rand_bits (1 )) {
0 commit comments