-
Notifications
You must be signed in to change notification settings - Fork 268
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
secp256k1_ecdh_hash_function must return 0 or 1 #196
Comments
Thank you for opening the issue @sipa But I already have an idea around this without a breaking change, so I'll open a PR next week and we can discuss it until the next upstream bump. Any thoughts? @apoelstra |
Nice, good find. We should definitely fix rust-secp to match the documented upstream behavior. Curious what your non-breaking solution is Elichai. |
It seems that the correct solution would be to pass any other return data using a field in data pointer's object. |
My original thought was across the lines that @sipa suggested. But then I realized we can do this simpler by instead of passing a raw u8 pointer in the here are the code changes for both ways: |
This variant wrongly assumes that the u8 buffer is the first field in the struct (and that there's no padding in front of it). edit: We could add (Tbh, what #180 introduced is pretty complex. I'm still not convinced if it's not better to get the raw x and y data from C and handle the entire user-provided callback purely in Rust.) |
Well that depends if upstream promises to not touch the output pointer. |
Ah I see, I understand now. I think you're right. (And anyway, no-aliasing rules don't apply to unsigned char.)
What do people think about this? At the moment, the user gives us a Rust callback, that we wrap by creating a C callback from it. Then we call from Rust into C, which calls the C callback, which calls back into the user-provided Rust. This asks for complexity, if not for trouble. And my failure to understand the code is at least partially a result of this. What I suggest is to write a custom pass-through callback function that simply outputs the x and y values. Then after the FFI call we're done with C business, and then we apply the user-provided hash function (in Rust). Besides the reduced complexity, one advantage is that we don't need to deal with the case that the user-provided function panics. Would there be any drawbacks? |
I understand your concern of complexity. One "problem" with your suggestion is that if your cleaning PR(bitcoin-core/secp256k1#636) will ever get merged than we introduce here an explicit stack copy of those elements that we have nothing to do about it. FWIW Rust->C->Rust is a thing that also happens in the rust compiler. |
I see that it's not a huge difference in the end but if it's "basically the same except the panicking part", isn't it then better because of the panicking part? |
Originally discussed at bitcoin-core/secp256k1@4f72054#r371029012 (github fails to link to the discussion; scroll through bitcoin-core/secp256k1#710 instead).
See https://github.com/rust-bitcoin/rust-secp256k1/blob/master/src/ecdh.rs#L162, where it seems behavior relies on seeing the return value of the hash function propagated up to the signing return value.
The documentation for hash functions specifies that it should return 1 or 0, and similarly,
secp256k1_ecdh
will return 0 or 1.The text was updated successfully, but these errors were encountered: