Skip to content
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

Question: Could rust compiler optimization possibly expose side channel attacks? #341

Open
junderw opened this issue Nov 23, 2021 · 3 comments

Comments

@junderw
Copy link
Contributor

junderw commented Nov 23, 2021

The title is self-explanatory, but I have read that constant time operations in Rust are difficult due to compiler optimizations removing things.

To combat this, I have seen some discussions on Rust RFC: rust-lang/rfcs#2859

(Also, for LLVM side of the issue, see here)

Does anyone know if the usage of FFI in the sys package somehow prevents this kind of optimization?

@real-or-random
Copy link
Collaborator

real-or-random commented Nov 24, 2021

Does anyone know if the usage of FFI in the sys package somehow prevents this kind of optimization?

This is just an educated guess but I believe it depends on whether the build uses cross-language link-time optimization (LTO), see rust-lang/rust#49879. If no, then we should not have more side channels than upstream secp256k1 (which has a valgrind-style test).

Even if LTO is enabled, I don't expect any optimization to kick in that hurts constant timeness. But you never know. We could write a Rust-equivalent of the valgrind constant-time test and run it in CI (or even transpile the C test to Rust automatically. It doesn't need to be nice code.)

@junderw
Copy link
Contributor Author

junderw commented Nov 24, 2021

We could write a Rust-equivalent of the valgrind constant-time test and run it in CI

This might be worthwhile to prevent some small seemingly insignificant build config change to introduce a side-channel vector.

FYI, I ran a few very simple benchmarks in NodeJS that compare the old native JS implementation of ECMult vs. the new WASM which is derived from this library, and it was night and day. JS took 5x time to ECMult n-1 vs. 2. WASM I ran quite a few times, and the variance was less than 1 percent, and the difference was less than the variance (immeasurable) if any.

ecdsaSign was also similar, though JS did fare better than 5x, that's not saying much.

@apoelstra
Copy link
Member

I don't think a valgrind-style test would show us anything different in Rust than in C. I would be curious to see, but not curious enough to do the work :).

My feeling is that, to get meaningful constant-time protection beyond trusting that upstream's analysis will carry over to bindings, you'd have to inspect the (W)ASM by hand. Though I appreciate your emprical tests @junderw ! Might be interesting to e.g. compare signing with a mostly-1s key vs a mostly-0s key and check that there isn't a reliable statistical tell.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants