-
Notifications
You must be signed in to change notification settings - Fork 281
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
Add combine_keys function to PublicKey #291
Conversation
f5eba4c
to
c7522b5
Compare
Looking at the CI failure and the fact that there is no use of |
Hmmm if we make |
21a0482
to
3db7e6b
Compare
@elichai Thanks for the suggestions, the transmutation trick seems indeed to work! Or at least it works for me locally. Is it safe to assume that the SIGILL on the CI is not caused by my change? (I can see it also happened on master) |
We can see that miri doesn't complain here: https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=bb329246b3e8ad06a104d06d2aba429e |
maybe also assert that |
3db7e6b
to
0c0e61d
Compare
Added a |
src/key.rs
Outdated
#[cfg(all(feature = "std"))] | ||
pub fn combine_keys(keys: &[&PublicKey]) -> Result<PublicKey, Error> { | ||
use std::mem::transmute; | ||
use std::i32::MAX; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you use core
and drop the feature gate?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done thanks that's much better indeed.
Yes, this will be fixed by #290 |
0c0e61d
to
71a1bbf
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM (@apoelstra what's our policy about assert vs debug_assert?)
@Tibo-lg Can you rebase please? that will solve the CI failures |
71a1bbf
to
7d32182
Compare
Done! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Re-ACK with the same wondering about debug_assert vs assert
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ack 7d32182
Funny, I have no recollection of the C function taking an arbitrary number of pubkeys.
Re debug_assert vs assert, we don't really have a policy ... but I think here where it's (a) an overflow condition, and (b) a programmer error, it's okay to use debug_assert. I'm not thrilled with it, but this is what libstd does all over the place, so it's consistent with the Rust ecosystem at least.
/// Adds the keys in the provided slice together, returning the sum. Returns | ||
/// an error if the result would be the point at infinity, i.e. we are adding | ||
/// a point to its own negation | ||
pub fn combine_keys(keys: &[&PublicKey]) -> Result<PublicKey, Error> { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Post-merge note: PublicKey
is a copy type and I am not sure why we need to have it here by reference
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
IIRC the reason is because we need a &[&PublicKey]
to transmute. It would also be possible to take a &[PublicKey]
and do the conversion internally but I guess I preferred to keep the library code minimal. I don't have a strong opinion if people want to change it though.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah the C code takes pointer to a list of pointers, so we'd have to allocate a vector of pointers and we try to avoid allocations where possible
To be honest, maybe upstream should reconsider this. The function is mostly useless to end users. |
It was added by the PR of the old Schnorr module to normal secp256k1.h (outside the module) https://github.com/bitcoin-core/secp256k1/pull/212/files#diff-4c52bd5cae65c9519af920228863ca34102abef6414e790498caa9fb05f03bbdR431 @Tibo-lg Do you need this function or did you simply create this PR because to make the bindings more complete? |
@real-or-random it is used somewhere by the LN folks (which is why it still exists in upstream BTW), so it would not surprise me if it has some use in rust-lightning |
I need it to efficiently compute adaptor points (for adaptor signatures) based on multiple signature points, and using this version over calling If someone is curious I had made some quick and dirty benchmarks to compare both versions when adding 1000 pubkeys here.
For just 10 keys it's still about 5 times slower:
|
Thanks. Post merge review: rust-secp256k1/secp256k1-sys/src/lib.rs Line 894 in bb25ed4
|
It's for Discrete Log Contracts (DLC) with numerical decompositions (or multiple oracles). You can check this post for example for a small write up. Note that as I mentioned above the memoization optimization that I describe there is actually slower than just using
Tried to address your comments here: #304 |
Added a static method to
PublicKey
to enable computing the sum of a slice of public keys, as at the moment it looked like it was only possible to compute the sum of two public keys.