Skip to main content

Module hyperelliptic

Module hyperelliptic 

Source
Expand description

§Genus-2 curves and the Richelot (2,2)-isogeny — the abelian-surface mechanism

When an elliptic-curve pair is glued into an abelian surface (a genus-2 Jacobian), the Castryck–Decru break walks (2,2)-isogenies of that surface and watches for the codomain to split back into a product of elliptic curves — each split reveals a step of the secret isogeny.

A genus-2 curve is y² = f(x) with f a sextic, and its 2-torsion is the six Weierstrass points (the roots of f). A (2,2)-subgroup is a partition of those six roots into three pairs — equivalently a factorisation f = G₁·G₂·G₃ into three quadratics; there are exactly 15 of them, the neighbours in the (2,2)-isogeny graph. Richelot’s isogeny sends f to the dual sextic H₁·H₂·H₃, where Hᵢ = Gⱼ·Gₖ' − Gⱼ'·Gₖ (' = d/dx, {i,j,k} cyclic), scaled by the Richelot determinant δ = det[coeffs of G₁,G₂,G₃]. When δ = 0 the three quadratics are dependent, the correspondence degenerates, and the abelian surface is reducible — the split condition, in its cleanest form.

This module builds that mechanism over 𝔽_p and the chain-walk across the (2,2)-graph. The honest boundary: the full Castryck–Decru secret recovery, and Damien Robert’s higher-dimensional (dimension 4/8, theta-coordinate) generalisation, are genuine research-grade machinery built ON this core — the chain-walk framework here is the shape they generalise, not a claim to have implemented dimension 8.

Structs§

MatchedPairGlue
A matched-pair (2,2)-gluing: the genus-2 curve C: y² = ∏ᵢ(x² + cᵢx + 1) whose Jacobian is (2,2)-isogenous to E₁ × E₂, where E₁, E₂ share three of the four quartic 2-torsion roots −cᵢ and differ in the fourth (∓2). Derived from the involution x ↦ 1/x (invariants t = x + 1/x, w = y(x³+1)/2x³, giving W = 2w/(t−1) with W² = (t+2)∏(t+cᵢ)). Unlike the even-sextic special case, this is the general gluing along a matched 2-torsion; any two curves with a symplectic 2-torsion isomorphism reach this form after a Möbius normalization of the shared points. Validated exactly by #Jac(C) = #E₁·#E₂ (genus2_jacobian_order).
Mumford
A divisor class in Jac(C) in Mumford form (u, v).
Richelot
The result of a Richelot (2,2)-isogeny from a quadratic splitting f = G₁·G₂·G₃.
SplitGenus2
A genus-2 curve C: y² = g(x²) (an even sextic) with a (2,2)-split Jacobian Jac(C) ~ E₁ × E₂, together with its two elliptic quotients. This is the (2,2)-gluing in reverse: the two degree-2 maps (x,y) ↦ (x², y) onto E₁: y² = g(u) and (x,y) ↦ (1/x², y/x³) onto E₂: y² = ĝ(u) (the reversed cubic) exhibit the split. It is the abelian-surface object the Kani/Castryck–Decru oracle detects.

Enums§

GuidedWalk
The outcome of following a guided Richelot chain.

Functions§

cantor_add
Cantor’s algorithm: add two divisor classes on C: y² = f(x) (genus 2, char ≠ 2).
count_curve_fp
#{(x,y) ∈ 𝔽_p² : y² = f(x)} + inf — the 𝔽_p-point count of y² = f(x) (inf = points at infinity).
find_split_neighbour
Walk the (2,2)-isogeny graph from a genus-2 Jacobian given by its six Weierstrass points: try each of the 15 Richelot neighbours and report whether any is a split (reducible) surface. This is the shape of the Castryck–Decru search — at real scale it is guided by the torsion images rather than exhaustive, and Robert’s generalisation lifts the same walk to dimension 4/8. Returns the splitting quadratics of the first split neighbour, if one exists.
genus2_jacobian_order
#Jac(C)(𝔽_p) for the genus-2 curve C: y² = f(x) (deg f = 6, monic), from its L-polynomial via the point counts over 𝔽_p and 𝔽_{p²}. For a split Jacobian Jac(C) ~ E₁ × E₂ this equals #E₁·#E₂ (Tate: isogenous abelian varieties over 𝔽_p share their order) — the exact point-count validation of a gluing.
genus2_jacobian_order_general
#Jac(C)(𝔽_p) for C: y² = f(x) of any degree 5 or 6, with the correct number of points at infinity: deg 5 ⟹ 1; deg 6 ⟹ 2 if the leading coefficient is a square (over 𝔽_p), else 0. Over 𝔽_{p²} every 𝔽_p leading coefficient is a square, so the count there is 2 (deg 6) or 1 (deg 5). Needed to compare a Richelot dual (a non-monic, possibly quadratic-twisted sextic) against its domain.
glue_shared_2torsion
Glue two elliptic curves along their matched 2-torsion {−c₁, −c₂, −c₃} into the genus-2 curve C: y² = ∏(x² + cᵢx + 1). See MatchedPairGlue.
guided_chain
Follow a guided chain of Richelot isogenies: apply the neighbour named by each index in path in turn, reporting the first split. In the full Castryck–Decru attack the path is not free — it is dictated by the torsion images φ(P), φ(Q): the kernel of each (2,2)-step is the image of a prescribed torsion subgroup, so the walk is a single guided line rather than the 15-way exhaustive tree. This function is that guided line; deriving path from the torsion images is the remaining Castryck–Decru integration.
jac_element_order
The order of a divisor class D in Jac(C) — the least n | group_order with [n]·D = 0. Computed by stripping each prime of group_order as far as still annihilates D.
jac_identity
The identity divisor class (1, 0).
jac_negate
−D = (u, −v).
jac_scalar_mul
Scalar multiple [n]·D by double-and-add.
poly_deriv
Formal derivative of a polynomial mod p.
poly_eval
Evaluate a polynomial at x mod p (Horner).
poly_mul
Polynomial product mod p (coefficients low-to-high).
richelot
The Richelot (2,2)-isogeny from a quadratic splitting G = (G₁, G₂, G₃) over 𝔽_p.
richelot_chain
Walk chains of Richelot (2,2)-isogenies to depth depth (a chain of depth + 1 steps), returning the sequence of neighbour indices that first reaches a split (reducible) surface, or None if none does within the bound. This is the recursive form of the Castryck–Decru search across the (2,2)-graph: from each node it forms the codomain, extracts its Weierstrass points, and recurses. Neighbours whose codomain 2-torsion escapes to 𝔽_{p²} are skipped over the prime field.
richelot_partitions
The 15 quadratic splittings of six roots into three pairs — the neighbours of a genus-2 Jacobian in the (2,2)-isogeny graph. Each pair (rₐ, r_b) becomes the quadratic (x−rₐ)(x−r_b).
select_splitting_branch
The per-digit split oracle. Given the candidate surface for each branch of the recursive descent (one per guessed -adic digit — in the full attack each is built by Kani gluing from the torsion images and the guess), return the index of the branch whose surface splits. The split-test prunes every branch but the consistent one — the is_split/Kani step of Castryck–Decru, as a wired per-digit selector.
split_jacobian_from_cubic
Glue E₁: y² = g(u) with its reverse E₂: y² = ĝ(u) into the genus-2 curve C: y² = g(x²). g is a cubic given low→high [g₀, g₁, g₂, g₃]. The result carries a split Jacobian — validated by the quotient maps and by the Richelot ±-splitting being reducible (δ = 0).
surface_is_reducible
Whether the genus-2 curve with these six Weierstrass points has a reducible Jacobian (splits as a product of elliptic curves) — decided by the Richelot split-test: some (2,2)-splitting has δ = 0. This is exactly the decision the Castryck–Decru per-digit oracle makes — a correct guess yields a splitting abelian surface, a wrong one an indecomposable genus-2 Jacobian.

Type Aliases§

Quad
A quadratic g₀ + g₁·x + g₂·x², coefficients low-to-high.