passagemath-schemes 10.8.1a4__cp314-cp314t-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.
Files changed (312) 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.8.1a4.dist-info/METADATA +203 -0
  7. passagemath_schemes-10.8.1a4.dist-info/METADATA.bak +204 -0
  8. passagemath_schemes-10.8.1a4.dist-info/RECORD +312 -0
  9. passagemath_schemes-10.8.1a4.dist-info/WHEEL +6 -0
  10. passagemath_schemes-10.8.1a4.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 +9556 -0
  24. sage/dynamics/arithmetic_dynamics/projective_ds_helper.cpython-314t-darwin.so +0 -0
  25. sage/dynamics/arithmetic_dynamics/projective_ds_helper.pyx +301 -0
  26. sage/dynamics/arithmetic_dynamics/wehlerK3.py +2578 -0
  27. sage/lfunctions/all.py +18 -0
  28. sage/lfunctions/dokchitser.py +727 -0
  29. sage/lfunctions/pari.py +971 -0
  30. sage/lfunctions/zero_sums.cpython-314t-darwin.so +0 -0
  31. sage/lfunctions/zero_sums.pyx +1847 -0
  32. sage/modular/abvar/abvar.py +5132 -0
  33. sage/modular/abvar/abvar_ambient_jacobian.py +414 -0
  34. sage/modular/abvar/abvar_newform.py +246 -0
  35. sage/modular/abvar/all.py +8 -0
  36. sage/modular/abvar/constructor.py +187 -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 +721 -0
  40. sage/modular/abvar/homspace.py +989 -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 +741 -0
  45. sage/modular/all.py +43 -0
  46. sage/modular/arithgroup/all.py +20 -0
  47. sage/modular/arithgroup/arithgroup_element.cpython-314t-darwin.so +0 -0
  48. sage/modular/arithgroup/arithgroup_element.pyx +474 -0
  49. sage/modular/arithgroup/arithgroup_generic.py +1406 -0
  50. sage/modular/arithgroup/arithgroup_perm.py +2692 -0
  51. sage/modular/arithgroup/congroup.cpython-314t-darwin.so +0 -0
  52. sage/modular/arithgroup/congroup.pyx +334 -0
  53. sage/modular/arithgroup/congroup_gamma.py +361 -0
  54. sage/modular/arithgroup/congroup_gamma0.py +692 -0
  55. sage/modular/arithgroup/congroup_gamma1.py +659 -0
  56. sage/modular/arithgroup/congroup_gammaH.py +1491 -0
  57. sage/modular/arithgroup/congroup_generic.py +630 -0
  58. sage/modular/arithgroup/congroup_sl2z.py +266 -0
  59. sage/modular/arithgroup/farey_symbol.cpython-314t-darwin.so +0 -0
  60. sage/modular/arithgroup/farey_symbol.pyx +1067 -0
  61. sage/modular/arithgroup/tests.py +425 -0
  62. sage/modular/btquotients/all.py +4 -0
  63. sage/modular/btquotients/btquotient.py +3736 -0
  64. sage/modular/btquotients/pautomorphicform.py +2564 -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 +1107 -0
  69. sage/modular/cusps_nf.py +1270 -0
  70. sage/modular/dims.py +571 -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 +1076 -0
  77. sage/modular/hecke/algebra.py +725 -0
  78. sage/modular/hecke/all.py +19 -0
  79. sage/modular/hecke/ambient_module.py +994 -0
  80. sage/modular/hecke/degenmap.py +119 -0
  81. sage/modular/hecke/element.py +302 -0
  82. sage/modular/hecke/hecke_operator.py +736 -0
  83. sage/modular/hecke/homspace.py +185 -0
  84. sage/modular/hecke/module.py +1744 -0
  85. sage/modular/hecke/morphism.py +139 -0
  86. sage/modular/hecke/submodule.py +970 -0
  87. sage/modular/hypergeometric_misc.cpython-314t-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 +2020 -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 +1070 -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 +817 -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 +120 -0
  101. sage/modular/modform/ambient_g1.py +199 -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 +487 -0
  106. sage/modular/modform/eisenstein_submodule.py +663 -0
  107. sage/modular/modform/element.py +4105 -0
  108. sage/modular/modform/half_integral.py +154 -0
  109. sage/modular/modform/hecke_operator_on_qexp.py +247 -0
  110. sage/modular/modform/j_invariant.py +47 -0
  111. sage/modular/modform/l_series_gross_zagier.py +127 -0
  112. sage/modular/modform/l_series_gross_zagier_coeffs.cpython-314t-darwin.so +0 -0
  113. sage/modular/modform/l_series_gross_zagier_coeffs.pyx +177 -0
  114. sage/modular/modform/notes.py +45 -0
  115. sage/modular/modform/numerical.py +514 -0
  116. sage/modular/modform/periods.py +14 -0
  117. sage/modular/modform/ring.py +1257 -0
  118. sage/modular/modform/space.py +1859 -0
  119. sage/modular/modform/submodule.py +118 -0
  120. sage/modular/modform/tests.py +64 -0
  121. sage/modular/modform/theta.py +110 -0
  122. sage/modular/modform/vm_basis.py +380 -0
  123. sage/modular/modform/weight1.py +221 -0
  124. sage/modular/modform_hecketriangle/abstract_ring.py +1932 -0
  125. sage/modular/modform_hecketriangle/abstract_space.py +2527 -0
  126. sage/modular/modform_hecketriangle/all.py +30 -0
  127. sage/modular/modform_hecketriangle/analytic_type.py +590 -0
  128. sage/modular/modform_hecketriangle/constructor.py +416 -0
  129. sage/modular/modform_hecketriangle/element.py +351 -0
  130. sage/modular/modform_hecketriangle/functors.py +752 -0
  131. sage/modular/modform_hecketriangle/graded_ring.py +541 -0
  132. sage/modular/modform_hecketriangle/graded_ring_element.py +2225 -0
  133. sage/modular/modform_hecketriangle/hecke_triangle_group_element.py +3349 -0
  134. sage/modular/modform_hecketriangle/hecke_triangle_groups.py +1426 -0
  135. sage/modular/modform_hecketriangle/readme.py +1214 -0
  136. sage/modular/modform_hecketriangle/series_constructor.py +580 -0
  137. sage/modular/modform_hecketriangle/space.py +1037 -0
  138. sage/modular/modform_hecketriangle/subspace.py +423 -0
  139. sage/modular/modsym/all.py +17 -0
  140. sage/modular/modsym/ambient.py +3844 -0
  141. sage/modular/modsym/boundary.py +1420 -0
  142. sage/modular/modsym/element.py +336 -0
  143. sage/modular/modsym/g1list.py +178 -0
  144. sage/modular/modsym/ghlist.py +182 -0
  145. sage/modular/modsym/hecke_operator.py +73 -0
  146. sage/modular/modsym/manin_symbol.cpython-314t-darwin.so +0 -0
  147. sage/modular/modsym/manin_symbol.pxd +5 -0
  148. sage/modular/modsym/manin_symbol.pyx +497 -0
  149. sage/modular/modsym/manin_symbol_list.py +1291 -0
  150. sage/modular/modsym/modsym.py +400 -0
  151. sage/modular/modsym/modular_symbols.py +384 -0
  152. sage/modular/modsym/p1list_nf.py +1241 -0
  153. sage/modular/modsym/relation_matrix.py +591 -0
  154. sage/modular/modsym/relation_matrix_pyx.cpython-314t-darwin.so +0 -0
  155. sage/modular/modsym/relation_matrix_pyx.pyx +108 -0
  156. sage/modular/modsym/space.py +2468 -0
  157. sage/modular/modsym/subspace.py +455 -0
  158. sage/modular/modsym/tests.py +376 -0
  159. sage/modular/multiple_zeta.py +2635 -0
  160. sage/modular/multiple_zeta_F_algebra.py +789 -0
  161. sage/modular/overconvergent/all.py +6 -0
  162. sage/modular/overconvergent/genus0.py +1879 -0
  163. sage/modular/overconvergent/hecke_series.py +1187 -0
  164. sage/modular/overconvergent/weightspace.py +776 -0
  165. sage/modular/pollack_stevens/all.py +4 -0
  166. sage/modular/pollack_stevens/distributions.py +874 -0
  167. sage/modular/pollack_stevens/fund_domain.py +1572 -0
  168. sage/modular/pollack_stevens/manin_map.py +856 -0
  169. sage/modular/pollack_stevens/modsym.py +1590 -0
  170. sage/modular/pollack_stevens/padic_lseries.py +417 -0
  171. sage/modular/pollack_stevens/sigma0.py +534 -0
  172. sage/modular/pollack_stevens/space.py +1078 -0
  173. sage/modular/quasimodform/all.py +3 -0
  174. sage/modular/quasimodform/element.py +846 -0
  175. sage/modular/quasimodform/ring.py +826 -0
  176. sage/modular/quatalg/all.py +3 -0
  177. sage/modular/quatalg/brandt.py +1642 -0
  178. sage/modular/ssmod/all.py +8 -0
  179. sage/modular/ssmod/ssmod.py +827 -0
  180. sage/rings/all__sagemath_schemes.py +1 -0
  181. sage/rings/polynomial/all__sagemath_schemes.py +1 -0
  182. sage/rings/polynomial/binary_form_reduce.py +585 -0
  183. sage/schemes/all.py +41 -0
  184. sage/schemes/berkovich/all.py +6 -0
  185. sage/schemes/berkovich/berkovich_cp_element.py +2582 -0
  186. sage/schemes/berkovich/berkovich_space.py +700 -0
  187. sage/schemes/curves/affine_curve.py +2924 -0
  188. sage/schemes/curves/all.py +33 -0
  189. sage/schemes/curves/closed_point.py +434 -0
  190. sage/schemes/curves/constructor.py +397 -0
  191. sage/schemes/curves/curve.py +542 -0
  192. sage/schemes/curves/plane_curve_arrangement.py +1283 -0
  193. sage/schemes/curves/point.py +463 -0
  194. sage/schemes/curves/projective_curve.py +3203 -0
  195. sage/schemes/curves/weighted_projective_curve.py +106 -0
  196. sage/schemes/curves/zariski_vankampen.py +1931 -0
  197. sage/schemes/cyclic_covers/all.py +2 -0
  198. sage/schemes/cyclic_covers/charpoly_frobenius.py +320 -0
  199. sage/schemes/cyclic_covers/constructor.py +137 -0
  200. sage/schemes/cyclic_covers/cycliccover_finite_field.py +1309 -0
  201. sage/schemes/cyclic_covers/cycliccover_generic.py +310 -0
  202. sage/schemes/elliptic_curves/BSD.py +991 -0
  203. sage/schemes/elliptic_curves/Qcurves.py +592 -0
  204. sage/schemes/elliptic_curves/addition_formulas_ring.py +94 -0
  205. sage/schemes/elliptic_curves/all.py +49 -0
  206. sage/schemes/elliptic_curves/cardinality.py +609 -0
  207. sage/schemes/elliptic_curves/cm.py +1103 -0
  208. sage/schemes/elliptic_curves/constructor.py +1530 -0
  209. sage/schemes/elliptic_curves/ec_database.py +175 -0
  210. sage/schemes/elliptic_curves/ell_curve_isogeny.py +3971 -0
  211. sage/schemes/elliptic_curves/ell_egros.py +457 -0
  212. sage/schemes/elliptic_curves/ell_field.py +2837 -0
  213. sage/schemes/elliptic_curves/ell_finite_field.py +3249 -0
  214. sage/schemes/elliptic_curves/ell_generic.py +3760 -0
  215. sage/schemes/elliptic_curves/ell_local_data.py +1207 -0
  216. sage/schemes/elliptic_curves/ell_modular_symbols.py +775 -0
  217. sage/schemes/elliptic_curves/ell_number_field.py +4220 -0
  218. sage/schemes/elliptic_curves/ell_padic_field.py +107 -0
  219. sage/schemes/elliptic_curves/ell_point.py +4944 -0
  220. sage/schemes/elliptic_curves/ell_rational_field.py +7184 -0
  221. sage/schemes/elliptic_curves/ell_tate_curve.py +671 -0
  222. sage/schemes/elliptic_curves/ell_torsion.py +436 -0
  223. sage/schemes/elliptic_curves/ell_wp.py +352 -0
  224. sage/schemes/elliptic_curves/formal_group.py +760 -0
  225. sage/schemes/elliptic_curves/gal_reps.py +1459 -0
  226. sage/schemes/elliptic_curves/gal_reps_number_field.py +1663 -0
  227. sage/schemes/elliptic_curves/gp_simon.py +152 -0
  228. sage/schemes/elliptic_curves/heegner.py +7328 -0
  229. sage/schemes/elliptic_curves/height.py +2108 -0
  230. sage/schemes/elliptic_curves/hom.py +1788 -0
  231. sage/schemes/elliptic_curves/hom_composite.py +1084 -0
  232. sage/schemes/elliptic_curves/hom_fractional.py +544 -0
  233. sage/schemes/elliptic_curves/hom_frobenius.py +522 -0
  234. sage/schemes/elliptic_curves/hom_scalar.py +531 -0
  235. sage/schemes/elliptic_curves/hom_sum.py +681 -0
  236. sage/schemes/elliptic_curves/hom_velusqrt.py +1290 -0
  237. sage/schemes/elliptic_curves/homset.py +271 -0
  238. sage/schemes/elliptic_curves/isogeny_class.py +1523 -0
  239. sage/schemes/elliptic_curves/isogeny_small_degree.py +2797 -0
  240. sage/schemes/elliptic_curves/jacobian.py +247 -0
  241. sage/schemes/elliptic_curves/kodaira_symbol.py +344 -0
  242. sage/schemes/elliptic_curves/kraus.py +1014 -0
  243. sage/schemes/elliptic_curves/lseries_ell.py +915 -0
  244. sage/schemes/elliptic_curves/mod5family.py +105 -0
  245. sage/schemes/elliptic_curves/mod_poly.py +197 -0
  246. sage/schemes/elliptic_curves/mod_sym_num.cpython-314t-darwin.so +0 -0
  247. sage/schemes/elliptic_curves/mod_sym_num.pyx +3796 -0
  248. sage/schemes/elliptic_curves/modular_parametrization.py +305 -0
  249. sage/schemes/elliptic_curves/padic_lseries.py +1793 -0
  250. sage/schemes/elliptic_curves/padics.py +1816 -0
  251. sage/schemes/elliptic_curves/period_lattice.py +2234 -0
  252. sage/schemes/elliptic_curves/period_lattice_region.cpython-314t-darwin.so +0 -0
  253. sage/schemes/elliptic_curves/period_lattice_region.pyx +722 -0
  254. sage/schemes/elliptic_curves/saturation.py +716 -0
  255. sage/schemes/elliptic_curves/sha_tate.py +1158 -0
  256. sage/schemes/elliptic_curves/weierstrass_morphism.py +1117 -0
  257. sage/schemes/elliptic_curves/weierstrass_transform.py +200 -0
  258. sage/schemes/hyperelliptic_curves/all.py +6 -0
  259. sage/schemes/hyperelliptic_curves/constructor.py +369 -0
  260. sage/schemes/hyperelliptic_curves/hyperelliptic_finite_field.py +1948 -0
  261. sage/schemes/hyperelliptic_curves/hyperelliptic_g2.py +192 -0
  262. sage/schemes/hyperelliptic_curves/hyperelliptic_generic.py +936 -0
  263. sage/schemes/hyperelliptic_curves/hyperelliptic_padic_field.py +1332 -0
  264. sage/schemes/hyperelliptic_curves/hyperelliptic_rational_field.py +84 -0
  265. sage/schemes/hyperelliptic_curves/invariants.py +410 -0
  266. sage/schemes/hyperelliptic_curves/jacobian_endomorphism_utils.py +312 -0
  267. sage/schemes/hyperelliptic_curves/jacobian_g2.py +32 -0
  268. sage/schemes/hyperelliptic_curves/jacobian_generic.py +437 -0
  269. sage/schemes/hyperelliptic_curves/jacobian_homset.py +186 -0
  270. sage/schemes/hyperelliptic_curves/jacobian_morphism.py +878 -0
  271. sage/schemes/hyperelliptic_curves/kummer_surface.py +99 -0
  272. sage/schemes/hyperelliptic_curves/mestre.py +302 -0
  273. sage/schemes/hyperelliptic_curves/monsky_washnitzer.py +3863 -0
  274. sage/schemes/jacobians/abstract_jacobian.py +277 -0
  275. sage/schemes/jacobians/all.py +2 -0
  276. sage/schemes/overview.py +161 -0
  277. sage/schemes/plane_conics/all.py +22 -0
  278. sage/schemes/plane_conics/con_field.py +1296 -0
  279. sage/schemes/plane_conics/con_finite_field.py +158 -0
  280. sage/schemes/plane_conics/con_number_field.py +456 -0
  281. sage/schemes/plane_conics/con_rational_field.py +406 -0
  282. sage/schemes/plane_conics/con_rational_function_field.py +581 -0
  283. sage/schemes/plane_conics/constructor.py +249 -0
  284. sage/schemes/plane_quartics/all.py +2 -0
  285. sage/schemes/plane_quartics/quartic_constructor.py +71 -0
  286. sage/schemes/plane_quartics/quartic_generic.py +53 -0
  287. sage/schemes/riemann_surfaces/all.py +1 -0
  288. sage/schemes/riemann_surfaces/riemann_surface.py +4177 -0
  289. sage_wheels/share/cremona/cremona_mini.db +0 -0
  290. sage_wheels/share/ellcurves/rank0 +30427 -0
  291. sage_wheels/share/ellcurves/rank1 +31871 -0
  292. sage_wheels/share/ellcurves/rank10 +6 -0
  293. sage_wheels/share/ellcurves/rank11 +6 -0
  294. sage_wheels/share/ellcurves/rank12 +1 -0
  295. sage_wheels/share/ellcurves/rank14 +1 -0
  296. sage_wheels/share/ellcurves/rank15 +1 -0
  297. sage_wheels/share/ellcurves/rank17 +1 -0
  298. sage_wheels/share/ellcurves/rank19 +1 -0
  299. sage_wheels/share/ellcurves/rank2 +2388 -0
  300. sage_wheels/share/ellcurves/rank20 +1 -0
  301. sage_wheels/share/ellcurves/rank21 +1 -0
  302. sage_wheels/share/ellcurves/rank22 +1 -0
  303. sage_wheels/share/ellcurves/rank23 +1 -0
  304. sage_wheels/share/ellcurves/rank24 +1 -0
  305. sage_wheels/share/ellcurves/rank28 +1 -0
  306. sage_wheels/share/ellcurves/rank3 +836 -0
  307. sage_wheels/share/ellcurves/rank4 +10 -0
  308. sage_wheels/share/ellcurves/rank5 +5 -0
  309. sage_wheels/share/ellcurves/rank6 +5 -0
  310. sage_wheels/share/ellcurves/rank7 +5 -0
  311. sage_wheels/share/ellcurves/rank8 +6 -0
  312. sage_wheels/share/ellcurves/rank9 +7 -0
