passagemath-pari 10.6.32__cp314-cp314-musllinux_1_2_x86_64.whl

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

Potentially problematic release.


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

Files changed (331) hide show
  1. PARIKernel/__init__.py +2 -0
  2. PARIKernel/__main__.py +5 -0
  3. PARIKernel/io.cpython-314-x86_64-linux-musl.so +0 -0
  4. PARIKernel/io.pxd +7 -0
  5. PARIKernel/io.pyx +84 -0
  6. PARIKernel/kernel.cpython-314-x86_64-linux-musl.so +0 -0
  7. PARIKernel/kernel.pyx +260 -0
  8. PARIKernel/paridecl.pxd +95 -0
  9. PARIKernel/svg.cpython-314-x86_64-linux-musl.so +0 -0
  10. PARIKernel/svg.pyx +52 -0
  11. cypari2/__init__.py +8 -0
  12. cypari2/auto_paridecl.pxd +1070 -0
  13. cypari2/closure.cpython-314-x86_64-linux-musl.so +0 -0
  14. cypari2/closure.pxd +5 -0
  15. cypari2/closure.pyx +246 -0
  16. cypari2/convert.cpython-314-x86_64-linux-musl.so +0 -0
  17. cypari2/convert.pxd +80 -0
  18. cypari2/convert.pyx +613 -0
  19. cypari2/custom_block.cpython-314-x86_64-linux-musl.so +0 -0
  20. cypari2/custom_block.pyx +30 -0
  21. cypari2/cypari.h +13 -0
  22. cypari2/gen.cpython-314-x86_64-linux-musl.so +0 -0
  23. cypari2/gen.pxd +69 -0
  24. cypari2/gen.pyx +4819 -0
  25. cypari2/handle_error.cpython-314-x86_64-linux-musl.so +0 -0
  26. cypari2/handle_error.pxd +7 -0
  27. cypari2/handle_error.pyx +232 -0
  28. cypari2/pari_instance.cpython-314-x86_64-linux-musl.so +0 -0
  29. cypari2/pari_instance.pxd +27 -0
  30. cypari2/pari_instance.pyx +1438 -0
  31. cypari2/paridecl.pxd +5353 -0
  32. cypari2/paripriv.pxd +34 -0
  33. cypari2/pycore_long.h +98 -0
  34. cypari2/pycore_long.pxd +9 -0
  35. cypari2/stack.cpython-314-x86_64-linux-musl.so +0 -0
  36. cypari2/stack.pxd +27 -0
  37. cypari2/stack.pyx +278 -0
  38. cypari2/string_utils.cpython-314-x86_64-linux-musl.so +0 -0
  39. cypari2/string_utils.pxd +29 -0
  40. cypari2/string_utils.pyx +65 -0
  41. cypari2/types.pxd +147 -0
  42. passagemath_pari-10.6.32.data/data/etc/jupyter/nbconfig/notebook.d/gp-mode.json +5 -0
  43. passagemath_pari-10.6.32.data/data/share/jupyter/kernels/pari_jupyter/kernel.js +28 -0
  44. passagemath_pari-10.6.32.data/data/share/jupyter/kernels/pari_jupyter/kernel.json +6 -0
  45. passagemath_pari-10.6.32.data/data/share/jupyter/kernels/pari_jupyter/logo-64x64.png +0 -0
  46. passagemath_pari-10.6.32.data/data/share/jupyter/kernels/xeus-gp/kernel.json +13 -0
  47. passagemath_pari-10.6.32.data/data/share/jupyter/kernels/xeus-gp/logo-32x32.png +0 -0
  48. passagemath_pari-10.6.32.data/data/share/jupyter/kernels/xeus-gp/logo-64x64.png +0 -0
  49. passagemath_pari-10.6.32.data/data/share/jupyter/kernels/xeus-gp/logo-svg.svg +75 -0
  50. passagemath_pari-10.6.32.data/data/share/jupyter/nbextensions/gp-mode/gp.js +284 -0
  51. passagemath_pari-10.6.32.data/data/share/jupyter/nbextensions/gp-mode/main.js +15 -0
  52. passagemath_pari-10.6.32.dist-info/METADATA +209 -0
  53. passagemath_pari-10.6.32.dist-info/RECORD +331 -0
  54. passagemath_pari-10.6.32.dist-info/WHEEL +5 -0
  55. passagemath_pari-10.6.32.dist-info/top_level.txt +4 -0
  56. passagemath_pari.libs/libcrypto-f04afe95.so.3 +0 -0
  57. passagemath_pari.libs/libflint-fd6f12fc.so.21.0.0 +0 -0
  58. passagemath_pari.libs/libgcc_s-0cd532bd.so.1 +0 -0
  59. passagemath_pari.libs/libgf2x-9e30c3e3.so.3.0.0 +0 -0
  60. passagemath_pari.libs/libgfortran-2c33b284.so.5.0.0 +0 -0
  61. passagemath_pari.libs/libgivaro-9a94c711.so.9.2.1 +0 -0
  62. passagemath_pari.libs/libgmp-0e7fc84e.so.10.5.0 +0 -0
  63. passagemath_pari.libs/libgmpxx-9e08595c.so.4.7.0 +0 -0
  64. passagemath_pari.libs/libgsl-42cda06f.so.28.0.0 +0 -0
  65. passagemath_pari.libs/libmpfr-aaecbfc0.so.6.2.1 +0 -0
  66. passagemath_pari.libs/libncursesw-9c9e32c3.so.6.5 +0 -0
  67. passagemath_pari.libs/libntl-26885ca2.so.44.0.1 +0 -0
  68. passagemath_pari.libs/libopenblasp-r0-905cb27d.3.29.so +0 -0
  69. passagemath_pari.libs/libpari-gmp-tls-f31f908f.so.2.17.2 +0 -0
  70. passagemath_pari.libs/libquadmath-bb76a5fc.so.0.0.0 +0 -0
  71. passagemath_pari.libs/libreadline-06542304.so.8.2 +0 -0
  72. passagemath_pari.libs/libstdc++-5d72f927.so.6.0.33 +0 -0
  73. passagemath_pari.libs/libuuid-f3770415.so.1.3.0 +0 -0
  74. passagemath_pari.libs/libxeus-735780ff.so.13.1.0 +0 -0
  75. passagemath_pari.libs/libxeus-zmq-c68577b4.so.6.0.1 +0 -0
  76. passagemath_pari.libs/libzmq-1ba9a3da.so.5.2.5 +0 -0
  77. sage/all__sagemath_pari.py +26 -0
  78. sage/databases/all__sagemath_pari.py +7 -0
  79. sage/databases/conway.py +274 -0
  80. sage/ext/all__sagemath_pari.py +1 -0
  81. sage/ext/memory.cpython-314-x86_64-linux-musl.so +0 -0
  82. sage/ext/memory.pyx +98 -0
  83. sage/ext_data/pari/buzzard/DimensionSk.g +286 -0
  84. sage/ext_data/pari/buzzard/Tpprog.g +179 -0
  85. sage/ext_data/pari/buzzard/genusn.g +129 -0
  86. sage/ext_data/pari/dokchitser/computel.gp +740 -0
  87. sage/ext_data/pari/dokchitser/computel.gp.template +740 -0
  88. sage/ext_data/pari/dokchitser/ex-bsw +43 -0
  89. sage/ext_data/pari/dokchitser/ex-chgen +48 -0
  90. sage/ext_data/pari/dokchitser/ex-chqua +37 -0
  91. sage/ext_data/pari/dokchitser/ex-delta +35 -0
  92. sage/ext_data/pari/dokchitser/ex-eisen +30 -0
  93. sage/ext_data/pari/dokchitser/ex-gen2 +38 -0
  94. sage/ext_data/pari/dokchitser/ex-gen3 +49 -0
  95. sage/ext_data/pari/dokchitser/ex-gen4 +54 -0
  96. sage/ext_data/pari/dokchitser/ex-nf +48 -0
  97. sage/ext_data/pari/dokchitser/ex-shin +50 -0
  98. sage/ext_data/pari/dokchitser/ex-tau2 +30 -0
  99. sage/ext_data/pari/dokchitser/ex-zeta +27 -0
  100. sage/ext_data/pari/dokchitser/ex-zeta2 +47 -0
  101. sage/ext_data/pari/dokchitser/testall +13 -0
  102. sage/ext_data/pari/simon/ell.gp +2129 -0
  103. sage/ext_data/pari/simon/ellQ.gp +2151 -0
  104. sage/ext_data/pari/simon/ellcommon.gp +126 -0
  105. sage/ext_data/pari/simon/qfsolve.gp +722 -0
  106. sage/ext_data/pari/simon/resultant3.gp +306 -0
  107. sage/groups/all__sagemath_pari.py +3 -0
  108. sage/groups/pari_group.py +175 -0
  109. sage/interfaces/all__sagemath_pari.py +1 -0
  110. sage/interfaces/genus2reduction.py +464 -0
  111. sage/interfaces/gp.py +1114 -0
  112. sage/libs/all__sagemath_pari.py +2 -0
  113. sage/libs/linkages/__init__.py +1 -0
  114. sage/libs/linkages/padics/API.pxi +617 -0
  115. sage/libs/linkages/padics/Polynomial_ram.pxi +388 -0
  116. sage/libs/linkages/padics/Polynomial_shared.pxi +554 -0
  117. sage/libs/linkages/padics/__init__.py +1 -0
  118. sage/libs/linkages/padics/fmpz_poly_unram.pxi +869 -0
  119. sage/libs/linkages/padics/mpz.pxi +691 -0
  120. sage/libs/linkages/padics/relaxed/API.pxi +518 -0
  121. sage/libs/linkages/padics/relaxed/__init__.py +1 -0
  122. sage/libs/linkages/padics/relaxed/flint.pxi +543 -0
  123. sage/libs/linkages/padics/unram_shared.pxi +247 -0
  124. sage/libs/pari/__init__.py +210 -0
  125. sage/libs/pari/all.py +5 -0
  126. sage/libs/pari/convert_flint.cpython-314-x86_64-linux-musl.so +0 -0
  127. sage/libs/pari/convert_flint.pxd +14 -0
  128. sage/libs/pari/convert_flint.pyx +159 -0
  129. sage/libs/pari/convert_gmp.cpython-314-x86_64-linux-musl.so +0 -0
  130. sage/libs/pari/convert_gmp.pxd +14 -0
  131. sage/libs/pari/convert_gmp.pyx +210 -0
  132. sage/libs/pari/convert_sage.cpython-314-x86_64-linux-musl.so +0 -0
  133. sage/libs/pari/convert_sage.pxd +16 -0
  134. sage/libs/pari/convert_sage.pyx +588 -0
  135. sage/libs/pari/convert_sage_complex_double.cpython-314-x86_64-linux-musl.so +0 -0
  136. sage/libs/pari/convert_sage_complex_double.pxd +14 -0
  137. sage/libs/pari/convert_sage_complex_double.pyx +132 -0
  138. sage/libs/pari/convert_sage_matrix.cpython-314-x86_64-linux-musl.so +0 -0
  139. sage/libs/pari/convert_sage_matrix.pyx +106 -0
  140. sage/libs/pari/convert_sage_real_double.cpython-314-x86_64-linux-musl.so +0 -0
  141. sage/libs/pari/convert_sage_real_double.pxd +5 -0
  142. sage/libs/pari/convert_sage_real_double.pyx +14 -0
  143. sage/libs/pari/convert_sage_real_mpfr.cpython-314-x86_64-linux-musl.so +0 -0
  144. sage/libs/pari/convert_sage_real_mpfr.pxd +7 -0
  145. sage/libs/pari/convert_sage_real_mpfr.pyx +108 -0
  146. sage/libs/pari/misc.cpython-314-x86_64-linux-musl.so +0 -0
  147. sage/libs/pari/misc.pxd +4 -0
  148. sage/libs/pari/misc.pyx +26 -0
  149. sage/libs/pari/tests.py +1848 -0
  150. sage/matrix/all__sagemath_pari.py +1 -0
  151. sage/matrix/matrix_integer_pari.cpython-314-x86_64-linux-musl.so +0 -0
  152. sage/matrix/matrix_integer_pari.pyx +187 -0
  153. sage/matrix/matrix_rational_pari.cpython-314-x86_64-linux-musl.so +0 -0
  154. sage/matrix/matrix_rational_pari.pyx +160 -0
  155. sage/quadratic_forms/all__sagemath_pari.py +10 -0
  156. sage/quadratic_forms/genera/all.py +9 -0
  157. sage/quadratic_forms/genera/genus.py +3506 -0
  158. sage/quadratic_forms/genera/normal_form.py +1519 -0
  159. sage/quadratic_forms/genera/spinor_genus.py +243 -0
  160. sage/quadratic_forms/qfsolve.py +255 -0
  161. sage/quadratic_forms/quadratic_form__automorphisms.py +427 -0
  162. sage/quadratic_forms/quadratic_form__genus.py +141 -0
  163. sage/quadratic_forms/quadratic_form__local_density_interfaces.py +140 -0
  164. sage/quadratic_forms/quadratic_form__local_normal_form.py +421 -0
  165. sage/quadratic_forms/quadratic_form__local_representation_conditions.py +889 -0
  166. sage/quadratic_forms/quadratic_form__mass.py +69 -0
  167. sage/quadratic_forms/quadratic_form__mass__Conway_Sloane_masses.py +663 -0
  168. sage/quadratic_forms/quadratic_form__mass__Siegel_densities.py +373 -0
  169. sage/quadratic_forms/quadratic_form__siegel_product.py +198 -0
  170. sage/quadratic_forms/special_values.py +323 -0
  171. sage/rings/all__sagemath_pari.py +15 -0
  172. sage/rings/factorint_pari.cpython-314-x86_64-linux-musl.so +0 -0
  173. sage/rings/factorint_pari.pyx +80 -0
  174. sage/rings/finite_rings/all__sagemath_pari.py +1 -0
  175. sage/rings/finite_rings/element_givaro.cpython-314-x86_64-linux-musl.so +0 -0
  176. sage/rings/finite_rings/element_givaro.pxd +91 -0
  177. sage/rings/finite_rings/element_givaro.pyx +1769 -0
  178. sage/rings/finite_rings/element_ntl_gf2e.cpython-314-x86_64-linux-musl.so +0 -0
  179. sage/rings/finite_rings/element_ntl_gf2e.pxd +22 -0
  180. sage/rings/finite_rings/element_ntl_gf2e.pyx +1333 -0
  181. sage/rings/finite_rings/element_pari_ffelt.cpython-314-x86_64-linux-musl.so +0 -0
  182. sage/rings/finite_rings/element_pari_ffelt.pxd +13 -0
  183. sage/rings/finite_rings/element_pari_ffelt.pyx +1441 -0
  184. sage/rings/finite_rings/finite_field_givaro.py +612 -0
  185. sage/rings/finite_rings/finite_field_pari_ffelt.py +238 -0
  186. sage/rings/finite_rings/hom_finite_field_givaro.cpython-314-x86_64-linux-musl.so +0 -0
  187. sage/rings/finite_rings/hom_finite_field_givaro.pxd +28 -0
  188. sage/rings/finite_rings/hom_finite_field_givaro.pyx +280 -0
  189. sage/rings/finite_rings/residue_field_givaro.cpython-314-x86_64-linux-musl.so +0 -0
  190. sage/rings/finite_rings/residue_field_givaro.pyx +133 -0
  191. sage/rings/finite_rings/residue_field_pari_ffelt.cpython-314-x86_64-linux-musl.so +0 -0
  192. sage/rings/finite_rings/residue_field_pari_ffelt.pyx +128 -0
  193. sage/rings/function_field/all__sagemath_pari.py +1 -0
  194. sage/rings/function_field/valuation.py +1450 -0
  195. sage/rings/function_field/valuation_ring.py +212 -0
  196. sage/rings/number_field/all__sagemath_pari.py +14 -0
  197. sage/rings/number_field/totallyreal.cpython-314-x86_64-linux-musl.so +0 -0
  198. sage/rings/number_field/totallyreal.pyx +509 -0
  199. sage/rings/number_field/totallyreal_data.cpython-314-x86_64-linux-musl.so +0 -0
  200. sage/rings/number_field/totallyreal_data.pxd +26 -0
  201. sage/rings/number_field/totallyreal_data.pyx +928 -0
  202. sage/rings/number_field/totallyreal_phc.py +144 -0
  203. sage/rings/number_field/totallyreal_rel.py +1018 -0
  204. sage/rings/padics/CA_template.pxi +1847 -0
  205. sage/rings/padics/CA_template_header.pxi +50 -0
  206. sage/rings/padics/CR_template.pxi +2563 -0
  207. sage/rings/padics/CR_template_header.pxi +57 -0
  208. sage/rings/padics/FM_template.pxi +1575 -0
  209. sage/rings/padics/FM_template_header.pxi +50 -0
  210. sage/rings/padics/FP_template.pxi +2176 -0
  211. sage/rings/padics/FP_template_header.pxi +57 -0
  212. sage/rings/padics/all.py +3 -0
  213. sage/rings/padics/all__sagemath_pari.py +11 -0
  214. sage/rings/padics/common_conversion.cpython-314-x86_64-linux-musl.so +0 -0
  215. sage/rings/padics/common_conversion.pxd +15 -0
  216. sage/rings/padics/common_conversion.pyx +508 -0
  217. sage/rings/padics/eisenstein_extension_generic.py +232 -0
  218. sage/rings/padics/factory.py +3623 -0
  219. sage/rings/padics/generic_nodes.py +1615 -0
  220. sage/rings/padics/lattice_precision.py +2889 -0
  221. sage/rings/padics/morphism.cpython-314-x86_64-linux-musl.so +0 -0
  222. sage/rings/padics/morphism.pxd +11 -0
  223. sage/rings/padics/morphism.pyx +366 -0
  224. sage/rings/padics/padic_base_generic.py +467 -0
  225. sage/rings/padics/padic_base_leaves.py +1235 -0
  226. sage/rings/padics/padic_capped_absolute_element.cpython-314-x86_64-linux-musl.so +0 -0
  227. sage/rings/padics/padic_capped_absolute_element.pxd +15 -0
  228. sage/rings/padics/padic_capped_absolute_element.pyx +520 -0
  229. sage/rings/padics/padic_capped_relative_element.cpython-314-x86_64-linux-musl.so +0 -0
  230. sage/rings/padics/padic_capped_relative_element.pxd +14 -0
  231. sage/rings/padics/padic_capped_relative_element.pyx +614 -0
  232. sage/rings/padics/padic_extension_generic.py +990 -0
  233. sage/rings/padics/padic_extension_leaves.py +738 -0
  234. sage/rings/padics/padic_fixed_mod_element.cpython-314-x86_64-linux-musl.so +0 -0
  235. sage/rings/padics/padic_fixed_mod_element.pxd +15 -0
  236. sage/rings/padics/padic_fixed_mod_element.pyx +584 -0
  237. sage/rings/padics/padic_floating_point_element.cpython-314-x86_64-linux-musl.so +0 -0
  238. sage/rings/padics/padic_floating_point_element.pxd +14 -0
  239. sage/rings/padics/padic_floating_point_element.pyx +447 -0
  240. sage/rings/padics/padic_generic_element.cpython-314-x86_64-linux-musl.so +0 -0
  241. sage/rings/padics/padic_generic_element.pxd +48 -0
  242. sage/rings/padics/padic_generic_element.pyx +4642 -0
  243. sage/rings/padics/padic_lattice_element.py +1342 -0
  244. sage/rings/padics/padic_printing.cpython-314-x86_64-linux-musl.so +0 -0
  245. sage/rings/padics/padic_printing.pxd +38 -0
  246. sage/rings/padics/padic_printing.pyx +1505 -0
  247. sage/rings/padics/padic_relaxed_element.cpython-314-x86_64-linux-musl.so +0 -0
  248. sage/rings/padics/padic_relaxed_element.pxd +56 -0
  249. sage/rings/padics/padic_relaxed_element.pyx +18 -0
  250. sage/rings/padics/padic_relaxed_errors.cpython-314-x86_64-linux-musl.so +0 -0
  251. sage/rings/padics/padic_relaxed_errors.pxd +11 -0
  252. sage/rings/padics/padic_relaxed_errors.pyx +71 -0
  253. sage/rings/padics/padic_template_element.pxi +1212 -0
  254. sage/rings/padics/padic_template_element_header.pxi +50 -0
  255. sage/rings/padics/padic_valuation.py +1423 -0
  256. sage/rings/padics/pow_computer_flint.cpython-314-x86_64-linux-musl.so +0 -0
  257. sage/rings/padics/pow_computer_flint.pxd +38 -0
  258. sage/rings/padics/pow_computer_flint.pyx +641 -0
  259. sage/rings/padics/pow_computer_relative.cpython-314-x86_64-linux-musl.so +0 -0
  260. sage/rings/padics/pow_computer_relative.pxd +29 -0
  261. sage/rings/padics/pow_computer_relative.pyx +415 -0
  262. sage/rings/padics/qadic_flint_CA.cpython-314-x86_64-linux-musl.so +0 -0
  263. sage/rings/padics/qadic_flint_CA.pxd +21 -0
  264. sage/rings/padics/qadic_flint_CA.pyx +130 -0
  265. sage/rings/padics/qadic_flint_CR.cpython-314-x86_64-linux-musl.so +0 -0
  266. sage/rings/padics/qadic_flint_CR.pxd +13 -0
  267. sage/rings/padics/qadic_flint_CR.pyx +172 -0
  268. sage/rings/padics/qadic_flint_FM.cpython-314-x86_64-linux-musl.so +0 -0
  269. sage/rings/padics/qadic_flint_FM.pxd +14 -0
  270. sage/rings/padics/qadic_flint_FM.pyx +111 -0
  271. sage/rings/padics/qadic_flint_FP.cpython-314-x86_64-linux-musl.so +0 -0
  272. sage/rings/padics/qadic_flint_FP.pxd +12 -0
  273. sage/rings/padics/qadic_flint_FP.pyx +165 -0
  274. sage/rings/padics/relative_extension_leaves.py +429 -0
  275. sage/rings/padics/relative_ramified_CA.cpython-314-x86_64-linux-musl.so +0 -0
  276. sage/rings/padics/relative_ramified_CA.pxd +9 -0
  277. sage/rings/padics/relative_ramified_CA.pyx +33 -0
  278. sage/rings/padics/relative_ramified_CR.cpython-314-x86_64-linux-musl.so +0 -0
  279. sage/rings/padics/relative_ramified_CR.pxd +8 -0
  280. sage/rings/padics/relative_ramified_CR.pyx +33 -0
  281. sage/rings/padics/relative_ramified_FM.cpython-314-x86_64-linux-musl.so +0 -0
  282. sage/rings/padics/relative_ramified_FM.pxd +9 -0
  283. sage/rings/padics/relative_ramified_FM.pyx +33 -0
  284. sage/rings/padics/relative_ramified_FP.cpython-314-x86_64-linux-musl.so +0 -0
  285. sage/rings/padics/relative_ramified_FP.pxd +8 -0
  286. sage/rings/padics/relative_ramified_FP.pyx +33 -0
  287. sage/rings/padics/relaxed_template.pxi +4229 -0
  288. sage/rings/padics/relaxed_template_header.pxi +160 -0
  289. sage/rings/padics/tests.py +35 -0
  290. sage/rings/padics/tutorial.py +341 -0
  291. sage/rings/padics/unramified_extension_generic.py +335 -0
  292. sage/rings/padics/witt_vector.py +917 -0
  293. sage/rings/padics/witt_vector_ring.py +934 -0
  294. sage/rings/pari_ring.py +235 -0
  295. sage/rings/polynomial/all__sagemath_pari.py +1 -0
  296. sage/rings/polynomial/padics/all.py +1 -0
  297. sage/rings/polynomial/padics/polynomial_padic.py +360 -0
  298. sage/rings/polynomial/padics/polynomial_padic_capped_relative_dense.py +1324 -0
  299. sage/rings/polynomial/padics/polynomial_padic_flat.py +72 -0
  300. sage/rings/power_series_pari.cpython-314-x86_64-linux-musl.so +0 -0
  301. sage/rings/power_series_pari.pxd +6 -0
  302. sage/rings/power_series_pari.pyx +934 -0
  303. sage/rings/tate_algebra.py +1282 -0
  304. sage/rings/tate_algebra_element.cpython-314-x86_64-linux-musl.so +0 -0
  305. sage/rings/tate_algebra_element.pxd +49 -0
  306. sage/rings/tate_algebra_element.pyx +3464 -0
  307. sage/rings/tate_algebra_ideal.cpython-314-x86_64-linux-musl.so +0 -0
  308. sage/rings/tate_algebra_ideal.pxd +7 -0
  309. sage/rings/tate_algebra_ideal.pyx +1307 -0
  310. sage/rings/valuation/all.py +7 -0
  311. sage/rings/valuation/augmented_valuation.py +2118 -0
  312. sage/rings/valuation/developing_valuation.py +362 -0
  313. sage/rings/valuation/gauss_valuation.py +812 -0
  314. sage/rings/valuation/inductive_valuation.py +1686 -0
  315. sage/rings/valuation/limit_valuation.py +946 -0
  316. sage/rings/valuation/mapped_valuation.py +656 -0
  317. sage/rings/valuation/scaled_valuation.py +322 -0
  318. sage/rings/valuation/trivial_valuation.py +382 -0
  319. sage/rings/valuation/valuation.py +1119 -0
  320. sage/rings/valuation/valuation_space.py +1615 -0
  321. sage/rings/valuation/valuations_catalog.py +10 -0
  322. sage/rings/valuation/value_group.py +697 -0
  323. sage/schemes/all__sagemath_pari.py +1 -0
  324. sage/schemes/elliptic_curves/all__sagemath_pari.py +1 -0
  325. sage/schemes/elliptic_curves/descent_two_isogeny_pari.cpython-314-x86_64-linux-musl.so +0 -0
  326. sage/schemes/elliptic_curves/descent_two_isogeny_pari.pyx +46 -0
  327. sage_wheels/bin/gp +0 -0
  328. sage_wheels/bin/gp2c +0 -0
  329. sage_wheels/bin/gp2c-run +57 -0
  330. sage_wheels/bin/xeus-gp +0 -0
  331. sage_wheels/share/gp2c/func.dsc +18414 -0
