diff --git a/Cargo.toml b/Cargo.toml index 25b7ae1..8a2ea08 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -44,7 +44,7 @@ platforms = "3.0.2" [[bench]] name = "dalek_benchmarks" harness = false -required-features = ["rand_core"] +required-features = ["alloc", "rand_core"] [dependencies] cfg-if = "1" diff --git a/benches/dalek_benchmarks.rs b/benches/dalek_benchmarks.rs index bffe9a0..5f8fee4 100644 --- a/benches/dalek_benchmarks.rs +++ b/benches/dalek_benchmarks.rs @@ -32,10 +32,9 @@ mod edwards_benches { } fn consttime_fixed_base_scalar_mul(c: &mut Criterion) { - let B = constants::ED25519_BASEPOINT_TABLE; let s = Scalar::from(897987897u64).invert(); c.bench_function("Constant-time fixed-base scalar mul", move |b| { - b.iter(|| B * &s) + b.iter(|| EdwardsPoint::mul_base(&s)) }); } @@ -50,7 +49,7 @@ mod edwards_benches { fn vartime_double_base_scalar_mul(c: &mut Criterion) { c.bench_function("Variable-time aA+bB, A variable, B fixed", |bench| { let mut rng = thread_rng(); - let A = &Scalar::random(&mut rng) * constants::ED25519_BASEPOINT_TABLE; + let A = EdwardsPoint::mul_base(&Scalar::random(&mut rng)); bench.iter_batched( || (Scalar::random(&mut rng), Scalar::random(&mut rng)), |(a, b)| EdwardsPoint::vartime_double_scalar_mul_basepoint(&a, &A, &b), @@ -88,7 +87,7 @@ mod multiscalar_benches { fn construct_points(n: usize) -> Vec { let mut rng = thread_rng(); (0..n) - .map(|_| &Scalar::random(&mut rng) * constants::ED25519_BASEPOINT_TABLE) + .map(|_| EdwardsPoint::mul_base(&Scalar::random(&mut rng))) .collect() } diff --git a/src/backend/serial/scalar_mul/vartime_double_base.rs b/src/backend/serial/scalar_mul/vartime_double_base.rs index 66ed2db..cdb31a1 100644 --- a/src/backend/serial/scalar_mul/vartime_double_base.rs +++ b/src/backend/serial/scalar_mul/vartime_double_base.rs @@ -22,7 +22,11 @@ use crate::window::NafLookupTable5; /// Compute \\(aA + bB\\) in variable time, where \\(B\\) is the Ed25519 basepoint. pub fn mul(a: &Scalar, A: &EdwardsPoint, b: &Scalar) -> EdwardsPoint { let a_naf = a.non_adjacent_form(5); + + #[cfg(feature = "precomputed-tables")] let b_naf = b.non_adjacent_form(8); + #[cfg(not(feature = "precomputed-tables"))] + let b_naf = b.non_adjacent_form(5); // Find starting index let mut i: usize = 255; @@ -34,7 +38,11 @@ pub fn mul(a: &Scalar, A: &EdwardsPoint, b: &Scalar) -> EdwardsPoint { } let table_A = NafLookupTable5::::from(A); + #[cfg(feature = "precomputed-tables")] let table_B = &constants::AFFINE_ODD_MULTIPLES_OF_BASEPOINT; + #[cfg(not(feature = "precomputed-tables"))] + let table_B = + &NafLookupTable5::::from(&constants::ED25519_BASEPOINT_POINT); let mut r = ProjectivePoint::identity(); loop { diff --git a/src/backend/serial/u32/constants.rs b/src/backend/serial/u32/constants.rs index 8844e25..51ccbb9 100644 --- a/src/backend/serial/u32/constants.rs +++ b/src/backend/serial/u32/constants.rs @@ -15,12 +15,14 @@ use super::field::FieldElement2625; use super::scalar::Scalar29; -use crate::backend::serial::curve_models::AffineNielsPoint; use crate::edwards::EdwardsPoint; -use crate::window::NafLookupTable8; #[cfg(feature = "precomputed-tables")] -use crate::{edwards::EdwardsBasepointTable, window::LookupTable}; +use crate::{ + backend::serial::curve_models::AffineNielsPoint, + edwards::EdwardsBasepointTable, + window::{LookupTable, NafLookupTable8}, +}; /// The value of minus one, equal to `-&FieldElement::ONE` pub(crate) const MINUS_ONE: FieldElement2625 = FieldElement2625([ @@ -3896,6 +3898,7 @@ static ED25519_BASEPOINT_TABLE_INNER_DOC_HIDDEN: EdwardsBasepointTable = Edwards ]); /// Odd multiples of the basepoint `[B, 3B, 5B, 7B, 9B, 11B, 13B, 15B, ..., 127B]`. +#[cfg(feature = "precomputed-tables")] #[allow(dead_code)] pub(crate) const AFFINE_ODD_MULTIPLES_OF_BASEPOINT: NafLookupTable8 = NafLookupTable8([ diff --git a/src/backend/serial/u64/constants.rs b/src/backend/serial/u64/constants.rs index a17c811..1aaed31 100644 --- a/src/backend/serial/u64/constants.rs +++ b/src/backend/serial/u64/constants.rs @@ -13,12 +13,14 @@ use super::field::FieldElement51; use super::scalar::Scalar52; -use crate::backend::serial::curve_models::AffineNielsPoint; use crate::edwards::EdwardsPoint; -use crate::window::NafLookupTable8; #[cfg(feature = "precomputed-tables")] -use crate::{edwards::EdwardsBasepointTable, window::LookupTable}; +use crate::{ + backend::serial::curve_models::AffineNielsPoint, + edwards::EdwardsBasepointTable, + window::{LookupTable, NafLookupTable8}, +}; /// The value of minus one, equal to `-&FieldElement::ONE` pub(crate) const MINUS_ONE: FieldElement51 = FieldElement51([ @@ -6287,6 +6289,7 @@ static ED25519_BASEPOINT_TABLE_INNER_DOC_HIDDEN: EdwardsBasepointTable = Edwards ]); /// Odd multiples of the basepoint `[B, 3B, 5B, 7B, 9B, 11B, 13B, 15B, ..., 127B]`. +#[cfg(feature = "precomputed-tables")] #[allow(dead_code)] pub(crate) const AFFINE_ODD_MULTIPLES_OF_BASEPOINT: NafLookupTable8 = NafLookupTable8([ diff --git a/src/backend/vector/avx2/constants.rs b/src/backend/vector/avx2/constants.rs index ab11036..ad80f67 100644 --- a/src/backend/vector/avx2/constants.rs +++ b/src/backend/vector/avx2/constants.rs @@ -15,6 +15,8 @@ use packed_simd::u32x8; use crate::backend::vector::avx2::edwards::{CachedPoint, ExtendedPoint}; use crate::backend::vector::avx2::field::FieldElement2625x4; + +#[cfg(feature = "precomputed-tables")] use crate::window::NafLookupTable8; /// The identity element as an `ExtendedPoint`. @@ -96,6 +98,7 @@ pub(crate) static P_TIMES_16_HI: u32x8 = u32x8::new( ); /// Odd multiples of the Ed25519 basepoint: +#[cfg(feature = "precomputed-tables")] pub(crate) static BASEPOINT_ODD_LOOKUP_TABLE: NafLookupTable8 = NafLookupTable8([ CachedPoint(FieldElement2625x4([ u32x8::new( diff --git a/src/backend/vector/ifma/constants.rs b/src/backend/vector/ifma/constants.rs index e9dc24f..47b9b26 100644 --- a/src/backend/vector/ifma/constants.rs +++ b/src/backend/vector/ifma/constants.rs @@ -11,6 +11,7 @@ use packed_simd::u64x4; +#[cfg(feature = "precomputed-tables")] use crate::window::NafLookupTable8; use super::edwards::{CachedPoint, ExtendedPoint}; @@ -35,6 +36,7 @@ pub(crate) static CACHEDPOINT_IDENTITY: CachedPoint = CachedPoint(F51x4Reduced([ ])); /// Odd multiples of the Ed25519 basepoint: +#[cfg(feature = "precomputed-tables")] pub(crate) static BASEPOINT_ODD_LOOKUP_TABLE: NafLookupTable8 = NafLookupTable8([ CachedPoint(F51x4Reduced([ u64x4::new(1277522120965857, 73557767439946, 243332, 1943719795065404), diff --git a/src/backend/vector/mod.rs b/src/backend/vector/mod.rs index 1f3a40c..f81648e 100644 --- a/src/backend/vector/mod.rs +++ b/src/backend/vector/mod.rs @@ -23,16 +23,12 @@ pub mod avx2; all(target_feature = "avx2", not(target_feature = "avx512ifma")), all(docsrs, target_arch = "x86_64") ))] -pub(crate) use self::avx2::{ - constants::BASEPOINT_ODD_LOOKUP_TABLE, edwards::CachedPoint, edwards::ExtendedPoint, -}; +pub(crate) use self::avx2::{edwards::CachedPoint, edwards::ExtendedPoint}; #[cfg(any(target_feature = "avx512ifma", all(docsrs, target_arch = "x86_64")))] pub mod ifma; #[cfg(target_feature = "avx512ifma")] -pub(crate) use self::ifma::{ - constants::BASEPOINT_ODD_LOOKUP_TABLE, edwards::CachedPoint, edwards::ExtendedPoint, -}; +pub(crate) use self::ifma::{edwards::CachedPoint, edwards::ExtendedPoint}; #[cfg(any( target_feature = "avx2", @@ -41,3 +37,21 @@ pub(crate) use self::ifma::{ ))] #[allow(missing_docs)] pub mod scalar_mul; + +// Precomputed table re-exports + +#[cfg(any( + all( + target_feature = "avx2", + not(target_feature = "avx512ifma"), + feature = "precomputed-tables" + ), + all(docsrs, target_arch = "x86_64") +))] +pub(crate) use self::avx2::constants::BASEPOINT_ODD_LOOKUP_TABLE; + +#[cfg(any( + all(target_feature = "avx512ifma", feature = "precomputed-tables"), + all(docsrs, target_arch = "x86_64") +))] +pub(crate) use self::ifma::constants::BASEPOINT_ODD_LOOKUP_TABLE; diff --git a/src/backend/vector/scalar_mul/vartime_double_base.rs b/src/backend/vector/scalar_mul/vartime_double_base.rs index b25e773..5ec69ed 100644 --- a/src/backend/vector/scalar_mul/vartime_double_base.rs +++ b/src/backend/vector/scalar_mul/vartime_double_base.rs @@ -13,7 +13,6 @@ use core::cmp::Ordering; -use crate::backend::vector::BASEPOINT_ODD_LOOKUP_TABLE; use crate::backend::vector::{CachedPoint, ExtendedPoint}; use crate::edwards::EdwardsPoint; use crate::scalar::Scalar; @@ -23,7 +22,11 @@ use crate::window::NafLookupTable5; /// Compute \\(aA + bB\\) in variable time, where \\(B\\) is the Ed25519 basepoint. pub fn mul(a: &Scalar, A: &EdwardsPoint, b: &Scalar) -> EdwardsPoint { let a_naf = a.non_adjacent_form(5); + + #[cfg(feature = "precomputed-tables")] let b_naf = b.non_adjacent_form(8); + #[cfg(not(feature = "precomputed-tables"))] + let b_naf = b.non_adjacent_form(5); // Find starting index let mut i: usize = 255; @@ -35,7 +38,11 @@ pub fn mul(a: &Scalar, A: &EdwardsPoint, b: &Scalar) -> EdwardsPoint { } let table_A = NafLookupTable5::::from(A); - let table_B = &BASEPOINT_ODD_LOOKUP_TABLE; + + #[cfg(feature = "precomputed-tables")] + let table_B = &crate::backend::vector::BASEPOINT_ODD_LOOKUP_TABLE; + #[cfg(not(feature = "precomputed-tables"))] + let table_B = &NafLookupTable5::::from(&crate::constants::ED25519_BASEPOINT_POINT); let mut Q = ExtendedPoint::identity(); diff --git a/src/window.rs b/src/window.rs index aed5174..c1067ce 100644 --- a/src/window.rs +++ b/src/window.rs @@ -222,10 +222,13 @@ impl<'a> From<&'a EdwardsPoint> for NafLookupTable5 { } } -/// Holds stuff up to 8. +/// Holds stuff up to 8. The only time we use tables this big is for precomputed basepoint tables +/// and multiscalar multiplication (which requires alloc). +#[cfg(any(feature = "precomputed-tables", feature = "alloc"))] #[derive(Copy, Clone)] pub(crate) struct NafLookupTable8(pub(crate) [T; 64]); +#[cfg(any(feature = "precomputed-tables", feature = "alloc"))] impl NafLookupTable8 { pub fn select(&self, x: usize) -> T { debug_assert_eq!(x & 1, 1); @@ -235,6 +238,7 @@ impl NafLookupTable8 { } } +#[cfg(any(feature = "precomputed-tables", feature = "alloc"))] impl Debug for NafLookupTable8 { fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { writeln!(f, "NafLookupTable8([")?; @@ -245,6 +249,7 @@ impl Debug for NafLookupTable8 { } } +#[cfg(any(feature = "precomputed-tables", feature = "alloc"))] impl<'a> From<&'a EdwardsPoint> for NafLookupTable8 { fn from(A: &'a EdwardsPoint) -> Self { let mut Ai = [A.as_projective_niels(); 64]; @@ -257,6 +262,7 @@ impl<'a> From<&'a EdwardsPoint> for NafLookupTable8 { } } +#[cfg(any(feature = "precomputed-tables", feature = "alloc"))] impl<'a> From<&'a EdwardsPoint> for NafLookupTable8 { fn from(A: &'a EdwardsPoint) -> Self { let mut Ai = [A.as_affine_niels(); 64];