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

Use predication intrinsics (i.e. CMOV) for ConditionallySelectable #101

Open
tarcieri opened this issue Jan 10, 2023 · 2 comments
Open

Use predication intrinsics (i.e. CMOV) for ConditionallySelectable #101

tarcieri opened this issue Jan 10, 2023 · 2 comments

Comments

@tarcieri
Copy link
Contributor

The foundation of ConditionallySelectable is bitwise masking of values + XOR, using the input Choice to generate a conditional mask, such that the mask erases one of the two values from the XOR output:

https://github.com/dalek-cryptography/subtle/blob/b4b070c/src/lib.rs#L477-L503

This seems fine for now (and is the best thing possible in a portable implementation), but may have issues with future LLVM versions which are able to deduce how to rewrite such code with a branch.

CPUs provide predication intrinsics such as x86's conditional move (a.k.a. CMOV) family of instructions. Intel has guaranteed that the CMOV family operates in constant time on all extant Intel CPUs. ARM provides conditional select (a.k.a. CSEL) instructions which perform a similar function.

Within the @RustCrypto project, we've made a cmov crate which provides a portable abstraction for this based on the now stable inline assembly support added to Rust 1.59: https://github.com/RustCrypto/utils/tree/master/cmov

...however its implementation is simple and could be copied into subtle to avoid a dependency.

@tarcieri
Copy link
Contributor Author

tarcieri commented Apr 4, 2023

I wrote up this idea a bit more in #107 (comment).

The CMOV family on x86/x86_64 can be used to implement ConditionallySelectable::conditional_assign, and the CSEL family can be used on aarch64.

Once you have this defined, ConstantTimeEq can be implemented in terms of it, by XORing the inputs and using e.g. cmovnz

@brxken128
Copy link

I second this, as the implementor of CmovEq and just generally helping the crate out, I do have a working custom-time module based on cmov alone - the dudect-bencher for Rust outputs extremely low T values, which idicates that it does indeed work and runs in constant-time, across a variety of tests.

Getting assured, guaranteed branch-less code into a crate such as this would be a game-changer, IMO - I don't mind doing any of the heavy lifting in my free time either.

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

2 participants