@@ -0,0 +1,1333 @@
1
+ # sage_setup: distribution = sagemath-pari
2
+ # distutils: libraries = NTL_LIBRARIES
3
+ # distutils: extra_compile_args = NTL_CFLAGS
4
+ # distutils: include_dirs = NTL_INCDIR
5
+ # distutils: library_dirs = NTL_LIBDIR
6
+ # distutils: extra_link_args = NTL_LIBEXTRA
7
+ # distutils: language = c++
8
+ # sage.doctest: needs sage.libs.ntl sage.rings.finite_rings
9
+ r"""
10
+ Elements of finite fields of characteristic 2
11
+
12
+ This implementation uses NTL's GF2E class to perform the arithmetic
13
+ and is the standard implementation for ``GF(2^n)`` for ``n >= 16``.
14
+
15
+ AUTHORS:
16
+
17
+ - Martin Albrecht <malb@informatik.uni-bremen.de> (2007-10)
18
+ """
19
+
20
+ # ****************************************************************************
21
+ # Copyright (C) 2007 Martin Albrecht <malb@informatik.uni-bremen.de>
22
+ #
23
+ # This program is free software: you can redistribute it and/or modify
24
+ # it under the terms of the GNU General Public License as published by
25
+ # the Free Software Foundation, either version 2 of the License, or
26
+ # (at your option) any later version.
27
+ # https://www.gnu.org/licenses/
28
+ # ****************************************************************************
29
+
30
+ from cysignals.memory cimport check_malloc, sig_free
31
+ from cysignals.signals cimport sig_on
32
+ from sage.ext.cplusplus cimport ccrepr, ccreadstr
33
+
34
+ include "sage/libs/ntl/decl.pxi"
35
+ from cypari2.paridecl cimport *
36
+
37
+ from sage.structure.richcmp cimport (richcmp,
38
+ richcmp_not_equal, rich_to_bool)
39
+
40
+ from sage.structure.parent cimport Parent
41
+ from sage.structure.element cimport Vector
42
+
43
+ from sage.rings.finite_rings.finite_field_base cimport FiniteField
44
+
45
+ from sage.libs.pari import pari
46
+ from cypari2.gen cimport Gen
47
+ from cypari2.stack cimport clear_stack
48
+
49
+ from sage.rings.finite_rings.element_pari_ffelt import FiniteFieldElement_pari_ffelt
50
+ from sage.rings.finite_rings.finite_field_ntl_gf2e import FiniteField_ntl_gf2e
51
+
52
+ from sage.interfaces.abc import GapElement
53
+
54
+
55
+ cdef object IntegerMod_abstract
56
+ cdef object Integer
57
+ cdef object Rational
58
+ cdef object MPolynomial
59
+ cdef object Polynomial
60
+ cdef object GF
61
+ cdef object GF2, GF2_0, GF2_1
62
+
63
+ cdef int late_import() except -1:
64
+ """
65
+ Import a bunch of objects to the module name space late,
66
+ i.e. after the module was loaded. This is needed to avoid circular
67
+ imports.
68
+ """
69
+ global IntegerMod_abstract, \
70
+ Integer, \
71
+ Rational, \
72
+ MPolynomial, \
73
+ Polynomial, \
74
+ GF, \
75
+ GF2, GF2_0, GF2_1
76
+
77
+ if IntegerMod_abstract is not None:
78
+ return 0
79
+
80
+ import sage.rings.finite_rings.integer_mod
81
+ IntegerMod_abstract = sage.rings.finite_rings.integer_mod.IntegerMod_abstract
82
+
83
+ import sage.rings.rational
84
+ Rational = sage.rings.rational.Rational
85
+
86
+ import sage.rings.polynomial.multi_polynomial_element
87
+ MPolynomial = sage.rings.polynomial.multi_polynomial_element.MPolynomial
88
+
89
+ import sage.rings.polynomial.polynomial_element
90
+ Polynomial = sage.rings.polynomial.polynomial_element.Polynomial
91
+
92
+ import sage.rings.finite_rings.finite_field_constructor
93
+ GF = sage.rings.finite_rings.finite_field_constructor.FiniteField
94
+ GF2 = GF(2)
95
+ GF2_0 = GF2(0)
96
+ GF2_1 = GF2(1)
97
+
98
+ cdef extern from "arpa/inet.h":
99
+ unsigned int htonl(unsigned int)
100
+
101
+ cdef little_endian():
102
+ return htonl(1) != 1
103
+
104
+ cdef unsigned int switch_endianess(unsigned int i) noexcept:
105
+ cdef size_t j
106
+ cdef unsigned int ret = 0
107
+ for j in range(sizeof(int)):
108
+ (<unsigned char*>&ret)[j] = (<unsigned char*>&i)[sizeof(int)-j-1]
109
+ return ret
110
+
111
+ cdef class Cache_ntl_gf2e(Cache_base):
112
+ """
113
+ This class stores information for an NTL finite field in a Cython
114
+ class so that elements can access it quickly.
115
+
116
+ It's modeled on
117
+ :class:`~sage.rings.finite_rings.integer_mod.NativeIntStruct`,
118
+ but includes many functions that were previously included in
119
+ the parent (see :issue:`12062`).
120
+ """
121
+ def __cinit__(self, parent, Py_ssize_t k, modulus):
122
+ """
123
+ Construction.
124
+
125
+ TESTS::
126
+
127
+ sage: from sage.rings.finite_rings.element_ntl_gf2e import Cache_ntl_gf2e
128
+ sage: Cache_ntl_gf2e.__new__(Cache_ntl_gf2e, None, 2, [1,1,1])
129
+ <sage.rings.finite_rings.element_ntl_gf2e.Cache_ntl_gf2e object at ...>
130
+ """
131
+ cdef GF2X_c ntl_m
132
+ cdef GF2_c c
133
+ cdef Py_ssize_t i
134
+
135
+ for i in range(k + 1):
136
+ GF2_conv_long(c, modulus[i])
137
+ GF2X_SetCoeff(ntl_m, i, c)
138
+ self.F = GF2EContext_c(ntl_m)
139
+ self.F.restore()
140
+ self._order = Integer(1) << GF2E_degree()
141
+ self._degree = Integer(GF2E_degree())
142
+
143
+ def __init__(self, parent, Py_ssize_t k, modulus):
144
+ """
145
+ Initialization.
146
+
147
+ TESTS::
148
+
149
+ sage: k.<a> = GF(2^8, impl='ntl')
150
+ """
151
+ self._parent = <FiniteField?>parent
152
+ self._zero_element = self._new()
153
+ GF2E_conv_long((<FiniteField_ntl_gf2eElement>self._zero_element).x,0)
154
+ self._one_element = self._new()
155
+ GF2E_conv_long((<FiniteField_ntl_gf2eElement>self._one_element).x,1)
156
+ if k > 1:
157
+ self._gen = self._new()
158
+ ccreadstr(self._gen.x, b"[0 1]")
159
+ elif modulus[0]:
160
+ self._gen = self._one_element
161
+ else:
162
+ self._gen = self._zero_element
163
+
164
+ late_import()
165
+
166
+ def _doctest_for_5340(self):
167
+ r"""
168
+ Every bug fix should have a doctest. But :issue:`5340` only happens
169
+ when a garbage collection happens between restoring the modulus and
170
+ using it, so it can't be reliably doctested using any of the
171
+ existing Cython functions in this module. The sole purpose of
172
+ this method is to doctest the fix for :issue:`5340`.
173
+
174
+ EXAMPLES::
175
+
176
+ sage: k.<a> = GF(2^20)
177
+ sage: k._cache._doctest_for_5340()
178
+ [1 1 0 0 1 1 1 1 0 1 1 0 0 0 0 0 0 0 0 0 1]
179
+ [1 1 0 0 1 1 1 1 0 1 1 0 0 0 0 0 0 0 0 0 1]
180
+ """
181
+ import gc
182
+
183
+ # Do a garbage collection, so that this method is repeatable.
184
+ gc.collect()
185
+
186
+ # Create a new finite field.
187
+ new_fld = GF(1<<30, 'a', modulus='random')
188
+ # Create a garbage cycle.
189
+ cycle = [new_fld]
190
+ cycle.append(cycle)
191
+ # Make the cycle inaccessible.
192
+ new_fld = None
193
+ cycle = None
194
+
195
+ # Set the modulus.
196
+ self.F.restore()
197
+ # Print the current modulus.
198
+ cdef GF2XModulus_c modulus = GF2E_modulus()
199
+ cdef GF2X_c mod_poly = GF2XModulus_GF2X(modulus)
200
+ print(ccrepr(mod_poly))
201
+
202
+ # do another garbage collection
203
+ gc.collect()
204
+
205
+ # and print the modulus again
206
+ modulus = GF2E_modulus()
207
+ mod_poly = GF2XModulus_GF2X(modulus)
208
+ print(ccrepr(mod_poly))
209
+
210
+ cdef FiniteField_ntl_gf2eElement _new(self):
211
+ """
212
+ Return a new element in ``self``. Use this method to construct
213
+ 'empty' elements.
214
+ """
215
+ cdef FiniteField_ntl_gf2eElement y
216
+ self.F.restore()
217
+ y = FiniteField_ntl_gf2eElement.__new__(FiniteField_ntl_gf2eElement)
218
+ y._parent = self._parent
219
+ y._cache = self
220
+ return y
221
+
222
+ def order(self):
223
+ """
224
+ Return the cardinality of the field.
225
+
226
+ EXAMPLES::
227
+
228
+ sage: k.<a> = GF(2^64)
229
+ sage: k._cache.order()
230
+ 18446744073709551616
231
+ """
232
+ return self._order
233
+
234
+ def degree(self):
235
+ r"""
236
+ If the field has cardinality `2^n` this method returns `n`.
237
+
238
+ EXAMPLES::
239
+
240
+ sage: k.<a> = GF(2^64)
241
+ sage: k._cache.degree()
242
+ 64
243
+ """
244
+ return self._degree
245
+
246
+ def import_data(self, e):
247
+ """
248
+ EXAMPLES::
249
+
250
+ sage: k.<a> = GF(2^17)
251
+ sage: V = k.vector_space(map=False)
252
+ sage: v = [1,0,0,0,0,1,0,0,1,0,0,0,0,1,0,0,0]
253
+ sage: k._cache.import_data(v)
254
+ a^13 + a^8 + a^5 + 1
255
+ sage: k._cache.import_data(V(v))
256
+ a^13 + a^8 + a^5 + 1
257
+
258
+ TESTS:
259
+
260
+ We check that :issue:`12584` is fixed::
261
+
262
+ sage: k(2^63)
263
+ 0
264
+
265
+ We can coerce from PARI finite field implementations::
266
+
267
+ sage: K.<a> = GF(2^19, impl='ntl')
268
+ sage: a^20
269
+ a^6 + a^3 + a^2 + a
270
+ sage: M.<c> = GF(2^19, impl='pari_ffelt')
271
+ sage: K(c^20)
272
+ a^6 + a^3 + a^2 + a
273
+ """
274
+ if isinstance(e, FiniteField_ntl_gf2eElement) and e.parent() is self._parent: return e
275
+ cdef FiniteField_ntl_gf2eElement res = self._new()
276
+ cdef FiniteField_ntl_gf2eElement x
277
+ cdef FiniteField_ntl_gf2eElement g
278
+ cdef Py_ssize_t i
279
+
280
+ if isinstance(e, IntegerMod_abstract):
281
+ e = e.lift()
282
+ if isinstance(e, (int, Integer)):
283
+ GF2E_conv_long(res.x,int(e&1))
284
+ return res
285
+
286
+ elif isinstance(e, float):
287
+ GF2E_conv_long(res.x,int(e))
288
+ return res
289
+
290
+ elif isinstance(e, str):
291
+ return self._parent(eval(e.replace("^","**"),self._parent.gens_dict()))
292
+
293
+ elif isinstance(e, Vector):
294
+ if self._parent.vector_space(map=False) != e.parent():
295
+ raise TypeError("e.parent must match self.vector_space")
296
+ ztmp = Integer(e.list(),2)
297
+ # Can't do the following since we can't cimport Integer because of circular imports.
298
+ #for i from 0 <= i < len(e):
299
+ # if e[i]:
300
+ # mpz_setbit(ztmp.value, i)
301
+ return self.fetch_int(ztmp)
302
+
303
+ elif isinstance(e, (list, tuple)):
304
+ if len(e) > self._degree:
305
+ # could reduce here...
306
+ raise ValueError("list is too long")
307
+ ztmp = Integer(e,2)
308
+ return self.fetch_int(ztmp)
309
+
310
+ elif isinstance(e, MPolynomial):
311
+ if e.is_constant():
312
+ return self._parent(e.constant_coefficient())
313
+ else:
314
+ raise TypeError("no coercion defined")
315
+
316
+ elif isinstance(e, Polynomial):
317
+ if e.is_constant():
318
+ return self._parent(e.constant_coefficient())
319
+ else:
320
+ return e(self._parent.gen())
321
+
322
+ elif isinstance(e, Rational):
323
+ num = e.numer()
324
+ den = e.denom()
325
+ if den % 2:
326
+ if num % 2:
327
+ return self._one_element
328
+ return self._zero_element
329
+ raise ZeroDivisionError
330
+
331
+ elif isinstance(e, Gen):
332
+ pass # handle this in next if clause
333
+
334
+ elif isinstance(e, FiniteFieldElement_pari_ffelt):
335
+ # Reduce to pari
336
+ e = e.__pari__()
337
+
338
+ elif isinstance(e, GapElement):
339
+ from sage.libs.gap.libgap import libgap
340
+ return libgap(e).sage(ring=self._parent)
341
+
342
+ else:
343
+ try:
344
+ from sage.libs.gap.element import GapElement_FiniteField
345
+ except ImportError:
346
+ pass
347
+ else:
348
+ if isinstance(e, GapElement_FiniteField):
349
+ return e.sage(ring=self._parent)
350
+ raise TypeError("unable to coerce %r" % type(e))
351
+
352
+ cdef GEN t
353
+ if isinstance(e, Gen):
354
+ sig_on()
355
+ t = (<Gen>e).g
356
+ if typ(t) == t_FFELT:
357
+ t = FF_to_FpXQ(t)
358
+ else:
359
+ t = liftall_shallow(t)
360
+
361
+ if typ(t) == t_INT:
362
+ GF2E_conv_long(res.x, itos(t))
363
+ clear_stack()
364
+ elif typ(t) == t_POL:
365
+ g = self._gen
366
+ x = self._new()
367
+ GF2E_conv_long(x.x, 1)
368
+
369
+ for i from 0 <= i <= degpol(t):
370
+ if gtolong(gel(t, i+2)):
371
+ GF2E_add(res.x, res.x, x.x)
372
+ GF2E_mul(x.x, x.x, g.x)
373
+ clear_stack()
374
+ else:
375
+ clear_stack()
376
+ raise TypeError(f"unable to convert PARI {e.type()} to {self.parent}")
377
+
378
+ return res
379
+
380
+ raise ValueError("Cannot coerce element %s to this field." % e)
381
+
382
+ cpdef FiniteField_ntl_gf2eElement fetch_int(self, number):
383
+ r"""
384
+ Given an integer less than `p^n` with base `2`
385
+ representation `a_0 + a_1 \cdot 2 + \cdots + a_k 2^k`, this returns
386
+ `a_0 + a_1 x + \cdots + a_k x^k`, where `x` is the
387
+ generator of this finite field.
388
+
389
+ INPUT:
390
+
391
+ - ``number`` -- integer; of size less than the cardinality
392
+
393
+ EXAMPLES::
394
+
395
+ sage: k.<a> = GF(2^48)
396
+ sage: k._cache.fetch_int(2^33 + 2 + 1)
397
+ a^33 + a + 1
398
+
399
+ TESTS:
400
+
401
+ We test that :issue:`17027` is fixed::
402
+
403
+ sage: K.<a> = GF(2^16)
404
+ sage: K._cache.fetch_int(0r)
405
+ 0
406
+ """
407
+ cdef FiniteField_ntl_gf2eElement a
408
+ cdef GF2X_c _a
409
+ cdef int n
410
+
411
+ self.F.restore()
412
+
413
+ if number < 0 or number >= self._order:
414
+ raise TypeError("n must be between 0 and self.order()")
415
+
416
+ if isinstance(number, int):
417
+ if not number:
418
+ n = 0
419
+ else:
420
+ n = int(Integer(number).nbits())
421
+ n = n // 8 + 1
422
+ elif isinstance(number, Integer):
423
+ n = int(number.nbits())
424
+ n = n // 8 + 1
425
+ else:
426
+ raise TypeError("number %s is not an integer" % number)
427
+
428
+ cdef unsigned char* p = <unsigned char*>check_malloc(n)
429
+ cdef long i
430
+ a = self._new()
431
+ for i in range(n):
432
+ p[i] = (number % 256)
433
+ number = number >> 8
434
+ GF2XFromBytes(_a, p, n)
435
+ GF2E_conv_GF2X(a.x, _a)
436
+ sig_free(p)
437
+ return a
438
+
439
+ def polynomial(self):
440
+ """
441
+ Return the list of 0s and 1s giving the defining polynomial of the
442
+ field.
443
+
444
+ EXAMPLES::
445
+
446
+ sage: k.<a> = GF(2^20,modulus='minimal_weight')
447
+ sage: k._cache.polynomial()
448
+ [1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1]
449
+ """
450
+ cdef FiniteField_ntl_gf2eElement P
451
+ cdef GF2X_c _P
452
+ cdef GF2_c c
453
+ self.F.restore()
454
+ cdef int i
455
+
456
+ P = -(self._gen**self._degree)
457
+ _P = GF2E_rep(P.x)
458
+
459
+ ret = []
460
+ for i from 0 <= i < GF2E_degree():
461
+ c = GF2X_coeff(_P,i)
462
+ if not GF2_IsZero(c):
463
+ ret.append(1)
464
+ else:
465
+ ret.append(0)
466
+ ret.append(1)
467
+ return ret
468
+
469
+ cdef class FiniteField_ntl_gf2eElement(FinitePolyExtElement):
470
+ """
471
+ An element of an NTL:GF2E finite field.
472
+ """
473
+
474
+ def __init__(FiniteField_ntl_gf2eElement self, parent=None ):
475
+ """
476
+ Initialize an element in parent. It's much better to use
477
+ parent(<value>) or any specialized method of parent
478
+ (one,zero,gen) instead. Do not call this constructor directly,
479
+ it doesn't make much sense.
480
+
481
+ INPUT:
482
+
483
+ - ``parent`` -- base field
484
+
485
+ OUTPUT: a finite field element
486
+
487
+ EXAMPLES::
488
+
489
+ sage: k.<a> = GF(2^16)
490
+ sage: from sage.rings.finite_rings.element_ntl_gf2e import FiniteField_ntl_gf2eElement
491
+ sage: FiniteField_ntl_gf2eElement(k)
492
+ 0
493
+ sage: k.<a> = GF(2^20)
494
+ sage: a.parent() is k
495
+ True
496
+ """
497
+ if parent is None:
498
+ raise ValueError("You must provide a parent to construct a finite field element")
499
+
500
+ def __cinit__(FiniteField_ntl_gf2eElement self, parent=None ):
501
+ """
502
+ Restore the cache and construct the underlying NTL element.
503
+
504
+ EXAMPLES::
505
+
506
+ sage: k.<a> = GF(2^8, impl='ntl') # indirect doctest
507
+ """
508
+ if parent is None:
509
+ return
510
+ if isinstance(parent, FiniteField_ntl_gf2e):
511
+ self._parent = parent
512
+ (<Cache_ntl_gf2e>self._parent._cache).F.restore()
513
+
514
+ cdef FiniteField_ntl_gf2eElement _new(FiniteField_ntl_gf2eElement self):
515
+ cdef FiniteField_ntl_gf2eElement y
516
+ (<Cache_ntl_gf2e>self._parent._cache).F.restore()
517
+ y = FiniteField_ntl_gf2eElement.__new__(FiniteField_ntl_gf2eElement)
518
+ y._parent = self._parent
519
+ y._cache = self._cache
520
+ return y
521
+
522
+ def __repr__(FiniteField_ntl_gf2eElement self) -> str:
523
+ """
524
+ Polynomial representation of ``self``.
525
+
526
+ EXAMPLES::
527
+
528
+ sage: k.<a> = GF(2^16)
529
+ sage: str(a^16) # indirect doctest
530
+ 'a^5 + a^3 + a^2 + 1'
531
+ sage: k.<u> = GF(2^16)
532
+ sage: u
533
+ u
534
+ """
535
+ (<Cache_ntl_gf2e>self._parent._cache).F.restore()
536
+ cdef GF2X_c rep = GF2E_rep(self.x)
537
+ cdef GF2_c c
538
+ cdef int i
539
+
540
+ if GF2E_IsZero(self.x):
541
+ return "0"
542
+
543
+ name = self._parent.variable_name()
544
+ _repr = []
545
+
546
+ c = GF2X_coeff(rep, 0)
547
+ if not GF2_IsZero(c):
548
+ _repr.append("1")
549
+
550
+ c = GF2X_coeff(rep, 1)
551
+ if not GF2_IsZero(c):
552
+ _repr.append(name)
553
+
554
+ for i from 1 < i <= GF2X_deg(rep):
555
+ c = GF2X_coeff(rep, i)
556
+ if not GF2_IsZero(c):
557
+ _repr.append("%s^%d" % (name, i))
558
+
559
+ return " + ".join(reversed(_repr))
560
+
561
+ def __bool__(FiniteField_ntl_gf2eElement self) -> bool:
562
+ r"""
563
+ Return ``True`` if ``self != k(0)``.
564
+
565
+ EXAMPLES::
566
+
567
+ sage: k.<a> = GF(2^20)
568
+ sage: bool(a) # indirect doctest
569
+ True
570
+ sage: bool(k(0))
571
+ False
572
+ sage: a.is_zero()
573
+ False
574
+ """
575
+ (<Cache_ntl_gf2e>self._parent._cache).F.restore()
576
+ return not bool(GF2E_IsZero(self.x))
577
+
578
+ def is_one(FiniteField_ntl_gf2eElement self):
579
+ r"""
580
+ Return ``True`` if ``self == k(1)``.
581
+
582
+ Equivalent to ``self != k(0)``.
583
+
584
+ EXAMPLES::
585
+
586
+ sage: k.<a> = GF(2^20)
587
+ sage: a.is_one() # indirect doctest
588
+ False
589
+ sage: k(1).is_one()
590
+ True
591
+ """
592
+ (<Cache_ntl_gf2e>self._parent._cache).F.restore()
593
+ return self.x == self._cache._one_element.x
594
+
595
+ def is_unit(FiniteField_ntl_gf2eElement self):
596
+ """
597
+ Return ``True`` if ``self`` is nonzero, so it is a unit as an element
598
+ of the finite field.
599
+
600
+ EXAMPLES::
601
+
602
+ sage: k.<a> = GF(2^17)
603
+ sage: a.is_unit()
604
+ True
605
+ sage: k(0).is_unit()
606
+ False
607
+ """
608
+ (<Cache_ntl_gf2e>self._parent._cache).F.restore()
609
+ if not GF2E_IsZero(self.x):
610
+ return True
611
+ else:
612
+ return False
613
+
614
+ def is_square(FiniteField_ntl_gf2eElement self):
615
+ r"""
616
+ Return ``True`` as every element in `\GF{2^n}` is a square.
617
+
618
+ EXAMPLES::
619
+
620
+ sage: k.<a> = GF(2^18)
621
+ sage: e = k.random_element()
622
+ sage: e.parent() is k
623
+ True
624
+ sage: e.is_square()
625
+ True
626
+ sage: e.sqrt()^2 == e
627
+ True
628
+ """
629
+ return True
630
+
631
+ def sqrt(FiniteField_ntl_gf2eElement self, all=False, extend=False):
632
+ """
633
+ Return a square root of this finite field element in its parent.
634
+
635
+ EXAMPLES::
636
+
637
+ sage: k.<a> = GF(2^20)
638
+ sage: a.is_square()
639
+ True
640
+ sage: a.sqrt()
641
+ a^19 + a^15 + a^14 + a^12 + a^9 + a^7 + a^4 + a^3 + a + 1
642
+ sage: a.sqrt()^2 == a
643
+ True
644
+
645
+ This failed before :issue:`4899`::
646
+
647
+ sage: GF(2^16,'a')(1).sqrt()
648
+ 1
649
+ """
650
+ # this really should be handled special, its gf2 linear after
651
+ # all
652
+ a = self ** (self._cache._order // 2)
653
+ if all:
654
+ return [a]
655
+ else:
656
+ return a
657
+
658
+ cpdef _add_(self, right):
659
+ """
660
+ Add two elements.
661
+
662
+ EXAMPLES::
663
+
664
+ sage: k.<a> = GF(2^16)
665
+ sage: e = a^2 + a + 1 # indirect doctest
666
+ sage: f = a^15 + a^2 + 1
667
+ sage: e + f
668
+ a^15 + a
669
+ """
670
+ cdef FiniteField_ntl_gf2eElement r = (<FiniteField_ntl_gf2eElement>self)._new()
671
+ GF2E_add(r.x, (<FiniteField_ntl_gf2eElement>self).x, (<FiniteField_ntl_gf2eElement>right).x)
672
+ return r
673
+
674
+ cpdef _mul_(self, right):
675
+ """
676
+ Multiply two elements.
677
+
678
+ EXAMPLES::
679
+
680
+ sage: k.<a> = GF(2^16)
681
+ sage: e = a^2 + a + 1 # indirect doctest
682
+ sage: f = a^15 + a^2 + 1
683
+ sage: e * f
684
+ a^15 + a^6 + a^5 + a^3 + a^2
685
+ """
686
+ cdef FiniteField_ntl_gf2eElement r = (<FiniteField_ntl_gf2eElement>self)._new()
687
+ GF2E_mul(r.x, (<FiniteField_ntl_gf2eElement>self).x, (<FiniteField_ntl_gf2eElement>right).x)
688
+ return r
689
+
690
+ cpdef _div_(self, other):
691
+ """
692
+ Divide two elements.
693
+
694
+ EXAMPLES::
695
+
696
+ sage: k.<a> = GF(2^16)
697
+ sage: e = a^2 + a + 1 # indirect doctest
698
+ sage: f = a^15 + a^2 + 1
699
+ sage: e / f
700
+ a^11 + a^8 + a^7 + a^6 + a^5 + a^3 + a^2 + 1
701
+ sage: k(1) / k(0)
702
+ Traceback (most recent call last):
703
+ ...
704
+ ZeroDivisionError: division by zero in finite field
705
+ """
706
+ cdef FiniteField_ntl_gf2eElement o = <FiniteField_ntl_gf2eElement>other
707
+ if GF2E_IsZero(o.x):
708
+ raise ZeroDivisionError('division by zero in finite field')
709
+ cdef FiniteField_ntl_gf2eElement r = self._new()
710
+ GF2E_div(r.x, self.x, o.x)
711
+ return r
712
+
713
+ cpdef _sub_(self, right):
714
+ """
715
+ Subtract two elements.
716
+
717
+ EXAMPLES::
718
+
719
+ sage: k.<a> = GF(2^16)
720
+ sage: e = a^2 - a + 1 # indirect doctest
721
+ sage: f = a^15 - a^2 + 1
722
+ sage: e - f
723
+ a^15 + a
724
+ """
725
+ cdef FiniteField_ntl_gf2eElement r = (<FiniteField_ntl_gf2eElement>self)._new()
726
+ GF2E_sub(r.x, (<FiniteField_ntl_gf2eElement>self).x, (<FiniteField_ntl_gf2eElement>right).x)
727
+ return r
728
+
729
+ def __neg__(FiniteField_ntl_gf2eElement self):
730
+ """
731
+ Return this element.
732
+
733
+ EXAMPLES::
734
+
735
+ sage: k.<a> = GF(2^16)
736
+ sage: -a
737
+ a
738
+ """
739
+ cdef FiniteField_ntl_gf2eElement r = (<FiniteField_ntl_gf2eElement>self)._new()
740
+ r.x = (<FiniteField_ntl_gf2eElement>self).x
741
+ return r
742
+
743
+ def __invert__(self):
744
+ """
745
+ Return the multiplicative inverse of an element.
746
+
747
+ EXAMPLES::
748
+
749
+ sage: k.<a> = GF(2^16)
750
+ sage: ~a
751
+ a^15 + a^4 + a^2 + a
752
+ sage: a * ~a
753
+ 1
754
+ sage: ~k(0)
755
+ Traceback (most recent call last):
756
+ ...
757
+ ZeroDivisionError: division by zero in finite field
758
+ """
759
+ cdef FiniteField_ntl_gf2eElement o = self._parent._cache._one_element
760
+ return o._div_(self)
761
+
762
+ cdef _pow_long(self, long n):
763
+ """
764
+ EXAMPLES::
765
+
766
+ sage: k.<a> = GF(2^63)
767
+ sage: a^2
768
+ a^2
769
+ sage: a^64
770
+ a^25 + a^24 + a^23 + a^18 + a^17 + a^16 + a^12 + a^10 + a^9 + a^5 + a^4 + a^3 + a^2 + a
771
+ sage: a^(2^64)
772
+ a^2
773
+ sage: a^(2^128)
774
+ a^4
775
+
776
+ TESTS::
777
+
778
+ sage: k(0) ^ (-1)
779
+ Traceback (most recent call last):
780
+ ...
781
+ ZeroDivisionError: division by zero in finite field
782
+ sage: k(0) ^ (-10^100)
783
+ Traceback (most recent call last):
784
+ ...
785
+ ZeroDivisionError: division by zero in finite field
786
+ sage: 2 ^ a
787
+ Traceback (most recent call last):
788
+ ...
789
+ TypeError: unsupported operand parent(s) for ^: 'Finite Field in a of size 2^63' and 'Finite Field in a of size 2^63'
790
+ sage: a ^ "exp"
791
+ Traceback (most recent call last):
792
+ ...
793
+ TypeError: unsupported operand type(s) for ** or pow(): 'sage.rings.finite_rings.element_ntl_gf2e.FiniteField_ntl_gf2eElement' and 'str'
794
+ """
795
+ if n < 0 and GF2E_IsZero(self.x):
796
+ raise ZeroDivisionError('division by zero in finite field')
797
+ r = self._new()
798
+ GF2E_power(r.x, self.x, n)
799
+ return r
800
+
801
+ cpdef _richcmp_(left, right, int op):
802
+ """
803
+ Comparison of finite field elements.
804
+
805
+ .. NOTE::
806
+
807
+ Finite fields are unordered. However, we adopt the convention that
808
+ an element ``e`` is bigger than element ``f`` if its polynomial
809
+ representation is bigger.
810
+
811
+ EXAMPLES::
812
+
813
+ sage: k.<a> = GF(2^20)
814
+ sage: e = k.random_element()
815
+ sage: f = loads(dumps(e))
816
+ sage: e is f
817
+ False
818
+ sage: e == f
819
+ True
820
+ sage: e != (e + 1)
821
+ True
822
+
823
+ ::
824
+
825
+ sage: K.<a> = GF(2^100)
826
+ sage: a < a^2
827
+ True
828
+ sage: a > a^2
829
+ False
830
+ sage: a+1 > a^2
831
+ False
832
+ sage: a+1 < a^2
833
+ True
834
+ sage: a+1 < a
835
+ False
836
+ sage: a+1 == a
837
+ False
838
+ sage: a == a
839
+ True
840
+ """
841
+ (<Cache_ntl_gf2e>left._parent._cache).F.restore()
842
+ cdef int c = (<FiniteField_ntl_gf2eElement>left).x == (<FiniteField_ntl_gf2eElement>right).x
843
+ if c == 1:
844
+ return rich_to_bool(op, 0)
845
+ else:
846
+ lx = GF2X_deg(GF2E_rep((<FiniteField_ntl_gf2eElement>left).x))
847
+ rx = GF2X_deg(GF2E_rep((<FiniteField_ntl_gf2eElement>right).x))
848
+ if lx != rx:
849
+ return richcmp_not_equal(lx, rx, op)
850
+ li = left._integer_representation()
851
+ ri = right._integer_representation()
852
+ return richcmp(li, ri, op)
853
+
854
+ def _integer_(FiniteField_ntl_gf2eElement self, Integer):
855
+ """
856
+ Convert ``self`` to an integer if it is in the prime subfield.
857
+
858
+ EXAMPLES::
859
+
860
+ sage: k.<b> = GF(2^16); k
861
+ Finite Field in b of size 2^16
862
+ sage: ZZ(k(1))
863
+ 1
864
+ sage: ZZ(k(0))
865
+ 0
866
+ sage: ZZ(b)
867
+ Traceback (most recent call last):
868
+ ...
869
+ TypeError: not in prime subfield
870
+ sage: GF(2)(b^(2^16-1)) # indirect doctest
871
+ 1
872
+ """
873
+ if self.is_zero(): return Integer(0)
874
+ elif self.is_one(): return Integer(1)
875
+ else:
876
+ raise TypeError("not in prime subfield")
877
+
878
+ def __int__(FiniteField_ntl_gf2eElement self):
879
+ """
880
+ Return the int representation of ``self``. When ``self`` is in the
881
+ prime subfield, the integer returned is equal to ``self`` and
882
+ otherwise raises an error.
883
+
884
+ EXAMPLES::
885
+
886
+ sage: k.<a> = GF(2^20)
887
+ sage: int(k(0))
888
+ 0
889
+ sage: int(k(1))
890
+ 1
891
+ sage: int(a)
892
+ Traceback (most recent call last):
893
+ ...
894
+ TypeError: Cannot coerce element to an integer.
895
+ sage: int(a^2 + 1)
896
+ Traceback (most recent call last):
897
+ ...
898
+ TypeError: Cannot coerce element to an integer.
899
+ """
900
+ if self == 0:
901
+ return int(0)
902
+ elif self == 1:
903
+ return int(1)
904
+ else:
905
+ raise TypeError("Cannot coerce element to an integer.")
906
+
907
+ def _integer_representation(FiniteField_ntl_gf2eElement self):
908
+ r"""
909
+ Return the int representation of ``self``. When ``self`` is in the
910
+ prime subfield, the integer returned is equal to ``self`` and not
911
+ to ``log_repr``.
912
+
913
+ Elements of this field are represented as ints in as follows:
914
+ for `e \in \GF{p}[x]` with `e = a_0 + a_1 x + a_2 x^2 + \cdots`,
915
+ `e` is represented as: `n = a_0 + a_1 p + a_2 p^2 + \cdots`.
916
+
917
+ .. SEEALSO::
918
+
919
+ :meth:`sage.rings.finite_rings.element_base.FinitePolyExtElement.to_integer`
920
+
921
+ EXAMPLES::
922
+
923
+ sage: k.<a> = GF(2^20)
924
+ sage: a._integer_representation()
925
+ 2
926
+ sage: (a^2 + 1)._integer_representation()
927
+ 5
928
+ sage: k.<a> = GF(2^70)
929
+ sage: (a^65 + a^64 + 1)._integer_representation()
930
+ 55340232221128654849
931
+ """
932
+ cdef unsigned int i = 0
933
+ ret = int(0)
934
+ cdef unsigned long shift = 0
935
+ cdef GF2X_c r = GF2E_rep(self.x)
936
+
937
+ if GF2X_IsZero(r):
938
+ return 0
939
+
940
+ if little_endian():
941
+ while GF2X_deg(r) >= <long>(8 * sizeof(int)):
942
+ BytesFromGF2X(<unsigned char *>&i, r, sizeof(int))
943
+ ret += int(i) << shift
944
+ shift += sizeof(int)*8
945
+ GF2X_RightShift(r,r,(sizeof(int)*8))
946
+ BytesFromGF2X(<unsigned char *>&i, r, sizeof(int))
947
+ ret += int(i) << shift
948
+ else:
949
+ while GF2X_deg(r) >= <long>(8 * sizeof(int)):
950
+ BytesFromGF2X(<unsigned char *>&i, r, sizeof(int))
951
+ ret += int(switch_endianess(i)) << shift
952
+ shift += sizeof(int)*8
953
+ GF2X_RightShift(r,r,(sizeof(int)*8))
954
+ BytesFromGF2X(<unsigned char *>&i, r, sizeof(int))
955
+ ret += int(switch_endianess(i)) << shift
956
+
957
+ return int(ret)
958
+
959
+ def polynomial(FiniteField_ntl_gf2eElement self, name=None):
960
+ r"""
961
+ Return ``self`` viewed as a polynomial over
962
+ ``self.parent().prime_subfield()``.
963
+
964
+ INPUT:
965
+
966
+ - ``name`` -- (optional) variable name
967
+
968
+ EXAMPLES::
969
+
970
+ sage: k.<a> = GF(2^17)
971
+ sage: e = a^15 + a^13 + a^11 + a^10 + a^9 + a^8 + a^7 + a^6 + a^4 + a + 1
972
+ sage: e.polynomial()
973
+ a^15 + a^13 + a^11 + a^10 + a^9 + a^8 + a^7 + a^6 + a^4 + a + 1
974
+
975
+ sage: from sage.rings.polynomial.polynomial_element import Polynomial
976
+ sage: isinstance(e.polynomial(), Polynomial)
977
+ True
978
+
979
+ sage: e.polynomial('x')
980
+ x^15 + x^13 + x^11 + x^10 + x^9 + x^8 + x^7 + x^6 + x^4 + x + 1
981
+ """
982
+ cdef GF2X_c r = GF2E_rep(self.x)
983
+ cdef int i
984
+
985
+ C = []
986
+ for i from 0 <= i <= GF2X_deg(r):
987
+ C.append(GF2_conv_to_long(GF2X_coeff(r,i)))
988
+ return self._parent.polynomial_ring(name)(C)
989
+
990
+ def charpoly(self, var='x'):
991
+ r"""
992
+ Return the characteristic polynomial of ``self`` as a polynomial
993
+ in var over the prime subfield.
994
+
995
+ INPUT:
996
+
997
+ - ``var`` -- string (default: ``'x'``)
998
+
999
+ OUTPUT: polynomial
1000
+
1001
+ EXAMPLES::
1002
+
1003
+ sage: k.<a> = GF(2^8, impl='ntl')
1004
+ sage: b = a^3 + a
1005
+ sage: b.minpoly()
1006
+ x^4 + x^3 + x^2 + x + 1
1007
+ sage: b.charpoly()
1008
+ x^8 + x^6 + x^4 + x^2 + 1
1009
+ sage: b.charpoly().factor()
1010
+ (x^4 + x^3 + x^2 + x + 1)^2
1011
+ sage: b.charpoly('Z')
1012
+ Z^8 + Z^6 + Z^4 + Z^2 + 1
1013
+ """
1014
+ f = self.minpoly(var)
1015
+ cdef int d = f.degree(), n = self.parent().degree()
1016
+ cdef int pow = n/d
1017
+ return f if pow == 1 else f**pow
1018
+
1019
+ def minpoly(self, var='x'):
1020
+ r"""
1021
+ Return the minimal polynomial of ``self``, which is the smallest
1022
+ degree polynomial `f \in \GF{2}[x]` such that ``f(self) == 0``.
1023
+
1024
+ INPUT:
1025
+
1026
+ - ``var`` -- string (default: ``'x'``)
1027
+
1028
+ OUTPUT: polynomial
1029
+
1030
+ EXAMPLES::
1031
+
1032
+ sage: K.<a> = GF(2^100)
1033
+ sage: f = a.minpoly(); f
1034
+ x^100 + x^57 + x^56 + x^55 + x^52 + x^48 + x^47 + x^46 + x^45 + x^44 + x^43 + x^41 + x^37 + x^36 + x^35 + x^34 + x^31 + x^30 + x^27 + x^25 + x^24 + x^22 + x^20 + x^19 + x^16 + x^15 + x^11 + x^9 + x^8 + x^6 + x^5 + x^3 + 1
1035
+ sage: f(a)
1036
+ 0
1037
+ sage: g = K.random_element()
1038
+ sage: g.minpoly()(g)
1039
+ 0
1040
+ """
1041
+ (<Cache_ntl_gf2e>self._parent._cache).F.restore()
1042
+ cdef GF2X_c r = GF2X_IrredPolyMod(GF2E_rep(self.x), GF2E_modulus())
1043
+ cdef int i
1044
+ C = []
1045
+ for i from 0 <= i <= GF2X_deg(r):
1046
+ C.append(GF2_conv_to_long(GF2X_coeff(r,i)))
1047
+ return self._parent.polynomial_ring(var)(C)
1048
+
1049
+ def trace(self):
1050
+ """
1051
+ Return the trace of ``self``.
1052
+
1053
+ EXAMPLES::
1054
+
1055
+ sage: K.<a> = GF(2^25)
1056
+ sage: a.trace()
1057
+ 0
1058
+ sage: a.charpoly()
1059
+ x^25 + x^8 + x^6 + x^2 + 1
1060
+ sage: parent(a.trace())
1061
+ Finite Field of size 2
1062
+
1063
+ sage: b = a+1
1064
+ sage: b.trace()
1065
+ 1
1066
+ sage: b.charpoly()[1]
1067
+ 1
1068
+ """
1069
+ if GF2_IsOne(GF2E_trace(self.x)):
1070
+ return GF2_1
1071
+ else:
1072
+ return GF2_0
1073
+
1074
+ def weight(self):
1075
+ """
1076
+ Return the number of nonzero coefficients in the polynomial
1077
+ representation of ``self``.
1078
+
1079
+ EXAMPLES::
1080
+
1081
+ sage: K.<a> = GF(2^21)
1082
+ sage: a.weight()
1083
+ 1
1084
+ sage: (a^5+a^2+1).weight()
1085
+ 3
1086
+ sage: b = 1/(a+1); b
1087
+ a^20 + a^19 + a^18 + a^17 + a^16 + a^15 + a^14 + a^13 + a^12 + a^11 + a^10 + a^9 + a^8 + a^7 + a^6 + a^4 + a^3 + a^2
1088
+ sage: b.weight()
1089
+ 18
1090
+ """
1091
+ return GF2X_weight(GF2E_rep(self.x))
1092
+
1093
+ def _magma_init_(self, magma):
1094
+ r"""
1095
+ Return a string representation of ``self`` that MAGMA can
1096
+ understand.
1097
+
1098
+ EXAMPLES::
1099
+
1100
+ sage: k.<a> = GF(2^16)
1101
+ sage: a._magma_init_(magma) # random; optional - magma
1102
+ '_sage_[...]'
1103
+
1104
+ .. NOTE::
1105
+
1106
+ This method calls MAGMA to setup the parent.
1107
+ """
1108
+ km = magma(self.parent())
1109
+ vn_m = km.gen(1).name()
1110
+ vn_s = str(self.parent().polynomial_ring().gen())
1111
+ return str(self.polynomial()).replace(vn_s,vn_m)
1112
+
1113
+ def __copy__(self):
1114
+ """
1115
+ Return a copy of this element. Actually just returns ``self``, since
1116
+ finite field elements are immutable.
1117
+
1118
+ EXAMPLES::
1119
+
1120
+ sage: k.<a> = GF(2^16)
1121
+ sage: copy(a) is a
1122
+ True
1123
+ """
1124
+ return self
1125
+
1126
+ def __deepcopy__(self, memo):
1127
+ """
1128
+ EXAMPLES::
1129
+
1130
+ sage: k.<a> = GF(2^16)
1131
+ sage: deepcopy(a) is a
1132
+ True
1133
+ """
1134
+ return self
1135
+
1136
+ def _gap_init_(self):
1137
+ r"""
1138
+ Return a string that evaluates to the GAP representation of
1139
+ this element.
1140
+
1141
+ A :exc:`NotImplementedError` is raised if
1142
+ ``self.parent().modulus()`` is not a Conway polynomial, as
1143
+ the isomorphism of finite fields is not implemented yet.
1144
+
1145
+ EXAMPLES::
1146
+
1147
+ sage: k.<b> = GF(2^16)
1148
+ sage: b._gap_init_()
1149
+ 'Z(65536)^1'
1150
+ sage: k(gap('Z(2^16)^3+Z(2^16)^5')) # needs sage.libs.gap
1151
+ b^5 + b^3
1152
+ sage: k(libgap.Z(2^16)^3+libgap.Z(2^16)^5) # needs sage.libs.gap
1153
+ b^5 + b^3
1154
+ """
1155
+ F = self._parent
1156
+ if not F.is_conway():
1157
+ raise NotImplementedError("conversion of (NTL) finite field element to GAP not implemented except for fields defined by Conway polynomials.")
1158
+ order = F.order()
1159
+ if order > 65536:
1160
+ raise TypeError("order (=%s) must be at most 65536." % order)
1161
+ if self == 0:
1162
+ return '0*Z(%s)' % order
1163
+ assert F.degree() > 1
1164
+ g = F.multiplicative_generator()
1165
+ n = self.log(g)
1166
+ return 'Z(%s)^%s' % (order, n)
1167
+
1168
+ def __hash__(FiniteField_ntl_gf2eElement self):
1169
+ """
1170
+ Return the hash of this finite field element. We hash the parent
1171
+ and the underlying integer representation of this element.
1172
+
1173
+ EXAMPLES::
1174
+
1175
+ sage: k.<a> = GF(2^18)
1176
+ sage: {a:1,a:0} # indirect doctest
1177
+ {a: 0}
1178
+ """
1179
+ return hash(self._integer_representation()) # todo, come up with a faster version
1180
+
1181
+ def _vector_(FiniteField_ntl_gf2eElement self, reverse=False):
1182
+ r"""
1183
+ Return a vector matching this element in the vector space attached
1184
+ to the parent. The most significant bit is to the right.
1185
+
1186
+ INPUT:
1187
+
1188
+ - ``reverse`` -- reverse the order of the bits from little endian to
1189
+ big endian
1190
+
1191
+ EXAMPLES::
1192
+
1193
+ sage: k.<a> = GF(2^16)
1194
+ sage: e = a^14 + a^13 + 1
1195
+ sage: vector(e) # little endian
1196
+ (1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0)
1197
+
1198
+ sage: e._vector_(reverse=True) # big endian
1199
+ (0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1)
1200
+ """
1201
+ #vector(foo) might pass in ZZ
1202
+ if isinstance(reverse, Parent):
1203
+ raise TypeError("Base field is fixed to prime subfield.")
1204
+
1205
+ cdef GF2X_c r = GF2E_rep(self.x)
1206
+ cdef int i
1207
+
1208
+ (<Cache_ntl_gf2e>self._parent._cache).F.restore()
1209
+
1210
+ C = []
1211
+ for i from 0 <= i < GF2E_degree():
1212
+ C.append(GF2_conv_to_long(GF2X_coeff(r,i)))
1213
+ if reverse:
1214
+ C = list(reversed(C))
1215
+ return self._parent.vector_space(map=False)(C)
1216
+
1217
+ def __reduce__(FiniteField_ntl_gf2eElement self):
1218
+ """
1219
+ Used for supporting pickling of finite field elements.
1220
+
1221
+ EXAMPLES::
1222
+
1223
+ sage: k.<a> = GF(2^16)
1224
+ sage: loads(dumps(a)) == a
1225
+ True
1226
+ """
1227
+ return unpickleFiniteField_ntl_gf2eElement, (self._parent, str(self))
1228
+
1229
+ def log(self, base, order=None, *, check=False):
1230
+ """
1231
+ Compute an integer `x` such that `b^x = a`, where `a` is ``self``
1232
+ and `b` is ``base``.
1233
+
1234
+ INPUT:
1235
+
1236
+ - ``base`` -- finite field element
1237
+ - ``order`` -- integer (optional), the order of the base
1238
+ - ``check`` -- boolean (default: ``False``): If set,
1239
+ test whether the given ``order`` is correct.
1240
+
1241
+ OUTPUT:
1242
+
1243
+ Integer `x` such that `a^x = b`, if it exists.
1244
+ Raises a :exc:`ValueError` exception if no such `x` exists.
1245
+
1246
+ ALGORITHM: :pari:`fflog`
1247
+
1248
+ EXAMPLES::
1249
+
1250
+ sage: F = FiniteField(2^10, 'a')
1251
+ sage: g = F.gen()
1252
+ sage: b = g; a = g^37
1253
+ sage: a.log(b)
1254
+ 37
1255
+ sage: b^37; a
1256
+ a^8 + a^7 + a^4 + a + 1
1257
+ a^8 + a^7 + a^4 + a + 1
1258
+
1259
+ Big instances used to take a very long time before :issue:`32842`::
1260
+
1261
+ sage: g = GF(2^61).gen()
1262
+ sage: g.log(g^7)
1263
+ 1976436865040309101
1264
+
1265
+ TESTS:
1266
+
1267
+ Check that non-existence is correctly detected::
1268
+
1269
+ sage: g = GF(2^50).gen()
1270
+ sage: (2^50-1) % 1023
1271
+ 0
1272
+ sage: g.log(g^1023)
1273
+ Traceback (most recent call last):
1274
+ ...
1275
+ ValueError: no logarithm of z50 exists to base z50^49 + z50^46 + z50^45 + z50^44 + z50^41 + z50^34 + z50^33 + z50^32 + z50^27 + z50^25 + z50^24 + z50^21 + z50^18 + z50^17 + z50^16 + z50^15 + z50^12 + z50^11 + z50^10 + z50^8 + z50^7 + z50^3 + z50^2
1276
+
1277
+ An example for ``check=True``::
1278
+
1279
+ sage: F.<t> = GF(2^5, impl='ntl')
1280
+ sage: t.log(t, 3^4, check=True)
1281
+ Traceback (most recent call last):
1282
+ ...
1283
+ ValueError: base does not have the provided order
1284
+
1285
+ AUTHORS:
1286
+
1287
+ - David Joyner and William Stein (2005-11)
1288
+ - Lorenz Panny (2021-11): use PARI's :pari:`fflog` instead of :func:`sage.groups.generic.discrete_log`
1289
+ """
1290
+ cdef Integer base_order
1291
+
1292
+ base = self.parent()(base)
1293
+
1294
+ # The result is undefined if the input to fflog() is invalid.
1295
+ # Since the unit group is cyclic, it suffices to check orders.
1296
+ if order is None:
1297
+ base_order = base.multiplicative_order()
1298
+ else:
1299
+ if check:
1300
+ from sage.groups.generic import has_order
1301
+ if not has_order(base, order, '*'):
1302
+ raise ValueError('base does not have the provided order')
1303
+ base_order = order
1304
+
1305
+ cdef Integer self_order = self.multiplicative_order()
1306
+ if not self_order.divides(base_order):
1307
+ raise ValueError(f'no logarithm of {self} exists to base {base}')
1308
+
1309
+ # Let's pass the known factorization of the order to PARI.
1310
+ fs, = self._parent.factored_unit_order() # cached
1311
+ ps = pari.Col(p for p,_ in fs)
1312
+ vs = pari.Col(base_order.valuation(p) for p,_ in fs)
1313
+ fac = pari.matconcat((ps, vs))
1314
+
1315
+ x = pari.fflog(self, base, (base_order, fac))
1316
+ return Integer(x)
1317
+
1318
+
1319
+ def unpickleFiniteField_ntl_gf2eElement(parent, elem):
1320
+ """
1321
+ EXAMPLES::
1322
+
1323
+ sage: k.<a> = GF(2^20)
1324
+ sage: e = k.random_element()
1325
+ sage: f = loads(dumps(e)) # indirect doctest
1326
+ sage: e == f
1327
+ True
1328
+ """
1329
+ return parent(elem)
1330
+
1331
+
1332
+ from sage.misc.persist import register_unpickle_override
1333
+ register_unpickle_override('sage.rings.finite_field_ntl_gf2e', 'unpickleFiniteField_ntl_gf2eElement', unpickleFiniteField_ntl_gf2eElement)