curve: add precomputation length to MSM structs (#685)

This commit is contained in:
Aaron Feickert 2025-01-11 21:57:50 -06:00 committed by GitHub
parent 4570d806ee
commit ed83542d7e
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 70 additions and 0 deletions

View file

@ -128,6 +128,32 @@ impl VartimePrecomputedStraus {
} }
} }
/// Return the number of static points in the precomputation.
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(),
}
}
/// Determine if the precomputation is empty.
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<I, J, K>( pub fn optional_mixed_multiscalar_mul<I, J, K>(
&self, &self,
static_scalars: I, static_scalars: I,

View file

@ -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<I, J, K>( fn optional_mixed_multiscalar_mul<I, J, K>(
&self, &self,
static_scalars: I, static_scalars: I,

View file

@ -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<I, J, K>( fn optional_mixed_multiscalar_mul<I, J, K>(
&self, &self,
static_scalars: I, static_scalars: I,

View file

@ -879,6 +879,14 @@ impl VartimePrecomputedMultiscalarMul for VartimeEdwardsPrecomputation {
Self(crate::backend::VartimePrecomputedStraus::new(static_points)) 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<I, J, K>( fn optional_mixed_multiscalar_mul<I, J, K>(
&self, &self,
static_scalars: I, static_scalars: I,
@ -2136,6 +2144,9 @@ mod test {
let precomputation = VartimeEdwardsPrecomputation::new(static_points.iter()); let precomputation = VartimeEdwardsPrecomputation::new(static_points.iter());
assert_eq!(precomputation.len(), 128);
assert!(!precomputation.is_empty());
let P = precomputation.vartime_mixed_multiscalar_mul( let P = precomputation.vartime_mixed_multiscalar_mul(
&static_scalars, &static_scalars,
&dynamic_scalars, &dynamic_scalars,

View file

@ -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<I, J, K>( fn optional_mixed_multiscalar_mul<I, J, K>(
&self, &self,
static_scalars: I, static_scalars: I,
@ -1852,6 +1860,9 @@ mod test {
let precomputation = VartimeRistrettoPrecomputation::new(static_points.iter()); let precomputation = VartimeRistrettoPrecomputation::new(static_points.iter());
assert_eq!(precomputation.len(), 128);
assert!(!precomputation.is_empty());
let P = precomputation.vartime_mixed_multiscalar_mul( let P = precomputation.vartime_mixed_multiscalar_mul(
&static_scalars, &static_scalars,
&dynamic_scalars, &dynamic_scalars,

View file

@ -299,6 +299,12 @@ pub trait VartimePrecomputedMultiscalarMul: Sized {
I: IntoIterator, I: IntoIterator,
I::Item: Borrow<Self::Point>; I::Item: Borrow<Self::Point>;
/// 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 /// Given `static_scalars`, an iterator of public scalars
/// \\(b_i\\), compute /// \\(b_i\\), compute
/// $$ /// $$