From 9c7161d6524972ccdaa42f7a41a3e356d1925970 Mon Sep 17 00:00:00 2001 From: zz-sol Date: Mon, 22 Jun 2026 09:47:37 -0400 Subject: [PATCH] simply lookup table constructor (#56) --- .../serial/scalar_mul/precomputed_straus.rs | 15 ++++------ .../src/backend/serial/scalar_mul/straus.rs | 15 ++++------ .../vector/scalar_mul/precomputed_straus.rs | 16 +++++----- .../src/backend/vector/scalar_mul/straus.rs | 15 ++++------ curve25519/solana-ed25519/src/window.rs | 30 +++++++++++++++++++ 5 files changed, 54 insertions(+), 37 deletions(-) diff --git a/curve25519/solana-ed25519/src/backend/serial/scalar_mul/precomputed_straus.rs b/curve25519/solana-ed25519/src/backend/serial/scalar_mul/precomputed_straus.rs index 8c3a474..bc437c2 100644 --- a/curve25519/solana-ed25519/src/backend/serial/scalar_mul/precomputed_straus.rs +++ b/curve25519/solana-ed25519/src/backend/serial/scalar_mul/precomputed_straus.rs @@ -23,7 +23,9 @@ use crate::edwards::EdwardsPoint; use crate::scalar::Scalar; use crate::traits::Identity; use crate::traits::VartimePrecomputedMultiscalarMul; -use crate::window::{NafLookupTable5, NafLookupTable8}; +use crate::window::{ + NafLookupTable5, NafLookupTable8, build_lookup_tables, build_lookup_tables_for_optional_points, +}; #[allow(missing_docs)] pub struct VartimePrecomputedStraus { @@ -39,10 +41,7 @@ impl VartimePrecomputedMultiscalarMul for VartimePrecomputedStraus { I::Item: Borrow, { Self { - static_lookup_tables: static_points - .into_iter() - .map(|P| NafLookupTable8::::from(P.borrow())) - .collect(), + static_lookup_tables: build_lookup_tables(static_points), } } @@ -76,10 +75,8 @@ impl VartimePrecomputedMultiscalarMul for VartimePrecomputedStraus { .map(|c| c.borrow().non_adjacent_form(5)) .collect::>(); - let dynamic_lookup_tables = dynamic_points - .into_iter() - .map(|P_opt| P_opt.map(|P| NafLookupTable5::::from(&P))) - .collect::>>()?; + let dynamic_lookup_tables: Vec> = + build_lookup_tables_for_optional_points(dynamic_points)?; let sp = self.static_lookup_tables.len(); let dp = dynamic_lookup_tables.len(); diff --git a/curve25519/solana-ed25519/src/backend/serial/scalar_mul/straus.rs b/curve25519/solana-ed25519/src/backend/serial/scalar_mul/straus.rs index c4d49ba..72274f7 100644 --- a/curve25519/solana-ed25519/src/backend/serial/scalar_mul/straus.rs +++ b/curve25519/solana-ed25519/src/backend/serial/scalar_mul/straus.rs @@ -109,12 +109,9 @@ impl MultiscalarMul for Straus { { use crate::backend::serial::curve_models::ProjectiveNielsPoint; use crate::traits::Identity; - use crate::window::LookupTable; + use crate::window::{LookupTable, build_lookup_tables}; - let lookup_tables: Vec<_> = points - .into_iter() - .map(|point| LookupTable::::from(point.borrow())) - .collect(); + let lookup_tables: Vec> = build_lookup_tables(points); // This puts the scalar digits into a heap-allocated Vec. // To ensure that these are erased, pass ownership of the Vec into a @@ -166,17 +163,15 @@ impl VartimeMultiscalarMul for Straus { CompletedPoint, ProjectiveNielsPoint, ProjectivePoint, }; use crate::traits::Identity; - use crate::window::NafLookupTable5; + use crate::window::{NafLookupTable5, build_lookup_tables_for_optional_points}; let nafs: Vec<_> = scalars .into_iter() .map(|c| c.borrow().non_adjacent_form(5)) .collect(); - let lookup_tables = points - .into_iter() - .map(|P_opt| P_opt.map(|P| NafLookupTable5::::from(&P))) - .collect::>>()?; + let lookup_tables: Vec> = + build_lookup_tables_for_optional_points(points)?; let mut r = ProjectivePoint::identity(); diff --git a/curve25519/solana-ed25519/src/backend/vector/scalar_mul/precomputed_straus.rs b/curve25519/solana-ed25519/src/backend/vector/scalar_mul/precomputed_straus.rs index 43bbd99..2519d36 100644 --- a/curve25519/solana-ed25519/src/backend/vector/scalar_mul/precomputed_straus.rs +++ b/curve25519/solana-ed25519/src/backend/vector/scalar_mul/precomputed_straus.rs @@ -26,7 +26,10 @@ pub mod spec { use crate::scalar::Scalar; use crate::traits::Identity; use crate::traits::VartimePrecomputedMultiscalarMul; - use crate::window::{NafLookupTable5, NafLookupTable8}; + use crate::window::{ + NafLookupTable5, NafLookupTable8, build_lookup_tables, + build_lookup_tables_for_optional_points, + }; pub struct VartimePrecomputedStraus { static_lookup_tables: Vec>, @@ -41,10 +44,7 @@ pub mod spec { I::Item: Borrow, { Self { - static_lookup_tables: static_points - .into_iter() - .map(|P| NafLookupTable8::::from(P.borrow())) - .collect(), + static_lookup_tables: build_lookup_tables(static_points), } } @@ -78,10 +78,8 @@ pub mod spec { .map(|c| c.borrow().non_adjacent_form(5)) .collect::>(); - let dynamic_lookup_tables = dynamic_points - .into_iter() - .map(|P_opt| P_opt.map(|P| NafLookupTable5::::from(&P))) - .collect::>>()?; + let dynamic_lookup_tables: Vec> = + build_lookup_tables_for_optional_points(dynamic_points)?; let sp = self.static_lookup_tables.len(); let dp = dynamic_lookup_tables.len(); diff --git a/curve25519/solana-ed25519/src/backend/vector/scalar_mul/straus.rs b/curve25519/solana-ed25519/src/backend/vector/scalar_mul/straus.rs index b7b8efc..0fca257 100644 --- a/curve25519/solana-ed25519/src/backend/vector/scalar_mul/straus.rs +++ b/curve25519/solana-ed25519/src/backend/vector/scalar_mul/straus.rs @@ -28,7 +28,9 @@ pub mod spec { use crate::edwards::EdwardsPoint; use crate::scalar::Scalar; use crate::traits::{Identity, MultiscalarMul, VartimeMultiscalarMul}; - use crate::window::{LookupTable, NafLookupTable5}; + use crate::window::{ + LookupTable, NafLookupTable5, build_lookup_tables, build_lookup_tables_for_optional_points, + }; /// Multiscalar multiplication using interleaved window / Straus' /// method. See the `Straus` struct in the serial backend for more @@ -52,10 +54,7 @@ pub mod spec { { // Construct a lookup table of [P,2P,3P,4P,5P,6P,7P,8P] // for each input point P - let lookup_tables: Vec<_> = points - .into_iter() - .map(|point| LookupTable::::from(point.borrow())) - .collect(); + let lookup_tables: Vec> = build_lookup_tables(points); let scalar_digits_vec: Vec<_> = scalars .into_iter() @@ -91,10 +90,8 @@ pub mod spec { .into_iter() .map(|c| c.borrow().non_adjacent_form(5)) .collect(); - let lookup_tables: Vec<_> = points - .into_iter() - .map(|P_opt| P_opt.map(|P| NafLookupTable5::::from(&P))) - .collect::>>()?; + let lookup_tables: Vec> = + build_lookup_tables_for_optional_points(points)?; let mut Q = ExtendedPoint::identity(); diff --git a/curve25519/solana-ed25519/src/window.rs b/curve25519/solana-ed25519/src/window.rs index 348ef5f..756e616 100644 --- a/curve25519/solana-ed25519/src/window.rs +++ b/curve25519/solana-ed25519/src/window.rs @@ -15,7 +15,11 @@ use core::fmt::Debug; +#[cfg(feature = "alloc")] +use alloc::vec::Vec; use cfg_if::cfg_if; +#[cfg(feature = "alloc")] +use core::borrow::Borrow; use subtle::Choice; use subtle::ConditionallyNegatable; @@ -28,6 +32,32 @@ use crate::backend::serial::curve_models::AffineNielsPoint; use crate::backend::serial::curve_models::ProjectiveNielsPoint; use crate::edwards::EdwardsPoint; +#[cfg(feature = "alloc")] +pub(crate) fn build_lookup_tables(points: I) -> Vec +where + T: for<'a> From<&'a EdwardsPoint>, + I: IntoIterator, + I::Item: Borrow, +{ + points + .into_iter() + .map(|point| T::from(point.borrow())) + .collect() +} + +#[cfg(feature = "alloc")] +pub(crate) fn build_lookup_tables_for_optional_points(points: I) -> Option> +where + T: for<'a> From<&'a EdwardsPoint>, + I: IntoIterator>, + P: Borrow, +{ + points + .into_iter() + .map(|point| point.map(|point| T::from(point.borrow()))) + .collect() +} + #[cfg(feature = "zeroize")] use zeroize::Zeroize;