passagemath-schemes 10.6.40__cp314-cp314-macosx_13_0_arm64.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of passagemath-schemes might be problematic. Click here for more details.

Files changed (314) hide show
  1. passagemath_schemes/.dylibs/libflint.22.0.dylib +0 -0
  2. passagemath_schemes/.dylibs/libgmp.10.dylib +0 -0
  3. passagemath_schemes/.dylibs/libgmpxx.4.dylib +0 -0
  4. passagemath_schemes/.dylibs/libmpfr.6.dylib +0 -0
  5. passagemath_schemes/__init__.py +3 -0
  6. passagemath_schemes-10.6.40.dist-info/METADATA +204 -0
  7. passagemath_schemes-10.6.40.dist-info/METADATA.bak +205 -0
  8. passagemath_schemes-10.6.40.dist-info/RECORD +314 -0
  9. passagemath_schemes-10.6.40.dist-info/WHEEL +6 -0
  10. passagemath_schemes-10.6.40.dist-info/top_level.txt +3 -0
  11. sage/all__sagemath_schemes.py +23 -0
  12. sage/databases/all__sagemath_schemes.py +7 -0
  13. sage/databases/cremona.py +1723 -0
  14. sage/dynamics/all__sagemath_schemes.py +2 -0
  15. sage/dynamics/arithmetic_dynamics/affine_ds.py +1083 -0
  16. sage/dynamics/arithmetic_dynamics/all.py +14 -0
  17. sage/dynamics/arithmetic_dynamics/berkovich_ds.py +1101 -0
  18. sage/dynamics/arithmetic_dynamics/dynamical_semigroup.py +1543 -0
  19. sage/dynamics/arithmetic_dynamics/endPN_automorphism_group.py +2426 -0
  20. sage/dynamics/arithmetic_dynamics/endPN_minimal_model.py +1169 -0
  21. sage/dynamics/arithmetic_dynamics/generic_ds.py +663 -0
  22. sage/dynamics/arithmetic_dynamics/product_projective_ds.py +339 -0
  23. sage/dynamics/arithmetic_dynamics/projective_ds.py +9558 -0
  24. sage/dynamics/arithmetic_dynamics/projective_ds_helper.cpython-314-darwin.so +0 -0
  25. sage/dynamics/arithmetic_dynamics/projective_ds_helper.pyx +301 -0
  26. sage/dynamics/arithmetic_dynamics/wehlerK3.py +2576 -0
  27. sage/lfunctions/all.py +18 -0
  28. sage/lfunctions/dokchitser.py +745 -0
  29. sage/lfunctions/pari.py +818 -0
  30. sage/lfunctions/zero_sums.cpython-314-darwin.so +0 -0
  31. sage/lfunctions/zero_sums.pyx +1847 -0
  32. sage/modular/abvar/abvar.py +5135 -0
  33. sage/modular/abvar/abvar_ambient_jacobian.py +413 -0
  34. sage/modular/abvar/abvar_newform.py +244 -0
  35. sage/modular/abvar/all.py +8 -0
  36. sage/modular/abvar/constructor.py +186 -0
  37. sage/modular/abvar/cuspidal_subgroup.py +371 -0
  38. sage/modular/abvar/finite_subgroup.py +896 -0
  39. sage/modular/abvar/homology.py +720 -0
  40. sage/modular/abvar/homspace.py +998 -0
  41. sage/modular/abvar/lseries.py +415 -0
  42. sage/modular/abvar/morphism.py +935 -0
  43. sage/modular/abvar/torsion_point.py +274 -0
  44. sage/modular/abvar/torsion_subgroup.py +740 -0
  45. sage/modular/all.py +43 -0
  46. sage/modular/arithgroup/all.py +20 -0
  47. sage/modular/arithgroup/arithgroup_element.cpython-314-darwin.so +0 -0
  48. sage/modular/arithgroup/arithgroup_element.pyx +474 -0
  49. sage/modular/arithgroup/arithgroup_generic.py +1402 -0
  50. sage/modular/arithgroup/arithgroup_perm.py +2692 -0
  51. sage/modular/arithgroup/congroup.cpython-314-darwin.so +0 -0
  52. sage/modular/arithgroup/congroup.pyx +334 -0
  53. sage/modular/arithgroup/congroup_gamma.py +363 -0
  54. sage/modular/arithgroup/congroup_gamma0.py +692 -0
  55. sage/modular/arithgroup/congroup_gamma1.py +653 -0
  56. sage/modular/arithgroup/congroup_gammaH.py +1469 -0
  57. sage/modular/arithgroup/congroup_generic.py +628 -0
  58. sage/modular/arithgroup/congroup_sl2z.py +267 -0
  59. sage/modular/arithgroup/farey_symbol.cpython-314-darwin.so +0 -0
  60. sage/modular/arithgroup/farey_symbol.pyx +1066 -0
  61. sage/modular/arithgroup/tests.py +418 -0
  62. sage/modular/btquotients/all.py +4 -0
  63. sage/modular/btquotients/btquotient.py +3753 -0
  64. sage/modular/btquotients/pautomorphicform.py +2570 -0
  65. sage/modular/buzzard.py +100 -0
  66. sage/modular/congroup.py +29 -0
  67. sage/modular/congroup_element.py +13 -0
  68. sage/modular/cusps.py +1109 -0
  69. sage/modular/cusps_nf.py +1270 -0
  70. sage/modular/dims.py +569 -0
  71. sage/modular/dirichlet.py +3310 -0
  72. sage/modular/drinfeld_modform/all.py +2 -0
  73. sage/modular/drinfeld_modform/element.py +446 -0
  74. sage/modular/drinfeld_modform/ring.py +773 -0
  75. sage/modular/drinfeld_modform/tutorial.py +236 -0
  76. sage/modular/etaproducts.py +1065 -0
  77. sage/modular/hecke/algebra.py +746 -0
  78. sage/modular/hecke/all.py +20 -0
  79. sage/modular/hecke/ambient_module.py +1019 -0
  80. sage/modular/hecke/degenmap.py +119 -0
  81. sage/modular/hecke/element.py +325 -0
  82. sage/modular/hecke/hecke_operator.py +780 -0
  83. sage/modular/hecke/homspace.py +206 -0
  84. sage/modular/hecke/module.py +1767 -0
  85. sage/modular/hecke/morphism.py +174 -0
  86. sage/modular/hecke/submodule.py +989 -0
  87. sage/modular/hypergeometric_misc.cpython-314-darwin.so +0 -0
  88. sage/modular/hypergeometric_misc.pxd +4 -0
  89. sage/modular/hypergeometric_misc.pyx +166 -0
  90. sage/modular/hypergeometric_motive.py +2017 -0
  91. sage/modular/local_comp/all.py +2 -0
  92. sage/modular/local_comp/liftings.py +292 -0
  93. sage/modular/local_comp/local_comp.py +1071 -0
  94. sage/modular/local_comp/smoothchar.py +1825 -0
  95. sage/modular/local_comp/type_space.py +748 -0
  96. sage/modular/modform/all.py +30 -0
  97. sage/modular/modform/ambient.py +815 -0
  98. sage/modular/modform/ambient_R.py +177 -0
  99. sage/modular/modform/ambient_eps.py +306 -0
  100. sage/modular/modform/ambient_g0.py +124 -0
  101. sage/modular/modform/ambient_g1.py +204 -0
  102. sage/modular/modform/constructor.py +545 -0
  103. sage/modular/modform/cuspidal_submodule.py +708 -0
  104. sage/modular/modform/defaults.py +14 -0
  105. sage/modular/modform/eis_series.py +505 -0
  106. sage/modular/modform/eisenstein_submodule.py +663 -0
  107. sage/modular/modform/element.py +4131 -0
  108. sage/modular/modform/find_generators.py +59 -0
  109. sage/modular/modform/half_integral.py +154 -0
  110. sage/modular/modform/hecke_operator_on_qexp.py +247 -0
  111. sage/modular/modform/j_invariant.py +47 -0
  112. sage/modular/modform/l_series_gross_zagier.py +133 -0
  113. sage/modular/modform/l_series_gross_zagier_coeffs.cpython-314-darwin.so +0 -0
  114. sage/modular/modform/l_series_gross_zagier_coeffs.pyx +177 -0
  115. sage/modular/modform/notes.py +45 -0
  116. sage/modular/modform/numerical.py +514 -0
  117. sage/modular/modform/periods.py +14 -0
  118. sage/modular/modform/ring.py +1257 -0
  119. sage/modular/modform/space.py +1860 -0
  120. sage/modular/modform/submodule.py +118 -0
  121. sage/modular/modform/tests.py +64 -0
  122. sage/modular/modform/theta.py +110 -0
  123. sage/modular/modform/vm_basis.py +381 -0
  124. sage/modular/modform/weight1.py +220 -0
  125. sage/modular/modform_hecketriangle/abstract_ring.py +1932 -0
  126. sage/modular/modform_hecketriangle/abstract_space.py +2528 -0
  127. sage/modular/modform_hecketriangle/all.py +30 -0
  128. sage/modular/modform_hecketriangle/analytic_type.py +590 -0
  129. sage/modular/modform_hecketriangle/constructor.py +416 -0
  130. sage/modular/modform_hecketriangle/element.py +351 -0
  131. sage/modular/modform_hecketriangle/functors.py +752 -0
  132. sage/modular/modform_hecketriangle/graded_ring.py +541 -0
  133. sage/modular/modform_hecketriangle/graded_ring_element.py +2225 -0
  134. sage/modular/modform_hecketriangle/hecke_triangle_group_element.py +3352 -0
  135. sage/modular/modform_hecketriangle/hecke_triangle_groups.py +1432 -0
  136. sage/modular/modform_hecketriangle/readme.py +1214 -0
  137. sage/modular/modform_hecketriangle/series_constructor.py +580 -0
  138. sage/modular/modform_hecketriangle/space.py +1037 -0
  139. sage/modular/modform_hecketriangle/subspace.py +423 -0
  140. sage/modular/modsym/all.py +17 -0
  141. sage/modular/modsym/ambient.py +3846 -0
  142. sage/modular/modsym/boundary.py +1420 -0
  143. sage/modular/modsym/element.py +336 -0
  144. sage/modular/modsym/g1list.py +178 -0
  145. sage/modular/modsym/ghlist.py +182 -0
  146. sage/modular/modsym/hecke_operator.py +73 -0
  147. sage/modular/modsym/manin_symbol.cpython-314-darwin.so +0 -0
  148. sage/modular/modsym/manin_symbol.pxd +5 -0
  149. sage/modular/modsym/manin_symbol.pyx +497 -0
  150. sage/modular/modsym/manin_symbol_list.py +1295 -0
  151. sage/modular/modsym/modsym.py +400 -0
  152. sage/modular/modsym/modular_symbols.py +384 -0
  153. sage/modular/modsym/p1list.cpython-314-darwin.so +0 -0
  154. sage/modular/modsym/p1list.pxd +29 -0
  155. sage/modular/modsym/p1list.pyx +1372 -0
  156. sage/modular/modsym/p1list_nf.py +1241 -0
  157. sage/modular/modsym/relation_matrix.py +591 -0
  158. sage/modular/modsym/relation_matrix_pyx.cpython-314-darwin.so +0 -0
  159. sage/modular/modsym/relation_matrix_pyx.pyx +108 -0
  160. sage/modular/modsym/space.py +2468 -0
  161. sage/modular/modsym/subspace.py +455 -0
  162. sage/modular/modsym/tests.py +375 -0
  163. sage/modular/multiple_zeta.py +2632 -0
  164. sage/modular/multiple_zeta_F_algebra.py +786 -0
  165. sage/modular/overconvergent/all.py +6 -0
  166. sage/modular/overconvergent/genus0.py +1878 -0
  167. sage/modular/overconvergent/hecke_series.py +1187 -0
  168. sage/modular/overconvergent/weightspace.py +778 -0
  169. sage/modular/pollack_stevens/all.py +4 -0
  170. sage/modular/pollack_stevens/distributions.py +874 -0
  171. sage/modular/pollack_stevens/fund_domain.py +1572 -0
  172. sage/modular/pollack_stevens/manin_map.py +859 -0
  173. sage/modular/pollack_stevens/modsym.py +1593 -0
  174. sage/modular/pollack_stevens/padic_lseries.py +417 -0
  175. sage/modular/pollack_stevens/sigma0.py +534 -0
  176. sage/modular/pollack_stevens/space.py +1076 -0
  177. sage/modular/quasimodform/all.py +3 -0
  178. sage/modular/quasimodform/element.py +845 -0
  179. sage/modular/quasimodform/ring.py +828 -0
  180. sage/modular/quatalg/all.py +3 -0
  181. sage/modular/quatalg/brandt.py +1642 -0
  182. sage/modular/ssmod/all.py +8 -0
  183. sage/modular/ssmod/ssmod.py +827 -0
  184. sage/rings/all__sagemath_schemes.py +1 -0
  185. sage/rings/polynomial/all__sagemath_schemes.py +1 -0
  186. sage/rings/polynomial/binary_form_reduce.py +585 -0
  187. sage/schemes/all.py +41 -0
  188. sage/schemes/berkovich/all.py +6 -0
  189. sage/schemes/berkovich/berkovich_cp_element.py +2582 -0
  190. sage/schemes/berkovich/berkovich_space.py +748 -0
  191. sage/schemes/curves/affine_curve.py +2928 -0
  192. sage/schemes/curves/all.py +33 -0
  193. sage/schemes/curves/closed_point.py +434 -0
  194. sage/schemes/curves/constructor.py +381 -0
  195. sage/schemes/curves/curve.py +542 -0
  196. sage/schemes/curves/plane_curve_arrangement.py +1283 -0
  197. sage/schemes/curves/point.py +463 -0
  198. sage/schemes/curves/projective_curve.py +3026 -0
  199. sage/schemes/curves/zariski_vankampen.py +1932 -0
  200. sage/schemes/cyclic_covers/all.py +2 -0
  201. sage/schemes/cyclic_covers/charpoly_frobenius.py +320 -0
  202. sage/schemes/cyclic_covers/constructor.py +137 -0
  203. sage/schemes/cyclic_covers/cycliccover_finite_field.py +1309 -0
  204. sage/schemes/cyclic_covers/cycliccover_generic.py +310 -0
  205. sage/schemes/elliptic_curves/BSD.py +1036 -0
  206. sage/schemes/elliptic_curves/Qcurves.py +592 -0
  207. sage/schemes/elliptic_curves/addition_formulas_ring.py +94 -0
  208. sage/schemes/elliptic_curves/all.py +49 -0
  209. sage/schemes/elliptic_curves/cardinality.py +609 -0
  210. sage/schemes/elliptic_curves/cm.py +1102 -0
  211. sage/schemes/elliptic_curves/constructor.py +1552 -0
  212. sage/schemes/elliptic_curves/ec_database.py +175 -0
  213. sage/schemes/elliptic_curves/ell_curve_isogeny.py +3972 -0
  214. sage/schemes/elliptic_curves/ell_egros.py +459 -0
  215. sage/schemes/elliptic_curves/ell_field.py +2836 -0
  216. sage/schemes/elliptic_curves/ell_finite_field.py +3359 -0
  217. sage/schemes/elliptic_curves/ell_generic.py +3760 -0
  218. sage/schemes/elliptic_curves/ell_local_data.py +1207 -0
  219. sage/schemes/elliptic_curves/ell_modular_symbols.py +775 -0
  220. sage/schemes/elliptic_curves/ell_number_field.py +4220 -0
  221. sage/schemes/elliptic_curves/ell_padic_field.py +107 -0
  222. sage/schemes/elliptic_curves/ell_point.py +4787 -0
  223. sage/schemes/elliptic_curves/ell_rational_field.py +7368 -0
  224. sage/schemes/elliptic_curves/ell_tate_curve.py +671 -0
  225. sage/schemes/elliptic_curves/ell_torsion.py +436 -0
  226. sage/schemes/elliptic_curves/ell_wp.py +352 -0
  227. sage/schemes/elliptic_curves/formal_group.py +760 -0
  228. sage/schemes/elliptic_curves/gal_reps.py +1459 -0
  229. sage/schemes/elliptic_curves/gal_reps_number_field.py +1669 -0
  230. sage/schemes/elliptic_curves/gp_simon.py +152 -0
  231. sage/schemes/elliptic_curves/heegner.py +7335 -0
  232. sage/schemes/elliptic_curves/height.py +2109 -0
  233. sage/schemes/elliptic_curves/hom.py +1406 -0
  234. sage/schemes/elliptic_curves/hom_composite.py +934 -0
  235. sage/schemes/elliptic_curves/hom_frobenius.py +522 -0
  236. sage/schemes/elliptic_curves/hom_scalar.py +531 -0
  237. sage/schemes/elliptic_curves/hom_sum.py +682 -0
  238. sage/schemes/elliptic_curves/hom_velusqrt.py +1290 -0
  239. sage/schemes/elliptic_curves/homset.py +271 -0
  240. sage/schemes/elliptic_curves/isogeny_class.py +1521 -0
  241. sage/schemes/elliptic_curves/isogeny_small_degree.py +2797 -0
  242. sage/schemes/elliptic_curves/jacobian.py +237 -0
  243. sage/schemes/elliptic_curves/kodaira_symbol.py +344 -0
  244. sage/schemes/elliptic_curves/kraus.py +1014 -0
  245. sage/schemes/elliptic_curves/lseries_ell.py +943 -0
  246. sage/schemes/elliptic_curves/mod5family.py +105 -0
  247. sage/schemes/elliptic_curves/mod_poly.py +197 -0
  248. sage/schemes/elliptic_curves/mod_sym_num.cpython-314-darwin.so +0 -0
  249. sage/schemes/elliptic_curves/mod_sym_num.pyx +3796 -0
  250. sage/schemes/elliptic_curves/modular_parametrization.py +305 -0
  251. sage/schemes/elliptic_curves/padic_lseries.py +1793 -0
  252. sage/schemes/elliptic_curves/padics.py +1816 -0
  253. sage/schemes/elliptic_curves/period_lattice.py +2234 -0
  254. sage/schemes/elliptic_curves/period_lattice_region.cpython-314-darwin.so +0 -0
  255. sage/schemes/elliptic_curves/period_lattice_region.pyx +722 -0
  256. sage/schemes/elliptic_curves/saturation.py +715 -0
  257. sage/schemes/elliptic_curves/sha_tate.py +1158 -0
  258. sage/schemes/elliptic_curves/weierstrass_morphism.py +1117 -0
  259. sage/schemes/elliptic_curves/weierstrass_transform.py +200 -0
  260. sage/schemes/hyperelliptic_curves/all.py +6 -0
  261. sage/schemes/hyperelliptic_curves/constructor.py +291 -0
  262. sage/schemes/hyperelliptic_curves/hyperelliptic_finite_field.py +1914 -0
  263. sage/schemes/hyperelliptic_curves/hyperelliptic_g2.py +192 -0
  264. sage/schemes/hyperelliptic_curves/hyperelliptic_generic.py +954 -0
  265. sage/schemes/hyperelliptic_curves/hyperelliptic_padic_field.py +1332 -0
  266. sage/schemes/hyperelliptic_curves/hyperelliptic_rational_field.py +84 -0
  267. sage/schemes/hyperelliptic_curves/invariants.py +410 -0
  268. sage/schemes/hyperelliptic_curves/jacobian_endomorphism_utils.py +315 -0
  269. sage/schemes/hyperelliptic_curves/jacobian_g2.py +32 -0
  270. sage/schemes/hyperelliptic_curves/jacobian_generic.py +419 -0
  271. sage/schemes/hyperelliptic_curves/jacobian_homset.py +186 -0
  272. sage/schemes/hyperelliptic_curves/jacobian_morphism.py +875 -0
  273. sage/schemes/hyperelliptic_curves/kummer_surface.py +99 -0
  274. sage/schemes/hyperelliptic_curves/mestre.py +302 -0
  275. sage/schemes/hyperelliptic_curves/monsky_washnitzer.py +3871 -0
  276. sage/schemes/jacobians/abstract_jacobian.py +277 -0
  277. sage/schemes/jacobians/all.py +2 -0
  278. sage/schemes/overview.py +161 -0
  279. sage/schemes/plane_conics/all.py +22 -0
  280. sage/schemes/plane_conics/con_field.py +1296 -0
  281. sage/schemes/plane_conics/con_finite_field.py +158 -0
  282. sage/schemes/plane_conics/con_number_field.py +456 -0
  283. sage/schemes/plane_conics/con_rational_field.py +406 -0
  284. sage/schemes/plane_conics/con_rational_function_field.py +580 -0
  285. sage/schemes/plane_conics/constructor.py +249 -0
  286. sage/schemes/plane_quartics/all.py +2 -0
  287. sage/schemes/plane_quartics/quartic_constructor.py +71 -0
  288. sage/schemes/plane_quartics/quartic_generic.py +73 -0
  289. sage/schemes/riemann_surfaces/all.py +1 -0
  290. sage/schemes/riemann_surfaces/riemann_surface.py +4117 -0
  291. sage_wheels/share/cremona/cremona_mini.db +0 -0
  292. sage_wheels/share/ellcurves/rank0 +30427 -0
  293. sage_wheels/share/ellcurves/rank1 +31871 -0
  294. sage_wheels/share/ellcurves/rank10 +6 -0
  295. sage_wheels/share/ellcurves/rank11 +6 -0
  296. sage_wheels/share/ellcurves/rank12 +1 -0
  297. sage_wheels/share/ellcurves/rank14 +1 -0
  298. sage_wheels/share/ellcurves/rank15 +1 -0
  299. sage_wheels/share/ellcurves/rank17 +1 -0
  300. sage_wheels/share/ellcurves/rank19 +1 -0
  301. sage_wheels/share/ellcurves/rank2 +2388 -0
  302. sage_wheels/share/ellcurves/rank20 +1 -0
  303. sage_wheels/share/ellcurves/rank21 +1 -0
  304. sage_wheels/share/ellcurves/rank22 +1 -0
  305. sage_wheels/share/ellcurves/rank23 +1 -0
  306. sage_wheels/share/ellcurves/rank24 +1 -0
  307. sage_wheels/share/ellcurves/rank28 +1 -0
  308. sage_wheels/share/ellcurves/rank3 +836 -0
  309. sage_wheels/share/ellcurves/rank4 +10 -0
  310. sage_wheels/share/ellcurves/rank5 +5 -0
  311. sage_wheels/share/ellcurves/rank6 +5 -0
  312. sage_wheels/share/ellcurves/rank7 +5 -0
  313. sage_wheels/share/ellcurves/rank8 +6 -0
  314. sage_wheels/share/ellcurves/rank9 +7 -0
