@@ -33,9 +33,10 @@ extern "C" {
3333 * verification).
3434 *
3535 * A constructed context can safely be used from multiple threads
36- * simultaneously, but API call that take a non-const pointer to a context
36+ * simultaneously, but API calls that take a non-const pointer to a context
3737 * need exclusive access to it. In particular this is the case for
38- * secp256k1_context_destroy and secp256k1_context_randomize.
38+ * secp256k1_context_destroy, secp256k1_context_prealloc_destroy,
39+ * and secp256k1_context_randomize.
3940 *
4041 * Regarding randomization, either do it once at creation time (in which case
4142 * you do not need any locking for the other calls), or use a read-write lock.
@@ -163,7 +164,8 @@ typedef int (*secp256k1_nonce_function)(
163164#define SECP256K1_FLAGS_BIT_CONTEXT_SIGN (1 << 9)
164165#define SECP256K1_FLAGS_BIT_COMPRESSION (1 << 8)
165166
166- /** Flags to pass to secp256k1_context_create. */
167+ /** Flags to pass to secp256k1_context_create, secp256k1_context_prealloc_size, and
168+ * secp256k1_context_prealloc_size. */
167169#define SECP256K1_CONTEXT_VERIFY (SECP256K1_FLAGS_TYPE_CONTEXT | SECP256K1_FLAGS_BIT_CONTEXT_VERIFY)
168170#define SECP256K1_CONTEXT_SIGN (SECP256K1_FLAGS_TYPE_CONTEXT | SECP256K1_FLAGS_BIT_CONTEXT_SIGN)
169171#define SECP256K1_CONTEXT_NONE (SECP256K1_FLAGS_TYPE_CONTEXT)
@@ -186,7 +188,7 @@ typedef int (*secp256k1_nonce_function)(
186188 */
187189SECP256K1_API extern secp256k1_context * secp256k1_context_no_precomp ;
188190
189- /** Create a secp256k1 context object.
191+ /** Create a secp256k1 context object (in dynamically allocated memory) .
190192 *
191193 * Returns: a newly created context object.
192194 * In: flags: which parts of the context to initialize.
@@ -197,7 +199,7 @@ SECP256K1_API secp256k1_context* secp256k1_context_create(
197199 unsigned int flags
198200) SECP256K1_WARN_UNUSED_RESULT ;
199201
200- /** Copies a secp256k1 context object.
202+ /** Copy a secp256k1 context object (into dynamically allocated memory) .
201203 *
202204 * Returns: a newly created context object.
203205 * Args: ctx: an existing context to copy (cannot be NULL)
@@ -206,15 +208,98 @@ SECP256K1_API secp256k1_context* secp256k1_context_clone(
206208 const secp256k1_context * ctx
207209) SECP256K1_ARG_NONNULL (1 ) SECP256K1_WARN_UNUSED_RESULT ;
208210
209- /** Destroy a secp256k1 context object.
211+ /** Destroy a secp256k1 context object (created in dynamically allocated memory) .
210212 *
211213 * The context pointer may not be used afterwards.
212- * Args: ctx: an existing context to destroy (cannot be NULL)
214+ *
215+ * The context to destroy must have been created using secp256k1_context_create
216+ * or secp256k1_context_clone. If the context has instead been created using
217+ * secp256k1_context_prealloc_create or secp256k1_context_prealloc_clone, the
218+ * behaviour is undefined. In that case, secp256k1_context_prealloc_destroy must
219+ * be used instead.
220+ *
221+ * Args: ctx: an existing context to destroy, constructed using
222+ * secp256k1_context_create or secp256k1_context_clone
213223 */
214224SECP256K1_API void secp256k1_context_destroy (
215225 secp256k1_context * ctx
216226);
217227
228+ /** Determine the memory size of a secp256k1 context object to be created in
229+ * caller-provided memory.
230+ *
231+ * The purpose of this function is to determine how much memory must be provided
232+ * to secp256k1_context_prealloc_create.
233+ *
234+ * Returns: the required size of the caller-provided memory block
235+ * In: flags: which parts of the context to initialize.
236+ */
237+ SECP256K1_API size_t secp256k1_context_prealloc_size (
238+ unsigned int flags
239+ ) SECP256K1_WARN_UNUSED_RESULT ;
240+
241+ /** Create a secp256k1 context object in caller-provided memory.
242+ *
243+ * Returns: a newly created context object.
244+ * In: prealloc: a pointer to a rewritable contiguous block of memory of
245+ * size at least secp256k1_context_prealloc_size(flags)
246+ * bytes, suitably aligned to hold an object of any type
247+ * (cannot be NULL)
248+ * flags: which parts of the context to initialize.
249+ *
250+ * See also secp256k1_context_randomize.
251+ */
252+ SECP256K1_API secp256k1_context * secp256k1_context_prealloc_create (
253+ void * prealloc ,
254+ unsigned int flags
255+ ) SECP256K1_ARG_NONNULL (1 ) SECP256K1_WARN_UNUSED_RESULT ;
256+
257+ /** Determine the memory size of a secp256k1 context object to be copied into
258+ * caller-provided memory.
259+ *
260+ * The purpose of this function is to determine how much memory must be provided
261+ * to secp256k1_context_prealloc_clone when copying the context ctx.
262+ *
263+ * Returns: the required size of the caller-provided memory block.
264+ * In: ctx: an existing context to copy (cannot be NULL)
265+ */
266+ SECP256K1_API size_t secp256k1_context_prealloc_clone_size (
267+ const secp256k1_context * ctx
268+ ) SECP256K1_ARG_NONNULL (1 ) SECP256K1_WARN_UNUSED_RESULT ;
269+
270+ /** Copy a secp256k1 context object into caller-provided memory.
271+ *
272+ * Returns: a newly created context object.
273+ * Args: ctx: an existing context to copy (cannot be NULL)
274+ * In: prealloc: a pointer to a rewritable contiguous block of memory of
275+ * size at least secp256k1_context_prealloc_size(flags)
276+ * bytes, suitably aligned to hold an object of any type
277+ * (cannot be NULL)
278+ */
279+ SECP256K1_API secp256k1_context * secp256k1_context_prealloc_clone (
280+ const secp256k1_context * ctx ,
281+ void * prealloc
282+ ) SECP256K1_ARG_NONNULL (1 ) SECP256K1_ARG_NONNULL (2 ) SECP256K1_WARN_UNUSED_RESULT ;
283+
284+ /** Destroy a secp256k1 context object that has been created in
285+ * caller-provided memory.
286+ *
287+ * The context pointer may not be used afterwards.
288+ *
289+ * The context to destroy must have been created using
290+ * secp256k1_context_prealloc_create or secp256k1_context_prealloc_clone.
291+ * If the context has instead been created using secp256k1_context_create or
292+ * secp256k1_context_clone, the behaviour is undefined. In that case,
293+ * secp256k1_context_destroy must be used instead.
294+ *
295+ * Args: ctx: an existing context to destroy, constructed using
296+ * secp256k1_context_prealloc_create or
297+ * secp256k1_context_prealloc_clone (cannot be NULL)
298+ */
299+ SECP256K1_API void secp256k1_context_prealloc_destroy (
300+ secp256k1_context * ctx
301+ );
302+
218303/** Set a callback function to be called when an illegal argument is passed to
219304 * an API call. It will only trigger for violations that are mentioned
220305 * explicitly in the header.
@@ -631,7 +716,8 @@ SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_pubkey_tweak_mul(
631716 * rely on any input-dependent behaviour.
632717 *
633718 * You should call this after secp256k1_context_create or
634- * secp256k1_context_clone, and may call this repeatedly afterwards.
719+ * secp256k1_context_clone (and secp256k1_context_prealloc_create or
720+ * secp256k1_context_clone, resp.), and you may call this repeatedly afterwards.
635721 */
636722SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_context_randomize (
637723 secp256k1_context * ctx ,
0 commit comments