// ---
// tags: genies, source
// crystal-type: source
// crystal-domain: comp
// ---
//! ℓ-isogeny computation via Vélu's formulas for Montgomery curves.
//!
//! Given a curve E_A and a kernel point K of order ℓ, compute:
//! - the codomain curve E_{A'} = E_A / <K>
//! - the image of an arbitrary point Q under the isogeny
//!
//! Uses Vélu's formulas in short Weierstrass form, converted to/from Montgomery.
use crateFq;
use crate;
/// Maximum half-kernel size: (587 - 1) / 2 = 293.
const MAX_HALF_KERNEL: usize = 293;
/// Compute kernel multiples [1]K, [2]K, ..., [h]K where h = (ℓ-1)/2.
/// Compute the codomain curve of an ℓ-isogeny with kernel generated by `kernel`
/// (a point of order ℓ) on `curve`.
///
/// Uses the Vélu formula adapted for Montgomery curves via the Edwards
/// intermediate representation. For each half-kernel point with affine
/// x-coordinate x_i, compute Edwards y-coordinate v_i = (x_i - 1)/(x_i + 1),
/// then the new Edwards parameters from which A' is recovered.
///
/// The formula (affine, using kernel x-coordinates):
/// For E_A: y^2 = x^3 + Ax^2 + x, let a_ed = A+2, d_ed = A-2.
/// The kernel half-multiples have affine x-coords x_1,...,x_h.
/// Edwards y-coords: v_i = (x_i - 1)/(x_i + 1).
///
/// v = sum_{i=1}^{h} (3*x_i^2 + 2*A*x_i + 1) / (x_i * (x_i^2 + A*x_i + 1))
/// = sum_{i=1}^{h} (3*x_i^2 + 2*A*x_i + 1) / (y_i^2) [since y^2 = x*(x^2+Ax+1)]
///
/// Actually, using the Vélu approach on short Weierstrass and converting back:
/// For Montgomery E_A (which is y^2 = x^3 + Ax^2 + x in Weierstrass form with a2=A):
/// g_Q^x = 3*x_Q^2 + 2*A*x_Q + 1 (derivative of x^3+Ax^2+x at x_Q)
/// For Q of order > 2:
/// t_Q = 2*g_Q^x = 2*(3*x_Q^2 + 2*A*x_Q + 1)
/// u_Q = 4*y_Q^2 = 4*(x_Q^3 + A*x_Q^2 + x_Q)
/// V = sum(t_Q), W = sum(u_Q + x_Q*t_Q)
/// a2_new = A - V, a4_new = 1 - 5*V + A*something...
///
/// For simplicity and correctness, we use the DIRECT affine formula:
/// Compute the codomain via Vélu on the general Weierstrass form
/// y^2 = x^3 + a2*x^2 + a4*x + a6 with a2=A, a4=1, a6=0.
/// Evaluate the ℓ-isogeny at an arbitrary point Q.
///
/// The projective evaluation formula:
/// phi(X_Q : Z_Q) = ( X_Q * prod((X_Q*Z_i - Z_Q*X_i)^2),
/// Z_Q * prod((X_Q*X_i - Z_Q*Z_i)^2) )
/// Compute an ℓ-isogeny: returns (new_curve, image_of_optional_point).
genies/rs/src/isogeny.rs
π 0.0%