From adbf6e50f1beba57b34e2e8ef7b6c79fa3d80b36 Mon Sep 17 00:00:00 2001 From: Aaron Feickert <66188213+AaronFeickert@users.noreply.github.com> Date: Fri, 2 Aug 2024 21:47:07 -0500 Subject: [PATCH 1/2] Add precomputation length --- curve25519-dalek/src/backend/mod.rs | 24 +++++++++++++++++++ .../serial/scalar_mul/precomputed_straus.rs | 8 +++++++ .../vector/scalar_mul/precomputed_straus.rs | 8 +++++++ curve25519-dalek/src/edwards.rs | 11 +++++++++ curve25519-dalek/src/ristretto.rs | 11 +++++++++ curve25519-dalek/src/traits.rs | 6 +++++ 6 files changed, 68 insertions(+) diff --git a/curve25519-dalek/src/backend/mod.rs b/curve25519-dalek/src/backend/mod.rs index c5fab97f5..329d15f27 100644 --- a/curve25519-dalek/src/backend/mod.rs +++ b/curve25519-dalek/src/backend/mod.rs @@ -128,6 +128,30 @@ impl VartimePrecomputedStraus { } } + pub fn len(&self) -> usize { + use crate::traits::VartimePrecomputedMultiscalarMul; + + match self { + #[cfg(curve25519_dalek_backend = "simd")] + VartimePrecomputedStraus::Avx2(inner) => inner.len(), + #[cfg(all(curve25519_dalek_backend = "unstable_avx512", nightly))] + VartimePrecomputedStraus::Avx512ifma(inner) => inner.len(), + VartimePrecomputedStraus::Scalar(inner) => inner.len(), + } + } + + pub fn is_empty(&self) -> bool { + use crate::traits::VartimePrecomputedMultiscalarMul; + + match self { + #[cfg(curve25519_dalek_backend = "simd")] + VartimePrecomputedStraus::Avx2(inner) => inner.is_empty(), + #[cfg(all(curve25519_dalek_backend = "unstable_avx512", nightly))] + VartimePrecomputedStraus::Avx512ifma(inner) => inner.is_empty(), + VartimePrecomputedStraus::Scalar(inner) => inner.is_empty(), + } + } + pub fn optional_mixed_multiscalar_mul( &self, static_scalars: I, diff --git a/curve25519-dalek/src/backend/serial/scalar_mul/precomputed_straus.rs b/curve25519-dalek/src/backend/serial/scalar_mul/precomputed_straus.rs index 53116c628..8c3a474c2 100644 --- a/curve25519-dalek/src/backend/serial/scalar_mul/precomputed_straus.rs +++ b/curve25519-dalek/src/backend/serial/scalar_mul/precomputed_straus.rs @@ -46,6 +46,14 @@ impl VartimePrecomputedMultiscalarMul for VartimePrecomputedStraus { } } + fn len(&self) -> usize { + self.static_lookup_tables.len() + } + + fn is_empty(&self) -> bool { + self.static_lookup_tables.is_empty() + } + fn optional_mixed_multiscalar_mul( &self, static_scalars: I, diff --git a/curve25519-dalek/src/backend/vector/scalar_mul/precomputed_straus.rs b/curve25519-dalek/src/backend/vector/scalar_mul/precomputed_straus.rs index 6038d18c7..cc44c5795 100644 --- a/curve25519-dalek/src/backend/vector/scalar_mul/precomputed_straus.rs +++ b/curve25519-dalek/src/backend/vector/scalar_mul/precomputed_straus.rs @@ -57,6 +57,14 @@ pub mod spec { } } + fn len(&self) -> usize { + self.static_lookup_tables.len() + } + + fn is_empty(&self) -> bool { + self.static_lookup_tables.is_empty() + } + fn optional_mixed_multiscalar_mul( &self, static_scalars: I, diff --git a/curve25519-dalek/src/edwards.rs b/curve25519-dalek/src/edwards.rs index 02f8631b8..811764b47 100644 --- a/curve25519-dalek/src/edwards.rs +++ b/curve25519-dalek/src/edwards.rs @@ -879,6 +879,14 @@ impl VartimePrecomputedMultiscalarMul for VartimeEdwardsPrecomputation { Self(crate::backend::VartimePrecomputedStraus::new(static_points)) } + fn len(&self) -> usize { + self.0.len() + } + + fn is_empty(&self) -> bool { + self.0.is_empty() + } + fn optional_mixed_multiscalar_mul( &self, static_scalars: I, @@ -2136,6 +2144,9 @@ mod test { let precomputation = VartimeEdwardsPrecomputation::new(static_points.iter()); + assert_eq!(precomputation.len(), 128); + assert!(!precomputation.is_empty()); + let P = precomputation.vartime_mixed_multiscalar_mul( &static_scalars, &dynamic_scalars, diff --git a/curve25519-dalek/src/ristretto.rs b/curve25519-dalek/src/ristretto.rs index 1918d0326..49c134eb8 100644 --- a/curve25519-dalek/src/ristretto.rs +++ b/curve25519-dalek/src/ristretto.rs @@ -1027,6 +1027,14 @@ impl VartimePrecomputedMultiscalarMul for VartimeRistrettoPrecomputation { )) } + fn len(&self) -> usize { + self.0.len() + } + + fn is_empty(&self) -> bool { + self.0.is_empty() + } + fn optional_mixed_multiscalar_mul( &self, static_scalars: I, @@ -1852,6 +1860,9 @@ mod test { let precomputation = VartimeRistrettoPrecomputation::new(static_points.iter()); + assert_eq!(precomputation.len(), 128); + assert!(!precomputation.is_empty()); + let P = precomputation.vartime_mixed_multiscalar_mul( &static_scalars, &dynamic_scalars, diff --git a/curve25519-dalek/src/traits.rs b/curve25519-dalek/src/traits.rs index ea7ca3be7..80a64234b 100644 --- a/curve25519-dalek/src/traits.rs +++ b/curve25519-dalek/src/traits.rs @@ -299,6 +299,12 @@ pub trait VartimePrecomputedMultiscalarMul: Sized { I: IntoIterator, I::Item: Borrow; + /// Return the number of static points in the precomputation. + fn len(&self) -> usize; + + /// Determine if the precomputation is empty. + fn is_empty(&self) -> bool; + /// Given `static_scalars`, an iterator of public scalars /// \\(b_i\\), compute /// $$ From 66f8b32715ed4026ba9d0182a43649459830e7d1 Mon Sep 17 00:00:00 2001 From: Aaron Feickert <66188213+AaronFeickert@users.noreply.github.com> Date: Sat, 4 Jan 2025 18:27:22 -0600 Subject: [PATCH 2/2] Review comments --- curve25519-dalek/src/backend/mod.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/curve25519-dalek/src/backend/mod.rs b/curve25519-dalek/src/backend/mod.rs index 329d15f27..cfb8b003f 100644 --- a/curve25519-dalek/src/backend/mod.rs +++ b/curve25519-dalek/src/backend/mod.rs @@ -128,6 +128,7 @@ impl VartimePrecomputedStraus { } } + /// Return the number of static points in the precomputation. pub fn len(&self) -> usize { use crate::traits::VartimePrecomputedMultiscalarMul; @@ -140,6 +141,7 @@ impl VartimePrecomputedStraus { } } + /// Determine if the precomputation is empty. pub fn is_empty(&self) -> bool { use crate::traits::VartimePrecomputedMultiscalarMul;