@@ -0,0 +1,4944 @@
1
+ # sage_setup: distribution = sagemath-schemes
2
+ r"""
3
+ Points on elliptic curves
4
+
5
+ The base class :class:`EllipticCurvePoint` provides support for
6
+ points on elliptic curves defined over general rings, including
7
+ generic addition formulas.
8
+
9
+ The derived classes :class:`EllipticCurvePoint_field` and its
10
+ child classes :class:`EllipticCurvePoint_number_field` and
11
+ :class:`EllipticCurvePoint_finite_field` provide further support
12
+ for points on curves defined over arbitrary fields, as well as
13
+ specialized functionality for points on curves over number fields
14
+ (including the rational field `\QQ`) and finite fields.
15
+
16
+ EXAMPLES:
17
+
18
+ An example over `\QQ`::
19
+
20
+ sage: # needs database_cremona_mini_ellcurve
21
+ sage: E = EllipticCurve('389a1')
22
+ sage: P = E(-1,1); P
23
+ (-1 : 1 : 1)
24
+ sage: Q = E(0,-1); Q
25
+ (0 : -1 : 1)
26
+ sage: P+Q
27
+ (4 : 8 : 1)
28
+ sage: P-Q
29
+ (1 : 0 : 1)
30
+ sage: 3*P-5*Q
31
+ (328/361 : -2800/6859 : 1)
32
+
33
+ An example over a number field::
34
+
35
+ sage: # needs sage.rings.number_field
36
+ sage: K.<i> = QuadraticField(-1)
37
+ sage: E = EllipticCurve(K, [1,0,0,0,-1])
38
+ sage: P = E(0,i); P
39
+ (0 : i : 1)
40
+ sage: P.order()
41
+ +Infinity
42
+ sage: 101*P - 100*P == P
43
+ True
44
+
45
+ An example over a finite field::
46
+
47
+ sage: # needs sage.rings.finite_rings
48
+ sage: K.<a> = GF((101,3))
49
+ sage: E = EllipticCurve(K, [1,0,0,0,-1])
50
+ sage: P = E(40*a^2 + 69*a + 84 , 58*a^2 + 73*a + 45)
51
+ sage: P.order()
52
+ 1032210
53
+ sage: E.cardinality()
54
+ 1032210
55
+
56
+ Arithmetic with a point over an extension of a finite field::
57
+
58
+ sage: # needs sage.rings.finite_rings
59
+ sage: k.<a> = GF((5,2))
60
+ sage: E = EllipticCurve(k,[1,0]); E
61
+ Elliptic Curve defined by y^2 = x^3 + x over Finite Field in a of size 5^2
62
+ sage: P = E([a,2*a+4])
63
+ sage: 5*P
64
+ (2*a + 3 : 2*a : 1)
65
+ sage: P*5
66
+ (2*a + 3 : 2*a : 1)
67
+ sage: P + P + P + P + P
68
+ (2*a + 3 : 2*a : 1)
69
+
70
+ ::
71
+
72
+ sage: F = Zmod(3)
73
+ sage: E = EllipticCurve(F, [1,0]);
74
+ sage: P = E([2,1])
75
+ sage: import sys
76
+ sage: n = sys.maxsize
77
+ sage: P*(n+1)-P*n == P
78
+ True
79
+
80
+ Arithmetic over `\Zmod{N}` with composite `N` is supported::
81
+
82
+ sage: N = 1715761513
83
+ sage: E = EllipticCurve(Integers(N), [3,-13])
84
+ sage: P = E(2,1)
85
+ sage: LCM([2..60])*P
86
+ (1643112467 : 9446995 : 26927)
87
+
88
+ However, some algorithms (e.g., toy examples of ECM) involve performing
89
+ elliptic-curve operations as if the base ring were a field even when it
90
+ is not, and exploit the failures when attempting to invert a non-unit.
91
+ Sage provides a *hack* to support such educational examples via the
92
+ :meth:`EllipticCurve_generic.assume_base_ring_is_field` method.
93
+ Example::
94
+
95
+ sage: E.assume_base_ring_is_field()
96
+ sage: P = E(2,1)
97
+ sage: LCM([2..60])*P
98
+ Traceback (most recent call last):
99
+ ...
100
+ ZeroDivisionError: Inverse of 26927 does not exist
101
+ (characteristic = 1715761513 = 26927*63719)
102
+
103
+ AUTHORS:
104
+
105
+ - William Stein (2005) -- Initial version
106
+
107
+ - Robert Bradshaw et al....
108
+
109
+ - John Cremona (Feb 2008) -- Point counting and group structure for
110
+ non-prime fields, Frobenius endomorphism and order, elliptic logs
111
+
112
+ - John Cremona (Aug 2008) -- Introduced ``EllipticCurvePoint_number_field`` class
113
+
114
+ - Tobias Nagel, Michael Mardaus, John Cremona (Dec 2008) -- `p`-adic elliptic logarithm over `\QQ`
115
+
116
+ - David Hansen (Jan 2009) -- Added ``weil_pairing`` function to ``EllipticCurvePoint_finite_field`` class
117
+
118
+ - Mariah Lenox (March 2011) -- Added ``tate_pairing`` and ``ate_pairing``
119
+ functions to ``EllipticCurvePoint_finite_field`` class
120
+
121
+ - Lorenz Panny (2022): point addition over general rings
122
+ """
123
+
124
+ # ****************************************************************************
125
+ # Copyright (C) 2005 William Stein <wstein@gmail.com>
126
+ #
127
+ # Distributed under the terms of the GNU General Public License (GPL)
128
+ # as published by the Free Software Foundation; either version 2 of
129
+ # the License, or (at your option) any later version.
130
+ # https://www.gnu.org/licenses/
131
+ # ****************************************************************************
132
+
133
+ import math
134
+
135
+ import sage.groups.generic as generic
136
+ import sage.rings.abc
137
+
138
+ from sage.misc.lazy_import import lazy_import
139
+ from sage.rings.finite_rings.integer_mod import Mod
140
+ from sage.rings.infinity import Infinity as oo
141
+ from sage.rings.integer import Integer
142
+ from sage.rings.integer_ring import ZZ
143
+ from sage.rings.padics.precision_error import PrecisionError
144
+ from sage.rings.rational_field import QQ
145
+ from sage.rings.real_mpfr import RealField, RR
146
+ from sage.rings.quotient_ring import QuotientRing_generic
147
+
148
+ from sage.structure.element import AdditiveGroupElement
149
+ from sage.structure.sequence import Sequence
150
+ from sage.structure.richcmp import richcmp
151
+
152
+ from sage.structure.coerce_actions import IntegerMulAction
153
+
154
+ from sage.schemes.curves.projective_curve import Hasse_bounds
155
+ from sage.schemes.elliptic_curves.constructor import EllipticCurve
156
+ from sage.schemes.projective.projective_point import (SchemeMorphism_point_projective_ring,
157
+ SchemeMorphism_point_abelian_variety_field)
158
+
159
+ lazy_import('sage.rings.padics.factory', 'Qp')
160
+ lazy_import('sage.schemes.generic.morphism', 'SchemeMorphism')
161
+
162
+ try:
163
+ from sage.libs.pari import pari
164
+ from cypari2.handle_error import PariError
165
+ except ImportError:
166
+ PariError = ()
167
+
168
+
169
+ class EllipticCurvePoint(AdditiveGroupElement,
170
+ SchemeMorphism_point_projective_ring):
171
+ """
172
+ A point on an elliptic curve.
173
+ """
174
+ def __init__(self, *args, **kwds):
175
+ r"""
176
+ Initialize this elliptic-curve point.
177
+
178
+ EXAMPLES::
179
+
180
+ sage: E = EllipticCurve(Zmod(77), [1,1,1,1,1])
181
+ sage: E(0)
182
+ (0 : 1 : 0)
183
+ sage: E(3, 9)
184
+ (3 : 9 : 1)
185
+ sage: E(6, 18, 2)
186
+ (3 : 9 : 1)
187
+ sage: E(66, 23, 22)
188
+ (33 : 50 : 11)
189
+ """
190
+ super().__init__(*args, **kwds)
191
+ try:
192
+ self.normalize_coordinates()
193
+ except NotImplementedError:
194
+ pass
195
+
196
+ def curve(self):
197
+ """
198
+ Return the curve that this point is on.
199
+
200
+ This is a synonym for :meth:`scheme`.
201
+
202
+ EXAMPLES::
203
+
204
+ sage: # needs database_cremona_mini_ellcurve
205
+ sage: E = EllipticCurve('389a')
206
+ sage: P = E([-1, 1])
207
+ sage: P.curve()
208
+ Elliptic Curve defined by y^2 + y = x^3 + x^2 - 2*x over Rational Field
209
+
210
+ sage: E = EllipticCurve(QQ, [1, 1])
211
+ sage: P = E(0, 1)
212
+ sage: P.scheme()
213
+ Elliptic Curve defined by y^2 = x^3 + x + 1 over Rational Field
214
+ sage: P.scheme() == P.curve()
215
+ True
216
+ sage: x = polygen(ZZ, 'x')
217
+ sage: K.<a> = NumberField(x^2 - 3,'a') # needs sage.rings.number_field
218
+ sage: P = E.base_extend(K)(1, a) # needs sage.rings.number_field
219
+ sage: P.scheme() # needs sage.rings.number_field
220
+ Elliptic Curve defined by y^2 = x^3 + x + 1 over
221
+ Number Field in a with defining polynomial x^2 - 3
222
+ """
223
+ return self.scheme()
224
+
225
+ def _add_(self, other):
226
+ r"""
227
+ Add this point to another point on the same elliptic curve.
228
+
229
+ This method computes point additions for fairly general rings.
230
+
231
+ ALGORITHM:
232
+
233
+ Over quotient rings of Euclidean domains modulo principal ideals:
234
+ The standard formulas for fields, extended to non-fields via the
235
+ Chinese remainder theorem.
236
+
237
+ In more general rings: Formulas due to Bosma and Lenstra [BL1995]_
238
+ with corrections by Best [Best2021]_ (Appendix A).
239
+ See :mod:`sage.schemes.elliptic_curves.addition_formulas_ring`.
240
+
241
+ EXAMPLES::
242
+
243
+ sage: N = 1113121
244
+ sage: E = EllipticCurve(Zmod(N), [1,0])
245
+ sage: R1 = E(301098, 673883, 644675)
246
+ sage: R2 = E(411415, 758555, 255837)
247
+ sage: R3 = E(983009, 342673, 207687)
248
+ sage: R1 + R2 == R3
249
+ True
250
+
251
+ TESTS:
252
+
253
+ We check on random examples that the results are compatible modulo
254
+ all divisors of the characteristic. (In particular, this includes
255
+ prime divisors, for which the result is computed using the "old",
256
+ much simpler formulas for fields.) ::
257
+
258
+ sage: N = randrange(10**4) * 6 + choice([5, 7]) # coprime to 6
259
+ sage: E = None
260
+ sage: while True:
261
+ ....: try:
262
+ ....: E = EllipticCurve(list((Zmod(N)^5).random_element()))
263
+ ....: except ArithmeticError:
264
+ ....: pass
265
+ ....: else:
266
+ ....: if E.discriminant().is_unit():
267
+ ....: break
268
+ sage: pts = []
269
+ sage: X = polygen(Zmod(N^2))
270
+ sage: while len(pts) < 2:
271
+ ....: y, z = (Zmod(N)^2).random_element()
272
+ ....: f = E.defining_polynomial()(X, y, z)
273
+ ....: xs = f.roots(multiplicities=False)
274
+ ....: xs = [x for x in xs if 1 in Zmod(N).ideal([x,y,z])]
275
+ ....: if xs:
276
+ ....: pts.append(E(choice(xs), y, z))
277
+ sage: P, Q = pts
278
+ sage: R = P + Q
279
+ sage: for d in N.divisors():
280
+ ....: if d > 1:
281
+ ....: assert R.change_ring(Zmod(d)) == P.change_ring(Zmod(d)) + Q.change_ring(Zmod(d))
282
+ """
283
+ E = self.curve()
284
+ R = E.base_ring()
285
+
286
+ # According to https://cr.yp.to/bib/1987/lenstra-ecnta.pdf, §3,
287
+ # the formulas require 6 to be a unit. See #39191 for details.
288
+ if not R(6).is_unit():
289
+ raise NotImplementedError('addition of elliptic-curve points over non-fields is only supported when 6 is a unit')
290
+
291
+ # We handle Euclidean domains modulo principal ideals separately.
292
+ # Important special cases of this include quotient rings of the
293
+ # integers as well as of univariate polynomial rings over fields.
294
+ if isinstance(R, QuotientRing_generic):
295
+ from sage.categories.euclidean_domains import EuclideanDomains
296
+ if R.cover_ring() in EuclideanDomains():
297
+ I = R.defining_ideal()
298
+ if I.ngens() == 1:
299
+ mod, = I.gens()
300
+
301
+ a1, a2, a3, a4, a6 = E.ainvs()
302
+ x1, y1, z1 = map(R, self)
303
+ x2, y2, z2 = map(R, other)
304
+
305
+ mod_1st = mod.gcd(z2.lift())
306
+ mod //= mod_1st
307
+ mod_2nd = mod.gcd(z1.lift())
308
+ mod //= mod_2nd
309
+
310
+ xz, zx = x1*z2, x2*z1
311
+ yz, zy = y1*z2, y2*z1
312
+ zz = z1*z2
313
+
314
+ # addition
315
+ num_add = yz - zy
316
+ den_add = xz - zx
317
+ mod_dbl = mod.gcd(num_add.lift()).gcd(den_add.lift())
318
+ mod_add = mod // mod_dbl
319
+
320
+ # doubling
321
+ if not mod_dbl.is_one():
322
+ num_dbl = (3*x1 + 2*a2*z1) * x1 + (a4*z1 - a1*y1) * z1
323
+ den_dbl = (2*y1 + a1*x1 + a3*z1) * z1
324
+ else:
325
+ num_dbl = den_dbl = 0
326
+
327
+ if mod_dbl.gcd(mod_add).is_one():
328
+ from sage.arith.misc import CRT_vectors
329
+ if mod_dbl.is_one():
330
+ num, den = num_add, den_add
331
+ elif mod_add.is_one():
332
+ num, den = num_dbl, den_dbl
333
+ else:
334
+ num, den = CRT_vectors([(num_add, den_add), (num_dbl, den_dbl)], [mod_add, mod_dbl])
335
+
336
+ den2 = den**2
337
+ x3 = ((num + a1*den)*zz*num - (xz + zx + a2*zz)*den2) * den
338
+ y3 = ((2*xz + zx + (a2 - a1**2)*zz)*num + (a1*(xz + zx + a2*zz) - a3*zz - yz)*den) * den2 - (num + 2*a1*den)*zz*num**2
339
+ z3 = zz * den * den2
340
+
341
+ pt = x3.lift(), y3.lift(), z3.lift()
342
+ if not mod_1st.is_one():
343
+ pt = CRT_vectors([pt, [x1.lift(), y1.lift(), z1.lift()]], [mod, mod_1st])
344
+ mod = mod.lcm(mod_1st)
345
+ if not mod_2nd.is_one():
346
+ pt = CRT_vectors([pt, [x2.lift(), y2.lift(), z2.lift()]], [mod, mod_2nd])
347
+
348
+ return E.point(Sequence(pt, E.base_ring()), check=False)
349
+
350
+ from sage.schemes.elliptic_curves.addition_formulas_ring import _add
351
+ from sage.modules.free_module_element import vector
352
+
353
+ pts = []
354
+ for pt in filter(any, _add(E, self, other)):
355
+ if R.one() in R.ideal(pt):
356
+ return E.point(pt)
357
+ pts.append(pt)
358
+ assert len(pts) == 2, 'bug in elliptic-curve point addition'
359
+
360
+ #TODO: If the base ring has trivial Picard group, it is known
361
+ # that some linear combination of the two vectors is a valid
362
+ # projective point (whose coordinates generate the unit ideal).
363
+ # Below, we simply try random linear combinations until we
364
+ # find a good choice. Is there a general method that doesn't
365
+ # involve guessing?
366
+ # Answer: Yes.
367
+ # See pages 7-8 of Lenstra's "Elliptic Curves and Number-Theoretic Algorithms".
368
+ # https://cr.yp.to/bib/1987/lenstra-ecnta.pdf
369
+
370
+ pts = [vector(R, pt) for pt in pts]
371
+ for _ in range(1000):
372
+ result = tuple(sum(R.random_element() * pt for pt in pts))
373
+ if R.one() in R.ideal(result):
374
+ return E.point(result, check=False)
375
+
376
+ assert False, 'bug: failed to compute elliptic-curve point addition'
377
+
378
+ def _neg_(self):
379
+ """
380
+ Return the negative of this elliptic-curve point, over a general ring.
381
+
382
+ EXAMPLES::
383
+
384
+ sage: # needs database_cremona_mini_ellcurve
385
+ sage: E = EllipticCurve('389a')
386
+ sage: P = E([-1,1])
387
+ sage: Q = -P; Q
388
+ (-1 : -2 : 1)
389
+ sage: Q + P
390
+ (0 : 1 : 0)
391
+
392
+ ::
393
+
394
+ sage: N = 1113121
395
+ sage: E = EllipticCurve(Zmod(N), [1,0])
396
+ sage: R = E(301098, 673883, 644675)
397
+ sage: -R
398
+ (136211 : 914033 : 107)
399
+ sage: ((-R) + R) == 0
400
+ True
401
+ """
402
+ if self.is_zero():
403
+ return self
404
+ E = self.curve()
405
+ a1, _, a3, _, _ = E.a_invariants()
406
+ x, y, z = self
407
+ return E.point([x, -y - a1*x - a3*z, z], check=False)
408
+
409
+ def _sub_(self, other):
410
+ """
411
+ Subtract ``other`` from ``self``.
412
+
413
+ ALGORITHM: :meth:`_add_` and :meth:`_neg_`.
414
+
415
+ EXAMPLES::
416
+
417
+ sage: # needs database_cremona_mini_ellcurve
418
+ sage: E = EllipticCurve('389a')
419
+ sage: P = E([-1,1]); Q = E([0,0])
420
+ sage: P - Q
421
+ (4 : 8 : 1)
422
+ sage: P - Q == P._sub_(Q)
423
+ True
424
+ sage: (P - Q) + Q
425
+ (-1 : 1 : 1)
426
+ sage: P
427
+ (-1 : 1 : 1)
428
+
429
+ ::
430
+
431
+ sage: N = 1113121
432
+ sage: E = EllipticCurve(Zmod(N), [1,0])
433
+ sage: R1 = E(301098, 673883, 644675)
434
+ sage: R2 = E(411415, 758555, 255837)
435
+ sage: R3 = E(983009, 342673, 207687)
436
+ sage: R1 == R3 - R2
437
+ True
438
+ """
439
+ return self + (-other)
440
+
441
+ def _acted_upon_(self, other, side):
442
+ r"""
443
+ We implement ``_acted_upon_`` to provide scalar multiplications.
444
+
445
+ EXAMPLES::
446
+
447
+ sage: # needs sage.rings.finite_rings
448
+ sage: N = 1113121
449
+ sage: E = EllipticCurve(Zmod(N), [1,0])
450
+ sage: R = E(301098, 673883, 644675)
451
+ sage: 123*R
452
+ (703739 : 464106 : 107)
453
+ sage: 70200*R
454
+ (0 : 1 : 0)
455
+ """
456
+ return IntegerMulAction(ZZ, self.parent())._act_(other, self)
457
+
458
+ def __bool__(self):
459
+ r"""
460
+ Test whether this elliptic-curve point equals the neutral
461
+ element of the group (i.e., the point at infinity).
462
+
463
+ EXAMPLES::
464
+
465
+ sage: E = EllipticCurve(GF(7), [1,1])
466
+ sage: bool(E(0))
467
+ False
468
+ sage: bool(E.lift_x(2))
469
+ True
470
+
471
+ sage:
472
+
473
+ sage: E = EllipticCurve(Zmod(77), [1,1,1,1,1])
474
+ sage: bool(E(0))
475
+ False
476
+ sage: P = E(66, 23, 22); P
477
+ (33 : 50 : 11)
478
+ sage: bool(P)
479
+ True
480
+ """
481
+ return bool(self[2])
482
+
483
+
484
+ class EllipticCurvePoint_field(EllipticCurvePoint,
485
+ SchemeMorphism_point_abelian_variety_field):
486
+ """
487
+ A point on an elliptic curve over a field. The point has coordinates
488
+ in the base field.
489
+
490
+ EXAMPLES::
491
+
492
+ sage: # needs database_cremona_mini_ellcurve
493
+ sage: E = EllipticCurve('37a')
494
+ sage: E([0,0])
495
+ (0 : 0 : 1)
496
+ sage: E(0,0) # brackets are optional
497
+ (0 : 0 : 1)
498
+ sage: E([GF(5)(0), 0]) # entries are coerced
499
+ (0 : 0 : 1)
500
+ sage: E(0.000, 0)
501
+ (0 : 0 : 1)
502
+ sage: E(1,0,0)
503
+ Traceback (most recent call last):
504
+ ...
505
+ TypeError: Coordinates [1, 0, 0] do not define a point on
506
+ Elliptic Curve defined by y^2 + y = x^3 - x over Rational Field
507
+
508
+ ::
509
+
510
+ sage: E = EllipticCurve([0,0,1,-1,0])
511
+ sage: S = E(QQ); S
512
+ Abelian group of points on
513
+ Elliptic Curve defined by y^2 + y = x^3 - x over Rational Field
514
+
515
+ sage: # needs sage.rings.number_field
516
+ sage: x = polygen(ZZ, 'x')
517
+ sage: K.<i> = NumberField(x^2 + 1)
518
+ sage: E = EllipticCurve(K, [0,1,0,-160,308])
519
+ sage: P = E(26, -120)
520
+ sage: Q = E(2+12*i, -36+48*i)
521
+ sage: P.order() == Q.order() == 4 # long time
522
+ True
523
+ sage: 2*P == 2*Q
524
+ False
525
+
526
+ ::
527
+
528
+ sage: K.<t> = FractionField(PolynomialRing(QQ,'t'))
529
+ sage: E = EllipticCurve([0,0,0,0,t^2])
530
+ sage: P = E(0,t)
531
+ sage: P, 2*P, 3*P
532
+ ((0 : t : 1), (0 : -t : 1), (0 : 1 : 0))
533
+
534
+ TESTS::
535
+
536
+ sage: loads(S.dumps()) == S
537
+ True
538
+
539
+ sage: # needs database_cremona_mini_ellcurve
540
+ sage: E = EllipticCurve('37a')
541
+ sage: P = E(0,0); P
542
+ (0 : 0 : 1)
543
+ sage: loads(P.dumps()) == P
544
+ True
545
+ sage: T = 100*P
546
+ sage: loads(T.dumps()) == T
547
+ True
548
+
549
+ Test pickling an elliptic curve that has known points on it::
550
+
551
+ sage: e = EllipticCurve([0, 0, 1, -1, 0]); g = e.gens(); loads(dumps(e)) == e # needs eclib
552
+ True
553
+
554
+ Test that the refactoring from :issue:`14711` did preserve the behaviour
555
+ of domain and codomain::
556
+
557
+ sage: E = EllipticCurve(QQ,[1,1])
558
+ sage: P = E(0,1)
559
+ sage: P.domain()
560
+ Spectrum of Rational Field
561
+ sage: K.<a> = NumberField(x^2 - 3, 'a') # needs sage.rings.number_field
562
+ sage: P = E.base_extend(K)(1,a) # needs sage.rings.number_field
563
+ sage: P.domain() # needs sage.rings.number_field
564
+ Spectrum of Number Field in a with defining polynomial x^2 - 3
565
+ sage: P.codomain() # needs sage.rings.number_field
566
+ Elliptic Curve defined by y^2 = x^3 + x + 1
567
+ over Number Field in a with defining polynomial x^2 - 3
568
+ sage: P.codomain() == P.curve() # needs sage.rings.number_field
569
+ True
570
+ """
571
+ def __init__(self, curve, v, check=True):
572
+ """
573
+ Constructor for a point on an elliptic curve.
574
+
575
+ INPUT:
576
+
577
+ - ``curve`` -- an elliptic curve
578
+ - ``v`` -- data determining a point (another point, the integer
579
+ 0, or a tuple of coordinates)
580
+
581
+ EXAMPLES::
582
+
583
+ sage: # needs database_cremona_mini_ellcurve
584
+ sage: E = EllipticCurve('43a')
585
+ sage: P = E([2, -4, 2]); P
586
+ (1 : -2 : 1)
587
+ sage: P == E([1,-2])
588
+ True
589
+ sage: P = E(0); P
590
+ (0 : 1 : 0)
591
+ sage: P=E(2, -4, 2); P
592
+ (1 : -2 : 1)
593
+ """
594
+ point_homset = curve.point_homset()
595
+ R = point_homset.value_ring()
596
+ if isinstance(v, SchemeMorphism):
597
+ v = list(v)
598
+ elif v == 0:
599
+ v = (R.zero(), R.one(), R.zero())
600
+
601
+ SchemeMorphism_point_abelian_variety_field.__init__(self, point_homset, v, check=check)
602
+
603
+ self.normalize_coordinates()
604
+
605
+ def _repr_(self):
606
+ """
607
+ Return a string representation of this point.
608
+
609
+ EXAMPLES::
610
+
611
+ sage: # needs database_cremona_mini_ellcurve
612
+ sage: E = EllipticCurve('39a')
613
+ sage: P = E([-2, 1, 1])
614
+ sage: P._repr_()
615
+ '(-2 : 1 : 1)'
616
+ """
617
+ return self.codomain().ambient_space()._repr_generic_point(self._coords)
618
+
619
+ def _latex_(self):
620
+ """
621
+ Return a LaTeX representation of this point.
622
+
623
+ EXAMPLES::
624
+
625
+ sage: # needs database_cremona_mini_ellcurve
626
+ sage: E = EllipticCurve('40a')
627
+ sage: P = E([3, 0])
628
+ sage: P._latex_()
629
+ '\\left(3 : 0 : 1\\right)'
630
+ """
631
+ return self.codomain().ambient_space()._latex_generic_point(self._coords)
632
+
633
+ def __getitem__(self, n):
634
+ """
635
+ Return the n'th coordinate of this point.
636
+
637
+ EXAMPLES::
638
+
639
+ sage: # needs database_cremona_mini_ellcurve
640
+ sage: E = EllipticCurve('42a')
641
+ sage: P = E([-17, -51, 17])
642
+ sage: [P[i] for i in [2,1,0]]
643
+ [1, -3, -1]
644
+ """
645
+ return self._coords[n]
646
+
647
+ def __iter__(self):
648
+ """
649
+ Return the coordinates of this point as a list.
650
+
651
+ EXAMPLES::
652
+
653
+ sage: # needs database_cremona_mini_ellcurve
654
+ sage: E = EllipticCurve('37a')
655
+ sage: list(E([0,0]))
656
+ [0, 0, 1]
657
+ """
658
+ return iter(self._coords)
659
+
660
+ def __tuple__(self):
661
+ """
662
+ Return the coordinates of this point as a tuple.
663
+
664
+ EXAMPLES::
665
+
666
+ sage: # needs database_cremona_mini_ellcurve
667
+ sage: E = EllipticCurve('44a')
668
+ sage: P = E([1, -2, 1])
669
+ sage: P.__tuple__()
670
+ (1, -2, 1)
671
+ """
672
+ return tuple(self._coords) # Warning: _coords is a list!
673
+
674
+ def _richcmp_(self, other, op):
675
+ """
676
+ Comparison function for points to allow sorting and equality testing.
677
+
678
+ EXAMPLES::
679
+
680
+ sage: # needs database_cremona_mini_ellcurve
681
+ sage: E = EllipticCurve('45a')
682
+ sage: P = E([2, -1, 1])
683
+ sage: P == E(0)
684
+ False
685
+ sage: P+P == E(0)
686
+ True
687
+
688
+ The additive identity is always the minimum element::
689
+
690
+ sage: E = EllipticCurve(GF(103), [3, 5])
691
+ sage: min(E.points()) == 0
692
+ True
693
+ """
694
+ if not isinstance(other, EllipticCurvePoint_field):
695
+ try:
696
+ other = self.codomain().ambient_space()(other)
697
+ except TypeError:
698
+ return NotImplemented
699
+ # op_EQ
700
+ if op == 2:
701
+ return richcmp(self._coords, other._coords, op)
702
+
703
+ try:
704
+ return richcmp(self._zxy_coords, other._zxy_coords, op)
705
+ except AttributeError:
706
+ # Compute _zxy_coords
707
+ # There is a chance that we recompute this for either ``self`` or
708
+ # ``other`` However, in the most common use case which is sorting
709
+ # list of `n` variables This will cause a O(n) cost only. If there
710
+ # is a better way feel free to implement it!
711
+ self._zxy_coords = (self._coords[2], self._coords[0], self._coords[1])
712
+ other._zxy_coords = (other._coords[2], other._coords[0], other._coords[1])
713
+ return richcmp(self._zxy_coords, other._zxy_coords, op)
714
+
715
+ def __pari__(self):
716
+ r"""
717
+ Convert this point to PARI format.
718
+
719
+ EXAMPLES::
720
+
721
+ sage: E = EllipticCurve([0,0,0,3,0])
722
+ sage: O = E(0)
723
+ sage: P = E.point([1,2])
724
+ sage: O.__pari__()
725
+ [0]
726
+ sage: P.__pari__()
727
+ [1, 2]
728
+
729
+ The following implicitly calls O.__pari__() and P.__pari__()::
730
+
731
+ sage: pari(E).elladd(O,P)
732
+ [1, 2]
733
+
734
+ TESTS:
735
+
736
+ Try the same over a finite field::
737
+
738
+ sage: E = EllipticCurve(GF(11), [0,0,0,3,0])
739
+ sage: O = E(0)
740
+ sage: P = E.point([1,2])
741
+ sage: O.__pari__()
742
+ [0]
743
+ sage: P.__pari__()
744
+ [Mod(1, 11), Mod(2, 11)]
745
+
746
+ We no longer need to explicitly call ``pari(O)`` and ``pari(P)``
747
+ after :issue:`11868`::
748
+
749
+ sage: pari(E).elladd(O, P)
750
+ [Mod(1, 11), Mod(2, 11)]
751
+ """
752
+ x,y,z = self._coords
753
+ if z:
754
+ return pari([x/z, y/z])
755
+ else:
756
+ return pari([0])
757
+
758
+ def order(self, algorithm=None):
759
+ r"""
760
+ Return the order of this point on the elliptic curve.
761
+
762
+ If the point is zero, returns 1, otherwise raise a
763
+ :exc:`NotImplementedError`.
764
+
765
+ For curves over number fields and finite fields, see
766
+ :meth:`EllipticCurvePoint_number_field.order` and
767
+ :meth:`EllipticCurvePoint_finite_field.order` respectively.
768
+
769
+ .. NOTE::
770
+
771
+ :meth:`additive_order` is a synonym for :meth:`order`
772
+
773
+ INPUT:
774
+
775
+ - ``algorithm`` -- string (default: ``None``) -- the algorithm to use,
776
+ can be ``'pari'``, ``'generic'``, ``'generic_small'`` or ``'hybrid'``.
777
+ ``'generic_small'`` may be preferable when the order of the point
778
+ is very small compared to the order of the torsion,
779
+ and the order of the torsion is hard to factorize.
780
+ ``'hybrid'`` uses a combination of ``'pari'`` and ``'generic_small'``
781
+ to ensure the complexity of computing the order is
782
+ roughly the square root of the order, and that it is still fast
783
+ if the order only have very small prime factors.
784
+
785
+ EXAMPLES::
786
+
787
+ sage: K.<t> = FractionField(PolynomialRing(QQ,'t'))
788
+ sage: E = EllipticCurve([0, 0, 0, -t^2, 0])
789
+ sage: P = E(t,0)
790
+ sage: P.order()
791
+ Traceback (most recent call last):
792
+ ...
793
+ NotImplementedError: default algorithm not available...
794
+ sage: E(0).additive_order()
795
+ 1
796
+ sage: E(0).order() == 1
797
+ True
798
+ """
799
+ if hasattr(self, "_order"):
800
+ return self._order
801
+ if self.is_zero():
802
+ self._order = Integer(1)
803
+ return self._order
804
+ self._order = self._compute_order(algorithm)
805
+ return self._order
806
+
807
+ def _compute_order(self, algorithm):
808
+ """
809
+ Internal method to compute the order of this point. Used by :meth:`order`.
810
+ Subclasses may override this method. ``self`` is guaranteed to be nonzero.
811
+ The implementation of :meth:`order` takes care of the :meth:`is_zero` case and
812
+ caching of :attr:`_order`.
813
+
814
+ TESTS::
815
+
816
+ sage: K.<t> = FractionField(PolynomialRing(QQ,'t'))
817
+ sage: E = EllipticCurve([0, 0, 0, -t^2, 0])
818
+ sage: P = E(t,0)
819
+ sage: P._compute_order(algorithm='generic_small')
820
+ 2
821
+ sage: P._compute_order(algorithm=None)
822
+ Traceback (most recent call last):
823
+ ...
824
+ NotImplementedError: default algorithm not available...
825
+ """
826
+ if algorithm == 'generic_small':
827
+ return generic.order_from_bounds(self, None)
828
+ elif algorithm == 'hybrid':
829
+ lb = 1
830
+ sqrt_ub = 32
831
+ N = None
832
+ while True:
833
+ if N is None and sqrt_ub >= 5000:
834
+ N = self.curve().order()
835
+ if isinstance(N, Integer):
836
+ factorization = N.factor(limit=sqrt_ub)
837
+ if factorization.is_complete_factorization():
838
+ return self._compute_order(algorithm='pari')
839
+ try:
840
+ ub = sqrt_ub**2
841
+ return generic.order_from_bounds(self, (lb, ub))
842
+ except ValueError:
843
+ lb = ub + 1
844
+ sqrt_ub *= 4
845
+ elif algorithm is None:
846
+ raise NotImplementedError(
847
+ "default algorithm not available for order of a point on "
848
+ "an elliptic curve over general fields; you may try algorithm=generic_small "
849
+ "if you are sure the order is finite and small")
850
+ raise NotImplementedError(f"algorithm {algorithm!r} not implemented for "
851
+ "order of a point on an elliptic curve over general fields")
852
+
853
+ additive_order = order
854
+
855
+ def __bool__(self) -> bool:
856
+ """
857
+ Return ``True`` if this is not the zero point on the curve.
858
+
859
+ EXAMPLES::
860
+
861
+ sage: # needs database_cremona_mini_ellcurve
862
+ sage: E = EllipticCurve('37a')
863
+ sage: P = E(0); P
864
+ (0 : 1 : 0)
865
+ sage: P.is_zero()
866
+ True
867
+ sage: P = E.gens()[0] # needs eclib
868
+ sage: P.is_zero() # needs eclib
869
+ False
870
+ """
871
+ return bool(self._coords[2])
872
+
873
+ def has_order(self, n) -> bool:
874
+ r"""
875
+ Test if this point has order exactly `n`.
876
+
877
+ INPUT:
878
+
879
+ - ``n`` -- integer or its :class:`~sage.structure.factorization.Factorization`
880
+
881
+ ALGORITHM:
882
+
883
+ Compare a cached order if available, otherwise use :func:`sage.groups.generic.has_order`.
884
+
885
+ EXAMPLES::
886
+
887
+ sage: # needs database_cremona_mini_ellcurve
888
+ sage: E = EllipticCurve('26b1')
889
+ sage: P = E(1, 0)
890
+ sage: P.has_order(7)
891
+ True
892
+ sage: P._order
893
+ 7
894
+ sage: P.has_order(7)
895
+ True
896
+
897
+ It also works with a :class:`~sage.structure.factorization.Factorization` object::
898
+
899
+ sage: E = EllipticCurve(GF(419), [1,0])
900
+ sage: P = E(-33, 8)
901
+ sage: P.has_order(factor(21))
902
+ True
903
+ sage: P._order
904
+ 21
905
+ sage: P.has_order(factor(21))
906
+ True
907
+
908
+ This method can be much faster than computing the order and comparing::
909
+
910
+ sage: # not tested -- timings are different each time
911
+ sage: p = 4 * prod(primes(3,377)) * 587 - 1
912
+ sage: E = EllipticCurve(GF(p), [1,0])
913
+ sage: %timeit P = E.random_point(); P.set_order(multiple=p+1)
914
+ 72.4 ms ± 773 µs per loop (mean ± std. dev. of 7 runs, 1 loop each)
915
+ sage: %timeit P = E.random_point(); P.has_order(p+1)
916
+ 32.8 ms ± 3.12 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)
917
+ sage: fac = factor(p+1)
918
+ sage: %timeit P = E.random_point(); P.has_order(fac)
919
+ 30.6 ms ± 3.48 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)
920
+
921
+ The order is cached once it has been confirmed once, and the cache is
922
+ shared with :meth:`order`::
923
+
924
+ sage: # not tested -- timings are different each time
925
+ sage: P, = E.gens()
926
+ sage: delattr(P, '_order')
927
+ sage: %time P.has_order(p+1)
928
+ CPU times: user 83.6 ms, sys: 30 µs, total: 83.6 ms
929
+ Wall time: 83.8 ms
930
+ True
931
+ sage: %time P.has_order(p+1)
932
+ CPU times: user 31 µs, sys: 2 µs, total: 33 µs
933
+ Wall time: 37.9 µs
934
+ True
935
+ sage: %time P.order()
936
+ CPU times: user 11 µs, sys: 0 ns, total: 11 µs
937
+ Wall time: 16 µs
938
+ 5326738796327623094747867617954605554069371494832722337612446642054009560026576537626892113026381253624626941643949444792662881241621373288942880288065660
939
+ sage: delattr(P, '_order')
940
+ sage: %time P.has_order(fac)
941
+ CPU times: user 68.6 ms, sys: 17 µs, total: 68.7 ms
942
+ Wall time: 68.7 ms
943
+ True
944
+ sage: %time P.has_order(fac)
945
+ CPU times: user 92 µs, sys: 0 ns, total: 92 µs
946
+ Wall time: 97.5 µs
947
+ True
948
+ sage: %time P.order()
949
+ CPU times: user 10 µs, sys: 1e+03 ns, total: 11 µs
950
+ Wall time: 14.5 µs
951
+ 5326738796327623094747867617954605554069371494832722337612446642054009560026576537626892113026381253624626941643949444792662881241621373288942880288065660
952
+
953
+ TESTS::
954
+
955
+ sage: E = EllipticCurve([1,2,3,4,5])
956
+ sage: E(0).has_order(1)
957
+ True
958
+ sage: E(0).has_order(Factorization([]))
959
+ True
960
+ """
961
+ if hasattr(self, '_order'): # already known
962
+ if not isinstance(n, Integer):
963
+ n = n.value()
964
+ return self._order == n
965
+ ret = generic.has_order(self, n, operation='+')
966
+ if ret and not hasattr(self, '_order'): # known now; cache
967
+ if not isinstance(n, Integer):
968
+ n = n.value()
969
+ self._order = n
970
+ return ret
971
+
972
+ def has_finite_order(self) -> bool:
973
+ """
974
+ Return ``True`` if this point has finite additive order as an
975
+ element of the group of points on this curve.
976
+
977
+ For fields other than number fields and finite fields, this is
978
+ NotImplemented unless self.is_zero().
979
+
980
+ EXAMPLES::
981
+
982
+ sage: K.<t> = FractionField(PolynomialRing(QQ,'t'))
983
+ sage: E = EllipticCurve([0, 0, 0, -t^2, 0])
984
+ sage: P = E(0)
985
+ sage: P.has_finite_order()
986
+ True
987
+ sage: P = E(t,0)
988
+ sage: P.has_finite_order()
989
+ Traceback (most recent call last):
990
+ ...
991
+ NotImplementedError: default algorithm not available...
992
+ sage: (2*P).is_zero()
993
+ True
994
+ """
995
+ if self.is_zero():
996
+ return True
997
+ return self.order() != oo
998
+
999
+ is_finite_order = has_finite_order # for backward compatibility
1000
+
1001
+ def has_infinite_order(self) -> bool:
1002
+ """
1003
+ Return ``True`` if this point has infinite additive order as an element
1004
+ of the group of points on this curve.
1005
+
1006
+ For fields other than number fields and finite fields, this is
1007
+ NotImplemented unless ``self.is_zero()``.
1008
+
1009
+ EXAMPLES::
1010
+
1011
+ sage: K.<t> = FractionField(PolynomialRing(QQ,'t'))
1012
+ sage: E = EllipticCurve([0, 0, 0, -t^2, 0])
1013
+ sage: P = E(0)
1014
+ sage: P.has_infinite_order()
1015
+ False
1016
+ sage: P = E(t,0)
1017
+ sage: P.has_infinite_order()
1018
+ Traceback (most recent call last):
1019
+ ...
1020
+ NotImplementedError: default algorithm not available...
1021
+ sage: (2*P).is_zero()
1022
+ True
1023
+ """
1024
+ if self.is_zero():
1025
+ return False
1026
+ return self.order() == oo
1027
+
1028
+ def plot(self, **args):
1029
+ """
1030
+ Plot this point on an elliptic curve.
1031
+
1032
+ INPUT:
1033
+
1034
+ - ``**args`` -- all arguments get passed directly onto the point
1035
+ plotting function
1036
+
1037
+ EXAMPLES::
1038
+
1039
+ sage: # needs database_cremona_mini_ellcurve
1040
+ sage: E = EllipticCurve('389a')
1041
+ sage: P = E([-1,1])
1042
+ sage: P.plot(pointsize=30, rgbcolor=(1,0,0)) # needs sage.plot
1043
+ Graphics object consisting of 1 graphics primitive
1044
+ """
1045
+ from sage.plot.point import point
1046
+ from sage.plot.text import text
1047
+
1048
+ if self.is_zero():
1049
+ return text("$\\infty$", (-3, 3), **args)
1050
+ else:
1051
+ return point((self[0], self[1]), **args)
1052
+
1053
+ def _add_(self, other):
1054
+ r"""
1055
+ Add this point to another point on the same elliptic curve.
1056
+
1057
+ This method is specialized to elliptic curves over fields.
1058
+
1059
+ EXAMPLES::
1060
+
1061
+ sage: # needs database_cremona_mini_ellcurve
1062
+ sage: E = EllipticCurve('389a')
1063
+ sage: P = E([-1,1]); Q = E([0,0])
1064
+ sage: P + Q
1065
+ (1 : 0 : 1)
1066
+ sage: P._add_(Q) == P + Q
1067
+ True
1068
+
1069
+ TESTS:
1070
+
1071
+ Example to show that bug :issue:`4820` is fixed::
1072
+
1073
+ sage: # needs database_cremona_mini_ellcurve
1074
+ sage: [type(c) for c in 2*EllipticCurve('37a1').gen(0)] # needs eclib
1075
+ [<... 'sage.rings.rational.Rational'>,
1076
+ <... 'sage.rings.rational.Rational'>,
1077
+ <... 'sage.rings.rational.Rational'>]
1078
+
1079
+ Checks that :issue:`15964` is fixed::
1080
+
1081
+ sage: N = 1715761513
1082
+ sage: E = EllipticCurve(Integers(N), [3,-13])
1083
+ sage: E.assume_base_ring_is_field()
1084
+ sage: P = E(2,1)
1085
+ sage: LCM([2..60])*P
1086
+ Traceback (most recent call last):
1087
+ ...
1088
+ ZeroDivisionError: Inverse of 26927 does not exist
1089
+ (characteristic = 1715761513 = 26927*63719)
1090
+
1091
+ sage: N = 35
1092
+ sage: E = EllipticCurve(Integers(N), [5,1])
1093
+ sage: E.assume_base_ring_is_field()
1094
+ sage: P = E(0,1)
1095
+ sage: 4*P
1096
+ Traceback (most recent call last):
1097
+ ...
1098
+ ZeroDivisionError: Inverse of 7 does not exist
1099
+ (characteristic = 35 = 7*5)
1100
+
1101
+ Checks that :issue:`34681` is fixed::
1102
+
1103
+ sage: P+P
1104
+ (15 : 14 : 1)
1105
+ sage: 2*P
1106
+ (15 : 14 : 1)
1107
+ """
1108
+ # Use Prop 7.1.7 of Cohen "A Course in Computational Algebraic Number Theory"
1109
+
1110
+ if self.is_zero():
1111
+ return other
1112
+ if other.is_zero():
1113
+ return self
1114
+
1115
+ E = self.curve()
1116
+ a1, a2, a3, a4, a6 = E.ainvs()
1117
+ x1, y1 = self.xy()
1118
+ x2, y2 = other.xy()
1119
+
1120
+ if x1 == x2 and y1 == -y2 - a1*x2 - a3:
1121
+ return E(0) # point at infinity
1122
+
1123
+ try:
1124
+ if x1 == x2 and y1 == y2:
1125
+ m = (3*x1*x1 + 2*a2*x1 + a4 - a1*y1) / (2*y1 + a1*x1 + a3)
1126
+ else:
1127
+ m = (y1 - y2) / (x1 - x2)
1128
+ except ZeroDivisionError as ex:
1129
+ try:
1130
+ d = next(d for d in (x1 - x2, 2*y1 + a1*x1 + a3) if d and not d.is_unit())
1131
+ m, = d.parent().defining_ideal().gens()
1132
+ f1 = d.lift().gcd(m)
1133
+ f2 = m // f1
1134
+ assert m == f1 * f2
1135
+ except Exception:
1136
+ raise ex
1137
+ else:
1138
+ raise ZeroDivisionError(f'Inverse of {d} does not exist (characteristic = {m} = {f1}*{f2})')
1139
+
1140
+ x3 = -x1 - x2 - a2 + m*(m+a1)
1141
+ y3 = -y1 - a3 - a1*x3 + m*(x1-x3)
1142
+ # See trac #4820 for why we need to coerce 1 into the base ring here:
1143
+ return E.point([x3, y3, E.base_ring().one()], check=False)
1144
+
1145
+ _sub_ = EllipticCurvePoint._sub_
1146
+
1147
+ def _neg_(self):
1148
+ """
1149
+ Return the additive inverse of this point.
1150
+
1151
+ Same as :meth:`EllipticCurvePoint._neg_`, but specialized
1152
+ to points over fields, which are normalized to satisfy `z=1`.
1153
+
1154
+ EXAMPLES::
1155
+
1156
+ sage: # needs database_cremona_mini_ellcurve
1157
+ sage: E = EllipticCurve('389a')
1158
+ sage: P = E([-1,1])
1159
+ sage: Q = -P; Q
1160
+ (-1 : -2 : 1)
1161
+ sage: Q + P
1162
+ (0 : 1 : 0)
1163
+
1164
+ Example to show that bug :issue:`4820` is fixed::
1165
+
1166
+ sage: # needs database_cremona_mini_ellcurve
1167
+ sage: [type(c) for c in -EllipticCurve('37a1').gen(0)] # needs eclib
1168
+ [<... 'sage.rings.rational.Rational'>,
1169
+ <... 'sage.rings.rational.Rational'>,
1170
+ <... 'sage.rings.rational.Rational'>]
1171
+ """
1172
+ if self.is_zero():
1173
+ return self
1174
+ E, x, y = self.curve(), self[0], self[1]
1175
+ # See trac #4820 for why we need to coerce 1 into the base ring here:
1176
+ return E.point([x, -y - E.a1()*x - E.a3(), E.base_ring().one()], check=False)
1177
+
1178
+ def xy(self):
1179
+ """
1180
+ Return the `x` and `y` coordinates of this point, as a 2-tuple.
1181
+ If this is the point at infinity, a :exc:`ZeroDivisionError` is raised.
1182
+
1183
+ EXAMPLES::
1184
+
1185
+ sage: # needs database_cremona_mini_ellcurve
1186
+ sage: E = EllipticCurve('389a')
1187
+ sage: P = E([-1,1])
1188
+ sage: P.xy()
1189
+ (-1, 1)
1190
+ sage: Q = E(0); Q
1191
+ (0 : 1 : 0)
1192
+ sage: Q.xy()
1193
+ Traceback (most recent call last):
1194
+ ...
1195
+ ZeroDivisionError: rational division by zero
1196
+ """
1197
+ if self[2].is_one():
1198
+ return self[0], self[1]
1199
+ else:
1200
+ return self[0]/self[2], self[1]/self[2]
1201
+
1202
+ def x(self):
1203
+ """
1204
+ Return the `x` coordinate of this point, as an element of the base field.
1205
+ If this is the point at infinity, a :exc:`ZeroDivisionError` is raised.
1206
+
1207
+ EXAMPLES::
1208
+
1209
+ sage: # needs database_cremona_mini_ellcurve
1210
+ sage: E = EllipticCurve('389a')
1211
+ sage: P = E([-1,1])
1212
+ sage: P.x()
1213
+ -1
1214
+ sage: Q = E(0); Q
1215
+ (0 : 1 : 0)
1216
+ sage: Q.x()
1217
+ Traceback (most recent call last):
1218
+ ...
1219
+ ZeroDivisionError: rational division by zero
1220
+ """
1221
+ if self[2].is_one():
1222
+ return self[0]
1223
+ else:
1224
+ return self[0]/self[2]
1225
+
1226
+ def y(self):
1227
+ """
1228
+ Return the `y` coordinate of this point, as an element of the base field.
1229
+ If this is the point at infinity, a :exc:`ZeroDivisionError` is raised.
1230
+
1231
+ EXAMPLES::
1232
+
1233
+ sage: # needs database_cremona_mini_ellcurve
1234
+ sage: E = EllipticCurve('389a')
1235
+ sage: P = E([-1,1])
1236
+ sage: P.y()
1237
+ 1
1238
+ sage: Q = E(0); Q
1239
+ (0 : 1 : 0)
1240
+ sage: Q.y()
1241
+ Traceback (most recent call last):
1242
+ ...
1243
+ ZeroDivisionError: rational division by zero
1244
+ """
1245
+ if self[2].is_one():
1246
+ return self[1]
1247
+ else:
1248
+ return self[1]/self[2]
1249
+
1250
+ def is_divisible_by(self, m):
1251
+ """
1252
+ Return ``True`` if there exists a point `Q` defined over the same
1253
+ field as ``self`` such that `mQ` == ``self``.
1254
+
1255
+ INPUT:
1256
+
1257
+ - ``m`` -- positive integer
1258
+
1259
+ OUTPUT:
1260
+
1261
+ boolean; ``True`` if there is a solution, else False.
1262
+
1263
+ .. WARNING::
1264
+
1265
+ This function usually triggers the computation of the
1266
+ `m`-th division polynomial of the associated elliptic
1267
+ curve, which will be expensive if `m` is large, though it
1268
+ will be cached for subsequent calls with the same `m`.
1269
+
1270
+ EXAMPLES::
1271
+
1272
+ sage: # needs database_cremona_mini_ellcurve
1273
+ sage: E = EllipticCurve('389a')
1274
+ sage: Q = 5*E(0,0); Q
1275
+ (-2739/1444 : -77033/54872 : 1)
1276
+ sage: Q.is_divisible_by(4)
1277
+ False
1278
+ sage: Q.is_divisible_by(5)
1279
+ True
1280
+
1281
+ A finite field example::
1282
+
1283
+ sage: E = EllipticCurve(GF(101), [23,34])
1284
+ sage: E.cardinality().factor()
1285
+ 2 * 53
1286
+ sage: Set([T.order() for T in E.points()])
1287
+ {1, 106, 2, 53}
1288
+ sage: len([T for T in E.points() if T.is_divisible_by(2)])
1289
+ 53
1290
+ sage: len([T for T in E.points() if T.is_divisible_by(3)])
1291
+ 106
1292
+
1293
+ TESTS:
1294
+
1295
+ This shows that the bug reported at :issue:`10076` is fixed::
1296
+
1297
+ sage: # needs sage.rings.number_field
1298
+ sage: K = QuadraticField(8,'a')
1299
+ sage: E = EllipticCurve([K(0),0,0,-1,0])
1300
+ sage: P = E([-1,0])
1301
+ sage: P.is_divisible_by(2)
1302
+ False
1303
+ sage: P.division_points(2)
1304
+ []
1305
+
1306
+ Note that it is not sufficient to test that
1307
+ ``self.division_points(m,poly_only=True)`` has roots::
1308
+
1309
+ sage: P.division_points(2, poly_only=True).roots() # needs sage.rings.number_field
1310
+ [(1/2*a - 1, 1), (-1/2*a - 1, 1)]
1311
+
1312
+ sage: # needs sage.rings.number_field
1313
+ sage: tor = E.torsion_points(); len(tor)
1314
+ 8
1315
+ sage: [T.order() for T in tor]
1316
+ [1, 2, 4, 4, 2, 2, 4, 4]
1317
+ sage: all(T.is_divisible_by(3) for T in tor)
1318
+ True
1319
+ sage: sorted(T for T in tor if T.is_divisible_by(2))
1320
+ [(0 : 1 : 0), (1 : 0 : 1)]
1321
+ sage: sorted(Set([2*T for T in tor]))
1322
+ [(0 : 1 : 0), (1 : 0 : 1)]
1323
+ """
1324
+ # Coerce the input m to an integer
1325
+ m = Integer(m)
1326
+
1327
+ # Check for trivial cases of m = 1, -1 and 0.
1328
+ if m == 1 or m == -1:
1329
+ return True
1330
+ if m == 0:
1331
+ return self == 0 # then m*self=self for all m!
1332
+ m = m.abs()
1333
+
1334
+ # Now the following line would of course be correct, but we
1335
+ # work harder to be more efficient:
1336
+ # return len(self.division_points(m)) > 0
1337
+
1338
+ P = self
1339
+
1340
+ # If P has finite order n and gcd(m,n)=1 then the result is
1341
+ # True. However, over general fields computing P.order() is
1342
+ # not implemented.
1343
+
1344
+ try:
1345
+ n = P.order()
1346
+ if not n == oo:
1347
+ if m.gcd(n) == 1:
1348
+ return True
1349
+ except NotImplementedError:
1350
+ pass
1351
+
1352
+ P_is_2_torsion = (P == -P)
1353
+ g = P.division_points(m, poly_only=True)
1354
+
1355
+ if not P_is_2_torsion:
1356
+ # In this case deg(g)=m^2, and each root in K lifts to two
1357
+ # points Q,-Q both in E(K), of which exactly one is a
1358
+ # solution. So we just check the existence of roots:
1359
+ return len(g.roots()) > 0
1360
+
1361
+ # Now 2*P==0
1362
+
1363
+ if m % 2 == 1:
1364
+ return True # P itself is a solution when m is odd
1365
+
1366
+ # Now m is even and 2*P=0. Roots of g in K may or may not
1367
+ # lift to solutions in E(K), so we fall back to the default.
1368
+ # Note that division polynomials are cached so this is not
1369
+ # inefficient:
1370
+
1371
+ return len(self.division_points(m)) > 0
1372
+
1373
+ def division_points(self, m, poly_only=False):
1374
+ r"""
1375
+ Return a list of all points `Q` such that `mQ=P` where `P` = ``self``.
1376
+
1377
+ Only points on the elliptic curve containing ``self`` and defined
1378
+ over the base field are included.
1379
+
1380
+ INPUT:
1381
+
1382
+ - ``m`` -- positive integer
1383
+
1384
+ - ``poly_only`` -- boolean (default: ``False``); if ``True`` return
1385
+ polynomial whose roots give all possible `x`-coordinates of
1386
+ `m`-th roots of ``self``
1387
+
1388
+ OUTPUT: a (possibly empty) list of solutions `Q` to `mQ=P`,
1389
+ where `P` = ``self``
1390
+
1391
+ .. SEEALSO ::
1392
+
1393
+ :meth:`~sage.schemes.elliptic_curves.hom.EllipticCurveHom.inverse_image`
1394
+
1395
+ EXAMPLES:
1396
+
1397
+ We find the five 5-torsion points on an elliptic curve::
1398
+
1399
+ sage: # needs database_cremona_mini_ellcurve
1400
+ sage: E = EllipticCurve('11a'); E
1401
+ Elliptic Curve defined by y^2 + y = x^3 - x^2 - 10*x - 20 over Rational Field
1402
+ sage: P = E(0); P
1403
+ (0 : 1 : 0)
1404
+ sage: P.division_points(5)
1405
+ [(0 : 1 : 0), (5 : -6 : 1), (5 : 5 : 1), (16 : -61 : 1), (16 : 60 : 1)]
1406
+
1407
+ Note above that 0 is included since [5]*0 = 0.
1408
+
1409
+ We create a curve of rank 1 with no torsion and do a consistency check::
1410
+
1411
+ sage: # needs database_cremona_mini_ellcurve
1412
+ sage: E = EllipticCurve('11a').quadratic_twist(-7)
1413
+ sage: Q = E([44,-270])
1414
+ sage: (4*Q).division_points(4)
1415
+ [(44 : -270 : 1)]
1416
+
1417
+ We create a curve over a non-prime finite field with group of
1418
+ order `18`::
1419
+
1420
+ sage: # needs sage.rings.finite_rings
1421
+ sage: k.<a> = GF((5,2))
1422
+ sage: E = EllipticCurve(k, [1,2+a,3,4*a,2])
1423
+ sage: P = E([3, 3*a+4])
1424
+ sage: factor(E.order())
1425
+ 2 * 3^2
1426
+ sage: P.order()
1427
+ 9
1428
+
1429
+ We find the `1`-division points as a consistency check -- there
1430
+ is just one, of course::
1431
+
1432
+ sage: P.division_points(1) # needs sage.rings.finite_rings
1433
+ [(3 : 3*a + 4 : 1)]
1434
+
1435
+ The point `P` has order coprime to 2 but divisible by 3, so::
1436
+
1437
+ sage: P.division_points(2) # needs sage.rings.finite_rings
1438
+ [(2*a + 1 : 3*a + 4 : 1), (3*a + 1 : a : 1)]
1439
+
1440
+ We check that each of the 2-division points works as claimed::
1441
+
1442
+ sage: [2*Q for Q in P.division_points(2)] # needs sage.rings.finite_rings
1443
+ [(3 : 3*a + 4 : 1), (3 : 3*a + 4 : 1)]
1444
+
1445
+ Some other checks::
1446
+
1447
+ sage: P.division_points(3) # needs sage.rings.finite_rings
1448
+ []
1449
+ sage: P.division_points(4) # needs sage.rings.finite_rings
1450
+ [(0 : 3*a + 2 : 1), (1 : 0 : 1)]
1451
+ sage: P.division_points(5) # needs sage.rings.finite_rings
1452
+ [(1 : 1 : 1)]
1453
+
1454
+ An example over a number field (see :issue:`3383`)::
1455
+
1456
+ sage: # needs database_cremona_mini_ellcurve sage.rings.number_field
1457
+ sage: E = EllipticCurve('19a1')
1458
+ sage: x = polygen(ZZ, 'x')
1459
+ sage: K.<t> = NumberField(x^9 - 3*x^8 - 4*x^7 + 16*x^6 - 3*x^5
1460
+ ....: - 21*x^4 + 5*x^3 + 7*x^2 - 7*x + 1)
1461
+ sage: EK = E.base_extend(K)
1462
+ sage: E(0).division_points(3)
1463
+ [(0 : 1 : 0), (5 : -10 : 1), (5 : 9 : 1)]
1464
+ sage: EK(0).division_points(3)
1465
+ [(0 : 1 : 0), (5 : 9 : 1), (5 : -10 : 1)]
1466
+ sage: E(0).division_points(9)
1467
+ [(0 : 1 : 0), (5 : -10 : 1), (5 : 9 : 1)]
1468
+ sage: EK(0).division_points(9)
1469
+ [(0 : 1 : 0), (5 : 9 : 1), (5 : -10 : 1), (-150/121*t^8 + 414/121*t^7 + 1481/242*t^6 - 2382/121*t^5 - 103/242*t^4 + 629/22*t^3 - 367/242*t^2 - 1307/121*t + 625/121 : 35/484*t^8 - 133/242*t^7 + 445/242*t^6 - 799/242*t^5 + 373/484*t^4 + 113/22*t^3 - 2355/484*t^2 - 753/242*t + 1165/484 : 1), (-150/121*t^8 + 414/121*t^7 + 1481/242*t^6 - 2382/121*t^5 - 103/242*t^4 + 629/22*t^3 - 367/242*t^2 - 1307/121*t + 625/121 : -35/484*t^8 + 133/242*t^7 - 445/242*t^6 + 799/242*t^5 - 373/484*t^4 - 113/22*t^3 + 2355/484*t^2 + 753/242*t - 1649/484 : 1), (-1383/484*t^8 + 970/121*t^7 + 3159/242*t^6 - 5211/121*t^5 + 37/484*t^4 + 654/11*t^3 - 909/484*t^2 - 4831/242*t + 6791/484 : 927/121*t^8 - 5209/242*t^7 - 8187/242*t^6 + 27975/242*t^5 - 1147/242*t^4 - 1729/11*t^3 + 1566/121*t^2 + 12873/242*t - 10871/242 : 1), (-1383/484*t^8 + 970/121*t^7 + 3159/242*t^6 - 5211/121*t^5 + 37/484*t^4 + 654/11*t^3 - 909/484*t^2 - 4831/242*t + 6791/484 : -927/121*t^8 + 5209/242*t^7 + 8187/242*t^6 - 27975/242*t^5 + 1147/242*t^4 + 1729/11*t^3 - 1566/121*t^2 - 12873/242*t + 10629/242 : 1), (-4793/484*t^8 + 6791/242*t^7 + 10727/242*t^6 - 18301/121*t^5 + 2347/484*t^4 + 2293/11*t^3 - 7311/484*t^2 - 17239/242*t + 26767/484 : 30847/484*t^8 - 21789/121*t^7 - 34605/121*t^6 + 117164/121*t^5 - 10633/484*t^4 - 29437/22*t^3 + 39725/484*t^2 + 55428/121*t - 176909/484 : 1), (-4793/484*t^8 + 6791/242*t^7 + 10727/242*t^6 - 18301/121*t^5 + 2347/484*t^4 + 2293/11*t^3 - 7311/484*t^2 - 17239/242*t + 26767/484 : -30847/484*t^8 + 21789/121*t^7 + 34605/121*t^6 - 117164/121*t^5 + 10633/484*t^4 + 29437/22*t^3 - 39725/484*t^2 - 55428/121*t + 176425/484 : 1)]
1470
+
1471
+ TESTS:
1472
+
1473
+ Check that :issue:`24844` is fixed::
1474
+
1475
+ sage: # needs sage.rings.finite_rings
1476
+ sage: p = next_prime(1000000)
1477
+ sage: E = EllipticCurve(GF(p), 123, 456)
1478
+ sage: pts = E(0).division_points(3)
1479
+ sage: P = pts[1]; P
1480
+ (389063 : 124244 : 1)
1481
+ sage: P._order
1482
+ 3
1483
+
1484
+ When we successfully divide a point known to have infinite
1485
+ order, the points returned know that they also have infinite
1486
+ order::
1487
+
1488
+ sage: E = EllipticCurve([0,0,1,-1,0])
1489
+ sage: P = E(-1,0)
1490
+ sage: P.order()
1491
+ +Infinity
1492
+ sage: pts = P.division_points(3); len(pts)
1493
+ 1
1494
+ sage: [(Q,Q._order) for Q in pts]
1495
+ [((0 : -1 : 1), +Infinity)]
1496
+
1497
+ When we successfully divide a point of known finite order `n`,
1498
+ the points returned know that they also have finite order `nk`
1499
+ for some divisor `k` of `m`::
1500
+
1501
+ sage: E = EllipticCurve([1, 0, 1, -19, 26])
1502
+ sage: [(Q,Q._order) for Q in E(0).division_points(12)]
1503
+ [((0 : 1 : 0), 1),
1504
+ ((-5 : 2 : 1), 2),
1505
+ ((-2 : -7 : 1), 6),
1506
+ ((-2 : 8 : 1), 6),
1507
+ ((1 : -4 : 1), 6),
1508
+ ((1 : 2 : 1), 6),
1509
+ ((7/4 : -11/8 : 1), 2),
1510
+ ((3 : -2 : 1), 2),
1511
+ ((4 : -7 : 1), 3),
1512
+ ((4 : 2 : 1), 3),
1513
+ ((13 : -52 : 1), 6),
1514
+ ((13 : 38 : 1), 6)]
1515
+ sage: P = E(4,-7)
1516
+ sage: P.order()
1517
+ 3
1518
+ sage: [(Q,Q._order) for Q in P.division_points(4)]
1519
+ [((-2 : -7 : 1), 6), ((1 : 2 : 1), 6), ((4 : -7 : 1), 3), ((13 : 38 : 1), 6)]
1520
+
1521
+ Check for :issue:`38796`::
1522
+
1523
+ sage: E = EllipticCurve(GF(127), [1,1])
1524
+ sage: P = E(72, 24)
1525
+ sage: [-1*Q for Q in P.division_points(-1)]
1526
+ [(72 : 24 : 1)]
1527
+ """
1528
+ # Coerce the input m to an integer
1529
+ m = Integer(m)
1530
+ # Check for trivial cases of m = 1, -1 and 0.
1531
+ if m == 1 or m == -1:
1532
+ return [m*self]
1533
+ if m == 0:
1534
+ if self == 0: # then every point Q is a solution, but...
1535
+ return [self]
1536
+ else:
1537
+ return []
1538
+
1539
+ # ans will contain the list of division points.
1540
+ ans = []
1541
+
1542
+ # We compute a polynomial g whose roots give all possible x
1543
+ # coordinates of the m-division points. The number of
1544
+ # solutions (over the algebraic closure) is m^2, assuming that
1545
+ # the characteristic does not divide m.
1546
+
1547
+ E = self.curve()
1548
+ P = self
1549
+ nP = -P
1550
+ P_is_2_torsion = (P == nP)
1551
+
1552
+ # If self is the 0, then self is a solution, and the correct
1553
+ # poly is the m'th division polynomial
1554
+ if P == 0:
1555
+ ans.append(P)
1556
+ g = E.division_polynomial(m)
1557
+ else:
1558
+ # The poly g here is 0 at x(Q) iff x(m*Q) = x(P).
1559
+ g = E._multiple_x_numerator(m) - P[0]*E._multiple_x_denominator(m)
1560
+
1561
+ # When 2*P=0, then -Q is a solution iff Q is. For even m,
1562
+ # no 2-torsion point is a solution, so that g is the
1563
+ # square of a polynomial g1 of degree m^2/2, and each root
1564
+ # of g1 leads to a pair of solutions Q, -Q to m*Q=P. For
1565
+ # odd m, P itself is the only 2-torsion solution, so g has
1566
+ # the form (x-x(P))*g1(x)^2 where g1 has degree (m^2-1)/2
1567
+ # and each root of g1 leads to a pair Q, -Q.
1568
+
1569
+ if P_is_2_torsion:
1570
+ if m % 2 == 0:
1571
+ # This computes g.sqrt() which is not implemented
1572
+ g = g.gcd(g.derivative())*g.leading_coefficient().sqrt()
1573
+
1574
+ # When 2*P!=0, then for each solution Q to m*Q=P, -Q is
1575
+ # not a solution (and points of order 2 are not
1576
+ # solutions). Hence the roots of g are distinct and each
1577
+ # gives rise to precisely one solution Q.
1578
+
1579
+ else:
1580
+ g0 = g.variables()[0] - P[0]
1581
+ g = g // g0
1582
+ g = g.gcd(g.derivative())*g.leading_coefficient().sqrt()
1583
+ g = g0*g
1584
+
1585
+ if poly_only:
1586
+ return g
1587
+
1588
+ for x in g.roots(multiplicities=False):
1589
+ if E.is_x_coord(x):
1590
+ # Make a point on the curve with this x coordinate.
1591
+ Q = E.lift_x(x)
1592
+ nQ = -Q
1593
+ mQ = m*Q
1594
+ # if P==-P then Q works iff -Q works, so we include
1595
+ # both unless they are equal:
1596
+ if P_is_2_torsion:
1597
+ if mQ == P:
1598
+ ans.append(Q)
1599
+ if nQ != Q:
1600
+ ans.append(nQ)
1601
+ else:
1602
+ # P is not 2-torsion so at most one of Q, -Q works
1603
+ # and we must try both:
1604
+ if mQ == P:
1605
+ ans.append(Q)
1606
+ elif mQ == nP:
1607
+ ans.append(nQ)
1608
+
1609
+ if not ans:
1610
+ return ans
1611
+
1612
+ # set orders of points found when self's order is known:
1613
+ if self.is_zero():
1614
+ self._order = Integer(1)
1615
+ try:
1616
+ n = self._order # do not compute, just use if already known
1617
+ if n == oo:
1618
+ for Q in ans:
1619
+ Q._order = oo
1620
+ else:
1621
+ mfac = m.factor()
1622
+ for Q in ans:
1623
+ R = n * Q
1624
+ Q._order = n * generic.order_from_multiple(R, m, factorization=mfac, operation='+')
1625
+ except AttributeError: # do nothing about order if self's order unknown
1626
+ pass
1627
+
1628
+ # Finally, sort and return
1629
+ ans.sort()
1630
+ return ans
1631
+
1632
+ def _divide_out(self, p):
1633
+ r"""
1634
+ Return `(Q,k)` where `p^kQ` == ``self`` and `Q` cannot be divided by `p`.
1635
+
1636
+ .. WARNING::
1637
+
1638
+ It is up to the caller to make sure that this does not loop
1639
+ endlessly. It is used in
1640
+ ``EllipticCurve_generic._p_primary_torsion_basis()``, when
1641
+ ``self`` will always have (finite) order which is a power of `p`,
1642
+ so that the order of `Q` increases by a factor of `p` at each
1643
+ stage.
1644
+
1645
+ Since it will clearly be in danger of looping when
1646
+ ``self.is_zero()``, this case is caught, but otherwise caveat user.
1647
+
1648
+ EXAMPLES::
1649
+
1650
+ sage: # needs database_cremona_mini_ellcurve
1651
+ sage: E = EllipticCurve('37a1')
1652
+ sage: P = E([0, 0])
1653
+ sage: R = 12*P
1654
+ sage: R._divide_out(2)
1655
+ ((-1 : -1 : 1), 2)
1656
+ sage: R._divide_out(3)
1657
+ ((2 : -3 : 1), 1)
1658
+ sage: R._divide_out(5)
1659
+ ((1357/841 : 28888/24389 : 1), 0)
1660
+ sage: R._divide_out(12)
1661
+ Traceback (most recent call last):
1662
+ ...
1663
+ ValueError: p (=12) should be prime.
1664
+ """
1665
+ p = Integer(p)
1666
+ if not p.is_prime():
1667
+ raise ValueError("p (=%s) should be prime." % p)
1668
+
1669
+ if self.is_zero():
1670
+ raise ValueError("self must not be 0.")
1671
+
1672
+ k = 0
1673
+ Q = self
1674
+ pts = Q.division_points(p)
1675
+ while pts:
1676
+ Q = pts[0]
1677
+ k += 1
1678
+ pts = Q.division_points(p)
1679
+ return (Q, k)
1680
+
1681
+ def set_order(self, value=None, *, multiple=None, check=True):
1682
+ r"""
1683
+ Set the cached order of this point (i.e., the value of
1684
+ ``self._order``) to the given ``value``.
1685
+
1686
+ Alternatively, when ``multiple`` is given, this method will
1687
+ first run :func:`~sage.groups.generic.order_from_multiple`
1688
+ to determine the exact order from the given multiple of the
1689
+ point order, then cache the result.
1690
+
1691
+ Use this when you know a priori the order of this point, or
1692
+ a multiple of the order, to avoid a potentially expensive
1693
+ order calculation.
1694
+
1695
+ INPUT:
1696
+
1697
+ - ``value`` -- positive integer
1698
+ - ``multiple`` -- positive integer; mutually exclusive with ``value``
1699
+
1700
+ OUTPUT: none
1701
+
1702
+ EXAMPLES:
1703
+
1704
+ This example illustrates basic usage.
1705
+
1706
+ ::
1707
+
1708
+ sage: E = EllipticCurve(GF(7), [0, 1]) # This curve has order 12
1709
+ sage: G = E(5, 0)
1710
+ sage: G.set_order(2)
1711
+ sage: 2*G
1712
+ (0 : 1 : 0)
1713
+ sage: G = E(0, 6)
1714
+ sage: G.set_order(multiple=12)
1715
+ sage: G._order
1716
+ 3
1717
+
1718
+ We now give a more interesting case, the NIST-P521 curve. Its
1719
+ order is too big to calculate with Sage, and takes a long time
1720
+ using other packages, so it is very useful here.
1721
+
1722
+ ::
1723
+
1724
+ sage: # needs sage.rings.finite_rings
1725
+ sage: p = 2^521 - 1
1726
+ sage: prev_proof_state = proof.arithmetic()
1727
+ sage: proof.arithmetic(False) # turn off primality checking
1728
+ sage: F = GF(p)
1729
+ sage: A = p - 3
1730
+ sage: B = 1093849038073734274511112390766805569936207598951683748994586394495953116150735016013708737573759623248592132296706313309438452531591012912142327488478985984
1731
+ sage: q = 6864797660130609714981900799081393217269435300143305409394463459185543183397655394245057746333217197532963996371363321113864768612440380340372808892707005449
1732
+ sage: E = EllipticCurve([F(A), F(B)])
1733
+ sage: G = E.random_point()
1734
+ sage: G.set_order(q)
1735
+ sage: G.order() * G # This takes practically no time.
1736
+ (0 : 1 : 0)
1737
+ sage: proof.arithmetic(prev_proof_state) # restore state
1738
+
1739
+ Using ``.set_order()`` with a ``multiple=`` argument can
1740
+ be used to compute a point's order *significantly* faster
1741
+ than calling :meth:`order` if the point is already known
1742
+ to be `m`-torsion::
1743
+
1744
+ sage: F.<a> = GF((10007, 23))
1745
+ sage: E = EllipticCurve(F, [9,9])
1746
+ sage: n = E.order()
1747
+ sage: m = 5 * 47 * 139 * 1427 * 2027 * 4831 * 275449 * 29523031
1748
+ sage: assert m.divides(n)
1749
+ sage: P = n/m * E.lift_x(6747+a)
1750
+ sage: assert m * P == 0
1751
+ sage: P.set_order(multiple=m) # compute exact order
1752
+ sage: factor(m // P.order()) # order is now cached
1753
+ 47 * 139
1754
+
1755
+ The algorithm used internally for this functionality is
1756
+ :meth:`~sage.groups.generic.order_from_multiple`.
1757
+ Indeed, simply calling :meth:`order` on ``P`` would take
1758
+ much longer since factoring ``n`` is fairly expensive::
1759
+
1760
+ sage: n == m * 6670822796985115651 * 441770032618665681677 * 9289973478285634606114927
1761
+ True
1762
+
1763
+ It is an error to pass a ``value`` equal to `0`::
1764
+
1765
+ sage: # needs sage.rings.finite_rings
1766
+ sage: E = EllipticCurve(GF(7), [0, 1]) # This curve has order 12
1767
+ sage: G = E.random_point()
1768
+ sage: G.set_order(0)
1769
+ Traceback (most recent call last):
1770
+ ...
1771
+ ValueError: Value 0 illegal for point order
1772
+ sage: G.set_order(1000)
1773
+ Traceback (most recent call last):
1774
+ ...
1775
+ ValueError: Value 1000 illegal: outside max Hasse bound
1776
+
1777
+ It is also very likely an error to pass a value which is not the actual
1778
+ order of this point. How unlikely is determined by the factorization of
1779
+ the actual order, and the actual group structure::
1780
+
1781
+ sage: E = EllipticCurve(GF(7), [0, 1]) # This curve has order 12
1782
+ sage: G = E(5, 0) # G has order 2
1783
+ sage: G.set_order(11)
1784
+ Traceback (most recent call last):
1785
+ ...
1786
+ ValueError: Value 11 illegal: 11 * (5 : 0 : 1) is not the identity
1787
+
1788
+ However, ``set_order`` can be fooled. For instance, the order
1789
+ can be set to a multiple the actual order::
1790
+
1791
+ sage: E = EllipticCurve(GF(7), [0, 1]) # This curve has order 12
1792
+ sage: G = E(5, 0) # G has order 2
1793
+ sage: G.set_order(8)
1794
+ sage: G.order()
1795
+ 8
1796
+
1797
+ TESTS:
1798
+
1799
+ Check that some invalid inputs are caught::
1800
+
1801
+ sage: E = EllipticCurve(GF(101), [5,5])
1802
+ sage: P = E.lift_x(11)
1803
+ sage: P.set_order(17, multiple=119)
1804
+ Traceback (most recent call last):
1805
+ ...
1806
+ ValueError: cannot pass both value and multiple
1807
+ sage: P.set_order(17)
1808
+ sage: P.set_order(multiple=119+1)
1809
+ Traceback (most recent call last):
1810
+ ...
1811
+ ValueError: previously cached order 17 does not divide given multiple 120
1812
+ sage: P.set_order(119)
1813
+ Traceback (most recent call last):
1814
+ ...
1815
+ ValueError: value 119 contradicts previously cached order 17
1816
+
1817
+ AUTHORS:
1818
+
1819
+ - Mariah Lenox (2011-02-16)
1820
+ - Lorenz Panny (2022): add ``multiple=`` option
1821
+ """
1822
+ if multiple is not None:
1823
+ if value is not None:
1824
+ raise ValueError('cannot pass both value and multiple')
1825
+
1826
+ if hasattr(self, '_order'): # already known
1827
+ if check and not self._order.divides(multiple):
1828
+ raise ValueError(f'previously cached order {self._order} does not divide given multiple {multiple}')
1829
+ return
1830
+
1831
+ from sage.groups.generic import order_from_multiple
1832
+ value = order_from_multiple(self, multiple, check=check)
1833
+ check = False
1834
+
1835
+ value = Integer(value)
1836
+
1837
+ if check:
1838
+ if value <= 0:
1839
+ raise ValueError('Value %s illegal for point order' % value)
1840
+ E = self.curve()
1841
+ q = E.base_ring().cardinality()
1842
+ if q < oo:
1843
+ _, hi = Hasse_bounds(q)
1844
+ if value > hi:
1845
+ raise ValueError('Value %s illegal: outside max Hasse bound' % value)
1846
+ if value * self != E(0):
1847
+ raise ValueError('Value %s illegal: %s * %s is not the identity' % (value, value, self))
1848
+ if hasattr(self, '_order') and self._order != value: # already known
1849
+ raise ValueError(f'value {value} contradicts previously cached order {self._order}')
1850
+
1851
+ self._order = value
1852
+
1853
+ # ############################# end ################################
1854
+
1855
+ def _line_(self, R, Q):
1856
+ r"""
1857
+ Compute the value at `Q` of a straight line through points
1858
+ ``self`` and `R`.
1859
+
1860
+ INPUT:
1861
+
1862
+ - ``R``, ``Q`` -- points on ``self.curve()`` with `Q` nonzero
1863
+
1864
+ OUTPUT:
1865
+
1866
+ An element of the base field ``self.curve().base_field()``.
1867
+ A :exc:`ValueError` is raised if `Q` is zero.
1868
+
1869
+ EXAMPLES::
1870
+
1871
+ sage: # needs sage.rings.finite_rings
1872
+ sage: F.<a> = GF((2,5))
1873
+ sage: E = EllipticCurve(F,[0,0,1,1,1])
1874
+ sage: P = E(a^4 + 1, a^3)
1875
+ sage: Q = E(a^4, a^4 + a^3)
1876
+ sage: O = E(0)
1877
+ sage: P._line_(P,-2*P) == 0
1878
+ True
1879
+ sage: P._line_(Q,-(P+Q)) == 0
1880
+ True
1881
+ sage: O._line_(O,Q) == F(1)
1882
+ True
1883
+ sage: P._line_(O,Q) == a^4 - a^4 + 1
1884
+ True
1885
+ sage: P._line_(13*P,Q) == a^4
1886
+ True
1887
+ sage: P._line_(P,Q) == a^4 + a^3 + a^2 + 1
1888
+ True
1889
+
1890
+ See :issue:`7116`::
1891
+
1892
+ sage: P._line_(Q, O) # needs sage.rings.finite_rings
1893
+ Traceback (most recent call last):
1894
+ ...
1895
+ ValueError: Q must be nonzero.
1896
+
1897
+ .. NOTE::
1898
+
1899
+ This function is used in _miller_ algorithm.
1900
+
1901
+ AUTHORS:
1902
+
1903
+ - David Hansen (2009-01-25)
1904
+ """
1905
+ if Q.is_zero():
1906
+ raise ValueError("Q must be nonzero.")
1907
+
1908
+ if self.is_zero() or R.is_zero():
1909
+ if self == R:
1910
+ return self.curve().base_field().one()
1911
+ if self.is_zero():
1912
+ return Q[0] - R[0]
1913
+ if R.is_zero():
1914
+ return Q[0] - self[0]
1915
+ elif self != R:
1916
+ if self[0] == R[0]:
1917
+ return Q[0] - self[0]
1918
+ else:
1919
+ l = (R[1] - self[1])/(R[0] - self[0])
1920
+ return Q[1] - self[1] - l * (Q[0] - self[0])
1921
+ else:
1922
+ a1, a2, a3, a4, a6 = self.curve().a_invariants()
1923
+ numerator = (3*self[0]**2 + 2*a2*self[0] + a4 - a1*self[1])
1924
+ denominator = (2*self[1] + a1*self[0] + a3)
1925
+ if denominator == 0:
1926
+ return Q[0] - self[0]
1927
+ else:
1928
+ l = numerator/denominator
1929
+ return Q[1] - self[1] - l * (Q[0] - self[0])
1930
+
1931
+ def _miller_(self, Q, n):
1932
+ r"""
1933
+ Return the value at `Q` of the rational function `f_{n,P}`, where the
1934
+ divisor of `f_{n,P}` is `n[P]-[nP]-(n-1)[O]`.
1935
+
1936
+ INPUT:
1937
+
1938
+ - ``Q`` -- a nonzero point on ``self.curve()``
1939
+
1940
+ - ``n`` -- nonzero integer; if `n<0` then return `Q`
1941
+ evaluated at `1/(v_{nP}*f_{n,P})` (used in the ate pairing)
1942
+
1943
+ OUTPUT:
1944
+
1945
+ An element in the base field ``self.curve().base_field()``.
1946
+ A :exc:`ValueError` is raised if `Q` is zero.
1947
+
1948
+ EXAMPLES::
1949
+
1950
+ sage: # needs sage.rings.finite_rings
1951
+ sage: F.<a> = GF((2,5))
1952
+ sage: E = EllipticCurve(F, [0,0,1,1,1])
1953
+ sage: P = E(a^4 + 1, a^3)
1954
+ sage: Fx.<b> = GF((2,(4*5)))
1955
+ sage: Ex = EllipticCurve(Fx, [0,0,1,1,1])
1956
+ sage: phi = Hom(F,Fx)(F.gen().minpoly().roots(Fx)[0][0])
1957
+ sage: Px = Ex(phi(P.x()), phi(P.y()))
1958
+ sage: Qx = Ex(b^19 + b^18 + b^16 + b^12 + b^10 + b^9 + b^8 + b^5 + b^3 + 1,
1959
+ ....: b^18 + b^13 + b^10 + b^8 + b^5 + b^4 + b^3 + b)
1960
+ sage: Px._miller_(Qx,41) == b^17 + b^13 + b^12 + b^9 + b^8 + b^6 + b^4 + 1
1961
+ True
1962
+ sage: Qx._miller_(Px,41) == b^13 + b^10 + b^8 + b^7 + b^6 + b^5
1963
+ True
1964
+ sage: P._miller_(E(0),41)
1965
+ Traceback (most recent call last):
1966
+ ...
1967
+ ValueError: Q must be nonzero.
1968
+
1969
+ An example of even order::
1970
+
1971
+ sage: # needs sage.rings.finite_rings
1972
+ sage: F.<a> = GF((19,4))
1973
+ sage: E = EllipticCurve(F, [-1,0])
1974
+ sage: P = E(15*a^3 + 17*a^2 + 14*a + 13,16*a^3 + 7*a^2 + a + 18)
1975
+ sage: Q = E(10*a^3 + 16*a^2 + 4*a + 2, 6*a^3 + 4*a^2 + 3*a + 2)
1976
+ sage: x = P.weil_pairing(Q, 360)
1977
+ sage: x^360 == F(1)
1978
+ True
1979
+
1980
+ You can use the _miller_ function on linearly dependent
1981
+ points, but with the risk of a dividing with zero::
1982
+
1983
+ sage: Px._miller_(2*Px, 41) # needs sage.rings.finite_rings
1984
+ Traceback (most recent call last):
1985
+ ...
1986
+ ZeroDivisionError: division by zero in finite field
1987
+
1988
+ A small example of embedding degree 6::
1989
+
1990
+ sage: # needs sage.rings.finite_rings
1991
+ sage: q = 401; F = GF(q); a = 146; b = 400; k = 6
1992
+ sage: E = EllipticCurve([F(a), F(b)])
1993
+ sage: R.<x> = F[]
1994
+ sage: K.<a> = GF(q^k, modulus=x^6 + 4*x^4 + 115*x^3 + 81*x^2 + 51*x + 3)
1995
+ sage: EK = E.base_extend(K)
1996
+ sage: P = E([F(338), F(227)])
1997
+ sage: Q_x = 333*a^5 + 391*a^4 + 160*a^3 + 335*a^2 + 71*a + 93
1998
+ sage: Q_y = 343*a^5 + 273*a^4 + 26*a^3 + 342*a^2 + 340*a + 210
1999
+ sage: Q = EK([Q_x, Q_y])
2000
+ sage: P._miller_(Q, 127)
2001
+ 371*a^5 + 39*a^4 + 355*a^3 + 233*a^2 + 20*a + 275
2002
+
2003
+ A series of small examples and small torsions. We start with
2004
+ `n=1`, which is trivial: the function is the constant
2005
+ 1::
2006
+
2007
+ sage: E = EllipticCurve([GF(7)(0), 2])
2008
+ sage: P = E(5, 1); Q = E(0, 3); I = E(0)
2009
+ sage: I._miller_(P, 1)
2010
+ 1
2011
+ sage: I._miller_(Q, 1)
2012
+ 1
2013
+
2014
+ A two-torsion example. In this case `f_{n,P}(Q) = x_Q - x_P`::
2015
+
2016
+ sage: E = EllipticCurve([GF(7)(-1), 0])
2017
+ sage: P = E(0,0); Q = E(1, 0);
2018
+ sage: P._miller_(P, 2)
2019
+ 0
2020
+ sage: Q._miller_(Q, 2)
2021
+ 0
2022
+ sage: P._miller_(Q, 2)
2023
+ 1
2024
+ sage: Q._miller_(P, 2)
2025
+ 6
2026
+
2027
+ A three-torsion example::
2028
+
2029
+ sage: E = EllipticCurve([GF(7)(0), 2])
2030
+ sage: P = E(5, 1); Q = E(0, 3);
2031
+ sage: P._miller_(Q, 3)
2032
+ 4
2033
+
2034
+ A 4-torsion example::
2035
+
2036
+ sage: E = EllipticCurve([GF(7)(-1), 0])
2037
+ sage: P = E(5, 1); Q = E(4, 2)
2038
+ sage: P._miller_(Q, 4)
2039
+ 3
2040
+
2041
+ A 5-torsion example::
2042
+
2043
+ sage: E = EllipticCurve([GF(7)(-1), 4])
2044
+ sage: P = E(4, 1); Q = E(6, 5)
2045
+ sage: P._miller_(Q, 5)
2046
+ 1
2047
+
2048
+ A 6-torsion example::
2049
+
2050
+ sage: E = EllipticCurve([GF(7)(3), 1])
2051
+ sage: P = E(5, 1); Q = E(3, 3)
2052
+ sage: P._miller_(Q, 6)
2053
+ 5
2054
+
2055
+ An example which is part of an ate pairing calculation. The trace of
2056
+ the curve is negative, so it should exercise the `n<0` case in the
2057
+ code::
2058
+
2059
+ sage: # needs sage.rings.finite_rings
2060
+ sage: p = 2017; A = 1; B = 30; r = 29; t = -70; k = 7
2061
+ sage: F = GF(p); R.<x> = F[]
2062
+ sage: E = EllipticCurve([F(A), F(B)]); P = E(369, 716)
2063
+ sage: K.<a> = GF(p^k, modulus=x^k+2); EK = E.base_extend(K)
2064
+ sage: Qx = 1226*a^6 + 1778*a^5 + 660*a^4 + 1791*a^3 + 1750*a^2 + 867*a + 770
2065
+ sage: Qy = 1764*a^6 + 198*a^5 + 1206*a^4 + 406*a^3 + 1200*a^2 + 273*a + 1712
2066
+ sage: Q = EK(Qx, Qy)
2067
+ sage: Q._miller_(P, t - 1)
2068
+ 1311*a^6 + 1362*a^5 + 1177*a^4 + 807*a^3 + 1331*a^2 + 1530*a + 1931
2069
+
2070
+ ALGORITHM:
2071
+
2072
+ Double-and-add. See also [Mil2004]_.
2073
+
2074
+ AUTHORS:
2075
+
2076
+ - David Hansen (2009-01-25)
2077
+ - Mariah Lenox (2011-03-07) -- Added more doctests and support for
2078
+ negative n.
2079
+ """
2080
+ if Q.is_zero():
2081
+ raise ValueError("Q must be nonzero.")
2082
+ if n.is_zero():
2083
+ raise ValueError("n must be nonzero.")
2084
+ n_is_negative = False
2085
+ if n < 0:
2086
+ n = n.abs()
2087
+ n_is_negative = True
2088
+
2089
+ one = self.curve().base_field().one()
2090
+ t = one
2091
+ V = self
2092
+ nbin = n.bits()
2093
+ i = n.nbits() - 2
2094
+ while i > -1:
2095
+ S = 2*V
2096
+ ell = V._line_(V, Q)
2097
+ vee = S._line_(-S, Q)
2098
+ t = (t**2)*(ell/vee)
2099
+ V = S
2100
+ if nbin[i] == 1:
2101
+ S = V+self
2102
+ ell = V._line_(self, Q)
2103
+ vee = S._line_(-S, Q)
2104
+ t = t*(ell/vee)
2105
+ V = S
2106
+ i = i-1
2107
+ if n_is_negative:
2108
+ vee = V._line_(-V, Q)
2109
+ t = 1/(t*vee)
2110
+ return t
2111
+
2112
+ def weil_pairing(self, Q, n, algorithm=None):
2113
+ r"""
2114
+ Compute the Weil pairing of this point with another point `Q`
2115
+ on the same curve.
2116
+
2117
+ INPUT:
2118
+
2119
+ - ``Q`` -- another point on the same curve as ``self``
2120
+
2121
+ - ``n`` -- integer `n` such that `nP = nQ = (0:1:0)`, where
2122
+ `P` is ``self``
2123
+
2124
+ - ``algorithm`` -- (default: ``None``) choices are ``'pari'``
2125
+ and ``'sage'``. PARI is usually significantly faster, but it
2126
+ only works over finite fields. When ``None`` is given, a
2127
+ suitable algorithm is chosen automatically.
2128
+
2129
+ OUTPUT: an `n`-th root of unity in the base field of the curve
2130
+
2131
+ EXAMPLES::
2132
+
2133
+ sage: # needs sage.rings.finite_rings
2134
+ sage: F.<a> = GF((2,5))
2135
+ sage: E = EllipticCurve(F, [0,0,1,1,1])
2136
+ sage: P = E(a^4 + 1, a^3)
2137
+ sage: Fx.<b> = GF((2, 4*5))
2138
+ sage: Ex = EllipticCurve(Fx, [0,0,1,1,1])
2139
+ sage: phi = Hom(F, Fx)(F.gen().minpoly().roots(Fx)[0][0])
2140
+ sage: Px = Ex(phi(P.x()), phi(P.y()))
2141
+ sage: O = Ex(0)
2142
+ sage: Qx = Ex(b^19 + b^18 + b^16 + b^12 + b^10 + b^9 + b^8 + b^5 + b^3 + 1,
2143
+ ....: b^18 + b^13 + b^10 + b^8 + b^5 + b^4 + b^3 + b)
2144
+ sage: Px.weil_pairing(Qx, 41) == b^19 + b^15 + b^9 + b^8 + b^6 + b^4 + b^3 + b^2 + 1
2145
+ True
2146
+ sage: Px.weil_pairing(17*Px, 41) == Fx(1)
2147
+ True
2148
+ sage: Px.weil_pairing(O, 41) == Fx(1)
2149
+ True
2150
+
2151
+ An error is raised if either point is not `n`-torsion::
2152
+
2153
+ sage: Px.weil_pairing(O, 40) # needs sage.rings.finite_rings
2154
+ Traceback (most recent call last):
2155
+ ...
2156
+ ValueError: points must both be n-torsion
2157
+
2158
+ A larger example (see :issue:`4964`)::
2159
+
2160
+ sage: # needs sage.rings.finite_rings
2161
+ sage: P, Q = EllipticCurve(GF((19,4),'a'), [-1,0]).gens()
2162
+ sage: P.order(), Q.order()
2163
+ (360, 360)
2164
+ sage: z = P.weil_pairing(Q, 360)
2165
+ sage: z.multiplicative_order()
2166
+ 360
2167
+
2168
+ Another larger example::
2169
+
2170
+ sage: F = GF(65537^2, modulus=[3,-1,1], name='a')
2171
+ sage: F.inject_variables()
2172
+ Defining a
2173
+ sage: E = EllipticCurve(F, [0,1])
2174
+ sage: P = E(22, 28891)
2175
+ sage: Q = E(-93, 2728*a + 64173)
2176
+ sage: P.weil_pairing(Q, 7282, algorithm='sage')
2177
+ 53278*a + 36700
2178
+
2179
+ An example over a number field::
2180
+
2181
+ sage: # needs database_cremona_mini_ellcurve sage.rings.number_field
2182
+ sage: E = EllipticCurve('11a1').change_ring(CyclotomicField(5))
2183
+ sage: P, Q = E.torsion_subgroup().gens()
2184
+ sage: P, Q = (P.element(), Q.element())
2185
+ sage: (P.order(), Q.order())
2186
+ (5, 5)
2187
+ sage: P.weil_pairing(Q, 5)
2188
+ zeta5^2
2189
+ sage: Q.weil_pairing(P, 5)
2190
+ zeta5^3
2191
+
2192
+ TESTS:
2193
+
2194
+ Check that the original Sage implementation still works and
2195
+ that the result coincides with the PARI implementation::
2196
+
2197
+ sage: # needs sage.rings.finite_rings
2198
+ sage: GF(65537^2).inject_variables()
2199
+ Defining z2
2200
+ sage: E = EllipticCurve(GF(65537^2), [0,1])
2201
+ sage: R, S = E.torsion_basis(7282)
2202
+ sage: a, b = ZZ.random_element(), ZZ.random_element()
2203
+ sage: P = a*R + b*S
2204
+ sage: c, d = ZZ.random_element(), ZZ.random_element()
2205
+ sage: Q = c*R + d*S
2206
+ sage: P.weil_pairing(Q, 7282, algorithm='sage') == P.weil_pairing(Q, 7282, algorithm='pari')
2207
+ True
2208
+
2209
+ Passing an unknown ``algorithm=`` argument should fail::
2210
+
2211
+ sage: P.weil_pairing(Q, 7282, algorithm='_invalid_') # needs sage.rings.finite_rings
2212
+ Traceback (most recent call last):
2213
+ ...
2214
+ ValueError: unknown algorithm
2215
+
2216
+ ALGORITHM:
2217
+
2218
+ - For ``algorithm='pari'``: :pari:`ellweilpairing`.
2219
+
2220
+ - For ``algorithm='sage'``:
2221
+ Implemented using Proposition 8 in [Mil2004]_. The value 1 is
2222
+ returned for linearly dependent input points. This condition
2223
+ is caught via a :exc:`ZeroDivisionError`, since the use of a
2224
+ discrete logarithm test for linear dependence is much too slow
2225
+ for large `n`.
2226
+
2227
+ AUTHORS:
2228
+
2229
+ - David Hansen (2009-01-25)
2230
+ - Lorenz Panny (2022): ``algorithm='pari'``
2231
+ """
2232
+ P = self
2233
+ E = P.curve()
2234
+
2235
+ if Q.curve() is not E:
2236
+ raise ValueError("points must both be on the same curve")
2237
+
2238
+ if algorithm is None:
2239
+ if E.base_field().is_finite():
2240
+ algorithm = 'pari'
2241
+ else:
2242
+ algorithm = 'sage'
2243
+
2244
+ if algorithm == 'pari':
2245
+ if pari.ellmul(E,P,n) != [0] or pari.ellmul(E,Q,n) != [0]:
2246
+ raise ValueError("points must both be n-torsion")
2247
+ return E.base_field()(pari.ellweilpairing(E, P, Q, n))
2248
+
2249
+ if algorithm != 'sage':
2250
+ raise ValueError('unknown algorithm')
2251
+
2252
+ # Test if P, Q are both in E[n]
2253
+ if n*P or n*Q:
2254
+ raise ValueError("points must both be n-torsion")
2255
+
2256
+ one = E.base_field().one()
2257
+
2258
+ # Case where P = Q
2259
+ if P == Q:
2260
+ return one
2261
+
2262
+ # Case where P = O or Q = O
2263
+ if P.is_zero() or Q.is_zero():
2264
+ return one
2265
+
2266
+ # The non-trivial case P != Q
2267
+
2268
+ # Note (2010-12-29): The following code block should not be
2269
+ # used. It attempts to reduce the pairing calculation to order
2270
+ # d = gcd(|P|,|Q|) instead of order n, but this approach is
2271
+ # counterproductive, since calculating |P| and |Q| is much
2272
+ # slower than calculating the pairing [BGN05].
2273
+ #
2274
+ # [BGN05] D. Boneh, E. Goh, and K. Nissim, "Evaluating 2-DNF
2275
+ # Formulas on Ciphertexts", TCC 2005, LNCS 3378, pp. 325-341.
2276
+ #
2277
+ # Reduction to order d = gcd(|P|,|Q|); value is a d'th root of unity
2278
+ # try:
2279
+ # nP = P.order()
2280
+ # except AttributeError:
2281
+ # nP = generic.order_from_multiple(P,n,operation='+')
2282
+ # try:
2283
+ # nQ = Q.order()
2284
+ # except AttributeError:
2285
+ # nQ = generic.order_from_multiple(Q,n,operation='+')
2286
+ # d = arith.gcd(nP,nQ)
2287
+ # if d==1:
2288
+ # return one
2289
+ #
2290
+ # P = (nP//d)*P # order d
2291
+ # Q = (nQ//d)*Q # order d
2292
+ # n = d
2293
+
2294
+ try:
2295
+ return ((-1)**n.test_bit(0))*(P._miller_(Q, n)/Q._miller_(P, n))
2296
+ except ZeroDivisionError:
2297
+ return one
2298
+
2299
+ def tate_pairing(self, Q, n, k, q=None):
2300
+ r"""
2301
+ Return Tate pairing of `n`-torsion point `P = self` and point `Q`.
2302
+
2303
+ The value returned is `f_{n,P}(Q)^e` where `f_{n,P}` is a function with
2304
+ divisor `n[P]-n[O].`. This is also known as the "modified Tate
2305
+ pairing". It is a well-defined bilinear map.
2306
+
2307
+ INPUT:
2308
+
2309
+ - ``P=self`` -- elliptic curve point having order `n`
2310
+
2311
+ - ``Q`` -- elliptic curve point on same curve as `P` (can be any order)
2312
+
2313
+ - ``n`` -- positive integer; order of `P`
2314
+
2315
+ - ``k`` -- positive integer; embedding degree
2316
+
2317
+ - ``q`` -- positive integer; size of base field (the "big"
2318
+ field is `GF(q^k)`. `q` needs to be set only if its value
2319
+ cannot be deduced.)
2320
+
2321
+ OUTPUT:
2322
+
2323
+ An `n`-th root of unity in the base field ``self.curve().base_field()``.
2324
+
2325
+ EXAMPLES:
2326
+
2327
+ A simple example, pairing a point with itself, and pairing a point with
2328
+ another rational point::
2329
+
2330
+ sage: p = 103; A = 1; B = 18; E = EllipticCurve(GF(p), [A, B])
2331
+ sage: P = E(33, 91); n = P.order(); n
2332
+ 19
2333
+ sage: k = GF(n)(p).multiplicative_order(); k
2334
+ 6
2335
+ sage: P.tate_pairing(P, n, k)
2336
+ 1
2337
+ sage: Q = E(87, 51)
2338
+ sage: P.tate_pairing(Q, n, k)
2339
+ 1
2340
+ sage: set_random_seed(35)
2341
+ sage: P.tate_pairing(P, n, k)
2342
+ 1
2343
+
2344
+ We now let `Q` be a point on the same curve as above, but defined over
2345
+ the pairing extension field, and we also demonstrate the bilinearity of
2346
+ the pairing::
2347
+
2348
+ sage: # needs sage.rings.finite_rings
2349
+ sage: K.<a> = GF((p,k))
2350
+ sage: EK = E.base_extend(K); P = EK(P)
2351
+ sage: Qx = 69*a^5 + 96*a^4 + 22*a^3 + 86*a^2 + 6*a + 35
2352
+ sage: Qy = 34*a^5 + 24*a^4 + 16*a^3 + 41*a^2 + 4*a + 40
2353
+ sage: Q = EK(Qx, Qy);
2354
+
2355
+ Multiply by cofactor so Q has order n::
2356
+
2357
+ sage: # needs sage.rings.finite_rings
2358
+ sage: h = 551269674; Q = h*Q
2359
+ sage: P = EK(P); P.tate_pairing(Q, n, k)
2360
+ 24*a^5 + 34*a^4 + 3*a^3 + 69*a^2 + 86*a + 45
2361
+ sage: s = Integer(randrange(1,n))
2362
+ sage: ans1 = (s*P).tate_pairing(Q, n, k)
2363
+ sage: ans2 = P.tate_pairing(s*Q, n, k)
2364
+ sage: ans3 = P.tate_pairing(Q, n, k)^s
2365
+ sage: ans1 == ans2 == ans3
2366
+ True
2367
+ sage: (ans1 != 1) and (ans1^n == 1)
2368
+ True
2369
+
2370
+ Here is an example of using the Tate pairing to compute the Weil
2371
+ pairing (using the same data as above)::
2372
+
2373
+ sage: # needs sage.rings.finite_rings
2374
+ sage: e = Integer((p^k-1)/n); e
2375
+ 62844857712
2376
+ sage: P.weil_pairing(Q, n)^e
2377
+ 94*a^5 + 99*a^4 + 29*a^3 + 45*a^2 + 57*a + 34
2378
+ sage: P.tate_pairing(Q, n, k) == P._miller_(Q, n)^e
2379
+ True
2380
+ sage: Q.tate_pairing(P, n, k) == Q._miller_(P, n)^e
2381
+ True
2382
+ sage: P.tate_pairing(Q, n, k)/Q.tate_pairing(P, n, k)
2383
+ 94*a^5 + 99*a^4 + 29*a^3 + 45*a^2 + 57*a + 34
2384
+
2385
+ An example where we have to pass the base field size (and we again have
2386
+ agreement with the Weil pairing)::
2387
+
2388
+ sage: # needs sage.rings.finite_rings
2389
+ sage: F.<a> = GF((2,5))
2390
+ sage: E = EllipticCurve(F, [0,0,1,1,1])
2391
+ sage: P = E(a^4 + 1, a^3)
2392
+ sage: Fx.<b> = GF((2,4*5))
2393
+ sage: Ex = EllipticCurve(Fx,[0,0,1,1,1])
2394
+ sage: phi = Hom(F, Fx)(F.gen().minpoly().roots(Fx)[0][0])
2395
+ sage: Px = Ex(phi(P.x()), phi(P.y()))
2396
+ sage: Qx = Ex(b^19 + b^18 + b^16 + b^12 + b^10 + b^9 + b^8 + b^5 + b^3 + 1,
2397
+ ....: b^18 + b^13 + b^10 + b^8 + b^5 + b^4 + b^3 + b)
2398
+ sage: Px.tate_pairing(Qx, n=41, k=4)
2399
+ Traceback (most recent call last):
2400
+ ...
2401
+ ValueError: Unexpected field degree: set keyword argument q equal to
2402
+ the size of the base field (big field is GF(q^4)).
2403
+ sage: num = Px.tate_pairing(Qx, n=41, k=4, q=32); num
2404
+ b^19 + b^14 + b^13 + b^12 + b^6 + b^4 + b^3
2405
+ sage: den = Qx.tate_pairing(Px, n=41, k=4, q=32); den
2406
+ b^19 + b^17 + b^16 + b^15 + b^14 + b^10 + b^6 + b^2 + 1
2407
+ sage: e = Integer((32^4-1)/41); e
2408
+ 25575
2409
+ sage: Px.weil_pairing(Qx, 41)^e == num/den
2410
+ True
2411
+
2412
+ An example over a large base field::
2413
+
2414
+ sage: F = GF(65537^2, modulus=[3,46810,1], name='z2')
2415
+ sage: F.inject_variables()
2416
+ Defining z2
2417
+ sage: E = EllipticCurve(F, [0,1])
2418
+ sage: P = E(22, 28891)
2419
+ sage: Q = E(-93, 40438*z2 + 31573)
2420
+ sage: P.tate_pairing(Q, 7282, 2)
2421
+ 34585*z2 + 4063
2422
+
2423
+ TESTS:
2424
+
2425
+ The point ``P (self)`` must have ``n`` torsion::
2426
+
2427
+ sage: P.tate_pairing(Q, 163, 2)
2428
+ Traceback (most recent call last):
2429
+ ...
2430
+ ValueError: The point P must be n-torsion
2431
+
2432
+ We must have that ``n`` divides ``q^k - 1``, this is only checked when q is supplied::
2433
+
2434
+ sage: P.tate_pairing(Q, 7282, 2, q=123)
2435
+ Traceback (most recent call last):
2436
+ ...
2437
+ ValueError: n does not divide (q^k - 1) for the supplied value of q
2438
+
2439
+ The Tate pairing is only defined for points on curves defined over finite fields::
2440
+
2441
+ sage: E = EllipticCurve([0,1])
2442
+ sage: P = E(2,3)
2443
+ sage: P.tate_pairing(P, 6, 1)
2444
+ Traceback (most recent call last):
2445
+ ...
2446
+ NotImplementedError: Reduced Tate pairing is currently only implemented for finite fields
2447
+
2448
+ Test Issue #40764 is solved::
2449
+
2450
+ sage: p = 886368969471450739924935101400677
2451
+ sage: a = 26392827536965106777121445123290
2452
+ sage: b = 372325368096095544195525883520589
2453
+ sage: n = 886368969471450710152985728350703
2454
+ sage: K = GF(p)
2455
+ sage: K3.<u> = K.extension(K['x']([4, 1, 0, 1]))
2456
+ sage: K6.<t> = K3.extension(K3['x']([2, 0, 1]))
2457
+ sage: E = EllipticCurve(K, [a, b])
2458
+ sage: E6 = EllipticCurve(K6, [a, b])
2459
+ sage: xs = [856868015088199526146278020391084, 443540958770895237304916133834125, 394350320674188950754967186520706]
2460
+ sage: ys = [132025069108007720916581753555587, 11656262681159388373035244637826, 697338684369558801829591141320120]
2461
+ sage: G6 = E6(K3(xs) * t^-2, K3(ys) * t^-3)
2462
+ sage: G = E6((211525223196641227957134531065457, 59355916731390463777191161722550))
2463
+ sage: G.tate_pairing(G6, n, 6, q=p)
2464
+ (699432283102586243018242179516873*u^2 + 265571225406900742458432149860962*u + 701042518368651902930590425782509)*t + 802059826004050667481466713086225*u^2 + 178851543248946074944443141484182*u + 242940802691096077821709859741616
2465
+
2466
+ ALGORITHM:
2467
+
2468
+ - :pari:`elltatepairing` computes the
2469
+ non-reduced tate pairing and the exponentiation is handled by
2470
+ Sage using user input for `k` (and optionally `q`).
2471
+
2472
+ AUTHORS:
2473
+
2474
+ - Mariah Lenox (2011-03-07)
2475
+ - Giacomo Pope (2024): Use of PARI for the non-reduced Tate pairing
2476
+ """
2477
+ P = self
2478
+ E = P.curve()
2479
+
2480
+ if Q.curve() is not E:
2481
+ raise ValueError("Points must both be on the same curve")
2482
+
2483
+ K = E.base_ring()
2484
+ if not K.is_finite():
2485
+ raise NotImplementedError("Reduced Tate pairing is currently only implemented for finite fields")
2486
+
2487
+ d = K.degree()
2488
+ if q is None:
2489
+ if d == 1:
2490
+ q = K.order()
2491
+ elif d == k:
2492
+ q = K.base_ring().order()
2493
+ else:
2494
+ raise ValueError("Unexpected field degree: set keyword argument q equal to the size of the base field (big field is GF(q^%s))." % k)
2495
+ # The user has supplied q, so we check here that it's a sensible value
2496
+ elif Mod(q, n)**k != 1:
2497
+ raise ValueError("n does not divide (q^k - 1) for the supplied value of q")
2498
+
2499
+ if pari.ellmul(E, P, n) != [0]:
2500
+ raise ValueError("The point P must be n-torsion")
2501
+
2502
+ # NOTE: Pari `elltatepairing` only works with curves with
2503
+ # `ell_get_type()` equal to `t_ELL_Fp` or `t_ELL_Fq`, which
2504
+ # correspond to `EllipticCurve_finite_field`.
2505
+ if isinstance(E, sage.schemes.elliptic_curves.ell_finite_field.EllipticCurve_finite_field):
2506
+ # The value returned by `elltatepairing` is the raw Miller loop
2507
+ # output, so we still need to do the final exponentiation.
2508
+ ePQ = K(pari.elltatepairing(E, P, Q, n)) # Cast the PARI type back to the base ring
2509
+ else:
2510
+ # In small cases, or in the case of pairing an element with
2511
+ # itself, Q could be on one of the lines in the Miller
2512
+ # algorithm. If this happens we try again, with an offset of a
2513
+ # random point.
2514
+ try:
2515
+ ePQ = P._miller_(Q, n)
2516
+ except (ZeroDivisionError, ValueError):
2517
+ R = E.random_point()
2518
+ return self.tate_pairing(Q + R, n, k) / self.tate_pairing(R, n, k)
2519
+
2520
+ exp = Integer((q**k - 1)/n)
2521
+ return ePQ**exp
2522
+
2523
+ def ate_pairing(self, Q, n, k, t, q=None):
2524
+ r"""
2525
+ Return ate pairing of `n`-torsion points `P` (``=self``) and `Q`.
2526
+
2527
+ Also known as the `n`-th modified ate pairing. `P` is `GF(q)`-rational,
2528
+ and `Q` must be an element of `Ker(\pi-p)`, where `\pi` is the
2529
+ `q`-frobenius map (and hence `Q` is `GF(q^k)`-rational).
2530
+
2531
+ INPUT:
2532
+
2533
+ - ``P`` (``=self``) -- a point of order `n`, in `ker(\pi-1)`, where
2534
+ `\pi` is the `q`-Frobenius map (e.g., `P` is `q`-rational)
2535
+
2536
+ - ``Q`` -- a point of order `n` in `ker(\pi-q)`
2537
+
2538
+ - ``n`` -- the order of `P` and `Q`
2539
+
2540
+ - ``k`` -- the embedding degree
2541
+
2542
+ - ``t`` -- the trace of Frobenius of the curve over `GF(q)`
2543
+
2544
+ - ``q`` -- (default: ``None``) the size of base field (the "big"
2545
+ field is `GF(q^k)`). `q` needs to be set only if its value
2546
+ cannot be deduced.
2547
+
2548
+ OUTPUT:
2549
+
2550
+ FiniteFieldElement in `GF(q^k)` -- the ate pairing of `P` and `Q`.
2551
+
2552
+ EXAMPLES:
2553
+
2554
+ An example with embedding degree 6::
2555
+
2556
+ sage: # needs sage.rings.finite_rings
2557
+ sage: p = 7549; A = 0; B = 1; n = 157; k = 6; t = 14
2558
+ sage: F = GF(p); E = EllipticCurve(F, [A, B])
2559
+ sage: R.<x> = F[]; K.<a> = GF((p,k), modulus=x^k+2)
2560
+ sage: EK = E.base_extend(K)
2561
+ sage: P = EK(3050, 5371); Q = EK(6908*a^4, 3231*a^3)
2562
+ sage: P.ate_pairing(Q, n, k, t)
2563
+ 6708*a^5 + 4230*a^4 + 4350*a^3 + 2064*a^2 + 4022*a + 6733
2564
+ sage: s = Integer(randrange(1, n))
2565
+ sage: (s*P).ate_pairing(Q, n, k, t) == P.ate_pairing(s*Q, n, k, t)
2566
+ True
2567
+ sage: P.ate_pairing(s*Q, n, k, t) == P.ate_pairing(Q, n, k, t)^s
2568
+ True
2569
+
2570
+ Another example with embedding degree 7 and positive trace::
2571
+
2572
+ sage: # needs sage.rings.finite_rings
2573
+ sage: p = 2213; A = 1; B = 49; n = 1093; k = 7; t = 28
2574
+ sage: F = GF(p); E = EllipticCurve(F, [A, B])
2575
+ sage: R.<x> = F[]; K.<a> = GF((p,k), modulus=x^k+2)
2576
+ sage: EK = E.base_extend(K)
2577
+ sage: P = EK(1583, 1734)
2578
+ sage: Qx = 1729*a^6+1767*a^5+245*a^4+980*a^3+1592*a^2+1883*a+722
2579
+ sage: Qy = 1299*a^6+1877*a^5+1030*a^4+1513*a^3+1457*a^2+309*a+1636
2580
+ sage: Q = EK(Qx, Qy)
2581
+ sage: P.ate_pairing(Q, n, k, t)
2582
+ 1665*a^6 + 1538*a^5 + 1979*a^4 + 239*a^3 + 2134*a^2 + 2151*a + 654
2583
+ sage: s = Integer(randrange(1, n))
2584
+ sage: (s*P).ate_pairing(Q, n, k, t) == P.ate_pairing(s*Q, n, k, t)
2585
+ True
2586
+ sage: P.ate_pairing(s*Q, n, k, t) == P.ate_pairing(Q, n, k, t)^s
2587
+ True
2588
+
2589
+ Another example with embedding degree 7 and negative trace::
2590
+
2591
+ sage: # needs sage.rings.finite_rings
2592
+ sage: p = 2017; A = 1; B = 30; n = 29; k = 7; t = -70
2593
+ sage: F = GF(p); E = EllipticCurve(F, [A, B])
2594
+ sage: R.<x> = F[]; K.<a> = GF((p,k), modulus=x^k+2)
2595
+ sage: EK = E.base_extend(K)
2596
+ sage: P = EK(369, 716)
2597
+ sage: Qx = 1226*a^6+1778*a^5+660*a^4+1791*a^3+1750*a^2+867*a+770
2598
+ sage: Qy = 1764*a^6+198*a^5+1206*a^4+406*a^3+1200*a^2+273*a+1712
2599
+ sage: Q = EK(Qx, Qy)
2600
+ sage: P.ate_pairing(Q, n, k, t)
2601
+ 1794*a^6 + 1161*a^5 + 576*a^4 + 488*a^3 + 1950*a^2 + 1905*a + 1315
2602
+ sage: s = Integer(randrange(1, n))
2603
+ sage: (s*P).ate_pairing(Q, n, k, t) == P.ate_pairing(s*Q, n, k, t)
2604
+ True
2605
+ sage: P.ate_pairing(s*Q, n, k, t) == P.ate_pairing(Q, n, k, t)^s
2606
+ True
2607
+
2608
+ Using the same data, we show that the ate pairing is a power of the
2609
+ Tate pairing (see [HSV2006]_ end of section 3.1)::
2610
+
2611
+ sage: # needs sage.rings.finite_rings
2612
+ sage: c = (k*p^(k-1)).mod(n); T = t - 1
2613
+ sage: N = gcd(T^k - 1, p^k - 1)
2614
+ sage: s = Integer(N/n)
2615
+ sage: L = Integer((T^k - 1)/N)
2616
+ sage: M = (L*s*c.inverse_mod(n)).mod(n)
2617
+ sage: P.ate_pairing(Q, n, k, t) == Q.tate_pairing(P, n, k)^M
2618
+ True
2619
+
2620
+ An example where we have to pass the base field size (and we again have
2621
+ agreement with the Tate pairing). Note that though `Px` is not
2622
+ `F`-rational, (it is the homomorphic image of an `F`-rational point) it
2623
+ is nonetheless in `ker(\pi-1)`, and so is a legitimate input::
2624
+
2625
+ sage: # needs sage.rings.finite_rings
2626
+ sage: q = 2^5; F.<a> = GF(q)
2627
+ sage: n = 41; k = 4; t = -8
2628
+ sage: E = EllipticCurve(F,[0,0,1,1,1])
2629
+ sage: P = E(a^4 + 1, a^3)
2630
+ sage: Fx.<b> = GF(q^k)
2631
+ sage: Ex = EllipticCurve(Fx, [0,0,1,1,1])
2632
+ sage: phi = Hom(F, Fx)(F.gen().minpoly().roots(Fx)[0][0])
2633
+ sage: Px = Ex(phi(P.x()), phi(P.y()))
2634
+ sage: Qx = Ex(b^19+b^18+b^16+b^12+b^10+b^9+b^8+b^5+b^3+1,
2635
+ ....: b^18+b^13+b^10+b^8+b^5+b^4+b^3+b)
2636
+ sage: Qx = Ex(Qx[0]^q, Qx[1]^q) - Qx # ensure Qx is in ker(pi - q)
2637
+ sage: Px.ate_pairing(Qx, n, k, t)
2638
+ Traceback (most recent call last):
2639
+ ...
2640
+ ValueError: Unexpected field degree: set keyword argument q equal to
2641
+ the size of the base field (big field is GF(q^4)).
2642
+ sage: Px.ate_pairing(Qx, n, k, t, q)
2643
+ b^19 + b^18 + b^17 + b^16 + b^15 + b^14 + b^13 + b^12
2644
+ + b^11 + b^9 + b^8 + b^5 + b^4 + b^2 + b + 1
2645
+ sage: s = Integer(randrange(1, n))
2646
+ sage: (s*Px).ate_pairing(Qx, n, k, t, q) == Px.ate_pairing(s*Qx, n, k, t, q)
2647
+ True
2648
+ sage: Px.ate_pairing(s*Qx, n, k, t, q) == Px.ate_pairing(Qx, n, k, t, q)^s
2649
+ True
2650
+ sage: c = (k*q^(k-1)).mod(n); T = t - 1
2651
+ sage: N = gcd(T^k - 1, q^k - 1)
2652
+ sage: s = Integer(N/n)
2653
+ sage: L = Integer((T^k - 1)/N)
2654
+ sage: M = (L*s*c.inverse_mod(n)).mod(n)
2655
+ sage: Px.ate_pairing(Qx, n, k, t, q) == Qx.tate_pairing(Px, n, k, q)^M
2656
+ True
2657
+
2658
+ It is an error if `Q` is not in the kernel of `\pi - p`, where `\pi` is
2659
+ the Frobenius automorphism::
2660
+
2661
+ sage: # needs sage.rings.finite_rings
2662
+ sage: p = 29; A = 1; B = 0; n = 5; k = 2; t = 10
2663
+ sage: F = GF(p); R.<x> = F[]
2664
+ sage: E = EllipticCurve(F, [A, B]);
2665
+ sage: K.<a> = GF((p,k), modulus=x^k+2); EK = E.base_extend(K)
2666
+ sage: P = EK(13, 8); Q = EK(13, 21)
2667
+ sage: P.ate_pairing(Q, n, k, t)
2668
+ Traceback (most recent call last):
2669
+ ...
2670
+ ValueError: Point (13 : 21 : 1) not in Ker(pi - q)
2671
+
2672
+ It is also an error if `P` is not in the kernel os `\pi - 1`::
2673
+
2674
+ sage: # needs sage.rings.finite_rings
2675
+ sage: p = 29; A = 1; B = 0; n = 5; k = 2; t = 10
2676
+ sage: F = GF(p); R.<x> = F[]
2677
+ sage: E = EllipticCurve(F, [A, B]);
2678
+ sage: K.<a> = GF((p,k), modulus=x^k+2); EK = E.base_extend(K)
2679
+ sage: P = EK(14, 10*a); Q = EK(13, 21)
2680
+ sage: P.ate_pairing(Q, n, k, t)
2681
+ Traceback (most recent call last):
2682
+ ...
2683
+ ValueError: This point (14 : 10*a : 1) is not in Ker(pi - 1)
2684
+
2685
+ .. NOTE::
2686
+
2687
+ First defined in the paper of [HSV2006]_, the ate pairing
2688
+ can be computationally effective in those cases when the
2689
+ trace of the curve over the base field is significantly
2690
+ smaller than the expected value. This implementation is
2691
+ simply Miller's algorithm followed by a naive
2692
+ exponentiation, and makes no claims towards efficiency.
2693
+
2694
+ AUTHORS:
2695
+
2696
+ - Mariah Lenox (2011-03-08)
2697
+ """
2698
+ P = self
2699
+ # check for same curve
2700
+ E = P.curve()
2701
+ O = E(0)
2702
+ if Q.curve() is not E:
2703
+ raise ValueError("Points must both be on the same curve")
2704
+
2705
+ # set q to be the order of the base field
2706
+ K = E.base_ring()
2707
+ if q is None:
2708
+ d = K.degree()
2709
+ if d == k:
2710
+ q = K.base_ring().order()
2711
+ else:
2712
+ raise ValueError("Unexpected field degree: set keyword argument q equal to the size of the base field (big field is GF(q^%s))." % k)
2713
+
2714
+ # check order of P
2715
+ if n*P != O:
2716
+ raise ValueError('This point %s is not of order n=%s' % (P, n))
2717
+
2718
+ # check for P in kernel pi - 1:
2719
+ piP = E(P[0]**q, P[1]**q)
2720
+ if piP - P != O:
2721
+ raise ValueError('This point %s is not in Ker(pi - 1)' % P)
2722
+
2723
+ # check for Q in kernel pi - q:
2724
+ piQ = E(Q[0]**q, Q[1]**q)
2725
+ if piQ - q*Q != O:
2726
+ raise ValueError('Point %s not in Ker(pi - q)' % Q)
2727
+
2728
+ T = t-1
2729
+ ret = Q._miller_(P, T)
2730
+ e = Integer((q**k - 1)/n)
2731
+ ret = ret**e
2732
+ return ret
2733
+
2734
+ def point_of_jacobian_of_curve(self):
2735
+ r"""
2736
+ Return the point in the Jacobian of the curve.
2737
+
2738
+ The Jacobian is the one attached to the projective curve associated
2739
+ with this elliptic curve.
2740
+
2741
+ EXAMPLES::
2742
+
2743
+ sage: # needs sage.rings.finite_rings
2744
+ sage: k.<a> = GF((5,2))
2745
+ sage: E = EllipticCurve(k,[1,0]); E
2746
+ Elliptic Curve defined by y^2 = x^3 + x over Finite Field in a of size 5^2
2747
+ sage: E.order()
2748
+ 32
2749
+ sage: P = E([a, 2*a + 4])
2750
+ sage: P
2751
+ (a : 2*a + 4 : 1)
2752
+ sage: P.order()
2753
+ 8
2754
+ sage: p = P.point_of_jacobian_of_curve()
2755
+ sage: p
2756
+ [Place (x + 4*a, y + 3*a + 1)]
2757
+ sage: p.order()
2758
+ 8
2759
+ sage: Q = 3*P
2760
+ sage: q = Q.point_of_jacobian_of_curve()
2761
+ sage: q == 3*p
2762
+ True
2763
+ sage: G = p.parent()
2764
+ sage: G.order()
2765
+ 32
2766
+ sage: G
2767
+ Group of rational points of Jacobian over Finite Field in a of size 5^2 (Hess model)
2768
+ sage: J = G.parent(); J
2769
+ Jacobian of Projective Plane Curve over Finite Field in a of size 5^2
2770
+ defined by x^2*y + y^3 - x*z^2 (Hess model)
2771
+ sage: J.curve() == E.affine_patch(2).projective_closure()
2772
+ True
2773
+ """
2774
+ from sage.schemes.curves.constructor import Curve
2775
+ C = self.curve()
2776
+ A = C.ambient_space() # projective plane
2777
+ x, y, z = self
2778
+
2779
+ X = Curve(C.defining_ideal().gens(), A)
2780
+ X = X.affine_patch(2).projective_closure()
2781
+ F = X.function_field()
2782
+ P = X(z,x,y).place()
2783
+
2784
+ Pinf = F.places_infinite()[0]
2785
+ assert Pinf.degree() == 1, "no rational point at infinity"
2786
+
2787
+ J = X.jacobian(model='hess', base_div=F.genus()*Pinf)
2788
+ G = J.group(self.base_ring())
2789
+ return G(P - P.degree()*Pinf)
2790
+
2791
+
2792
+ class EllipticCurvePoint_number_field(EllipticCurvePoint_field):
2793
+ """
2794
+ A point on an elliptic curve over a number field.
2795
+
2796
+ Most of the functionality is derived from the parent class
2797
+ :class:`EllipticCurvePoint_field`. In addition we have support for
2798
+ orders, heights, reduction modulo primes, and elliptic logarithms.
2799
+
2800
+ EXAMPLES::
2801
+
2802
+ sage: # needs database_cremona_mini_ellcurve
2803
+ sage: E = EllipticCurve('37a')
2804
+ sage: E([0,0])
2805
+ (0 : 0 : 1)
2806
+ sage: E(0,0) # brackets are optional
2807
+ (0 : 0 : 1)
2808
+ sage: E([GF(5)(0), 0]) # entries are coerced
2809
+ (0 : 0 : 1)
2810
+ sage: E(0.000, 0)
2811
+ (0 : 0 : 1)
2812
+ sage: E(1,0,0)
2813
+ Traceback (most recent call last):
2814
+ ...
2815
+ TypeError: Coordinates [1, 0, 0] do not define a point on
2816
+ Elliptic Curve defined by y^2 + y = x^3 - x over Rational Field
2817
+
2818
+ ::
2819
+
2820
+ sage: E = EllipticCurve([0,0,1,-1,0])
2821
+ sage: S = E(QQ); S
2822
+ Abelian group of points on
2823
+ Elliptic Curve defined by y^2 + y = x^3 - x over Rational Field
2824
+
2825
+ TESTS::
2826
+
2827
+ sage: loads(S.dumps()) == S
2828
+ True
2829
+ sage: P = E(0,0); P
2830
+ (0 : 0 : 1)
2831
+ sage: loads(P.dumps()) == P
2832
+ True
2833
+ sage: T = 100*P
2834
+ sage: loads(T.dumps()) == T
2835
+ True
2836
+
2837
+ Test pickling an elliptic curve that has known points on it::
2838
+
2839
+ sage: e = EllipticCurve([0, 0, 1, -1, 0]); g = e.gens(); loads(dumps(e)) == e # needs ecl
2840
+ True
2841
+ """
2842
+
2843
+ def order(self, algorithm=None):
2844
+ r"""
2845
+ Return the order of this point on the elliptic curve.
2846
+
2847
+ If the point has infinite order, returns +Infinity. For
2848
+ curves defined over `\QQ`, we call PARI; over other
2849
+ number fields we implement the function here.
2850
+
2851
+ .. NOTE::
2852
+
2853
+ :meth:`additive_order` is a synonym for :meth:`order`
2854
+
2855
+ INPUT:
2856
+
2857
+ - ``algorithm`` -- string (default: ``None``) -- the algorithm to use,
2858
+ can be ``'pari'``, ``'generic'``, ``'generic_small'`` or ``'hybrid'``.
2859
+ ``'generic_small'`` may be preferable when the order of the point
2860
+ is very small compared to the order of the torsion,
2861
+ and the order of the torsion is hard to factorize.
2862
+ ``'hybrid'`` uses a combination of ``'pari'`` and ``'generic_small'``
2863
+ to ensure the complexity of computing the order is
2864
+ roughly the square root of the order, and that it is still fast
2865
+ if the order only have very small prime factors.
2866
+
2867
+ EXAMPLES::
2868
+
2869
+ sage: E = EllipticCurve([0,0,1,-1,0])
2870
+ sage: P = E([0,0]); P
2871
+ (0 : 0 : 1)
2872
+ sage: P.order()
2873
+ +Infinity
2874
+
2875
+ ::
2876
+
2877
+ sage: E = EllipticCurve([0,1])
2878
+ sage: P = E([-1,0])
2879
+ sage: P.order()
2880
+ 2
2881
+ sage: P.additive_order()
2882
+ 2
2883
+ """
2884
+ return super().order(algorithm)
2885
+
2886
+ def _compute_order(self, algorithm):
2887
+ """
2888
+ TESTS::
2889
+
2890
+ sage: E = EllipticCurve([0,0,1,-1,0])
2891
+ sage: P = E([0,0]); P
2892
+ (0 : 0 : 1)
2893
+ sage: P._compute_order(algorithm='pari')
2894
+ +Infinity
2895
+ sage: P._compute_order(algorithm='generic')
2896
+ +Infinity
2897
+ sage: P._compute_order(algorithm='unknown')
2898
+ Traceback (most recent call last):
2899
+ ...
2900
+ NotImplementedError: unknown algorithm 'unknown'
2901
+
2902
+ sage: E = EllipticCurve([1, 2])
2903
+ sage: E(1, 2).order(algorithm='generic')
2904
+ 4
2905
+ sage: E(1, -2).order(algorithm='hybrid')
2906
+ 4
2907
+ """
2908
+ E = self.curve()
2909
+
2910
+ if algorithm == 'pari':
2911
+ n = E.pari_curve().ellorder(self)
2912
+ if n:
2913
+ return Integer(n)
2914
+ else:
2915
+ return oo
2916
+
2917
+ if algorithm == 'generic':
2918
+ # Get the torsion order if known, else a bound on (multiple
2919
+ # of) the order. We do not compute the torsion if it is not
2920
+ # already known, since computing the bound is faster (and is
2921
+ # also cached).
2922
+ try:
2923
+ N = E._torsion_order
2924
+ except AttributeError:
2925
+ N = E._torsion_bound()
2926
+
2927
+ # Now self is a torsion point iff it is killed by N:
2928
+ if not (N*self).is_zero():
2929
+ return oo
2930
+
2931
+ # Finally we find the exact order using the generic code:
2932
+ return generic.order_from_multiple(self, N, operation='+')
2933
+
2934
+ if algorithm in ('generic_small', 'hybrid'):
2935
+ return super()._compute_order(algorithm)
2936
+
2937
+ if algorithm is not None:
2938
+ raise NotImplementedError(f"unknown algorithm {algorithm!r}")
2939
+
2940
+ # First try PARI
2941
+ try:
2942
+ return self._compute_order('pari')
2943
+ except PariError:
2944
+ pass
2945
+ return self._compute_order('generic')
2946
+
2947
+ additive_order = order
2948
+
2949
+ def has_finite_order(self) -> bool:
2950
+ """
2951
+ Return ``True`` iff this point has finite order on the elliptic curve.
2952
+
2953
+ EXAMPLES::
2954
+
2955
+ sage: E = EllipticCurve([0,0,1,-1,0])
2956
+ sage: P = E([0,0]); P
2957
+ (0 : 0 : 1)
2958
+ sage: P.has_finite_order()
2959
+ False
2960
+
2961
+ ::
2962
+
2963
+ sage: E = EllipticCurve([0,1])
2964
+ sage: P = E([-1,0])
2965
+ sage: P.has_finite_order()
2966
+ True
2967
+ """
2968
+ if self.is_zero():
2969
+ return True
2970
+ return self.order() != oo
2971
+
2972
+ def has_infinite_order(self) -> bool:
2973
+ r"""
2974
+ Return ``True`` iff this point has infinite order on the elliptic curve.
2975
+
2976
+ EXAMPLES::
2977
+
2978
+ sage: E = EllipticCurve([0,0,1,-1,0])
2979
+ sage: P = E([0,0]); P
2980
+ (0 : 0 : 1)
2981
+ sage: P.has_infinite_order()
2982
+ True
2983
+
2984
+ ::
2985
+
2986
+ sage: E = EllipticCurve([0,1])
2987
+ sage: P = E([-1,0])
2988
+ sage: P.has_infinite_order()
2989
+ False
2990
+ """
2991
+ if self.is_zero():
2992
+ return False
2993
+ return self.order() == oo
2994
+
2995
+ def _has_order_at_least(self, bound, *, attempts=999):
2996
+ r"""
2997
+ Return ``True`` if this point definitely has order at least ``bound``
2998
+ on the elliptic curve, ``False`` if the point has smaller order, and
2999
+ ``None`` if the result of this test is inconclusive.
3000
+
3001
+ This method can be much faster than calling :meth:`has_infinite_order`
3002
+ if all that is needed is a lower bound on the order.
3003
+
3004
+ ALGORITHM: Compute the order of the point modulo various small primes
3005
+ and combine that information using CRT.
3006
+
3007
+ EXAMPLES::
3008
+
3009
+ sage: # needs database_cremona_mini_ellcurve
3010
+ sage: E = EllipticCurve('11a3')
3011
+ sage: P = next(filter(bool, E.torsion_points()))
3012
+ sage: P._has_order_at_least(5)
3013
+ True
3014
+ sage: P._has_order_at_least(6) # long time -- 5s
3015
+ sage: P.order()
3016
+ 5
3017
+ sage: Q = E.lift_x(10^42, extend=True)
3018
+ sage: Q._has_order_at_least(10^100)
3019
+ True
3020
+
3021
+ ::
3022
+
3023
+ sage: x = polygen(ZZ)
3024
+ sage: K.<a> = NumberField(x^2 - x + 2)
3025
+ sage: E = EllipticCurve([1, a-1, a+1, -2*a-2, -5*a+7]) # 2.0.7.1-268.3-b1
3026
+ sage: P = next(filter(bool, E.torsion_points()))
3027
+ sage: P._has_order_at_least(11)
3028
+ True
3029
+ sage: P._has_order_at_least(12)
3030
+ False
3031
+ sage: P.order()
3032
+ 11
3033
+ sage: Q = E.lift_x(123*a + 456, extend=True)
3034
+ sage: Q._has_order_at_least(10^100)
3035
+ True
3036
+ """
3037
+ n = getattr(self, '_order', None)
3038
+ if n is not None:
3039
+ return n >= bound
3040
+
3041
+ from sage.sets.primes import Primes
3042
+ from sage.rings.finite_rings.finite_field_constructor import GF
3043
+ field_deg = self.curve().base_field().absolute_degree()
3044
+ if field_deg > 1:
3045
+ K = self.curve().base_field().absolute_field('T')
3046
+ _, iso = K.structure()
3047
+ E = self.curve().change_ring(iso)
3048
+ P = self.change_ring(iso)
3049
+ poly = lambda elt: elt.polynomial()
3050
+ if field_deg == 2:
3051
+ # Kamienny-Kenku-Momose
3052
+ bound = min(bound, 18 + 1)
3053
+ else:
3054
+ K, E, P = QQ, self.curve(), self
3055
+ poly = lambda elt: QQ['x'](elt)
3056
+ # Mazur / Ogg's torsion conjecture
3057
+ # Torsion points can only have order <= 12, so order of > 12 -> infinite order
3058
+ bound = min(bound, 12 + 1)
3059
+ assert P.curve() is E
3060
+
3061
+ n = ZZ.one()
3062
+ no_progress = 0
3063
+ for p in Primes():
3064
+ try:
3065
+ f,_ = K.defining_polynomial().change_ring(GF(p)).factor()[0]
3066
+ except ZeroDivisionError:
3067
+ continue
3068
+ F = GF(p).extension(f,'t')
3069
+ red = lambda elt: F(f.parent()(poly(elt)).change_ring(GF(p)) % f)
3070
+
3071
+ try:
3072
+ Ered = E.change_ring(red)
3073
+ Pred = Ered(*map(red, P))
3074
+ except (ZeroDivisionError, ArithmeticError):
3075
+ continue
3076
+
3077
+ o = Pred.order()
3078
+ if not o.divides(n):
3079
+ n = n.lcm(o)
3080
+ no_progress = 0
3081
+ else:
3082
+ no_progress += 1
3083
+
3084
+ if n >= bound:
3085
+ return True
3086
+ if no_progress >= attempts:
3087
+ return
3088
+
3089
+ assert False # unreachable unless there are only finitely many primes
3090
+
3091
+ def is_on_identity_component(self, embedding=None):
3092
+ r"""
3093
+ Return ``True`` iff this point is on the identity component of
3094
+ its curve with respect to a given (real or complex) embedding.
3095
+
3096
+ INPUT:
3097
+
3098
+ - ``self`` -- a point on a curve over any ordered field (e.g. `\QQ`)
3099
+
3100
+ - ``embedding`` -- an embedding from the base_field of the
3101
+ point's curve into `\RR` or `\CC`; if ``None`` (the
3102
+ default) it uses the first embedding of the base_field into
3103
+ `\RR` if any, else the first embedding into `\CC`.
3104
+
3105
+ OUTPUT:
3106
+
3107
+ boolean; ``True`` iff the point is on the identity component of
3108
+ the curve. (If the point is zero then the result is ``True``.)
3109
+
3110
+ EXAMPLES:
3111
+
3112
+ For `K=\QQ` there is no need to specify an embedding::
3113
+
3114
+ sage: # needs database_cremona_mini_ellcurve
3115
+ sage: E = EllipticCurve('5077a1')
3116
+ sage: [E.lift_x(x).is_on_identity_component() for x in srange(-3,5)]
3117
+ [False, False, False, False, False, True, True, True]
3118
+
3119
+ An example over a field with two real embeddings::
3120
+
3121
+ sage: # needs sage.rings.number_field
3122
+ sage: L.<a> = QuadraticField(2)
3123
+ sage: E = EllipticCurve(L, [0,1,0,a,a])
3124
+ sage: P = E(-1,0)
3125
+ sage: [P.is_on_identity_component(e) for e in L.embeddings(RR)]
3126
+ [False, True]
3127
+
3128
+ We can check this as follows::
3129
+
3130
+ sage: # needs sage.rings.number_field
3131
+ sage: [e(E.discriminant()) > 0 for e in L.embeddings(RR)]
3132
+ [True, False]
3133
+ sage: e = L.embeddings(RR)[0]
3134
+ sage: E1 = EllipticCurve(RR, [e(ai) for ai in E.ainvs()])
3135
+ sage: e1, e2, e3 = E1.two_division_polynomial().roots(RR,
3136
+ ....: multiplicities=False)
3137
+ sage: e1 < e2 < e3 and e(P[0]) < e3
3138
+ True
3139
+ """
3140
+ if self.is_zero(): # trivial case
3141
+ return True
3142
+
3143
+ e = embedding
3144
+ # It is also trivially true if we have a complex embedding
3145
+ if e is not None:
3146
+ if not isinstance(e.codomain(), sage.rings.abc.RealField):
3147
+ return True
3148
+
3149
+ # find a suitable embedding if none was supplied:
3150
+ E = self.curve()
3151
+ K = E.base_field()
3152
+ if e is None:
3153
+ try:
3154
+ e = K.embeddings(RealField())[0]
3155
+ except IndexError:
3156
+ e = K.embeddings(ComplexField())[0]
3157
+
3158
+ # If there is only one component, the result is True:
3159
+ if not isinstance(e.codomain(), sage.rings.abc.RealField): # complex embedding
3160
+ return True
3161
+ if e(E.discriminant()) < 0: # only one component
3162
+ return True
3163
+
3164
+ # Now we have a real embedding and two components and have to work:
3165
+ gx = E.two_division_polynomial()
3166
+ gxd = gx.derivative()
3167
+ gxdd = gxd.derivative()
3168
+ return (e(gxd(self[0])) > 0 and e(gxdd(self[0])) > 0)
3169
+
3170
+ def has_good_reduction(self, P=None) -> bool:
3171
+ r"""
3172
+ Return ``True`` iff this point has good reduction modulo a prime.
3173
+
3174
+ INPUT:
3175
+
3176
+ - ``P`` -- a prime of the base_field of the point's curve, or
3177
+ ``None`` (default)
3178
+
3179
+ OUTPUT:
3180
+
3181
+ boolean; if a prime `P` of the base field is specified, returns
3182
+ ``True`` iff the point has good reduction at `P`; otherwise,
3183
+ return ``True`` if the point has god reduction at all primes in
3184
+ the support of the discriminant of this model.
3185
+
3186
+ EXAMPLES::
3187
+
3188
+ sage: # needs database_cremona_mini_ellcurve eclib
3189
+ sage: E = EllipticCurve('990e1')
3190
+ sage: P = E.gen(0); P
3191
+ (15 : 51 : 1)
3192
+ sage: [E.has_good_reduction(p) for p in [2,3,5,7]]
3193
+ [False, False, False, True]
3194
+ sage: [P.has_good_reduction(p) for p in [2,3,5,7]]
3195
+ [True, False, True, True]
3196
+ sage: [E.tamagawa_exponent(p) for p in [2,3,5,7]]
3197
+ [2, 2, 1, 1]
3198
+ sage: [(2*P).has_good_reduction(p) for p in [2,3,5,7]]
3199
+ [True, True, True, True]
3200
+ sage: P.has_good_reduction()
3201
+ False
3202
+ sage: (2*P).has_good_reduction()
3203
+ True
3204
+ sage: (3*P).has_good_reduction()
3205
+ False
3206
+
3207
+ ::
3208
+
3209
+ sage: # needs sage.rings.number_field
3210
+ sage: x = polygen(ZZ, 'x')
3211
+ sage: K.<i> = NumberField(x^2 + 1)
3212
+ sage: E = EllipticCurve(K, [0,1,0,-160,308])
3213
+ sage: P = E(26, -120)
3214
+ sage: E.discriminant().support()
3215
+ [Fractional ideal (i - 1),
3216
+ Fractional ideal (2*i - 1),
3217
+ Fractional ideal (-2*i - 1),
3218
+ Fractional ideal (3)]
3219
+ sage: [E.tamagawa_exponent(p) for p in E.discriminant().support()]
3220
+ [1, 4, 4, 4]
3221
+ sage: P.has_good_reduction()
3222
+ False
3223
+ sage: (2*P).has_good_reduction()
3224
+ False
3225
+ sage: (4*P).has_good_reduction()
3226
+ True
3227
+
3228
+ TESTS:
3229
+
3230
+ An example showing that :issue:`8498` is fixed::
3231
+
3232
+ sage: # needs database_cremona_mini_ellcurve sage.rings.number_field
3233
+ sage: E = EllipticCurve('11a1')
3234
+ sage: K.<t> = NumberField(x^2 + 47)
3235
+ sage: EK = E.base_extend(K)
3236
+ sage: T = EK(5, 5)
3237
+ sage: P = EK(-2, -1/2*t - 1/2)
3238
+ sage: p = K.ideal(11)
3239
+ sage: T.has_good_reduction(p)
3240
+ False
3241
+ sage: P.has_good_reduction(p)
3242
+ True
3243
+ """
3244
+ if self.is_zero(): # trivial case
3245
+ return True
3246
+
3247
+ E = self.curve()
3248
+ if P is None:
3249
+ return all(self.has_good_reduction(Pr)
3250
+ for Pr in E.discriminant().support())
3251
+ K = E.base_field()
3252
+ from sage.schemes.elliptic_curves.ell_local_data import check_prime
3253
+ P = check_prime(K, P)
3254
+
3255
+ # If the curve has good reduction at P, the result is True:
3256
+ t = E.local_data(P).bad_reduction_type()
3257
+ if t is None:
3258
+ return True
3259
+
3260
+ # Make sure the curve is integral and locally minimal at P:
3261
+ Emin = E.local_minimal_model(P)
3262
+ urst = E.isomorphism_to(Emin)
3263
+ Q = urst(self)
3264
+
3265
+ # Scale the homogeneous coordinates of the point to be primitive:
3266
+ xyz = list(Q)
3267
+ e = min([c.valuation(P) for c in xyz])
3268
+ if e != 0:
3269
+ if K is QQ:
3270
+ pi = P
3271
+ else:
3272
+ pi = K.uniformizer(P)
3273
+ pie = pi**e
3274
+ xyz = [c/pie for c in xyz]
3275
+
3276
+ # Evaluate the partial derivatives at the point to see if they
3277
+ # are zero mod P
3278
+
3279
+ # See #8498: sometimes evaluating F's derivatives at xyz
3280
+ # returns a constant polynomial instead of a constant
3281
+
3282
+ F = Emin.defining_polynomial()
3283
+ for v in F.variables():
3284
+ c = (F.derivative(v))(xyz)
3285
+ try:
3286
+ val = c.valuation(P)
3287
+ except AttributeError:
3288
+ val = c.constant_coefficient().valuation(P)
3289
+ if val == 0:
3290
+ return True
3291
+ return False
3292
+
3293
+ def reduction(self, p):
3294
+ """
3295
+ This finds the reduction of a point `P` on the elliptic curve
3296
+ modulo the prime `p`.
3297
+
3298
+ INPUT:
3299
+
3300
+ - ``self`` -- a point on an elliptic curve
3301
+
3302
+ - ``p`` -- a prime number
3303
+
3304
+ OUTPUT: the point reduced to be a point on the elliptic curve modulo `p`
3305
+
3306
+ EXAMPLES::
3307
+
3308
+ sage: E = EllipticCurve([1,2,3,4,0])
3309
+ sage: P = E(0,0)
3310
+ sage: P.reduction(5)
3311
+ (0 : 0 : 1)
3312
+ sage: Q = E(98,931)
3313
+ sage: Q.reduction(5)
3314
+ (3 : 1 : 1)
3315
+ sage: Q.reduction(5).curve() == E.reduction(5)
3316
+ True
3317
+
3318
+ ::
3319
+
3320
+ sage: # needs sage.rings.number_field
3321
+ sage: x = polygen(ZZ, 'x')
3322
+ sage: F.<a> = NumberField(x^2 + 5)
3323
+ sage: E = EllipticCurve(F, [1,2,3,4,0])
3324
+ sage: Q = E(98, 931)
3325
+ sage: Q.reduction(a)
3326
+ (3 : 1 : 1)
3327
+ sage: Q.reduction(11)
3328
+ (10 : 7 : 1)
3329
+
3330
+ ::
3331
+
3332
+ sage: # needs sage.rings.number_field
3333
+ sage: F.<a> = NumberField(x^3 + x^2 + 1)
3334
+ sage: E = EllipticCurve(F, [a,2])
3335
+ sage: P = E(a, 1)
3336
+ sage: P.reduction(F.ideal(5))
3337
+ (abar : 1 : 1)
3338
+ sage: P.reduction(F.ideal(a^2 - 4*a - 2))
3339
+ (abar : 1 : 1)
3340
+ """
3341
+ P = self
3342
+ E = P.curve()
3343
+ return E.reduction(p)(P)
3344
+
3345
+ def height(self, precision=None, normalised=True, algorithm='pari'):
3346
+ r"""Return the Néron-Tate canonical height of the point.
3347
+
3348
+ INPUT:
3349
+
3350
+ - ``self`` -- a point on an elliptic curve over a number field `K`
3351
+
3352
+ - ``precision`` -- positive integer, or ``None`` (default). The
3353
+ precision in bits of the result. If ``None``, the default real
3354
+ precision is used.
3355
+
3356
+ - ``normalised`` -- boolean. If ``True`` (default), the height is
3357
+ normalised to be invariant under extension of `K`. If ``False``,
3358
+ return this normalised height multiplied by the degree of `K`.
3359
+
3360
+ - ``algorithm`` -- string; either ``'pari'`` (default) or ``'sage'``.
3361
+ If ``'pari'`` and the base field is `\QQ`, use the PARI library
3362
+ function; otherwise use the Sage implementation.
3363
+
3364
+ OUTPUT:
3365
+
3366
+ The rational number 0, or a nonnegative real number.
3367
+
3368
+ There are two normalisations used in the literature, one of
3369
+ which is double the other. We use the larger of the two, which
3370
+ is the one appropriate for the BSD conjecture. This is
3371
+ consistent with [Cre1997]_ and double that of [Sil2009]_.
3372
+
3373
+ See :wikipedia:`Néron-Tate height`.
3374
+
3375
+ .. NOTE::
3376
+
3377
+ The correct height to use for the regulator in the BSD
3378
+ formula is the non-normalised height.
3379
+
3380
+ EXAMPLES::
3381
+
3382
+ sage: # needs database_cremona_mini_ellcurve
3383
+ sage: E = EllipticCurve('11a'); E
3384
+ Elliptic Curve defined by y^2 + y = x^3 - x^2 - 10*x - 20 over Rational Field
3385
+ sage: P = E([5,5]); P
3386
+ (5 : 5 : 1)
3387
+ sage: P.height()
3388
+ 0
3389
+ sage: Q = 5*P
3390
+ sage: Q.height()
3391
+ 0
3392
+
3393
+ ::
3394
+
3395
+ sage: # needs database_cremona_mini_ellcurve
3396
+ sage: E = EllipticCurve('37a'); E
3397
+ Elliptic Curve defined by y^2 + y = x^3 - x over Rational Field
3398
+ sage: P = E([0,0])
3399
+ sage: P.height()
3400
+ 0.0511114082399688
3401
+ sage: P.order()
3402
+ +Infinity
3403
+ sage: E.regulator() # needs eclib
3404
+ 0.0511114082399688...
3405
+ sage: def naive_height(P):
3406
+ ....: return log(RR(max(abs(P[0].numerator()), abs(P[0].denominator()))))
3407
+ sage: for n in [1..10]:
3408
+ ....: print(naive_height(2^n*P)/4^n)
3409
+ 0.000000000000000
3410
+ 0.0433216987849966
3411
+ 0.0502949347635656
3412
+ 0.0511006335618645
3413
+ 0.0511007834799612
3414
+ 0.0511013666152466
3415
+ 0.0511034199907743
3416
+ 0.0511106492906471
3417
+ 0.0511114081541082
3418
+ 0.0511114081541180
3419
+
3420
+ ::
3421
+
3422
+ sage: # needs database_cremona_mini_ellcurve
3423
+ sage: E = EllipticCurve('4602a1'); E
3424
+ Elliptic Curve defined by y^2 + x*y = x^3 + x^2 - 37746035*x - 89296920339
3425
+ over Rational Field
3426
+ sage: x = 77985922458974949246858229195945103471590
3427
+ sage: y = 19575260230015313702261379022151675961965157108920263594545223
3428
+ sage: d = 2254020761884782243
3429
+ sage: E([ x / d^2, y / d^3 ]).height()
3430
+ 86.7406561381275
3431
+
3432
+ ::
3433
+
3434
+ sage: # needs database_cremona_mini_ellcurve
3435
+ sage: E = EllipticCurve([17, -60, -120, 0, 0]); E
3436
+ Elliptic Curve defined by y^2 + 17*x*y - 120*y = x^3 - 60*x^2 over Rational Field
3437
+ sage: E([30, -90]).height()
3438
+ 0
3439
+
3440
+ sage: # needs database_cremona_mini_ellcurve
3441
+ sage: E = EllipticCurve('389a1'); E
3442
+ Elliptic Curve defined by y^2 + y = x^3 + x^2 - 2*x over Rational Field
3443
+ sage: P, Q = E(-1,1), E(0,-1)
3444
+ sage: P.height(precision=100)
3445
+ 0.68666708330558658572355210295
3446
+ sage: (3*Q).height(precision=100)/Q.height(precision=100)
3447
+ 9.0000000000000000000000000000
3448
+ sage: _.parent()
3449
+ Real Field with 100 bits of precision
3450
+
3451
+ Canonical heights over number fields are implemented as well::
3452
+
3453
+ sage: R.<x> = QQ[]
3454
+ sage: K.<a> = NumberField(x^3 - 2) # needs sage.rings.number_field
3455
+ sage: E = EllipticCurve([a, 4]); E # needs sage.rings.number_field
3456
+ Elliptic Curve defined by y^2 = x^3 + a*x + 4
3457
+ over Number Field in a with defining polynomial x^3 - 2
3458
+ sage: P = E((0,2)) # needs sage.rings.number_field
3459
+ sage: P.height() # needs sage.rings.number_field
3460
+ 0.810463096585925
3461
+ sage: P.height(precision=100) # needs sage.rings.number_field
3462
+ 0.81046309658592536863991810577
3463
+ sage: P.height(precision=200) # needs sage.rings.number_field
3464
+ 0.81046309658592536863991810576865158896130286417155832378086
3465
+ sage: (2*P).height() / P.height() # needs sage.rings.number_field
3466
+ 4.00000000000000
3467
+ sage: (100*P).height() / P.height() # needs sage.rings.number_field
3468
+ 10000.0000000000
3469
+
3470
+ Setting ``normalised=False`` multiplies the height by the degree of `K`::
3471
+
3472
+ sage: # needs database_cremona_mini_ellcurve
3473
+ sage: E = EllipticCurve('37a')
3474
+ sage: P = E([0,0])
3475
+ sage: P.height()
3476
+ 0.0511114082399688
3477
+ sage: P.height(normalised=False)
3478
+ 0.0511114082399688
3479
+ sage: K.<z> = CyclotomicField(5) # needs sage.rings.number_field
3480
+ sage: EK = E.change_ring(K) # needs sage.rings.number_field
3481
+ sage: PK = EK([0,0]) # needs sage.rings.number_field
3482
+ sage: PK.height() # needs sage.rings.number_field
3483
+ 0.0511114082399688
3484
+ sage: PK.height(normalised=False) # needs sage.rings.number_field
3485
+ 0.204445632959875
3486
+
3487
+ Some consistency checks::
3488
+
3489
+ sage: # needs database_cremona_mini_ellcurve
3490
+ sage: E = EllipticCurve('5077a1')
3491
+ sage: P = E([-2,3,1])
3492
+ sage: P.height()
3493
+ 1.36857250535393
3494
+ sage: EK = E.change_ring(QuadraticField(-3,'a')) # needs sage.rings.number_field
3495
+ sage: PK = EK([-2,3,1]) # needs sage.rings.number_field
3496
+ sage: PK.height() # needs sage.rings.number_field
3497
+ 1.36857250535393
3498
+
3499
+ sage: # needs sage.rings.number_field
3500
+ sage: K.<i> = NumberField(x^2 + 1)
3501
+ sage: E = EllipticCurve(K, [0,0,4,6*i,0])
3502
+ sage: Q = E.lift_x(-9/4); Q
3503
+ (-9/4 : 27/8*i - 4 : 1)
3504
+ sage: Q.height()
3505
+ 2.69518560017909
3506
+ sage: (15*Q).height() / Q.height()
3507
+ 225.000000000000
3508
+
3509
+ sage: # needs database_cremona_mini_ellcurve
3510
+ sage: E = EllipticCurve('37a')
3511
+ sage: P = E([0,-1])
3512
+ sage: P.height()
3513
+ 0.0511114082399688
3514
+ sage: K.<a> = QuadraticField(-7) # needs sage.rings.number_field
3515
+ sage: ED = E.quadratic_twist(-7) # needs sage.rings.number_field
3516
+ sage: Q = E.isomorphism_to(ED.change_ring(K))(P); Q # needs sage.rings.number_field
3517
+ (0 : -7/2*a - 1/2 : 1)
3518
+ sage: Q.height() # needs sage.rings.number_field
3519
+ 0.0511114082399688
3520
+ sage: Q.height(precision=100) # needs sage.rings.number_field
3521
+ 0.051111408239968840235886099757
3522
+
3523
+ An example to show that the bug at :issue:`5252` is fixed::
3524
+
3525
+ sage: E = EllipticCurve([1, -1, 1, -2063758701246626370773726978, 32838647793306133075103747085833809114881])
3526
+ sage: P = E([-30987785091199, 258909576181697016447])
3527
+ sage: P.height()
3528
+ 25.8603170675462
3529
+ sage: P.height(precision=100)
3530
+ 25.860317067546190743868840741
3531
+ sage: P.height(precision=250)
3532
+ 25.860317067546190743868840740735110323098872903844416215577171041783572513
3533
+ sage: P.height(precision=500)
3534
+ 25.8603170675461907438688407407351103230988729038444162155771710417835725129551130570889813281792157278507639909972112856019190236125362914195452321720
3535
+
3536
+ sage: P.height(precision=100) == P.non_archimedean_local_height(prec=100)+P.archimedean_local_height(prec=100)
3537
+ True
3538
+
3539
+ An example to show that the bug at :issue:`8319` is fixed (correct height when the curve is not minimal)::
3540
+
3541
+ sage: E = EllipticCurve([-5580472329446114952805505804593498080000,-157339733785368110382973689903536054787700497223306368000000])
3542
+ sage: xP = 204885147732879546487576840131729064308289385547094673627174585676211859152978311600/23625501907057948132262217188983681204856907657753178415430361
3543
+ sage: P = E.lift_x(xP)
3544
+ sage: P.height()
3545
+ 157.432598516754
3546
+ sage: Q = 2*P
3547
+ sage: Q.height() # long time (4s)
3548
+ 629.730394067016
3549
+ sage: Q.height()-4*P.height() # long time
3550
+ 0.000000000000000
3551
+
3552
+ An example to show that the bug at :issue:`12509` is fixed (precision issues)::
3553
+
3554
+ sage: # needs sage.rings.number_field
3555
+ sage: x = polygen(QQ)
3556
+ sage: K.<a> = NumberField(x^2 - x - 1)
3557
+ sage: v = [0, a + 1, 1, 28665*a - 46382, 2797026*a - 4525688]
3558
+ sage: E = EllipticCurve(v)
3559
+ sage: P = E([72*a - 509/5, -682/25*a - 434/25])
3560
+ sage: P.height()
3561
+ 1.38877711688727
3562
+ sage: (2*P).height()/P.height()
3563
+ 4.00000000000000
3564
+ sage: (2*P).height(precision=100)/P.height(precision=100)
3565
+ 4.0000000000000000000000000000
3566
+ sage: (2*P).height(precision=1000)/P.height(precision=1000)
3567
+ 4.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
3568
+
3569
+ This shows that the bug reported at :issue:`13951` has been fixed::
3570
+
3571
+ sage: E = EllipticCurve([0,17])
3572
+ sage: P1 = E(2,5)
3573
+ sage: P1.height()
3574
+ 1.06248137652528
3575
+ sage: F = E.change_ring(QuadraticField(-3, 'a')) # needs sage.rings.number_field
3576
+ sage: P2 = F([2,5]) # needs sage.rings.number_field
3577
+ sage: P2.height() # needs sage.rings.number_field
3578
+ 1.06248137652528
3579
+
3580
+ This shows that the bug reported at :issue:`36834` (incorrect
3581
+ value when the model is not integral) has been fixed::
3582
+
3583
+ sage: # needs sage.rings.number_field
3584
+ sage: K.<a> = NumberField(x^2 - 84131656042917)
3585
+ sage: E = EllipticCurve(K, [0, 0, 0, -5482707841/48, -244634179112639/864])
3586
+ sage: P = E(349189/12, 1/2*a)
3587
+ sage: P.height()
3588
+ 10.4560438181991
3589
+ sage: [(n*P).height()/P.height() for n in [2,3,4,5]]
3590
+ [4.00000000000000, 9.00000000000000, 16.0000000000000, 25.0000000000000]
3591
+
3592
+ """
3593
+ if self.has_finite_order():
3594
+ return QQ(0)
3595
+
3596
+ E = self.curve()
3597
+ K = E.base_ring()
3598
+
3599
+ if precision is None:
3600
+ precision = RealField().precision()
3601
+
3602
+ known_prec = -1
3603
+ try:
3604
+ height = self.__height
3605
+ known_prec = height.prec()
3606
+ if known_prec > precision:
3607
+ height = RealField(precision)(height)
3608
+ except AttributeError:
3609
+ pass
3610
+
3611
+ if known_prec < precision:
3612
+ if algorithm == 'pari' and K is QQ:
3613
+ Emin = E.minimal_model()
3614
+ iso = E.isomorphism_to(Emin)
3615
+ P = iso(self)
3616
+ h = Emin.pari_curve().ellheight(P, precision=precision)
3617
+ height = RealField(precision)(h)
3618
+ else:
3619
+ height = (self.non_archimedean_local_height(prec=precision)
3620
+ + self.archimedean_local_height(prec=precision))
3621
+
3622
+ # The cached height is the one that is independent of the base field.
3623
+ self.__height = height
3624
+ if not normalised:
3625
+ height *= K.degree()
3626
+ return height
3627
+
3628
+ def archimedean_local_height(self, v=None, prec=None, weighted=False):
3629
+ """
3630
+ Compute the local height of ``self`` at the archimedean place `v`.
3631
+
3632
+ INPUT:
3633
+
3634
+ - ``self`` -- a point on an elliptic curve over a number field `K`
3635
+
3636
+ - ``v`` -- a real or complex embedding of K, or None (default).
3637
+ If `v` is a real or complex embedding, return the local
3638
+ height of ``self`` at `v`. If `v` is None, return the total
3639
+ archimedean contribution to the global height.
3640
+
3641
+ - ``prec`` -- integer or ``None`` (default). The precision of the
3642
+ computation. If ``None``, the precision is deduced from `v`
3643
+
3644
+ - ``weighted`` -- boolean. If ``False`` (default), the height is
3645
+ normalised to be invariant under extension of `K`. If ``True``,
3646
+ return this normalised height multiplied by the local degree
3647
+ if `v` is a single place, or by the degree of `K` if `v` is ``None``.
3648
+
3649
+ OUTPUT:
3650
+
3651
+ A real number. The normalisation is twice that in Silverman's
3652
+ paper [Sil1988]_. Note that this local height depends on the
3653
+ model of the curve.
3654
+
3655
+ ALGORITHM:
3656
+
3657
+ See [Sil1988]_, Section 4.
3658
+
3659
+ EXAMPLES:
3660
+
3661
+ Examples 1, 2, and 3 from [Sil1988]_::
3662
+
3663
+ sage: # needs sage.rings.number_field
3664
+ sage: K.<a> = QuadraticField(-2)
3665
+ sage: E = EllipticCurve(K, [0,-1,1,0,0]); E
3666
+ Elliptic Curve defined by y^2 + y = x^3 + (-1)*x^2 over Number Field
3667
+ in a with defining polynomial x^2 + 2 with a = 1.414213562373095?*I
3668
+ sage: P = E.lift_x(2 + a); P
3669
+ (a + 2 : -2*a - 2 : 1)
3670
+ sage: P.archimedean_local_height(K.places(prec=170)[0]) / 2
3671
+ 0.45754773287523276736211210741423654346576029814695
3672
+
3673
+ sage: # needs sage.rings.number_field
3674
+ sage: x = polygen(ZZ, 'x')
3675
+ sage: K.<i> = NumberField(x^2 + 1)
3676
+ sage: E = EllipticCurve(K, [0,0,4,6*i,0]); E
3677
+ Elliptic Curve defined by y^2 + 4*y = x^3 + 6*i*x
3678
+ over Number Field in i with defining polynomial x^2 + 1
3679
+ sage: P = E((0,0))
3680
+ sage: P.archimedean_local_height(K.places()[0]) / 2
3681
+ 0.510184995162373
3682
+
3683
+ sage: Q = E.lift_x(-9/4); Q # needs sage.rings.number_field
3684
+ (-9/4 : 27/8*i - 4 : 1)
3685
+ sage: Q.archimedean_local_height(K.places()[0]) / 2 # needs sage.rings.number_field
3686
+ 0.654445619529600
3687
+
3688
+ An example over the rational numbers::
3689
+
3690
+ sage: E = EllipticCurve([0, 0, 0, -36, 0])
3691
+ sage: P = E([-3, 9])
3692
+ sage: P.archimedean_local_height()
3693
+ 1.98723816350773
3694
+
3695
+ Local heights of torsion points can be nonzero (unlike the
3696
+ global height)::
3697
+
3698
+ sage: # needs sage.rings.number_field
3699
+ sage: K.<i> = QuadraticField(-1)
3700
+ sage: E = EllipticCurve([0, 0, 0, K(1), 0])
3701
+ sage: P = E(i, 0)
3702
+ sage: P.archimedean_local_height()
3703
+ 0.346573590279973
3704
+
3705
+ TESTS:
3706
+
3707
+ See :issue:`12509`::
3708
+
3709
+ sage: # needs sage.rings.number_field
3710
+ sage: x = polygen(QQ)
3711
+ sage: K.<a> = NumberField(x^2 - x - 1)
3712
+ sage: v = [0, a + 1, 1, 28665*a - 46382, 2797026*a - 4525688]
3713
+ sage: E = EllipticCurve(v)
3714
+ sage: P = E([72*a - 509/5, -682/25*a - 434/25])
3715
+ sage: P.archimedean_local_height()
3716
+ -0.220660795546828
3717
+
3718
+ See :issue:`19276`::
3719
+
3720
+ sage: # needs sage.rings.number_field
3721
+ sage: K.<a> = NumberField(x^2 - x - 104)
3722
+ sage: E = EllipticCurve([1, a - 1, 1, -816765673272*a - 7931030674178, 1478955604013312315*a + 14361086227143654561])
3723
+ sage: P = E(5393511/49*a + 52372721/49 , -33896210324/343*a - 329141996591/343 )
3724
+ sage: P.height()
3725
+ 0.974232017827741
3726
+
3727
+ See :issue:`29966`::
3728
+
3729
+ sage: # needs sage.rings.number_field
3730
+ sage: K.<a> = NumberField(x^3 - x^2 - 6*x + 2)
3731
+ sage: E = EllipticCurve([1, -a^2 + 2*a + 4, 0, -6056450500590472699700624*a^2 - 11239394326797569935861742*a + 4241549693833829432516231,
3732
+ ....: 1904879037869682826729875958079326124520*a^2 + 3535022146945771697732350459284777382011*a - 1334055169621036218710397707677347972626])
3733
+ sage: P = E([1033399668533*a^2 + 1917754693229*a - 723726883800 , 12536493059202326563*a^2 + 23264879148900575548*a - 8779756111574815918 , 1])
3734
+ sage: P.height()
3735
+ 0.297318833424763
3736
+ sage: (2*P).height() / P.height()
3737
+ 4.00000000000000
3738
+ sage: P.height(200)
3739
+ 0.29731883342476341806143743594519935578696537745294661858984
3740
+ sage: (2*P).height(200) / P.height(200)
3741
+ 4.0000000000000000000000000000000000000000000000000000000000
3742
+ """
3743
+ from sage.rings.number_field.number_field import refine_embedding
3744
+ from sage.rings.real_mpfr import RealField
3745
+ from sage.rings.complex_mpfr import ComplexField
3746
+ from sage.rings.infinity import Infinity
3747
+
3748
+ E = self.curve()
3749
+ K = E.base_ring()
3750
+
3751
+ if v is None:
3752
+
3753
+ if prec is None:
3754
+ prec = 53
3755
+ if K is QQ:
3756
+ v = K.embeddings(RR)[0]
3757
+ h = self.archimedean_local_height(v, prec+10)
3758
+ else:
3759
+ r1, r2 = K.signature()
3760
+ pl = K.places()
3761
+ h = (sum(self.archimedean_local_height(pl[i], prec+10, weighted=False)
3762
+ for i in range(r1))
3763
+ + 2 * sum(self.archimedean_local_height(pl[i], prec+10, weighted=False)
3764
+ for i in range(r1, r1 + r2)))
3765
+ if not weighted:
3766
+ h /= K.degree()
3767
+ return RealField(prec)(h)
3768
+
3769
+ prec_v = v.codomain().prec()
3770
+ if prec is None:
3771
+ prec = prec_v
3772
+ if K is QQ:
3773
+ v = K.embeddings(RealField())[0]
3774
+ v_inf = refine_embedding(v, Infinity)
3775
+ v_is_real = v_inf(K.gen()).imag().is_zero()
3776
+
3777
+ # Find a suitable working precision. See trac#29666 for an
3778
+ # example where 100 extra bits is not enough when the
3779
+ # discriminant is ~1e-92, but this code uses a working
3780
+ # precision of 333 and gets it right.
3781
+
3782
+ D = v_inf(E.discriminant())
3783
+
3784
+ if D.abs().real_number(RealField()).round():
3785
+ extra_prec = 100
3786
+ else: # then |D| is small
3787
+ extra_prec = 10 + (1/D).abs().real_number(RealField()).round().nbits()
3788
+
3789
+ working_prec = prec + extra_prec
3790
+ RC = RealField(working_prec) if v_is_real else ComplexField(working_prec)
3791
+ # print("Using working precision {}, |D| = {}".format(working_prec, RC(D).abs()))
3792
+
3793
+ # NB We risk losing much precision if we compute the embedding
3794
+ # of K into RR or CC to some precision and then apply that to
3795
+ # elements of K. Instead we map elements of K into AA or Qbar
3796
+ # (with infinite precision) and then trim back to RR or CC.
3797
+
3798
+ x = RC(v_inf(self[0]))
3799
+ b2, b4, b6, b8 = (RC(v_inf(b)) for b in E.b_invariants())
3800
+
3801
+ # The following comes from Silverman Theorem 4.2. Silverman
3802
+ # uses decimal precision d, so his term (5/3)d =
3803
+ # (5/3)*(log(2)/log(10))*prec = 0.5017*prec, which we round
3804
+ # up. The rest of the expression was wrongly transcribed in
3805
+ # Sage versions <5.6 (see #12509).
3806
+
3807
+ H = max(RC(4).abs(), b2.abs(), 2*b4.abs(), 2*b6.abs(), b8.abs())
3808
+ absdisc = RC(v_inf(E.discriminant())).abs()
3809
+ adl3 = 0 if absdisc >= 1 else absdisc.log() / 3
3810
+ nterms = int(math.ceil(0.51*working_prec + 0.5 + 0.75 * (7 + 4*H.log()/3 - adl3).log()))
3811
+
3812
+ b2p = b2 - 12
3813
+ b4p = b4 - b2 + 6
3814
+ b6p = b6 - 2*b4 + b2 - 4
3815
+ b8p = b8 - 3*b6 + 3*b4 - b2 + 3
3816
+
3817
+ fz = lambda T: 1 - T**2 * (b4 + T*(2*b6 + T*b8))
3818
+ fzp = lambda T: 1 - T**2 * (b4p + T*(2*b6p + T*b8p))
3819
+ fw = lambda T: T*(4 + T*(b2 + T*(2*b4 + T*b6)))
3820
+ fwp = lambda T: T*(4 + T*(b2p + T*(2*b4p + T*b6p)))
3821
+
3822
+ if abs(x) >= .5:
3823
+ t = 1/x
3824
+ beta = True
3825
+ else:
3826
+ t = 1/(x+1)
3827
+ beta = False
3828
+ lam = -t.abs().log()
3829
+ mu = 0
3830
+ four_to_n = QQ(1)
3831
+
3832
+ for n in range(nterms):
3833
+ if beta:
3834
+ w = fw(t)
3835
+ z = fz(t)
3836
+ if abs(w) <= 2 * z.abs():
3837
+ mu += four_to_n * z.abs().log()
3838
+ t = w/z
3839
+ else:
3840
+ mu += four_to_n * (z+w).abs().log()
3841
+ t = w/(z+w)
3842
+ beta = not beta
3843
+ else:
3844
+ w = fwp(t)
3845
+ z = fzp(t)
3846
+ if abs(w) <= 2 * z.abs():
3847
+ mu += four_to_n * z.abs().log()
3848
+ t = w/z
3849
+ else:
3850
+ mu += four_to_n * (z-w).abs().log()
3851
+ t = w/(z-w)
3852
+ beta = not beta
3853
+ four_to_n >>= 2
3854
+
3855
+ h = RealField(prec)(lam + mu/4)
3856
+ if weighted and not v_is_real:
3857
+ h *= 2
3858
+ return h
3859
+
3860
+ def non_archimedean_local_height(self, v=None, prec=None,
3861
+ weighted=False, is_minimal=None):
3862
+ """
3863
+ Compute the local height of ``self`` at non-archimedean places.
3864
+
3865
+ INPUT:
3866
+
3867
+ - ``self`` -- a point on an elliptic curve over a number field `K`
3868
+
3869
+ - ``v`` -- a non-archimedean place of `K`, or ``None`` (default).
3870
+ If `v` is a non-archimedean place, return the local height
3871
+ of ``self`` at `v`. If `v` is ``None``, return the total
3872
+ non-archimedean contribution to the global height.
3873
+
3874
+ - ``prec`` -- integer; or ``None`` (default). The precision of the
3875
+ computation. If ``None``, the height is returned symbolically
3876
+
3877
+ - ``weighted`` -- boolean. If ``False`` (default), the height is
3878
+ normalised to be invariant under extension of `K`. If ``True``,
3879
+ return this normalised height multiplied by the local degree
3880
+ if `v` is a single place, or by the degree of `K` if `v` is ``None``.
3881
+
3882
+ - ``is_minimal`` -- boolean, or ``None`` (default). Ignored
3883
+ when ``v`` is ``None`` (default) or ``True``. Otherwise,
3884
+ when the place ``v`` is specified: if ``True``, the model is
3885
+ assumed to be both locally integral and a local minimal
3886
+ model; if ``None`` (default) or ``False``, a local minimal
3887
+ model is computed and the computation is done on that model.
3888
+
3889
+ OUTPUT:
3890
+
3891
+ A real number. The normalisation is twice that in Silverman's
3892
+ paper [Sil1988]_. Note that this local height depends on the
3893
+ model of the curve.
3894
+
3895
+ ALGORITHM:
3896
+
3897
+ See [Sil1988]_, Section 5.
3898
+
3899
+ EXAMPLES:
3900
+
3901
+ Examples 2 and 3 from [Sil1988]_::
3902
+
3903
+ sage: # needs sage.rings.number_field sage.symbolic
3904
+ sage: x = polygen(ZZ, 'x')
3905
+ sage: K.<i> = NumberField(x^2 + 1)
3906
+ sage: E = EllipticCurve(K, [0,0,4,6*i,0]); E
3907
+ Elliptic Curve defined by y^2 + 4*y = x^3 + 6*i*x
3908
+ over Number Field in i with defining polynomial x^2 + 1
3909
+ sage: P = E((0,0))
3910
+ sage: P.non_archimedean_local_height(K.ideal(i+1))
3911
+ -1/2*log(2)
3912
+ sage: P.non_archimedean_local_height(K.ideal(3))
3913
+ 0
3914
+ sage: P.non_archimedean_local_height(K.ideal(1-2*i))
3915
+ 0
3916
+ sage: Q = E.lift_x(-9/4); Q
3917
+ (-9/4 : 27/8*i - 4 : 1)
3918
+ sage: Q.non_archimedean_local_height(K.ideal(1+i))
3919
+ 2*log(2)
3920
+ sage: Q.non_archimedean_local_height(K.ideal(3))
3921
+ 0
3922
+ sage: Q.non_archimedean_local_height(K.ideal(1-2*i))
3923
+ 0
3924
+ sage: Q.non_archimedean_local_height()
3925
+ 2*log(2)
3926
+
3927
+ An example over the rational numbers::
3928
+
3929
+ sage: E = EllipticCurve([0, 0, 0, -36, 0])
3930
+ sage: P = E([-3, 9])
3931
+ sage: P.non_archimedean_local_height() # needs sage.symbolic
3932
+ -log(3)
3933
+
3934
+ Local heights of torsion points can be nonzero (unlike the
3935
+ global height)::
3936
+
3937
+ sage: # needs sage.rings.number_field sage.symbolic
3938
+ sage: K.<i> = QuadraticField(-1)
3939
+ sage: E = EllipticCurve([0, 0, 0, K(1), 0])
3940
+ sage: P = E(i, 0)
3941
+ sage: P.non_archimedean_local_height()
3942
+ -1/2*log(2)
3943
+
3944
+ TESTS::
3945
+
3946
+ sage: Q.non_archimedean_local_height(prec=100) # needs sage.rings.number_field sage.symbolic
3947
+ 1.3862943611198906188344642429
3948
+ sage: (3*Q).non_archimedean_local_height() # needs sage.rings.number_field sage.symbolic
3949
+ 1/2*log(75923153929839865104)
3950
+
3951
+ sage: # needs sage.rings.number_field
3952
+ sage: x = polygen(ZZ, 'x')
3953
+ sage: F.<a> = NumberField(x^4 + 2*x^3 + 19*x^2 + 18*x + 288)
3954
+ sage: F.ring_of_integers().basis()
3955
+ [1, 5/6*a^3 + 1/6*a, 1/6*a^3 + 1/6*a^2, a^3]
3956
+ sage: F.class_number()
3957
+ 12
3958
+ sage: E = EllipticCurve('37a').change_ring(F)
3959
+ sage: P = E((-a^2/6 - a/6 - 1, a)); P
3960
+ (-1/6*a^2 - 1/6*a - 1 : a : 1)
3961
+ sage: P[0].is_integral()
3962
+ True
3963
+ sage: P.non_archimedean_local_height() # needs sage.symbolic
3964
+ 0
3965
+
3966
+ This shows that the bug reported at :issue:`13951` has been fixed::
3967
+
3968
+ sage: E = EllipticCurve([0,17])
3969
+ sage: P = E(2,5)
3970
+ sage: P.non_archimedean_local_height(2) # needs sage.symbolic
3971
+ -2/3*log(2)
3972
+
3973
+ This shows that the bug reported at :issue:`36834` (incorrect
3974
+ value when the model is not integral) has been fixed::
3975
+
3976
+ sage: # needs sage.rings.number_field sage.symbolic
3977
+ sage: K.<a> = QuadraticField(84131656042917)
3978
+ sage: E = EllipticCurve(K, [0, 0, 0, -5482707841/48, -244634179112639/864])
3979
+ sage: P = E(349189/12, 1/2*a)
3980
+ sage: h = P.non_archimedean_local_height()
3981
+ sage: h
3982
+ 1/2*log(144) - log(3) - 2*log(2)
3983
+ sage: h.numerator().simplify_log()
3984
+ 0
3985
+
3986
+ """
3987
+ if prec:
3988
+ log = lambda x: RealField(prec)(x).log()
3989
+ else:
3990
+ from sage.functions.log import log
3991
+
3992
+ if v is None:
3993
+ D = self.curve().discriminant()
3994
+ K = self.curve().base_ring()
3995
+ if K is QQ:
3996
+ factorD = D.factor()
3997
+ if self[0] == 0:
3998
+ c = 1
3999
+ else:
4000
+ c = self[0].denominator()
4001
+ # The last sum is for bad primes that divide c where
4002
+ # the model is not minimal.
4003
+ h = (log(c)
4004
+ + sum(self.non_archimedean_local_height(p, prec, weighted=True, is_minimal=(e < 12))
4005
+ for p, e in factorD if not p.divides(c))
4006
+ + sum(self.non_archimedean_local_height(p, prec, weighted=True)
4007
+ - c.valuation(p) * log(p)
4008
+ for p, e in factorD if e >= 12 and c.valuation(p)))
4009
+ else:
4010
+ factorD = K.factor(D)
4011
+ if self[0] == 0:
4012
+ c = K.ideal(1)
4013
+ else:
4014
+ c = K.ideal(self[0]).denominator()
4015
+ h = (log(c.norm())
4016
+ + sum(self.non_archimedean_local_height(v, prec, weighted=True)
4017
+ - c.valuation(v) * log(v.norm())
4018
+ for v, e in factorD))
4019
+ if not weighted:
4020
+ h /= K.degree()
4021
+ return h
4022
+
4023
+ if is_minimal:
4024
+ E = self.curve()
4025
+ P = self
4026
+ offset = ZZ.zero()
4027
+ else:
4028
+ E = self.curve().local_minimal_model(v)
4029
+ P = self.curve().isomorphism_to(E)(self)
4030
+ # Silverman's normalization is not invariant under change of model,
4031
+ # but it all cancels out in the global height.
4032
+ offset = (self.curve().discriminant()/E.discriminant()).valuation(v)
4033
+
4034
+ a1, a2, a3, a4, a6 = E.a_invariants()
4035
+ b2, b4, b6, b8 = E.b_invariants()
4036
+ c4 = E.c4()
4037
+ x, y = P.xy()
4038
+ D = E.discriminant()
4039
+ N = D.valuation(v)
4040
+ A = (3*x**2 + 2*a2*x + a4 - a1*y).valuation(v)
4041
+ B = (2*y+a1*x+a3).valuation(v)
4042
+ C = (3*x**4 + b2*x**3 + 3*b4*x**2 + 3*b6*x + b8).valuation(v)
4043
+ if A <= 0 or B <= 0:
4044
+ r = max(0, -x.valuation(v))
4045
+ elif c4.valuation(v) == 0:
4046
+ n = min(B, N/2)
4047
+ r = -n*(N-n)/N
4048
+ elif C >= 3*B:
4049
+ r = -2*B/3
4050
+ else:
4051
+ r = -C/4
4052
+ r -= offset/6
4053
+ if not r:
4054
+ return QQ.zero()
4055
+ else:
4056
+ if E.base_ring() is QQ:
4057
+ Nv = Integer(v)
4058
+ else:
4059
+ Nv = v.norm()
4060
+ if not weighted:
4061
+ r = r / (v.ramification_index() * v.residue_class_degree())
4062
+ return r * log(Nv)
4063
+
4064
+ def elliptic_logarithm(self, embedding=None, precision=100,
4065
+ algorithm='pari'):
4066
+ r"""
4067
+ Return the elliptic logarithm of this elliptic curve point.
4068
+
4069
+ An embedding of the base field into `\RR` or `\CC` (with
4070
+ arbitrary precision) may be given; otherwise the first real
4071
+ embedding is used (with the specified precision) if any, else
4072
+ the first complex embedding.
4073
+
4074
+ INPUT:
4075
+
4076
+ - ``embedding`` -- an embedding of the base field into `\RR` or `\CC`
4077
+
4078
+ - ``precision`` -- a positive integer (default: 100) setting the
4079
+ number of bits of precision for the computation
4080
+
4081
+ - ``algorithm`` -- either ``'pari'`` (default: for real embeddings)
4082
+ to use PARI's :pari:`ellpointtoz`, or ``'sage'`` for a native
4083
+ implementation. Ignored for complex embeddings.
4084
+
4085
+ ALGORITHM:
4086
+
4087
+ See [Coh1993]_ for the case of real embeddings,
4088
+ and Cremona, J.E. and Thongjunthug, T. 2010 for the complex
4089
+ case.
4090
+
4091
+ AUTHORS:
4092
+
4093
+ - Michael Mardaus (2008-07),
4094
+ - Tobias Nagel (2008-07) -- original version from [Coh1993]_.
4095
+ - John Cremona (2008-07) -- revision following eclib code.
4096
+ - John Cremona (2010-03) -- implementation for complex embeddings.
4097
+
4098
+ EXAMPLES::
4099
+
4100
+ sage: # needs database_cremona_mini_ellcurve
4101
+ sage: E = EllipticCurve('389a')
4102
+ sage: E.discriminant() > 0
4103
+ True
4104
+ sage: P = E([-1,1])
4105
+ sage: P.is_on_identity_component ()
4106
+ False
4107
+ sage: P.elliptic_logarithm (precision=96)
4108
+ 0.4793482501902193161295330101 + 0.985868850775824102211203849...*I
4109
+ sage: Q = E([3,5])
4110
+ sage: Q.is_on_identity_component()
4111
+ True
4112
+ sage: Q.elliptic_logarithm (precision=96)
4113
+ 1.931128271542559442488585220
4114
+
4115
+ An example with negative discriminant, and a torsion point::
4116
+
4117
+ sage: # needs database_cremona_mini_ellcurve
4118
+ sage: E = EllipticCurve('11a1')
4119
+ sage: E.discriminant() < 0
4120
+ True
4121
+ sage: P = E([16,-61])
4122
+ sage: P.elliptic_logarithm(precision=70)
4123
+ 0.25384186085591068434
4124
+ sage: E.period_lattice().real_period(prec=70) / P.elliptic_logarithm(precision=70)
4125
+ 5.0000000000000000000
4126
+
4127
+ A larger example. The default algorithm uses PARI and makes
4128
+ sure the result has the requested precision::
4129
+
4130
+ sage: E = EllipticCurve([1, 0, 1, -85357462, 303528987048]) #18074g1
4131
+ sage: P = E([4458713781401/835903744, -64466909836503771/24167649046528, 1])
4132
+ sage: P.elliptic_logarithm() # 100 bits
4133
+ 0.27656204014107061464076203097
4134
+
4135
+ The native algorithm ``'sage'`` used to have trouble with
4136
+ precision in this example, but no longer::
4137
+
4138
+ sage: P.elliptic_logarithm(algorithm='sage') # 100 bits
4139
+ 0.27656204014107061464076203097
4140
+
4141
+ This shows that the bug reported at :issue:`4901` has been fixed::
4142
+
4143
+ sage: # needs database_cremona_mini_ellcurve
4144
+ sage: E = EllipticCurve("4390c2")
4145
+ sage: P = E(683762969925/44944,-565388972095220019/9528128)
4146
+ sage: P.elliptic_logarithm()
4147
+ 0.00025638725886520225353198932529
4148
+ sage: P.elliptic_logarithm(precision=64)
4149
+ 0.000256387258865202254
4150
+ sage: P.elliptic_logarithm(precision=65)
4151
+ 0.0002563872588652022535
4152
+ sage: P.elliptic_logarithm(precision=128)
4153
+ 0.00025638725886520225353198932528666427412
4154
+ sage: P.elliptic_logarithm(precision=129)
4155
+ 0.00025638725886520225353198932528666427412
4156
+ sage: P.elliptic_logarithm(precision=256)
4157
+ 0.0002563872588652022535319893252866642741168388008346370015005142128009610936373
4158
+ sage: P.elliptic_logarithm(precision=257)
4159
+ 0.00025638725886520225353198932528666427411683880083463700150051421280096109363730
4160
+
4161
+ Examples over number fields::
4162
+
4163
+ sage: # needs sage.rings.number_field
4164
+ sage: x = polygen(ZZ, 'x')
4165
+ sage: K.<a> = NumberField(x^3 - 2)
4166
+ sage: embs = K.embeddings(CC)
4167
+ sage: E = EllipticCurve([0,1,0,a,a])
4168
+ sage: Ls = [E.period_lattice(e) for e in embs]
4169
+ sage: [L.real_flag for L in Ls]
4170
+ [0, 0, -1]
4171
+ sage: P = E(-1,0) # order 2
4172
+ sage: [L.elliptic_logarithm(P) for L in Ls]
4173
+ [-1.73964256006716 - 1.07861534489191*I,
4174
+ -0.363756518406398 - 1.50699412135253*I, 1.90726488608927]
4175
+
4176
+ sage: # needs sage.rings.number_field
4177
+ sage: E = EllipticCurve([-a^2 - a - 1, a^2 + a])
4178
+ sage: Ls = [E.period_lattice(e) for e in embs]
4179
+ sage: pts = [E(2*a^2 - a - 1 , -2*a^2 - 2*a + 6 ),
4180
+ ....: E(-2/3*a^2 - 1/3 , -4/3*a - 2/3 ),
4181
+ ....: E(5/4*a^2 - 1/2*a , -a^2 - 1/4*a + 9/4 ),
4182
+ ....: E(2*a^2 + 3*a + 4 , -7*a^2 - 10*a - 12 )]
4183
+ sage: [[L.elliptic_logarithm(P) for P in pts] for L in Ls]
4184
+ [[0.250819591818930 - 0.411963479992219*I, -0.290994550611374 - 1.37239400324105*I,
4185
+ -0.693473752205595 - 2.45028458830342*I, -0.151659609775291 - 1.48985406505459*I],
4186
+ [1.33444787667954 - 1.50889756650544*I, 0.792633734249234 - 0.548467043256610*I,
4187
+ 0.390154532655013 + 0.529423541805758*I, 0.931968675085317 - 0.431006981443071*I],
4188
+ [1.14758249500109 + 0.853389664016075*I, 2.59823462472518 + 0.853389664016075*I,
4189
+ 1.75372176444709, 0.303069634723001]]
4190
+
4191
+ ::
4192
+
4193
+ sage: # needs sage.rings.number_field
4194
+ sage: K.<i> = QuadraticField(-1)
4195
+ sage: E = EllipticCurve([0,0,0,9*i-10,21-i])
4196
+ sage: emb = K.embeddings(CC)[1]
4197
+ sage: L = E.period_lattice(emb)
4198
+ sage: P = E(2-i, 4+2*i)
4199
+ sage: L.elliptic_logarithm(P, prec=100)
4200
+ 0.70448375537782208460499649302 - 0.79246725643650979858266018068*I
4201
+ """
4202
+ from sage.rings.number_field.number_field import refine_embedding
4203
+ from sage.rings.real_mpfr import RealField
4204
+ from sage.rings.complex_mpfr import ComplexField
4205
+ from sage.rings.rational_field import QQ
4206
+
4207
+ # Check the trivial case:
4208
+
4209
+ C = ComplexField(precision)
4210
+ if self.is_zero():
4211
+ return C.zero()
4212
+
4213
+ # find a suitable embedding if none was supplied:
4214
+
4215
+ E = self.curve()
4216
+ K = E.base_field()
4217
+ rational = (K is QQ)
4218
+ emb = embedding
4219
+
4220
+ if emb is None:
4221
+ emb = K.embeddings(RealField(precision))
4222
+ if emb:
4223
+ emb = emb[0]
4224
+ else:
4225
+ emb = K.embeddings(ComplexField(precision))[0]
4226
+ else:
4227
+ # Get the precision of the supplied embedding
4228
+ prec = emb.codomain().precision()
4229
+ # if the precision parameter is greater, refine the embedding:
4230
+ if precision > prec:
4231
+ emb = refine_embedding(emb, precision)
4232
+
4233
+ L = E.period_lattice(emb)
4234
+
4235
+ if algorithm == 'sage' or not isinstance(emb.codomain, sage.rings.abc.RealField):
4236
+ return L.elliptic_logarithm(self, precision)
4237
+
4238
+ if algorithm != 'pari':
4239
+ raise ValueError("algorithm must be either 'pari' or 'sage'")
4240
+
4241
+ # From now on emb() is a real embedding of K into
4242
+ # RealField(precision). We interface with the PARI library.
4243
+
4244
+ x, y = self.xy()
4245
+ if rational: # work with exact coordinates
4246
+ E_work = E
4247
+ pt_pari = pari([x, y])
4248
+ else: # use the embedding to get real coordinates
4249
+ ai = [emb(a) for a in E.a_invariants()]
4250
+ E_work = EllipticCurve(ai) # defined over RR
4251
+ pt_pari = pari([emb(x), emb(y)])
4252
+ working_prec = precision
4253
+ E_pari = E_work.pari_curve()
4254
+ log_pari = E_pari.ellpointtoz(pt_pari, precision=working_prec)
4255
+
4256
+ while log_pari.bitprecision() < precision:
4257
+ # result is not precise enough, re-compute with double
4258
+ # precision. if the base field is not QQ, this
4259
+ # requires modifying the precision of the embedding,
4260
+ # the curve, and the point
4261
+ working_prec = 2*working_prec
4262
+ if not rational:
4263
+ emb = refine_embedding(emb, working_prec)
4264
+ ai = [emb(a) for a in E.a_invariants()]
4265
+ E_work = EllipticCurve(ai) # defined over RR
4266
+ pt_pari = pari([emb(x), emb(y)])
4267
+ E_pari = E_work.pari_curve()
4268
+ log_pari = E_pari.ellpointtoz(pt_pari, precision=working_prec)
4269
+
4270
+ # normalization step
4271
+ r, i = C(log_pari)
4272
+ wR, wI = L.basis(prec=precision)
4273
+ k = (r/wR).floor()
4274
+ if k:
4275
+ r -= k*wR
4276
+ if self.is_on_identity_component(emb):
4277
+ return C(r)
4278
+ # Now there are two components and P is on the non-identity one
4279
+ return C(r)+C(wI/2)
4280
+
4281
+ def padic_elliptic_logarithm(self, p, absprec=20):
4282
+ r"""
4283
+ Compute the `p`-adic elliptic logarithm of this point.
4284
+
4285
+ INPUT:
4286
+
4287
+ - ``p`` -- integer; a prime
4288
+
4289
+ - ``absprec`` -- integer (default: 20); the initial `p`-adic absolute
4290
+ precision of the computation
4291
+
4292
+ OUTPUT:
4293
+
4294
+ The `p`-adic elliptic logarithm of self, with precision ``absprec``.
4295
+
4296
+ AUTHORS:
4297
+
4298
+ - Tobias Nagel
4299
+ - Michael Mardaus
4300
+ - John Cremona
4301
+
4302
+ ALGORITHM:
4303
+
4304
+ For points in the formal group (i.e. not integral at `p`) we
4305
+ take the ``log()`` function from the formal groups module and
4306
+ evaluate it at `-x/y`. Otherwise we first multiply the point
4307
+ to get into the formal group, and divide the result
4308
+ afterwards.
4309
+
4310
+ .. TODO::
4311
+
4312
+ See comments at :issue:`4805`. Currently the absolute
4313
+ precision of the result may be less than the given value
4314
+ of absprec, and error-handling is imperfect.
4315
+
4316
+ EXAMPLES::
4317
+
4318
+ sage: E = EllipticCurve([0,1,1,-2,0])
4319
+ sage: E(0).padic_elliptic_logarithm(3) # needs sage.rings.padics
4320
+ 0
4321
+ sage: P = E(0, 0) # needs sage.rings.padics
4322
+ sage: P.padic_elliptic_logarithm(3) # needs sage.rings.padics
4323
+ 2 + 2*3 + 3^3 + 2*3^7 + 3^8 + 3^9 + 3^11 + 3^15 + 2*3^17 + 3^18 + O(3^19)
4324
+ sage: P.padic_elliptic_logarithm(3).lift() # needs sage.rings.padics
4325
+ 660257522
4326
+ sage: P = E(-11/9, 28/27) # needs sage.rings.padics
4327
+ sage: [(2*P).padic_elliptic_logarithm(p)/P.padic_elliptic_logarithm(p) for p in prime_range(20)] # long time, needs sage.rings.padics
4328
+ [2 + O(2^19), 2 + O(3^20), 2 + O(5^19), 2 + O(7^19), 2 + O(11^19), 2 + O(13^19), 2 + O(17^19), 2 + O(19^19)]
4329
+ sage: [(3*P).padic_elliptic_logarithm(p)/P.padic_elliptic_logarithm(p) for p in prime_range(12)] # long time, needs sage.rings.padics
4330
+ [1 + 2 + O(2^19), 3 + 3^20 + O(3^21), 3 + O(5^19), 3 + O(7^19), 3 + O(11^19)]
4331
+ sage: [(5*P).padic_elliptic_logarithm(p)/P.padic_elliptic_logarithm(p) for p in prime_range(12)] # long time, needs sage.rings.padics
4332
+ [1 + 2^2 + O(2^19), 2 + 3 + O(3^20), 5 + O(5^19), 5 + O(7^19), 5 + O(11^19)]
4333
+
4334
+ An example which arose during reviewing :issue:`4741`::
4335
+
4336
+ sage: # needs database_cremona_mini_ellcurve
4337
+ sage: E = EllipticCurve('794a1')
4338
+ sage: P = E(-1,2)
4339
+ sage: P.padic_elliptic_logarithm(2) # default precision=20 # needs sage.rings.padics
4340
+ 2^4 + 2^5 + 2^6 + 2^8 + 2^9 + 2^13 + 2^14 + 2^15 + O(2^16)
4341
+ sage: P.padic_elliptic_logarithm(2, absprec=30) # needs sage.rings.padics
4342
+ 2^4 + 2^5 + 2^6 + 2^8 + 2^9 + 2^13 + 2^14 + 2^15 + 2^22 + 2^23 + 2^24 + O(2^26)
4343
+ sage: P.padic_elliptic_logarithm(2, absprec=40) # needs sage.rings.padics
4344
+ 2^4 + 2^5 + 2^6 + 2^8 + 2^9 + 2^13 + 2^14 + 2^15 + 2^22 + 2^23 + 2^24
4345
+ + 2^28 + 2^29 + 2^31 + 2^34 + O(2^35)
4346
+ """
4347
+ if not p.is_prime():
4348
+ raise ValueError('p must be prime')
4349
+ debug = False # True
4350
+ if debug:
4351
+ print("P=", self, "; p=", p, " with precision ", absprec)
4352
+ E = self.curve()
4353
+ Q_p = Qp(p, absprec)
4354
+ if self.has_finite_order():
4355
+ return Q_p(0)
4356
+ while True:
4357
+ try:
4358
+ Ep = E.change_ring(Q_p)
4359
+ P = Ep(self)
4360
+ x, y = P.xy()
4361
+ break
4362
+ except (PrecisionError, ArithmeticError, ZeroDivisionError):
4363
+ absprec *= 2
4364
+ Q_p = Qp(p, absprec)
4365
+ if debug:
4366
+ print("x,y=", (x, y))
4367
+ f = 1 # f will be such that f*P is in the formal group E^1(Q_p)
4368
+ if x.valuation() >= 0: # P is not in E^1
4369
+ if not self.has_good_reduction(p): # P is not in E^0
4370
+ n = E.tamagawa_exponent(p) # n*P has good reduction at p
4371
+ if debug:
4372
+ print("Tamagawa exponent = =", n)
4373
+ f = n
4374
+ P = n*P # lies in E^0
4375
+ if debug:
4376
+ print("P=", P)
4377
+ try:
4378
+ x, y = P.xy()
4379
+ except ZeroDivisionError:
4380
+ raise ValueError("Insufficient precision in "
4381
+ "p-adic_elliptic_logarithm()")
4382
+ if debug:
4383
+ print("x,y=", (x, y))
4384
+ if x.valuation() >= 0: # P is still not in E^1
4385
+ t = E.local_data(p).bad_reduction_type()
4386
+ if t is None:
4387
+ m = E.reduction(p).abelian_group().exponent()
4388
+ else:
4389
+ m = p - t
4390
+ if debug:
4391
+ print("mod p exponent = =", m)
4392
+ # now m*(n*P) reduces to the identity mod p, so is
4393
+ # in E^1(Q_p)
4394
+ f *= m
4395
+ P = m*P # lies in E^1
4396
+ try:
4397
+ x, y = P.xy()
4398
+ except ZeroDivisionError:
4399
+ raise ValueError("Insufficient precision in "
4400
+ "p-adic_elliptic_logarithm()")
4401
+ if debug:
4402
+ print("f=", f)
4403
+ print("x,y=", (x, y))
4404
+ vx = x.valuation()
4405
+ vy = y.valuation()
4406
+ v = vx-vy
4407
+ if not (v > 0 and vx == -2*v and vy == -3*v):
4408
+ raise ValueError("Insufficient precision in "
4409
+ "p-adic_elliptic_logarithm()")
4410
+ try:
4411
+ t = -x/y
4412
+ except (ZeroDivisionError, PrecisionError):
4413
+ raise ValueError("Insufficient precision in "
4414
+ "p-adic_elliptic_logarithm()")
4415
+ if debug:
4416
+ print("t=", t, ", with valuation ", v)
4417
+ phi = Ep.formal().log(prec=1+absprec//v)
4418
+ return phi(t)/f
4419
+
4420
+
4421
+ class EllipticCurvePoint_finite_field(EllipticCurvePoint_field):
4422
+ r"""
4423
+ Class for elliptic curve points over finite fields.
4424
+ """
4425
+ def _magma_init_(self, magma):
4426
+ """
4427
+ Return a string representation of ``self`` that ``MAGMA`` can
4428
+ use for input.
4429
+
4430
+ EXAMPLES::
4431
+
4432
+ sage: E = EllipticCurve(GF(17), [1,-1])
4433
+ sage: P = E([13, 4])
4434
+ sage: P._magma_init_(magma) # optional - magma
4435
+ 'EllipticCurve([_sage_ref...|GF(17)!0,GF(17)!0,GF(17)!0,GF(17)!1,GF(17)!16])![13,4]'
4436
+ """
4437
+ E = self.curve()._magma_init_(magma)
4438
+ x, y = self.xy()
4439
+ return "%s![%s,%s]" % (E, x, y)
4440
+
4441
+ def _acted_upon_(self, other, side):
4442
+ r"""
4443
+ We implement ``_acted_upon_`` to make use of the specialized faster
4444
+ scalar multiplication from PARI, and to keep track of cached point
4445
+ orders when scalar multiplications are applied.
4446
+
4447
+ EXAMPLES::
4448
+
4449
+ sage: # needs sage.rings.finite_rings
4450
+ sage: P = EllipticCurve(GF(65537), [2,2]).lift_x(6)
4451
+ sage: P.order().factor()
4452
+ 2^2 * 3 * 37^2
4453
+ sage: getattr(74*P, '_order', None)
4454
+ 222
4455
+ sage: getattr(P*4070, '_order', None)
4456
+ 222
4457
+ sage: getattr(506*P*37, '_order', None)
4458
+ 222
4459
+ """
4460
+ k = ZZ(other)
4461
+ E = self.curve()
4462
+
4463
+ try:
4464
+ pariQ = pari.ellmul(E, self, k)
4465
+ except PariError as err:
4466
+ if str(err.errdata().component(1)) == "Fp_inv":
4467
+ val = err.errdata().component(2)
4468
+ a = val.lift()
4469
+ N = val.mod()
4470
+ N1 = N.gcd(a)
4471
+ N2 = N//N1
4472
+ raise ZeroDivisionError(
4473
+ f"Inverse of {a} does not exist"
4474
+ f" (characteristic = {N} = {N1}*{N2})")
4475
+ pariQ = None
4476
+
4477
+ if pariQ is not None:
4478
+ if pariQ == [0]:
4479
+ vQ = 0
4480
+ else:
4481
+ assert len(pariQ) == 2
4482
+ vQ = Sequence(tuple(pariQ) + (1,), E.base_ring())
4483
+ Q = EllipticCurvePoint_finite_field(E, vQ, check=False)
4484
+
4485
+ else:
4486
+ Q = IntegerMulAction(ZZ, self.parent())._act_(k, self)
4487
+
4488
+ n = getattr(self, '_order', None)
4489
+ if n is not None:
4490
+ Q._order = n // n.gcd(k) # Lagrange's theorem
4491
+
4492
+ return Q
4493
+
4494
+ def log(self, base):
4495
+ r"""
4496
+ Return the discrete logarithm of this point to the given ``base``.
4497
+ In other words, return an integer `x` such that `xP = Q` where
4498
+ `P` is ``base`` and `Q` is this point.
4499
+
4500
+ If ``base`` is a list or tuple of two points, then this function
4501
+ solves a two-dimensional discrete logarithm: Given `(P_1,P_2)` in
4502
+ ``base``, it returns a tuple of integers `(x,y)` such that
4503
+ `[x]P_1 + [y]P_2 = Q`, where `Q` is this point.
4504
+
4505
+ A :exc:`ValueError` is raised if there is no solution.
4506
+
4507
+ ALGORITHM:
4508
+
4509
+ To compute the actual logarithm, :pari:`elllog` is called.
4510
+
4511
+ However, ``elllog()`` does not guarantee termination if `Q`
4512
+ is not a multiple of `P`, so we first need to check subgroup
4513
+ membership. This is done as follows:
4514
+
4515
+ - Let `n` denote the order of `P`. First check that `nQ` equals
4516
+ the point at infinity (and hence the order of `Q` divides `n`).
4517
+
4518
+ - If the curve order `\#E` has been cached, check whether
4519
+ `\gcd(n^2, \#E) = n`. If this holds, the curve has cyclic
4520
+ `n`-torsion, hence all points whose order divides `n` must be
4521
+ multiples of `P` and we are done.
4522
+
4523
+ - Otherwise (if this test is inconclusive), check that the Weil
4524
+ pairing of `P` and `Q` is trivial.
4525
+
4526
+ For anomalous curves with `\#E = p`, the
4527
+ :meth:`padic_elliptic_logarithm` function is called.
4528
+
4529
+ For two-dimensional logarithms, we first compute the Weil pairings
4530
+ of `Q` with `P_1` and `P_2` and their logarithms relative to the
4531
+ pairing of `P_1` and `P_2`; this allows reading off `x` and `y`
4532
+ modulo the part of the order where `P_1` and `P_2` are independent.
4533
+ Modulo the remaining part of the order the logarithm ends up being
4534
+ effectively one-dimensional, so we can reduce the problem to the
4535
+ basic one-dimensional case and finally recombine the results.
4536
+
4537
+ INPUT:
4538
+
4539
+ - ``base`` -- another point or sequence of two points on the same
4540
+ curve as ``self``
4541
+
4542
+ OUTPUT:
4543
+
4544
+ (integer) -- The discrete logarithm of `Q` with respect to `P`,
4545
+ which is an integer `x` with `0\le x<\mathrm{ord}(P)` such that
4546
+ `xP=Q`, if one exists. In the case of two points `P_1,P_2`, two
4547
+ integers `x,y` with `0\le x<\mathrm{ord}(P_1)` and
4548
+ `0\le y<\mathrm{ord}(P_2)` such that `[x]P_1 + [y]P_2 = Q`.
4549
+
4550
+ AUTHORS:
4551
+
4552
+ - John Cremona. Adapted to use generic functions 2008-04-05.
4553
+ - Lorenz Panny (2022): switch to PARI.
4554
+ - Lorenz Panny (2024): the two-dimensional case.
4555
+
4556
+ EXAMPLES::
4557
+
4558
+ sage: # needs sage.rings.finite_rings
4559
+ sage: F = GF((3,6),'a')
4560
+ sage: a = F.gen()
4561
+ sage: E = EllipticCurve([0,1,1,a,a])
4562
+ sage: E.cardinality()
4563
+ 762
4564
+ sage: P = E.gens()[0]
4565
+ sage: Q = 400*P
4566
+ sage: Q.log(P)
4567
+ 400
4568
+
4569
+ ::
4570
+
4571
+ sage: # needs sage.rings.finite_rings
4572
+ sage: F = GF((5, 60), 'a')
4573
+ sage: E = EllipticCurve(F, [1, 1])
4574
+ sage: E.abelian_group()
4575
+ Additive abelian group isomorphic to Z/194301464603136995341424045476456938000 + Z/4464 embedded in Abelian group of points on Elliptic Curve defined by y^2 = x^3 + x + 1 over Finite Field in a of size 5^60
4576
+ sage: P, Q = E.gens() # cached generators from .abelian_group()
4577
+ sage: T = 1234567890987654321*P + 1337*Q
4578
+ sage: T.log([P, Q])
4579
+ (1234567890987654321, 1337)
4580
+
4581
+ TESTS:
4582
+
4583
+ Some random testing::
4584
+
4585
+ sage: # needs sage.rings.finite_rings
4586
+ sage: sz = randint(8,32)
4587
+ sage: e = randint(1,3)
4588
+ sage: p = random_prime(ceil(2**(sz/e)))
4589
+ sage: E = EllipticCurve(j=GF((p,e),'a').random_element())
4590
+ sage: P = E.random_point()
4591
+ sage: Q = randrange(2**999) * P
4592
+ sage: x = Q.log(P)
4593
+ sage: x*P == Q
4594
+ True
4595
+
4596
+ ::
4597
+
4598
+ sage: # needs sage.rings.finite_rings
4599
+ sage: sz = randint(16,24)
4600
+ sage: e = randint(1,6)
4601
+ sage: p = random_prime(ceil(2**(sz/e)))
4602
+ sage: E = EllipticCurve(j=GF((p,e),'a').random_element())
4603
+ sage: E = choice(E.twists())
4604
+ sage: P = E.random_point()
4605
+ sage: Q = E.random_point()
4606
+ sage: T = randrange(2^99) * P + randrange(2^99) * Q
4607
+ sage: x, y = T.log([P, Q])
4608
+ sage: 0 <= x < P.order()
4609
+ True
4610
+ sage: 0 <= y < Q.order()
4611
+ True
4612
+ sage: T == x*P + y*Q
4613
+ True
4614
+ """
4615
+ # handle the two-dimensional case first
4616
+ if isinstance(base, (list, tuple)):
4617
+ if not base:
4618
+ return self.log(self.curve().zero())
4619
+ elif len(base) == 1:
4620
+ return self.log(base[0])
4621
+ elif len(base) > 2:
4622
+ raise ValueError('sequence must have length <= 2')
4623
+
4624
+ P1, P2 = base
4625
+ if P1 not in self.parent() or P2 not in self.parent():
4626
+ raise ValueError('points do not lie on the same curve')
4627
+
4628
+ n1, n2 = P1.order(), P2.order()
4629
+ n = n1.lcm(n2)
4630
+ if not hasattr(self, '_order'):
4631
+ if n * self:
4632
+ raise ValueError('ECDLog problem has no solution (order does not divide order of base)')
4633
+ self.set_order(multiple=n, check=False)
4634
+ if not self.order().divides(n):
4635
+ raise ValueError('ECDLog problem has no solution (order does not divide order of base)')
4636
+
4637
+ # find the solution modulo the part where P1,P2 are independent
4638
+ z = P1.weil_pairing(P2, n)
4639
+ o = generic.order_from_multiple(z, n1.gcd(n2), operation='*')
4640
+ if o.is_one():
4641
+ # slight optimization, but also workaround for PARI bug #2562
4642
+ x0, y0 = ZZ.zero(), ZZ.zero()
4643
+ else:
4644
+ v = self.weil_pairing(P2, n)
4645
+ w = P1.weil_pairing(self, n)
4646
+ x0, y0 = v.log(z, o), w.log(z, o)
4647
+
4648
+ T = self - x0*P1 - y0*P2
4649
+ if not T:
4650
+ return x0, y0
4651
+
4652
+ T1 = n//n1 * T
4653
+ T2 = n//n2 * T
4654
+ T1.set_order(multiple=n1, check=False)
4655
+ T2.set_order(multiple=n2, check=False)
4656
+ x1 = T1.log(o*P1)
4657
+ y1 = T2.log(o*P2)
4658
+
4659
+ # assert n//n1 * self == (x1*o + n//n1*x0) * P1 + n//n1*y0 * P2
4660
+ # assert n//n2 * self == n//n2*x0 * P1 + (y1*o + n//n2*y0) * P2
4661
+
4662
+ _,u,v = (n//n1).xgcd(n//n2)
4663
+ assert _.is_one()
4664
+ x = (u * (x1*o + n//n1*x0) + v * (n//n2*x0)) % n1
4665
+ y = (u * (n//n1*y0) + v * (y1*o + n//n2*y0)) % n2
4666
+
4667
+ # assert x*P1 + y*P2 == self
4668
+ return x, y
4669
+
4670
+ if base not in self.parent():
4671
+ raise ValueError('not a point on the same curve')
4672
+ n = base.order()
4673
+ if (hasattr(self, '_order') and not self._order.divides(n)) or n*self:
4674
+ raise ValueError('ECDLog problem has no solution (order does not divide order of base)')
4675
+ E = self.curve()
4676
+ F = E.base_ring()
4677
+ p = F.cardinality()
4678
+
4679
+ if F.is_prime_field() and n == p:
4680
+ # Anomalous case
4681
+ return base.padic_elliptic_logarithm(self, p)
4682
+ elif hasattr(E, '_order') and E._order.gcd(n**2) == n:
4683
+ pass # cyclic rational n-torsion -> okay
4684
+ elif base.weil_pairing(self, n) != 1:
4685
+ raise ValueError('ECDLog problem has no solution (non-trivial Weil pairing)')
4686
+
4687
+ return ZZ(pari.elllog(self.curve(), self, base, n))
4688
+
4689
+ def padic_elliptic_logarithm(self, Q, p):
4690
+ r"""
4691
+ Return the discrete logarithm of `Q` to base `P` = ``self``,
4692
+ that is, an integer `x` such that `xP = Q` only for anomalous curves.
4693
+
4694
+ ALGORITHM:
4695
+
4696
+ Discrete logarithm computed as in [Sma1999]_ with a loop to avoid
4697
+ the canonical lift.
4698
+
4699
+ INPUT:
4700
+
4701
+ - ``Q`` -- point; another point on the same curve as ``self``
4702
+ - ``p`` -- integer; a prime equal to the order of the curve
4703
+
4704
+ OUTPUT:
4705
+
4706
+ (integer) -- The discrete logarithm of `Q` with respect to `P`,
4707
+ which is an integer `x` with `0\le x<\mathrm{ord}(P)` such that
4708
+ `xP=Q`.
4709
+
4710
+ AUTHORS:
4711
+
4712
+ - Sylvain Pelissier (2022) based on Samuel Neves code_.
4713
+
4714
+ .. _code: https://crypto.stackexchange.com/questions/70454/why-smarts-attack-doesnt-work-on-this-ecdlp/70508#70508
4715
+
4716
+ EXAMPLES::
4717
+
4718
+ sage: # needs sage.rings.finite_rings
4719
+ sage: p = 235322474717419
4720
+ sage: b = 8856682
4721
+ sage: E = EllipticCurve(GF(p), [0, b])
4722
+ sage: P = E(200673830421813, 57025307876612)
4723
+ sage: Q = E(40345734829479, 211738132651297)
4724
+ sage: x = P.padic_elliptic_logarithm(Q, p) # needs sage.rings.padics
4725
+ sage: x * P == Q # needs sage.rings.padics
4726
+ True
4727
+
4728
+ TESTS:
4729
+
4730
+ Some testing::
4731
+
4732
+ sage: # needs sage.rings.finite_rings
4733
+ sage: a = 49850651047495986645822557378918223
4734
+ sage: b = 21049438014429831351540675253466229
4735
+ sage: p = 54283205379427155782089046839411711
4736
+ sage: E = EllipticCurve(GF(p), [a, b])
4737
+ sage: P = E.random_point()
4738
+ sage: Q = randrange(0, p-1) * P
4739
+ sage: x = P.padic_elliptic_logarithm(Q, p) # needs sage.rings.padics
4740
+ sage: x*P == Q # needs sage.rings.padics
4741
+ True
4742
+ """
4743
+ E = self.curve()
4744
+ F = E.base()
4745
+
4746
+ if Q.is_zero():
4747
+ k = 0
4748
+ else:
4749
+ for k in range(p):
4750
+ Eqp = EllipticCurve(Qp(p, 2), [ZZ(t) + k * p for t in E.a_invariants()])
4751
+
4752
+ P_Qps = Eqp.lift_x(ZZ(self.x()), all=True)
4753
+ for P_Qp in P_Qps:
4754
+ if F(P_Qp.y()) == self.y():
4755
+ break
4756
+
4757
+ Q_Qps = Eqp.lift_x(ZZ(Q.x()), all=True)
4758
+ for Q_Qp in Q_Qps:
4759
+ if F(Q_Qp.y()) == Q.y():
4760
+ break
4761
+
4762
+ pP = p * P_Qp
4763
+ pQ = p * Q_Qp
4764
+ if (pP.is_zero() or pQ.is_zero()):
4765
+ # Should happen with probability 1/p
4766
+ continue
4767
+ else:
4768
+ break
4769
+
4770
+ x_P,y_P = pP.xy()
4771
+ x_Q,y_Q = pQ.xy()
4772
+
4773
+ phi_P = -(x_P / y_P)
4774
+ phi_Q = -(x_Q / y_Q)
4775
+ k = phi_Q / phi_P
4776
+
4777
+ return ZZ(k % p)
4778
+
4779
+ def has_finite_order(self) -> bool:
4780
+ r"""
4781
+ Return ``True`` if this point has finite additive order as an element
4782
+ of the group of points on this curve.
4783
+
4784
+ Since the base field is finite, the answer will always be ``True``.
4785
+
4786
+ EXAMPLES::
4787
+
4788
+ sage: E = EllipticCurve(GF(7), [1,3])
4789
+ sage: P = E.points()[3]
4790
+ sage: P.has_finite_order()
4791
+ True
4792
+ """
4793
+ return True
4794
+
4795
+ def order(self, algorithm=None):
4796
+ r"""
4797
+ Return the order of this point on the elliptic curve.
4798
+
4799
+ ALGORITHM: Use PARI function :pari:`ellorder`.
4800
+
4801
+ .. NOTE::
4802
+
4803
+ :meth:`additive_order` is a synonym for :meth:`order`
4804
+
4805
+ INPUT:
4806
+
4807
+ - ``algorithm`` -- string (default: ``None``) -- the algorithm to use,
4808
+ can be ``'pari'``, ``'generic'``, ``'generic_small'`` or ``'hybrid'``.
4809
+ ``'generic_small'`` may be preferable when the order of the point
4810
+ is very small compared to the order of the torsion,
4811
+ and the order of the torsion is hard to factorize.
4812
+ ``'hybrid'`` uses a combination of ``'pari'`` and ``'generic_small'``
4813
+ to ensure the complexity of computing the order is
4814
+ roughly the square root of the order, and that it is still fast
4815
+ if the order only have very small prime factors.
4816
+
4817
+ EXAMPLES::
4818
+
4819
+ sage: # needs sage.rings.finite_rings
4820
+ sage: k.<a> = GF((5,5))
4821
+ sage: E = EllipticCurve(k,[2,4]); E
4822
+ Elliptic Curve defined by y^2 = x^3 + 2*x + 4 over Finite Field in a of size 5^5
4823
+ sage: P = E(3*a^4 + 3*a, 2*a + 1)
4824
+ sage: P.order()
4825
+ 3227
4826
+ sage: Q = E(0,2)
4827
+ sage: Q.order()
4828
+ 7
4829
+ sage: Q.additive_order()
4830
+ 7
4831
+
4832
+ ::
4833
+
4834
+ sage: # needs sage.rings.finite_rings
4835
+ sage: p = next_prime(2^150)
4836
+ sage: E = EllipticCurve(GF(p), [1,1])
4837
+ sage: P = E(831623307675610677632782670796608848711856078,
4838
+ ....: 42295786042873366706573292533588638217232964)
4839
+ sage: P.order()
4840
+ 1427247692705959881058262545272474300628281448
4841
+ sage: P.order() == E.cardinality()
4842
+ True
4843
+
4844
+ The next example has `j(E)=0`::
4845
+
4846
+ sage: # needs sage.rings.finite_rings
4847
+ sage: p = 33554501
4848
+ sage: F.<u> = GF((p,2))
4849
+ sage: E = EllipticCurve(F, [0,1])
4850
+ sage: E.j_invariant()
4851
+ 0
4852
+ sage: P = E.random_point()
4853
+ sage: P.order() # random
4854
+ 16777251
4855
+
4856
+ Similarly when `j(E)=1728`::
4857
+
4858
+ sage: # needs sage.rings.finite_rings
4859
+ sage: p = 33554473
4860
+ sage: F.<u> = GF((p,2))
4861
+ sage: E = EllipticCurve(F, [1,0])
4862
+ sage: E.j_invariant()
4863
+ 1728
4864
+ sage: P = E.random_point()
4865
+ sage: P.order() # random
4866
+ 46912611635760
4867
+
4868
+ Tests ``algorithm='generic_small'``::
4869
+
4870
+ sage: # needs sage.rings.finite_rings
4871
+ sage: p = next_prime(2^256)
4872
+ sage: q = next_prime(p)
4873
+ sage: E = EllipticCurve(GF(660*p*q-1), [1, 0])
4874
+ sage: P = E.lift_x(11) * p * q
4875
+ sage: P.order() # not tested (pari will try to factor p*q which takes forever)
4876
+ sage: P.order(algorithm='generic_small')
4877
+ 330
4878
+ sage: P.order() # works due to caching
4879
+ 330
4880
+
4881
+ TESTS:
4882
+
4883
+ Tests ``algorithm='hybrid'``::
4884
+
4885
+ sage: # needs sage.rings.finite_rings
4886
+ sage: P.order(algorithm='hybrid')
4887
+ 330
4888
+ sage: E = EllipticCurve(GF(60*2^200-1), [1, 0])
4889
+ sage: E.0._compute_order(algorithm='hybrid') == 60*2^200
4890
+ True
4891
+
4892
+ Check that the order actually gets cached (:issue:`32786`)::
4893
+
4894
+ sage: # needs sage.rings.finite_rings
4895
+ sage: E = EllipticCurve(GF(31337), [42,1])
4896
+ sage: P = E.lift_x(1)
4897
+ sage: hasattr(P, '_order')
4898
+ False
4899
+ sage: P.order()
4900
+ 15649
4901
+ sage: P._order
4902
+ 15649
4903
+
4904
+ The curve order should also get cached as a side effect
4905
+ of computing a point order::
4906
+
4907
+ sage: E._order # needs sage.rings.finite_rings
4908
+ 31298
4909
+ """
4910
+ return super().order(algorithm)
4911
+
4912
+ def _compute_order(self, algorithm):
4913
+ """
4914
+ TESTS::
4915
+
4916
+ sage: # needs sage.rings.finite_rings
4917
+ sage: E = EllipticCurve(GF(31337), [42, 1])
4918
+ sage: P = E.lift_x(1)
4919
+ sage: P._compute_order('pari')
4920
+ 15649
4921
+ sage: P._compute_order('generic_small')
4922
+ 15649
4923
+ sage: P._compute_order('unknown')
4924
+ Traceback (most recent call last):
4925
+ ...
4926
+ NotImplementedError: algorithm 'unknown' not implemented for order of a point on an elliptic curve over finite fields
4927
+ """
4928
+ E = self.curve()
4929
+
4930
+ if algorithm == 'pari' or algorithm is None:
4931
+ if getattr(E, '_order', None) is None:
4932
+ # The curve order will be computed and cached by PARI during
4933
+ # ellorder() anyway. We might as well cache it here too.
4934
+ E._order = Integer(E.pari_curve().ellcard())
4935
+
4936
+ return Integer(E.pari_curve().ellorder(self, E._order))
4937
+
4938
+ if algorithm in ('generic_small', 'hybrid'):
4939
+ return super()._compute_order(algorithm)
4940
+
4941
+ raise NotImplementedError(f"algorithm {algorithm!r} not implemented for "
4942
+ "order of a point on an elliptic curve over finite fields")
4943
+
4944
+ additive_order = order