Open apoelstra opened 1 week ago
It'd be also extra nice if it was possible to guarantee that callback
will be called (abort if it can't).
/* create context object on the stack, which can't be done from the public API */
Couldn't you create a context on the stack using secp256k1_context_preallocated_create
? I'm not saying it's elegant, and you'll need to take care of alignment, but it should be doable.
@real-or-random Rust doesn't have alloca
so it wouldn't work for dynamically-linked system libraries without going through C. We could in principle do that but to my knowledge alloca
has some problems (I don't remember the details). Calling into the library code which knows the exact size of its context sounds much more appealing.
without going through C. We could in principle do that but to my knowledge
alloca
has some problems (I don't remember the details).
alloca
is simply obsolete and nonstandard, but there's nothing wrong with it. Well, except that it allocates on the stack, but this is precisely what you want to do here. The "modern" (available since C99) version are variable-length arrays.
Calling into the library code which knows the exact size of its context sounds much more appealing.
I see that, I'm just trying to understand the nature of the problem and its urgency.
Concept ACK
I think that's a simple way to give users the ability to rerandomize every operation, and it works without breaking our context API. We could even provide convenience wrappers for key generation and signing.
Contexts are pretty small now after we've removed all the dynamic tables. One caveat is that we need to get the stack allocation right in C89... But that's doable, we know the size of the context at compilation time of the library, and we have BIGGEST_ALIGNMENT.
Would one of you be willing to work on a PR?
Yes, I can take this on.
In rust-secp256k1 we're exploring how we can best support a signing API for systems which potentially have no allocator, may be operating multiple threads, but which have very limited threading primitives (e.g. we have atomics with acquire/release semantics but no stdlib with prepackaged mutexes or other locks).
I think a useful function would be something like
(where
cb
is a type alias for a callback that takes a context and void pointer and returns an int).Our usage here would be to implement a signing function that used a freshly randomized context but which did not require the user pass context objects through every API function, nor would it require us to maintain a global mutable context object, which is really hard to do without mutexes. The resulting function would be ~twice as slow as normal signing function but for many usecases this is acceptable since signing is not a frequent operation.
On the other hand, maintaining a global mutable 32-byte random seed would be super easy because we don't need any synchronization beyond the use of atomics to avoid UB.
cc https://github.com/bitcoin-core/secp256k1/issues/780 which is closely related to this but more general.