@@ -0,0 +1,2797 @@
1
+ # sage_setup: distribution = sagemath-schemes
2
+ r"""
3
+ Isogenies of small prime degree
4
+
5
+ Functions for the computation of isogenies of small primes degree. First: `l` =
6
+ 2, 3, 5, 7, or 13, where the modular curve `X_0(l)` has genus 0. Second: `l` =
7
+ 11, 17, 19, 23, 29, 31, 41, 47, 59, or 71, where `X_0^+(l)` has genus 0 and
8
+ `X_0(l)` is elliptic or hyperelliptic. Also: `l` = 11, 17, 19, 37, 43, 67 or
9
+ 163 over `\QQ` (the sporadic cases with only finitely many `j`-invariants
10
+ each). All the above only require factorization of a polynomial of degree
11
+ `l+1`. Finally, a generic function which works for arbitrary odd primes `l`
12
+ (including the characteristic), but requires factorization of the `l`-division
13
+ polynomial, of degree `(l^2-1)/2`.
14
+
15
+ AUTHORS:
16
+
17
+ - John Cremona and Jenny Cooley: 2009-07..11: the genus 0 cases the sporadic
18
+ cases over `\QQ`.
19
+
20
+ - Kimi Tsukazaki and John Cremona: 2013-07: The 10 (hyper)-elliptic cases and
21
+ the generic algorithm. See [KT2013]_.
22
+ """
23
+
24
+ # ****************************************************************************
25
+ # Copyright (C) 2012-2013 John Cremona, Jenny Cooley, Kimi Tsukazaki
26
+ #
27
+ # Distributed under the terms of the GNU General Public License (GPL)
28
+ # as published by the Free Software Foundation; either version 2 of
29
+ # the License, or (at your option) any later version.
30
+ # https://www.gnu.org/licenses/
31
+ # ****************************************************************************
32
+
33
+ from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing
34
+ from sage.rings.polynomial.polynomial_ring import polygen
35
+ from sage.rings.integer_ring import ZZ
36
+ from sage.rings.rational_field import QQ
37
+ from sage.schemes.elliptic_curves.constructor import EllipticCurve
38
+
39
+ from sage.misc.cachefunc import cached_function
40
+
41
+ ##########################################################################
42
+ # The following section is all about computing l-isogenies, where l is
43
+ # a prime. The genus 0 cases `l` = 2, 3, 5, 7 and 13 are
44
+ # implemented over any field of characteristic not 2, 3 or `l`; over
45
+ # `\QQ` the "sporadic" cases `l` = 11, 17, 19, 37, 43, 67 or 163 with
46
+ # only finitely many `j`-invariants each. are also implemented.
47
+ ##########################################################################
48
+
49
+
50
+ @cached_function
51
+ def Fricke_polynomial(l):
52
+ r"""
53
+ Fricke polynomial for ``l`` =2,3,5,7,13.
54
+
55
+ For these primes (and these only) the modular curve `X_0(l)` has
56
+ genus zero, and its field is generated by a single modular
57
+ function called the Fricke module (or Hauptmodul), `t`. There is
58
+ a classical choice of such a generator `t` in each case, and the
59
+ `j`-function is a rational function of `t` of degree `l+1` of the
60
+ form `P(t)/t` where `P` is a polynomial of degree `l+1`. Up to
61
+ scaling, `t` is determined by the condition that the ramification
62
+ points above `j=\infty` are `t=0` (with ramification degree `1`)
63
+ and `t=\infty` (with degree `l`). The ramification above `j=0`
64
+ and `j=1728` may be seen in the factorizations of `j(t)` and
65
+ `k(t)` where `k=j-1728`.
66
+
67
+ OUTPUT:
68
+
69
+ The polynomial `P(t)` as an element of `\ZZ[t]`.
70
+
71
+ TESTS::
72
+
73
+ sage: from sage.schemes.elliptic_curves.isogeny_small_degree import Fricke_polynomial
74
+ sage: Fricke_polynomial(2)
75
+ t^3 + 48*t^2 + 768*t + 4096
76
+ sage: Fricke_polynomial(3)
77
+ t^4 + 36*t^3 + 270*t^2 + 756*t + 729
78
+ sage: Fricke_polynomial(5)
79
+ t^6 + 30*t^5 + 315*t^4 + 1300*t^3 + 1575*t^2 + 750*t + 125
80
+ sage: Fricke_polynomial(7)
81
+ t^8 + 28*t^7 + 322*t^6 + 1904*t^5 + 5915*t^4 + 8624*t^3 + 4018*t^2 + 748*t + 49
82
+ sage: Fricke_polynomial(13)
83
+ t^14 + 26*t^13 + 325*t^12 + 2548*t^11 + 13832*t^10 + 54340*t^9 + 157118*t^8
84
+ + 333580*t^7 + 509366*t^6 + 534820*t^5 + 354536*t^4 + 124852*t^3
85
+ + 15145*t^2 + 746*t + 13
86
+ """
87
+ t = PolynomialRing(ZZ, 't').gen()
88
+ if l == 2:
89
+ return (t+16)**3
90
+ elif l == 3:
91
+ return (t+3)**3*(t+27)
92
+ elif l == 5:
93
+ return (t**2+10*t+5)**3
94
+ elif l == 7:
95
+ return (t**2+5*t+1)**3 * (t**2+13*t+49)
96
+ elif l == 13:
97
+ return (t**2+5*t+13)*(t**4+7*t**3+20*t**2+19*t+1)**3
98
+ else:
99
+ raise ValueError("The only genus zero primes are 2, 3, 5, 7 or 13.")
100
+
101
+
102
+ @cached_function
103
+ def Fricke_module(l):
104
+ r"""
105
+ Fricke module for ``l`` =2,3,5,7,13.
106
+
107
+ For these primes (and these only) the modular curve `X_0(l)` has
108
+ genus zero, and its field is generated by a single modular
109
+ function called the Fricke module (or Hauptmodul), `t`. There is
110
+ a classical choice of such a generator `t` in each case, and the
111
+ `j`-function is a rational function of `t` of degree `l+1` of the
112
+ form `P(t)/t` where `P` is a polynomial of degree `l+1`. Up to
113
+ scaling, `t` is determined by the condition that the ramification
114
+ points above `j=\infty` are `t=0` (with ramification degree `1`)
115
+ and `t=\infty` (with degree `l`). The ramification above `j=0`
116
+ and `j=1728` may be seen in the factorizations of `j(t)` and
117
+ `k(t)` where `k=j-1728`.
118
+
119
+ OUTPUT:
120
+
121
+ The rational function `P(t)/t`.
122
+
123
+ TESTS::
124
+
125
+ sage: from sage.schemes.elliptic_curves.isogeny_small_degree import Fricke_module
126
+ sage: Fricke_module(2)
127
+ (t^3 + 48*t^2 + 768*t + 4096)/t
128
+ sage: Fricke_module(3)
129
+ (t^4 + 36*t^3 + 270*t^2 + 756*t + 729)/t
130
+ sage: Fricke_module(5)
131
+ (t^6 + 30*t^5 + 315*t^4 + 1300*t^3 + 1575*t^2 + 750*t + 125)/t
132
+ sage: Fricke_module(7)
133
+ (t^8 + 28*t^7 + 322*t^6 + 1904*t^5 + 5915*t^4 + 8624*t^3 + 4018*t^2 + 748*t + 49)/t
134
+ sage: Fricke_module(13)
135
+ (t^14 + 26*t^13 + 325*t^12 + 2548*t^11 + 13832*t^10
136
+ + 54340*t^9 + 157118*t^8 + 333580*t^7 + 509366*t^6
137
+ + 534820*t^5 + 354536*t^4 + 124852*t^3 + 15145*t^2 + 746*t + 13)/t
138
+ """
139
+ t = PolynomialRing(QQ, 't').gen()
140
+ return Fricke_polynomial(l) / t
141
+
142
+
143
+ @cached_function
144
+ def Psi(l, use_stored=True):
145
+ r"""
146
+ Generic kernel polynomial for genus zero primes.
147
+
148
+ For each of the primes `l` for which `X_0(l)` has genus zero
149
+ (namely `l=2,3,5,7,13`), we may define an elliptic curve `E_t`
150
+ over `\QQ(t)`, with coefficients in `\ZZ[t]`, which has good
151
+ reduction except at `t=0` and `t=\infty` (which lie above
152
+ `j=\infty`) and at certain other values of `t` above `j=0` when
153
+ `l=3` (one value) or `l\equiv1\pmod{3}` (two values) and above
154
+ `j=1728` when `l=2` (one value) or `l\equiv1 \pmod{4}` (two
155
+ values). (These exceptional values correspond to endomorphisms of
156
+ `E_t` of degree `l`.) The `l`-division polynomial of `E_t` has a
157
+ unique factor of degree `(l-1)/2` (or 1 when `l=2`), with
158
+ coefficients in `\ZZ[t]`, which we call the Generic Kernel
159
+ Polynomial for `l`. These are used, by specialising `t`, in the
160
+ function :meth:`isogenies_prime_degree_genus_0`, which also has to
161
+ take into account the twisting factor between `E_t` for a specific
162
+ value of `t` and the short Weierstrass form of an elliptic curve
163
+ with `j`-invariant `j(t)`. This enables the computation of the
164
+ kernel polynomials of isogenies without having to compute and
165
+ factor division polynomials.
166
+
167
+ All of this data is quickly computed from the Fricke modules, except
168
+ that for `l=13` the factorization of the Generic Division Polynomial
169
+ takes a long time, so the value have been precomputed and cached; by
170
+ default the cached values are used, but the code here will recompute
171
+ them when ``use_stored`` is ``False``, as in the doctests.
172
+
173
+ INPUT:
174
+
175
+ - ``l`` -- either 2, 3, 5, 7, or 13
176
+
177
+ - ``use_stored``-- boolean (default: ``True``); if ``True``, use
178
+ precomputed values, otherwise compute them on the fly
179
+
180
+ .. NOTE::
181
+
182
+ This computation takes a negligible time for `l=2,3,5,7`
183
+ but more than 100s for `l=13`. The reason
184
+ for allowing dynamic computation here instead of just using
185
+ precomputed values is for testing.
186
+
187
+ TESTS::
188
+
189
+ sage: from sage.schemes.elliptic_curves.isogeny_small_degree import Fricke_module, Psi
190
+ sage: assert Psi(2, use_stored=True) == Psi(2, use_stored=False)
191
+ sage: assert Psi(3, use_stored=True) == Psi(3, use_stored=False)
192
+ sage: assert Psi(5, use_stored=True) == Psi(5, use_stored=False)
193
+ sage: assert Psi(7, use_stored=True) == Psi(7, use_stored=False)
194
+ sage: assert Psi(13, use_stored=True) == Psi(13, use_stored=False) # long time (2s)
195
+ """
196
+ if l not in [2, 3, 5, 7, 13]:
197
+ raise ValueError("Genus zero primes are 2, 3, 5, 7 or 13.")
198
+
199
+ R = PolynomialRing(ZZ, 2, 'Xt')
200
+ X, t = R.gens()
201
+
202
+ if use_stored:
203
+ if l == 2:
204
+ return X + t + 64
205
+ if l == 3:
206
+ return X + t + 27
207
+ if l == 5:
208
+ return X**2 + 2*X*(t**2 + 22*t + 125) + (t**2 + 22*t + 89) * (t**2 + 22*t + 125)
209
+ if l == 7:
210
+ return (X**3 + 3*(t**2 + 13*t + 49)*X**2
211
+ + 3*(t**2 + 13*t + 33)*(t**2 + 13*t + 49)*X
212
+ + (t**2 + 13*t + 49)*(t**4 + 26*t**3 + 219*t**2 + 778*t + 881))
213
+ if l == 13:
214
+ return (t**24 + 66*t**23 + 2091*t**22 + 6*X*t**20 + 42582*t**21 + 330*X*t**19 + 627603*t**20 + 8700*X*t**18 + 7134744*t**19 + 15*X**2*t**16 + 146886*X*t**17 + 65042724*t**18 + 660*X**2*t**15 + 1784532*X*t**16 + 487778988*t**17 + 13890*X**2*t**14 + 16594230*X*t**15 + 3061861065*t**16 + 20*X**3*t**12 + 186024*X**2*t**13 + 122552328*X*t**14 + 16280123754*t**15 + 660*X**3*t**11 + 1774887*X**2*t**12 + 735836862*X*t**13 + 73911331425*t**14 + 10380*X**3*t**10 + 12787272*X**2*t**11 + 3646188342*X*t**12 + 287938949178*t**13 + 15*X**4*t**8 + 102576*X**3*t**9 + 71909658*X**2*t**10 + 15047141292*X*t**11 + 964903805434*t**12 + 330*X**4*t**7 + 707604*X**3*t**8 + 321704316*X**2*t**9 + 51955096824*X*t**10 + 2781843718722*t**11 + 3435*X**4*t**6 + 3582876*X**3*t**7 + 1155971196*X**2*t**8 + 150205315932*X*t**9 + 6885805359741*t**10 + 6*X**5*t**4 + 21714*X**4*t**5 + 13632168*X**3*t**6 + 3343499244*X**2*t**7 + 362526695094*X*t**8 + 14569390179114*t**9 + 66*X**5*t**3 + 90660*X**4*t**4 + 39215388*X**3*t**5 + 7747596090*X**2*t**6 + 725403501318*X*t**7 + 26165223178293*t**8 + 336*X**5*t**2 + 255090*X**4*t**3 + 84525732*X**3*t**4 + 14206132008*X**2*t**5 + 1189398495432*X*t**6 + 39474479008356*t**7 + X**6 + 858*X**5*t + 472143*X**4*t**2 + 132886992*X**3*t**3 + 20157510639*X**2*t**4 + 1569568001646*X*t**5 + 49303015587132*t**6 + 1014*X**5 + 525954*X**4*t + 144222780*X**3*t**2 + 21320908440*X**2*t**3 + 1622460290100*X*t**4 + 49941619724976*t**5 + 272259*X**4 + 96482100*X**3*t + 15765293778*X**2*t**2 + 1260038295438*X*t**3 + 39836631701295*t**4 + 29641924*X**3 + 7210949460*X**2*t + 686651250012*X*t**2 + 23947528862166*t**3 + 1506392823*X**2 + 231462513906*X*t + 10114876838391*t**2 + 35655266790*X + 2644809206442*t + 317295487717)
215
+ # The coefficients for l=13 are:
216
+ # X**6: 1
217
+ # X**5: (6) * (t**2 + 5*t + 13) * (t**2 + 6*t + 13)
218
+ # X**4: (3) * (t**2 + 5*t + 13) * (t**2 + 6*t + 13) * (5*t**4 + 55*t**3 + 260*t**2 + 583*t + 537)
219
+ # X**3: (4) * (t**2 + 5*t + 13) * (t**2 + 6*t + 13)**2 * (5*t**6 + 80*t**5 + 560*t**4 + 2214*t**3 + 5128*t**2 + 6568*t + 3373)
220
+ # X**2: (3) * (t**2 + 5*t + 13)**2 * (t**2 + 6*t + 13)**2 * (5*t**8 + 110*t**7 + 1045*t**6 + 5798*t**5 + 20508*t**4 + 47134*t**3 + 67685*t**2 + 54406*t + 17581)
221
+ # X**1: (6) * (t**2 + 5*t + 13)**2 * (t**2 + 6*t + 13)**3 * (t**10 + 27*t**9 + 316*t**8 + 2225*t**7 + 10463*t**6 + 34232*t**5 + 78299*t**4 + 122305*t**3 + 122892*t**2 + 69427*t + 16005)
222
+ # X**0: (t**2 + 5*t + 13)**2 * (t**2 + 6*t + 13)**3 * (t**14 + 38*t**13 + 649*t**12 + 6844*t**11 + 50216*t**10 + 271612*t**9 + 1115174*t**8 + 3520132*t**7 + 8549270*t**6 + 15812476*t**5 + 21764840*t**4 + 21384124*t**3 + 13952929*t**2 + 5282630*t + 854569)
223
+
224
+ # Here the generic kernel polynomials are actually calculated:
225
+ j = Fricke_module(l)
226
+ k = j - 1728
227
+ from sage.misc.misc_c import prod
228
+ f = prod([p for p, e in j.factor() if e == 3]
229
+ + [p for p, e in k.factor() if e == 2])
230
+ A4 = -3*t**2*j*k // f**2
231
+ A6 = -2*t**3*j*k**2 // f**3
232
+ E = EllipticCurve([0, 0, 0, A4, A6])
233
+ assert E.j_invariant() == j
234
+ return E.division_polynomial(l, X).factor()[0][0]
235
+
236
+
237
+ def isogenies_prime_degree_genus_0(E, l=None, minimal_models=True):
238
+ """
239
+ Return list of ``l`` -isogenies with domain ``E``.
240
+
241
+ INPUT:
242
+
243
+ - ``E`` -- an elliptic curve
244
+
245
+ - ``l`` -- either ``None`` or 2, 3, 5, 7, or 13
246
+
247
+ - ``minimal_models`` -- boolean (default: ``True``); if ``True``, all
248
+ curves computed will be minimal or semi-minimal models. Over
249
+ fields of larger degree it can be expensive to compute these so
250
+ set to ``False``.
251
+
252
+ OUTPUT:
253
+
254
+ (list) When ``l`` is None a list of all isogenies of degree 2, 3,
255
+ 5, 7 and 13, otherwise a list of isogenies of the given degree.
256
+
257
+ .. NOTE::
258
+
259
+ This function would normally be invoked indirectly via
260
+ ``E.isogenies_prime_degree(l)``, which automatically calls the
261
+ appropriate function.
262
+
263
+ ALGORITHM:
264
+
265
+ Cremona and Watkins [CW2005]_. See also [KT2013]_, Chapter 4.
266
+
267
+ EXAMPLES::
268
+
269
+ sage: from sage.schemes.elliptic_curves.isogeny_small_degree import isogenies_prime_degree_genus_0
270
+ sage: E = EllipticCurve([0,12])
271
+ sage: isogenies_prime_degree_genus_0(E, 5)
272
+ []
273
+
274
+ sage: E = EllipticCurve('1450c1') # needs database_cremona_mini_ellcurve
275
+ sage: isogenies_prime_degree_genus_0(E) # needs database_cremona_mini_ellcurve
276
+ [Isogeny of degree 3
277
+ from Elliptic Curve defined by y^2 + x*y = x^3 + x^2 + 300*x - 1000
278
+ over Rational Field
279
+ to Elliptic Curve defined by y^2 + x*y = x^3 + x^2 - 5950*x - 182250
280
+ over Rational Field]
281
+
282
+ sage: E = EllipticCurve('50a1') # needs database_cremona_mini_ellcurve
283
+ sage: isogenies_prime_degree_genus_0(E) # needs database_cremona_mini_ellcurve
284
+ [Isogeny of degree 3
285
+ from Elliptic Curve defined by y^2 + x*y + y = x^3 - x - 2 over Rational Field
286
+ to Elliptic Curve defined by y^2 + x*y + y = x^3 - 126*x - 552 over Rational Field,
287
+ Isogeny of degree 5
288
+ from Elliptic Curve defined by y^2 + x*y + y = x^3 - x - 2 over Rational Field
289
+ to Elliptic Curve defined by y^2 + x*y + y = x^3 - 76*x + 298 over Rational Field]
290
+ """
291
+ if l not in [2, 3, 5, 7, 13, None]:
292
+ raise ValueError("%s is not a genus 0 prime." % l)
293
+ F = E.base_ring()
294
+ j = E.j_invariant()
295
+ if F.characteristic() in [2, 3, l]:
296
+ raise NotImplementedError("2, 3, 5, 7 and 13-isogenies are not yet implemented in characteristic 2 and 3, and when the characteristic is the same as the degree of the isogeny.")
297
+ if l == 2:
298
+ return isogenies_2(E, minimal_models=minimal_models)
299
+ if l == 3:
300
+ return isogenies_3(E, minimal_models=minimal_models)
301
+ if j == F(0):
302
+ if l == 5:
303
+ return isogenies_5_0(E, minimal_models=minimal_models)
304
+ if l == 7:
305
+ return isogenies_7_0(E, minimal_models=minimal_models)
306
+ if l == 13:
307
+ return isogenies_13_0(E, minimal_models=minimal_models)
308
+ if j == F(1728):
309
+ if l == 5:
310
+ return isogenies_5_1728(E, minimal_models=minimal_models)
311
+ if l == 7:
312
+ return isogenies_7_1728(E, minimal_models=minimal_models)
313
+ if l == 13:
314
+ return isogenies_13_1728(E, minimal_models=minimal_models)
315
+
316
+ if l is not None:
317
+ R = PolynomialRing(F,'t')
318
+ t = R.gen()
319
+ f = R(Fricke_polynomial(l))
320
+ t_list = sorted((f-j*t).roots(multiplicities=False))
321
+ # The generic kernel polynomial applies to a standard curve
322
+ # E_t with the correct j-invariant; we must compute the
323
+ # appropriate twisting factor to scale X by:
324
+ c4, c6 = E.c_invariants()
325
+ T = c4/(3*c6)
326
+ jt = Fricke_module(l)
327
+ kt = jt-1728
328
+ from sage.misc.misc_c import prod
329
+ psi = Psi(l)
330
+ X = t
331
+ f = R(prod( [p for p,e in jt.factor() if e == 3]
332
+ + [p for p,e in kt.factor() if e == 2]))
333
+ kernels = [R(psi(X*T*(j-1728)*t0/f(t0),t0)) for t0 in t_list]
334
+ kernels = [ker.monic() for ker in kernels]
335
+ E1 = EllipticCurve([-27*c4,-54*c6])
336
+ w = E.isomorphism_to(E1)
337
+ from sage.rings.number_field.number_field_base import NumberField
338
+ model = "minimal" if minimal_models and isinstance(F, NumberField) else None
339
+ isogs = [E1.isogeny(kernel=ker, model=model) for ker in kernels]
340
+ isogs = [isog * w for isog in isogs]
341
+ return isogs
342
+
343
+ if l is None:
344
+ return sum([isogenies_prime_degree_genus_0(E, ell, minimal_models=minimal_models)
345
+ for ell in [2,3,5,7,13]],[])
346
+
347
+
348
+ # The following code computes data to be used in
349
+ # isogenies_sporadic_Q. Over Q there are only finitely many
350
+ # j-invariants of curves with l-isogenies where l is not equal to 2,
351
+ # 3, 5, 7 or 13. In these cases l is equal to 11, 17, 19, 37, 43, 67
352
+ # or 163. We refer to these l as "sporadic".
353
+
354
+ # sporadic_j is a dictionary holding for each possible sporadic
355
+ # j-invariant, the unique l such that an l-isogeny exists.
356
+ sporadic_j = {
357
+ QQ(-121) : 11,
358
+ QQ(-32768) : 11,
359
+ QQ(-24729001) : 11,
360
+ QQ(-297756989)/2 : 17,
361
+ QQ(-882216989)/131072 : 17,
362
+ QQ(-884736) : 19,
363
+ QQ(-9317) : 37,
364
+ QQ(-162677523113838677) : 37,
365
+ QQ(-884736000) : 43,
366
+ QQ(-147197952000) : 67,
367
+ QQ(-262537412640768000) : 163
368
+ }
369
+
370
+
371
+ @cached_function
372
+ def _sporadic_Q_data(j):
373
+ r"""
374
+ Return technical data used in computing sporadic isogenies over `\QQ`.
375
+
376
+ INPUT:
377
+
378
+ - ``j`` -- the `j`-invariant of a sporadic curve, i.e. one of the
379
+ keys of ``sporadic_j``
380
+
381
+ OUTPUT:
382
+
383
+ ``([a4,a6],coeffs)`` where ``[a4,a6]`` are the coefficients of a
384
+ short Weierstrass equation of an elliptic curve E with j(E)=``j``,
385
+ and ``coeffs`` is a list of coefficients of a polynomial defining
386
+ the kernel of an l-isogeny from E. In all but one case this
387
+ polynomial is monic with integer coefficients. In one case
388
+ (`\ell=37`, `j=-162677523113838677`) the constant coefficient has
389
+ denominator 37.
390
+
391
+ Whenever we have a curve of j-invariant ``j``, we can compute the
392
+ corresponding l-isogeny by just scaling ``coeffs`` by the right
393
+ twisting factor and using the result as a kernel-polynomial.
394
+
395
+ ALGORITHM:
396
+
397
+ For small l it works fine to factor the l-division polynomial, but
398
+ this takes a long time for the larger l and is a very bad idea for
399
+ l=163; hence we use floating point arithmetic with a precision
400
+ which is known to work. This idea was suggested by Samir Siksek.
401
+
402
+ TESTS::
403
+
404
+ sage: from sage.schemes.elliptic_curves.isogeny_small_degree import sporadic_j, _sporadic_Q_data
405
+ sage: [_sporadic_Q_data(j) for j in sorted(sporadic_j) if j != -262537412640768000]
406
+ [([-269675595, -1704553285050],
407
+ [-31653754873248632711650187487655160190139073510876609346911928661154296875/37,
408
+ -1469048260972089939455942042937882262144594798448952781325533511718750,
409
+ -1171741935131505774747142644126089902595908234671576131857702734375,
410
+ -574934780393177024547076427530739751753985644656221274606250000,
411
+ -193516922725803688001809624711400287605136013195315374687500,
412
+ -47085563820928456130325308223963045033502182349693125000,
413
+ -8472233937388712980597845725196873697064639957437500,
414
+ -1124815211213953261752081095348112305023653750000,
415
+ -105684015609077608033913080859605951322531250,
416
+ -5911406027236569746089675554748135312500,
417
+ 22343907270397352965399097794968750,
418
+ 43602171843758666292581116410000,
419
+ 5054350766002463251474186500,
420
+ 350135768194635636171000,
421
+ 16633063574896677300,
422
+ 549939627039600,
423
+ 12182993865,
424
+ 163170,
425
+ 1]),
426
+ ([-117920, 15585808],
427
+ [426552448394636714720553816389274308035895411389805883034985546818882031845376,
428
+ -55876556222880738651382959148329502876096075327084935039031884373558741172224,
429
+ 3393295715290183821010552313572221545212247684503012173117764703828786020352,
430
+ -125729166452196578653551230178028570067747190427221869867485520072257044480,
431
+ 3121342502030777257351089270834971957072933779704445667351054593298530304,
432
+ -52544031605544530265465344472543470442324636919759253720520768014516224,
433
+ 532110915869155495738137756847596184665209453108323879594125221167104,
434
+ -399031158106622651277981701966309467713625045637309782055519780864,
435
+ -101914346170769215732007802723651742508893380955930030421292613632,
436
+ 2296526155500449624398016447877283594461904009374321659789443072,
437
+ -31950871094301541469458501953701002806003991982768349794795520,
438
+ 329792235011603804948028315065667439678526339671142107709440,
439
+ -2655636715955021784085217734679612378726442691190553837568,
440
+ 16825164648840434987220620681420687654501026066872664064,
441
+ -81705027839007003131400500185224450729843244954288128,
442
+ 273656504606483403474090105104132405333665144373248,
443
+ -320807702482945680116212224172370503903312084992,
444
+ -3166683390779345463318656135338172047199043584,
445
+ 27871349428383710305216046431806697565585408,
446
+ -132774697798318602604125735604528772808704,
447
+ 436096215568182871014215818309741314048,
448
+ -964687143341252402362763535357837312,
449
+ 942144169187362941776488535425024,
450
+ 2794850106281773765892648206336,
451
+ -17236916236678037389276086272,
452
+ 50979778712911923486851072,
453
+ -105035658611718440992768,
454
+ 161833913559276412928,
455
+ -188675698610077696,
456
+ 163929317513984,
457
+ -102098677888,
458
+ 42387952,
459
+ -10184,
460
+ 1]),
461
+ ([-13760, 621264],
462
+ [-1961864562041980324821547425314935668736,
463
+ 784270445793223959453256359333693751296,
464
+ -120528107728500223255333768387027271680,
465
+ 10335626145581464192664472924270362624,
466
+ -568426570575654606865505142156820480,
467
+ 21261993723422650574629752537088000,
468
+ -544630471727787626557612832587776,
469
+ 8870521306520473088172555763712,
470
+ -54993059067301585878494740480,
471
+ -1434261324709904840432549888,
472
+ 50978938193065926383894528,
473
+ -845761855773797582372864,
474
+ 8627493611216601088000,
475
+ -48299605284169187328,
476
+ -32782260293713920,
477
+ 3415534989828096,
478
+ -34580115625984,
479
+ 199359712512,
480
+ -730488128,
481
+ 1658080,
482
+ -2064,
483
+ 1]),
484
+ ([-3940515, 3010787550],
485
+ [-6458213126940667330314375,
486
+ 34699336325466068070000,
487
+ -72461450055340471500,
488
+ 68342601718080000,
489
+ -15140380554450,
490
+ -25802960400,
491
+ 23981220,
492
+ -8160,
493
+ 1]),
494
+ ([-38907, -2953962], [-20349931239, -424530315, -134838, 53658, 429, 1]),
495
+ ([-608, 5776],
496
+ [-34162868224,
497
+ -8540717056,
498
+ 6405537792,
499
+ -1123778560,
500
+ 84283392,
501
+ -2033152,
502
+ -92416,
503
+ 6992,
504
+ -152,
505
+ 1]),
506
+ ([-9504, 365904], [1294672896, -92835072, 1463616, 7920, -264, 1]),
507
+ ([-10395, 444150],
508
+ [-38324677699334121599624973029296875,
509
+ -17868327793500376961572310472656250,
510
+ 2569568362004197901139023084765625,
511
+ -95128267987528547588017818750000,
512
+ -822168183291347061312510937500,
513
+ 134395594560592096297190625000,
514
+ -2881389756919344324888937500,
515
+ -2503855007083401977250000,
516
+ 922779077075655997443750,
517
+ -11503912310262102937500,
518
+ -18237870962450291250,
519
+ 1457822151548910000,
520
+ -10087015556047500,
521
+ -13677678063000,
522
+ 490243338900,
523
+ -2461460400,
524
+ 5198445,
525
+ -4410,
526
+ 1]),
527
+ ([-856035, -341748450],
528
+ [103687510635057329105625,
529
+ 961598491955315190000,
530
+ 1054634146768300500,
531
+ -6553122389064000,
532
+ -14554350284850,
533
+ -2046589200,
534
+ 13185540,
535
+ 8160,
536
+ 1]),
537
+ ([-3267, -280962], [1480352841, -56169531, -2829222, 10890, 429, 1])]
538
+
539
+ See :issue:`22328`. This used to fail on l=37,
540
+ j=-162677523113838677 for which the kernel polynomial is not
541
+ integral::
542
+
543
+ sage: R = PolynomialRing(QQ,'x')
544
+ sage: for j in sporadic_j:
545
+ ....: ell = sporadic_j[j]
546
+ ....: if ell==163: continue # takes 40s
547
+ ....: E = EllipticCurve(j=j).short_weierstrass_model()
548
+ ....: f = R(_sporadic_Q_data(j)[1])
549
+ ....: g = E.division_polynomial(ell)
550
+ ....: assert g % f == 0
551
+ """
552
+ from sage.rings.real_mpfr import RealField
553
+ from sage.misc.misc_c import prod
554
+ ell = sporadic_j[j]
555
+ E = EllipticCurve(j=j).short_weierstrass_model()
556
+ a4a6 = list(E.ainvs())[3:]
557
+ L = E.period_lattice()
558
+ pr = 100
559
+ if ell == 163:
560
+ pr = 1000
561
+ elif ell > 30:
562
+ pr = 300
563
+ w1, w2 = L.basis(prec=pr)
564
+ X = polygen(RealField(pr),'X')
565
+ w = w1 # real period
566
+ if j in [-121, -24729001, -162677523113838677, QQ(-882216989)/131072]:
567
+ w = 2*w2-w1 # imaginary period
568
+ kerpol = prod([X-L.elliptic_exponential(n*w/ell)[0] for n in range(1,(ell+1)//2)])
569
+ if j == -162677523113838677:
570
+ kerpolcoeffs = [(37*c.real()).round()/37 for c in list(kerpol)]
571
+ else:
572
+ kerpolcoeffs = [c.real().round() for c in list(kerpol)]
573
+ return (a4a6,kerpolcoeffs)
574
+
575
+
576
+ def isogenies_sporadic_Q(E, l=None, minimal_models=True):
577
+ r"""
578
+ Return a list of sporadic l-isogenies from E (l = 11, 17, 19, 37,
579
+ 43, 67 or 163). Only for elliptic curves over `\QQ`.
580
+
581
+ INPUT:
582
+
583
+ - ``E`` -- an elliptic curve defined over `\QQ`
584
+
585
+ - ``l`` -- either ``None`` or a prime number
586
+
587
+ OUTPUT:
588
+
589
+ (list) If ``l`` is None, a list of all isogenies with domain ``E``
590
+ and of degree 11, 17, 19, 37, 43, 67 or 163; otherwise a list of
591
+ isogenies of the given degree.
592
+
593
+ .. NOTE::
594
+
595
+ This function would normally be invoked indirectly via
596
+ ``E.isogenies_prime_degree(l)``, which automatically calls the appropriate
597
+ function.
598
+
599
+ EXAMPLES::
600
+
601
+ sage: from sage.schemes.elliptic_curves.isogeny_small_degree import isogenies_sporadic_Q
602
+ sage: E = EllipticCurve('121a1')
603
+ sage: isogenies_sporadic_Q(E, 11)
604
+ [Isogeny of degree 11
605
+ from Elliptic Curve defined by y^2 + x*y + y = x^3 + x^2 - 30*x - 76
606
+ over Rational Field
607
+ to Elliptic Curve defined by y^2 + x*y + y = x^3 + x^2 - 305*x + 7888
608
+ over Rational Field]
609
+ sage: isogenies_sporadic_Q(E, 13)
610
+ []
611
+ sage: isogenies_sporadic_Q(E, 17)
612
+ []
613
+ sage: isogenies_sporadic_Q(E)
614
+ [Isogeny of degree 11
615
+ from Elliptic Curve defined by y^2 + x*y + y = x^3 + x^2 - 30*x - 76
616
+ over Rational Field
617
+ to Elliptic Curve defined by y^2 + x*y + y = x^3 + x^2 - 305*x + 7888
618
+ over Rational Field]
619
+
620
+ sage: E = EllipticCurve([1, 1, 0, -660, -7600])
621
+ sage: isogenies_sporadic_Q(E, 17)
622
+ [Isogeny of degree 17
623
+ from Elliptic Curve defined by y^2 + x*y = x^3 + x^2 - 660*x - 7600
624
+ over Rational Field
625
+ to Elliptic Curve defined by y^2 + x*y = x^3 + x^2 - 878710*x + 316677750
626
+ over Rational Field]
627
+ sage: isogenies_sporadic_Q(E)
628
+ [Isogeny of degree 17
629
+ from Elliptic Curve defined by y^2 + x*y = x^3 + x^2 - 660*x - 7600
630
+ over Rational Field
631
+ to Elliptic Curve defined by y^2 + x*y = x^3 + x^2 - 878710*x + 316677750
632
+ over Rational Field]
633
+ sage: isogenies_sporadic_Q(E, 11)
634
+ []
635
+
636
+ sage: E = EllipticCurve([0, 0, 1, -1862, -30956])
637
+ sage: isogenies_sporadic_Q(E, 11)
638
+ []
639
+ sage: isogenies_sporadic_Q(E, 19)
640
+ [Isogeny of degree 19
641
+ from Elliptic Curve defined by y^2 + y = x^3 - 1862*x - 30956
642
+ over Rational Field
643
+ to Elliptic Curve defined by y^2 + y = x^3 - 672182*x + 212325489
644
+ over Rational Field]
645
+ sage: isogenies_sporadic_Q(E)
646
+ [Isogeny of degree 19
647
+ from Elliptic Curve defined by y^2 + y = x^3 - 1862*x - 30956
648
+ over Rational Field
649
+ to Elliptic Curve defined by y^2 + y = x^3 - 672182*x + 212325489
650
+ over Rational Field]
651
+
652
+ sage: E = EllipticCurve([0, -1, 0, -6288, 211072])
653
+ sage: E.conductor()
654
+ 19600
655
+ sage: isogenies_sporadic_Q(E,37)
656
+ [Isogeny of degree 37
657
+ from Elliptic Curve defined by y^2 = x^3 - x^2 - 6288*x + 211072
658
+ over Rational Field
659
+ to Elliptic Curve defined by y^2 = x^3 - x^2 - 163137088*x - 801950801728
660
+ over Rational Field]
661
+
662
+ sage: E = EllipticCurve([1, 1, 0, -25178045, 48616918750])
663
+ sage: E.conductor()
664
+ 148225
665
+ sage: isogenies_sporadic_Q(E,37)
666
+ [Isogeny of degree 37
667
+ from Elliptic Curve defined by y^2 + x*y = x^3 + x^2 - 25178045*x + 48616918750
668
+ over Rational Field
669
+ to Elliptic Curve defined by y^2 + x*y = x^3 + x^2 - 970*x - 13075
670
+ over Rational Field]
671
+
672
+ sage: E = EllipticCurve([-3440, 77658])
673
+ sage: E.conductor()
674
+ 118336
675
+ sage: isogenies_sporadic_Q(E,43)
676
+ [Isogeny of degree 43
677
+ from Elliptic Curve defined by y^2 = x^3 - 3440*x + 77658
678
+ over Rational Field
679
+ to Elliptic Curve defined by y^2 = x^3 - 6360560*x - 6174354606
680
+ over Rational Field]
681
+
682
+ sage: E = EllipticCurve([-29480, -1948226])
683
+ sage: E.conductor()
684
+ 287296
685
+ sage: isogenies_sporadic_Q(E,67)
686
+ [Isogeny of degree 67
687
+ from Elliptic Curve defined by y^2 = x^3 - 29480*x - 1948226
688
+ over Rational Field
689
+ to Elliptic Curve defined by y^2 = x^3 - 132335720*x + 585954296438
690
+ over Rational Field]
691
+
692
+ sage: E = EllipticCurve([-34790720, -78984748304])
693
+ sage: E.conductor()
694
+ 425104
695
+ sage: isogenies_sporadic_Q(E,163)
696
+ [Isogeny of degree 163
697
+ from Elliptic Curve defined by y^2 = x^3 - 34790720*x - 78984748304
698
+ over Rational Field
699
+ to Elliptic Curve defined by y^2 = x^3 - 924354639680*x + 342062961763303088
700
+ over Rational Field]
701
+ """
702
+ j = E.j_invariant()
703
+ j = QQ(j)
704
+ if (j not in sporadic_j or (l is not None and sporadic_j[j] != l)):
705
+ return []
706
+
707
+ F = E.base_field()
708
+ data = _sporadic_Q_data(j)
709
+ Ew = E.short_weierstrass_model()
710
+ E_to_Ew = E.isomorphism_to(Ew)
711
+ c4, c6 = Ew.c_invariants()
712
+ (a4, a6), f = data
713
+ d = (c6*a4)/(18*c4*a6) # twisting factor
714
+ R = PolynomialRing(F, 'X')
715
+ n = len(f)
716
+ ker = R([d**(n-i-1) * f[i] for i in range(n)])
717
+ from sage.rings.number_field.number_field_base import NumberField
718
+ model = "minimal" if minimal_models and isinstance(F, NumberField) else None
719
+ isog = Ew.isogeny(kernel=ker, degree=l, model=model, check=False)
720
+ isog = isog * E_to_Ew
721
+ return [isog]
722
+
723
+
724
+ def isogenies_2(E, minimal_models=True):
725
+ r"""
726
+ Return a list of all 2-isogenies with domain ``E``.
727
+
728
+ INPUT:
729
+
730
+ - ``E`` -- an elliptic curve
731
+
732
+ - ``minimal_models`` -- boolean (default: ``True``); if ``True``, all
733
+ curves computed will be minimal or semi-minimal models. Over
734
+ fields of larger degree it can be expensive to compute these so
735
+ set to ``False``.
736
+
737
+ OUTPUT:
738
+
739
+ (list) 2-isogenies with domain ``E``. In general these are
740
+ normalised, but over `\QQ` and other number fields, the codomain
741
+ is a minimal model where possible.
742
+
743
+ EXAMPLES::
744
+
745
+ sage: from sage.schemes.elliptic_curves.isogeny_small_degree import isogenies_2
746
+ sage: E = EllipticCurve('14a1'); E
747
+ Elliptic Curve defined by y^2 + x*y + y = x^3 + 4*x - 6 over Rational Field
748
+ sage: [phi.codomain().ainvs() for phi in isogenies_2(E)]
749
+ [(1, 0, 1, -36, -70)]
750
+
751
+ sage: E = EllipticCurve([1,2,3,4,5]); E
752
+ Elliptic Curve defined by y^2 + x*y + 3*y = x^3 + 2*x^2 + 4*x + 5 over Rational Field
753
+ sage: [phi.codomain().ainvs() for phi in isogenies_2(E)]
754
+ []
755
+ sage: E = EllipticCurve(QQbar, [9,8]); E # needs sage.rings.number_field
756
+ Elliptic Curve defined by y^2 = x^3 + 9*x + 8 over Algebraic Field
757
+ sage: isogenies_2(E) # not implemented # needs sage.rings.number_field
758
+ """
759
+ f2 = E.division_polynomial(2)
760
+ x2 = sorted(f2.roots(multiplicities=False))
761
+ x = f2.parent().gen()
762
+ ff = [x-x2i for x2i in x2]
763
+ from sage.rings.number_field.number_field_base import NumberField
764
+ model = "minimal" if minimal_models and isinstance(E.base_field(), NumberField) else None
765
+ isogs = [E.isogeny(f, model=model) for f in ff]
766
+ return isogs
767
+
768
+
769
+ def isogenies_3(E, minimal_models=True):
770
+ r"""
771
+ Return a list of all 3-isogenies with domain ``E``.
772
+
773
+ INPUT:
774
+
775
+ - ``E`` -- an elliptic curve
776
+
777
+ - ``minimal_models`` -- boolean (default: ``True``); if ``True``, all
778
+ curves computed will be minimal or semi-minimal models. Over
779
+ fields of larger degree it can be expensive to compute these so
780
+ set to ``False``.
781
+
782
+ OUTPUT:
783
+
784
+ (list) 3-isogenies with domain ``E``. In general these are
785
+ normalised, but over `\QQ` or a number field, the codomain is a
786
+ global minimal model where possible.
787
+
788
+ EXAMPLES::
789
+
790
+ sage: from sage.schemes.elliptic_curves.isogeny_small_degree import isogenies_3
791
+ sage: E = EllipticCurve(GF(17), [1,1])
792
+ sage: [phi.codomain().ainvs() for phi in isogenies_3(E)]
793
+ [(0, 0, 0, 9, 7), (0, 0, 0, 0, 1)]
794
+
795
+ sage: E = EllipticCurve(GF(17^2,'a'), [1,1]) # needs sage.rings.finite_rings
796
+ sage: [phi.codomain().ainvs() for phi in isogenies_3(E)] # needs sage.rings.finite_rings
797
+ [(0, 0, 0, 9, 7), (0, 0, 0, 0, 1), (0, 0, 0, 5*a + 1, a + 13), (0, 0, 0, 12*a + 6, 16*a + 14)]
798
+
799
+ sage: E = EllipticCurve('19a1')
800
+ sage: [phi.codomain().ainvs() for phi in isogenies_3(E)]
801
+ [(0, 1, 1, 1, 0), (0, 1, 1, -769, -8470)]
802
+
803
+ sage: E = EllipticCurve([1,1])
804
+ sage: [phi.codomain().ainvs() for phi in isogenies_3(E)]
805
+ []
806
+ """
807
+ f3 = E.division_polynomial(3)
808
+ x3 = sorted(f3.roots(multiplicities=False))
809
+ x = f3.parent().gen()
810
+ ff = [x - x3i for x3i in x3]
811
+ from sage.rings.number_field.number_field_base import NumberField
812
+ model = "minimal" if minimal_models and isinstance(E.base_field(), NumberField) else None
813
+ isogs = [E.isogeny(f, model=model) for f in ff]
814
+ return isogs
815
+
816
+ # 6 special cases: `l` = 5, 7, 13 and `j` = 0, 1728.
817
+
818
+
819
+ def isogenies_5_0(E, minimal_models=True):
820
+ r"""
821
+ Return a list of all the 5-isogenies with domain ``E`` when the
822
+ j-invariant is 0.
823
+
824
+ INPUT:
825
+
826
+ - ``E`` -- an elliptic curve with j-invariant 0
827
+
828
+ - ``minimal_models`` -- boolean (default: ``True``); if ``True``, all
829
+ curves computed will be minimal or semi-minimal models. Over
830
+ fields of larger degree it can be expensive to compute these so
831
+ set to ``False``.
832
+
833
+ OUTPUT:
834
+
835
+ (list) 5-isogenies with codomain E. In general these are
836
+ normalised, but over `\QQ` or a number field, the codomain is a
837
+ global minimal model where possible.
838
+
839
+ .. NOTE::
840
+
841
+ This implementation requires that the characteristic is not 2,
842
+ 3 or 5.
843
+
844
+ .. NOTE::
845
+
846
+ This function would normally be invoked indirectly via ``E.isogenies_prime_degree(5)``.
847
+
848
+ EXAMPLES::
849
+
850
+ sage: from sage.schemes.elliptic_curves.isogeny_small_degree import isogenies_5_0
851
+ sage: E = EllipticCurve([0,12])
852
+ sage: isogenies_5_0(E)
853
+ []
854
+
855
+ sage: E = EllipticCurve(GF(13^2,'a'), [0,-3]) # needs sage.rings.finite_rings
856
+ sage: isogenies_5_0(E) # needs sage.rings.finite_rings
857
+ [Isogeny of degree 5
858
+ from Elliptic Curve defined by y^2 = x^3 + 10 over Finite Field in a of size 13^2
859
+ to Elliptic Curve defined by y^2 = x^3 + (4*a+6)*x + (2*a+10)
860
+ over Finite Field in a of size 13^2,
861
+ Isogeny of degree 5
862
+ from Elliptic Curve defined by y^2 = x^3 + 10 over Finite Field in a of size 13^2
863
+ to Elliptic Curve defined by y^2 = x^3 + (12*a+5)*x + (2*a+10)
864
+ over Finite Field in a of size 13^2,
865
+ Isogeny of degree 5
866
+ from Elliptic Curve defined by y^2 = x^3 + 10 over Finite Field in a of size 13^2
867
+ to Elliptic Curve defined by y^2 = x^3 + (10*a+2)*x + (2*a+10)
868
+ over Finite Field in a of size 13^2,
869
+ Isogeny of degree 5
870
+ from Elliptic Curve defined by y^2 = x^3 + 10 over Finite Field in a of size 13^2
871
+ to Elliptic Curve defined by y^2 = x^3 + (3*a+12)*x + (11*a+12)
872
+ over Finite Field in a of size 13^2,
873
+ Isogeny of degree 5
874
+ from Elliptic Curve defined by y^2 = x^3 + 10 over Finite Field in a of size 13^2
875
+ to Elliptic Curve defined by y^2 = x^3 + (a+4)*x + (11*a+12)
876
+ over Finite Field in a of size 13^2,
877
+ Isogeny of degree 5
878
+ from Elliptic Curve defined by y^2 = x^3 + 10 over Finite Field in a of size 13^2
879
+ to Elliptic Curve defined by y^2 = x^3 + (9*a+10)*x + (11*a+12)
880
+ over Finite Field in a of size 13^2]
881
+
882
+ sage: x = polygen(QQ, 'x')
883
+ sage: K.<a> = NumberField(x**6 - 320*x**3 - 320) # needs sage.rings.number_field
884
+ sage: E = EllipticCurve(K, [0,0,1,0,0]) # needs sage.rings.number_field
885
+ sage: isogenies_5_0(E) # needs sage.rings.number_field
886
+ [Isogeny of degree 5
887
+ from Elliptic Curve defined by y^2 + y = x^3
888
+ over Number Field in a with defining polynomial x^6 - 320*x^3 - 320
889
+ to Elliptic Curve defined by
890
+ y^2 + y = x^3 + (643/8*a^5-15779/48*a^4-32939/24*a^3-71989/2*a^2+214321/6*a-112115/3)*x
891
+ + (2901961/96*a^5+4045805/48*a^4+12594215/18*a^3-30029635/6*a^2+15341626/3*a-38944312/9)
892
+ over Number Field in a with defining polynomial x^6 - 320*x^3 - 320,
893
+ Isogeny of degree 5
894
+ from Elliptic Curve defined by y^2 + y = x^3
895
+ over Number Field in a with defining polynomial x^6 - 320*x^3 - 320
896
+ to Elliptic Curve defined by
897
+ y^2 + y = x^3 + (-1109/8*a^5-53873/48*a^4-180281/24*a^3-14491/2*a^2+35899/6*a-43745/3)*x
898
+ + (-17790679/96*a^5-60439571/48*a^4-77680504/9*a^3+1286245/6*a^2-4961854/3*a-73854632/9)
899
+ over Number Field in a with defining polynomial x^6 - 320*x^3 - 320]
900
+ """
901
+ F = E.base_field()
902
+ if E.j_invariant() != 0:
903
+ raise ValueError("j-invariant must be 0.")
904
+ if F.characteristic() in [2,3,5]:
905
+ raise NotImplementedError("Not implemented in characteristic 2, 3 or 5.")
906
+ if not F(5).is_square():
907
+ return []
908
+ Ew = E.short_weierstrass_model()
909
+ a = Ew.a6()
910
+ x = polygen(F)
911
+ betas = sorted((x**6-160*a*x**3-80*a**2).roots(multiplicities=False))
912
+ if not betas:
913
+ return []
914
+ gammas = [(beta**2 * (beta**3-140*a))/(120*a) for beta in betas]
915
+ from sage.rings.number_field.number_field_base import NumberField
916
+ model = "minimal" if minimal_models and isinstance(F, NumberField) else None
917
+ isogs = [Ew.isogeny(x**2+beta*x+gamma, model=model) for beta,gamma in zip(betas,gammas)]
918
+ iso = E.isomorphism_to(Ew)
919
+ isogs = [isog * iso for isog in isogs]
920
+ return isogs
921
+
922
+
923
+ def isogenies_5_1728(E, minimal_models=True):
924
+ r"""
925
+ Return a list of 5-isogenies with domain ``E`` when the j-invariant is
926
+ 1728.
927
+
928
+ INPUT:
929
+
930
+ - ``E`` -- an elliptic curve with j-invariant 1728
931
+
932
+ - ``minimal_models`` -- boolean (default: ``True``); if ``True``, all
933
+ curves computed will be minimal or semi-minimal models. Over
934
+ fields of larger degree it can be expensive to compute these so
935
+ set to ``False``.
936
+
937
+ OUTPUT:
938
+
939
+ (list) 5-isogenies with codomain E. In general these are
940
+ normalised; but if `-1` is a square then there are two
941
+ endomorphisms of degree `5`, for which the codomain is the same as
942
+ the domain curve; and over `\QQ` or a number field, the codomain
943
+ is a global minimal model where possible.
944
+
945
+ .. NOTE::
946
+
947
+ This implementation requires that the characteristic is not 2,
948
+ 3 or 5.
949
+
950
+ .. NOTE::
951
+
952
+ This function would normally be invoked indirectly via ``E.isogenies_prime_degree(5)``.
953
+
954
+ EXAMPLES::
955
+
956
+ sage: from sage.schemes.elliptic_curves.isogeny_small_degree import isogenies_5_1728
957
+ sage: E = EllipticCurve([7,0])
958
+ sage: isogenies_5_1728(E)
959
+ []
960
+
961
+ sage: E = EllipticCurve(GF(13), [11,0])
962
+ sage: isogenies_5_1728(E)
963
+ [Isogeny of degree 5
964
+ from Elliptic Curve defined by y^2 = x^3 + 11*x over Finite Field of size 13
965
+ to Elliptic Curve defined by y^2 = x^3 + 11*x over Finite Field of size 13,
966
+ Isogeny of degree 5
967
+ from Elliptic Curve defined by y^2 = x^3 + 11*x over Finite Field of size 13
968
+ to Elliptic Curve defined by y^2 = x^3 + 11*x over Finite Field of size 13]
969
+
970
+ An example of endomorphisms of degree 5::
971
+
972
+ sage: # needs sage.rings.number_field
973
+ sage: K.<i> = QuadraticField(-1)
974
+ sage: E = EllipticCurve(K, [0,0,0,1,0])
975
+ sage: isogenies_5_1728(E)
976
+ [Isogeny of degree 5
977
+ from Elliptic Curve defined by y^2 = x^3 + x over Number Field in i
978
+ with defining polynomial x^2 + 1 with i = 1*I
979
+ to Elliptic Curve defined by y^2 = x^3 + x over Number Field in i
980
+ with defining polynomial x^2 + 1 with i = 1*I,
981
+ Isogeny of degree 5
982
+ from Elliptic Curve defined by y^2 = x^3 + x over Number Field in i
983
+ with defining polynomial x^2 + 1 with i = 1*I
984
+ to Elliptic Curve defined by y^2 = x^3 + x over Number Field in i
985
+ with defining polynomial x^2 + 1 with i = 1*I]
986
+ sage: _[0].rational_maps()
987
+ (((4/25*i + 3/25)*x^5
988
+ + (4/5*i - 2/5)*x^3 - x)/(x^4 + (-4/5*i + 2/5)*x^2 + (-4/25*i - 3/25)),
989
+ ((11/125*i + 2/125)*x^6*y + (-23/125*i + 64/125)*x^4*y
990
+ + (141/125*i + 162/125)*x^2*y
991
+ + (3/25*i - 4/25)*y)/(x^6 + (-6/5*i + 3/5)*x^4
992
+ + (-12/25*i - 9/25)*x^2 + (2/125*i - 11/125)))
993
+
994
+ An example of 5-isogenies over a number field::
995
+
996
+ sage: # needs sage.rings.number_field
997
+ sage: x = polygen(QQ, 'x')
998
+ sage: K.<a> = NumberField(x**4 + 20*x**2 - 80)
999
+ sage: K(5).is_square() # necessary but not sufficient!
1000
+ True
1001
+ sage: E = EllipticCurve(K, [0,0,0,1,0])
1002
+ sage: isogenies_5_1728(E)
1003
+ [Isogeny of degree 5
1004
+ from Elliptic Curve defined by y^2 = x^3 + x
1005
+ over Number Field in a with defining polynomial x^4 + 20*x^2 - 80
1006
+ to Elliptic Curve defined by y^2 = x^3 + (-753/4*a^2-4399)*x + (2779*a^3+65072*a)
1007
+ over Number Field in a with defining polynomial x^4 + 20*x^2 - 80,
1008
+ Isogeny of degree 5
1009
+ from Elliptic Curve defined by y^2 = x^3 + x
1010
+ over Number Field in a with defining polynomial x^4 + 20*x^2 - 80
1011
+ to Elliptic Curve defined by y^2 = x^3 + (-753/4*a^2-4399)*x + (-2779*a^3-65072*a)
1012
+ over Number Field in a with defining polynomial x^4 + 20*x^2 - 80]
1013
+
1014
+ See :issue:`19840`::
1015
+
1016
+ sage: # needs sage.rings.number_field
1017
+ sage: K.<a> = NumberField(x^4 - 5*x^2 + 5)
1018
+ sage: E = EllipticCurve([a^2 + a + 1, a^3 + a^2 + a + 1, a^2 + a,
1019
+ ....: 17*a^3 + 34*a^2 - 16*a - 37,
1020
+ ....: 54*a^3 + 105*a^2 - 66*a - 135])
1021
+ sage: len(E.isogenies_prime_degree(5))
1022
+ 2
1023
+ sage: from sage.schemes.elliptic_curves.isogeny_small_degree import isogenies_5_1728
1024
+ sage: [phi.codomain().j_invariant() for phi in isogenies_5_1728(E)]
1025
+ [19691491018752*a^2 - 27212977933632, 19691491018752*a^2 - 27212977933632]
1026
+ """
1027
+ F = E.base_field()
1028
+ if E.j_invariant() != 1728:
1029
+ raise ValueError("j-invariant must be 1728.")
1030
+ if F.characteristic() in [2,3,5]:
1031
+ raise NotImplementedError("Not implemented in characteristic 2, 3 or 5.")
1032
+ from sage.rings.number_field.number_field_base import NumberField
1033
+ model = "minimal" if minimal_models and isinstance(F, NumberField) else None
1034
+ # quick test for a negative answer (from Fricke module)
1035
+ square5 = F(5).is_square()
1036
+ square1 = F(-1).is_square()
1037
+ if not square5 and not square1:
1038
+ return []
1039
+ Ew = E.short_weierstrass_model()
1040
+ iso = E.isomorphism_to(Ew)
1041
+ a = Ew.a4()
1042
+ x = polygen(F)
1043
+ isogs = []
1044
+ # 2 cases
1045
+ # Type 1: if -1 is a square we have 2 endomorphisms
1046
+ if square1:
1047
+ i = F(-1).sqrt()
1048
+ isogs = [Ew.isogeny(f) for f in [x**2+a/(1+2*i), x**2+a/(1-2*i)]]
1049
+ isogs = [isog.codomain().isomorphism_to(E) * isog for isog in isogs]
1050
+ # Type 2: if 5 is a square we have up to 4 (non-endomorphism) isogenies
1051
+ if square5:
1052
+ betas = sorted((x**4+20*a*x**2-80*a**2).roots(multiplicities=False))
1053
+ gammas = [(beta**2-2*a)/6 for beta in betas]
1054
+ isogs += [Ew.isogeny(x**2+beta*x+gamma, model=model) for beta,gamma in zip(betas,gammas)]
1055
+ isogs = [isog * iso for isog in isogs]
1056
+ return isogs
1057
+
1058
+
1059
+ def isogenies_7_0(E, minimal_models=True):
1060
+ r"""
1061
+ Return list of all 7-isogenies from E when the j-invariant is 0.
1062
+
1063
+ INPUT:
1064
+
1065
+ - ``E`` -- an elliptic curve with j-invariant 0
1066
+
1067
+ - ``minimal_models`` -- boolean (default: ``True``); if ``True``, all
1068
+ curves computed will be minimal or semi-minimal models. Over
1069
+ fields of larger degree it can be expensive to compute these so
1070
+ set to ``False``.
1071
+
1072
+ OUTPUT:
1073
+
1074
+ (list) 7-isogenies with codomain E. In general these are
1075
+ normalised; but if `-3` is a square then there are two
1076
+ endomorphisms of degree `7`, for which the codomain is the same as
1077
+ the domain; and over `\QQ` or a number field, the codomain is a
1078
+ global minimal model where possible.
1079
+
1080
+ .. NOTE::
1081
+
1082
+ This implementation requires that the characteristic is not 2,
1083
+ 3 or 7.
1084
+
1085
+ .. NOTE::
1086
+
1087
+ This function would normally be invoked indirectly via ``E.isogenies_prime_degree(7)``.
1088
+
1089
+ EXAMPLES:
1090
+
1091
+ First some examples of endomorphisms::
1092
+
1093
+ sage: from sage.schemes.elliptic_curves.isogeny_small_degree import isogenies_7_0
1094
+ sage: K.<r> = QuadraticField(-3) # needs sage.rings.number_field
1095
+ sage: E = EllipticCurve(K, [0,1]) # needs sage.rings.number_field
1096
+ sage: isogenies_7_0(E) # needs sage.rings.number_field
1097
+ [Isogeny of degree 7
1098
+ from Elliptic Curve defined by y^2 = x^3 + 1 over Number Field in r
1099
+ with defining polynomial x^2 + 3 with r = 1.732050807568878?*I
1100
+ to Elliptic Curve defined by y^2 = x^3 + 1 over Number Field in r
1101
+ with defining polynomial x^2 + 3 with r = 1.732050807568878?*I,
1102
+ Isogeny of degree 7
1103
+ from Elliptic Curve defined by y^2 = x^3 + 1 over Number Field in r
1104
+ with defining polynomial x^2 + 3 with r = 1.732050807568878?*I
1105
+ to Elliptic Curve defined by y^2 = x^3 + 1 over Number Field in r
1106
+ with defining polynomial x^2 + 3 with r = 1.732050807568878?*I]
1107
+
1108
+ sage: E = EllipticCurve(GF(13^2,'a'), [0,-3]) # needs sage.rings.finite_rings
1109
+ sage: isogenies_7_0(E) # needs sage.rings.finite_rings
1110
+ [Isogeny of degree 7
1111
+ from Elliptic Curve defined by y^2 = x^3 + 10 over Finite Field in a of size 13^2
1112
+ to Elliptic Curve defined by y^2 = x^3 + 10 over Finite Field in a of size 13^2,
1113
+ Isogeny of degree 7
1114
+ from Elliptic Curve defined by y^2 = x^3 + 10 over Finite Field in a of size 13^2
1115
+ to Elliptic Curve defined by y^2 = x^3 + 10 over Finite Field in a of size 13^2]
1116
+
1117
+ Now some examples of 7-isogenies which are not endomorphisms::
1118
+
1119
+ sage: K = GF(101)
1120
+ sage: E = EllipticCurve(K, [0,1])
1121
+ sage: isogenies_7_0(E)
1122
+ [Isogeny of degree 7
1123
+ from Elliptic Curve defined by y^2 = x^3 + 1 over Finite Field of size 101
1124
+ to Elliptic Curve defined by y^2 = x^3 + 55*x + 100 over Finite Field of size 101,
1125
+ Isogeny of degree 7
1126
+ from Elliptic Curve defined by y^2 = x^3 + 1 over Finite Field of size 101
1127
+ to Elliptic Curve defined by y^2 = x^3 + 83*x + 26 over Finite Field of size 101]
1128
+
1129
+ Examples over a number field::
1130
+
1131
+ sage: from sage.schemes.elliptic_curves.isogeny_small_degree import isogenies_7_0
1132
+ sage: E = EllipticCurve('27a1').change_ring(QuadraticField(-3,'r')) # needs sage.rings.number_field
1133
+ sage: isogenies_7_0(E) # needs sage.rings.number_field
1134
+ [Isogeny of degree 7
1135
+ from Elliptic Curve defined by y^2 + y = x^3 + (-7) over Number Field in r
1136
+ with defining polynomial x^2 + 3 with r = 1.732050807568878?*I
1137
+ to Elliptic Curve defined by y^2 + y = x^3 + (-7) over Number Field in r
1138
+ with defining polynomial x^2 + 3 with r = 1.732050807568878?*I,
1139
+ Isogeny of degree 7
1140
+ from Elliptic Curve defined by y^2 + y = x^3 + (-7) over Number Field in r
1141
+ with defining polynomial x^2 + 3 with r = 1.732050807568878?*I
1142
+ to Elliptic Curve defined by y^2 + y = x^3 + (-7) over Number Field in r
1143
+ with defining polynomial x^2 + 3 with r = 1.732050807568878?*I]
1144
+
1145
+ sage: # needs sage.rings.number_field sage.symbolic
1146
+ sage: x = polygen(QQ, 'x')
1147
+ sage: K.<a> = NumberField(x^6 + 1512*x^3 - 21168)
1148
+ sage: E = EllipticCurve(K, [0,1])
1149
+ sage: isogs = isogenies_7_0(E)
1150
+ sage: [phi.codomain().a_invariants() for phi in isogs]
1151
+ [(0,
1152
+ 0,
1153
+ 0,
1154
+ -415/98*a^5 - 675/14*a^4 + 2255/7*a^3 - 74700/7*a^2 - 25110*a - 66420,
1155
+ -141163/56*a^5 + 1443453/112*a^4 - 374275/2*a^3
1156
+ - 3500211/2*a^2 - 17871975/4*a - 7710065),
1157
+ (0,
1158
+ 0,
1159
+ 0,
1160
+ -24485/392*a^5 - 1080/7*a^4 - 2255/7*a^3 - 1340865/14*a^2 - 230040*a - 553500,
1161
+ 1753037/56*a^5 + 8345733/112*a^4 + 374275/2*a^3
1162
+ + 95377029/2*a^2 + 458385345/4*a + 275241835)]
1163
+ sage: [phi.codomain().j_invariant() for phi in isogs]
1164
+ [158428486656000/7*a^3 - 313976217600000,
1165
+ -158428486656000/7*a^3 - 34534529335296000]
1166
+ """
1167
+ if E.j_invariant() != 0:
1168
+ raise ValueError("j-invariant must be 0.")
1169
+ F = E.base_field()
1170
+ if F.characteristic() in [2,3,7]:
1171
+ raise NotImplementedError("Not implemented when the characteristic of the base field is 2, 3 or 7.")
1172
+ x = polygen(F)
1173
+ Ew = E.short_weierstrass_model()
1174
+ iso = E.isomorphism_to(Ew)
1175
+ a = Ew.a6()
1176
+ from sage.rings.number_field.number_field_base import NumberField
1177
+ model = "minimal" if minimal_models and isinstance(F, NumberField) else None
1178
+
1179
+ # there will be 2 endomorphisms if -3 is a square:
1180
+
1181
+ ts = sorted((x**2+3).roots(multiplicities=False))
1182
+ kers = [7*x-(2+6*t) for t in ts]
1183
+ kers = [k(x**3/a).monic() for k in kers]
1184
+ isogs = [Ew.isogeny(k,model=model) for k in kers]
1185
+ isogs = [endo.codomain().isomorphism_to(E) * endo for endo in isogs]
1186
+
1187
+ # we may have up to 6 other isogenies:
1188
+ ts = (x**2-21).roots(multiplicities=False)
1189
+ for t0 in ts:
1190
+ s3 = a/(28+6*t0)
1191
+ ss = sorted((x**3-s3).roots(multiplicities=False))
1192
+ ker = x**3 - 2*t0*x**2 - 4*t0*x + 4*t0 + 28
1193
+ kers = [ker(x/s).monic() for s in ss]
1194
+ isogs += [Ew.isogeny(k, model=model) for k in kers]
1195
+
1196
+ isogs = [isog * iso for isog in isogs]
1197
+ return isogs
1198
+
1199
+
1200
+ def isogenies_7_1728(E, minimal_models=True):
1201
+ r"""
1202
+ Return list of all 7-isogenies from E when the j-invariant is 1728.
1203
+
1204
+ INPUT:
1205
+
1206
+ - ``E`` -- an elliptic curve with j-invariant 1728
1207
+
1208
+ - ``minimal_models`` -- boolean (default: ``True``); if ``True``, all
1209
+ curves computed will be minimal or semi-minimal models. Over
1210
+ fields of larger degree it can be expensive to compute these so
1211
+ set to ``False``.
1212
+
1213
+ OUTPUT:
1214
+
1215
+ (list) 7-isogenies with codomain E. In general these are
1216
+ normalised; but over `\QQ` or a number field, the codomain is a
1217
+ global minimal model where possible.
1218
+
1219
+ .. NOTE::
1220
+
1221
+ This implementation requires that the characteristic is not 2,
1222
+ 3, or 7.
1223
+
1224
+ .. NOTE::
1225
+
1226
+ This function would normally be invoked indirectly via ``E.isogenies_prime_degree(7)``.
1227
+
1228
+ EXAMPLES::
1229
+
1230
+ sage: from sage.schemes.elliptic_curves.isogeny_small_degree import isogenies_7_1728
1231
+ sage: E = EllipticCurve(GF(47), [1, 0])
1232
+ sage: isogenies_7_1728(E)
1233
+ [Isogeny of degree 7
1234
+ from Elliptic Curve defined by y^2 = x^3 + x over Finite Field of size 47
1235
+ to Elliptic Curve defined by y^2 = x^3 + 26 over Finite Field of size 47,
1236
+ Isogeny of degree 7
1237
+ from Elliptic Curve defined by y^2 = x^3 + x over Finite Field of size 47
1238
+ to Elliptic Curve defined by y^2 = x^3 + 21 over Finite Field of size 47]
1239
+
1240
+ An example in characteristic 53 (for which an earlier implementation did not work)::
1241
+
1242
+ sage: # needs sage.rings.finite_rings
1243
+ sage: from sage.schemes.elliptic_curves.isogeny_small_degree import isogenies_7_1728
1244
+ sage: E = EllipticCurve(GF(53), [1, 0])
1245
+ sage: isogenies_7_1728(E)
1246
+ []
1247
+ sage: E = EllipticCurve(GF(53^2,'a'), [1, 0])
1248
+ sage: [iso.codomain().ainvs() for iso in isogenies_7_1728(E)]
1249
+ [(0, 0, 0, 36, 19*a + 15), (0, 0, 0, 36, 34*a + 38), (0, 0, 0, 33, 39*a + 28),
1250
+ (0, 0, 0, 33, 14*a + 25), (0, 0, 0, 19, 45*a + 16), (0, 0, 0, 19, 8*a + 37),
1251
+ (0, 0, 0, 3, 45*a + 16), (0, 0, 0, 3, 8*a + 37)]
1252
+
1253
+ ::
1254
+
1255
+ sage: # needs sage.rings.number_field
1256
+ sage: x = polygen(QQ, 'x')
1257
+ sage: K.<a> = NumberField(x^8 + 84*x^6 - 1890*x^4 + 644*x^2 - 567)
1258
+ sage: E = EllipticCurve(K, [1, 0])
1259
+ sage: isogs = isogenies_7_1728(E)
1260
+ sage: [phi.codomain().j_invariant() for phi in isogs]
1261
+ [-526110256146528/53*a^6 + 183649373229024*a^4
1262
+ - 3333881559996576/53*a^2 + 2910267397643616/53,
1263
+ -526110256146528/53*a^6 + 183649373229024*a^4
1264
+ - 3333881559996576/53*a^2 + 2910267397643616/53]
1265
+ sage: E1 = isogs[0].codomain()
1266
+ sage: E2 = isogs[1].codomain()
1267
+ sage: E1.is_isomorphic(E2)
1268
+ False
1269
+ sage: E1.is_quadratic_twist(E2)
1270
+ -1
1271
+ """
1272
+ if E.j_invariant() != 1728:
1273
+ raise ValueError("j_invariant must be 1728 (in base field).")
1274
+ F = E.base_field()
1275
+ if F.characteristic() in [2,3,7]:
1276
+ raise NotImplementedError("Not implemented when the characteristic of the base field is 2, 3 or 7.")
1277
+ Ew = E.short_weierstrass_model()
1278
+ iso = E.isomorphism_to(Ew)
1279
+ a = Ew.a4()
1280
+
1281
+ ts = (Fricke_module(7)-1728).numerator().roots(F,multiplicities=False)
1282
+ if not ts:
1283
+ return []
1284
+ ts.sort()
1285
+ isogs = []
1286
+ from sage.rings.number_field.number_field_base import NumberField
1287
+ model = "minimal" if minimal_models and isinstance(F, NumberField) else None
1288
+ x = polygen(F)
1289
+ for t0 in ts:
1290
+ s2 = a/t0
1291
+ ss = sorted((x**2-s2).roots(multiplicities=False))
1292
+ ker = 9*x**3 + (-3*t0**3 - 36*t0**2 - 123*t0)*x**2 + (-8*t0**3 - 101*t0**2 - 346*t0 + 35)*x - 7*t0**3 - 88*t0**2 - 296*t0 + 28
1293
+
1294
+ kers = [ker(x/s) for s in ss]
1295
+ isogs += [Ew.isogeny(k.monic(), model=model) for k in kers]
1296
+ isogs = [isog * iso for isog in isogs]
1297
+ return isogs
1298
+
1299
+
1300
+ def isogenies_13_0(E, minimal_models=True):
1301
+ """
1302
+ Return list of all 13-isogenies from E when the j-invariant is 0.
1303
+
1304
+ INPUT:
1305
+
1306
+ - ``E`` -- an elliptic curve with j-invariant 0
1307
+
1308
+ - ``minimal_models`` -- boolean (default: ``True``); if ``True``, all
1309
+ curves computed will be minimal or semi-minimal models. Over
1310
+ fields of larger degree it can be expensive to compute these so
1311
+ set to ``False``.
1312
+
1313
+ OUTPUT:
1314
+
1315
+ (list) 13-isogenies with codomain E. In general these are
1316
+ normalised; but if `-3` is a square then there are two
1317
+ endomorphisms of degree `13`, for which the codomain is the same
1318
+ as the domain.
1319
+
1320
+ .. NOTE::
1321
+
1322
+ This implementation requires that the characteristic is not 2,
1323
+ 3 or 13.
1324
+
1325
+ .. NOTE::
1326
+
1327
+ This function would normally be invoked indirectly via ``E.isogenies_prime_degree(13)``.
1328
+
1329
+ EXAMPLES::
1330
+
1331
+ sage: from sage.schemes.elliptic_curves.isogeny_small_degree import isogenies_13_0
1332
+
1333
+ Endomorphisms of degree 13 will exist when -3 is a square::
1334
+
1335
+ sage: # needs sage.rings.number_field
1336
+ sage: K.<r> = QuadraticField(-3)
1337
+ sage: E = EllipticCurve(K, [0, r]); E
1338
+ Elliptic Curve defined by y^2 = x^3 + r over Number Field in r
1339
+ with defining polynomial x^2 + 3 with r = 1.732050807568878?*I
1340
+ sage: isogenies_13_0(E)
1341
+ [Isogeny of degree 13
1342
+ from Elliptic Curve defined by y^2 = x^3 + r over Number Field in r
1343
+ with defining polynomial x^2 + 3 with r = 1.732050807568878?*I
1344
+ to Elliptic Curve defined by y^2 = x^3 + r over Number Field in r
1345
+ with defining polynomial x^2 + 3 with r = 1.732050807568878?*I,
1346
+ Isogeny of degree 13
1347
+ from Elliptic Curve defined by y^2 = x^3 + r over Number Field in r
1348
+ with defining polynomial x^2 + 3 with r = 1.732050807568878?*I
1349
+ to Elliptic Curve defined by y^2 = x^3 + r over Number Field in r
1350
+ with defining polynomial x^2 + 3 with r = 1.732050807568878?*I]
1351
+ sage: isogenies_13_0(E)[0].rational_maps()
1352
+ (((7/338*r + 23/338)*x^13 + (-164/13*r - 420/13)*x^10
1353
+ + (720/13*r + 3168/13)*x^7 + (3840/13*r - 576/13)*x^4
1354
+ + (4608/13*r + 2304/13)*x)/(x^12 + (4*r + 36)*x^9 + (1080/13*r + 3816/13)*x^6
1355
+ + (2112/13*r - 5184/13)*x^3 + (-17280/169*r - 1152/169)),
1356
+ ((18/2197*r + 35/2197)*x^18*y + (23142/2197*r + 35478/2197)*x^15*y
1357
+ + (-1127520/2197*r - 1559664/2197)*x^12*y + (-87744/2197*r + 5992704/2197)*x^9*y
1358
+ + (-6625152/2197*r - 9085824/2197)*x^6*y + (-28919808/2197*r - 2239488/2197)*x^3*y
1359
+ + (-1990656/2197*r - 3870720/2197)*y)/(x^18 + (6*r + 54)*x^15
1360
+ + (3024/13*r + 11808/13)*x^12 + (31296/13*r + 51840/13)*x^9
1361
+ + (487296/169*r - 2070144/169)*x^6 + (-940032/169*r + 248832/169)*x^3
1362
+ + (1990656/2197*r + 3870720/2197)))
1363
+
1364
+ An example of endomorphisms over a finite field::
1365
+
1366
+ sage: # needs sage.rings.finite_rings
1367
+ sage: K = GF(19^2,'a')
1368
+ sage: E = EllipticCurve(j=K(0)); E
1369
+ Elliptic Curve defined by y^2 = x^3 + 1
1370
+ over Finite Field in a of size 19^2
1371
+ sage: isogenies_13_0(E)
1372
+ [Isogeny of degree 13
1373
+ from Elliptic Curve defined by y^2 = x^3 + 1 over Finite Field in a of size 19^2
1374
+ to Elliptic Curve defined by y^2 = x^3 + 1 over Finite Field in a of size 19^2,
1375
+ Isogeny of degree 13
1376
+ from Elliptic Curve defined by y^2 = x^3 + 1 over Finite Field in a of size 19^2
1377
+ to Elliptic Curve defined by y^2 = x^3 + 1 over Finite Field in a of size 19^2]
1378
+ sage: isogenies_13_0(E)[0].rational_maps()
1379
+ ((6*x^13 - 6*x^10 - 3*x^7 + 6*x^4 + x)/(x^12 - 5*x^9 - 9*x^6 - 7*x^3 + 5),
1380
+ (-8*x^18*y - 9*x^15*y + 9*x^12*y - 5*x^9*y
1381
+ + 5*x^6*y - 7*x^3*y + 7*y)/(x^18 + 2*x^15 + 3*x^12 - x^9 + 8*x^6 - 9*x^3 + 7))
1382
+
1383
+ A previous implementation did not work in some characteristics::
1384
+
1385
+ sage: K = GF(29)
1386
+ sage: E = EllipticCurve(j=K(0))
1387
+ sage: isogenies_13_0(E)
1388
+ [Isogeny of degree 13
1389
+ from Elliptic Curve defined by y^2 = x^3 + 1 over Finite Field of size 29
1390
+ to Elliptic Curve defined by y^2 = x^3 + 26*x + 12 over Finite Field of size 29,
1391
+ Isogeny of degree 13
1392
+ from Elliptic Curve defined by y^2 = x^3 + 1 over Finite Field of size 29
1393
+ to Elliptic Curve defined by y^2 = x^3 + 16*x + 28 over Finite Field of size 29]
1394
+
1395
+ ::
1396
+
1397
+ sage: K = GF(101)
1398
+ sage: E = EllipticCurve(j=K(0)); E.ainvs()
1399
+ (0, 0, 0, 0, 1)
1400
+ sage: [phi.codomain().ainvs() for phi in isogenies_13_0(E)]
1401
+ [(0, 0, 0, 64, 36), (0, 0, 0, 42, 66)]
1402
+
1403
+ ::
1404
+
1405
+ sage: x = polygen(QQ)
1406
+ sage: f = x^12 + 78624*x^9 - 130308048*x^6 + 2270840832*x^3 - 54500179968
1407
+ sage: K.<a> = NumberField(f) # needs sage.rings.number_field
1408
+ sage: E = EllipticCurve(j=K(0)); E.ainvs() # needs sage.rings.number_field
1409
+ (0, 0, 0, 0, 1)
1410
+ sage: len([phi.codomain().ainvs() # long time # needs sage.rings.number_field
1411
+ ....: for phi in isogenies_13_0(E)])
1412
+ 2
1413
+ """
1414
+ if E.j_invariant() != 0:
1415
+ raise ValueError("j-invariant must be 0.")
1416
+ F = E.base_field()
1417
+ if F.characteristic() in [2,3,13]:
1418
+ raise NotImplementedError("Not implemented when the characteristic of the base field is 2, 3 or 13.")
1419
+ Ew = E.short_weierstrass_model()
1420
+ iso = E.isomorphism_to(Ew)
1421
+ a = Ew.a6()
1422
+ from sage.rings.number_field.number_field_base import NumberField
1423
+ model = "minimal" if minimal_models and isinstance(F, NumberField) else None
1424
+ x = polygen(F)
1425
+
1426
+ # there will be 2 endomorphisms if -3 is a square:
1427
+ ts = sorted((x**2+3).roots(multiplicities=False))
1428
+ kers = [13*x**2 + (78*t + 26)*x + 24*t + 40 for t in ts]
1429
+ kers = [k(x**3/a).monic() for k in kers]
1430
+ isogs = [Ew.isogeny(k,model=model) for k in kers]
1431
+ isogs = [endo.codomain().isomorphism_to(E) * endo for endo in isogs]
1432
+
1433
+ # we may have up to 12 other isogenies:
1434
+ ts = sorted((x**4 + 7*x**3 + 20*x**2 + 19*x + 1).roots(multiplicities=False))
1435
+ for t0 in ts:
1436
+ s3 = a / (6*t0**3 + 32*t0**2 + 68*t0 + 4)
1437
+ ss = sorted((x**3-s3).roots(multiplicities=False))
1438
+ ker = (x**6 + (20*t0**3 + 106*t0**2 + 218*t0 + 4)*x**5
1439
+ + (-826*t0**3 - 4424*t0**2 - 9244*t0 - 494)*x**4
1440
+ + (13514*t0**3 + 72416*t0**2 + 151416*t0 + 8238)*x**3
1441
+ + (-101948*t0**3 - 546304*t0**2 - 1142288*t0 - 62116)*x**2
1442
+ + (354472*t0**3 + 1899488*t0**2 + 3971680*t0 + 215960)*x
1443
+ - 459424*t0**3 - 2461888*t0**2 - 5147648*t0 - 279904)
1444
+ kers = [ker(x/s).monic() for s in ss]
1445
+ isogs += [Ew.isogeny(k, model=model) for k in kers]
1446
+
1447
+ isogs = [isog * iso for isog in isogs]
1448
+
1449
+ return isogs
1450
+
1451
+
1452
+ def isogenies_13_1728(E, minimal_models=True):
1453
+ r"""
1454
+ Return list of all 13-isogenies from E when the j-invariant is 1728.
1455
+
1456
+ INPUT:
1457
+
1458
+ - ``E`` -- an elliptic curve with j-invariant 1728
1459
+
1460
+ - ``minimal_models`` -- boolean (default: ``True``); if ``True``, all
1461
+ curves computed will be minimal or semi-minimal models. Over
1462
+ fields of larger degree it can be expensive to compute these so
1463
+ set to ``False``.
1464
+
1465
+ OUTPUT:
1466
+
1467
+ (list) 13-isogenies with codomain E. In general these are
1468
+ normalised; but if `-1` is a square then there are two
1469
+ endomorphisms of degree `13`, for which the codomain is the same
1470
+ as the domain; and over `\QQ` or a number field, the codomain is a
1471
+ global minimal model where possible.
1472
+
1473
+ .. NOTE::
1474
+
1475
+ This implementation requires that the characteristic is not
1476
+ 2, 3 or 13.
1477
+
1478
+ .. NOTE::
1479
+
1480
+ This function would normally be invoked indirectly via ``E.isogenies_prime_degree(13)``.
1481
+
1482
+ EXAMPLES::
1483
+
1484
+ sage: from sage.schemes.elliptic_curves.isogeny_small_degree import isogenies_13_1728
1485
+
1486
+ sage: K.<i> = QuadraticField(-1) # needs sage.rings.number_field
1487
+ sage: E = EllipticCurve([0,0,0,i,0]); E.ainvs() # needs sage.rings.number_field
1488
+ (0, 0, 0, i, 0)
1489
+ sage: isogenies_13_1728(E) # needs sage.rings.number_field
1490
+ [Isogeny of degree 13
1491
+ from Elliptic Curve defined by y^2 = x^3 + i*x over Number Field in i
1492
+ with defining polynomial x^2 + 1 with i = 1*I
1493
+ to Elliptic Curve defined by y^2 = x^3 + i*x over Number Field in i
1494
+ with defining polynomial x^2 + 1 with i = 1*I,
1495
+ Isogeny of degree 13
1496
+ from Elliptic Curve defined by y^2 = x^3 + i*x over Number Field in i
1497
+ with defining polynomial x^2 + 1 with i = 1*I
1498
+ to Elliptic Curve defined by y^2 = x^3 + i*x over Number Field in i
1499
+ with defining polynomial x^2 + 1 with i = 1*I]
1500
+
1501
+ ::
1502
+
1503
+ sage: K = GF(83)
1504
+ sage: E = EllipticCurve(K, [0,0,0,5,0]); E.ainvs()
1505
+ (0, 0, 0, 5, 0)
1506
+ sage: isogenies_13_1728(E)
1507
+ []
1508
+ sage: K = GF(89)
1509
+ sage: E = EllipticCurve(K, [0,0,0,5,0]); E.ainvs()
1510
+ (0, 0, 0, 5, 0)
1511
+ sage: isogenies_13_1728(E)
1512
+ [Isogeny of degree 13
1513
+ from Elliptic Curve defined by y^2 = x^3 + 5*x over Finite Field of size 89
1514
+ to Elliptic Curve defined by y^2 = x^3 + 5*x over Finite Field of size 89,
1515
+ Isogeny of degree 13
1516
+ from Elliptic Curve defined by y^2 = x^3 + 5*x over Finite Field of size 89
1517
+ to Elliptic Curve defined by y^2 = x^3 + 5*x over Finite Field of size 89]
1518
+
1519
+ ::
1520
+
1521
+ sage: K = GF(23)
1522
+ sage: E = EllipticCurve(K, [1,0])
1523
+ sage: isogenies_13_1728(E)
1524
+ [Isogeny of degree 13
1525
+ from Elliptic Curve defined by y^2 = x^3 + x over Finite Field of size 23
1526
+ to Elliptic Curve defined by y^2 = x^3 + 16 over Finite Field of size 23,
1527
+ Isogeny of degree 13
1528
+ from Elliptic Curve defined by y^2 = x^3 + x over Finite Field of size 23
1529
+ to Elliptic Curve defined by y^2 = x^3 + 7 over Finite Field of size 23]
1530
+
1531
+ ::
1532
+
1533
+ sage: x = polygen(QQ)
1534
+ sage: f = (x^12 + 1092*x^10 - 432432*x^8 + 6641024*x^6
1535
+ ....: - 282896640*x^4 - 149879808*x^2 - 349360128)
1536
+ sage: K.<a> = NumberField(f) # needs sage.rings.number_field
1537
+ sage: E = EllipticCurve(K, [1,0]) # needs sage.rings.number_field
1538
+ sage: [phi.codomain().ainvs() # long time # needs sage.rings.number_field
1539
+ ....: for phi in isogenies_13_1728(E)]
1540
+ [(0,
1541
+ 0,
1542
+ 0,
1543
+ -4225010072113/3063768069807341568*a^10 - 24841071989413/15957125363579904*a^8
1544
+ + 11179537789374271/21276167151439872*a^6 - 407474562289492049/47871376090739712*a^4
1545
+ + 1608052769560747/4522994717568*a^2 + 7786720245212809/36937790193472,
1546
+ -363594277511/574456513088876544*a^11 - 7213386922793/2991961005671232*a^9
1547
+ - 2810970361185589/1329760446964992*a^7 + 281503836888046601/8975883017013696*a^5
1548
+ - 1287313166530075/848061509544*a^3 + 9768837984886039/6925835661276*a),
1549
+ (0,
1550
+ 0,
1551
+ 0,
1552
+ -4225010072113/3063768069807341568*a^10 - 24841071989413/15957125363579904*a^8
1553
+ + 11179537789374271/21276167151439872*a^6 - 407474562289492049/47871376090739712*a^4
1554
+ + 1608052769560747/4522994717568*a^2 + 7786720245212809/36937790193472,
1555
+ 363594277511/574456513088876544*a^11 + 7213386922793/2991961005671232*a^9
1556
+ + 2810970361185589/1329760446964992*a^7 - 281503836888046601/8975883017013696*a^5
1557
+ + 1287313166530075/848061509544*a^3 - 9768837984886039/6925835661276*a)]
1558
+ """
1559
+ if E.j_invariant() != 1728:
1560
+ raise ValueError("j-invariant must be 1728.")
1561
+ F = E.base_field()
1562
+ if F.characteristic() in [2, 3, 13]:
1563
+ raise NotImplementedError("Not implemented when the characteristic of the base field is 2, 3 or 13.")
1564
+ Ew = E.short_weierstrass_model()
1565
+ iso = E.isomorphism_to(Ew)
1566
+ a = Ew.a4()
1567
+ from sage.rings.number_field.number_field_base import NumberField
1568
+ model = "minimal" if minimal_models and isinstance(F, NumberField) else None
1569
+ x = polygen(F)
1570
+
1571
+ # we will have two endomorphisms if -1 is a square:
1572
+ ts = sorted((x**2+1).roots(multiplicities=False))
1573
+ kers = [13*x**3 + (-26*i - 13)*x**2 + (-52*i - 13)*x - 2*i - 3 for i in ts]
1574
+ kers = [k(x**2/a).monic() for k in kers]
1575
+ isogs = [Ew.isogeny(k,model=model) for k in kers]
1576
+ isogs = [endo.codomain().isomorphism_to(E) * endo for endo in isogs]
1577
+
1578
+ # we may have up to 12 other isogenies:
1579
+
1580
+ ts = sorted((x**6 + 10*x**5 + 46*x**4 + 108*x**3 + 122*x**2 + 38*x - 1).roots(multiplicities=False))
1581
+ for t0 in ts:
1582
+ s2 = a/(66*t0**5 + 630*t0**4 + 2750*t0**3 + 5882*t0**2 + 5414*t0 + 162)
1583
+ ss = sorted((x**2-s2).roots(multiplicities=False))
1584
+ ker = (x**6 + (-66*t0**5 - 630*t0**4 - 2750*t0**3 - 5882*t0**2
1585
+ - 5414*t0 - 162)*x**5 + (-21722*t0**5 - 205718*t0**4 -
1586
+ 890146*t0**3 - 1873338*t0**2 - 1652478*t0 + 61610)*x**4
1587
+ + (-3391376*t0**5 - 32162416*t0**4 - 139397232*t0**3 -
1588
+ 294310576*t0**2 - 261885968*t0 + 6105552)*x**3 +
1589
+ (-241695080*t0**5 - 2291695976*t0**4 - 9930313256*t0**3
1590
+ - 20956609720*t0**2 - 18625380856*t0 + 469971320)*x**2 +
1591
+ (-8085170432*t0**5 - 76663232384*t0**4 -
1592
+ 332202985024*t0**3 - 701103233152*t0**2 -
1593
+ 623190845440*t0 + 15598973056)*x - 101980510208*t0**5 -
1594
+ 966973468160*t0**4 - 4190156868352*t0**3 -
1595
+ 8843158270336*t0**2 - 7860368751232*t0 + 196854655936)
1596
+
1597
+ kers = [ker(x/s).monic() for s in ss]
1598
+ isogs += [Ew.isogeny(k, model=model) for k in kers]
1599
+
1600
+ isogs = [isog * iso for isog in isogs]
1601
+
1602
+ return isogs
1603
+
1604
+ # List of primes l for which X_0(l) is (hyper)elliptic and X_0^+(l) has genus 0
1605
+
1606
+
1607
+ hyperelliptic_primes = [11, 17, 19, 23, 29, 31, 41, 47, 59, 71]
1608
+
1609
+
1610
+ @cached_function
1611
+ def _hyperelliptic_isogeny_data(l):
1612
+ r"""
1613
+ Helper function for elliptic curve isogenies.
1614
+
1615
+ INPUT:
1616
+
1617
+ - ``l`` -- a prime in [11, 17, 19, 23, 29, 31, 41, 47, 59, 71]
1618
+
1619
+ OUTPUT: a dict holding a collection of precomputed data needed for
1620
+ computing `l`-isogenies
1621
+
1622
+ EXAMPLES::
1623
+
1624
+ sage: from sage.schemes.elliptic_curves.isogeny_small_degree import _hyperelliptic_isogeny_data
1625
+ sage: HID = _hyperelliptic_isogeny_data(11)
1626
+ sage: HID['A2']
1627
+ 55*u - 33
1628
+ sage: HID['A4']
1629
+ -183*u^2 + 738*u - 180*v - 135
1630
+ sage: HID['A6']
1631
+ 1330*u^3 - 11466*u^2 + 1332*u*v + 2646*u - 1836*v + 1890
1632
+ sage: HID['alpha']
1633
+ u^11 - 55*u^10 + 1188*u^9 - 12716*u^8 + 69630*u^7 - 177408*u^6 + 133056*u^5 + 132066*u^4 - 187407*u^3 + 40095*u^2 + 24300*u - 6750
1634
+ sage: HID['beta']
1635
+ u^9 - 47*u^8 + 843*u^7 - 7187*u^6 + 29313*u^5 - 48573*u^4 + 10665*u^3 + 27135*u^2 - 12150*u
1636
+ sage: HID['hyper_poly']
1637
+ u^4 - 16*u^3 + 2*u^2 + 12*u - 7
1638
+
1639
+ sage: _hyperelliptic_isogeny_data(37)
1640
+ Traceback (most recent call last):
1641
+ ...
1642
+ ValueError: 37 must be one of [11, 17, 19, 23, 29, 31, 41, 47, 59, 71].
1643
+ """
1644
+ if l not in hyperelliptic_primes:
1645
+ raise ValueError("%s must be one of %s." % (l,hyperelliptic_primes))
1646
+ data = {}
1647
+ Zu = PolynomialRing(ZZ,'u')
1648
+ Zuv = PolynomialRing(ZZ,['u','v'])
1649
+ Zxuv = PolynomialRing(ZZ,['x','u','v'])
1650
+ x,u,v = Zxuv.gens()
1651
+ if l == 11:
1652
+ data['hyper_poly'] = Zu([-7, 12, 2, -16, 1])
1653
+ data['A2'] = Zu([-33, 55])
1654
+ data['A4'] = Zuv(Zu([-135, 738, -183])+v*Zu([-180]))
1655
+ data['A6'] = Zuv(Zu([1890, 2646, -11466, 1330]) + v*Zu([-1836, 1332]))
1656
+ data['alpha'] = Zu([-6750, 24300, 40095, -187407, 132066, 133056, -177408, 69630, -12716, 1188, -55, 1])
1657
+ data['beta'] = Zu([0, -12150, 27135, 10665, -48573, 29313, -7187, 843, -47, 1])
1658
+ #beta factors as (u - 15) * (u - 6) * (u - 3) * (u - 1) * u * (u**2 - 12*u - 9) * (u**2 - 10*u + 5)
1659
+ return data
1660
+ if l == 17:
1661
+ data['hyper_poly'] = Zu([-8, 4, -3, -10, 1])
1662
+ data['A2'] = Zu([68, -204, 136])
1663
+ data['A4'] = Zuv(Zu([60, 720, -2595, 2250, -435]) + v*Zu([-360, 792, -432]))
1664
+ data['A6'] = Zuv(Zu([-8512, 22608, -5064, -57528, 87288, -43704, 4912] ) + v*Zu( [2520, -15372, 28098, -20160, 4914]))
1665
+ data['alpha'] = Zu([16000, -67200, 2720, 557600, -1392232, 1073992, 1104830, -3131026, 2450210, 73746, -1454945, 1110355, -424065, 95659, -13243, 1105, -51, 1])
1666
+ data['beta'] = Zu([0, 22400, -105920, 146208, 111616, -593800, 680948, -102282, -457950, 468035, -219274, 58549, -9374, 889, -46, 1])
1667
+ #beta factors as (u - 10) * (u - 5) * (u - 2) * (u - 1) * u * (u + 1) * (u**2 - 10*u + 7) * (u**2 - 6*u - 4) * (u**2 - 4*u + 2) * (u**3 - 9*u**2 + 8*u - 4)
1668
+ data['endo'] = 17*x**8 + 17*(-4*u + 4)*v*x**6 + 17*(4*u + 6)*v**2*x**4 + 17*(4*u + 4)*v**3*x**2 + (-4*u + 1)*v**4
1669
+ data['endo_u'] = 1
1670
+ return data
1671
+ if l == 19:
1672
+ data['hyper_poly'] = Zu([-8, 20, -8, -8, 1])
1673
+ data['A2'] = Zu([-114, 57, 171])
1674
+ data['A4'] = Zuv(Zu([-1020, 444, 2733, 726, -543]) + v*Zu([-180, -720, -540]))
1675
+ data['A6'] = Zuv(Zu([-10080, 21816, 54324, -37386, -86742, -20070, 6858]) + v*Zu([-2968, -13748, -11284, 6356, 6860]))
1676
+ data['alpha'] = Zu([16000, -22400, -337440, 475456, 1562104, -1988616, -3025294, 3245960, 2833014, -2420087, -1140950, 932406, 129580, -180443, 21090, 11153, -4066, 570, -38, 1])
1677
+ data['beta'] = Zu([0, 33600, -8160, -292400, 23472, 791244, 39282, -847909, -47024, 392654, -24046, -82469, 19162, 4833, -2652, 446, -34, 1])
1678
+ #beta factors as (u - 7) * (u - 2) * (u - 1) * u * (u + 1) * (u**2 - 8*u - 4) * (u**2 - 6*u - 15) * (u**2 - 5*u - 5) * (u**2 - 5*u + 2) * (u**2 - 2*u - 4) * (u**2 + u - 1)
1679
+ data['endo'] = 19*x**9 + 19*(-12*u - 24)*v*x**6 + 19*(-24*u - 24)*v**2*x**3 + (96*u - 224)*v**3
1680
+ data['endo_u'] = -1
1681
+ return data
1682
+ if l == 23:
1683
+ data['hyper_poly'] = Zu([-7, 10, -11, 2, 2, -8, 1])
1684
+ data['A2'] = Zu([69, -230, 253])
1685
+ data['A4'] = Zuv(Zu([405, 180, -930, 2820, -795]) + v*Zu([360, -792]))
1686
+ data['A6'] = Zuv(Zu([-15498, 34020, -36918, -8120, 51114, -72492, 12166]) + v*Zu([-1080, 7704, -24840, 12168]))
1687
+ data['alpha'] = Zu([-6750, 48600, -83835, -170775, 1115109, -2492280, 2732814, -116403, -4877702, 8362616, -6612454, 302266, 5423124, -6447728, 3209696, 336674, -1470068, 953856, -336927, 74221, -10465, 920, -46, 1])
1688
+ data['beta'] = Zu( [0, 12150, -72495, 168588, -144045, -254034, 930982, -1256170, 604358, 693650, -1563176, 1271974, -225188, -444070, 421050, -184350, 47754, -7696, 759, -42, 1])
1689
+ #beta factors as (u - 5) * (u - 3) * (u - 2) * (u - 1) * u * (u + 1) * (u**2 - 8*u + 3) * (u**2 - 6*u - 9) * (u**3 - 7*u**2 + 3*u - 5) * (u**3 - 7*u**2 + 7*u - 3) * (u**4 - 4*u**3 - 1)
1690
+ return data
1691
+ if l == 29:
1692
+ data['hyper_poly'] = Zu([-7, 8, 8, 2, -12, -4, 1])
1693
+ data['A2'] = Zu([-174, -232, 348, 406])
1694
+ data['A4'] = Zuv(Zu([-1215, -3096, 132, 7614, 6504, -360, -1263] ) + v*Zu( [180, -720, -2160, -1260]))
1695
+ data['A6'] = Zuv(Zu([-18900, -63504, 24696, 285068, 285264, -185136, -506268, -275520, 504, 24388] ) + v*Zu( [4482, -2448, -59868, -94968, -18144, 48276, 24390]))
1696
+ data['alpha'] = Zu([-6750, -12150, 281880, 570024, -1754181, -5229135, 2357613, 19103721, 9708910, -31795426, -38397537, 19207947, 54103270, 9216142, -37142939, -18871083, 14041394, 10954634, -3592085, -3427365, 853818, 622398, -189399, -53679, 26680, -580, -1421, 319, -29, 1])
1697
+ data['beta'] = Zu([0, -24300, -57510, 257850, 839187, -373185, -3602119, -2371192, 5865017, 8434433, -2363779, -10263744, -2746015, 5976011, 3151075, -2093854, -1356433, 569525, 299477, -129484, -28279, 19043, -895, -1076, 273, -27, 1])
1698
+ #beta factors as (u - 3) * (u - 1) * u * (u + 1) * (u + 2) * (u**2 - 6*u + 2) * (u**2 - 5*u - 5) * (u**2 - 5*u + 3) * (u**2 - 3*u - 9) * (u**2 - u - 3) * (u**2 - u - 1) * (u**2 + u - 1) * (u**3 - 4*u**2 - 6*u - 5) * (u**4 - 2*u**3 - 5*u**2 - 4*u - 1)
1699
+ data['endo'] = 29*x**14 + 29*(-14*u + 3)*v*x**12 + 29*(-20*u + 73)*v**2*x**10 + 29*(-58*u + 115)*v**3*x**8 + 29*(-56*u + 59)*v**4*x**6 + 29*(30*u + 1)*v**5*x**4 + 29*(12*u - 5)*v**6*x**2 + (2*u + 5)*v**7
1700
+ data['endo_u'] = -1
1701
+ return data
1702
+ if l == 31:
1703
+ data['hyper_poly'] = Zu([-3, -14, -11, 18, 6, -8, 1])
1704
+ data['A2'] = Zu([558, 837, -1488, 465])
1705
+ data['A4'] = Zuv(Zu([-4140, -12468, 15189, 16956, -27054, 11184, -1443]) + v*Zu([2160, -7560, 6120, -1440]))
1706
+ data['A6'] = Zuv(Zu([71280, 592056, -108324, -2609730, 2373048, 1282266, -2793204, 1530882, -356976, 29790]) + v*Zu([-81312, 181664, 294728, -868392, 701400, -238840, 29792]))
1707
+ data['alpha'] = Zu([108000, 475200, -7053120, -27353408, 90884374, 303670296, -665806437, -1361301729, 3259359840, 2249261823, -9368721606, 2279583264, 13054272515, -12759480061, -4169029296, 14390047139, -7803693550, -2988803682, 6239473912, -3296588360, 134066754, 908915598, -685615437, 294482733, -87483178, 18983315, -3052818, 361336, -30659, 1767, -62, 1])
1708
+ data['beta'] = Zu([0, 712800, 1216080, -18430560, -15262464, 168899202, -12931221, -720077416, 624871714, 1239052988, -2259335558, 68648452, 2679085427, -2318039014, -229246628, 1710545918, -1243026758, 211524870, 296674626, -291810274, 145889932, -48916468, 11793961, -2085662, 269348, -24778, 1540, -58, 1])
1709
+ #beta factors as (u - 3) * (u - 2) * (u - 1) * u * (u + 1) * (u**2 - 8*u + 11) * (u**2 - 7*u + 2) * (u**2 - 5*u - 2) * (u**2 - 5*u + 5) * (u**2 - 4*u - 4) * (u**2 - 4*u - 1) * (u**2 - 2*u - 1) * (u**2 - u - 1) * (u**3 - 9*u**2 + 21*u - 15) * (u**4 - 8*u**3 + 8*u**2 + 12*u - 9)
1710
+ data['endo'] = 31*x**15 + 31*(-66*u + 86)*v*x**12 + 31*(168*u + 280)*v**2*x**9 + 31*(576*u + 1792)*v**3*x**6 + 31*(384*u + 896)*v**4*x**3 + (-3072*u - 2048)*v**5
1711
+ data['endo_u'] = 2
1712
+ return data
1713
+ if l == 41:
1714
+ data['hyper_poly'] = Zu([-8, -20, -15, 8, 20, 10, -8, -4, 1])
1715
+ data['A2'] = Zu([328, 656, -656, -1148, 820])
1716
+ data['A4'] = Zuv(Zu([-1380, -4008, 1701, 10872, 6144, -18378, -2160, 9732, -2523]) + v*Zu([720, -1440, -2160, 5400, -2520]))
1717
+ data['A6'] = Zuv(Zu([4480, 155616, 16080, -550720, -343968, 832680, 938632, -621648, -1468608, 953920, 427632, -413016, 68920]) + v*Zu([-14616, 6804, 96390, -2016, -324324, 184464, 260568, -276192, 68922]))
1718
+ data['alpha'] = Zu([16000, 67200, -465760, -2966432, -1742664, 20985112, 46140990, -31732934, -217030548, -147139488, 436080674, 745775322, -271341362, -1542677562, -605560447, 1832223375, 1772593672, -1270633050, -2400692229, 343522723, 2179745361, 282422801, -1503727029, -421357697, 879637411, 261059095, -462271351, -61715127, 193718727, -24135265, -49355103, 20512341, 3613289, -4706595, 1099661, 163057, -162483, 46617, -7544, 738, -41, 1])
1719
+ data['beta'] = Zu([0, 44800, 167040, -447040, -2734272, -1104272, 13488360, 21067652, -24681704, -83929974, -8986886, 169059382, 127641266, -196479899, -283039783, 124573790, 366614063, -12946368, -332987597, -58867672, 241909907, 60568430, -155045647, -17919564, 79114945, -12025938, -24060781, 11190142, 1979597, -2931764, 750233, 110144, -122263, 37484, -6439, 666, -39, 1])
1720
+ #beta factors as (u - 5) * (u - 2) * (u - 1) * u * (u + 1) * (u**2 - 5*u + 5) * (u**2 - 3*u - 7) * (u**2 - 2*u - 4) * (u**2 - 2*u - 1) * (u**2 - u - 1) * (u**2 - 2) * (u**2 + u - 1) * (u**3 - 3*u**2 - 5*u - 2) * (u**3 - 2*u**2 - 2*u - 1) * (u**4 - 6*u**3 + 5*u**2 + 2*u - 1) * (u**4 - 5*u**3 + u**2 + 4) * (u**4 - 4*u**3 + 2)
1721
+ data['endo'] = 41*x**20 + 41*(-12*u - 22)*v*x**18 + 41*(-252*u - 247)*v**2*x**16 + 41*(-176*u - 424)*v**3*x**14 + 41*(464*u - 254)*v**4*x**12 + 41*(1688*u - 868)*v**5*x**10 + 41*(1720*u - 1190)*v**6*x**8 + 41*(528*u - 232)*v**7*x**6 + 41*(16*u + 29)*v**8*x**4 + 41*(20*u + 10)*v**9*x**2 + (4*u + 5)*v**10
1722
+ data['endo_u'] = 1
1723
+ return data
1724
+ if l == 47:
1725
+ data['hyper_poly'] = Zu([-11, 28, -38, 30, -13, -16, 19, -24, 11, -6, 1])
1726
+ data['A2'] = Zu([376, -1504, 2209, -1598, 1081])
1727
+ data['A4'] = Zuv(Zu([2400, -4080, -1440, 18000, -26355, 34740, -22050, 12900, -3315]) + v*Zu([1152, -3384, 3672, -3312]))
1728
+ data['A6'] = Zuv(Zu([-119504, 606336, -1505280, 2109392, -1509360, -515808, 2920702, -4614012, 4334322, -3260312, 1571442, -622428, 103822]) + v*Zu([2016, 48384, -235872, 438984, -627480, 503496, -311976, 103824]))
1729
+ data['alpha'] = Zu([-65536, 688128, -2502656, -96256, 38598656, -187217920, 508021120, -845669120, 552981696, 1469334304, -5945275904, 11705275552, -14673798654, 9100068184, 8421580132, -34288012648, 56657584158, -60426283952, 36612252089, 9942017442, -60791892299, 93046207239, -92028642340, 59196883097, -10454018992, -33364599371, 57280402355, -57873890484, 41879296232, -20241250112, 2065827049, 8435506655, -11611941072, 10182603298, -7040645261, 4071881378, -2013138357, 856757031, -313468474, 97893151, -25770006, 5617769, -990431, 136864, -14194, 1034, -47, 1])
1730
+ data['beta'] = Zu([0, 114688, -1114112, 4854784, -11205632, 7426048, 42663936, -182555136, 394092544, -508851472, 213245648, 743315936, -2203729384, 3409478688, -3280008936, 1139839970, 2576264698, -6272528962, 8005203155, -6671665088, 2744569094, 1996771588, -5520074039, 6637395180, -5455622885, 3028415830, -601645255, -1012737914, 1632999370, -1525982346, 1093778952, -644352392, 319489974, -134176208, 47566499, -14083902, 3424200, -667810, 101271, -11438, 901, -44, 1])
1731
+ #beta factors as (u - 4) * (u - 2) * (u - 1) * u * (u + 1) * (u**2 - 5*u + 2) * (u**2 - 2*u - 1) * (u**3 - 5*u**2 + 5*u - 7) * (u**3 - 4*u**2 + 3*u - 4) * (u**3 - 4*u**2 + 3*u - 1) * (u**3 - 3*u**2 + 2*u - 4) * (u**3 - 2*u**2 + 2*u - 2) * (u**3 + u + 1) * (u**4 - 4*u**3 - 2*u**2 - 4) * (u**5 - 5*u**4 + 5*u**3 - 11*u**2 + 6*u - 4) * (u**6 - 4*u**5 + 2*u**4 - 4*u**3 - u**2 + 4*u - 2)
1732
+ return data
1733
+ if l == 59:
1734
+ data['hyper_poly'] = Zu([-8, -4, 20, -24, -3, 40, -62, 40, 3, -28, 22, -8, 1])
1735
+ data['A2'] = Zu([590, -1475, -295, 4130, -4425, 1711])
1736
+ data['A4'] = Zuv(Zu([-2460, 8844, -3843, -20718, 57153, -50418, -12600, 72762, -69339, 30978, -5223]) + v*Zu([900, 360, -7560, 10800, -5220]))
1737
+ data['A6'] = Zuv(Zu([25760, -373560, 568020, 1147870, -4634370, 5318070, 1631996, -14270202, 21535998, -14119408, -2820102, 14275410, -13535292, 6790074, -1847898, 205378]) + v*Zu([-23688, 27972, 183708, -696024, 721980, 453600, -1925028, 2039184, -1027404, 205380]))
1738
+ data['alpha'] = Zu([16000, -67200, -783520, 5573376, -5127336, -60792184, 241324042, -170978932, -1262437160, 4310971231, -3953349811, -10887235780, 41679530185, -51342089572, -33068562195, 230682514316, -372641172307, 121615007703, 682044179678, -1549365239197, 1373184591667, 614906882627, -3566756201696, 4920423266916, -2342393877496, -3589340274442, 8772457933356, -8488557160148, 1742977715620, 7131088674129, -11643540780203, 8512399456274, -315658868113, -6917286294515, 8713332734648, -5190227733987, -54249978263, 3397583328372, -3658171840037, 1987950394792, -179519591637, -748989116551, 800595050760, -459184355769, 134398080099, 28871590941, -64236756338, 46651654354, -23352309386, 9059054346, -2830320860, 721829600, -150487052, 25475079, -3452149, 365800, -29205, 1652, -59, 1])
1739
+ data['beta'] = Zu([0, -56000, 320800, 391440, -7693120, 21125500, 11515130, -204780145, 486681785, -102547033, -2147060784, 5552726794, -4419031758, -9431888681, 33728080307, -42367773552, -2994127157, 105330637610, -188172973931, 127559513693, 123083802224, -421097252069, 490425751691, -161944881372, -408669953969, 799965143719, -668167261718, 69589638764, 563644022562, -787681290965, 505670881115, 2900924856, -364669742737, 407962360532, -223582547975, 9985786664, 102435489491, -105519055992, 58212400117, -14331637533, -6742538722, 10205452686, -6853903214, 3244679736, -1188153136, 347102566, -81626216, 15409226, -2307408, 268126, -23322, 1429, -55, 1])
1740
+ #beta factors as (u - 2) * (u - 1) * u * (u + 1) * (u**2 - 4*u - 1) * (u**2 - 3*u - 5) * (u**2 - 3*u - 2) * (u**2 - 3*u + 1) * (u**2 - u - 1) * (u**3 - 6*u**2 + 10*u - 7) * (u**3 - 5*u**2 + 7*u - 5) * (u**3 - 3*u**2 + 2*u - 1) * (u**3 - u**2 + 1) * (u**4 - 5*u**3 + 4*u**2 - 1) * (u**4 - 4*u**3 + 3*u**2 + 2*u - 4) * (u**4 - 3*u**3 - u - 1) * (u**4 - u**3 + 2*u - 1) * (u**5 - 6*u**4 + 10*u**3 - 11*u**2 + 8*u - 4) * (u**6 - 5*u**5 + 5*u**4 - 5*u**2 + 5*u - 5)
1741
+ return data
1742
+ if l == 71:
1743
+ data['hyper_poly'] = Zu([-7, 6, -27, 40, -58, 66, -66, 40, 15, -48, 66, -66, 37, -10, 1])
1744
+ data['A2'] = Zu([213, -1420, 4260, -4970, 9940, -9088, 2485])
1745
+ data['A4'] = Zuv(Zu([2565, -10008, 18024, -26532, 23208, 7584, -104418, 189432, -251736, 275148, -182232, 60144, -7563]) + v*Zu([720, -4320, 7560, -20160, 23040, -7560]))
1746
+ data['A6'] = Zuv(Zu([-69930, 382536, -1898568, 5206124, -11813256, 23115792, -35705670, 44318064, -41531952, 20674360, 23881872, -77986944, 114989770, -124612152, 103122936, -59431204, 21485688, -4294416, 357910]) + v*Zu([18576, -53856, 57672, 161856, -961920, 3199176, -5706288, 8032896, -9352584, 6786720, -2505888, 357912]))
1747
+ data['alpha'] = Zu([-6750, 97200, -603855, 2263977, -4854483, -2486349, 75190491, -399596520, 1441975423, -4089818964, 9450153463, -17516526653, 23635982289, -11859874932, -53385529273, 230566737711, -585283867605, 1136695427037, -1753961304140, 2020891913264, -1147488305875, -1930304898882, 8102336330029, -17218530732347, 27006964902986, -32365758791872, 25902000374138, -468390635342, -46332664858222, 107139839089502, -162234735929274, 182582147217312, -140033523896938, 22513210292184, 152367877270246, -334009986053250, 451855980915164, -443144048889720, 284518400252142, -11142427766850, -289840331821002, 512373447321402, -576967281819172, 466024421705696, -230395084854230, -36287337331916, 241209603962570, -330646545417814, 304702155703516, -205131886553392, 87504290135653, 5131997859077, -54867900326127, 66216047255551, -54817285755105, 36239054778472, -20052219750661, 9464634765852, -3841191816845, 1343947848527, -405138280373, 104923131180, -23228729413, 4364552115, -689157169, 90223321, -9613968, 812240, -52327, 2414, -71, 1])
1748
+ data['beta'] = Zu([0, 12150, -163215, 1115640, -5311143, 18820224, -50700172, 99823812, -102454041, -183909134, 1354660714, -4462311942, 10695310224, -20015395554, 28262441676, -23240987282, -17879387475, 124501604946, -315187724212, 564766450688, -765154573538, 705985549104, -115433273216, -1206098873334, 3175185881748, -5228317292044, 6292310032120, -5077451367560, 719644756530, 6451571564682, -14460150103020, 19999710623352, -19681838601268, 11819712227412, 2180981559572, -17790742756618, 29025463386612, -31179247603548, 23207078145510, -8345354986332, -7468523752270, 18486966963350, -21719818051100, 17831212433536, -10100011266030, 2336962513536, 2906983627184, -4989755986066, 4711466210012, -3361479243242, 1952316811463, -948555371584, 389878900245, -136099552242, 40341734984, -10121407164, 2136756509, -376218102, 54551634, -6399080, 591884, -41538, 2078, -66, 1])
1749
+ #beta factors as (u - 3) * (u - 2) * (u - 1) * u * (u + 1) * (u**2 - 5*u + 5) * (u**2 - 3*u + 1) * (u**2 - 2*u - 1) * (u**2 - u - 1) * (u**3 - 5*u**2 + 5*u - 3) * (u**3 - 4*u**2 - 1) * (u**3 - 2*u**2 - 1) * (u**4 - 6*u**3 + 7*u**2 + 6*u - 9) * (u**4 - 5*u**3 + 4*u**2 + u + 3) * (u**4 - 5*u**3 + 6*u**2 - 3*u + 5) * (u**4 - 4*u**3 + u**2 - 4*u + 1) * (u**4 - 4*u**3 + 2*u**2 - u + 1) * (u**4 - 2*u**3 - 3*u**2 - 2*u - 1) * (u**4 - 2*u**3 + u - 1) * (u**6 - 5*u**5 + 8*u**4 - 7*u**3 + 6*u**2 - 3*u + 1) * (u**8 - 6*u**7 + 9*u**6 - 2*u**5 + 2*u**3 - 9*u**2 + 2*u - 1)
1750
+ return data
1751
+
1752
+
1753
+ @cached_function
1754
+ def Psi2(l):
1755
+ """
1756
+ Return the generic kernel polynomial for hyperelliptic `l`-isogenies.
1757
+
1758
+ INPUT:
1759
+
1760
+ - ``l`` -- either 11, 17, 19, 23, 29, 31, 41, 47, 59, or 71
1761
+
1762
+ OUTPUT: the generic `l`-kernel polynomial
1763
+
1764
+ EXAMPLES::
1765
+
1766
+ sage: from sage.schemes.elliptic_curves.isogeny_small_degree import Psi2
1767
+ sage: Psi2(11)
1768
+ x^5 - 55*x^4*u + 994*x^3*u^2 - 8774*x^2*u^3 + 41453*x*u^4 - 928945/11*u^5
1769
+ + 33*x^4 + 276*x^3*u - 7794*x^2*u^2 + 4452*x*u^3 + 1319331/11*u^4 + 216*x^3*v
1770
+ - 4536*x^2*u*v + 31752*x*u^2*v - 842616/11*u^3*v + 162*x^3 + 38718*x^2*u
1771
+ - 610578*x*u^2 + 33434694/11*u^3 - 4536*x^2*v + 73872*x*u*v - 2745576/11*u^2*v
1772
+ - 16470*x^2 + 580068*x*u - 67821354/11*u^2 - 185976*x*v + 14143896/11*u*v
1773
+ + 7533*x - 20437029/11*u - 12389112/11*v + 19964151/11
1774
+ sage: p = Psi2(71) # long time
1775
+ sage: (x,u,v) = p.variables() # long time
1776
+ sage: p.coefficient({x: 0, u: 210, v: 0}) # long time
1777
+ -2209380711722505179506258739515288584116147237393815266468076436521/71
1778
+ sage: p.coefficient({x: 0, u: 0, v: 0}) # long time
1779
+ -14790739586438315394567393301990769678157425619440464678252277649/71
1780
+
1781
+ TESTS::
1782
+
1783
+ sage: Psi2(13)
1784
+ Traceback (most recent call last):
1785
+ ...
1786
+ ValueError: 13 must be one of [11, 17, 19, 23, 29, 31, 41, 47, 59, 71].
1787
+ """
1788
+ data = _hyperelliptic_isogeny_data(l)
1789
+
1790
+ R = PolynomialRing(QQ, 'u')
1791
+ L = PolynomialRing(R, 'v')
1792
+ v = L.gen()
1793
+ K = R.extension(v*v - R(data['hyper_poly']), 'v')
1794
+ v = K.gen()
1795
+
1796
+ from sage.categories.homset import Hom
1797
+ h = Hom(K,K)(-v)
1798
+
1799
+ A = K(data['A4'])
1800
+ B = K(data['A6'])
1801
+ Abar = h(A)*l**2
1802
+ Bbar = -h(B)*l**3
1803
+ s1 = K(data['A2'])
1804
+
1805
+ d = (l-1)//2
1806
+ s = [K(1)]
1807
+ t = [d, s1, ((1-10*d)*A - Abar) * QQ((1,30))]
1808
+ t.append(((1-28*d)*B - 42*t[1]*A - Bbar) * QQ((1,70)))
1809
+ c = [0, 6*t[2] + 2*A*t[0], 10*t[3] + 6*A*t[1] + 4*B*t[0]]
1810
+ for n in range(2,d):
1811
+ k = sum(c[i]*c[n-i] for i in range(1,n))
1812
+ c.append((3*k-(2*n-1)*(n-1)*A*c[n-1]-(2*n-2)*(n-2)*B*c[n-2]) * QQ((1,(2*n+5)*(n-1))))
1813
+ for n in range(3,d):
1814
+ t.append((c[n]-(4*n-2)*A*t[n-1]-(4*n-4)*B*t[n-2]) * QQ((1,4*n+2)))
1815
+ for n in range(1,d+1):
1816
+ s.append(QQ((-1,n)) * sum((-1)**i*t[i]*s[n-i] for i in range(1,n+1)))
1817
+
1818
+ R = PolynomialRing(QQ, ('x', 'u', 'v'))
1819
+ x = R.gen(0)
1820
+ return sum((-1)**i * x**(d-i) * R(s[i].lift()) for i in range(0,d+1))
1821
+
1822
+
1823
+ def isogenies_prime_degree_genus_plus_0(E, l=None, minimal_models=True):
1824
+ """
1825
+ Return list of ``l`` -isogenies with domain ``E``.
1826
+
1827
+ INPUT:
1828
+
1829
+ - ``E`` -- an elliptic curve
1830
+
1831
+ - ``l`` -- either ``None`` or 11, 17, 19, 23, 29, 31, 41, 47, 59, or 71
1832
+
1833
+ - ``minimal_models`` -- boolean (default: ``True``); if ``True``, all
1834
+ curves computed will be minimal or semi-minimal models. Over
1835
+ fields of larger degree it can be expensive to compute these so
1836
+ set to ``False``.
1837
+
1838
+ OUTPUT:
1839
+
1840
+ (list) When ``l`` is None a list of all isogenies of degree 11, 17, 19, 23,
1841
+ 29, 31, 41, 47, 59, or 71, otherwise a list of isogenies of the given degree.
1842
+
1843
+ .. NOTE::
1844
+
1845
+ This function would normally be invoked indirectly via
1846
+ ``E.isogenies_prime_degree(l)``, which automatically calls the appropriate function.
1847
+
1848
+ ALGORITHM:
1849
+
1850
+ See [KT2013]_, Chapter 5.
1851
+
1852
+ EXAMPLES::
1853
+
1854
+ sage: from sage.schemes.elliptic_curves.isogeny_small_degree import isogenies_prime_degree_genus_plus_0
1855
+
1856
+ sage: E = EllipticCurve('121a1')
1857
+ sage: isogenies_prime_degree_genus_plus_0(E, 11)
1858
+ [Isogeny of degree 11
1859
+ from Elliptic Curve defined by y^2 + x*y + y = x^3 + x^2 - 30*x - 76
1860
+ over Rational Field
1861
+ to Elliptic Curve defined by y^2 + x*y + y = x^3 + x^2 - 305*x + 7888
1862
+ over Rational Field]
1863
+
1864
+ sage: E = EllipticCurve([1, 1, 0, -660, -7600])
1865
+ sage: isogenies_prime_degree_genus_plus_0(E, 17)
1866
+ [Isogeny of degree 17
1867
+ from Elliptic Curve defined by y^2 + x*y = x^3 + x^2 - 660*x - 7600
1868
+ over Rational Field
1869
+ to Elliptic Curve defined by y^2 + x*y = x^3 + x^2 - 878710*x + 316677750
1870
+ over Rational Field]
1871
+
1872
+ sage: E = EllipticCurve([0, 0, 1, -1862, -30956])
1873
+ sage: isogenies_prime_degree_genus_plus_0(E, 19)
1874
+ [Isogeny of degree 19
1875
+ from Elliptic Curve defined by y^2 + y = x^3 - 1862*x - 30956
1876
+ over Rational Field
1877
+ to Elliptic Curve defined by y^2 + y = x^3 - 672182*x + 212325489
1878
+ over Rational Field]
1879
+
1880
+ sage: # needs sage.rings.number_field
1881
+ sage: K = QuadraticField(-295,'a')
1882
+ sage: a = K.gen()
1883
+ sage: E = EllipticCurve_from_j(-484650135/16777216*a + 4549855725/16777216)
1884
+ sage: isogenies_prime_degree_genus_plus_0(E, 23)
1885
+ [Isogeny of degree 23
1886
+ from Elliptic Curve defined by
1887
+ y^2 = x^3 + (-14460494784192904095/140737488355328*a+270742665778826768325/140737488355328)*x
1888
+ + (37035998788154488846811217135/590295810358705651712*a-1447451882571839266752561148725/590295810358705651712)
1889
+ over Number Field in a with defining polynomial x^2 + 295
1890
+ with a = 17.17556403731767?*I
1891
+ to Elliptic Curve defined by
1892
+ y^2 = x^3 + (-5130542435555445498495/140737488355328*a+173233955029127361005925/140737488355328)*x
1893
+ + (-1104699335561165691575396879260545/590295810358705651712*a+3169785826904210171629535101419675/590295810358705651712)
1894
+ over Number Field in a with defining polynomial x^2 + 295
1895
+ with a = 17.17556403731767?*I]
1896
+
1897
+ sage: # needs sage.rings.number_field
1898
+ sage: K = QuadraticField(-199,'a')
1899
+ sage: a = K.gen()
1900
+ sage: E = EllipticCurve_from_j(94743000*a + 269989875)
1901
+ sage: isogenies_prime_degree_genus_plus_0(E, 29)
1902
+ [Isogeny of degree 29
1903
+ from Elliptic Curve defined by
1904
+ y^2 = x^3 + (-153477413215038000*a+5140130723072965125)*x
1905
+ + (297036215130547008455526000*a+2854277047164317800973582250)
1906
+ over Number Field in a with defining polynomial x^2 + 199
1907
+ with a = 14.106735979665884?*I
1908
+ to Elliptic Curve defined by
1909
+ y^2 = x^3 + (251336161378040805000*a-3071093219933084341875)*x
1910
+ + (-8411064283162168580187643221000*a+34804337770798389546017184785250)
1911
+ over Number Field in a with defining polynomial x^2 + 199
1912
+ with a = 14.106735979665884?*I]
1913
+
1914
+ sage: # needs sage.rings.number_field
1915
+ sage: K = QuadraticField(253,'a')
1916
+ sage: a = K.gen()
1917
+ sage: E = EllipticCurve_from_j(208438034112000*a - 3315409892960000)
1918
+ sage: isogenies_prime_degree_genus_plus_0(E, 31)
1919
+ [Isogeny of degree 31
1920
+ from Elliptic Curve defined by
1921
+ y^2 = x^3 + (4146345122185433034677956608000*a-65951656549965037259634800640000)*x
1922
+ + (-18329111516954473474583425393698245080252416000*a+291542366110383928366510368064204147260129280000)
1923
+ over Number Field in a with defining polynomial x^2 - 253
1924
+ with a = 15.905973720586867?
1925
+ to Elliptic Curve defined by
1926
+ y^2 = x^3 + (200339763852548615776123686912000*a-3186599019027216904280948275200000)*x
1927
+ + (7443671791411479629112717260182286294850207744000*a-118398847898864757209685951728838895495168655360000)
1928
+ over Number Field in a with defining polynomial x^2 - 253
1929
+ with a = 15.905973720586867?]
1930
+
1931
+ sage: E = EllipticCurve_from_j(GF(5)(1))
1932
+ sage: isogenies_prime_degree_genus_plus_0(E, 41)
1933
+ [Isogeny of degree 41
1934
+ from Elliptic Curve defined by y^2 = x^3 + x + 2 over Finite Field of size 5
1935
+ to Elliptic Curve defined by y^2 = x^3 + x + 3 over Finite Field of size 5,
1936
+ Isogeny of degree 41
1937
+ from Elliptic Curve defined by y^2 = x^3 + x + 2 over Finite Field of size 5
1938
+ to Elliptic Curve defined by y^2 = x^3 + x + 3 over Finite Field of size 5]
1939
+
1940
+ sage: # needs sage.rings.number_field
1941
+ sage: K = QuadraticField(5,'a')
1942
+ sage: a = K.gen()
1943
+ sage: E = EllipticCurve_from_j(184068066743177379840*a
1944
+ ....: - 411588709724712960000)
1945
+ sage: isogenies_prime_degree_genus_plus_0(E, 47) # long time
1946
+ [Isogeny of degree 47
1947
+ from Elliptic Curve defined by
1948
+ y^2 = x^3 + (454562028554080355857852049849975895490560*a-1016431595837124114668689286176511361024000)*x
1949
+ + (-249456798429896080881440540950393713303830363999480904280965120*a+557802358738710443451273320227578156598454035482869042774016000)
1950
+ over Number Field in a with defining polynomial x^2 - 5
1951
+ with a = 2.236067977499790?
1952
+ to Elliptic Curve defined by
1953
+ y^2 = x^3 + (39533118442361013730577638493616965245992960*a-88398740199669828340617478832005245173760000)*x
1954
+ + (214030321479466610282320528611562368963830105830555363061803253760*a-478586348074220699687616322532666163722004497458452316582576128000)
1955
+ over Number Field in a with defining polynomial x^2 - 5
1956
+ with a = 2.236067977499790?]
1957
+
1958
+ sage: K = QuadraticField(-66827,'a') # needs sage.rings.number_field
1959
+ sage: a = K.gen() # needs sage.rings.number_field
1960
+ sage: E = EllipticCurve_from_j(-98669236224000*a + 4401720074240000) # needs sage.rings.number_field
1961
+ sage: isogenies_prime_degree_genus_plus_0(E, 59) # long time (5s)
1962
+ [Isogeny of degree 59
1963
+ from Elliptic Curve defined by
1964
+ y^2 = x^3 + (2605886146782144762297974784000*a+1893681048912773634944634716160000)*x
1965
+ + (-116918454256410782232296183198067568744071168000*a+17012043538294664027185882358514011304812871680000)
1966
+ over Number Field in a with defining polynomial x^2 + 66827
1967
+ with a = 258.5091874576221?*I
1968
+ to Elliptic Curve defined by
1969
+ y^2 = x^3 + (-19387084027159786821400775098368000*a-4882059104868154225052787156713472000)*x
1970
+ + (-25659862010101415428713331477227179429538847260672000*a-2596038148441293485938798119003462972840818381946880000)
1971
+ over Number Field in a with defining polynomial x^2 + 66827
1972
+ with a = 258.5091874576221?*I]
1973
+
1974
+ sage: E = EllipticCurve_from_j(GF(13)(5))
1975
+ sage: isogenies_prime_degree_genus_plus_0(E, 71)
1976
+ [Isogeny of degree 71
1977
+ from Elliptic Curve defined by y^2 = x^3 + x + 4 over Finite Field of size 13
1978
+ to Elliptic Curve defined by y^2 = x^3 + 10*x + 7 over Finite Field of size 13,
1979
+ Isogeny of degree 71
1980
+ from Elliptic Curve defined by y^2 = x^3 + x + 4 over Finite Field of size 13
1981
+ to Elliptic Curve defined by y^2 = x^3 + 10*x + 7 over Finite Field of size 13]
1982
+
1983
+ sage: E = EllipticCurve(GF(13), [0,1,1,1,0])
1984
+ sage: isogenies_prime_degree_genus_plus_0(E)
1985
+ [Isogeny of degree 17
1986
+ from Elliptic Curve defined by y^2 + y = x^3 + x^2 + x over Finite Field of size 13
1987
+ to Elliptic Curve defined by y^2 + y = x^3 + x^2 + 10*x + 1 over Finite Field of size 13,
1988
+ Isogeny of degree 17
1989
+ from Elliptic Curve defined by y^2 + y = x^3 + x^2 + x over Finite Field of size 13
1990
+ to Elliptic Curve defined by y^2 + y = x^3 + x^2 + 12*x + 4 over Finite Field of size 13,
1991
+ Isogeny of degree 29
1992
+ from Elliptic Curve defined by y^2 + y = x^3 + x^2 + x over Finite Field of size 13
1993
+ to Elliptic Curve defined by y^2 + y = x^3 + x^2 + 12*x + 6 over Finite Field of size 13,
1994
+ Isogeny of degree 29
1995
+ from Elliptic Curve defined by y^2 + y = x^3 + x^2 + x over Finite Field of size 13
1996
+ to Elliptic Curve defined by y^2 + y = x^3 + x^2 + 5*x + 6 over Finite Field of size 13,
1997
+ Isogeny of degree 41
1998
+ from Elliptic Curve defined by y^2 + y = x^3 + x^2 + x over Finite Field of size 13
1999
+ to Elliptic Curve defined by y^2 + y = x^3 + x^2 + 12*x + 4 over Finite Field of size 13,
2000
+ Isogeny of degree 41
2001
+ from Elliptic Curve defined by y^2 + y = x^3 + x^2 + x over Finite Field of size 13
2002
+ to Elliptic Curve defined by y^2 + y = x^3 + x^2 + 5*x + 6 over Finite Field of size 13]
2003
+ """
2004
+ if l is None:
2005
+ return sum([isogenies_prime_degree_genus_plus_0(E, ell, minimal_models=minimal_models)
2006
+ for ell in hyperelliptic_primes],[])
2007
+
2008
+ if l not in hyperelliptic_primes:
2009
+ raise ValueError("%s must be one of %s." % (l, hyperelliptic_primes))
2010
+
2011
+ F = E.base_ring()
2012
+ j = E.j_invariant()
2013
+ if F.characteristic() in [2, 3, l]:
2014
+ raise NotImplementedError("11, 17, 19, 23, 29, 31, 41, 47, 59, and 71-isogenies are not yet implemented in characteristic 2 and 3, and when the characteristic is the same as the degree of the isogeny.")
2015
+
2016
+ if j == F(0):
2017
+ return isogenies_prime_degree_genus_plus_0_j0(E, l, minimal_models=minimal_models)
2018
+ if j == F(1728):
2019
+ return isogenies_prime_degree_genus_plus_0_j1728(E, l, minimal_models=minimal_models)
2020
+
2021
+ Fu = PolynomialRing(F,'u')
2022
+ u = Fu.gen()
2023
+ Fuv = PolynomialRing(F,['u','v'])
2024
+ Fxuv = PolynomialRing(F,['x','u','v'])
2025
+ X = u
2026
+ data = _hyperelliptic_isogeny_data(l)
2027
+ a = Fu(data['alpha'])
2028
+ b = Fu(data['beta'])
2029
+ f = Fu(data['hyper_poly'])
2030
+ P = a
2031
+ Q = Fu((a**2 - f*b**2)/Fu(4))
2032
+ u_list = (j**2-P*j+Q).roots(multiplicities=False)
2033
+
2034
+ S = []
2035
+ for u0 in u_list:
2036
+ if b(u0) == 0:
2037
+ S += [[u0,v0] for v0 in (X**2-f(u0)).roots(multiplicities=False)]
2038
+ else:
2039
+ S += [[u0,(2*j-a(u0))/b(u0)]]
2040
+ if not S:
2041
+ return []
2042
+ S.sort()
2043
+
2044
+ c4, c6 = E.c_invariants()
2045
+ b2 = E.b2()
2046
+ kernels = []
2047
+
2048
+ psi = Fxuv(Psi2(l))
2049
+ for u0, v0 in S:
2050
+ A4 = Fuv(data['A4'])(u0,v0) # nonzero since j!=0
2051
+ A6 = Fuv(data['A6'])(u0,v0) # nonzero since j!=1728
2052
+ T = (c4*A6)/(2*c6*A4)
2053
+ kernels += [psi((36*X+3*b2)*T,u0,v0).monic()]
2054
+ return [E.isogeny(ker) for ker in kernels]
2055
+
2056
+
2057
+ def isogenies_prime_degree_genus_plus_0_j0(E, l, minimal_models=True):
2058
+ """
2059
+ Return a list of hyperelliptic ``l`` -isogenies with domain ``E`` when `j(E)=0`.
2060
+
2061
+ INPUT:
2062
+
2063
+ - ``E`` -- an elliptic curve with j-invariant 0
2064
+
2065
+ - ``l`` -- 11, 17, 19, 23, 29, 31, 41, 47, 59, or 71
2066
+
2067
+ - ``minimal_models`` -- boolean (default: ``True``); if ``True``, all
2068
+ curves computed will be minimal or semi-minimal models. Over
2069
+ fields of larger degree it can be expensive to compute these so
2070
+ set to ``False``.
2071
+
2072
+ OUTPUT:
2073
+
2074
+ (list) a list of all isogenies of degree 11, 17, 19, 23, 29, 31, 41, 47, 59, or 71.
2075
+
2076
+ .. NOTE::
2077
+
2078
+ This implementation requires that the characteristic is not 2, 3 or ``l``.
2079
+
2080
+ .. NOTE::
2081
+
2082
+ This function would normally be invoked indirectly via ``E.isogenies_prime_degree(l)``.
2083
+
2084
+ EXAMPLES::
2085
+
2086
+ sage: from sage.schemes.elliptic_curves.isogeny_small_degree import isogenies_prime_degree_genus_plus_0_j0
2087
+
2088
+ sage: u = polygen(QQ)
2089
+ sage: K.<a> = NumberField(u^4 + 228*u^3 + 486*u^2 - 540*u + 225) # needs sage.rings.number_field
2090
+ sage: E = EllipticCurve(K, [0, -121/5*a^3 - 20691/5*a^2 - 29403/5*a + 3267]) # needs sage.rings.number_field
2091
+ sage: isogenies_prime_degree_genus_plus_0_j0(E, 11) # needs sage.rings.number_field
2092
+ [Isogeny of degree 11
2093
+ from Elliptic Curve defined by
2094
+ y^2 = x^3 + (-121/5*a^3-20691/5*a^2-29403/5*a+3267) over
2095
+ Number Field in a with defining polynomial x^4 + 228*x^3 + 486*x^2 - 540*x + 225
2096
+ to Elliptic Curve defined by
2097
+ y^2 = x^3 + (-44286*a^2+178596*a-32670)*x
2098
+ + (-17863351/5*a^3+125072739/5*a^2-74353653/5*a-682803) over
2099
+ Number Field in a with defining polynomial x^4 + 228*x^3 + 486*x^2 - 540*x + 225,
2100
+ Isogeny of degree 11
2101
+ from Elliptic Curve defined by
2102
+ y^2 = x^3 + (-121/5*a^3-20691/5*a^2-29403/5*a+3267) over
2103
+ Number Field in a with defining polynomial x^4 + 228*x^3 + 486*x^2 - 540*x + 225
2104
+ to Elliptic Curve defined by
2105
+ y^2 = x^3 + (-3267*a^3-740157*a^2+600039*a-277695)*x
2106
+ + (-17863351/5*a^3-4171554981/5*a^2+3769467867/5*a-272366523) over
2107
+ Number Field in a with defining polynomial x^4 + 228*x^3 + 486*x^2 - 540*x + 225]
2108
+
2109
+ sage: E = EllipticCurve(GF(5^6,'a'),[0,1])
2110
+ sage: isogenies_prime_degree_genus_plus_0_j0(E,17)
2111
+ [Isogeny of degree 17 from Elliptic Curve defined by y^2 = x^3 + 1 over Finite Field in a of size 5^6 to Elliptic Curve defined by y^2 = x^3 + 2 over Finite Field in a of size 5^6, Isogeny of degree 17 from Elliptic Curve defined by y^2 = x^3 + 1 over Finite Field in a of size 5^6 to Elliptic Curve defined by y^2 = x^3 + 2 over Finite Field in a of size 5^6, Isogeny of degree 17 from Elliptic Curve defined by y^2 = x^3 + 1 over Finite Field in a of size 5^6 to Elliptic Curve defined by y^2 = x^3 + 2 over Finite Field in a of size 5^6, Isogeny of degree 17 from Elliptic Curve defined by y^2 = x^3 + 1 over Finite Field in a of size 5^6 to Elliptic Curve defined by y^2 = x^3 + 2 over Finite Field in a of size 5^6, Isogeny of degree 17 from Elliptic Curve defined by y^2 = x^3 + 1 over Finite Field in a of size 5^6 to Elliptic Curve defined by y^2 = x^3 + 2 over Finite Field in a of size 5^6, Isogeny of degree 17 from Elliptic Curve defined by y^2 = x^3 + 1 over Finite Field in a of size 5^6 to Elliptic Curve defined by y^2 = x^3 + 2 over Finite Field in a of size 5^6, Isogeny of degree 17 from Elliptic Curve defined by y^2 = x^3 + 1 over Finite Field in a of size 5^6 to Elliptic Curve defined by y^2 = x^3 + 2 over Finite Field in a of size 5^6, Isogeny of degree 17 from Elliptic Curve defined by y^2 = x^3 + 1 over Finite Field in a of size 5^6 to Elliptic Curve defined by y^2 = x^3 + 2 over Finite Field in a of size 5^6, Isogeny of degree 17 from Elliptic Curve defined by y^2 = x^3 + 1 over Finite Field in a of size 5^6 to Elliptic Curve defined by y^2 = x^3 + 2 over Finite Field in a of size 5^6, Isogeny of degree 17 from Elliptic Curve defined by y^2 = x^3 + 1 over Finite Field in a of size 5^6 to Elliptic Curve defined by y^2 = x^3 + 2 over Finite Field in a of size 5^6, Isogeny of degree 17 from Elliptic Curve defined by y^2 = x^3 + 1 over Finite Field in a of size 5^6 to Elliptic Curve defined by y^2 = x^3 + 2 over Finite Field in a of size 5^6, Isogeny of degree 17 from Elliptic Curve defined by y^2 = x^3 + 1 over Finite Field in a of size 5^6 to Elliptic Curve defined by y^2 = x^3 + 2 over Finite Field in a of size 5^6, Isogeny of degree 17 from Elliptic Curve defined by y^2 = x^3 + 1 over Finite Field in a of size 5^6 to Elliptic Curve defined by y^2 = x^3 + 2 over Finite Field in a of size 5^6, Isogeny of degree 17 from Elliptic Curve defined by y^2 = x^3 + 1 over Finite Field in a of size 5^6 to Elliptic Curve defined by y^2 = x^3 + 2 over Finite Field in a of size 5^6, Isogeny of degree 17 from Elliptic Curve defined by y^2 = x^3 + 1 over Finite Field in a of size 5^6 to Elliptic Curve defined by y^2 = x^3 + 2 over Finite Field in a of size 5^6, Isogeny of degree 17 from Elliptic Curve defined by y^2 = x^3 + 1 over Finite Field in a of size 5^6 to Elliptic Curve defined by y^2 = x^3 + 2 over Finite Field in a of size 5^6, Isogeny of degree 17 from Elliptic Curve defined by y^2 = x^3 + 1 over Finite Field in a of size 5^6 to Elliptic Curve defined by y^2 = x^3 + 2 over Finite Field in a of size 5^6, Isogeny of degree 17 from Elliptic Curve defined by y^2 = x^3 + 1 over Finite Field in a of size 5^6 to Elliptic Curve defined by y^2 = x^3 + 2 over Finite Field in a of size 5^6]
2112
+ """
2113
+ if l not in hyperelliptic_primes:
2114
+ raise ValueError("%s must be one of %s." % (l,hyperelliptic_primes))
2115
+ F = E.base_field()
2116
+ if E.j_invariant() != 0:
2117
+ raise ValueError("j-invariant must be 0.")
2118
+ if F.characteristic() in [2,3,l]:
2119
+ raise NotImplementedError("Not implemented in characteristic 2, 3 or l.")
2120
+
2121
+ Fu = PolynomialRing(F,'u')
2122
+ u = Fu.gen()
2123
+ Fuv = PolynomialRing(F,['u','v'])
2124
+ Fxuv = PolynomialRing(F,['x','u','v'])
2125
+ X = u
2126
+ data = _hyperelliptic_isogeny_data(l)
2127
+ a = Fu(data['alpha'])
2128
+ b = Fu(data['beta'])
2129
+ f = Fu(data['hyper_poly'])
2130
+ Q = Fu((a**2 - f*b**2)/Fu(4))
2131
+ u_list = Q.roots(multiplicities=False)
2132
+ c6, b2 = E.c6(), E.b2()
2133
+ kernels = []
2134
+
2135
+ if l % 3 == 1 and F(-3).is_square():
2136
+ p = F(-3).sqrt()
2137
+ endo = Fxuv(data['endo'])
2138
+ kernels += [endo(36*X+3*b2,p,-54*c6).monic(), endo(36*X+3*b2,-p,-54*c6).monic()]
2139
+
2140
+ S = []
2141
+ for u0 in u_list:
2142
+ if l % 3 == 1 and u0 == F(data['endo_u']):
2143
+ continue
2144
+ if b(u0) == 0:
2145
+ S += [[u0,v0] for v0 in (X**2-f(u0)).roots(multiplicities=False)]
2146
+ else:
2147
+ S += [[u0,-a(u0)/b(u0)]]
2148
+ if not S and not kernels:
2149
+ return []
2150
+ S.sort()
2151
+
2152
+ psi = Fxuv(Psi2(l))
2153
+ for u0,v0 in S:
2154
+ A6 = Fuv(data['A6'])(u0,v0) # nonzero since j!=1728
2155
+ kernels += [psi((36*X+3*b2)*T,u0,v0).monic() for T in (X**3-A6/(-54*c6)).roots(multiplicities=False)]
2156
+ return [E.isogeny(ker) for ker in kernels]
2157
+
2158
+
2159
+ def isogenies_prime_degree_genus_plus_0_j1728(E, l, minimal_models=True):
2160
+ """
2161
+ Return a list of ``l`` -isogenies with domain ``E`` when `j(E)=1728`.
2162
+
2163
+ INPUT:
2164
+
2165
+ - ``E`` -- an elliptic curve with j-invariant 1728
2166
+
2167
+ - ``l`` -- 11, 17, 19, 23, 29, 31, 41, 47, 59, or 71
2168
+
2169
+ - ``minimal_models`` -- boolean (default: ``True``); if ``True``, all
2170
+ curves computed will be minimal or semi-minimal models. Over
2171
+ fields of larger degree it can be expensive to compute these so
2172
+ set to ``False``.
2173
+
2174
+ OUTPUT:
2175
+
2176
+ (list) a list of all isogenies of degree 11, 17, 19, 23, 29, 31, 41, 47, 59, or 71.
2177
+
2178
+ .. NOTE::
2179
+
2180
+ This implementation requires that the characteristic is not 2, 3 or ``l``.
2181
+
2182
+ .. NOTE::
2183
+
2184
+ This function would normally be invoked indirectly via ``E.isogenies_prime_degree(l)``.
2185
+
2186
+ EXAMPLES::
2187
+
2188
+ sage: from sage.schemes.elliptic_curves.isogeny_small_degree import isogenies_prime_degree_genus_plus_0_j1728
2189
+
2190
+ sage: # needs sage.rings.number_field
2191
+ sage: u = polygen(QQ)
2192
+ sage: K.<a> = NumberField(u^6 - 522*u^5 - 10017*u^4
2193
+ ....: + 2484*u^3 - 5265*u^2 + 12150*u - 5103)
2194
+ sage: E = EllipticCurve(K, [-75295/1335852*a^5 + 13066735/445284*a^4
2195
+ ....: + 44903485/74214*a^3 + 17086861/24738*a^2
2196
+ ....: + 11373021/16492*a - 1246245/2356, 0])
2197
+ sage: isogenies_prime_degree_genus_plus_0_j1728(E, 11)
2198
+ [Isogeny of degree 11
2199
+ from Elliptic Curve defined by
2200
+ y^2 = x^3 + (-75295/1335852*a^5+13066735/445284*a^4+44903485/74214*a^3+17086861/24738*a^2+11373021/16492*a-1246245/2356)*x
2201
+ over Number Field in a with defining polynomial
2202
+ x^6 - 522*x^5 - 10017*x^4 + 2484*x^3 - 5265*x^2 + 12150*x - 5103
2203
+ to Elliptic Curve defined by
2204
+ y^2 = x^3 + (9110695/1335852*a^5-1581074935/445284*a^4-5433321685/74214*a^3-3163057249/24738*a^2+1569269691/16492*a+73825125/2356)*x
2205
+ + (-3540460*a^3+30522492*a^2-7043652*a-5031180)
2206
+ over Number Field in a with defining polynomial
2207
+ x^6 - 522*x^5 - 10017*x^4 + 2484*x^3 - 5265*x^2 + 12150*x - 5103,
2208
+ Isogeny of degree 11
2209
+ from Elliptic Curve defined by
2210
+ y^2 = x^3 + (-75295/1335852*a^5+13066735/445284*a^4+44903485/74214*a^3+17086861/24738*a^2+11373021/16492*a-1246245/2356)*x
2211
+ over Number Field in a with defining polynomial
2212
+ x^6 - 522*x^5 - 10017*x^4 + 2484*x^3 - 5265*x^2 + 12150*x - 5103
2213
+ to Elliptic Curve defined by
2214
+ y^2 = x^3 + (9110695/1335852*a^5-1581074935/445284*a^4-5433321685/74214*a^3-3163057249/24738*a^2+1569269691/16492*a+73825125/2356)*x
2215
+ + (3540460*a^3-30522492*a^2+7043652*a+5031180)
2216
+ over Number Field in a with defining polynomial
2217
+ x^6 - 522*x^5 - 10017*x^4 + 2484*x^3 - 5265*x^2 + 12150*x - 5103]
2218
+ sage: i = QuadraticField(-1,'i').gen()
2219
+ sage: E = EllipticCurve([-1 - 2*i, 0])
2220
+ sage: isogenies_prime_degree_genus_plus_0_j1728(E, 17)
2221
+ [Isogeny of degree 17
2222
+ from Elliptic Curve defined by y^2 = x^3 + (-2*i-1)*x
2223
+ over Number Field in i with defining polynomial x^2 + 1 with i = 1*I
2224
+ to Elliptic Curve defined by y^2 = x^3 + (-82*i-641)*x
2225
+ over Number Field in i with defining polynomial x^2 + 1 with i = 1*I,
2226
+ Isogeny of degree 17
2227
+ from Elliptic Curve defined by y^2 = x^3 + (-2*i-1)*x
2228
+ over Number Field in i with defining polynomial x^2 + 1 with i = 1*I
2229
+ to Elliptic Curve defined by y^2 = x^3 + (-562*i+319)*x
2230
+ over Number Field in i with defining polynomial x^2 + 1 with i = 1*I]
2231
+ sage: Emin = E.global_minimal_model()
2232
+ sage: [(p, len(isogenies_prime_degree_genus_plus_0_j1728(Emin, p)))
2233
+ ....: for p in [17, 29, 41]]
2234
+ [(17, 2), (29, 2), (41, 2)]
2235
+ """
2236
+ if l not in hyperelliptic_primes:
2237
+ raise ValueError("%s must be one of %s." % (l,hyperelliptic_primes))
2238
+ F = E.base_ring()
2239
+ if E.j_invariant() != 1728:
2240
+ raise ValueError("j-invariant must be 1728.")
2241
+ if F.characteristic() in [2,3,l]:
2242
+ raise NotImplementedError("Not implemented in characteristic 2, 3 or l.")
2243
+
2244
+ Fu = PolynomialRing(F,'u')
2245
+ u = Fu.gen()
2246
+ Fuv = PolynomialRing(F,['u','v'])
2247
+ Fxuv = PolynomialRing(F,['x','u','v'])
2248
+ X = u
2249
+ data = _hyperelliptic_isogeny_data(l)
2250
+ a = Fu(data['alpha'])
2251
+ b = Fu(data['beta'])
2252
+ f = Fu(data['hyper_poly'])
2253
+ P = a
2254
+ Q = Fu((a**2 - f*b**2)/Fu(4))
2255
+ u_list = (1728**2-P*1728+Q).roots(multiplicities=False)
2256
+ c4, b2 = E.c4(), E.b2()
2257
+ kernels = []
2258
+
2259
+ if l % 4 == 1 and F(-1).is_square():
2260
+ i = F(-1).sqrt()
2261
+ endo = Fxuv(data['endo'])
2262
+ kernels += [endo(36*X+3*b2,i,-27*c4).monic(), endo(36*X+3*b2,-i,-27*c4).monic()]
2263
+
2264
+ S = []
2265
+ for u0 in u_list:
2266
+ if l % 4 == 1 and u0 == F(data['endo_u']):
2267
+ continue
2268
+ if b(u0) == 0:
2269
+ S += [[u0,v0] for v0 in (X**2-f(u0)).roots(multiplicities=False)]
2270
+ else:
2271
+ S += [[u0,(2*1728-a(u0))/b(u0)]]
2272
+ if not S and not kernels:
2273
+ return []
2274
+ S.sort()
2275
+
2276
+ psi = Fxuv(Psi2(l))
2277
+ for u0,v0 in S:
2278
+ A4 = Fuv(data['A4'])(u0,v0) # nonzero since j!=0
2279
+ kernels += [psi((36*X+3*b2)*T,u0,v0).monic() for T in (X**2-A4/(-27*c4)).roots(multiplicities=False)]
2280
+ return [E.isogeny(ker) for ker in kernels]
2281
+
2282
+
2283
+ @cached_function
2284
+ def _least_semi_primitive(p):
2285
+ r"""
2286
+ Return the smallest semi-primitive root modulo `p`, i.e., generator of the group `(\ZZ/p\ZZ)^*/\{1,-1\}`.
2287
+
2288
+ INPUT:
2289
+
2290
+ - ``p`` -- an odd prime power
2291
+
2292
+ OUTPUT: the smallest semi-primitive root modulo `p`
2293
+
2294
+ .. NOTE::
2295
+
2296
+ This function would normally be invoked indirectly via ``E.isogenies_prime_degree_general(l)``.
2297
+
2298
+ EXAMPLES::
2299
+
2300
+ sage: from sage.schemes.elliptic_curves.isogeny_small_degree import _least_semi_primitive
2301
+ sage: _least_semi_primitive(5)
2302
+ 2
2303
+ sage: _least_semi_primitive(13)
2304
+ 2
2305
+ sage: _least_semi_primitive(17)
2306
+ 3
2307
+ sage: _least_semi_primitive(73)
2308
+ 5
2309
+ sage: _least_semi_primitive(997)
2310
+ 7
2311
+ """
2312
+ if p % 2 == 0 or not p.is_prime_power():
2313
+ raise ValueError("{} is not an odd prime power".format(p))
2314
+
2315
+ from sage.arith.misc import euler_phi
2316
+ from sage.rings.finite_rings.integer_mod_ring import Integers
2317
+ phip = euler_phi(p)
2318
+ ord = phip if p % 4 == 1 else phip // 2
2319
+ R = Integers(p)
2320
+ return next((a for a in range(2, p) if p.gcd(a) == 1
2321
+ and R(a).multiplicative_order() >= ord), 0)
2322
+
2323
+
2324
+ def is_kernel_polynomial(E, m, f):
2325
+ r"""
2326
+ Test whether ``E`` has a cyclic isogeny of degree ``m`` with kernel
2327
+ polynomial ``f``.
2328
+
2329
+ INPUT:
2330
+
2331
+ - ``E`` -- an elliptic curve
2332
+
2333
+ - ``m`` -- positive integer
2334
+
2335
+ - ``f`` -- a polynomial over the base field of ``E``
2336
+
2337
+ OUTPUT:
2338
+
2339
+ boolean; ``True`` if ``E`` has a cyclic isogeny of degree ``m`` with
2340
+ kernel polynomial ``f``, else ``False``.
2341
+
2342
+ ALGORITHM:
2343
+
2344
+ `f` must have degree `(m-1)/2` (if `m` is odd) or degree `m/2` (if
2345
+ `m` is even), and have the property that for each root `x` of `f`,
2346
+ `\mu(x)` is also a root where `\mu` is the multiplication-by-`m`
2347
+ map on `E` and `m` runs over a set of generators of
2348
+ `(\ZZ/m\ZZ)^*/\{1,-1\}`.
2349
+
2350
+ EXAMPLES::
2351
+
2352
+ sage: from sage.schemes.elliptic_curves.isogeny_small_degree import is_kernel_polynomial
2353
+ sage: E = EllipticCurve([0, -1, 1, -10, -20])
2354
+ sage: x = polygen(QQ)
2355
+ sage: is_kernel_polynomial(E, 5, x^2 + x - 29/5)
2356
+ True
2357
+ sage: is_kernel_polynomial(E, 5, (x - 16) * (x - 5))
2358
+ True
2359
+
2360
+ An example from [KT2013]_, where the 13-division polynomial splits
2361
+ into 14 factors each of degree 6, but only two of these is a
2362
+ kernel polynomial for a 13-isogeny::
2363
+
2364
+ sage: F = GF(3)
2365
+ sage: E = EllipticCurve(F, [0,0,0,-1,0])
2366
+ sage: f13 = E.division_polynomial(13)
2367
+ sage: factors = [f for f, e in f13.factor()]
2368
+ sage: all(f.degree() == 6 for f in factors)
2369
+ True
2370
+ sage: [is_kernel_polynomial(E, 13, f) for f in factors]
2371
+ [True,
2372
+ True,
2373
+ False,
2374
+ False,
2375
+ False,
2376
+ False,
2377
+ False,
2378
+ False,
2379
+ False,
2380
+ False,
2381
+ False,
2382
+ False,
2383
+ False,
2384
+ False]
2385
+
2386
+ See :issue:`22232`::
2387
+
2388
+ sage: # needs sage.rings.finite_rings
2389
+ sage: K = GF(47^2)
2390
+ sage: E = EllipticCurve([0, K.gen()])
2391
+ sage: psi7 = E.division_polynomial(7)
2392
+ sage: f = psi7.factor()[4][0]
2393
+ sage: f
2394
+ x^3 + (7*z2 + 11)*x^2 + (25*z2 + 33)*x + 25*z2
2395
+ sage: f.divides(psi7)
2396
+ True
2397
+ sage: is_kernel_polynomial(E, 7, f)
2398
+ False
2399
+ """
2400
+ m2 = m // 2
2401
+ if f.degree() != m2:
2402
+ return False
2403
+ if m == 1:
2404
+ return True
2405
+
2406
+ # Compute the quotient polynomial ring mod (f)
2407
+ S = f.parent().quotient_ring(f)
2408
+
2409
+ # test if the m-division polynomial is a multiple of f by computing it in the quotient:
2410
+ if E.division_polynomial(m, x=S.gen()) != 0:
2411
+ return False
2412
+
2413
+ if m == 2 or m == 3:
2414
+ return True
2415
+
2416
+ # For each a in a set of generators of (Z/mZ)^*/{1,-1} we check
2417
+ # that the multiplication-by-a map permutes the roots of f.
2418
+ # If m is prime (or more generally, has a primitive root) then
2419
+ # only one a will be needed.
2420
+
2421
+ if m & 1 and m.is_prime_power():
2422
+ gens = _least_semi_primitive(m),
2423
+ else:
2424
+ from sage.rings.finite_rings.integer_mod_ring import Integers
2425
+ gens = Integers(m).unit_gens()
2426
+
2427
+ for a in gens:
2428
+ mu = E.multiplication_by_m(a, x_only=True)
2429
+ if f( S(mu.numerator()) / S(mu.denominator()) ) != 0:
2430
+ return False
2431
+ return True
2432
+
2433
+
2434
+ def isogenies_prime_degree_general(E, l, minimal_models=True):
2435
+ """
2436
+ Return all separable ``l``-isogenies with domain ``E``.
2437
+
2438
+ INPUT:
2439
+
2440
+ - ``E`` -- an elliptic curve
2441
+
2442
+ - ``l`` -- a prime
2443
+
2444
+ - ``minimal_models`` -- boolean (default: ``True``); if ``True``, all
2445
+ curves computed will be minimal or semi-minimal models. Over
2446
+ fields of larger degree it can be expensive to compute these so
2447
+ set to ``False``.
2448
+
2449
+ OUTPUT:
2450
+
2451
+ A list of all separable isogenies of degree `l` with domain ``E``
2452
+ (up to post-isomorphism).
2453
+
2454
+ ALGORITHM:
2455
+
2456
+ This algorithm factors the ``l``-division polynomial, then
2457
+ combines its factors to obtain kernels.
2458
+ Originally this was done using [KT2013]_, Chapter 3, but nowadays
2459
+ the recombination step is instead delegated to
2460
+ :meth:`~sage.schemes.elliptic_curves.ell_field.EllipticCurve_field.kernel_polynomial_from_divisor`.
2461
+
2462
+ .. NOTE::
2463
+
2464
+ This function works for any prime `l`. Normally one should use
2465
+ the function :meth:`isogenies_prime_degree` which uses special
2466
+ functions for certain small primes.
2467
+
2468
+ EXAMPLES::
2469
+
2470
+ sage: from sage.schemes.elliptic_curves.isogeny_small_degree import isogenies_prime_degree_general
2471
+ sage: E = EllipticCurve_from_j(GF(2^6,'a')(1)) # needs sage.rings.finite_rings
2472
+ sage: isogenies_prime_degree_general(E, 7) # needs sage.rings.finite_rings
2473
+ [Isogeny of degree 7
2474
+ from Elliptic Curve defined by y^2 + x*y = x^3 + 1
2475
+ over Finite Field in a of size 2^6
2476
+ to Elliptic Curve defined by y^2 + x*y = x^3 + x
2477
+ over Finite Field in a of size 2^6]
2478
+ sage: E = EllipticCurve_from_j(GF(3^12,'a')(2)) # needs sage.rings.finite_rings
2479
+ sage: isogenies_prime_degree_general(E, 17) # needs sage.rings.finite_rings
2480
+ [Isogeny of degree 17
2481
+ from Elliptic Curve defined by y^2 = x^3 + 2*x^2 + 2
2482
+ over Finite Field in a of size 3^12
2483
+ to Elliptic Curve defined by y^2 = x^3 + 2*x^2 + x + 2
2484
+ over Finite Field in a of size 3^12,
2485
+ Isogeny of degree 17
2486
+ from Elliptic Curve defined by y^2 = x^3 + 2*x^2 + 2
2487
+ over Finite Field in a of size 3^12
2488
+ to Elliptic Curve defined by y^2 = x^3 + 2*x^2 + 2*x
2489
+ over Finite Field in a of size 3^12]
2490
+ sage: E = EllipticCurve('50a1')
2491
+ sage: isogenies_prime_degree_general(E, 3)
2492
+ [Isogeny of degree 3
2493
+ from Elliptic Curve defined by y^2 + x*y + y = x^3 - x - 2 over Rational Field
2494
+ to Elliptic Curve defined by y^2 + x*y + y = x^3 - 126*x - 552
2495
+ over Rational Field]
2496
+ sage: isogenies_prime_degree_general(E, 5)
2497
+ [Isogeny of degree 5
2498
+ from Elliptic Curve defined by y^2 + x*y + y = x^3 - x - 2 over Rational Field
2499
+ to Elliptic Curve defined by y^2 + x*y + y = x^3 - 76*x + 298
2500
+ over Rational Field]
2501
+ sage: E = EllipticCurve([0, 0, 1, -1862, -30956])
2502
+ sage: isogenies_prime_degree_general(E, 19)
2503
+ [Isogeny of degree 19
2504
+ from Elliptic Curve defined by y^2 + y = x^3 - 1862*x - 30956
2505
+ over Rational Field
2506
+ to Elliptic Curve defined by y^2 + y = x^3 - 672182*x + 212325489
2507
+ over Rational Field]
2508
+ sage: E = EllipticCurve([0, -1, 0, -6288, 211072])
2509
+ sage: isogenies_prime_degree_general(E, 37) # long time (2s)
2510
+ [Isogeny of degree 37
2511
+ from Elliptic Curve defined by y^2 = x^3 - x^2 - 6288*x + 211072
2512
+ over Rational Field
2513
+ to Elliptic Curve defined by y^2 = x^3 - x^2 - 163137088*x - 801950801728
2514
+ over Rational Field]
2515
+
2516
+ sage: E = EllipticCurve([-3440, 77658])
2517
+ sage: isogenies_prime_degree_general(E, 43) # long time (2s)
2518
+ [Isogeny of degree 43
2519
+ from Elliptic Curve defined by y^2 = x^3 - 3440*x + 77658 over Rational Field
2520
+ to Elliptic Curve defined by y^2 = x^3 - 6360560*x - 6174354606
2521
+ over Rational Field]
2522
+
2523
+ Isogenies of degree equal to the characteristic are computed (but
2524
+ only the separable isogeny). In the following example we consider
2525
+ an elliptic curve which is supersingular in characteristic 2
2526
+ only::
2527
+
2528
+ sage: from sage.schemes.elliptic_curves.isogeny_small_degree import isogenies_prime_degree_general
2529
+ sage: ainvs = (0,1,1,-1,-1)
2530
+ sage: for l in prime_range(50):
2531
+ ....: E = EllipticCurve(GF(l),ainvs)
2532
+ ....: isogenies_prime_degree_general(E,l)
2533
+ []
2534
+ [Isogeny of degree 3
2535
+ from Elliptic Curve defined by y^2 + y = x^3 + x^2 + 2*x + 2
2536
+ over Finite Field of size 3
2537
+ to Elliptic Curve defined by y^2 + y = x^3 + x^2 + x over Finite Field of size 3]
2538
+ [Isogeny of degree 5
2539
+ from Elliptic Curve defined by y^2 + y = x^3 + x^2 + 4*x + 4
2540
+ over Finite Field of size 5
2541
+ to Elliptic Curve defined by y^2 + y = x^3 + x^2 + 4*x + 4
2542
+ over Finite Field of size 5]
2543
+ [Isogeny of degree 7
2544
+ from Elliptic Curve defined by y^2 + y = x^3 + x^2 + 6*x + 6
2545
+ over Finite Field of size 7
2546
+ to Elliptic Curve defined by y^2 + y = x^3 + x^2 + 4 over Finite Field of size 7]
2547
+ [Isogeny of degree 11
2548
+ from Elliptic Curve defined by y^2 + y = x^3 + x^2 + 10*x + 10
2549
+ over Finite Field of size 11
2550
+ to Elliptic Curve defined by y^2 + y = x^3 + x^2 + x + 1
2551
+ over Finite Field of size 11]
2552
+ [Isogeny of degree 13
2553
+ from Elliptic Curve defined by y^2 + y = x^3 + x^2 + 12*x + 12
2554
+ over Finite Field of size 13
2555
+ to Elliptic Curve defined by y^2 + y = x^3 + x^2 + 12*x + 12
2556
+ over Finite Field of size 13]
2557
+ [Isogeny of degree 17 from Elliptic Curve defined by y^2 + y = x^3 + x^2 + 16*x + 16 over Finite Field of size 17 to Elliptic Curve defined by y^2 + y = x^3 + x^2 + 15 over Finite Field of size 17]
2558
+ [Isogeny of degree 19 from Elliptic Curve defined by y^2 + y = x^3 + x^2 + 18*x + 18 over Finite Field of size 19 to Elliptic Curve defined by y^2 + y = x^3 + x^2 + 3*x + 12 over Finite Field of size 19]
2559
+ [Isogeny of degree 23 from Elliptic Curve defined by y^2 + y = x^3 + x^2 + 22*x + 22 over Finite Field of size 23 to Elliptic Curve defined by y^2 + y = x^3 + x^2 + 22*x + 22 over Finite Field of size 23]
2560
+ [Isogeny of degree 29 from Elliptic Curve defined by y^2 + y = x^3 + x^2 + 28*x + 28 over Finite Field of size 29 to Elliptic Curve defined by y^2 + y = x^3 + x^2 + 7*x + 27 over Finite Field of size 29]
2561
+ [Isogeny of degree 31 from Elliptic Curve defined by y^2 + y = x^3 + x^2 + 30*x + 30 over Finite Field of size 31 to Elliptic Curve defined by y^2 + y = x^3 + x^2 + 15*x + 16 over Finite Field of size 31]
2562
+ [Isogeny of degree 37 from Elliptic Curve defined by y^2 + y = x^3 + x^2 + 36*x + 36 over Finite Field of size 37 to Elliptic Curve defined by y^2 + y = x^3 + x^2 + 16*x + 17 over Finite Field of size 37]
2563
+ [Isogeny of degree 41 from Elliptic Curve defined by y^2 + y = x^3 + x^2 + 40*x + 40 over Finite Field of size 41 to Elliptic Curve defined by y^2 + y = x^3 + x^2 + 33*x + 16 over Finite Field of size 41]
2564
+ [Isogeny of degree 43 from Elliptic Curve defined by y^2 + y = x^3 + x^2 + 42*x + 42 over Finite Field of size 43 to Elliptic Curve defined by y^2 + y = x^3 + x^2 + 36 over Finite Field of size 43]
2565
+ [Isogeny of degree 47 from Elliptic Curve defined by y^2 + y = x^3 + x^2 + 46*x + 46 over Finite Field of size 47 to Elliptic Curve defined by y^2 + y = x^3 + x^2 + 42*x + 34 over Finite Field of size 47]
2566
+
2567
+ Note that not all factors of degree `(l-1)/2` of the `l`-division
2568
+ polynomial are kernel polynomials. In this example, the
2569
+ 13-division polynomial factors as a product of 14 irreducible
2570
+ factors of degree 6 each, but only two those are kernel
2571
+ polynomials::
2572
+
2573
+ sage: F3 = GF(3)
2574
+ sage: E = EllipticCurve(F3, [0,0,0,-1,0])
2575
+ sage: Psi13 = E.division_polynomial(13)
2576
+ sage: len([f for f, e in Psi13.factor() if f.degree() == 6])
2577
+ 14
2578
+ sage: len(E.isogenies_prime_degree(13))
2579
+ 2
2580
+
2581
+ Over GF(9) the other factors of degree 6 split into pairs of
2582
+ cubics which can be rearranged to give the remaining 12 kernel
2583
+ polynomials::
2584
+
2585
+ sage: len(E.change_ring(GF(3^2,'a')).isogenies_prime_degree(13)) # needs sage.rings.finite_rings
2586
+ 14
2587
+
2588
+ See :issue:`18589`: the following example took 20s before, now only 4s::
2589
+
2590
+ sage: K.<i> = QuadraticField(-1) # needs sage.rings.number_field
2591
+ sage: E = EllipticCurve(K,[0,0,0,1,0]) # needs sage.rings.number_field
2592
+ sage: [phi.codomain().ainvs() # long time # needs sage.rings.number_field
2593
+ ....: for phi in E.isogenies_prime_degree(37)]
2594
+ [(0, 0, 0, 840*i + 1081, 0),
2595
+ (0, 0, 0, -840*i + 1081, 0)]
2596
+ """
2597
+ if not l.is_prime():
2598
+ raise ValueError("%s is not prime." % l)
2599
+ if l == 2:
2600
+ return isogenies_2(E, minimal_models=minimal_models)
2601
+ if l == 3:
2602
+ return isogenies_3(E, minimal_models=minimal_models)
2603
+
2604
+ psi_l = E.division_polynomial(l)
2605
+
2606
+ factors = [h for h,_ in psi_l.factor() if h.degree().divides(l//2)]
2607
+
2608
+ ker = [] # will store all kernel polynomials found
2609
+
2610
+ while factors:
2611
+ h = factors.pop()
2612
+ try:
2613
+ k = E.kernel_polynomial_from_divisor(h, l, check=False)
2614
+ except ValueError:
2615
+ continue
2616
+ assert k.degree() == l//2 and k.divides(psi_l)
2617
+ ker.append(k)
2618
+ factors = [h for h in factors if not h.divides(k)]
2619
+
2620
+ return [E.isogeny(k, check=False) for k in ker]
2621
+
2622
+
2623
+ def isogenies_prime_degree(E, l, minimal_models=True):
2624
+ """
2625
+ Return all separable ``l``-isogenies with domain ``E``.
2626
+
2627
+ INPUT:
2628
+
2629
+ - ``E`` -- an elliptic curve
2630
+
2631
+ - ``l`` -- a prime
2632
+
2633
+ - ``minimal_models`` -- boolean (default: ``True``); if ``True``, all
2634
+ curves computed will be minimal or semi-minimal models. Over
2635
+ fields of larger degree it can be expensive to compute these so
2636
+ set to ``False``. Ignored except over number fields other than
2637
+ `QQ`.
2638
+
2639
+ OUTPUT: list of all separable isogenies of degree `l` with domain ``E``
2640
+
2641
+ EXAMPLES::
2642
+
2643
+ sage: from sage.schemes.elliptic_curves.isogeny_small_degree import isogenies_prime_degree
2644
+ sage: E = EllipticCurve_from_j(GF(2^6,'a')(1)) # needs sage.rings.finite_rings
2645
+ sage: isogenies_prime_degree(E, 7) # needs sage.rings.finite_rings
2646
+ [Isogeny of degree 7
2647
+ from Elliptic Curve defined by y^2 + x*y = x^3 + 1
2648
+ over Finite Field in a of size 2^6
2649
+ to Elliptic Curve defined by y^2 + x*y = x^3 + x
2650
+ over Finite Field in a of size 2^6]
2651
+ sage: E = EllipticCurve_from_j(GF(3^12,'a')(2)) # needs sage.rings.finite_rings
2652
+ sage: isogenies_prime_degree(E, 17) # needs sage.rings.finite_rings
2653
+ [Isogeny of degree 17
2654
+ from Elliptic Curve defined by y^2 = x^3 + 2*x^2 + 2
2655
+ over Finite Field in a of size 3^12
2656
+ to Elliptic Curve defined by y^2 = x^3 + 2*x^2 + x + 2
2657
+ over Finite Field in a of size 3^12,
2658
+ Isogeny of degree 17
2659
+ from Elliptic Curve defined by y^2 = x^3 + 2*x^2 + 2
2660
+ over Finite Field in a of size 3^12
2661
+ to Elliptic Curve defined by y^2 = x^3 + 2*x^2 + 2*x
2662
+ over Finite Field in a of size 3^12]
2663
+ sage: E = EllipticCurve('50a1')
2664
+ sage: isogenies_prime_degree(E, 3)
2665
+ [Isogeny of degree 3
2666
+ from Elliptic Curve defined by y^2 + x*y + y = x^3 - x - 2 over Rational Field
2667
+ to Elliptic Curve defined by y^2 + x*y + y = x^3 - 126*x - 552 over Rational Field]
2668
+ sage: isogenies_prime_degree(E, 5)
2669
+ [Isogeny of degree 5
2670
+ from Elliptic Curve defined by y^2 + x*y + y = x^3 - x - 2 over Rational Field
2671
+ to Elliptic Curve defined by y^2 + x*y + y = x^3 - 76*x + 298 over Rational Field]
2672
+ sage: E = EllipticCurve([0, 0, 1, -1862, -30956])
2673
+ sage: isogenies_prime_degree(E, 19)
2674
+ [Isogeny of degree 19
2675
+ from Elliptic Curve defined by y^2 + y = x^3 - 1862*x - 30956
2676
+ over Rational Field
2677
+ to Elliptic Curve defined by y^2 + y = x^3 - 672182*x + 212325489
2678
+ over Rational Field]
2679
+ sage: E = EllipticCurve([0, -1, 0, -6288, 211072])
2680
+ sage: isogenies_prime_degree(E, 37)
2681
+ [Isogeny of degree 37
2682
+ from Elliptic Curve defined by y^2 = x^3 - x^2 - 6288*x + 211072
2683
+ over Rational Field
2684
+ to Elliptic Curve defined by y^2 = x^3 - x^2 - 163137088*x - 801950801728
2685
+ over Rational Field]
2686
+
2687
+ Isogenies of degree equal to the characteristic are computed (but
2688
+ only the separable isogeny). In the following example we consider
2689
+ an elliptic curve which is supersingular in characteristic 2
2690
+ only::
2691
+
2692
+ sage: from sage.schemes.elliptic_curves.isogeny_small_degree import isogenies_prime_degree
2693
+ sage: ainvs = (0,1,1,-1,-1)
2694
+ sage: for l in prime_range(50):
2695
+ ....: E = EllipticCurve(GF(l), ainvs)
2696
+ ....: isogenies_prime_degree(E, l)
2697
+ []
2698
+ [Isogeny of degree 3
2699
+ from Elliptic Curve defined by y^2 + y = x^3 + x^2 + 2*x + 2 over Finite Field of size 3
2700
+ to Elliptic Curve defined by y^2 + y = x^3 + x^2 + x over Finite Field of size 3]
2701
+ [Isogeny of degree 5
2702
+ from Elliptic Curve defined by y^2 + y = x^3 + x^2 + 4*x + 4 over Finite Field of size 5
2703
+ to Elliptic Curve defined by y^2 + y = x^3 + x^2 + 4*x + 4 over Finite Field of size 5]
2704
+ [Isogeny of degree 7
2705
+ from Elliptic Curve defined by y^2 + y = x^3 + x^2 + 6*x + 6 over Finite Field of size 7
2706
+ to Elliptic Curve defined by y^2 + y = x^3 + x^2 + 4 over Finite Field of size 7]
2707
+ [Isogeny of degree 11
2708
+ from Elliptic Curve defined by y^2 + y = x^3 + x^2 + 10*x + 10 over Finite Field of size 11
2709
+ to Elliptic Curve defined by y^2 + y = x^3 + x^2 + x + 1 over Finite Field of size 11]
2710
+ [Isogeny of degree 13
2711
+ from Elliptic Curve defined by y^2 + y = x^3 + x^2 + 12*x + 12 over Finite Field of size 13
2712
+ to Elliptic Curve defined by y^2 + y = x^3 + x^2 + 12*x + 12 over Finite Field of size 13]
2713
+ [Isogeny of degree 17
2714
+ from Elliptic Curve defined by y^2 + y = x^3 + x^2 + 16*x + 16 over Finite Field of size 17
2715
+ to Elliptic Curve defined by y^2 + y = x^3 + x^2 + 15 over Finite Field of size 17]
2716
+ [Isogeny of degree 19
2717
+ from Elliptic Curve defined by y^2 + y = x^3 + x^2 + 18*x + 18 over Finite Field of size 19
2718
+ to Elliptic Curve defined by y^2 + y = x^3 + x^2 + 3*x + 12 over Finite Field of size 19]
2719
+ [Isogeny of degree 23
2720
+ from Elliptic Curve defined by y^2 + y = x^3 + x^2 + 22*x + 22 over Finite Field of size 23
2721
+ to Elliptic Curve defined by y^2 + y = x^3 + x^2 + 22*x + 22 over Finite Field of size 23]
2722
+ [Isogeny of degree 29
2723
+ from Elliptic Curve defined by y^2 + y = x^3 + x^2 + 28*x + 28 over Finite Field of size 29
2724
+ to Elliptic Curve defined by y^2 + y = x^3 + x^2 + 7*x + 27 over Finite Field of size 29]
2725
+ [Isogeny of degree 31
2726
+ from Elliptic Curve defined by y^2 + y = x^3 + x^2 + 30*x + 30 over Finite Field of size 31
2727
+ to Elliptic Curve defined by y^2 + y = x^3 + x^2 + 15*x + 16 over Finite Field of size 31]
2728
+ [Isogeny of degree 37
2729
+ from Elliptic Curve defined by y^2 + y = x^3 + x^2 + 36*x + 36 over Finite Field of size 37
2730
+ to Elliptic Curve defined by y^2 + y = x^3 + x^2 + 16*x + 17 over Finite Field of size 37]
2731
+ [Isogeny of degree 41
2732
+ from Elliptic Curve defined by y^2 + y = x^3 + x^2 + 40*x + 40 over Finite Field of size 41
2733
+ to Elliptic Curve defined by y^2 + y = x^3 + x^2 + 33*x + 16 over Finite Field of size 41]
2734
+ [Isogeny of degree 43
2735
+ from Elliptic Curve defined by y^2 + y = x^3 + x^2 + 42*x + 42 over Finite Field of size 43
2736
+ to Elliptic Curve defined by y^2 + y = x^3 + x^2 + 36 over Finite Field of size 43]
2737
+ [Isogeny of degree 47
2738
+ from Elliptic Curve defined by y^2 + y = x^3 + x^2 + 46*x + 46 over Finite Field of size 47
2739
+ to Elliptic Curve defined by y^2 + y = x^3 + x^2 + 42*x + 34 over Finite Field of size 47]
2740
+
2741
+ Note that the computation is faster for degrees equal to one of
2742
+ the genus 0 primes (2, 3, 5, 7, 13) or one of the hyperelliptic
2743
+ primes (11, 17, 19, 23, 29, 31, 41, 47, 59, 71) than when the
2744
+ generic code must be used::
2745
+
2746
+ sage: E = EllipticCurve(GF(101), [-3440, 77658])
2747
+ sage: E.isogenies_prime_degree(71) # fast
2748
+ []
2749
+ sage: E.isogenies_prime_degree(73) # long time
2750
+ []
2751
+
2752
+ Test that :issue:`32269` is fixed::
2753
+
2754
+ sage: K = QuadraticField(-11) # needs sage.rings.number_field
2755
+ sage: E = EllipticCurve(K, [0,1,0,-117,-541]) # needs sage.rings.number_field
2756
+ sage: E.isogenies_prime_degree(37) # long time # needs sage.rings.number_field
2757
+ [Isogeny of degree 37
2758
+ from Elliptic Curve defined by y^2 = x^3 + x^2 + (-117)*x + (-541)
2759
+ over Number Field in a with defining polynomial x^2 + 11
2760
+ with a = 3.316624790355400?*I
2761
+ to Elliptic Curve defined by
2762
+ y^2 = x^3 + x^2 + (-30800*a+123963)*x + (-3931312*a-21805005)
2763
+ over Number Field in a with defining polynomial x^2 + 11
2764
+ with a = 3.316624790355400?*I,
2765
+ Isogeny of degree 37
2766
+ from Elliptic Curve defined by y^2 = x^3 + x^2 + (-117)*x + (-541)
2767
+ over Number Field in a with defining polynomial x^2 + 11
2768
+ with a = 3.316624790355400?*I
2769
+ to Elliptic Curve defined by
2770
+ y^2 = x^3 + x^2 + (30800*a+123963)*x + (3931312*a-21805005)
2771
+ over Number Field in a with defining polynomial x^2 + 11
2772
+ with a = 3.316624790355400?*I]
2773
+ """
2774
+ if not l.is_prime():
2775
+ raise ValueError("%s is not prime." % l)
2776
+ if l == 2:
2777
+ return isogenies_2(E, minimal_models=minimal_models)
2778
+ if l == 3:
2779
+ return isogenies_3(E, minimal_models=minimal_models)
2780
+
2781
+ p = E.base_ring().characteristic()
2782
+ if l == p:
2783
+ return isogenies_prime_degree_general(E,l, minimal_models=minimal_models)
2784
+
2785
+ if l in [5,7,13] and p not in [2,3]:
2786
+ return isogenies_prime_degree_genus_0(E,l, minimal_models=minimal_models)
2787
+
2788
+ if l in hyperelliptic_primes and p not in [2,3]:
2789
+ return isogenies_prime_degree_genus_plus_0(E,l, minimal_models=minimal_models)
2790
+
2791
+ j = E.j_invariant()
2792
+ if j in QQ and E.base_field() is QQ:
2793
+ j = QQ(j)
2794
+ if j in sporadic_j:
2795
+ return isogenies_sporadic_Q(E,l, minimal_models=minimal_models)
2796
+
2797
+ return isogenies_prime_degree_general(E,l, minimal_models=minimal_models)