Use --cfg curve25519_dalek_backend to select backend (#455)

Crate features are intended to be additive, whereas only 1-of-N possible
backends can be selected.

Features can also be activated by transitive dependencies, which leads
to a problem of different dependences selecting conflicting backends.
Using `--cfg` instead moves all backend selection control to the
toplevel executable.

This commit switches to the following RUSTFLAGS to enable backends:

- `--cfg curve25519_dalek_backend="fiat"`: uses `fiat-crypto`
- `--cfg curve25519_dalek_backend="simd"`: uses nightly-only SIMD
This commit is contained in:
Tony Arcieri 2022-12-09 01:42:52 -07:00 committed by GitHub
parent f5dada3834
commit cc304c29ff
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
11 changed files with 39 additions and 35 deletions

View file

@ -29,8 +29,10 @@ jobs:
- run: ${{ matrix.deps }}
- run: cargo test --target ${{ matrix.target }} --no-default-features
- run: cargo test --target ${{ matrix.target }}
- run: cargo test --target ${{ matrix.target }} --features fiat_backend
- run: cargo test --target ${{ matrix.target }} --features serde
- env:
RUSTFLAGS: '--cfg curve25519_dalek_backend="fiat"'
run: cargo test --target ${{ matrix.target }}
build-simd:
name: Build simd backend (nightly)
@ -40,11 +42,11 @@ jobs:
- uses: dtolnay/rust-toolchain@nightly
# Build with AVX2 features, then with AVX512 features
- env:
RUSTFLAGS: "-C target_feature=+avx2"
run: cargo build --target x86_64-unknown-linux-gnu --features simd_backend
RUSTFLAGS: '--cfg curve25519_dalek_backend="simd" -C target_feature=+avx2'
run: cargo build --target x86_64-unknown-linux-gnu
- env:
RUSTFLAGS: "-C target_feature=+avx512ifma"
run: cargo build --target x86_64-unknown-linux-gnu --features simd_backend
RUSTFLAGS: '--cfg curve25519_dalek_backend="simd" -C target_feature=+avx512ifma'
run: cargo build --target x86_64-unknown-linux-gnu
nightly:
name: Test nightly compiler
@ -63,11 +65,11 @@ jobs:
with:
components: clippy
- env:
RUSTFLAGS: "-C target_feature=+avx2"
run: cargo clippy --target x86_64-unknown-linux-gnu --features simd_backend -- -D warnings
RUSTFLAGS: '--cfg curve25519_dalek_backend="simd" -C target_feature=+avx2'
run: cargo clippy --target x86_64-unknown-linux-gnu
- env:
RUSTFLAGS: "-C target_feature=+avx512ifma"
run: cargo clippy --target x86_64-unknown-linux-gnu --features simd_backend -- -D warnings
RUSTFLAGS: '--cfg curve25519_dalek_backend="simd" -C target_feature=+avx512ifma'
run: cargo clippy --target x86_64-unknown-linux-gnu
rustfmt:
name: Check formatting
@ -87,11 +89,11 @@ jobs:
# First run `cargo +nightly -Z minimal-verisons check` in order to get a
# Cargo.lock with the oldest possible deps
- uses: dtolnay/rust-toolchain@nightly
- run: cargo -Z minimal-versions check --no-default-features --features fiat_backend,serde
- run: cargo -Z minimal-versions check --no-default-features --features serde
# Now check that `cargo build` works with respect to the oldest possible
# deps and the stated MSRV
- uses: dtolnay/rust-toolchain@1.56.1
- run: cargo build --no-default-features --features fiat_backend,serde
- run: cargo build --no-default-features --features serde
bench:
name: Check that benchmarks compile
@ -100,8 +102,12 @@ jobs:
- uses: actions/checkout@v3
- uses: dtolnay/rust-toolchain@stable
- name: Build u32 bench
run: env RUSTFLAGS="--cfg curve25519_dalek_bits=\"32\"" cargo build --benches
env:
RUSTFLAGS: '--cfg curve25519_dalek_bits="32"'
run: cargo build --benches
- name: Build u64 bench
run: env RUSTFLAGS="--cfg curve25519_dalek_bits=\"64\"" cargo build --benches
env:
RUSTFLAGS: '--cfg curve25519_dalek_bits="64"'
run: cargo build --benches
- name: Build default (host native) bench
run: cargo build --benches

View file

@ -49,17 +49,16 @@ rand_core = { version = "0.6", default-features = false, optional = true }
digest = { version = "0.10", default-features = false, optional = true }
subtle = { version = "^2.2.1", default-features = false }
serde = { version = "1.0", default-features = false, optional = true, features = ["derive"] }
zeroize = { version = "1", default-features = false }
[target.'cfg(curve25519_dalek_backend = "fiat")'.dependencies]
fiat-crypto = "0.1.6"
# The original packed_simd package was orphaned, see
# https://github.com/rust-lang/packed_simd/issues/303#issuecomment-701361161
packed_simd = { version = "0.3.4", package = "packed_simd_2", features = ["into_bits"], optional = true }
zeroize = { version = "1", default-features = false }
fiat-crypto = { version = "0.1.6", optional = true}
[target.'cfg(curve25519_dalek_backend = "simd")'.dependencies]
packed_simd = { version = "0.3.4", package = "packed_simd_2", features = ["into_bits"] }
[features]
default = ["alloc"]
alloc = ["zeroize/alloc"]
# fiat-crypto backend with formally-verified field arithmetic
fiat_backend = ["fiat-crypto"]
# The SIMD backend uses parallel formulas, using either AVX2 or AVX512-IFMA.
simd_backend = ["packed_simd"]

View file

@ -36,5 +36,5 @@
pub mod serial;
#[cfg(any(feature = "simd_backend", docsrs))]
#[cfg(any(curve25519_dalek_backend = "simd", docsrs))]
pub mod vector;

View file

@ -21,8 +21,7 @@
use cfg_if::cfg_if;
cfg_if! {
if #[cfg(feature = "fiat_backend")] {
if #[cfg(curve25519_dalek_backend = "fiat")] {
#[cfg(curve25519_dalek_bits = "32")]
pub mod fiat_u32;
@ -44,7 +43,7 @@ cfg_if! {
pub mod curve_models;
#[cfg(not(all(
feature = "simd_backend",
curve25519_dalek_backend = "simd",
any(target_feature = "avx2", target_feature = "avx512ifma")
)))]
pub mod scalar_mul;

