-
Notifications
You must be signed in to change notification settings - Fork 270
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Make the -sys
crate optional
#703
base: master
Are you sure you want to change the base?
Conversation
f465167
to
6ee130a
Compare
Build failures are unrelated, I'm going AFK and I'm not sure if I'll come back until tomorrow, so @tcharding if fixing the CI is kind of task you'd like to do go ahead with a separate PR that fixes those things and I'll rebase this on top of it. |
@Kixunil thanks so much!!! I will dig into this. I wonder -- there are two ways we might go about this:
What do you think? |
Or a third option -- we introduce another crate |
Having it here is more useful - it helps also people who only need this crate and not whole
Yes, for keys at least. But disable signing&co if the feature is off.
I didn't want this originally but since we decided to wrap the keys I'm pretty open to it. I'll need to think if I can find a good reason to split them up.
|
I've been thinking a bunch about the dependencies and I found a potential use cases for having keys separated. For xpub -> address "calculators" that just let users generate addresses without dealing with checking the chain (donations, trusting friends etc) it'd be nice to not have to build code related to transactions etc. I think So I think But there's another thing: in a different issue I've suggested that the In principle Finally we need to somehow keep the vendoring and So ultimately the dependency graph can one of these:
|
Ok, great, that sounds good to me. ACK having As for splitting |
In my mind, those are a different layer. Not all applications working with keys work with signatures since keys are a fundamental building block of addresses. However splitting them seems like too much so I guess it'll be fine. Will do more thinking. By exclusive I mean you can only have one version. You can only link to a system library once (precisely because C has no namespacing). Cargo should know this but currently doesn't because we're missing it from |
I'm confused. I thought this is what the
Agreed. Signatures and sighash types are such small/simple types and they're mostly useless without keys (agreed that keys are useful without signatures, ofc) so giving them their own crate feels like overkill. Even |
With a fake versioned name. The real library is called |
Yes, because we intend to be exclusive with respect to any specific verison of libsecp, but not across versions, since different versions might as well be completely different libraries as far as we are concerned. I'm still not understanding what is wrong with our current approach. |
The field is wrong when we deactivate symbol renaming. In an ideal world we would've set it programmatically but we can't. |
We cannot deactivate symbol renaming because we are compiling a C library. If you don't rename the symbols they will collide from the symbols from other versions of libsecp256k1. |
We literally have a feature to do that, so that users can link to the system library (what the |
If you mean the This library has never been intended to be used with "the system library" (I guess, some random git commit of libsecp that some distro maintainer packaged against our wishes and without our input) and I am not aware of anybody using it that way. We can rename -sys to something else if you'd like (though I'd like to see a citation for what it "actually" means) but if we want to support linking to the system library that deserves its own separate issue where we investigate whether major distributions are packaging released version of libsecp and separating their symbols properly, how we can distinguish the different versions, etc. I think we have such an issue, because this has come up before a few times. It's a much bigger and separate project from just making |
We have one, #657, which you opened. We should move discussion there about supporting dynamic linking. |
The reason I brought this up now is that it potentially affects the name of the feature so if we ever want to stabilize this crate it needs to be resolved. But maybe what we should really do is separate feature namespace (in the future, when we bump MSRV) and name the feature |
Rebased on top of #705 to get it to compile. @apoelstra can we merge #705 soon? It's likely blocking a bunch of work. |
Yep -- I just need to get my local CI up to date (I did some major changes about a month ago and haven't updated all my repos..) then I can do it. Should be less than an hour. |
Downstream projects, such as `bitcoin` are using types from this crate and need to compile the C code even if they only use the types for checking validity of the data and don't perform cryptographic operations. Compiling C code is slow and unreliable so there was desire to avoid this. This commit introduces pure Rust implementation of basic non-cryptographic operations (is point on the curve, decompression of point, secret key constant time comparisons) and feature-gates cryptographic operations on `secp256k1-sys` which is now optional. To make use of this, downstream crates will have to deactivate the feature and possibly feature gate themselves. The implementation requires a U256 type which was copied from the `bitcoin` crate. We don't depend on a common crate to avoid needless compilation when the feature is turned on. This is a breaking change because users who did cryptographic operations with `default-features = false` will get compilation errors until they enable the feature.
Ok, looking more closely at this PR. Can you break it up into a series of commits?
Also we should double-back and expose the Overall this looks great. The nits that jump out at me are things like:
|
I'll be happy to split the first part and add the fuzz tests but honestly I think splitting the feature gating stuff is a bunch of useless work. It's just a bunch of one-line changes. Can I skip that part?
Oh yeah, just compare the parameters.
Weird, I swear I remember adding it...
I found it super hard to figure out what it really means. Using the LSB caused some test to fail while the current code works and it's what I got from some SO post. I guess I'll dig deeper, perhaps into the C code.
Can we MIT-license just the copied functions? Also maybe @KanoczTomas would be willing to relicense his work, we know each other personally. |
I meant to have pretty-much all the feature-gating stuff in the first commit. The others are meaningfully changing the logic by replacing the implementation when the C code is off.
It's a little bit more work than that but not much. You can look at the secp logic for
The C code definitely just does &1 in
Yes, fine to just MIT-license the copied functions. I don't know @KanoczTomas and AFAICT he hasn't written any of the libsecp code. If you got it from somewhere else I didn't realize that. |
I thought you wanted to just add the Rust code behind fuzzing feature in the first commit.
Oh, yeah, I completely forgot that was the reason I didn't put it in the PR - I wasn't in the mood to implement DER. :D
Yeah, I managed to find it but wasn't able to figure out what's wrong yet.
I copied some Rust code here from him but he also copied some from somewhere else. Note that most of my code is based on toy-secp256k1 which is completely my own, from scratch (except for U256 type and multiplicative inverse). |
@Kixunil could you maybe add a few sentences on the use case for a pure rust compilation? (ie why do some users don't want to link in libsecp if they're using pubkeys etc.) |
@elichai I think the most obvious example is parsing addresses. Addresses may contain keys, so we need to check them but there's no need to produce or validate signatures. And even within context of a larger application, one might want to pre-validate addresses or other types on frontend to avoid latency of reporting an error. (Very good for UX.) |
And you don't want to rely on LTO for that? |
@elichai LTO doesn't make the C code inherently memory-safe, nor does it help compiling with immature toolchains (e.g. wasm-pack), nor does it reduce the code/API surface. |
More like I don't want to incur the cost of compiling and then throw away the result. Try to cold-compile this PR with and without the flag. The time difference is huge. |
I don't, or I do yet minimally, use secp256k1. I almost entirely use the Rust k256 library as I produce signatures/manage keys on my end (not via the bitcoin/secp256k1 libs). Accordingly, this'd remove a dependency and I always appreciate that. |
I think this is a fairly common case and I'd also like to fix it -- while it's "safe" to use non-production-ready crypto libs for verification, in the sense that you'll never leak secret key data, in general if your verification code differs from consensus code that can still put you in a dangerous situation. |
Downstream projects, such as
bitcoin
are using types from this crate and need to compile the C code even if they only use the types for checking validity of the data and don't perform cryptographic operations. Compiling C code is slow and unreliable so there was desire to avoid this.This commit introduces pure Rust implementation of basic non-cryptographic operations (is point on the curve, decompression of point, secret key constant time comparisons) and feature-gates cryptographic operations on
secp256k1-sys
which is now optional. To make use of this, downstream crates will have to deactivate the feature and possibly feature gate themselves.The implementation requires a U256 type which was copied from the
bitcoin
crate. We don't depend on a common crate to avoid needless compilation when the feature is turned off.This is a breaking change because users who did cryptographic operations with
default-features = false
will get compilation errors until they enable the feature.