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