@@ -82,46 +82,71 @@ size_t secp256k1_context_preallocated_size(unsigned int flags) {
8282 return ret ;
8383}
8484
85- secp256k1_context * secp256k1_context_create (unsigned int flags ) {
86- secp256k1_context * ret = (secp256k1_context * )checked_malloc (& default_error_callback , sizeof (secp256k1_context ));
85+ secp256k1_context * secp256k1_context_preallocated_create (void * prealloc , unsigned int flags ) {
86+ void * const base = prealloc ;
87+ size_t prealloc_size = secp256k1_context_preallocated_size (flags );
88+ secp256k1_context * ret = (secp256k1_context * )manual_alloc (& prealloc , sizeof (secp256k1_context ), base , prealloc_size );
89+
8790 ret -> illegal_callback = default_illegal_callback ;
8891 ret -> error_callback = default_error_callback ;
8992
9093 if (EXPECT ((flags & SECP256K1_FLAGS_TYPE_MASK ) != SECP256K1_FLAGS_TYPE_CONTEXT , 0 )) {
9194 secp256k1_callback_call (& ret -> illegal_callback ,
9295 "Invalid flags" );
93- free (ret );
9496 return NULL ;
9597 }
9698
9799 secp256k1_ecmult_context_init (& ret -> ecmult_ctx );
98100 secp256k1_ecmult_gen_context_init (& ret -> ecmult_gen_ctx );
99101
100102 if (flags & SECP256K1_FLAGS_BIT_CONTEXT_SIGN ) {
101- secp256k1_ecmult_gen_context_build (& ret -> ecmult_gen_ctx , & ret -> error_callback );
103+ secp256k1_ecmult_gen_context_build (& ret -> ecmult_gen_ctx , & prealloc );
102104 }
103105 if (flags & SECP256K1_FLAGS_BIT_CONTEXT_VERIFY ) {
104- secp256k1_ecmult_context_build (& ret -> ecmult_ctx , & ret -> error_callback );
106+ secp256k1_ecmult_context_build (& ret -> ecmult_ctx , & prealloc );
105107 }
106108
107- return ret ;
109+ return (secp256k1_context * ) ret ;
110+ }
111+
112+ secp256k1_context * secp256k1_context_create (unsigned int flags ) {
113+ size_t const prealloc_size = secp256k1_context_preallocated_size (flags );
114+ secp256k1_context * ctx = (secp256k1_context * )checked_malloc (& default_error_callback , prealloc_size );
115+ if (EXPECT (secp256k1_context_preallocated_create (ctx , flags ) == NULL , 0 )) {
116+ free (ctx );
117+ return NULL ;
118+ }
119+
120+ return ctx ;
108121}
109122
110123secp256k1_context * secp256k1_context_clone (const secp256k1_context * ctx ) {
111- secp256k1_context * ret = (secp256k1_context * )checked_malloc (& ctx -> error_callback , sizeof (secp256k1_context ));
112- ret -> illegal_callback = ctx -> illegal_callback ;
113- ret -> error_callback = ctx -> error_callback ;
114- secp256k1_ecmult_context_clone (& ret -> ecmult_ctx , & ctx -> ecmult_ctx , & ctx -> error_callback );
115- secp256k1_ecmult_gen_context_clone (& ret -> ecmult_gen_ctx , & ctx -> ecmult_gen_ctx , & ctx -> error_callback );
124+ secp256k1_context * ret ;
125+ size_t prealloc_size = ROUND_TO_ALIGN (sizeof (secp256k1_context ));
126+ if (secp256k1_ecmult_gen_context_is_built (& ctx -> ecmult_gen_ctx )) {
127+ prealloc_size += SECP256K1_ECMULT_GEN_CONTEXT_PREALLOCATED_SIZE ;
128+ }
129+ if (secp256k1_ecmult_context_is_built (& ctx -> ecmult_ctx )) {
130+ prealloc_size += SECP256K1_ECMULT_CONTEXT_PREALLOCATED_SIZE ;
131+ }
132+ ret = checked_malloc (& ctx -> error_callback , prealloc_size );
133+ memcpy (ret , ctx , prealloc_size );
134+ secp256k1_ecmult_gen_context_finalize_memcpy (& ret -> ecmult_gen_ctx , & ctx -> ecmult_gen_ctx );
135+ secp256k1_ecmult_context_finalize_memcpy (& ret -> ecmult_ctx , & ctx -> ecmult_ctx );
116136 return ret ;
117137}
118138
119- void secp256k1_context_destroy (secp256k1_context * ctx ) {
139+ void secp256k1_context_preallocated_destroy (secp256k1_context * ctx ) {
120140 CHECK (ctx != secp256k1_context_no_precomp );
121141 if (ctx != NULL ) {
122142 secp256k1_ecmult_context_clear (& ctx -> ecmult_ctx );
123143 secp256k1_ecmult_gen_context_clear (& ctx -> ecmult_gen_ctx );
144+ }
145+ }
124146
147+ void secp256k1_context_destroy (secp256k1_context * ctx ) {
148+ if (ctx != NULL ) {
149+ secp256k1_context_preallocated_destroy (ctx );
125150 free (ctx );
126151 }
127152}
0 commit comments