-
Notifications
You must be signed in to change notification settings - Fork 130
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
crypto-intrinsics #730
crypto-intrinsics #730
Conversation
ADX and MULX are also good candidates, and particularly problematic to emit outside of inline assembly due to LLVM bugs: Namely LLVM isn't aware of the relevant flags for these instructions and either clobbers them or doesn't properly emit them. |
f6acf38
to
1b16dc8
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.
Interesting. Is it feasible for those intrinsics to be added to core::arch
eventually? Also I wonder about fragility of flags used with ADX/MULX. If we are to chain several calls to such intrinsics, are we sure that compiler can not reorder some intrinsics clobbering the flags between those calls?
2811bcd
to
a1b0fba
Compare
I think the only way would be if they used inline assembly themselves. In fact I requested as much and they seemed skeptical.
I think it still relies on careful inspection of the generated assembly, but really the important thing IMO is that LLVM does not insert additional instructions that clobber the flags, as otherwise I think the data dependencies should take care of reordering which would affect the flags. |
a1b0fba
to
86bb1f9
Compare
crypto-intrinsics/src/x86_64.rs
Outdated
/// | ||
/// This function requires support for the Intel BMI2 (Bit Manipulation | ||
/// Instruction Set 2) extension to the x86 instruction set. | ||
#[target_feature(enable = "bmi2")] |
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.
I was able to add this for MULX, as it requires BMI2.
I tried to do the same thing with ADX, but unfortunately:
error[E0658]: the target feature `adx` is currently unstable
--> crypto-intrinsics/src/x86_64.rs:26:18
|
26 | #[target_feature(enable = "adx")]
| ^^^^^^^^^^^^^^
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.
It looks like a PR to stabilize ADX stalled some time in 2019: rust-lang/rust#60109
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.
Opened a PR to stabilize the ADX target feature here: rust-lang/rust#93745
86bb1f9
to
62050d6
Compare
62050d6
to
829370d
Compare
Now that inline assembly has been stabilized in Rust 1.59, I thought we could start putting together a crate which provides wrappers for assembly instructions which are useful for cryptography but lack proper `core::arch` wrappers. More importantly, using inline assembly allows us to provide a sort of black box which LLVM will not interfere with, which is problematic using anything else besides ASM. For example, it's otherwise not possible to correctly emit CMOV instructions on x86 platforms with LLVM because the `x86-cmov-conversion` pass which will rewrite them as branches. For more details, see: https://dsprenkels.com/cmov-conversion.html
829370d
to
6f23b0a
Compare
Bumping the clippy version to 1.59 exposed some new warnings
Removed draft/WIP and slimmed the initial implementation down to just Namely I removed all ADX/MULX support as we need a solution which supports carry chains emitted as a single Potentially in the future we can add some more of the CMOVcc family, and try to come up with something like a macro solution for ADX/MULX chains which emits an If it winds up this crate only implements CMOV though, I've gone ahead and snagged the |
I'm going to open a separate PR for a simple |
Can you update the CI workflow with cargo cache and minimal versions job? The latter is less needed since the crate does no have any dependencies, but I guess it's better to keep workflows consistent with each other. |
keywords = ["crypto", "cmov", "intrinsics"] | ||
readme = "README.md" | ||
edition = "2018" # Can't bump to 2021 due to pre-1.56 MSRV crates in the same workspace | ||
rust-version = "1.59" |
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.
Wouldn't it be better to use 2021 edition and the separate workspace trick for now? It's already done for the inout
crate.
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.
That approach is really annoying from a maintenance perspective, since each crate gets its own Cargo.lock
and therefore needs its own dependabot config (although that's admittedly not really a problem here).
I'd rather attempt the "delete the toplevel Cargo.toml" trick if we were to do that, but this crate is so simple it doesn't really derive any benefits from being 2021 edition.
Here's a |
Closing in favor of #741 |
With the
forthcomingstabilization of inline assembly, I thought we could start putting together a crate which provides wrappers for assembly instructions which are useful for cryptography but lack propercore::arch
wrappers.More importantly, using inline assembly allows us to provide a sort of black box which LLVM will not interfere with, which is problematic using anything else besides ASM. For example, it's otherwise not possible to correctly emit CMOV instructions on x86 platforms with LLVM because the
x86-cmov-conversion
pass which will rewrite them as branches. For more details, see:https://dsprenkels.com/cmov-conversion.html