What is the context in libsecp256k1? I am experimenting with making a wallet for educational purposes, and would like to use libsecp256k1 directly. Aside from creating a context, and using it in calls, all I have perhaps learned so far is that you should generally only create one context, but I am not even entirely certain this is true. 

Not knowing why, or anything really about the context, I was wondering exactly what it is, how it is used, and how one should use it?
The code comments that serve as the library's documentation explain what it does:

/** Opaque data structure that holds context information (precomputed tables etc.).
 *
 *  The purpose of context structures is to cache large precomputed data tables
 *  that are expensive to construct, and also to maintain the randomization data
 *  for blinding.
 *
 *  Do not create a new context object for each operation, as construction is
 *  far slower than all other API calls (~100 times slower than an ECDSA
 *  verification).
 *
 *  A constructed context can safely be used from multiple threads
 *  simultaneously, but API call that take a non-const pointer to a context
 *  need exclusive access to it. In particular this is the case for
 *  secp256k1_context_destroy and secp256k1_context_randomize.
 *
 *  Regarding randomization, either do it once at creation time (in which case
 *  you do not need any locking for the other calls), or use a read-write lock.
 */
typedef struct secp256k1_context_struct secp256k1_context;


libsecp256k1 is not an object oriented library nor is it able to store various useful states. So the context object allows the useful states to be kept.

You should generally only create one because the stuff it generates and stores is relatively expensive to compute. To use the context, just create a new context that supports the operations you want to do using the secp256k1_context_create function. You pass in the bitwise OR'ing of the SECP256K1_CONTEXT_VERIFY, SECP256K1_CONTEXT_SIGN, SECP256K1_CONTEXT_NONE flags which represent the type of things you want to do.

E.g. if you wanted to create a context that will be used in signing functions, you would create a context with:

secp256k1_context* secp256k1_context_create(SECP256K1_CONTEXT_SIGN);


If you wanted one that can be used with both signing and verifying, you do:

secp256k1_context* secp256k1_context_create(SECP256K1_CONTEXT_SIGN | SECP256K1_CONTEXT_VERIFY);


The resulting context you just use as the context argument for any function that needs one.