Uh oh!
There was an error while loading. Please reload this page.
- Notifications
You must be signed in to change notification settings - Fork 167
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
Uh oh!
There was an error while loading. Please reload this page.
crypto-intrinsics #730
Changes from all commits
File filter
Filter by extension
Conversations
Uh oh!
There was an error while loading. Please reload this page.
Jump to
Uh oh!
There was an error while loading. Please reload this page.
Diff view
Diff view
There are no files selected for viewing
| 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 |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Uh oh!
There was an error while loading. Please reload this page.
| 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"] | ||
| 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 |
| 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; |
| 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); | ||
| } | ||
| } |
| 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.
Uh oh!There was an error while loading. Please reload this page. | ||
| 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); | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -29,12 +29,14 @@ pub trait Dbl { | ||
| /// `block<<1`, otherwise `(block<<1)^C`, where `C` is the non-leading | ||
| /// coefficients of the lexicographically first irreducible degree-b binary | ||
| /// polynomial with the minimal number of ones. | ||
| #[must_use] | ||
| fn dbl(self) -> Self; | ||
| /// Reverse double block. (alternatively: divbide block by x) | ||
| /// | ||
| /// If least significant bit of the block equals to zero will return | ||
| /// `block>>1`, otherwise `(block>>1)^(1<<n)^(C>>1)` | ||
| #[must_use] | ||
| fn inv_dbl(self) -> Self; | ||
tarcieri marked this conversation as resolved.
Uh oh!There was an error while loading. Please reload this page. | ||
| } | ||
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
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
inoutcrate.Uh oh!
There was an error while loading. Please reload this page.
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.lockand 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.