mirror of
https://github.com/saymrwulf/curve25519-dalek-source.git
synced 2026-09-04 20:24:10 +00:00
Replace avx2_backend with simd_backend (autoselects AVX2/IFMA)
This commit is contained in:
parent
9ed2128a10
commit
47a164da4d
6 changed files with 60 additions and 65 deletions
|
|
@ -69,10 +69,10 @@ yolocrypto = []
|
|||
u32_backend = []
|
||||
# The u64 backend uses u64s with u128 products.
|
||||
u64_backend = []
|
||||
# The AVX2 backend uses u32x8s with u64x4 products.
|
||||
# It uses the u64 code for serial operations.
|
||||
avx2_backend = ["nightly", "u64_backend", "packed_simd"]
|
||||
ifma_backend = ["nightly", "u64_backend", "packed_simd", "yolocrypto"]
|
||||
# The SIMD backend uses parallel formulas, using either AVX2 or AVX512-IFMA.
|
||||
simd_backend = ["nightly", "u64_backend", "packed_simd"]
|
||||
# Old name for the SIMD backend, preserved for compatibility
|
||||
avx2_backend = ["simd_backend"]
|
||||
|
||||
# Signals that we're in the main build stage. This is off by default,
|
||||
# to signal stage 1 of the build, where build.rs loads the library
|
||||
|
|
|
|||
12
build.rs
12
build.rs
|
|
@ -1,5 +1,11 @@
|
|||
#![cfg_attr(feature = "ifma_backend", feature(simd_ffi))]
|
||||
#![cfg_attr(feature = "ifma_backend", feature(link_llvm_intrinsics))]
|
||||
#![cfg_attr(
|
||||
all(feature = "simd_backend", target_feature = "avx512ifma"),
|
||||
feature(simd_ffi)
|
||||
)]
|
||||
#![cfg_attr(
|
||||
all(feature = "simd_backend", target_feature = "avx512ifma"),
|
||||
feature(link_llvm_intrinsics)
|
||||
)]
|
||||
#![cfg_attr(all(feature = "alloc", not(feature = "std")), feature(alloc))]
|
||||
#![cfg_attr(feature = "nightly", feature(cfg_target_feature))]
|
||||
#![allow(unused_variables)]
|
||||
|
|
@ -15,7 +21,7 @@ extern crate digest;
|
|||
extern crate rand;
|
||||
extern crate subtle;
|
||||
|
||||
#[cfg(all(feature = "nightly", any(feature = "avx2_backend", feature = "ifma_backend")))]
|
||||
#[cfg(all(feature = "nightly", feature = "packed_simd"))]
|
||||
extern crate packed_simd;
|
||||
|
||||
use std::env;
|
||||
|
|
|
|||
|
|
@ -24,17 +24,17 @@
|
|||
#[cfg(not(any(
|
||||
feature = "u32_backend",
|
||||
feature = "u64_backend",
|
||||
feature = "avx2_backend"
|
||||
feature = "simd_backend",
|
||||
)))]
|
||||
compile_error!(
|
||||
"no curve25519-dalek backend cargo feature enabled! \
|
||||
please enable one of: u32_backend, u64_backend, avx2_backend"
|
||||
please enable one of: u32_backend, u64_backend, simd_backend"
|
||||
);
|
||||
|
||||
pub mod serial;
|
||||
|
||||
#[cfg(any(
|
||||
all(feature = "ifma_backend", target_feature = "avx512ifma"),
|
||||
all(feature = "avx2_backend", target_feature = "avx2"),
|
||||
#[cfg(all(
|
||||
feature = "simd_backend",
|
||||
any(target_feature = "avx2", target_feature = "avx512ifma")
|
||||
))]
|
||||
pub mod vector;
|
||||
|
|
|
|||
|
|
@ -21,15 +21,17 @@
|
|||
//! `32bit` since identifiers can't start with letters, and the backends
|
||||
//! do use `u32`/`u64`, so this seems like a least-bad option.
|
||||
|
||||
#[cfg(all(feature = "avx2_backend", target_feature = "avx2"))]
|
||||
#[cfg(not(any(target_feature = "avx2", target_feature = "avx512ifma",)))]
|
||||
compile_error!("simd_backend selected without target_feature=+avx2 or +avx512ifma");
|
||||
|
||||
#[cfg(all(target_feature = "avx2", not(target_feature = "avx512ifma")))]
|
||||
pub mod avx2;
|
||||
#[cfg(all(feature = "avx2_backend", target_feature = "avx2"))]
|
||||
#[cfg(all(target_feature = "avx2", not(target_feature = "avx512ifma")))]
|
||||
pub(crate) use self::avx2::{
|
||||
constants::BASEPOINT_ODD_LOOKUP_TABLE, edwards::CachedPoint, edwards::ExtendedPoint,
|
||||
};
|
||||
|
||||
#[cfg(all(feature = "ifma_backend", target_feature = "avx512ifma"))]
|
||||
#[cfg(all(target_feature = "avx512ifma"))]
|
||||
pub mod ifma;
|
||||
|
||||
pub mod scalar_mul;
|
||||
|
||||
|
|
|
|||
|
|
@ -130,6 +130,17 @@ use traits::MultiscalarMul;
|
|||
#[cfg(any(feature = "alloc", feature = "std"))]
|
||||
use traits::VartimeMultiscalarMul;
|
||||
|
||||
#[cfg(not(all(
|
||||
feature = "simd_backend",
|
||||
any(target_feature = "avx2", target_feature = "avx512ifma")
|
||||
)))]
|
||||
use backend::serial::scalar_mul;
|
||||
#[cfg(all(
|
||||
feature = "simd_backend",
|
||||
any(target_feature = "avx2", target_feature = "avx512ifma")
|
||||
))]
|
||||
use backend::vector::scalar_mul;
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
// Compressed points
|
||||
// ------------------------------------------------------------------------
|
||||
|
|
@ -572,18 +583,7 @@ impl<'a, 'b> Mul<&'b Scalar> for &'a EdwardsPoint {
|
|||
/// For scalar multiplication of a basepoint,
|
||||
/// `EdwardsBasepointTable` is approximately 4x faster.
|
||||
fn mul(self, scalar: &'b Scalar) -> EdwardsPoint {
|
||||
// If we built with AVX2, use the AVX2 backend.
|
||||
#[cfg(all(feature="avx2_backend", target_feature="avx2"))]
|
||||
{
|
||||
use backend::vector::scalar_mul::variable_base::mul;
|
||||
mul(self, scalar)
|
||||
}
|
||||
// Otherwise, use the serial backend:
|
||||
#[cfg(not(all(feature="avx2_backend", target_feature="avx2")))]
|
||||
{
|
||||
use backend::serial::scalar_mul::variable_base::mul;
|
||||
mul(self, scalar)
|
||||
}
|
||||
scalar_mul::variable_base::mul(self, scalar)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -634,14 +634,7 @@ impl MultiscalarMul for EdwardsPoint {
|
|||
// size-dependent algorithm dispatch, use this as the hint.
|
||||
let _size = s_lo;
|
||||
|
||||
// If we built with AVX2, use the AVX2 backend.
|
||||
#[cfg(all(feature="avx2_backend", target_feature="avx2"))]
|
||||
use backend::vector::scalar_mul::straus::Straus;
|
||||
// Otherwise, proceed as normal:
|
||||
#[cfg(not(all(feature="avx2_backend", target_feature="avx2")))]
|
||||
use backend::serial::scalar_mul::straus::Straus;
|
||||
|
||||
Straus::multiscalar_mul(scalars, points)
|
||||
scalar_mul::straus::Straus::multiscalar_mul(scalars, points)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -672,29 +665,19 @@ impl VartimeMultiscalarMul for EdwardsPoint {
|
|||
// size-dependent algorithm dispatch, use this as the hint.
|
||||
let _size = s_lo;
|
||||
|
||||
// If we built with AVX2, use the AVX2 backend.
|
||||
#[cfg(all(feature="avx2_backend", target_feature="avx2"))]
|
||||
use backend::vector::scalar_mul::straus::Straus;
|
||||
// Otherwise, proceed as normal:
|
||||
#[cfg(not(all(feature="avx2_backend", target_feature="avx2")))]
|
||||
use backend::serial::scalar_mul::straus::Straus;
|
||||
|
||||
Straus::optional_multiscalar_mul(scalars, points)
|
||||
scalar_mul::straus::Straus::optional_multiscalar_mul(scalars, points)
|
||||
}
|
||||
}
|
||||
|
||||
impl EdwardsPoint {
|
||||
/// Compute \\(aA + bB\\) in variable time, where \\(B\\) is the Ed25519 basepoint.
|
||||
#[cfg(feature = "stage2_build")]
|
||||
pub fn vartime_double_scalar_mul_basepoint(a: &Scalar, A: &EdwardsPoint, b: &Scalar) -> EdwardsPoint {
|
||||
// If we built with AVX2, use the AVX2 backend.
|
||||
#[cfg(all(feature="avx2_backend", target_feature="avx2"))]
|
||||
use backend::vector::scalar_mul::vartime_double_base;
|
||||
// Otherwise, use the serial backend:
|
||||
#[cfg(not(all(feature="avx2_backend", target_feature="avx2")))]
|
||||
use backend::serial::scalar_mul::vartime_double_base;
|
||||
|
||||
vartime_double_base::mul(a, A, b)
|
||||
pub fn vartime_double_scalar_mul_basepoint(
|
||||
a: &Scalar,
|
||||
A: &EdwardsPoint,
|
||||
b: &Scalar,
|
||||
) -> EdwardsPoint {
|
||||
scalar_mul::vartime_double_base::mul(a, A, b)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
24
src/lib.rs
24
src/lib.rs
|
|
@ -9,14 +9,18 @@
|
|||
// - Henry de Valence <hdevalence@hdevalence.ca>
|
||||
|
||||
#![no_std]
|
||||
|
||||
#![cfg_attr(feature = "ifma_backend", feature(simd_ffi))]
|
||||
#![cfg_attr(feature = "ifma_backend", feature(link_llvm_intrinsics))]
|
||||
|
||||
#![cfg_attr(
|
||||
all(feature = "simd_backend", target_feature = "avx512ifma"),
|
||||
feature(simd_ffi)
|
||||
)]
|
||||
#![cfg_attr(
|
||||
all(feature = "simd_backend", target_feature = "avx512ifma"),
|
||||
feature(link_llvm_intrinsics)
|
||||
)]
|
||||
#![cfg_attr(feature = "nightly", feature(test))]
|
||||
#![cfg_attr(all(feature = "alloc", not(feature = "std")), feature(alloc))]
|
||||
#![cfg_attr(feature = "nightly", feature(cfg_target_feature))]
|
||||
#![cfg_attr(feature = "nightly", feature(external_doc))]
|
||||
|
||||
// Refuse to compile if documentation is missing, but only on nightly.
|
||||
//
|
||||
// This means that missing docs will still fail CI, but means we can use
|
||||
|
|
@ -41,21 +45,21 @@ extern crate alloc;
|
|||
#[macro_use]
|
||||
extern crate std;
|
||||
|
||||
#[cfg(all(feature = "nightly", any(feature = "avx2_backend", feature = "ifma_backend")))]
|
||||
#[cfg(all(feature = "nightly", feature = "packed_simd"))]
|
||||
extern crate packed_simd;
|
||||
|
||||
extern crate rand;
|
||||
extern crate clear_on_drop;
|
||||
extern crate byteorder;
|
||||
extern crate clear_on_drop;
|
||||
pub extern crate digest;
|
||||
extern crate rand;
|
||||
|
||||
// Used for traits related to constant-time code.
|
||||
extern crate subtle;
|
||||
|
||||
#[cfg(feature = "serde")]
|
||||
extern crate serde;
|
||||
#[cfg(all(test, feature = "serde"))]
|
||||
extern crate bincode;
|
||||
#[cfg(feature = "serde")]
|
||||
extern crate serde;
|
||||
|
||||
// Internal macros. Must come first!
|
||||
#[macro_use]
|
||||
|
|
|
|||
Loading…
Reference in a new issue