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: ${{ matrix.deps }}
- run: cargo test --target ${{ matrix.target }} --no-default-features - run: cargo test --target ${{ matrix.target }} --no-default-features
- run: cargo test --target ${{ matrix.target }} - run: cargo test --target ${{ matrix.target }}
- run: cargo test --target ${{ matrix.target }} --features fiat_backend
- run: cargo test --target ${{ matrix.target }} --features serde - run: cargo test --target ${{ matrix.target }} --features serde
- env:
RUSTFLAGS: '--cfg curve25519_dalek_backend="fiat"'
run: cargo test --target ${{ matrix.target }}
build-simd: build-simd:
name: Build simd backend (nightly) name: Build simd backend (nightly)
@ -40,11 +42,11 @@ jobs:
- uses: dtolnay/rust-toolchain@nightly - uses: dtolnay/rust-toolchain@nightly
# Build with AVX2 features, then with AVX512 features # Build with AVX2 features, then with AVX512 features
- env: - env:
RUSTFLAGS: "-C target_feature=+avx2" RUSTFLAGS: '--cfg curve25519_dalek_backend="simd" -C target_feature=+avx2'
run: cargo build --target x86_64-unknown-linux-gnu --features simd_backend run: cargo build --target x86_64-unknown-linux-gnu
- env: - env:
RUSTFLAGS: "-C target_feature=+avx512ifma" RUSTFLAGS: '--cfg curve25519_dalek_backend="simd" -C target_feature=+avx512ifma'
run: cargo build --target x86_64-unknown-linux-gnu --features simd_backend run: cargo build --target x86_64-unknown-linux-gnu
nightly: nightly:
name: Test nightly compiler name: Test nightly compiler
@ -63,11 +65,11 @@ jobs:
with: with:
components: clippy components: clippy
- env: - env:
RUSTFLAGS: "-C target_feature=+avx2" RUSTFLAGS: '--cfg curve25519_dalek_backend="simd" -C target_feature=+avx2'
run: cargo clippy --target x86_64-unknown-linux-gnu --features simd_backend -- -D warnings run: cargo clippy --target x86_64-unknown-linux-gnu
- env: - env:
RUSTFLAGS: "-C target_feature=+avx512ifma" RUSTFLAGS: '--cfg curve25519_dalek_backend="simd" -C target_feature=+avx512ifma'
run: cargo clippy --target x86_64-unknown-linux-gnu --features simd_backend -- -D warnings run: cargo clippy --target x86_64-unknown-linux-gnu
rustfmt: rustfmt:
name: Check formatting name: Check formatting
@ -87,11 +89,11 @@ jobs:
# First run `cargo +nightly -Z minimal-verisons check` in order to get a # First run `cargo +nightly -Z minimal-verisons check` in order to get a
# Cargo.lock with the oldest possible deps # Cargo.lock with the oldest possible deps
- uses: dtolnay/rust-toolchain@nightly - 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 # Now check that `cargo build` works with respect to the oldest possible
# deps and the stated MSRV # deps and the stated MSRV
- uses: dtolnay/rust-toolchain@1.56.1 - 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: bench:
name: Check that benchmarks compile name: Check that benchmarks compile
@ -100,8 +102,12 @@ jobs:
- uses: actions/checkout@v3 - uses: actions/checkout@v3
- uses: dtolnay/rust-toolchain@stable - uses: dtolnay/rust-toolchain@stable
- name: Build u32 bench - 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 - 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 - name: Build default (host native) bench
run: cargo build --benches 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 } digest = { version = "0.10", default-features = false, optional = true }
subtle = { version = "^2.2.1", default-features = false } subtle = { version = "^2.2.1", default-features = false }
serde = { version = "1.0", default-features = false, optional = true, features = ["derive"] } 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 # The original packed_simd package was orphaned, see
# https://github.com/rust-lang/packed_simd/issues/303#issuecomment-701361161 # 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 } [target.'cfg(curve25519_dalek_backend = "simd")'.dependencies]
zeroize = { version = "1", default-features = false } packed_simd = { version = "0.3.4", package = "packed_simd_2", features = ["into_bits"] }
fiat-crypto = { version = "0.1.6", optional = true}
[features] [features]
default = ["alloc"] default = ["alloc"]
alloc = ["zeroize/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; pub mod serial;
#[cfg(any(feature = "simd_backend", docsrs))] #[cfg(any(curve25519_dalek_backend = "simd", docsrs))]
pub mod vector; pub mod vector;

View file

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

View file

@ -12,7 +12,7 @@
#![doc = include_str!("../../../docs/parallel-formulas.md")] #![doc = include_str!("../../../docs/parallel-formulas.md")]
#[cfg(not(any(target_feature = "avx2", target_feature = "avx512ifma", docsrs)))] #[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( #[cfg(any(
all(target_feature = "avx2", not(target_feature = "avx512ifma")), all(target_feature = "avx2", not(target_feature = "avx512ifma")),

View file

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

View file

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

View file

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

View file

@ -10,7 +10,7 @@
// - Henry de Valence <hdevalence@hdevalence.ca> // - Henry de Valence <hdevalence@hdevalence.ca>
#![no_std] #![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, feature(doc_auto_cfg, doc_cfg, doc_cfg_hide))]
#![cfg_attr(docsrs, doc(cfg_hide(docsrs)))] #![cfg_attr(docsrs, doc(cfg_hide(docsrs)))]
//------------------------------------------------------------------------ //------------------------------------------------------------------------

View file

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

View file

@ -170,7 +170,7 @@ use crate::backend;
use crate::constants; use crate::constants;
cfg_if! { 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. /// 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` /// This is a type alias for one of the scalar types in the `backend`