anza-cryptography-source/curve25519
Edvard Fagerholm 7d80488798
ed25519: avoid split-scalar canonical checks (#24)
The triple-base verifier splits b into zero-extended 128-bit halves, so b_lo and b_hi are already canonical. Add a crate-private unchecked constructor and use it for that internal AVX2 path.

Benchmark notes:

- Ran this repository's Criterion benchmark program, benches/bench.rs, filtering to Single Verification, pinned to CPU 4 with 1s warmup, 2s measurement, and sample size 10.

- local_verify_zebra estimate was 19.996 us, with 95% CI 19.862..20.077 us.

- master measured 20.051 us, with 95% CI 19.938..20.134 us, so this branch was about 0.27% faster in that run.
2026-06-08 13:02:22 -04:00
..
curve25519-cuda Add workspace.package information and do minor clean-up (#14) 2026-04-26 10:11:05 +09:00
solana-ed25519 ed25519: avoid split-scalar canonical checks (#24) 2026-06-08 13:02:22 -04:00
LICENSE move all curve25519 related crates into curve25519 directory (#5) 2026-03-24 07:42:07 -04:00
LICENSE-APACHE move all curve25519 related crates into curve25519 directory (#5) 2026-03-24 07:42:07 -04:00
LICENSE-MIT move all curve25519 related crates into curve25519 directory (#5) 2026-03-24 07:42:07 -04:00
README.md move all curve25519 related crates into curve25519 directory (#5) 2026-03-24 07:42:07 -04:00
README_dalek.md move all curve25519 related crates into curve25519 directory (#5) 2026-03-24 07:42:07 -04:00

curve25519-sol

A high-performance, opinionated fork of curve25519-dalek and ed25519-zebra focused on accelerated Ed25519 signature verification via the HEEA (Half-Extended Euclidean Algorithm) method and a reduced set of well-tested backends.

Original library READMEs: README_dalek.md (workspace) · curve25519/README_dalek.md · ed25519-heea/README_zebra.md


Crates

Crate Description
curve25519 Fork of curve25519-dalek. Core elliptic-curve arithmetic over Curve25519, Edwards, Ristretto, and Short-Weierstrass forms, with HEEA scalar decomposition and a narrowed backend set (removed u32 and constraint device supports).
ed25519-heea Fork of ed25519-zebra. ZIP-215-compliant Ed25519 with an added verify_heea fast-path that uses HEEA half-size scalars.
curve25519-cuda GPU-accelerated multi-scalar multiplication (MSM) via CUDA/SPPARK. Falls back to CPU when CUDA is unavailable.
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

Key Changes from Upstream

HEEA Signature Verification

Standard Ed25519 verification checks sB = R + hA, where h is a 256-bit scalar. HEEA (from the TCHES 2025 paper "Accelerating EdDSA Signature Verification with Faster Scalar Size Halving") transforms this into a 4-point MSM with ~128-bit scalars:

τs_lo · B + τs_hi · (2¹²⁸·B) = τ·R + ρ·A

where ρ and τ are half-size (~127-bit) values derived from h via a half-extended Euclidean algorithm, and τs = τs_hi · 2¹²⁸ + τs_lo. All four scalars are ≤128 bits, and two of the bases (B and 2¹²⁸B) use precomputed tables. In practice this yields roughly ~15% faster verification compared to the standard double-scalar-multiplication path.

The algorithm is implemented in:

Reduced Backend Set

Upstream curve25519-dalek supports serial, fiat-crypto, AVX2, and unstable AVX512 backends. This fork retains only the backends actively tested and maintained here:

Backend Platform Selection
serial All (macOS, Linux, …) Automatic fallback
simd / AVX2 x86-64 with AVX2 Runtime CPU detection
CUDA (separate crate) NVIDIA GPU Opt-in via curve25519-cuda

The fiat (formally-verified) and unstable_avx512 backends have been removed to reduce maintenance surface. If you need them, use upstream curve25519-dalek directly.


Usage

Add the relevant crate to Cargo.toml:

# Core curve arithmetic with HEEA
curve25519-sol = { git = "https://github.com/zz-sol/ed25519-sol" }

# Ed25519 signatures with fast HEEA verification
ed25519-heea = { git = "https://github.com/zz-sol/ed25519-sol" }

Standard Ed25519 verification

use ed25519_heea::{SigningKey, VerificationKey};
use rand::thread_rng;

let msg = b"hello world";
let sk = SigningKey::new(thread_rng());
let sig = sk.sign(msg);
let vk = VerificationKey::from(&sk);

// Standard ZIP-215-compliant verification
vk.verify(&sig, msg).expect("valid signature");

HEEA-accelerated verification

// Fast path: ~15% faster via half-size scalars (same result)
vk.verify_heea(&sig, msg).expect("valid signature");

Building

# Standard build
cargo build --release

# With AVX2 (automatic on x86-64 at runtime; or force compile-time)
RUSTFLAGS='-C target-feature=+avx2' cargo build --release

# Run benchmarks
cargo bench --features "rand_core" -p curve25519
cargo bench -p ed25519-heea

References


License

Licensed under either of

at your option.

Portions of this library are derived from curve25519-dalek (isis lovecruft, Henry de Valence) and ed25519-zebra (Zcash Foundation), both dual-licensed MIT/Apache-2.0.