[ed25519] improve docs (#53)

* improve docs

* more docs

* improve docs
This commit is contained in:
zz-sol 2026-06-16 23:13:07 -04:00 committed by GitHub
parent befbe09d36
commit 7cca75ad6e
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 31 additions and 16 deletions

View file

@ -16,7 +16,9 @@ method and a reduced set of well-tested backends.
|---|---|
| [`solana-ed25519`](./solana-ed25519) | Fork of `curve25519-dalek` with ZIP-215-compliant Ed25519 from `ed25519-zebra`, HEEA-accelerated `verify` / `verify_zebra`, and a narrowed backend set (removed `u32` and constraint device supports). |
| [`curve25519-cuda`](./curve25519-cuda) | GPU-accelerated multi-scalar multiplication (MSM) via CUDA/SPPARK. Falls back to CPU when CUDA is unavailable. |
| [`curve25519-derive`](../curve25519-derive) | Helper proc-macro crate (`#[unsafe_target_feature]`) inherited from upstream; required to write clean SIMD code. Identical to the one in dalek 0.5.0 |
SIMD helper macros come from the workspace dependency `curve25519-dalek-derive = "0.1.1"`;
there is no local `curve25519-derive` crate in this workspace.
---

View file

@ -19,6 +19,15 @@ use crate::scalar::{HEEA_MAX_INDEX, Scalar};
use crate::traits::Identity;
use crate::window::NafLookupTable5;
const DYNAMIC_NAF_WINDOW: usize = 5;
// This intentionally differs from the vector backend when precomputed tables
// are enabled. The serial backend can select width-5 b_lo digits from the
// larger width-8 basepoint table, but keeps the smaller NAF window here as a
// backend-specific performance tradeoff. Revisit this only with comparative
// serial/vector benchmarks.
const B_LO_NAF_WINDOW: usize = DYNAMIC_NAF_WINDOW;
/// Compute \\(a_1 A_1 + a_2 A_2 + b B\\) in variable time, where \\(B\\) is the Ed25519 basepoint.
///
/// This function is optimized for the case where \\(a_1\\) and \\(a_2\\) are known to be less than
@ -82,10 +91,10 @@ pub(crate) fn mul_128_128_256_prechecked(
// The serial backend keeps b_lo at width 5 even when table_B is the larger
// precomputed width-8 basepoint table. The vector backend uses width 8 in
// that configuration.
let a1_naf = a1.non_adjacent_form(5);
let a2_naf = a2.non_adjacent_form(5);
let b_lo_naf = b_lo.non_adjacent_form(5);
let b_hi_naf = b_hi.non_adjacent_form(5);
let a1_naf = a1.non_adjacent_form(DYNAMIC_NAF_WINDOW);
let a2_naf = a2.non_adjacent_form(DYNAMIC_NAF_WINDOW);
let b_lo_naf = b_lo.non_adjacent_form(B_LO_NAF_WINDOW);
let b_hi_naf = b_hi.non_adjacent_form(DYNAMIC_NAF_WINDOW);
// Find starting index - check all NAFs up to bit 127
// (with potential carry to bit 128 or 129)

View file

@ -30,6 +30,17 @@ pub mod spec {
use crate::traits::Identity;
use crate::window::NafLookupTable5;
const DYNAMIC_NAF_WINDOW: usize = 5;
// This intentionally differs from the serial backend when precomputed
// tables are enabled. The AVX2 basepoint table is width 8, and this vector
// path uses the larger b_lo NAF window in that configuration as a
// backend-specific performance tradeoff.
#[cfg(feature = "precomputed-tables")]
const B_LO_NAF_WINDOW: usize = 8;
#[cfg(not(feature = "precomputed-tables"))]
const B_LO_NAF_WINDOW: usize = DYNAMIC_NAF_WINDOW;
/// Compute \\(a_1 A_1 + a_2 A_2 + b B\\) in variable time, where \\(B\\) is the Ed25519 basepoint.
///
/// This function is optimized for the case where \\(a_1\\) and \\(a_2\\) are known to be less than
@ -91,17 +102,10 @@ pub mod spec {
let b_hi = Scalar::from_canonical_bytes_unchecked(b_hi_bytes);
// Compute NAF representations (all scalars are now ~128 bits)
let a1_naf = a1.non_adjacent_form(5);
let a2_naf = a2.non_adjacent_form(5);
// With precomputed tables, the vector backend uses the larger width-8
// basepoint table for b_lo. The serial backend keeps b_lo at width 5.
#[cfg(feature = "precomputed-tables")]
let b_lo_naf = b_lo.non_adjacent_form(8);
#[cfg(not(feature = "precomputed-tables"))]
let b_lo_naf = b_lo.non_adjacent_form(5);
let b_hi_naf = b_hi.non_adjacent_form(5);
let a1_naf = a1.non_adjacent_form(DYNAMIC_NAF_WINDOW);
let a2_naf = a2.non_adjacent_form(DYNAMIC_NAF_WINDOW);
let b_lo_naf = b_lo.non_adjacent_form(B_LO_NAF_WINDOW);
let b_hi_naf = b_hi.non_adjacent_form(DYNAMIC_NAF_WINDOW);
// Find starting index - check all NAFs up to bit 127
// (with potential carry to bit 128 or 129)