I'm familiar with proprietary APIs where a third party decides what data and functionality is available to developers communicating with their server.

However, secp256k1 is an open source cryptographic library which is entirely accessible/callable and can be forked. What is the secp256k1 API in this case and in what ways is it restricted to limit functionality?

In this GitHub comment it is suggested that people back in 2015 were "attempting to use the library calling into random internal functions. That should be harder to do now". Why is this discouraged and why is it harder to do now?

1 Answer 1


This was discussed before a PR review club on secp256k1 usage examples on February 2nd 2022. Thanks to the individuals (glozow, lightlike, sipa, robot-dreams etc) who answered this. I haven't made any substantial changes but any errors are my own.

A function that isn't exposed in the header files is not visible to a prospective caller. The repo is open source so it can be forked with additional functions added to the header files but then you have to maintain a fork and upgrading will be a pain (no one upstream will care about keeping the interface of internal functions stable).

However, just adding a function to a header file isn't enough. The build will fail at linking time if you add a function to a header without also modifying the library to provide and export such a function. The header tells callers how they can call exported library functions. If the header and the exported library functions mismatch you'll get an error. You'll also need to modify the library to export these functions.

To the extent that doing this is advisable or not depends on the use case, capability of the developer and willingness to maintain a fork of the repo. Generally it is recommended that you don't "roll your own crypto" unless you know what you are doing. There are many pitfalls the more ambitious the changes are.

The Bitcoin Core repo uses the secp256k1 API in various ways. For ECDSA the caller provides the message hash to libsecp256k1 and it signs/verifies. For BIP 340 (Schnorr) the caller provides the message and libsecp256k1 does the hashing.

libsecp256k1 only has a very simple unoptimized implementation of the SHA256 hash function so it can do RFC6979. There have been discussions on allowing callers to provide their own SHA256 implementation to the library or adding a new API function that takes an unhashed message and returns the hash. However, Bitcoin uses double SHA256 to obtain the message hash and so that would either not match Bitcoin's usage of ECDSA or still require the caller to do one of two hashing steps (or not be standard).

There is an issue discussing how an external project can use the secp256k1 library here.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.