View file

@ -12,7 +12,7 @@
#![doc = include_str!("../../../docs/parallel-formulas.md")]
#[cfg(not(any(target_feature = "avx2", target_feature = "avx512ifma", docsrs)))]
compile_error!("simd_backend selected without target_feature=+avx2 or +avx512ifma");
compile_error!("'simd' backend selected without target_feature=+avx2 or +avx512ifma");
#[cfg(any(
all(target_feature = "avx2", not(target_feature = "avx512ifma")),

View file

@ -37,7 +37,7 @@ use crate::ristretto::RistrettoPoint;
use crate::scalar::Scalar;
cfg_if! {
if #[cfg(feature = "fiat_backend")] {
if #[cfg(curve25519_dalek_backend = "fiat")] {
#[cfg(curve25519_dalek_bits = "32")]
pub use crate::backend::serial::fiat_u32::constants::*;
#[cfg(curve25519_dalek_bits = "64")]
@ -149,7 +149,7 @@ mod test {
/// Test that d = -121665/121666
#[test]
#[cfg(all(curve25519_dalek_bits = "32", not(feature = "fiat_backend")))]
#[cfg(all(curve25519_dalek_bits = "32", not(curve25519_dalek_backend = "fiat")))]
fn test_d_vs_ratio() {
use crate::backend::serial::u32::field::FieldElement2625;
let a = -&FieldElement2625([121665, 0, 0, 0, 0, 0, 0, 0, 0, 0]);
@ -162,7 +162,7 @@ mod test {
/// Test that d = -121665/121666
#[test]
#[cfg(all(curve25519_dalek_bits = "64", not(feature = "fiat_backend")))]
#[cfg(all(curve25519_dalek_bits = "64", not(curve25519_dalek_backend = "fiat")))]
fn test_d_vs_ratio() {
use crate::backend::serial::u64::field::FieldElement51;
let a = -&FieldElement51([121665, 0, 0, 0, 0]);

View file

@ -139,12 +139,12 @@ use crate::traits::MultiscalarMul;
use crate::traits::{VartimeMultiscalarMul, VartimePrecomputedMultiscalarMul};
#[cfg(not(all(
feature = "simd_backend",
curve25519_dalek_backend = "simd",
any(target_feature = "avx2", target_feature = "avx512ifma")
)))]
use crate::backend::serial::scalar_mul;
#[cfg(all(
feature = "simd_backend",
curve25519_dalek_backend = "simd",
any(target_feature = "avx2", target_feature = "avx512ifma")
))]
use crate::backend::vector::scalar_mul;

View file

@ -36,7 +36,7 @@ use crate::backend;
use crate::constants;
cfg_if! {
if #[cfg(feature = "fiat_backend")] {
if #[cfg(curve25519_dalek_backend = "fiat")] {
#[cfg(curve25519_dalek_bits = "32")]
pub use backend::serial::fiat_u32::field::*;
#[cfg(curve25519_dalek_bits = "64")]

View file

@ -10,7 +10,7 @@
// - Henry de Valence <hdevalence@hdevalence.ca>
#![no_std]
#![cfg_attr(feature = "simd_backend", feature(stdsimd))]
#![cfg_attr(curve25519_dalek_backend = "simd", feature(stdsimd))]
#![cfg_attr(docsrs, feature(doc_auto_cfg, doc_cfg, doc_cfg_hide))]
#![cfg_attr(docsrs, doc(cfg_hide(docsrs)))]
//------------------------------------------------------------------------

View file

@ -202,7 +202,7 @@ use crate::traits::{MultiscalarMul, VartimeMultiscalarMul, VartimePrecomputedMul
#[cfg(feature = "alloc")]
cfg_if! {
if #[cfg(all(
feature = "simd_backend",
curve25519_dalek_backend = "simd",
any(target_feature = "avx2", target_feature = "avx512ifma")
))] {
use crate::backend::vector::scalar_mul;

View file

@ -170,7 +170,7 @@ use crate::backend;
use crate::constants;
cfg_if! {
if #[cfg(feature = "fiat_backend")] {
if #[cfg(curve25519_dalek_backend = "fiat")] {
/// An `UnpackedScalar` represents an element of the field GF(l), optimized for speed.
///
/// This is a type alias for one of the scalar types in the `backend`