Skip to content

Commit 8cfd95a

Browse files
committed
allocate less space to precomputations for EJ
1 parent 96d3084 commit 8cfd95a

File tree

1 file changed

+34
-26
lines changed

1 file changed

+34
-26
lines changed

src/elliptic/velu.rs

Lines changed: 34 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -317,7 +317,9 @@ impl<Fq: FqTrait> Curve<Fq> {
317317

318318
// ============================================================
319319
// Sqrt Velu functions for large ell-isogenies
320-
// WARNING: this is underperforming because of inefficienies absolutely everywhere!
320+
// WARNING: this is underperforming currently due to missing optimisations in some
321+
// specialised polynomial arithmetic to allow for fast scaled remainder trees and
322+
// other smaller things.
321323

322324
/// Precompute the points in the three partitions I, J and K using x-only arithmetic.
323325
// TODO: study Algorithm 1 of ia.cr/2024/584 and see if this still will lead to
@@ -390,7 +392,7 @@ impl<Fq: FqTrait> Curve<Fq> {
390392

391393
#[inline]
392394
fn precompute_eJ_values(
393-
eJ_coeffs: &mut [(Fq, Fq, Fq, Fq)],
395+
eJ_coeffs: &mut [(Fq, Fq, Fq)],
394396
hJ_points: &[PointX<Fq>],
395397
A24: &Fq,
396398
C24: &Fq,
@@ -407,29 +409,13 @@ impl<Fq: FqTrait> Curve<Fq> {
407409
for (i, P) in hJ_points.iter().enumerate() {
408410
let (X, Z) = P.coords();
409411
let XZ = X * Z;
410-
let XZ4neg = -XZ.mul4();
411412

412-
let sub_sqr = (X - Z).square();
413-
let add_sqr = sub_sqr - XZ4neg;
413+
let add_sqr = (X + Z).square();
414+
let XZ4neg = -XZ.mul4();
414415
let AXZ4neg = A * XZ4neg;
415416

416-
debug_assert!(add_sqr.equals(&(X + Z).square()) == u32::MAX);
417-
418-
eJ_coeffs[i] = (add_sqr, sub_sqr, XZ4neg, AXZ4neg);
419-
}
420-
}
421-
422-
/// Understanding the polynomial hK = prod(x * PZ - PX) for the set in hK, then
423-
/// evaluate this polynomial at alpha = 1 and alpha = -1
424-
#[inline]
425-
fn hK_codomain(hK_points: &[PointX<Fq>]) -> (Fq, Fq) {
426-
let mut h1 = Fq::ONE;
427-
let mut h2 = Fq::ONE;
428-
for P in hK_points.iter() {
429-
h1 *= P.Z - P.X;
430-
h2 *= -(P.Z + P.X);
417+
eJ_coeffs[i] = (add_sqr, XZ4neg, AXZ4neg);
431418
}
432-
(h1, h2)
433419
}
434420

435421
/// Compute the product of an array of Fq values using a product tree.
@@ -442,6 +428,27 @@ impl<Fq: FqTrait> Curve<Fq> {
442428
Self::product_tree_root_fq(&v[..half]) * Self::product_tree_root_fq(&v[half..])
443429
}
444430

431+
/// Understanding the polynomial hK = prod(x * PZ - PX) for the set in hK, then
432+
/// evaluate this polynomial at alpha = 1 and alpha = -1
433+
#[inline]
434+
fn hK_codomain(hK_points: &[PointX<Fq>]) -> (Fq, Fq) {
435+
// We have the factorisation of hK into linear pieces, so we evaluate
436+
// each factor to get an Fq element and then compute the product of these
437+
// with a product tree.
438+
let mut h1_linear = Vec::with_capacity(hK_points.len());
439+
let mut h2_linear = Vec::with_capacity(hK_points.len());
440+
441+
for P in hK_points.iter() {
442+
h1_linear.push(P.Z - P.X);
443+
h2_linear.push(-(P.Z + P.X));
444+
}
445+
446+
let h1 = Self::product_tree_root_fq(&h1_linear);
447+
let h2 = Self::product_tree_root_fq(&h2_linear);
448+
449+
(h1, h2)
450+
}
451+
445452
/// Understanding the polynomial hK = prod(x * PZ - PX) for the set in hK, then
446453
/// evaluate this polynomial at alpha and 1/alpha (projectively) where we have
447454
/// alpha = (X : Z) and we take as input X + Z and X - Z.
@@ -507,17 +514,18 @@ impl<Fq: FqTrait> Curve<Fq> {
507514
let hI_roots: Vec<Fq> = hI_points.iter().map(|P| P.X).collect();
508515

509516
// Precompute (X + Z)^2, (X - Z)^2, -4XZ and -4XZ*A
510-
let mut eJ_precomp = vec![(Fq::ZERO, Fq::ZERO, Fq::ZERO, Fq::ZERO); size_J];
517+
let mut eJ_precomp = vec![(Fq::ZERO, Fq::ZERO, Fq::ZERO); size_J];
511518
Self::precompute_eJ_values(&mut eJ_precomp, &hJ_points, A24, C24); // Cost: size_J * (1S + 2M)
512519

513520
let mut E0J_leaves: Vec<P> = Vec::with_capacity(size_J);
514521
let mut E1J_leaves: Vec<P> = Vec::with_capacity(size_J);
515-
for (sum_sqr, sub_sqr, _, AXZ4neg) in eJ_precomp.iter() {
516-
let c0_0 = *sub_sqr;
522+
for (sum_sqr, XZ4neg, AXZ4neg) in eJ_precomp.iter() {
523+
// (X - Z)^2 = (X + Z)^2 - 4 * X * Z
524+
let c0_0 = *sum_sqr + *XZ4neg;
517525
let c0_1 = *AXZ4neg - sum_sqr.mul2();
518526

519527
let c1_0 = *sum_sqr;
520-
let c1_1 = sub_sqr.mul2() - *AXZ4neg;
528+
let c1_1 = c0_0.mul2() - *AXZ4neg;
521529

522530
// Each quadratic factor here is a palindrome.
523531
// TODO: we could write specialised polynomial arithmetic which
@@ -565,7 +573,7 @@ impl<Fq: FqTrait> Curve<Fq> {
565573
let X2Z2 = XpZ.square() - XZ2; // X^2 + Z^2
566574

567575
let mut E1J_leaves: Vec<P> = Vec::with_capacity(size_J);
568-
for (i, (sum_sqr, _, XZ4neg, AXZ4neg)) in eJ_precomp.iter().enumerate() {
576+
for (i, (sum_sqr, XZ4neg, AXZ4neg)) in eJ_precomp.iter().enumerate() {
569577
let Pj = hJ_points[i];
570578

571579
// Precompute some multiplications for later.

0 commit comments

Comments
 (0)