-
Notifications
You must be signed in to change notification settings - Fork 138
crypto-intrinsics #730
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
Closed
Closed
crypto-intrinsics #730
Changes from all commits
Commits
Show all changes
2 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
name: crypto-intrinsics | ||
|
||
on: | ||
pull_request: | ||
paths: | ||
- "crypto-intrinsics/**" | ||
- "Cargo.*" | ||
push: | ||
branches: master | ||
|
||
defaults: | ||
run: | ||
working-directory: crypto-intrinsics | ||
|
||
env: | ||
CARGO_INCREMENTAL: 0 | ||
RUSTFLAGS: "-Dwarnings" | ||
|
||
jobs: | ||
build: | ||
runs-on: ubuntu-latest | ||
strategy: | ||
matrix: | ||
rust: | ||
- 1.59.0 # MSRV | ||
target: | ||
- thumbv7em-none-eabi | ||
- wasm32-unknown-unknown | ||
steps: | ||
- uses: actions/checkout@v1 | ||
- uses: actions-rs/toolchain@v1 | ||
with: | ||
profile: minimal | ||
toolchain: ${{ matrix.rust }} | ||
target: ${{ matrix.target }} | ||
override: true | ||
- run: cargo build --target ${{ matrix.target }} --release | ||
|
||
test: | ||
strategy: | ||
matrix: | ||
include: | ||
# 32-bit Linux | ||
- target: i686-unknown-linux-gnu | ||
platform: ubuntu-latest | ||
rust: 1.59.0 # MSRV | ||
deps: sudo apt update && sudo apt install gcc-multilib | ||
|
||
# 64-bit Linux | ||
- target: x86_64-unknown-linux-gnu | ||
platform: ubuntu-latest | ||
rust: 1.59.0 # MSRV | ||
|
||
# 64-bit Windows | ||
- target: x86_64-pc-windows-msvc | ||
platform: windows-latest | ||
rust: 1.59.0 # MSRV | ||
|
||
runs-on: ${{ matrix.platform }} | ||
steps: | ||
- uses: actions/checkout@v1 | ||
- uses: actions-rs/toolchain@v1 | ||
with: | ||
toolchain: ${{ matrix.rust }} | ||
target: ${{ matrix.target }} | ||
profile: minimal | ||
override: true | ||
- run: ${{ matrix.deps }} | ||
- run: cargo test --release |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
[package] | ||
name = "crypto-intrinsics" | ||
description = """ | ||
High-level wrappers for architecture-specific CPU intrinsics which are relevant | ||
to cryptographic use cases, such as the CMOV family, implemented using stable | ||
inline assembly | ||
""" | ||
version = "0.0.0" | ||
authors = ["RustCrypto Developers"] | ||
license = "Apache-2.0 OR MIT" | ||
repository = "https://github.com/RustCrypto/utils/tree/master/crypto-intrinsics" | ||
categories = ["cryptography"] | ||
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" | ||
|
||
[package.metadata.docs.rs] | ||
all-features = true | ||
all-targets = true | ||
rustdoc-args = ["--cfg", "docsrs"] |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,75 @@ | ||
# [RustCrypto]: CPU Intrinsics | ||
|
||
[![Crate][crate-image]][crate-link] | ||
[![Docs][docs-image]][docs-link] | ||
![Apache 2.0/MIT Licensed][license-image] | ||
![MSRV][rustc-image] | ||
[![Build Status][build-image]][build-link] | ||
|
||
High-level wrappers for architecture-specific CPU intrinsics which are not | ||
yet provided via [`core::arch`], implemented using inline assembly. | ||
|
||
[Documentation] | ||
|
||
## About | ||
|
||
Certain CPU instructions which are important for cryptographic applications | ||
are difficult to emit from LLVM due to various complicating factors. | ||
|
||
This crate provides high-level architecture-specific wrappers for these | ||
instructions built on stable inline assembly. No attempts at abstraction | ||
are made, just raw access to specific CPU instructions which are guaranteed | ||
to be emitted verbatim and not optimized away or otherwise rewritten by the | ||
compiler. | ||
|
||
## Supported Instructions | ||
|
||
### `x86` (32-bit) | ||
|
||
- `cmovz` (a.k.a. `cmove`) | ||
- `cmovnz` (a.k.a. `cmovne`) | ||
|
||
### `x86_64` | ||
|
||
- `cmovz` (a.k.a. `cmove`) | ||
- `cmovnz` (a.k.a. `cmovne`) | ||
|
||
## Minimum Supported Rust Version | ||
|
||
Rust **1.59** or newer. | ||
|
||
In the future, we reserve the right to change MSRV (i.e. MSRV is out-of-scope | ||
for this crate's SemVer guarantees), however when we do it will be accompanied by | ||
a minor version bump. | ||
|
||
## License | ||
|
||
Licensed under either of: | ||
|
||
* [Apache License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0) | ||
* [MIT license](http://opensource.org/licenses/MIT) | ||
|
||
at your option. | ||
|
||
### Contribution | ||
|
||
Unless you explicitly state otherwise, any contribution intentionally submitted | ||
for inclusion in the work by you, as defined in the Apache-2.0 license, shall be | ||
dual licensed as above, without any additional terms or conditions. | ||
|
||
[//]: # (badges) | ||
|
||
[crate-image]: https://img.shields.io/crates/v/crypto-intrinsics.svg | ||
[crate-link]: https://crates.io/crates/crypto-intrinsics | ||
[docs-image]: https://docs.rs/crypto-intrinsics/badge.svg | ||
[docs-link]: https://docs.rs/crypto-intrinsics/ | ||
[license-image]: https://img.shields.io/badge/license-Apache2.0/MIT-blue.svg | ||
[rustc-image]: https://img.shields.io/badge/rustc-1.51+-blue.svg | ||
[build-image]: https://github.com/RustCrypto/utils/actions/workflows/crypto-intrinsics.yml/badge.svg | ||
[build-link]: https://github.com/RustCrypto/utils/actions/workflows/crypto-intrinsics.yml | ||
|
||
[//]: # (general links) | ||
|
||
[RustCrypto]: https://github.com/RustCrypto | ||
[Documentation]: https://docs.rs/crypto-intrinsics | ||
[`core::arch`]: https://doc.rust-lang.org/core/arch/index.html |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
#![no_std] | ||
#![cfg_attr(docsrs, feature(doc_cfg))] | ||
#![doc = include_str!("../README.md")] | ||
#![doc( | ||
html_logo_url = "https://raw.githubusercontent.com/RustCrypto/meta/master/logo.svg", | ||
html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/meta/master/logo.svg" | ||
)] | ||
#![warn(missing_docs, rust_2018_idioms, unused_qualifications)] | ||
|
||
#[cfg(target_arch = "x86")] | ||
#[cfg_attr(docsrs, doc(cfg(target_arch = "x86")))] | ||
pub mod x86; | ||
|
||
#[cfg(target_arch = "x86_64")] | ||
#[cfg_attr(docsrs, doc(cfg(target_arch = "x86_64")))] | ||
pub mod x86_64; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
//! `x86` intrinsics (32-bit) | ||
|
||
use core::arch::asm; | ||
|
||
/// Move if zero. | ||
/// | ||
/// Uses a `test` instruction to check if the given `condition` value is | ||
/// equal to zero, then calls `cmovz` (a.k.a. `cmove`) to conditionally move | ||
/// `src` to `dst` when `condition` is equal to zero. | ||
#[inline(always)] | ||
pub fn cmovz(condition: u32, src: u32, dst: &mut u32) { | ||
unsafe { | ||
asm! { | ||
"test {0}, {0}", | ||
"cmovz {1}, {2}", | ||
in(reg) condition, | ||
inlateout(reg) *dst, | ||
in(reg) src | ||
}; | ||
} | ||
} | ||
|
||
/// Move if not zero. | ||
/// | ||
/// Uses a `test` instruction to check if the given `condition` value is not | ||
/// equal to zero, then calls `cmovnz` (a.k.a. `cmovne`) to conditionally move | ||
/// `src` to `dst` when `condition` is nonzero. | ||
#[inline(always)] | ||
pub fn cmovnz(condition: u32, src: u32, dst: &mut u32) { | ||
unsafe { | ||
asm! { | ||
"test {0}, {0}", | ||
"cmovnz {1}, {2}", | ||
in(reg) condition, | ||
inlateout(reg) *dst, | ||
in(reg) src | ||
}; | ||
} | ||
} | ||
|
||
#[cfg(test)] | ||
mod tests { | ||
use super::*; | ||
|
||
#[test] | ||
fn cmovz_works() { | ||
let mut n = 24; | ||
cmovz(42, 42, &mut n); | ||
assert_eq!(n, 24); | ||
cmovz(0, 42, &mut n); | ||
assert_eq!(n, 42); | ||
} | ||
|
||
#[test] | ||
fn cmovnz_works() { | ||
let mut n = 24; | ||
cmovnz(0, 42, &mut n); | ||
assert_eq!(n, 24); | ||
cmovnz(42, 42, &mut n); | ||
assert_eq!(n, 42); | ||
} | ||
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
//! `x86_64` intrinsics | ||
|
||
use core::arch::asm; | ||
|
||
/// Move if zero. | ||
/// | ||
/// Uses a `test` instruction to check if the given `condition` value is | ||
/// equal to zero, then calls `cmovz` (a.k.a. `cmove`) to conditionally move | ||
/// `src` to `dst` when `condition` is equal to zero. | ||
#[inline(always)] | ||
pub fn cmovz(condition: u64, src: u64, dst: &mut u64) { | ||
tarcieri marked this conversation as resolved.
Show resolved
Hide resolved
|
||
unsafe { | ||
asm! { | ||
"test {0}, {0}", | ||
"cmovz {1}, {2}", | ||
in(reg) condition, | ||
inlateout(reg) *dst, | ||
in(reg) src | ||
}; | ||
} | ||
} | ||
|
||
/// Move if not zero. | ||
/// | ||
/// Uses a `test` instruction to check if the given `condition` value is not | ||
/// equal to zero, then calls `cmovnz` (a.k.a. `cmovne`) to conditionally move | ||
/// `src` to `dst` when `condition` is nonzero. | ||
#[inline(always)] | ||
pub fn cmovnz(condition: u64, src: u64, dst: &mut u64) { | ||
unsafe { | ||
asm! { | ||
"test {0}, {0}", | ||
"cmovnz {1}, {2}", | ||
in(reg) condition, | ||
inlateout(reg) *dst, | ||
in(reg) src | ||
}; | ||
} | ||
} | ||
|
||
#[cfg(test)] | ||
mod tests { | ||
use super::*; | ||
|
||
#[test] | ||
fn cmovz_works() { | ||
let mut n = 24; | ||
cmovz(42, 42, &mut n); | ||
assert_eq!(n, 24); | ||
cmovz(0, 42, &mut n); | ||
assert_eq!(n, 42); | ||
} | ||
|
||
#[test] | ||
fn cmovnz_works() { | ||
let mut n = 24; | ||
cmovnz(0, 42, &mut n); | ||
assert_eq!(n, 24); | ||
cmovnz(42, 42, &mut n); | ||
assert_eq!(n, 42); | ||
} | ||
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
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.