passagemath-singular 10.6.31rc3__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-singular might be problematic. Click here for more details.

Files changed (493) hide show
  1. PySingular.cpython-314-x86_64-linux-musl.so +0 -0
  2. passagemath_singular-10.6.31rc3.dist-info/METADATA +183 -0
  3. passagemath_singular-10.6.31rc3.dist-info/RECORD +493 -0
  4. passagemath_singular-10.6.31rc3.dist-info/WHEEL +5 -0
  5. passagemath_singular-10.6.31rc3.dist-info/top_level.txt +3 -0
  6. passagemath_singular.libs/libSingular-4-67059f19.4.1.so +0 -0
  7. passagemath_singular.libs/libcddgmp-30166d29.so.0.1.3 +0 -0
  8. passagemath_singular.libs/libfactory-4-9d37bcf4.4.1.so +0 -0
  9. passagemath_singular.libs/libflint-fd6f12fc.so.21.0.0 +0 -0
  10. passagemath_singular.libs/libgcc_s-0cd532bd.so.1 +0 -0
  11. passagemath_singular.libs/libgf2x-9e30c3e3.so.3.0.0 +0 -0
  12. passagemath_singular.libs/libgfortran-2c33b284.so.5.0.0 +0 -0
  13. passagemath_singular.libs/libgmp-0e7fc84e.so.10.5.0 +0 -0
  14. passagemath_singular.libs/libgsl-42cda06f.so.28.0.0 +0 -0
  15. passagemath_singular.libs/libmpfr-aaecbfc0.so.6.2.1 +0 -0
  16. passagemath_singular.libs/libncursesw-9c9e32c3.so.6.5 +0 -0
  17. passagemath_singular.libs/libntl-26885ca2.so.44.0.1 +0 -0
  18. passagemath_singular.libs/libomalloc-0-e9ff96db.9.6.so +0 -0
  19. passagemath_singular.libs/libopenblasp-r0-905cb27d.3.29.so +0 -0
  20. passagemath_singular.libs/libpolys-4-8bcf8e7d.4.1.so +0 -0
  21. passagemath_singular.libs/libquadmath-bb76a5fc.so.0.0.0 +0 -0
  22. passagemath_singular.libs/libreadline-06542304.so.8.2 +0 -0
  23. passagemath_singular.libs/libsingular_resources-4-73bf7623.4.1.so +0 -0
  24. passagemath_singular.libs/libstdc++-5d72f927.so.6.0.33 +0 -0
  25. sage/algebras/all__sagemath_singular.py +3 -0
  26. sage/algebras/fusion_rings/all.py +19 -0
  27. sage/algebras/fusion_rings/f_matrix.py +2448 -0
  28. sage/algebras/fusion_rings/fast_parallel_fmats_methods.cpython-314-x86_64-linux-musl.so +0 -0
  29. sage/algebras/fusion_rings/fast_parallel_fmats_methods.pxd +5 -0
  30. sage/algebras/fusion_rings/fast_parallel_fmats_methods.pyx +538 -0
  31. sage/algebras/fusion_rings/fast_parallel_fusion_ring_braid_repn.cpython-314-x86_64-linux-musl.so +0 -0
  32. sage/algebras/fusion_rings/fast_parallel_fusion_ring_braid_repn.pxd +3 -0
  33. sage/algebras/fusion_rings/fast_parallel_fusion_ring_braid_repn.pyx +331 -0
  34. sage/algebras/fusion_rings/fusion_double.py +899 -0
  35. sage/algebras/fusion_rings/fusion_ring.py +1580 -0
  36. sage/algebras/fusion_rings/poly_tup_engine.cpython-314-x86_64-linux-musl.so +0 -0
  37. sage/algebras/fusion_rings/poly_tup_engine.pxd +24 -0
  38. sage/algebras/fusion_rings/poly_tup_engine.pyx +579 -0
  39. sage/algebras/fusion_rings/shm_managers.cpython-314-x86_64-linux-musl.so +0 -0
  40. sage/algebras/fusion_rings/shm_managers.pxd +24 -0
  41. sage/algebras/fusion_rings/shm_managers.pyx +780 -0
  42. sage/algebras/letterplace/all.py +1 -0
  43. sage/algebras/letterplace/free_algebra_element_letterplace.cpython-314-x86_64-linux-musl.so +0 -0
  44. sage/algebras/letterplace/free_algebra_element_letterplace.pxd +18 -0
  45. sage/algebras/letterplace/free_algebra_element_letterplace.pyx +755 -0
  46. sage/algebras/letterplace/free_algebra_letterplace.cpython-314-x86_64-linux-musl.so +0 -0
  47. sage/algebras/letterplace/free_algebra_letterplace.pxd +35 -0
  48. sage/algebras/letterplace/free_algebra_letterplace.pyx +914 -0
  49. sage/algebras/letterplace/letterplace_ideal.cpython-314-x86_64-linux-musl.so +0 -0
  50. sage/algebras/letterplace/letterplace_ideal.pyx +408 -0
  51. sage/algebras/quatalg/all.py +2 -0
  52. sage/algebras/quatalg/quaternion_algebra.py +4778 -0
  53. sage/algebras/quatalg/quaternion_algebra_cython.cpython-314-x86_64-linux-musl.so +0 -0
  54. sage/algebras/quatalg/quaternion_algebra_cython.pyx +261 -0
  55. sage/algebras/quatalg/quaternion_algebra_element.cpython-314-x86_64-linux-musl.so +0 -0
  56. sage/algebras/quatalg/quaternion_algebra_element.pxd +29 -0
  57. sage/algebras/quatalg/quaternion_algebra_element.pyx +2176 -0
  58. sage/all__sagemath_singular.py +11 -0
  59. sage/ext_data/all__sagemath_singular.py +1 -0
  60. sage/ext_data/singular/function_field/core.lib +98 -0
  61. sage/interfaces/all__sagemath_singular.py +1 -0
  62. sage/interfaces/singular.py +2835 -0
  63. sage/libs/all__sagemath_singular.py +1 -0
  64. sage/libs/singular/__init__.py +1 -0
  65. sage/libs/singular/decl.pxd +1168 -0
  66. sage/libs/singular/function.cpython-314-x86_64-linux-musl.so +0 -0
  67. sage/libs/singular/function.pxd +87 -0
  68. sage/libs/singular/function.pyx +1901 -0
  69. sage/libs/singular/function_factory.py +61 -0
  70. sage/libs/singular/groebner_strategy.cpython-314-x86_64-linux-musl.so +0 -0
  71. sage/libs/singular/groebner_strategy.pxd +22 -0
  72. sage/libs/singular/groebner_strategy.pyx +582 -0
  73. sage/libs/singular/option.cpython-314-x86_64-linux-musl.so +0 -0
  74. sage/libs/singular/option.pyx +671 -0
  75. sage/libs/singular/polynomial.cpython-314-x86_64-linux-musl.so +0 -0
  76. sage/libs/singular/polynomial.pxd +39 -0
  77. sage/libs/singular/polynomial.pyx +661 -0
  78. sage/libs/singular/ring.cpython-314-x86_64-linux-musl.so +0 -0
  79. sage/libs/singular/ring.pxd +58 -0
  80. sage/libs/singular/ring.pyx +893 -0
  81. sage/libs/singular/singular.cpython-314-x86_64-linux-musl.so +0 -0
  82. sage/libs/singular/singular.pxd +72 -0
  83. sage/libs/singular/singular.pyx +1944 -0
  84. sage/libs/singular/standard_options.py +145 -0
  85. sage/matrix/all__sagemath_singular.py +1 -0
  86. sage/matrix/matrix_mpolynomial_dense.cpython-314-x86_64-linux-musl.so +0 -0
  87. sage/matrix/matrix_mpolynomial_dense.pxd +7 -0
  88. sage/matrix/matrix_mpolynomial_dense.pyx +615 -0
  89. sage/rings/all__sagemath_singular.py +1 -0
  90. sage/rings/function_field/all__sagemath_singular.py +1 -0
  91. sage/rings/function_field/derivations_polymod.py +911 -0
  92. sage/rings/function_field/element_polymod.cpython-314-x86_64-linux-musl.so +0 -0
  93. sage/rings/function_field/element_polymod.pyx +406 -0
  94. sage/rings/function_field/function_field_polymod.py +2611 -0
  95. sage/rings/function_field/ideal_polymod.py +1775 -0
  96. sage/rings/function_field/order_polymod.py +1475 -0
  97. sage/rings/function_field/place_polymod.py +681 -0
  98. sage/rings/polynomial/all__sagemath_singular.py +1 -0
  99. sage/rings/polynomial/multi_polynomial_ideal_libsingular.cpython-314-x86_64-linux-musl.so +0 -0
  100. sage/rings/polynomial/multi_polynomial_ideal_libsingular.pxd +5 -0
  101. sage/rings/polynomial/multi_polynomial_ideal_libsingular.pyx +339 -0
  102. sage/rings/polynomial/multi_polynomial_libsingular.cpython-314-x86_64-linux-musl.so +0 -0
  103. sage/rings/polynomial/multi_polynomial_libsingular.pxd +30 -0
  104. sage/rings/polynomial/multi_polynomial_libsingular.pyx +6277 -0
  105. sage/rings/polynomial/plural.cpython-314-x86_64-linux-musl.so +0 -0
  106. sage/rings/polynomial/plural.pxd +48 -0
  107. sage/rings/polynomial/plural.pyx +3171 -0
  108. sage/symbolic/all__sagemath_singular.py +1 -0
  109. sage/symbolic/comparison_impl.pxi +428 -0
  110. sage/symbolic/constants_c_impl.pxi +178 -0
  111. sage/symbolic/expression.cpython-314-x86_64-linux-musl.so +0 -0
  112. sage/symbolic/expression.pxd +7 -0
  113. sage/symbolic/expression.pyx +14200 -0
  114. sage/symbolic/getitem_impl.pxi +202 -0
  115. sage/symbolic/pynac.pxi +572 -0
  116. sage/symbolic/pynac_constant_impl.pxi +133 -0
  117. sage/symbolic/pynac_function_impl.pxi +206 -0
  118. sage/symbolic/pynac_impl.pxi +2576 -0
  119. sage/symbolic/pynac_wrap.h +124 -0
  120. sage/symbolic/series_impl.pxi +272 -0
  121. sage/symbolic/substitution_map_impl.pxi +94 -0
  122. sage_wheels/bin/ESingular +0 -0
  123. sage_wheels/bin/Singular +0 -0
  124. sage_wheels/bin/TSingular +0 -0
  125. sage_wheels/lib/singular/MOD/cohomo.la +41 -0
  126. sage_wheels/lib/singular/MOD/cohomo.so +0 -0
  127. sage_wheels/lib/singular/MOD/customstd.la +41 -0
  128. sage_wheels/lib/singular/MOD/customstd.so +0 -0
  129. sage_wheels/lib/singular/MOD/freealgebra.la +41 -0
  130. sage_wheels/lib/singular/MOD/freealgebra.so +0 -0
  131. sage_wheels/lib/singular/MOD/gfanlib.la +41 -0
  132. sage_wheels/lib/singular/MOD/gfanlib.so +0 -0
  133. sage_wheels/lib/singular/MOD/gitfan.la +41 -0
  134. sage_wheels/lib/singular/MOD/gitfan.so +0 -0
  135. sage_wheels/lib/singular/MOD/interval.la +41 -0
  136. sage_wheels/lib/singular/MOD/interval.so +0 -0
  137. sage_wheels/lib/singular/MOD/loctriv.la +41 -0
  138. sage_wheels/lib/singular/MOD/loctriv.so +0 -0
  139. sage_wheels/lib/singular/MOD/machinelearning.la +41 -0
  140. sage_wheels/lib/singular/MOD/machinelearning.so +0 -0
  141. sage_wheels/lib/singular/MOD/p_Procs_FieldGeneral.la +41 -0
  142. sage_wheels/lib/singular/MOD/p_Procs_FieldGeneral.so +0 -0
  143. sage_wheels/lib/singular/MOD/p_Procs_FieldIndep.la +41 -0
  144. sage_wheels/lib/singular/MOD/p_Procs_FieldIndep.so +0 -0
  145. sage_wheels/lib/singular/MOD/p_Procs_FieldQ.la +41 -0
  146. sage_wheels/lib/singular/MOD/p_Procs_FieldQ.so +0 -0
  147. sage_wheels/lib/singular/MOD/p_Procs_FieldZp.la +41 -0
  148. sage_wheels/lib/singular/MOD/p_Procs_FieldZp.so +0 -0
  149. sage_wheels/lib/singular/MOD/partialgb.la +41 -0
  150. sage_wheels/lib/singular/MOD/partialgb.so +0 -0
  151. sage_wheels/lib/singular/MOD/pyobject.la +41 -0
  152. sage_wheels/lib/singular/MOD/pyobject.so +0 -0
  153. sage_wheels/lib/singular/MOD/singmathic.la +41 -0
  154. sage_wheels/lib/singular/MOD/singmathic.so +0 -0
  155. sage_wheels/lib/singular/MOD/sispasm.la +41 -0
  156. sage_wheels/lib/singular/MOD/sispasm.so +0 -0
  157. sage_wheels/lib/singular/MOD/subsets.la +41 -0
  158. sage_wheels/lib/singular/MOD/subsets.so +0 -0
  159. sage_wheels/lib/singular/MOD/systhreads.la +41 -0
  160. sage_wheels/lib/singular/MOD/systhreads.so +0 -0
  161. sage_wheels/lib/singular/MOD/syzextra.la +41 -0
  162. sage_wheels/lib/singular/MOD/syzextra.so +0 -0
  163. sage_wheels/libexec/singular/MOD/change_cost +0 -0
  164. sage_wheels/libexec/singular/MOD/singularsurf +11 -0
  165. sage_wheels/libexec/singular/MOD/singularsurf_jupyter +9 -0
  166. sage_wheels/libexec/singular/MOD/singularsurf_win +10 -0
  167. sage_wheels/libexec/singular/MOD/solve_IP +0 -0
  168. sage_wheels/libexec/singular/MOD/surfex +16 -0
  169. sage_wheels/libexec/singular/MOD/toric_ideal +0 -0
  170. sage_wheels/share/factory/gftables/10201 +342 -0
  171. sage_wheels/share/factory/gftables/1024 +37 -0
  172. sage_wheels/share/factory/gftables/10609 +356 -0
  173. sage_wheels/share/factory/gftables/11449 +384 -0
  174. sage_wheels/share/factory/gftables/11881 +398 -0
  175. sage_wheels/share/factory/gftables/121 +6 -0
  176. sage_wheels/share/factory/gftables/12167 +408 -0
  177. sage_wheels/share/factory/gftables/125 +7 -0
  178. sage_wheels/share/factory/gftables/12769 +428 -0
  179. sage_wheels/share/factory/gftables/128 +7 -0
  180. sage_wheels/share/factory/gftables/1331 +47 -0
  181. sage_wheels/share/factory/gftables/1369 +48 -0
  182. sage_wheels/share/factory/gftables/14641 +490 -0
  183. sage_wheels/share/factory/gftables/15625 +523 -0
  184. sage_wheels/share/factory/gftables/16 +3 -0
  185. sage_wheels/share/factory/gftables/16129 +540 -0
  186. sage_wheels/share/factory/gftables/16384 +549 -0
  187. sage_wheels/share/factory/gftables/16807 +563 -0
  188. sage_wheels/share/factory/gftables/1681 +58 -0
  189. sage_wheels/share/factory/gftables/169 +8 -0
  190. sage_wheels/share/factory/gftables/17161 +574 -0
  191. sage_wheels/share/factory/gftables/1849 +64 -0
  192. sage_wheels/share/factory/gftables/18769 +628 -0
  193. sage_wheels/share/factory/gftables/19321 +646 -0
  194. sage_wheels/share/factory/gftables/19683 +659 -0
  195. sage_wheels/share/factory/gftables/2048 +71 -0
  196. sage_wheels/share/factory/gftables/2187 +75 -0
  197. sage_wheels/share/factory/gftables/2197 +76 -0
  198. sage_wheels/share/factory/gftables/2209 +76 -0
  199. sage_wheels/share/factory/gftables/22201 +742 -0
  200. sage_wheels/share/factory/gftables/22801 +762 -0
  201. sage_wheels/share/factory/gftables/2401 +82 -0
  202. sage_wheels/share/factory/gftables/243 +11 -0
  203. sage_wheels/share/factory/gftables/24389 +815 -0
  204. sage_wheels/share/factory/gftables/24649 +824 -0
  205. sage_wheels/share/factory/gftables/25 +3 -0
  206. sage_wheels/share/factory/gftables/256 +11 -0
  207. sage_wheels/share/factory/gftables/26569 +888 -0
  208. sage_wheels/share/factory/gftables/27 +3 -0
  209. sage_wheels/share/factory/gftables/27889 +932 -0
  210. sage_wheels/share/factory/gftables/2809 +96 -0
  211. sage_wheels/share/factory/gftables/28561 +954 -0
  212. sage_wheels/share/factory/gftables/289 +12 -0
  213. sage_wheels/share/factory/gftables/29791 +995 -0
  214. sage_wheels/share/factory/gftables/29929 +1000 -0
  215. sage_wheels/share/factory/gftables/3125 +107 -0
  216. sage_wheels/share/factory/gftables/32 +4 -0
  217. sage_wheels/share/factory/gftables/32041 +1070 -0
  218. sage_wheels/share/factory/gftables/32761 +1094 -0
  219. sage_wheels/share/factory/gftables/32768 +1095 -0
  220. sage_wheels/share/factory/gftables/343 +14 -0
  221. sage_wheels/share/factory/gftables/3481 +118 -0
  222. sage_wheels/share/factory/gftables/361 +14 -0
  223. sage_wheels/share/factory/gftables/36481 +1218 -0
  224. sage_wheels/share/factory/gftables/3721 +126 -0
  225. sage_wheels/share/factory/gftables/37249 +1244 -0
  226. sage_wheels/share/factory/gftables/38809 +1296 -0
  227. sage_wheels/share/factory/gftables/39601 +1322 -0
  228. sage_wheels/share/factory/gftables/4 +3 -0
  229. sage_wheels/share/factory/gftables/4096 +139 -0
  230. sage_wheels/share/factory/gftables/44521 +1486 -0
  231. sage_wheels/share/factory/gftables/4489 +152 -0
  232. sage_wheels/share/factory/gftables/49 +4 -0
  233. sage_wheels/share/factory/gftables/4913 +166 -0
  234. sage_wheels/share/factory/gftables/49729 +1660 -0
  235. sage_wheels/share/factory/gftables/5041 +170 -0
  236. sage_wheels/share/factory/gftables/50653 +1691 -0
  237. sage_wheels/share/factory/gftables/512 +20 -0
  238. sage_wheels/share/factory/gftables/51529 +1720 -0
  239. sage_wheels/share/factory/gftables/52441 +1750 -0
  240. sage_wheels/share/factory/gftables/529 +20 -0
  241. sage_wheels/share/factory/gftables/5329 +180 -0
  242. sage_wheels/share/factory/gftables/54289 +1812 -0
  243. sage_wheels/share/factory/gftables/57121 +1906 -0
  244. sage_wheels/share/factory/gftables/58081 +1938 -0
  245. sage_wheels/share/factory/gftables/59049 +1971 -0
  246. sage_wheels/share/factory/gftables/6241 +210 -0
  247. sage_wheels/share/factory/gftables/625 +23 -0
  248. sage_wheels/share/factory/gftables/63001 +2102 -0
  249. sage_wheels/share/factory/gftables/64 +5 -0
  250. sage_wheels/share/factory/gftables/6561 +221 -0
  251. sage_wheels/share/factory/gftables/6859 +231 -0
  252. sage_wheels/share/factory/gftables/6889 +232 -0
  253. sage_wheels/share/factory/gftables/729 +27 -0
  254. sage_wheels/share/factory/gftables/7921 +266 -0
  255. sage_wheels/share/factory/gftables/8 +3 -0
  256. sage_wheels/share/factory/gftables/81 +5 -0
  257. sage_wheels/share/factory/gftables/8192 +276 -0
  258. sage_wheels/share/factory/gftables/841 +30 -0
  259. sage_wheels/share/factory/gftables/9 +3 -0
  260. sage_wheels/share/factory/gftables/9409 +316 -0
  261. sage_wheels/share/factory/gftables/961 +34 -0
  262. sage_wheels/share/info/singular.info +191898 -0
  263. sage_wheels/share/singular/LIB/GND.lib +1359 -0
  264. sage_wheels/share/singular/LIB/JMBTest.lib +976 -0
  265. sage_wheels/share/singular/LIB/JMSConst.lib +1363 -0
  266. sage_wheels/share/singular/LIB/KVequiv.lib +699 -0
  267. sage_wheels/share/singular/LIB/SingularityDBM.lib +491 -0
  268. sage_wheels/share/singular/LIB/VecField.lib +1542 -0
  269. sage_wheels/share/singular/LIB/absfact.lib +959 -0
  270. sage_wheels/share/singular/LIB/ainvar.lib +730 -0
  271. sage_wheels/share/singular/LIB/aksaka.lib +419 -0
  272. sage_wheels/share/singular/LIB/alexpoly.lib +2542 -0
  273. sage_wheels/share/singular/LIB/algebra.lib +1193 -0
  274. sage_wheels/share/singular/LIB/all.lib +136 -0
  275. sage_wheels/share/singular/LIB/arcpoint.lib +514 -0
  276. sage_wheels/share/singular/LIB/arnold.lib +4553 -0
  277. sage_wheels/share/singular/LIB/arnoldclassify.lib +2058 -0
  278. sage_wheels/share/singular/LIB/arr.lib +3486 -0
  279. sage_wheels/share/singular/LIB/assprimeszerodim.lib +755 -0
  280. sage_wheels/share/singular/LIB/autgradalg.lib +3361 -0
  281. sage_wheels/share/singular/LIB/bfun.lib +1964 -0
  282. sage_wheels/share/singular/LIB/bimodules.lib +774 -0
  283. sage_wheels/share/singular/LIB/brillnoether.lib +226 -0
  284. sage_wheels/share/singular/LIB/brnoeth.lib +5017 -0
  285. sage_wheels/share/singular/LIB/central.lib +2169 -0
  286. sage_wheels/share/singular/LIB/chern.lib +4162 -0
  287. sage_wheels/share/singular/LIB/cimonom.lib +571 -0
  288. sage_wheels/share/singular/LIB/cisimplicial.lib +1835 -0
  289. sage_wheels/share/singular/LIB/classify.lib +3239 -0
  290. sage_wheels/share/singular/LIB/classify2.lib +1462 -0
  291. sage_wheels/share/singular/LIB/classifyMapGerms.lib +1515 -0
  292. sage_wheels/share/singular/LIB/classify_aeq.lib +3253 -0
  293. sage_wheels/share/singular/LIB/classifyceq.lib +2092 -0
  294. sage_wheels/share/singular/LIB/classifyci.lib +1133 -0
  295. sage_wheels/share/singular/LIB/combinat.lib +91 -0
  296. sage_wheels/share/singular/LIB/compregb.lib +276 -0
  297. sage_wheels/share/singular/LIB/control.lib +1636 -0
  298. sage_wheels/share/singular/LIB/crypto.lib +3795 -0
  299. sage_wheels/share/singular/LIB/curveInv.lib +667 -0
  300. sage_wheels/share/singular/LIB/curvepar.lib +1817 -0
  301. sage_wheels/share/singular/LIB/customstd.lib +100 -0
  302. sage_wheels/share/singular/LIB/deRham.lib +5979 -0
  303. sage_wheels/share/singular/LIB/decodegb.lib +2134 -0
  304. sage_wheels/share/singular/LIB/decomp.lib +1655 -0
  305. sage_wheels/share/singular/LIB/deflation.lib +872 -0
  306. sage_wheels/share/singular/LIB/deform.lib +925 -0
  307. sage_wheels/share/singular/LIB/difform.lib +3055 -0
  308. sage_wheels/share/singular/LIB/divisors.lib +750 -0
  309. sage_wheels/share/singular/LIB/dmod.lib +5817 -0
  310. sage_wheels/share/singular/LIB/dmodapp.lib +3269 -0
  311. sage_wheels/share/singular/LIB/dmodideal.lib +1211 -0
  312. sage_wheels/share/singular/LIB/dmodloc.lib +2645 -0
  313. sage_wheels/share/singular/LIB/dmodvar.lib +818 -0
  314. sage_wheels/share/singular/LIB/dummy.lib +17 -0
  315. sage_wheels/share/singular/LIB/elim.lib +1009 -0
  316. sage_wheels/share/singular/LIB/ellipticcovers.lib +548 -0
  317. sage_wheels/share/singular/LIB/enumpoints.lib +146 -0
  318. sage_wheels/share/singular/LIB/equising.lib +2127 -0
  319. sage_wheels/share/singular/LIB/ffmodstd.lib +2384 -0
  320. sage_wheels/share/singular/LIB/ffsolve.lib +1289 -0
  321. sage_wheels/share/singular/LIB/findifs.lib +778 -0
  322. sage_wheels/share/singular/LIB/finitediff.lib +1768 -0
  323. sage_wheels/share/singular/LIB/finvar.lib +7989 -0
  324. sage_wheels/share/singular/LIB/fpadim.lib +2429 -0
  325. sage_wheels/share/singular/LIB/fpalgebras.lib +1666 -0
  326. sage_wheels/share/singular/LIB/fpaprops.lib +1462 -0
  327. sage_wheels/share/singular/LIB/freegb.lib +3853 -0
  328. sage_wheels/share/singular/LIB/general.lib +1350 -0
  329. sage_wheels/share/singular/LIB/gfan.lib +1768 -0
  330. sage_wheels/share/singular/LIB/gitfan.lib +3130 -0
  331. sage_wheels/share/singular/LIB/gkdim.lib +99 -0
  332. sage_wheels/share/singular/LIB/gmspoly.lib +589 -0
  333. sage_wheels/share/singular/LIB/gmssing.lib +1739 -0
  334. sage_wheels/share/singular/LIB/goettsche.lib +909 -0
  335. sage_wheels/share/singular/LIB/graal.lib +1366 -0
  336. sage_wheels/share/singular/LIB/gradedModules.lib +2541 -0
  337. sage_wheels/share/singular/LIB/graphics.lib +360 -0
  338. sage_wheels/share/singular/LIB/grobcov.lib +7706 -0
  339. sage_wheels/share/singular/LIB/groups.lib +1123 -0
  340. sage_wheels/share/singular/LIB/grwalk.lib +507 -0
  341. sage_wheels/share/singular/LIB/hdepth.lib +194 -0
  342. sage_wheels/share/singular/LIB/help.cnf +57 -0
  343. sage_wheels/share/singular/LIB/hess.lib +1946 -0
  344. sage_wheels/share/singular/LIB/hnoether.lib +4292 -0
  345. sage_wheels/share/singular/LIB/hodge.lib +400 -0
  346. sage_wheels/share/singular/LIB/homolog.lib +1965 -0
  347. sage_wheels/share/singular/LIB/hyperel.lib +975 -0
  348. sage_wheels/share/singular/LIB/inout.lib +679 -0
  349. sage_wheels/share/singular/LIB/integralbasis.lib +6224 -0
  350. sage_wheels/share/singular/LIB/interval.lib +1418 -0
  351. sage_wheels/share/singular/LIB/intprog.lib +778 -0
  352. sage_wheels/share/singular/LIB/invar.lib +443 -0
  353. sage_wheels/share/singular/LIB/involut.lib +980 -0
  354. sage_wheels/share/singular/LIB/jacobson.lib +1215 -0
  355. sage_wheels/share/singular/LIB/kskernel.lib +534 -0
  356. sage_wheels/share/singular/LIB/latex.lib +3146 -0
  357. sage_wheels/share/singular/LIB/lejeune.lib +651 -0
  358. sage_wheels/share/singular/LIB/linalg.lib +2040 -0
  359. sage_wheels/share/singular/LIB/locnormal.lib +212 -0
  360. sage_wheels/share/singular/LIB/lrcalc.lib +526 -0
  361. sage_wheels/share/singular/LIB/makedbm.lib +294 -0
  362. sage_wheels/share/singular/LIB/mathml.lib +813 -0
  363. sage_wheels/share/singular/LIB/matrix.lib +1372 -0
  364. sage_wheels/share/singular/LIB/maxlike.lib +1132 -0
  365. sage_wheels/share/singular/LIB/methods.lib +212 -0
  366. sage_wheels/share/singular/LIB/moddiq.lib +322 -0
  367. sage_wheels/share/singular/LIB/modfinduni.lib +181 -0
  368. sage_wheels/share/singular/LIB/modnormal.lib +218 -0
  369. sage_wheels/share/singular/LIB/modprimdec.lib +1278 -0
  370. sage_wheels/share/singular/LIB/modquotient.lib +269 -0
  371. sage_wheels/share/singular/LIB/modstd.lib +1024 -0
  372. sage_wheels/share/singular/LIB/modular.lib +545 -0
  373. sage_wheels/share/singular/LIB/modules.lib +2561 -0
  374. sage_wheels/share/singular/LIB/modwalk.lib +609 -0
  375. sage_wheels/share/singular/LIB/mondromy.lib +1016 -0
  376. sage_wheels/share/singular/LIB/monomialideal.lib +3851 -0
  377. sage_wheels/share/singular/LIB/mprimdec.lib +2353 -0
  378. sage_wheels/share/singular/LIB/mregular.lib +1863 -0
  379. sage_wheels/share/singular/LIB/multigrading.lib +5629 -0
  380. sage_wheels/share/singular/LIB/ncHilb.lib +777 -0
  381. sage_wheels/share/singular/LIB/ncModslimgb.lib +791 -0
  382. sage_wheels/share/singular/LIB/ncalg.lib +16311 -0
  383. sage_wheels/share/singular/LIB/ncall.lib +31 -0
  384. sage_wheels/share/singular/LIB/ncdecomp.lib +468 -0
  385. sage_wheels/share/singular/LIB/ncfactor.lib +13371 -0
  386. sage_wheels/share/singular/LIB/ncfrac.lib +1023 -0
  387. sage_wheels/share/singular/LIB/nchilbert.lib +448 -0
  388. sage_wheels/share/singular/LIB/nchomolog.lib +759 -0
  389. sage_wheels/share/singular/LIB/ncloc.lib +361 -0
  390. sage_wheels/share/singular/LIB/ncpreim.lib +795 -0
  391. sage_wheels/share/singular/LIB/ncrat.lib +2849 -0
  392. sage_wheels/share/singular/LIB/nctools.lib +1887 -0
  393. sage_wheels/share/singular/LIB/nets.lib +1456 -0
  394. sage_wheels/share/singular/LIB/nfmodstd.lib +1000 -0
  395. sage_wheels/share/singular/LIB/nfmodsyz.lib +732 -0
  396. sage_wheels/share/singular/LIB/noether.lib +1106 -0
  397. sage_wheels/share/singular/LIB/normal.lib +8700 -0
  398. sage_wheels/share/singular/LIB/normaliz.lib +2226 -0
  399. sage_wheels/share/singular/LIB/ntsolve.lib +362 -0
  400. sage_wheels/share/singular/LIB/numerAlg.lib +560 -0
  401. sage_wheels/share/singular/LIB/numerDecom.lib +2261 -0
  402. sage_wheels/share/singular/LIB/olga.lib +1933 -0
  403. sage_wheels/share/singular/LIB/orbitparam.lib +351 -0
  404. sage_wheels/share/singular/LIB/parallel.lib +319 -0
  405. sage_wheels/share/singular/LIB/paraplanecurves.lib +3110 -0
  406. sage_wheels/share/singular/LIB/perron.lib +202 -0
  407. sage_wheels/share/singular/LIB/pfd.lib +2223 -0
  408. sage_wheels/share/singular/LIB/phindex.lib +642 -0
  409. sage_wheels/share/singular/LIB/pointid.lib +673 -0
  410. sage_wheels/share/singular/LIB/polybori.lib +1430 -0
  411. sage_wheels/share/singular/LIB/polyclass.lib +525 -0
  412. sage_wheels/share/singular/LIB/polylib.lib +1174 -0
  413. sage_wheels/share/singular/LIB/polymake.lib +1902 -0
  414. sage_wheels/share/singular/LIB/presolve.lib +1533 -0
  415. sage_wheels/share/singular/LIB/primdec.lib +9576 -0
  416. sage_wheels/share/singular/LIB/primdecint.lib +1782 -0
  417. sage_wheels/share/singular/LIB/primitiv.lib +401 -0
  418. sage_wheels/share/singular/LIB/puiseuxexpansions.lib +1631 -0
  419. sage_wheels/share/singular/LIB/purityfiltration.lib +960 -0
  420. sage_wheels/share/singular/LIB/qhmoduli.lib +1561 -0
  421. sage_wheels/share/singular/LIB/qmatrix.lib +293 -0
  422. sage_wheels/share/singular/LIB/random.lib +455 -0
  423. sage_wheels/share/singular/LIB/ratgb.lib +489 -0
  424. sage_wheels/share/singular/LIB/realclassify.lib +5759 -0
  425. sage_wheels/share/singular/LIB/realizationMatroids.lib +772 -0
  426. sage_wheels/share/singular/LIB/realrad.lib +1197 -0
  427. sage_wheels/share/singular/LIB/recover.lib +2628 -0
  428. sage_wheels/share/singular/LIB/redcgs.lib +3984 -0
  429. sage_wheels/share/singular/LIB/reesclos.lib +465 -0
  430. sage_wheels/share/singular/LIB/resbinomial.lib +2802 -0
  431. sage_wheels/share/singular/LIB/resgraph.lib +789 -0
  432. sage_wheels/share/singular/LIB/resjung.lib +820 -0
  433. sage_wheels/share/singular/LIB/resolve.lib +5110 -0
  434. sage_wheels/share/singular/LIB/resources.lib +170 -0
  435. sage_wheels/share/singular/LIB/reszeta.lib +5473 -0
  436. sage_wheels/share/singular/LIB/ring.lib +1328 -0
  437. sage_wheels/share/singular/LIB/ringgb.lib +343 -0
  438. sage_wheels/share/singular/LIB/rinvar.lib +1153 -0
  439. sage_wheels/share/singular/LIB/rootisolation.lib +1481 -0
  440. sage_wheels/share/singular/LIB/rootsmr.lib +709 -0
  441. sage_wheels/share/singular/LIB/rootsur.lib +886 -0
  442. sage_wheels/share/singular/LIB/rstandard.lib +607 -0
  443. sage_wheels/share/singular/LIB/rwalk.lib +336 -0
  444. sage_wheels/share/singular/LIB/sagbi.lib +1353 -0
  445. sage_wheels/share/singular/LIB/sagbiNormaliz.lib +1622 -0
  446. sage_wheels/share/singular/LIB/sagbiNormaliz0.lib +1498 -0
  447. sage_wheels/share/singular/LIB/sagbigrob.lib +449 -0
  448. sage_wheels/share/singular/LIB/schreyer.lib +321 -0
  449. sage_wheels/share/singular/LIB/schubert.lib +2551 -0
  450. sage_wheels/share/singular/LIB/sets.lib +524 -0
  451. sage_wheels/share/singular/LIB/sheafcoh.lib +1663 -0
  452. sage_wheels/share/singular/LIB/signcond.lib +437 -0
  453. sage_wheels/share/singular/LIB/sing.lib +1094 -0
  454. sage_wheels/share/singular/LIB/sing4ti2.lib +419 -0
  455. sage_wheels/share/singular/LIB/solve.lib +2243 -0
  456. sage_wheels/share/singular/LIB/spcurve.lib +1077 -0
  457. sage_wheels/share/singular/LIB/spectrum.lib +62 -0
  458. sage_wheels/share/singular/LIB/sresext.lib +757 -0
  459. sage_wheels/share/singular/LIB/ssi.lib +143 -0
  460. sage_wheels/share/singular/LIB/standard.lib +2769 -0
  461. sage_wheels/share/singular/LIB/stanleyreisner.lib +473 -0
  462. sage_wheels/share/singular/LIB/stdmodule.lib +547 -0
  463. sage_wheels/share/singular/LIB/stratify.lib +1070 -0
  464. sage_wheels/share/singular/LIB/surf.lib +506 -0
  465. sage_wheels/share/singular/LIB/surf_jupyter.lib +223 -0
  466. sage_wheels/share/singular/LIB/surfacesignature.lib +522 -0
  467. sage_wheels/share/singular/LIB/surfex.lib +1462 -0
  468. sage_wheels/share/singular/LIB/swalk.lib +877 -0
  469. sage_wheels/share/singular/LIB/symodstd.lib +1570 -0
  470. sage_wheels/share/singular/LIB/systhreads.lib +74 -0
  471. sage_wheels/share/singular/LIB/tasks.lib +1324 -0
  472. sage_wheels/share/singular/LIB/tateProdCplxNegGrad.lib +2412 -0
  473. sage_wheels/share/singular/LIB/teachstd.lib +858 -0
  474. sage_wheels/share/singular/LIB/template.lib +116 -0
  475. sage_wheels/share/singular/LIB/toric.lib +1119 -0
  476. sage_wheels/share/singular/LIB/transformation.lib +116 -0
  477. sage_wheels/share/singular/LIB/triang.lib +1197 -0
  478. sage_wheels/share/singular/LIB/tropical.lib +8741 -0
  479. sage_wheels/share/singular/LIB/tropicalEllipticCovers.lib +2922 -0
  480. sage_wheels/share/singular/LIB/tropicalNewton.lib +1128 -0
  481. sage_wheels/share/singular/LIB/tst.lib +1108 -0
  482. sage_wheels/share/singular/LIB/weierstr.lib +241 -0
  483. sage_wheels/share/singular/LIB/zeroset.lib +1478 -0
  484. sage_wheels/share/singular/emacs/.emacs-general +184 -0
  485. sage_wheels/share/singular/emacs/.emacs-singular +234 -0
  486. sage_wheels/share/singular/emacs/COPYING +44 -0
  487. sage_wheels/share/singular/emacs/cmd-cmpl.el +241 -0
  488. sage_wheels/share/singular/emacs/ex-cmpl.el +1681 -0
  489. sage_wheels/share/singular/emacs/hlp-cmpl.el +4318 -0
  490. sage_wheels/share/singular/emacs/lib-cmpl.el +179 -0
  491. sage_wheels/share/singular/emacs/singular.el +4273 -0
  492. sage_wheels/share/singular/emacs/singular.xpm +39 -0
  493. sage_wheels/share/singular/singular.idx +5002 -0
@@ -0,0 +1,3795 @@
1
+ //////////////////////////////////////////////////////////////////////////////
2
+ version="version crypto.lib 4.4.0.5 Jul_2024 "; // $Id: 93d1b02b9c24093376ffb1e1393c18f8b77d541f $
3
+ category="Teaching";
4
+ info="
5
+ LIBRARY: crypto.lib Procedures for teaching cryptography
6
+ AUTHORS: Gerhard Pfister, pfister@mathematik.uni-kl.de
7
+ @* David Brittinger, dativ@gmx.net
8
+
9
+ OVERVIEW:
10
+ The library contains procedures to compute the discrete logarithm,
11
+ primality-tests, factorization included elliptic curves.
12
+ The library is intended to be used for teaching purposes but not
13
+ for serious computations. Sufficiently high printlevel allows to
14
+ control each step, thus illustrating the algorithms at work.
15
+
16
+
17
+ PROCEDURES:
18
+ round(r); rounds r to the nearest number in Z
19
+ bubblesort(L) sorts elements of the list L
20
+ decimal(s); number corresponding to the hexadecimal number s
21
+ eexgcdN(L) T with sum_i L[i]*T[i]=T[n+1]=gcd(L[1],...,L[n])
22
+ lcmN(a,b) compute lcm(a,b)
23
+ powerN(m,d,n) compute m^d mod n
24
+ chineseRem(T,L) compute x such that x = T[i] mod L[i]
25
+ Jacobi(a,n) the generalized Legendre symbol of a and n
26
+ primList(n) the list of all primes <=n
27
+ primL(q) first primes p_1,...,p_r such that q<p_1*...*p_r
28
+ intPart(x) the integral part of a rational number
29
+ intRoot(m) the integral part of the square root of m
30
+ squareRoot(a,p) the square root of a in Z/p, p prime
31
+ solutionsMod2(M) basis solutions of Mx=0 over Z/2
32
+ powerX(q,i,I) q-th power of the i-th variable modulo I
33
+ babyGiant(b,y,p) discrete logarithm x: b^x=y mod p
34
+ rho(b,y,p) discrete logarithm x: b^x=y mod p
35
+ MillerRabin(n,k) probabilistic primaly-test of Miller-Rabin
36
+ SolowayStrassen(n,k) probabilistic primaly-test of Soloway-Strassen
37
+ PocklingtonLehmer(N,[]) primaly-test of Pocklington-Lehmer
38
+ PollardRho(n,k,a,[]) Pollard's rho factorization
39
+ pFactor(n,B,P) Pollard's p-factorization
40
+ quadraticSieve(n,c,B,k) quadratic sieve factorization
41
+ isOnCurve(N,a,b,P) P is on the curve y^2z=x^3+a*xz^2+b*z^3 over Z/N
42
+ ellipticAdd(N,a,b,P,Q) P+Q, addition on elliptic curves
43
+ ellipticMult(N,a,b,P,k) k*P on elliptic curves
44
+ ellipticRandomCurve(N) generates y^2z=x^3+a*xz^2+b*z^3 over Z/N randomly
45
+ ellipticRandomPoint(N,a,b) random point on y^2z=x^3+a*xz^2+b*z^3 over Z/N
46
+ countPoints(N,a,b) number of points of y^2=x^3+a*x+b over Z/N
47
+ ellipticAllPoints(N,a,b) points of y^2=x^3+a*x+b over Z/N
48
+ ShanksMestre(q,a,b,[]) number of points of y^2=x^3+a*x+b over Z/N
49
+ Schoof(N,a,b) number of points of y^2=x^3+a*x+b over Z/N
50
+ generateG(a,b,m) m-th division polynomial of y^2=x^3+a*x+b over Z/N
51
+ factorLenstraECM(N,S,B,[]) Lenstra's factorization
52
+ ECPP(N) primaly-test of Goldwasser-Kilian
53
+ calculate_ordering(num1, primitive, mod1) Calculates x so that primitive^x == num1 mod mod1
54
+ is_primitive_root(primitive, mod1) Checks if primitive is a primitive root modulo mod1
55
+ find_first_primitive_root(mod1) Returns the first primitive root modulo mod1, starting with 1
56
+ binary_add(binary_list) Adds a 1 to a binary encoded list
57
+ inverse_modulus(num,mod1) Finds a t so that t*num = 1 mod mod1
58
+ is_prime(n) Checks if n is prime
59
+ proc find_biggest_index(a) Returns the index of the biggest element of a
60
+ find_index(a,e) Returns the list index of element e in list a. Returns 0 if e is not in a
61
+ subset_sum01(list knapsack, int solution) solves the subset-sum-knapsack-problem by calculating all subsets and choosing the right solution
62
+ subset_sum02(list knapsack, int sol) solves the subset-sum-knapsack-problem with a naive greedy algorithm
63
+ unbounded_knapsack(list knapsack, list profit, int capacity) solves the unbounded_knapsack-problem, needing a list of knapsack weights, a list of profits and a capacity
64
+ multidimensional_knapsack(matrix m, list capacities, list profits) solves the multidimensional_knapsack-problem by using the PECH algorithm, needing a weight matrix m, a list of capacities and a list of profits
65
+ naccache_stern_generation(int key, int primenum) generates a hard knapsack for the Naccache-Stern Kryptosystem for given key and prime modulus
66
+ naccache_stern_encryption(list knapsack, list message, int primenum) encrypts a message with the Naccache-Stern Kryptosystem, using a hard knapsack, a message encoded as binary list and a prime modulus
67
+ naccache_stern_decryption(list knapsack, int key, int primenum, int message) decrypts a message with the Naccache-Stern Kryptosystem, using the easy knapsack, the key, the prime modulus and the message encoded as integer
68
+ m_merkle_hellman_transformation(list knapsack, int primitive, int mod1) generates a hard knapsack for the multiplicative Merkle-Hellman Kryptosystem for a given easy knapsack and a primitive root for a modulus mod1
69
+ m_merkle_hellman_encryption(list knapsack, list message) encrypts a message with the multiplicative Merkle-Hellman Kryptosystem, using a hard knapsack and a message encoded as binary list
70
+ m_merkle_hellman_decryption(list knapsack, bigint primitive, bigint mod1, int message) decrypts a message with the multiplicative Merkle-Hellman Kryptosystem, using the easy knapsack, the key given by the primitive root, the modulus mod1 and the message encoded as integer
71
+ merkle_hellman_transformation(list knapsack, int key, int mod1 generates a hard knapsack for the Merkle-Hellman Kryptosystem for a given easy knapsack , a multiplicator key and a modulus mod1
72
+ merkle_hellman_encryption(list knapsack, list message) encrypts a message with the Merkle-Hellman Kryptosystem, using a hard knapsack and a message encoded as binary list
73
+ merkle_hellman_decryption(list knapsack, int key, int mod1, int message) decrypts a message with the multiplicative Merkle-Hellman Kryptosystem, using the hard knapsack, the key, the modulus mod1 and the message encoded as integer
74
+ super_increasing_knapsack(int ksize) Creates the smallest super-increasing knapsack of given size ksize
75
+ h_increasing_knapsack(int ksize, int h) Creates the smallest h-increasing knapsack of given size ksize and h
76
+ injective_knapsack(int ksize, int kmaxelement) Creates all list of all injective knapsacks of given size ksize and maximal element kmaxelement
77
+ calculate_max_sum(list a) Calculates the maximal sum of a given knapsack a
78
+ set_is_injective(list a) Checks if knapsack a is injective
79
+ is_h_injective(list a, int h) Checks if knapsack a is h-injective
80
+ is_fix_injective(list a) Checks if knapsack a is fix-injective
81
+ three_elements(list out, int iterations) Creates the smallest injective knapsack with a given injective_knapsack by using the three-elements-algorithm with a given number of iterations
82
+
83
+ [parameters in square brackets are optional]
84
+ ";
85
+
86
+ LIB "polylib.lib";
87
+
88
+ ///////////////////////////////////////////////////////////////////////////////
89
+
90
+ proc round(number r)
91
+ "USAGE: round(r);
92
+ RETURN: the nearest number to r out of Z
93
+ ASSUME: r should be a rational or a real number
94
+ EXAMPLE:example round; shows an example
95
+ "
96
+ {
97
+ number a=absValue(r);
98
+ number v=r/a;
99
+
100
+ number d=10;
101
+ int e;
102
+ while(1)
103
+ {
104
+ e=e+1;
105
+ if(a-d^e<0)
106
+ {
107
+ e=e-1;
108
+ break;
109
+ }
110
+ }
111
+
112
+ number b=a;
113
+ int k;
114
+ for(k=0;k<=e;k++)
115
+ {
116
+ while(1)
117
+ {
118
+ b=b-d^(e-k);
119
+ if(b<0)
120
+ {
121
+ b=b+d^(e-k);
122
+ break;
123
+ }
124
+ }
125
+ }
126
+
127
+ if(b<1/2)
128
+ {
129
+ return(v*(a-b));
130
+ }
131
+ else
132
+ {
133
+ return(v*(a+1-b));
134
+ }
135
+ }
136
+ example
137
+ { "EXAMPLE:"; echo = 2;
138
+ ring R = (real,50),x,dp;
139
+ number r=7357683445788723456321.6788643224;
140
+ round(r);
141
+ }
142
+
143
+
144
+ proc bubblesort(list L)
145
+ "USAGE: bubblesort(L);
146
+ RETURN: list L, sort in decreasing order
147
+ EXAMPLE:example bubblesort; shows an example
148
+ "
149
+ {
150
+ def b;
151
+ int n,i,j;
152
+ while(j==0)
153
+ {
154
+ i=i+1;
155
+ j=1;
156
+ for(n=1;n<=size(L)-i;n++)
157
+ {
158
+ if(L[n]<L[n+1])
159
+ {
160
+ b=L[n];
161
+ L[n]=L[n+1];
162
+ L[n+1]=b;
163
+ j=0;
164
+ }
165
+ }
166
+ }
167
+ return(L);
168
+ }
169
+ example
170
+ { "EXAMPLE:"; echo = 2;
171
+ ring r = 0,x,dp;
172
+ list L=-567,-233,446,12,-34,8907;
173
+ bubblesort(L);
174
+ }
175
+
176
+ //=============================================================================
177
+ //=========================== basic prozedures ================================
178
+ //=============================================================================
179
+
180
+ proc decimal(string s)
181
+ "USAGE: decimal(s); s = string
182
+ RETURN: the (decimal) number corresponding to the hexadecimal number s
183
+ EXAMPLE:example decimal; shows an example
184
+ "
185
+ {
186
+ int n=size(s);
187
+ int i;
188
+ bigint k;
189
+ bigint t=16;
190
+ bigint m=0;
191
+ for(i=1;i<=n;i++)
192
+ {
193
+ k=0;
194
+ if(s[i]=="1"){k=1;}
195
+ if(s[i]=="2"){k=2;}
196
+ if(s[i]=="3"){k=3;}
197
+ if(s[i]=="4"){k=4;}
198
+ if(s[i]=="5"){k=5;}
199
+ if(s[i]=="6"){k=6;}
200
+ if(s[i]=="7"){k=7;}
201
+ if(s[i]=="8"){k=8;}
202
+ if(s[i]=="9"){k=9;}
203
+ if(s[i]=="a"){k=10;}
204
+ if(s[i]=="b"){k=11;}
205
+ if(s[i]=="c"){k=12;}
206
+ if(s[i]=="d"){k=13;}
207
+ if(s[i]=="e"){k=14;}
208
+ if(s[i]=="f"){k=15;}
209
+ m=m*t+k;
210
+ }
211
+ return(m);
212
+ }
213
+ example
214
+ { "EXAMPLE:"; echo = 2;
215
+ string s ="8edfe37dae96cfd2466d77d3884d4196";
216
+ decimal(s);
217
+ }
218
+
219
+ proc eexgcdN(list L)
220
+ "USAGE: eexgcdN(L);
221
+ RETURN: list T such that sum_i L[i]*T[i]=T[n+1]=gcd(L[1],...,L[n])
222
+ EXAMPLE:example eexgcdN; shows an example
223
+ "
224
+ {
225
+ if(size(L)==2)
226
+ {
227
+ list LL=extgcd(L[1],L[2]);return(list(LL[2],LL[3],LL[1]));
228
+ }
229
+ bigint p=L[size(L)];
230
+ L=delete(L,size(L));
231
+ list T=eexgcdN(L);
232
+ list S=extgcd(T[size(T)],p);
233
+ int i;
234
+ for(i=1;i<=size(T)-1;i++)
235
+ {
236
+ T[i]=T[i]*S[2];
237
+ }
238
+ p=T[size(T)];
239
+ T[size(T)]=S[3];
240
+ T[size(T)+1]=S[1];
241
+ return(T);
242
+ }
243
+ example
244
+ { "EXAMPLE:"; echo = 2;
245
+ eexgcdN(list(24,15,21));
246
+ }
247
+
248
+ proc lcmN(bigint a, bigint b)
249
+ "USAGE: lcmN(a,b);
250
+ RETURN: lcm(a,b);
251
+ EXAMPLE:example lcmN; shows an example
252
+ "
253
+ {
254
+ return (a*b/gcd(a,b));
255
+ }
256
+ example
257
+ { "EXAMPLE:"; echo = 2;
258
+ lcmN(24,15);
259
+ }
260
+
261
+ proc powerN(bigint m, bigint d, bigint n)
262
+ "USAGE: powerN(m,d,n);
263
+ RETURN: m^d mod n
264
+ EXAMPLE:example powerN; shows an example
265
+ "
266
+ {
267
+ if(d==0){return(bigint(1));}
268
+ int i;
269
+ if(n==0)
270
+ {
271
+ for(i=12;i>=2;i--)
272
+ {
273
+ if((d mod i)==0){return(powerN(m,d div i,n)^i);}
274
+ }
275
+ return(m*powerN(m,d-1,n));
276
+ }
277
+ for(i=12;i>=2;i--)
278
+ {
279
+ if((d mod i)==0)
280
+ {
281
+ bigint rr=powerN(m,d div i,n)^i mod n;
282
+ if (rr<0) { rr=rr+n;}
283
+ return(rr);
284
+ }
285
+ }
286
+ return(m*powerN(m,d-1,n) mod n);
287
+ }
288
+ example
289
+ { "EXAMPLE:"; echo = 2;
290
+ powerN(24,15,7);
291
+ }
292
+
293
+ proc chineseRem(list T,list L)
294
+ "USAGE: chineseRem(T,L);
295
+ RETURN: x such that x = T[i] mod L[i]
296
+ NOTE: chinese remainder theorem
297
+ EXAMPLE:example chineseRem; shows an example
298
+ "
299
+ {
300
+ int i;
301
+ int n=size(L);
302
+ bigint N=1;
303
+ for(i=1;i<=n;i++)
304
+ {
305
+ N=N*L[i];
306
+ }
307
+ list M;
308
+ for(i=1;i<=n;i++)
309
+ {
310
+ M[i]=N div L[i];
311
+ }
312
+ list S=eexgcdN(M);
313
+ bigint x;
314
+ for(i=1;i<=n;i++)
315
+ {
316
+ x=x+S[i]*M[i]*T[i];
317
+ }
318
+ x=x mod N;
319
+ return(x);
320
+ }
321
+ example
322
+ { "EXAMPLE:"; echo = 2;
323
+ chineseRem(list(24,15,7),list(2,3,5));
324
+ }
325
+
326
+ proc Jacobi(bigint a, bigint n)
327
+ "USAGE: Jacobi(a,n);
328
+ RETURN: the generalized Legendre symbol
329
+ NOTE: if n is an odd prime then Jacobi(a,n)=0,1,-1 if n|a, a=x^2 mod n,else
330
+ EXAMPLE:example Jacobi; shows an example
331
+ "
332
+ {
333
+ int i;
334
+ int z=1;
335
+ bigint t=1;
336
+ bigint k;
337
+
338
+ if((((n-1) div 2) mod 2)!=0){z=-1;}
339
+ if(a<0){return(z*Jacobi(-a,n));}
340
+ a=a mod n;
341
+ if(n==1){return(1);}
342
+ if(a==0){return(0);}
343
+
344
+ while(a!=0)
345
+ {
346
+ while((a mod 2)==0)
347
+ {
348
+ a=a div 2;
349
+ if(((n mod 8)==3)||((n mod 8)==5)){t=-t;}
350
+ }
351
+ k=a;a=n;n=k;
352
+ if(((a mod 4)==3)&&((n mod 4)==3)){t=-t;}
353
+ a=a mod n;
354
+ }
355
+ if (n==1){return(t);}
356
+ return(0);
357
+ }
358
+ example
359
+ { "EXAMPLE:"; echo = 2;
360
+ Jacobi(13580555397810650806,5792543);
361
+ }
362
+
363
+ proc primList(int n)
364
+ "USAGE: primList(n);
365
+ RETURN: the list of all primes <=n
366
+ EXAMPLE:example primList; shows an example
367
+ "
368
+ {
369
+ int i,j;
370
+ list re;
371
+ re[1]=2;
372
+ re[2]=3;
373
+ for(i=5;i<=n;i=i+2)
374
+ {
375
+ j=1;
376
+ while(j<=size(re))
377
+ {
378
+ if((i mod re[j])==0){break;}
379
+ j++;
380
+ }
381
+ if(j==size(re)+1){re[size(re)+1]=i;}
382
+ }
383
+ return(re);
384
+ }
385
+ example
386
+ { "EXAMPLE:"; echo = 2;
387
+ list L=primList(100);
388
+ size(L);
389
+ L[size(L)];
390
+ }
391
+
392
+ proc primL(bigint q)
393
+ "USAGE: primL(q);
394
+ RETURN: list of the first primes p_1,...,p_r such that q>p_1*...*p_(r-1)
395
+ and q<p_1*...*p_r
396
+ EXAMPLE:example primL; shows an example
397
+ "
398
+ {
399
+ int i,j;
400
+ list re;
401
+ re[1]=2;
402
+ re[2]=3;
403
+ bigint s=6;
404
+ i=3;
405
+ while(s<=q)
406
+ {
407
+ i=i+2;
408
+ j=1;
409
+ while(j<=size(re))
410
+ {
411
+ if((i mod re[j])==0){break;}
412
+ j++;
413
+ }
414
+ if(j==size(re)+1)
415
+ {
416
+ re[size(re)+1]=i;
417
+ s=s*i;
418
+ }
419
+ }
420
+ return(re);
421
+ }
422
+ example
423
+ { "EXAMPLE:"; echo = 2;
424
+ primL(20);
425
+ }
426
+
427
+ proc intPart(number x)
428
+ "USAGE: intPart(x);
429
+ RETURN: the integral part of a rational number
430
+ EXAMPLE:example intPart; shows an example
431
+ "
432
+ {
433
+ if (x>=0)
434
+ {
435
+ return(bigint((numerator(x)-(bigint(numerator(x)) mod bigint(denominator(x)))))
436
+ div bigint(denominator(x)));
437
+ }
438
+ else
439
+ {
440
+ return(bigint((numerator(x)-(bigint(numerator(x)) mod bigint(denominator(x)+denominator(x)))))
441
+ div bigint(denominator(x)));
442
+ }
443
+ }
444
+ example
445
+ { "EXAMPLE:"; echo = 2;
446
+ ring r=0,x,dp;
447
+ intPart(7/3);
448
+ }
449
+
450
+ proc intRoot(bigint mm)
451
+ "USAGE: intRoot(m);
452
+ RETURN: the integral part of the square root of m
453
+ EXAMPLE:example intRoot; shows an example
454
+ "
455
+ {
456
+ ring R = 0,@x,dp;
457
+ number m=mm;
458
+ number x=1;
459
+ number t=x^2;
460
+ number s=(x+1)^2;
461
+ while(((m>t)&&(m>s))||((m<t)&&(m<s)))
462
+ {
463
+ if (x==0) { t=0; }
464
+ else
465
+ {
466
+ x=intPart(x/2+m/(2*x)); //Newton step
467
+ t=x^2;
468
+ }
469
+ if(t>m)
470
+ {
471
+ s=(x-1)^2;
472
+ }
473
+ else
474
+ {
475
+ s=(x+1)^2;
476
+ }
477
+ }
478
+ if(t>m){return(bigint(x-1));}
479
+ if(s==m){return(bigint(x+1));}
480
+ return(bigint(x));
481
+ }
482
+ example
483
+ { "EXAMPLE:"; echo = 2;
484
+ intRoot(20);
485
+ }
486
+
487
+ proc squareRoot(bigint a, bigint p)
488
+ "USAGE: squareRoot(a,p);
489
+ RETURN: the square root of a in Z/p, p prime
490
+ NOTE: assumes the Jacobi symbol is 1 or p=2.
491
+ EXAMPLE:example squareRoot; shows an example
492
+ "
493
+ {
494
+ if(p==2){return(a);}
495
+ if((a mod p)==0){return(0);}
496
+ if (a<0) { a=a+p; }
497
+ if(powerN(a,p-1,p)!=1)
498
+ {
499
+ "p is not prime";
500
+ return(bigint(-5));
501
+ }
502
+ bigint n=random(1,2147483647) mod p;
503
+ if(n==0){n=n+1;}
504
+ bigint j=Jacobi(n,p);
505
+ if(j==0)
506
+ {
507
+ "p is not prime";
508
+ return(bigint(-5));
509
+ }
510
+ if(j==1)
511
+ {
512
+ return(squareRoot(a,p));
513
+ }
514
+ bigint q=p-1;
515
+ bigint e=0;
516
+ bigint two=2;
517
+ bigint z,m,t;
518
+ while((q mod 2)==0)
519
+ {
520
+ e=e+1;
521
+ q=q div 2;
522
+ }
523
+ bigint y=powerN(n,q,p);
524
+ bigint r=e;
525
+ bigint x=powerN(a,(q-1) div 2,p);
526
+ bigint b=a*x^2 mod p;
527
+ x=a*x mod p;
528
+
529
+ while(((b-1) mod p)!=0)
530
+ {
531
+ m=0;z=b;
532
+ while(((z-1) mod p)!=0)
533
+ {
534
+ z=z^2 mod p;
535
+ m=m+1;
536
+ }
537
+ t=powerN(y,powerN(two,r-m-1,p),p);
538
+ y=t^2 mod p;
539
+ r=m;
540
+ x=x*t mod p;
541
+ b=b*y mod p;
542
+ }
543
+ return(x);
544
+ }
545
+ example
546
+ { "EXAMPLE:"; echo = 2;
547
+ squareRoot(8315890421938608,32003);
548
+ }
549
+
550
+
551
+ proc solutionsMod2(bigintmat MM)
552
+ "USAGE: solutionsMod2(M);
553
+ RETURN: an intmat containing a basis of the vector space of solutions of the
554
+ linear system of equations defined by M over the prime field of
555
+ characteristic 2
556
+ EXAMPLE:example solutionsMod2; shows an example
557
+ "
558
+ {
559
+ ring Rhelp=2,z,(c,dp);
560
+ int i,j;
561
+ matrix M[nrows(MM)][ncols(MM)];
562
+ for(i=1;i<=nrows(MM);i++)
563
+ {
564
+ for(j=1;j<=ncols(MM);j++)
565
+ {
566
+ M[i,j]=MM[i,j];
567
+ }
568
+ }
569
+ matrix S=syz(M);
570
+ intmat v[nrows(S)][ncols(S)];
571
+ for(i=1;i<=nrows(S);i++)
572
+ {
573
+ for(j=1;j<=ncols(S);j++)
574
+ {
575
+ if(S[i,j]==1){v[i,j]=1;}
576
+ }
577
+ }
578
+ return(v);
579
+ }
580
+ example
581
+ { "EXAMPLE:"; echo = 2;
582
+ bigintmat M[3][3]=1,2,3,4,5,6,7,6,5;
583
+ solutionsMod2(M);
584
+ }
585
+
586
+ proc powerX(int q, int i, ideal I)
587
+ "USAGE: powerX(q,i,I);
588
+ RETURN: the q-th power of the i-th variable modulo I
589
+ ASSUME: I is a standard basis
590
+ EXAMPLE:example powerX; shows an example
591
+ "
592
+ {
593
+ if(q<=181){return(reduce(var(i)^int(q),I));}
594
+ if((q mod 5)==0){return(reduce(powerX(q div 5,i,I)^5,I));}
595
+ if((q mod 4)==0){return(reduce(powerX(q div 4,i,I)^4,I));}
596
+ if((q mod 3)==0){return(reduce(powerX(q div 3,i,I)^3,I));}
597
+ if((q mod 2)==0){return(reduce(powerX(q div 2,i,I)^2,I));}
598
+ return(reduce(var(i)*powerX(q-1,i,I),I));
599
+ }
600
+ example
601
+ { "EXAMPLE:"; echo = 2;
602
+ ring R = 0,(x,y),dp;
603
+ powerX(100,2,std(ideal(x3-1,y2-x)));
604
+ }
605
+
606
+ //======================================================================
607
+ //=========================== Discrete Logarithm =======================
608
+ //======================================================================
609
+
610
+ //============== Shank's baby step - giant step ========================
611
+
612
+ proc babyGiant(bigint b, bigint y, bigint p)
613
+ "USAGE: babyGiant(b,y,p);
614
+ RETURN: the discrete logarithm x: b^x=y mod p
615
+ NOTE: This procedure works based on Shank's baby step - giant step method.
616
+ EXAMPLE:example babyGiant; shows an example
617
+ "
618
+ {
619
+ int i,j,m;
620
+ list l;
621
+ bigint h=1;
622
+ bigint x;
623
+
624
+ //choose m minimal such that m^2>p
625
+ for(i=1;i<=p;i++){if(i^2>p) break;}
626
+ m=i;
627
+
628
+ //baby-step: compute the table y*b^i for 1<=i<=m
629
+ for(i=1;i<=m;i++){l[i]=y*b^i mod p;}
630
+
631
+ //giant-step: compute b^(m+j), 1<=j<=m and search in the baby-step table
632
+ //for an i with y*b^i=b^(m*j). If found then x=m*j-i
633
+ bigint g=b^m mod p;
634
+ while(j<m)
635
+ {
636
+ j++;
637
+ h=h*g mod p;
638
+ for(i=1;i<=m;i++)
639
+ {
640
+ if(h==l[i])
641
+ {
642
+ x=m*j-i;
643
+ j=m;
644
+ break;
645
+ }
646
+ }
647
+ }
648
+ return(x);
649
+ }
650
+ example
651
+ { "EXAMPLE:"; echo = 2;
652
+ bigint b=2;
653
+ bigint y=10;
654
+ bigint p=101;
655
+ babyGiant(b,y,p);
656
+ }
657
+
658
+ //============== Pollards rho =================================
659
+
660
+ proc rho(bigint b, bigint y, bigint p)
661
+ "USAGE: rho(b,y,p);
662
+ RETURN: the discrete logarithm x=log_b(y): b^x=y mod p
663
+ NOTE: Pollard's rho:
664
+ choose random f_0 in 0,...,p-2 ,e_0=0, define x_0=b^f_0, define
665
+ x_i=y^e_i*b^f_i as below. For i large enough there is i with
666
+ x_(i/2)=x_i. Let s:=e_(i/2)-e_i mod p-1 and t:=f_i-f_(i/2) mod p-1,
667
+ d=gcd(s,p-1)=u*s+v*(p-1) then x=tu/d +j*(p-1)/d for some j (to be
668
+ found by trying)
669
+ EXAMPLE:example rho; shows an example
670
+ "
671
+ {
672
+ int i=1;
673
+ int j;
674
+ bigint s,t;
675
+ list e,f,x;
676
+
677
+ e[1]=0;
678
+ f[1]=random(0,2147483629) mod (p-1);
679
+ x[1]=powerN(b,f[1],p);
680
+ while(i)
681
+ {
682
+ if((x[i] mod 3)==1)
683
+ {
684
+ x[i+1]=y*x[i] mod p;
685
+ e[i+1]=e[i]+1 mod (p-1);
686
+ f[i+1]=f[i];
687
+ }
688
+ if((x[i] mod 3)==2)
689
+ {
690
+ x[i+1]=x[i]^2 mod p;
691
+ e[i+1]=e[i]*2 mod (p-1);
692
+ f[i+1]=f[i]*2 mod (p-1);
693
+ }
694
+ if((x[i] mod 3)==0)
695
+ {
696
+ x[i+1]=x[i]*b mod p;
697
+ e[i+1]=e[i];
698
+ f[i+1]=f[i]+1 mod (p-1);
699
+ }
700
+ i++;
701
+ for(j=i-1;j>=1;j--)
702
+ {
703
+ if(x[i]==x[j])
704
+ {
705
+ s=(e[j]-e[i]) mod (p-1);
706
+ t=(f[i]-f[j]) mod (p-1);
707
+ if(s!=0)
708
+ {
709
+ i=0;
710
+ }
711
+ else
712
+ {
713
+ e[1]=0;
714
+ f[1]=random(0,2147483629) mod (p-1);
715
+ x[1]=powerN(b,f[1],p);
716
+ i=1;
717
+ }
718
+ break;
719
+ }
720
+ }
721
+ }
722
+
723
+ list w=extgcd(s,p-1);
724
+ bigint u=w[2];
725
+ bigint d=w[1];
726
+
727
+ bigint a=(t*u div d) mod (p-1);
728
+
729
+ bigint pn=powerN(b,a,p);
730
+ if (pn<0) { pn=pn+p;}
731
+ while(powerN(b,a,p)!=y)
732
+ {
733
+ a=(a+(p-1) div d) mod (p-1);
734
+ if (a<0) { a=a+p-1; }
735
+ }
736
+ return(a);
737
+ }
738
+ example
739
+ { "EXAMPLE:"; echo = 2;
740
+ bigint b=2;
741
+ bigint y=10;
742
+ bigint p=101;
743
+ rho(b,y,p);
744
+ }
745
+ //====================================================================
746
+ //====================== Primality Tests =============================
747
+ //====================================================================
748
+
749
+ //================================= Miller-Rabin =====================
750
+
751
+ proc MillerRabin(bigint n, int k)
752
+ "USAGE: MillerRabin(n,k);
753
+ RETURN: 1 if n is prime, 0 else
754
+ NOTE: probabilistic test of Miller-Rabin with k loops to test if n is prime.
755
+ Using the theorem: If n is prime, n-1=2^s*r, r odd, then
756
+ powerN(a,r,n)=1 or powerN(a,r*2^i,n)=-1 for some i
757
+ EXAMPLE:example MillerRabin; shows an example
758
+ "
759
+ {
760
+ if(n<0){n=-n;}
761
+ if((n==2)||(n==3)){return(1);}
762
+ if((n mod 2)==0){return(0);}
763
+
764
+ int i;
765
+ bigint a,b,j,r,s;
766
+ r=n-1;
767
+ s=0;
768
+ while((r mod 2)==0)
769
+ {
770
+ s=s+1;
771
+ r=r div 2;
772
+ }
773
+ while(i<k)
774
+ {
775
+ i++;
776
+ a=random(2,2147483629) mod n; if(a==0){a=3;}
777
+ if(gcd(a,n)!=1){return(0);}
778
+ b=powerN(a,r,n);
779
+ if(b!=1)
780
+ {
781
+ j=0;
782
+ while(j<s)
783
+ {
784
+ if(((b+1) mod n)==0) break;
785
+ b=powerN(b,2,n);
786
+ j=j+1;
787
+ }
788
+ if(j==s){return(0);}
789
+ }
790
+ }
791
+ return(1);
792
+ }
793
+ example
794
+ { "EXAMPLE:"; echo = 2;
795
+ bigint x=2;
796
+ x=x^787-1;
797
+ MillerRabin(x,3);
798
+ }
799
+
800
+ //======================= Soloway-Strassen ==========================
801
+
802
+ proc SolowayStrassen(bigint n, int k)
803
+ "USAGE: SolowayStrassen(n,k);
804
+ RETURN: 1 if n is prime, 0 else
805
+ NOTE: probabilistic test of Soloway-Strassen with k loops to test if n is
806
+ prime using the theorem: If n is prime then
807
+ powerN(a,(n-1)/2,n)=Jacobi(a,n) mod n
808
+ EXAMPLE:example SolowayStrassen; shows an example
809
+ "
810
+ {
811
+ if(n<0){n=-n;}
812
+ if((n==2)||(n==3)){return(1);}
813
+ if((n mod 2)==0){return(0);}
814
+
815
+ bigint a,pn,jn;
816
+ int i;
817
+ while(i<k)
818
+ {
819
+ i++;
820
+ a=random(2,2147483629) mod n; if(a==0){a=3;}
821
+ if(gcd(a,n)!=1){return(0);}
822
+ pn=powerN(a,(n-1) div 2,n);
823
+ if (pn<0) { pn=pn+n;}
824
+ jn=Jacobi(a,n) mod n;
825
+ if (jn<0) { jn=jn+n;}
826
+ if(pn!=jn){return(0);}
827
+ }
828
+ return(1);
829
+ }
830
+ example
831
+ { "EXAMPLE:"; echo = 2;
832
+ bigint h=10;
833
+ bigint p=h^100+267;
834
+ //p=h^100+43723;
835
+ //p=h^200+632347;
836
+ SolowayStrassen(h,3);
837
+ }
838
+
839
+
840
+ /*
841
+ ring R=0,z,dp;
842
+ number p=398075086424064937397125500550386491199064362342526708406385189575946388957261768583317;
843
+ number q=472772146107435302536223071973048224632914695302097116459852171130520711256363590397527;
844
+ number n=p*q;
845
+ SolowayStrassen(n,3);
846
+ */
847
+
848
+ //===================== Pocklington-Lehmer ==============================
849
+
850
+ proc PocklingtonLehmer(bigint N, list #)
851
+ "USAGE: PocklingtonLehmer(N); optional: PocklingtonLehmer(N,L);
852
+ L a list of the first k primes
853
+ RETURN:message N is not prime or {A,{p},{a_p}} as certificate for N being prime
854
+ NOTE:assumes that it is possible to factorize N-1=A*B such that gcd(A,B)=1,
855
+ the factorization of A is completely known and A^2>N .
856
+ N is prime if and only if for each prime factor p of A we can find
857
+ a_p such that a_p^(N-1)=1 mod N and gcd(a_p^((N-1)/p)-1,N)=1
858
+ EXAMPLE:example PocklingtonLehmer; shows an example
859
+ "
860
+ {
861
+ bigint m=intRoot(N);
862
+ if(size(#)>0)
863
+ {
864
+ list S=PollardRho(N-1,10000,1,#);
865
+ }
866
+ else
867
+ {
868
+ list S=PollardRho(N-1,10000,1);
869
+ }
870
+ int i,j;
871
+ bigint A=1;
872
+ bigint p,a,g;
873
+ list PA;
874
+ list re;
875
+
876
+ while(i<size(S))
877
+ {
878
+ p=S[i+1];
879
+ A=A*p;
880
+ PA[i+1]=p;
881
+ if(A>m){break;}
882
+
883
+ while(1)
884
+ {
885
+ p=p*S[i+1];
886
+ if(((N-1) mod p)==0)
887
+ {
888
+ A=A*p;
889
+ }
890
+ else
891
+ {
892
+ break;
893
+ }
894
+ }
895
+ i++;
896
+ }
897
+ if(A<=m)
898
+ {
899
+ A=N div A;
900
+ PA=list(S[size(S)]);
901
+ }
902
+ for(i=1;i<=size(PA);i++)
903
+ {
904
+ a=1;
905
+ while(a<N-1)
906
+ {
907
+ a=a+1;
908
+ if(powerN(a,N-1,N)!=1){return("not prime");}
909
+ g=gcd(powerN(a,(N-1) div PA[i],N),N);
910
+ if(g==1)
911
+ {
912
+ re[size(re)+1]=list(PA[i],a);
913
+ break;
914
+ }
915
+ if(g<N){"not prime";return(g);}
916
+ }
917
+ }
918
+ return(list(A,re));
919
+ }
920
+ example
921
+ { "EXAMPLE:"; echo = 2;
922
+ bigint N=105554676553297;
923
+ PocklingtonLehmer(N);
924
+ list L=primList(1000);
925
+ PocklingtonLehmer(N,L);
926
+ }
927
+
928
+ //=======================================================================
929
+ //======================= Factorization =================================
930
+ //=======================================================================
931
+
932
+ //======================= Pollards rho =================================
933
+
934
+ proc PollardRho(bigint n, int k, int allFactors, list #)
935
+ "USAGE: PollardRho(n,k,allFactors); optional: PollardRho(n,k,allFactors,L);
936
+ L a list of the first k primes
937
+ RETURN: a list of factors of n (which could be just n),if allFactors=0@*
938
+ a list of all factors of n ,if allFactors=1
939
+ NOTE: probabilistic rho-algorithm of Pollard to find a factor of n in k loops.
940
+ Creates a sequence x_i such that (x_i)^2=(x_2i)^2 mod n for some i,
941
+ computes gcd(x_i-x_2i,n) to find a divisor. To define the sequence
942
+ choose x,a and define x_n+1=x_n^2+a mod n, x_1=x.
943
+ If allFactors is 1, it tries to find recursively all prime factors
944
+ using the Soloway-Strassen test.
945
+ SEE ALSO: primefactors
946
+ EXAMPLE:example PollardRho; shows an example
947
+ "
948
+ {
949
+ int i,j;
950
+ list L=primList(100);
951
+ list re,se;
952
+ if(n<0){n=-n;}
953
+ if(n==1){return(re);}
954
+
955
+ //this is optional: test whether a prime of the list # divides n
956
+ if(size(#)>0)
957
+ {
958
+ L=#;
959
+ }
960
+ for(i=1;i<=size(L);i++)
961
+ {
962
+ if((n mod L[i])==0)
963
+ {
964
+ re[size(re)+1]=L[i];
965
+ while((n mod L[i])==0)
966
+ {
967
+ n=n div L[i];
968
+ }
969
+ }
970
+ if(n==1){return(re);}
971
+ }
972
+ int e=size(re);
973
+ //here the rho-algorithm starts
974
+ bigint a,d,x,y;
975
+ while(n>1)
976
+ {
977
+ a=random(2,2147483629);
978
+ x=random(2,2147483629);
979
+ y=x;
980
+ d=1;
981
+ i=0;
982
+ while(i<k)
983
+ {
984
+ i++;
985
+ x=powerN(x,2,n); x=(x+a) mod n;
986
+ y=powerN(y,2,n); y=(y+a) mod n;
987
+ y=powerN(y,2,n); y=(y+a) mod n;
988
+ d=gcd(x-y,n);
989
+ if(d>1)
990
+ {
991
+ re[size(re)+1]=d;
992
+ while((n mod d)==0)
993
+ {
994
+ n=n div d;
995
+ }
996
+ break;
997
+ }
998
+ if(i==k)
999
+ {
1000
+ re[size(re)+1]=n;
1001
+ n=1;
1002
+ }
1003
+ }
1004
+ }
1005
+ if(allFactors) //want to obtain all prime factors
1006
+ {
1007
+ i=e;
1008
+ while(i<size(re))
1009
+ {
1010
+ i++;
1011
+
1012
+ if(!SolowayStrassen(re[i],5))
1013
+ {
1014
+ se=PollardRho(re[i],2*k,1);
1015
+ re[i]=se[size(se)];
1016
+ for(j=1;j<=size(se)-1;j++)
1017
+ {
1018
+ re[size(re)+1]=se[j];
1019
+ }
1020
+ i--;
1021
+ }
1022
+ }
1023
+ }
1024
+ return(re);
1025
+ }
1026
+ example
1027
+ { "EXAMPLE:"; echo = 2;
1028
+ bigint h=10;
1029
+ bigint p=h^30+4;
1030
+ PollardRho(p,5000,0);
1031
+ }
1032
+
1033
+ //======================== Pollards p-factorization ================
1034
+ proc pFactor(bigint n,int B, list P)
1035
+ "USAGE: pFactor(n,B,P); n to be factorized, B a bound , P a list of primes
1036
+ RETURN: a list of factors of n or n if no factor found
1037
+ NOTE: Pollard's p-factorization
1038
+ creates the product k of powers of primes (bounded by B) from
1039
+ the list P with the idea that for a prime divisor p of n we have
1040
+ p-1|k, and then p divides gcd(a^k-1,n) for some random a
1041
+ EXAMPLE:example pFactor; shows an example
1042
+ "
1043
+ {
1044
+ int i;
1045
+ bigint k=1;
1046
+ bigint w;
1047
+ while(i<size(P))
1048
+ {
1049
+ i++;
1050
+ w=P[i];
1051
+ if(w>B) break;
1052
+ while(w*P[i]<=B)
1053
+ {
1054
+ w=w*P[i];
1055
+ }
1056
+ k=k*w;
1057
+ }
1058
+ bigint a=random(2,2147483629);
1059
+ bigint d=gcd(powerN(a,k,n)-1,n);
1060
+ if((d>1)&&(d<n)){return(d);}
1061
+ return(n);
1062
+ }
1063
+ example
1064
+ { "EXAMPLE:"; echo = 2;
1065
+ list L=primList(1000);
1066
+ pFactor(1241143,13,L);
1067
+ bigint h=10;
1068
+ h=h^30+25;
1069
+ pFactor(h,20,L);
1070
+ }
1071
+
1072
+ //==================== quadratic sieve ==============================
1073
+
1074
+ proc quadraticSieve(bigint n, int c, list B, int k)
1075
+ "USAGE: quadraticSieve(n,c,B,k); n to be factorized, [-c,c] the
1076
+ sieve-intervall, B a list of primes,
1077
+ k for using the first k elements in B
1078
+ RETURN: a list of factors of n or the message: no divisor found
1079
+ NOTE: The idea being used is to find x,y such that x^2=y^2 mod n then
1080
+ gcd(x-y,n) can be a proper divisor of n
1081
+ EXAMPLE:example quadraticSieve; shows an example
1082
+ "
1083
+ {
1084
+ bigint f,d;
1085
+ int i,j,l,s,p;
1086
+ list S,tmp;
1087
+ intvec v;
1088
+ v[k]=0;
1089
+
1090
+ //compute the integral part of the square root of n
1091
+ bigint m=intRoot(n);
1092
+
1093
+ //consider the function f(X)=(X+m)^2-n and compute for s in [-c,c] the values
1094
+ while(i<=2*c)
1095
+ {
1096
+ f=(i-c+m)^2-n;
1097
+ tmp[1]=i-c+m;
1098
+ tmp[2]=f;
1099
+ tmp[3]=v;
1100
+ S[i+1]=tmp;
1101
+ i++;
1102
+ }
1103
+
1104
+ //the sieve with p in B
1105
+ //find all s in [-c,c] such that f(s) has all prime divisors in the first
1106
+ //k elements of B and the decomposition of f(s). They are characterized
1107
+ //by 1 or -1 at the second place of S[j]:
1108
+ //S[j]=j-c+m,f(j-c)/p_1^v_1*...*p_k^v_k, v_1,...,v_k maximal
1109
+ for(i=1;i<=k;i++)
1110
+ {
1111
+ p=B[i];
1112
+ if((p>2)&&(Jacobi(n,p)==-1)){i++;continue;}//n is no quadratic rest mod p
1113
+ j=1;
1114
+ while(j<=p)
1115
+ {
1116
+ if(j>2*c+1) break;
1117
+ f=S[j][2];
1118
+ v=S[j][3];
1119
+ s=0;
1120
+ while((f mod p)==0)
1121
+ {
1122
+ s++;
1123
+ f=f div p;
1124
+ }
1125
+ if(s)
1126
+ {
1127
+ S[j][2]=f;
1128
+ v[i]=s;
1129
+ S[j][3]=v;
1130
+ l=j;
1131
+ while(l+p<=2*c+1)
1132
+ {
1133
+ l=l+p;
1134
+ f=S[l][2];
1135
+ v=S[l][3];
1136
+ s=0;
1137
+ while((f mod p)==0)
1138
+ {
1139
+ s++;
1140
+ f=f div p;
1141
+ }
1142
+ S[l][2]=f;
1143
+ v[i]=s;
1144
+ S[l][3]=v;
1145
+ }
1146
+ }
1147
+ j++;
1148
+ }
1149
+ }
1150
+ list T;
1151
+ for(j=1;j<=2*c+1;j++)
1152
+ {
1153
+ if((S[j][2]==1)||(S[j][2]==-1))
1154
+ {
1155
+ T[size(T)+1]=S[j];
1156
+ }
1157
+ }
1158
+
1159
+ //the system of equations for the exponents {l_s} for the f(s) such
1160
+ //product f(s)^l_s is a square (l_s are 1 or 0)
1161
+ bigintmat M[k+1][size(T)];
1162
+ for(j=1;j<=size(T);j++)
1163
+ {
1164
+ if(T[j][2]==-1){M[1,j]=1;}
1165
+ for(i=1;i<=k;i++)
1166
+ {
1167
+ M[i+1,j]=T[j][3][i];
1168
+ }
1169
+ }
1170
+ intmat G=solutionsMod2(M);
1171
+
1172
+ //construction of x and y such that x^2=y^2 mod n and d=gcd(x-y,n)
1173
+ //y=square root of product f(s)^l_s
1174
+ //x=product s+m
1175
+ bigint x=1;
1176
+ bigint y=1;
1177
+
1178
+ for(i=1;i<=ncols(G);i++)
1179
+ {
1180
+ kill v;
1181
+ intvec v;
1182
+ v[k]=0;
1183
+ for(j=1;j<=size(T);j++)
1184
+ {
1185
+ x=x*T[j][1]^G[j,i] mod n;
1186
+ if((T[j][2]==-1)&&(G[j,i]==1)){y=-y;}
1187
+ v=v+G[j,i]*T[j][3];
1188
+
1189
+ }
1190
+ for(l=1;l<=k;l++)
1191
+ {
1192
+ y=y*B[l]^(v[l] div 2) mod n;
1193
+ }
1194
+ d=gcd(x-y,n);
1195
+ if((d>1)&&(d<n)){return(d);}
1196
+ }
1197
+ return("no divisor found");
1198
+ }
1199
+ example
1200
+ { "EXAMPLE:"; echo = 2;
1201
+ list L=primList(5000);
1202
+ quadraticSieve(7429,3,L,4);
1203
+ quadraticSieve(1241143,100,L,50);
1204
+ }
1205
+
1206
+ //======================================================================
1207
+ //==================== elliptic curves ================================
1208
+ //======================================================================
1209
+
1210
+ //================= elementary operations ==============================
1211
+
1212
+ proc isOnCurve(bigint N, bigint a, bigint b, list P)
1213
+ "USAGE: isOnCurve(N,a,b,P);
1214
+ RETURN: 1 or 0 (depending on whether P is on the curve or not)
1215
+ NOTE: checks whether P=(P[1]:P[2]:P[3]) is a point on the elliptic
1216
+ curve defined by y^2z=x^3+a*xz^2+b*z^3 over Z/N
1217
+ EXAMPLE:example isOnCurve; shows an example
1218
+ "
1219
+ {
1220
+ if(((P[2]^2*P[3]-P[1]^3-a*P[1]*P[3]^2-b*P[3]^3) mod N)!=0){return(0);}
1221
+ return(1);
1222
+ }
1223
+ example
1224
+ { "EXAMPLE:"; echo = 2;
1225
+ isOnCurve(32003,5,7,list(10,16,1));
1226
+ }
1227
+
1228
+ proc ellipticAdd(bigint N, bigint a, bigint b, list P, list Q)
1229
+ "USAGE: ellipticAdd(N,a,b,P,Q);
1230
+ RETURN: list L, representing the point P+Q
1231
+ NOTE: P=(P[1]:P[2]:P[3]), Q=(Q[1]:Q[2]:Q[3]) points on the elliptic curve
1232
+ defined by y^2z=x^3+a*xz^2+b*z^3 over Z/N
1233
+ EXAMPLE:example ellipticAdd; shows an example
1234
+ "
1235
+ {
1236
+ if(N==2){ERROR("not implemented for 2");}
1237
+ int i;
1238
+ for(i=1;i<=3;i++)
1239
+ {
1240
+ P[i]=P[i] mod N; if (P[i]<0) { P[i]=P[i]+N:}
1241
+ Q[i]=Q[i] mod N; if (Q[i]<0) { Q[i]=Q[i]+N;}
1242
+ }
1243
+ list Resu;
1244
+ Resu[1]=bigint(0);
1245
+ Resu[2]=bigint(1);
1246
+ Resu[3]=bigint(0);
1247
+ list Error;
1248
+ Error[1]=0;
1249
+ //test for ellictic curve
1250
+ bigint D=4*a^3+27*b^2;
1251
+ bigint g=gcd(D,N);
1252
+ if(g==N){return(Error);}
1253
+ if(g!=1)
1254
+ {
1255
+ P[4]=g;
1256
+ return(P);
1257
+ }
1258
+ if(((P[1]==0)&&(P[2]==0)&&(P[3]==0))||((Q[1]==0)&&(Q[2]==0)&&(Q[3]==0)))
1259
+ {
1260
+ Error[1]=-2;
1261
+ return(Error);
1262
+ }
1263
+ if(!isOnCurve(N,a,b,P)||!isOnCurve(N,a,b,Q))
1264
+ {
1265
+ Error[1]=-1;
1266
+ return(Error);
1267
+ }
1268
+ if(P[3]==0){return(Q);}
1269
+ if(Q[3]==0){return(P);}
1270
+ list I=extgcd(P[3],N);
1271
+ if(I[1]!=1)
1272
+ {
1273
+ P[4]=I[1];
1274
+ return(P);
1275
+ }
1276
+ P[1]=P[1]*I[2] mod N;
1277
+ P[2]=P[2]*I[2] mod N;
1278
+ I=extgcd(Q[3],N);
1279
+ if(I[1]!=1)
1280
+ {
1281
+ P[4]=I[1];
1282
+ return(P);
1283
+ }
1284
+ Q[1]=Q[1]*I[2] mod N;
1285
+ Q[2]=Q[2]*I[2] mod N;
1286
+ if((P[1]==Q[1])&&(((P[2]+Q[2]) mod N)==0)){return(Resu);}
1287
+ bigint L;
1288
+ if((P[1]==Q[1])&&(P[2]==Q[2]))
1289
+ {
1290
+ I=extgcd(2*Q[2],N);
1291
+ if(I[1]!=1)
1292
+ {
1293
+ P[4]=I[1];
1294
+ return(P);
1295
+ }
1296
+ L=I[2]*(3*Q[1]^2+a) mod N;
1297
+ }
1298
+ else
1299
+ {
1300
+ I=extgcd(Q[1]-P[1],N);
1301
+ if(I[1]!=1)
1302
+ {
1303
+ P[4]=I[1];
1304
+ return(P);
1305
+ }
1306
+ L=(Q[2]-P[2])*I[2] mod N;
1307
+ }
1308
+ Resu[1]=(L^2-P[1]-Q[1]) mod N;
1309
+ if (Resu[1]<0) { Resu[1]=Resu[1]+N; }
1310
+ Resu[2]=(L*(P[1]-Resu[1])-P[2]) mod N;
1311
+ if (Resu[2]<0) { Resu[2]=Resu[2]+N; }
1312
+ Resu[3]=bigint(1);
1313
+ return(Resu);
1314
+ }
1315
+ example
1316
+ { "EXAMPLE:"; echo = 2;
1317
+ bigint N=11;
1318
+ bigint a=1;
1319
+ bigint b=6;
1320
+ list P,Q;
1321
+ P[1]=2;
1322
+ P[2]=4;
1323
+ P[3]=1;
1324
+ Q[1]=3;
1325
+ Q[2]=5;
1326
+ Q[3]=1;
1327
+ ellipticAdd(N,a,b,P,Q);
1328
+ }
1329
+
1330
+ proc ellipticMult(bigint N, bigint a, bigint b, list P, bigint k)
1331
+ "USAGE: ellipticMult(N,a,b,P,k);
1332
+ RETURN: a list L representing the point k*P
1333
+ NOTE: P=(P[1]:P[2]:P[3]) a point on the elliptic curve defined by
1334
+ y^2z=x^3+a*xz^2+b*z^3 over Z/N
1335
+ EXAMPLE:example ellipticMult; shows an example
1336
+ "
1337
+ {
1338
+ if(P[3]==0){return(P);}
1339
+ list resu;
1340
+ resu[1]=bigint(0);
1341
+ resu[2]=bigint(1);
1342
+ resu[3]=bigint(0);
1343
+
1344
+ if(k==0){return(resu);}
1345
+ if(k==1){return(P);}
1346
+ if(k==2){return(ellipticAdd(N,a,b,P,P));}
1347
+ if(k==-1)
1348
+ {
1349
+ resu=P;
1350
+ resu[2]=N-P[2];
1351
+ return(resu);
1352
+ }
1353
+ if(k<0)
1354
+ {
1355
+ resu=ellipticMult(N,a,b,P,-k);
1356
+ return(ellipticMult(N,a,b,resu,-1));
1357
+ }
1358
+ if((k mod 2)==0)
1359
+ {
1360
+ resu=ellipticMult(N,a,b,P,k div 2);
1361
+ return(ellipticAdd(N,a,b,resu,resu));
1362
+ }
1363
+ resu=ellipticMult(N,a,b,P,k-1);
1364
+ return(ellipticAdd(N,a,b,resu,P));
1365
+ }
1366
+ example
1367
+ { "EXAMPLE:"; echo = 2;
1368
+ bigint N=11;
1369
+ bigint a=1;
1370
+ bigint b=6;
1371
+ list P;
1372
+ P[1]=2;
1373
+ P[2]=4;
1374
+ P[3]=1;
1375
+ ellipticMult(N,a,b,P,3);
1376
+ }
1377
+
1378
+ //================== Random for elliptic curves =====================
1379
+
1380
+ proc ellipticRandomCurve(bigint N)
1381
+ "USAGE: ellipticRandomCurve(N);
1382
+ RETURN: a list of two random numbers a,b and 4a^3+27b^2 mod N
1383
+ NOTE: y^2z=x^3+a*xz^2+b^2*z^3 defines an elliptic curve over Z/N
1384
+ EXAMPLE:example ellipticRandomCurve; shows an example
1385
+ "
1386
+ {
1387
+ int k;
1388
+ while(k<=10)
1389
+ {
1390
+ k++;
1391
+ bigint a=random(1,2147483647) mod N;
1392
+ bigint b=random(1,2147483647) mod N;
1393
+ //test for ellictic curve
1394
+ bigint D=4*a^3+27*b^4; //the constant term is b^2
1395
+ bigint g=gcd(D,N);
1396
+ if(g<N){return(list(a,b,g));}
1397
+ }
1398
+ ERROR("no random curve found");
1399
+ }
1400
+ example
1401
+ { "EXAMPLE:"; echo = 2;
1402
+ ellipticRandomCurve(32003);
1403
+ }
1404
+
1405
+ proc ellipticRandomPoint(bigint N, bigint a, bigint b)
1406
+ "USAGE: ellipticRandomPoint(N,a,b);
1407
+ RETURN: a list representing a random point (x:y:z) of the elliptic curve
1408
+ defined by y^2z=x^3+a*xz^2+b*z^3 over Z/N
1409
+ EXAMPLE:example ellipticRandomPoint; shows an example
1410
+ "
1411
+ {
1412
+ bigint x=random(1,2147483647) mod N;
1413
+ bigint h=x^3+a*x+b;
1414
+ h=h mod N;
1415
+ list resu;
1416
+ resu[1]=x;
1417
+ resu[2]=0;
1418
+ resu[3]=1;
1419
+ if(h==0){return(resu);}
1420
+
1421
+ bigint n=Jacobi(h,N);
1422
+ if(n==0)
1423
+ {
1424
+ resu=-5;
1425
+ "N is not prime";
1426
+ return(resu);
1427
+ }
1428
+ if(n==1)
1429
+ {
1430
+ resu[2]=squareRoot(h,N);
1431
+ return(resu);
1432
+ }
1433
+ return(ellipticRandomPoint(N,a,b));
1434
+ }
1435
+ example
1436
+ { "EXAMPLE:"; echo = 2;
1437
+ ellipticRandomPoint(32003,3,181);
1438
+ }
1439
+
1440
+
1441
+
1442
+ //====================================================================
1443
+ //======== counting the points of an elliptic curve =================
1444
+ //====================================================================
1445
+
1446
+ //================== the trivial approaches =======================
1447
+ proc countPoints(bigint N, bigint a, bigint b)
1448
+ "USAGE: countPoints(N,a,b);
1449
+ RETURN: the number of points of the elliptic curve defined by
1450
+ y^2=x^3+a*x+b over Z/N
1451
+ NOTE: trivial approach
1452
+ EXAMPLE:example countPoints; shows an example
1453
+ "
1454
+ {
1455
+ bigint x;
1456
+ bigint r=N+1;
1457
+ while(x<N)
1458
+ {
1459
+ r=r+Jacobi((x^3+a*x+b) mod N,N);
1460
+ x=x+1;
1461
+ }
1462
+ return(r);
1463
+ }
1464
+ example
1465
+ { "EXAMPLE:"; echo = 2;
1466
+ countPoints(181,71,150);
1467
+ }
1468
+
1469
+ proc ellipticAllPoints(bigint N, bigint a, bigint b)
1470
+ "USAGE: ellipticAllPoints(N,a,b);
1471
+ RETURN: list of points (x:y:z) of the elliptic curve defined by
1472
+ y^2z=x^3+a*xz^2+b*z^3 over Z/N
1473
+ EXAMPLE:example ellipticAllPoints; shows an example
1474
+ "
1475
+ {
1476
+ list resu,point;
1477
+ point[1]=0;
1478
+ point[2]=1;
1479
+ point[3]=0;
1480
+ resu[1]=point;
1481
+ point[3]=1;
1482
+ bigint x,h,n;
1483
+ while(x<N)
1484
+ {
1485
+ h=(x^3+a*x+b) mod N;
1486
+ if(h==0)
1487
+ {
1488
+ point[1]=x;
1489
+ point[2]=0;
1490
+ resu[size(resu)+1]=point;
1491
+ }
1492
+ else
1493
+ {
1494
+ n=Jacobi(h,N);
1495
+ if(n==1)
1496
+ {
1497
+ n=squareRoot(h,N);
1498
+ point[1]=x;
1499
+ point[2]=n;
1500
+ resu[size(resu)+1]=point;
1501
+ point[2]=N-n;
1502
+ resu[size(resu)+1]=point;
1503
+ }
1504
+ }
1505
+ x=x+1;
1506
+ }
1507
+ return(resu);
1508
+ }
1509
+ example
1510
+ { "EXAMPLE:"; echo = 2;
1511
+ list L=ellipticAllPoints(181,71,150);
1512
+ size(L);
1513
+ L[size(L)];
1514
+ }
1515
+
1516
+ //================ the algorithm of Shanks and Mestre =================
1517
+
1518
+ proc ShanksMestre(bigint q, bigint a, bigint b, list #)
1519
+ "USAGE: ShanksMestre(q,a,b); optional: ShanksMestre(q,a,b,s); s the number
1520
+ of loops in the algorithm (default s=1)
1521
+ RETURN: the number of points of the elliptic curve defined by
1522
+ y^2=x^3+a*x+b over Z/N
1523
+ NOTE: algorithm of Shanks and Mestre (baby-step-giant-step)
1524
+ EXAMPLE:example ShanksMestre; shows an example
1525
+ "
1526
+ {
1527
+ bigint n=intRoot(4*q);
1528
+ bigint m=intRoot(intRoot(16*q))+1;
1529
+ bigint d;
1530
+ int i,j,k,s;
1531
+ list B,K,T,P,Q,R,mP;
1532
+ B[1]=list(0,1,0);
1533
+ if(size(#)>0)
1534
+ {
1535
+ s=#[1];
1536
+ }
1537
+ else
1538
+ {
1539
+ s=1;
1540
+ }
1541
+ while(k<s)
1542
+ {
1543
+ P =ellipticRandomPoint(q,a,b);
1544
+ Q =ellipticMult(q,a,b,P,n+q+1);
1545
+
1546
+ while(j<m)
1547
+ {
1548
+ j++;
1549
+ B[j+1]=ellipticAdd(q,a,b,P,B[j]); //baby-step list
1550
+ }
1551
+ mP=ellipticAdd(q,a,b,P,B[j]);
1552
+ mP[2]=q-mP[2];
1553
+ while(i<m) //giant-step
1554
+ {
1555
+ j=0;
1556
+ while(j<m)
1557
+ {
1558
+ j++;
1559
+ if((Q[1]==B[j][1])&&(Q[2]==B[j][2])&&(Q[3]==B[j][3]))
1560
+ {
1561
+ T[1]=P;
1562
+ T[2]=q+1+n-(i*m+j-1);
1563
+ K[size(K)+1]=T;
1564
+ if(size(K)>1)
1565
+ {
1566
+ if(K[size(K)][2]!=K[size(K)-1][2])
1567
+ {
1568
+ d=gcd(K[size(K)][2],K[size(K)-1][2]);
1569
+ if(ellipticMult(q,a,b,K[size(K)],d)[3]==0)
1570
+ {
1571
+ K[size(K)][2]=K[size(K)-1][2];
1572
+ }
1573
+ }
1574
+ }
1575
+ i=int(m);
1576
+ break;
1577
+ }
1578
+ }
1579
+ i=i+1;
1580
+ Q=ellipticAdd(q,a,b,mP,Q);
1581
+ }
1582
+ k++;
1583
+ }
1584
+ if(size(K)>0)
1585
+ {
1586
+ int te=1;
1587
+ for(i=1;i<=size(K)-1;i++)
1588
+ {
1589
+ if(K[size(K)][2]!=K[i][2])
1590
+ {
1591
+ if(ellipticMult(q,a,b,K[i],K[size(K)][2])[3]!=0)
1592
+ {
1593
+ te=0;
1594
+ break;
1595
+ }
1596
+ }
1597
+ }
1598
+ if(te)
1599
+ {
1600
+ return(K[size(K)][2]);
1601
+ }
1602
+ }
1603
+ return(ShanksMestre(q,a,b,s));
1604
+ }
1605
+ example
1606
+ { "EXAMPLE:"; echo = 2;
1607
+ ShanksMestre(32003,71,602);
1608
+ }
1609
+
1610
+ //==================== Schoof's algorithm =============================
1611
+
1612
+ proc Schoof(bigint N,bigint a, bigint b)
1613
+ "USAGE: Schoof(N,a,b);
1614
+ RETURN: the number of points of the elliptic curve defined by
1615
+ y^2=x^3+a*x+b over Z/N
1616
+ NOTE: algorithm of Schoof
1617
+ EXAMPLE:example Schoof; shows an example
1618
+ "
1619
+ {
1620
+ int pr=printlevel;
1621
+ //test for ellictic curve
1622
+ bigint D=4*a^3+27*b^2;
1623
+ bigint G=gcd(D,N);
1624
+ if(G==N){ERROR("not an elliptic curve");}
1625
+ if(G!=1){ERROR("not a prime");}
1626
+ //=== small N
1627
+ if((N<=500)&&(pr<5)){return(countPoints(int(N),a,b));}
1628
+ //=== the general case
1629
+ bigint q=intRoot(4*N);
1630
+ list L=primL(2*q);
1631
+ list L1=primList(100);
1632
+ int r=size(L);
1633
+ L1=L1[r+1..size(L1)];
1634
+ list T;
1635
+ int i,j;
1636
+ for(j=1;j<=size(L1);j++)
1637
+ {
1638
+ if(N mod L1[j]==2){L1=delete(L1,j);}
1639
+ }
1640
+ i=1;
1641
+ for(j=1;j<=r;j++)
1642
+ {
1643
+ T[j]=(testElliptic(int(N),a,b,L[j])+int(q)) mod L[j];
1644
+ }
1645
+ if(pr>=5)
1646
+ {
1647
+ "===================================================================";
1648
+ "Chinese remainder :";
1649
+ for(i=1;i<=size(T);i++)
1650
+ {
1651
+ " x =",T[i]," mod ",L[i];
1652
+ }
1653
+ "gives t+ integral part of the square root of q (to be positive)";
1654
+ chineseRem(T,L);
1655
+ "we obtain t = ",chineseRem(T,L)-q;
1656
+ "===================================================================";
1657
+ }
1658
+ bigint t=chineseRem(T,L)-q;
1659
+ return(N+1-t);
1660
+ }
1661
+ example
1662
+ { "EXAMPLE:"; echo = 2;
1663
+ Schoof(32003,71,602);
1664
+ }
1665
+
1666
+ /*
1667
+ Schoof(2147483629,17,3567);
1668
+ 2147339065 //Aenderung
1669
+ */
1670
+
1671
+
1672
+ proc generateG(number a,number b, int m)
1673
+ "USAGE: generateG(a,b,m);
1674
+ RETURN: m-th division polynomial
1675
+ NOTE: generate the so-called division polynomials, i.e., the recursively defined
1676
+ polynomials p_m=generateG(a,b,m) in Z[x, y] such that, for a point (x:y:1) on the
1677
+ elliptic curve defined by y^2=x^3+a*x+b over Z/N the point@*
1678
+ m*P=(x-(p_(m-1)*p_(m+1))/p_m^2 :(p_(m+2)*p_(m-1)^2-p_(m-2)*p_(m+1)^2)/4y*p_m^3 :1)
1679
+ and m*P=0 if and only if p_m(P)=0
1680
+ EXAMPLE:example generateG; shows an example
1681
+ "
1682
+ {
1683
+ if(m==0){return(poly(0));}
1684
+ if(m==1){return(poly(1));}
1685
+ if(m==2){return(2*var(1));}
1686
+ if(m==3){return(3*var(2)^4+6*a*var(2)^2+12*b*var(2)-a^2);}
1687
+ if(m==4)
1688
+ {
1689
+ return(4*var(1)*(var(2)^6+5*a*var(2)^4+20*b*var(2)^3-5*a^2*var(2)^2
1690
+ -4*a*b*var(2)-8*b^2-a^3));
1691
+ }
1692
+ if((m mod 2)==0)
1693
+ {
1694
+ return((generateG(a,b,m div 2+2)*generateG(a,b,m div 2-1)^2
1695
+ -generateG(a,b,m div 2-2)*generateG(a,b,m div 2+1)^2)
1696
+ *generateG(a,b,m div 2)/(2*var(1)));
1697
+ }
1698
+ return(generateG(a,b,(m-1) div 2+2)*generateG(a,b,(m-1) div 2)^3
1699
+ -generateG(a,b,(m-1) div 2-1)*generateG(a,b,(m-1) div 2+1)^3);
1700
+ }
1701
+ example
1702
+ { "EXAMPLE:"; echo = 2;
1703
+ ring R = 0,(x,y),dp;
1704
+ generateG(7,15,4);
1705
+ }
1706
+
1707
+
1708
+ static proc testElliptic(int q,bigint aa,bigint bb,int l)
1709
+ "USAGE: testElliptic(q,a,b,l);
1710
+ RETURN: an integer t, the trace of the Frobenius
1711
+ NOTE: the kernel for the Schoof algorithm: looks for the t such that for all
1712
+ points (x:y:1) in C[l]={P in C | l*P=0},C the elliptic curve defined by
1713
+ y^2=x^3+a*x+b over Z/q with group structure induced by 0=(0:1:0),
1714
+ (x:y:1)^(q^2)-t*(x:y:1)^q -ql*(x:y:1)=(0:1:0), ql= q mod l, trace of
1715
+ Frobenius.
1716
+ EXAMPLE:example testElliptic; shows an example
1717
+ "
1718
+ {
1719
+ int pr=printlevel;
1720
+ ring S=q,(y,x),(L(100000),lp);
1721
+ number a=aa;
1722
+ number b=bb;
1723
+ poly F=y2-x3-a*x-b; // the curve C
1724
+ poly G=generateG(a,b,l);
1725
+ ideal I=std(ideal(F,G)); // the points C[l]
1726
+ poly xq=powerX(q,2,I);
1727
+ poly yq=powerX(q,1,I);
1728
+ poly xq2=reduce(subst(xq,x,xq,y,yq),I);
1729
+ poly yq2=reduce(subst(yq,x,xq,y,yq),I);
1730
+ ideal J;
1731
+ int ql=q mod l;
1732
+ if(ql==0){ERROR("q is not prime");}
1733
+ int t;
1734
+ poly F1,F2,G1,G2,P1,P2,Q1,Q2,H1,H2,L1,L2;
1735
+
1736
+ if(pr>=5)
1737
+ {
1738
+ "===================================================================";
1739
+ "q=",q;
1740
+ "l=",l;
1741
+ "q mod l=",ql;
1742
+ "the Groebner basis for C[l]:";I;
1743
+ "x^q mod I = ",xq;
1744
+ "x^(q^2) mod I = ",xq2;
1745
+ "y^q mod I = ",yq;
1746
+ "y^(q^2) mod I = ",yq2;
1747
+ pause();
1748
+ }
1749
+ //==== l=2 =============================================================
1750
+ if(l==2)
1751
+ {
1752
+ xq=powerX(q,2,std(x3+a*x+b));
1753
+ J=std(ideal(xq-x,x3+a*x+b));
1754
+ if(deg(J[1])==0){t=1;}
1755
+ if(pr>=5)
1756
+ {
1757
+ "===================================================================";
1758
+ "the case l=2";
1759
+ "the gcd(x^q-x,x^3+ax+b)=",J[1];
1760
+ pause();
1761
+ }
1762
+ return(t);
1763
+ }
1764
+ //=== (F1/G1,F2/G2)=[ql](x,y) ==========================================
1765
+ if(ql==1)
1766
+ {
1767
+ F1=x;G1=1;F2=y;G2=1;
1768
+ }
1769
+ else
1770
+ {
1771
+ G1=reduce(generateG(a,b,ql)^2,I);
1772
+ F1=reduce(x*G1-generateG(a,b,ql-1)*generateG(a,b,ql+1),I);
1773
+ G2=reduce(4*y*generateG(a,b,ql)^3,I);
1774
+ F2=reduce(generateG(a,b,ql+2)*generateG(a,b,ql-1)^2
1775
+ -generateG(a,b,ql-2)*generateG(a,b,ql+1)^2,I);
1776
+
1777
+ }
1778
+ if(pr>=5)
1779
+ {
1780
+ "===================================================================";
1781
+ "the point ql*(x,y)=(F1/G1,F2/G2)";
1782
+ "F1=",F1;
1783
+ "G1=",G1;
1784
+ "F2=",F2;
1785
+ "G2=",G2;
1786
+ pause();
1787
+ }
1788
+ //==== the case t=0 : the equations for (x,y)^(q^2)=-[ql](x,y) ===
1789
+ J[1]=xq2*G1-F1;
1790
+ J[2]=yq2*G2+F2;
1791
+ if(pr>=5)
1792
+ {
1793
+ "===================================================================";
1794
+ "the case t=0 mod l";
1795
+ "the equations for (x,y)^(q^2)=-[ql](x,y) :";
1796
+ J;
1797
+ "the test, if they vanish for all points in C[l]:";
1798
+ reduce(J,I);
1799
+ pause();
1800
+ }
1801
+ //=== test if all points of C[l] satisfy (x,y)^(q^2)=-[ql](x,y)
1802
+ //=== if so: t mod l =0 is returned
1803
+ if(size(reduce(J,I,5))==0){return(0);}
1804
+
1805
+ //==== test for (x,y)^(q^2)=[ql](x,y) for some point
1806
+
1807
+ J=xq2*G1-F1,yq2*G2-F2;
1808
+ J=std(J+I);
1809
+ if(pr>=5)
1810
+ {
1811
+ "===================================================================";
1812
+ "test if (x,y)^(q^2)=[ql](x,y) for one point";
1813
+ "if so, the Frobenius has an eigenvalue 2ql/t: (x,y)^q=(2ql/t)*(x,y)";
1814
+ "it follows that t^2=4q mod l";
1815
+ "if w is one square root of q mod l";
1816
+ "t =2w mod l or -2w mod l ";
1817
+ "-------------------------------------------------------------------";
1818
+ "the equations for (x,y)^(q^2)=[ql](x,y) :";
1819
+ xq2*G1-F1,yq2*G2-F2;
1820
+ "the test if one point satisfies them";
1821
+ J;
1822
+ pause();
1823
+ }
1824
+ if(deg(J[1])>0)
1825
+ {
1826
+ int w=int(squareRoot(q,l));
1827
+ //=== +/-2w mod l zurueckgeben, wenn (x,y)^q=+/-[w](x,y)
1828
+ //==== the case t>0 : (Q1/P1,Q2/P2)=[w](x,y) ==============
1829
+ if(w==1)
1830
+ {
1831
+ Q1=x;P1=1;Q2=y;P2=1;
1832
+ }
1833
+ else
1834
+ {
1835
+ P1=reduce(generateG(a,b,w)^2,I);
1836
+ Q1=reduce(x*G1-generateG(a,b,w-1)*generateG(a,b,w+1),I);
1837
+ P2=reduce(4*y*generateG(a,b,w)^3,I);
1838
+ Q2=reduce(generateG(a,b,w+2)*generateG(a,b,w-1)^2
1839
+ -generateG(a,b,w-2)*generateG(a,b,w+1)^2,I);
1840
+ }
1841
+ J=xq*P1-Q1,yq*P2+Q2; //Aenderung
1842
+ J=std(I+J);
1843
+ if(pr>=5)
1844
+ {
1845
+ "===================================================================";
1846
+ "the Frobenius has an eigenvalue, one of the roots of w^2=q mod l:";
1847
+ "one root is:";w;
1848
+ "test, if it is the eigenvalue (if not it must be -w):";
1849
+ "the equations for (x,y)^q=w*(x,y)";I;xq*P1-Q1,yq*P2-Q2;
1850
+ "the Groebner basis";
1851
+ J;
1852
+ pause();
1853
+ }
1854
+ if(deg(J[1])>0){return(2*w mod l);}
1855
+ return(-2*w mod l);
1856
+ }
1857
+
1858
+ //==== the case t>0 : (Q1/P1,Q2/P2)=(x,y)^(q^2)+[ql](x,y) =====
1859
+ P1=reduce(G1*G2^2*(F1-xq2*G1)^2,I);
1860
+ Q1=reduce((F2-yq2*G2)^2*G1^3-F1*G2^2*(F1-xq2*G1)^2-xq2*P1,I);
1861
+ P2=reduce(P1*G2*(F1-xq2*G1),I);
1862
+ Q2=reduce((xq2*P1-Q1)*(F2-yq2*G2)*G1-yq2*P2,I);
1863
+
1864
+ if(pr>=5)
1865
+ {
1866
+ "we are in the general case:";
1867
+ "(x,y)^(q^2)!=ql*(x,y) and (x,y)^(q^2)!=-ql*(x,y) ";
1868
+ "the point (Q1/P1,Q2/P2)=(x,y)^(q^2)+[ql](x,y)";
1869
+ "Q1=",Q1;
1870
+ "P1=",P1;
1871
+ "Q2=",Q2;
1872
+ "P2=",P2;
1873
+ pause();
1874
+ }
1875
+ while(t<(l-1) div 2)
1876
+ {
1877
+ t++;
1878
+ //==== (H1/L1,H2/L2)=[t](x,y)^q ===============================
1879
+ if(t==1)
1880
+ {
1881
+ H1=xq;L1=1;
1882
+ H2=yq;L2=1;
1883
+ }
1884
+ else
1885
+ {
1886
+ H1=x*generateG(a,b,t)^2-generateG(a,b,t-1)*generateG(a,b,t+1);
1887
+ H1=subst(H1,x,xq,y,yq);
1888
+ H1=reduce(H1,I);
1889
+ L1=generateG(a,b,t)^2;
1890
+ L1=subst(L1,x,xq,y,yq);
1891
+ L1=reduce(L1,I);
1892
+ H2=generateG(a,b,t+2)*generateG(a,b,t-1)^2
1893
+ -generateG(a,b,t-2)*generateG(a,b,t+1)^2;
1894
+ H2=subst(H2,x,xq,y,yq);
1895
+ H2=reduce(H2,I);
1896
+ L2=4*y*generateG(a,b,t)^3;
1897
+ L2=subst(L2,x,xq,y,yq);
1898
+ L2=reduce(L2,I);
1899
+ }
1900
+ J=Q1*L1-P1*H1,Q2*L2-P2*H2;
1901
+ if(pr>=5)
1902
+ {
1903
+ "we test now the different t, 0<t<=(l-1)/2:";
1904
+ "the point (H1/L1,H2/L2)=[t](x,y)^q :";
1905
+ "H1=",H1;
1906
+ "L1=",L1;
1907
+ "H2=",H2;
1908
+ "L2=",L2;
1909
+ "the equations for (x,y)^(q^2)+[ql](x,y)=[t](x,y)^q :";J;
1910
+ "the test";reduce(J,I);
1911
+ "the test for l-t (the x-cordinate is the same):";
1912
+ Q1*L1-P1*H1,Q2*L2+P2*H2;
1913
+ reduce(ideal(Q1*L1-P1*H1,Q2*L2+P2*H2),I);
1914
+ pause();
1915
+ }
1916
+ if(size(reduce(J,I,5))==0){return(t);}
1917
+ J=Q1*L1-P1*H1,Q2*L2+P2*H2;
1918
+ if(size(reduce(J,I,5))==0){return(l-t);}
1919
+ }
1920
+ ERROR("something is wrong in testElliptic");
1921
+ }
1922
+ example
1923
+ { "EXAMPLE:"; echo = 2;
1924
+ testElliptic(1267985441,338474977,64740730,3);
1925
+ }
1926
+
1927
+ //============================================================================
1928
+ //================== Factorization and Primality Test ========================
1929
+ //============================================================================
1930
+
1931
+ //============= Lenstra's ECM Factorization ==================================
1932
+
1933
+ proc factorLenstraECM(bigint N, list S, int B, list #)
1934
+ "USAGE: factorLenstraECM(N,S,B); optional: factorLenstraECM(N,S,B,d);
1935
+ d+1 the number of loops in the algorithm (default d=0)
1936
+ RETURN: a factor of N or the message no factor found
1937
+ NOTE: - computes a factor of N using Lenstra's ECM factorization@*
1938
+ - the idea is that the fact that N is not prime is detected using
1939
+ the operations on the elliptic curve
1940
+ - is similarly to Pollard's p-1-factorization
1941
+ EXAMPLE:example factorLenstraECM; shows an example
1942
+ "
1943
+ {
1944
+ list L,P;
1945
+ bigint g,M,w;
1946
+ int i,j,k,d;
1947
+ int l=size(S);
1948
+ if(size(#)>0)
1949
+ {
1950
+ d=#[1];
1951
+ }
1952
+
1953
+ while(i<=d)
1954
+ {
1955
+ L=ellipticRandomCurve(N);
1956
+ if(L[3]>1){return(L[3]);} //the discriminant was not invertible
1957
+ P=list(0,L[2],1);
1958
+ j=0;
1959
+ M=1;
1960
+ while(j<l)
1961
+ {
1962
+ j++;
1963
+ w=S[j];
1964
+ if(w>B) break;
1965
+ while(w*S[j]<B)
1966
+ {
1967
+ w=w*S[j];
1968
+ }
1969
+ M=M*w;
1970
+ P=ellipticMult(N,L[1],L[2]^2,P,w);
1971
+ if(size(P)==4){return(P[4]);} //some inverse did not exist
1972
+ if(P[3]==0){break;} //the case M*P=0
1973
+ }
1974
+ i++;
1975
+ }
1976
+ return("no factor found");
1977
+ }
1978
+ example
1979
+ { "EXAMPLE:"; echo = 2;
1980
+ list L=primList(1000);
1981
+ factorLenstraECM(181*32003,L,10,5);
1982
+ bigint h=10;
1983
+ h=h^30+25;
1984
+ factorLenstraECM(h,L,4,3);
1985
+ }
1986
+
1987
+ //================= ECPP (Goldwasser-Kilian) a primaly-test =============
1988
+
1989
+ proc ECPP(bigint N)
1990
+ "USAGE: ECPP(N);
1991
+ RETURN: message:N is not prime or {L,P,m,q} as certificate for N being prime@*
1992
+ L a list (y^2=x^3+L[1]*x+L[2] defines an elliptic curve C)@*
1993
+ P a list ((P[1]:P[2]:P[3]) is a point of C)@*
1994
+ m,q integers
1995
+ ASSUME: gcd(N,6)=1
1996
+ NOTE: The basis of the algorithm is the following theorem:
1997
+ Given C, an elliptic curve over Z/N, P a point of C(Z/N),
1998
+ m an integer, q a prime with the following properties:
1999
+ - q|m
2000
+ - q>(4-th root(N) +1)^2
2001
+ - m*P=0=(0:1:0)
2002
+ - (m/q)*P=(x:y:z) and z a unit in Z/N
2003
+ Then N is prime.
2004
+ EXAMPLE:example ECPP; shows an example
2005
+ "
2006
+ {
2007
+ list L,S,P;
2008
+ bigint m,q;
2009
+ int i;
2010
+
2011
+ bigint n=intRoot(intRoot(N));
2012
+ n=(n+1)^2; //lower bound for q
2013
+ while(1)
2014
+ {
2015
+ L=ellipticRandomCurve(N); //a random elliptic curve C
2016
+ m=ShanksMestre(N,L[1],L[2],3); //number of points of the curve C
2017
+ S=PollardRho(m,10000,1); //factorization of m
2018
+ for(i=1;i<=size(S);i++) //search for q between the primes
2019
+ {
2020
+ q=S[i];
2021
+ if(n<q){break;}
2022
+ }
2023
+ if(n<q){break;}
2024
+ }
2025
+ bigint u=m/q;
2026
+ while(1)
2027
+ {
2028
+ P=ellipticRandomPoint(N,L[1],L[2]); //a random point on C
2029
+ "P=",P;
2030
+ if(ellipticMult(N,L[1],L[2],P,m)[3]!=0){"N is not prime";return(-5);}
2031
+ if(ellipticMult(N,L[1],L[2],P,u)[3]!=0)
2032
+ {
2033
+ L=delete(L,3);
2034
+ return(list(L,P,m,q));
2035
+ }
2036
+ }
2037
+ }
2038
+ example
2039
+ { "EXAMPLE:"; echo = 2;
2040
+ bigint N=1267985441;
2041
+ ECPP(N);
2042
+ }
2043
+
2044
+ static proc wordToNumber(string s)
2045
+ {
2046
+ int i;
2047
+ intvec v;
2048
+ bigint n;
2049
+ bigint t=27;
2050
+ for(i=size(s);i>0;i--)
2051
+ {
2052
+ if(s[i]=="a"){v[i]=0;}
2053
+ if(s[i]=="b"){v[i]=1;}
2054
+ if(s[i]=="c"){v[i]=2;}
2055
+ if(s[i]=="d"){v[i]=3;}
2056
+ if(s[i]=="e"){v[i]=4;}
2057
+ if(s[i]=="f"){v[i]=5;}
2058
+ if(s[i]=="g"){v[i]=6;}
2059
+ if(s[i]=="h"){v[i]=7;}
2060
+ if(s[i]=="i"){v[i]=8;}
2061
+ if(s[i]=="j"){v[i]=9;}
2062
+ if(s[i]=="k"){v[i]=10;}
2063
+ if(s[i]=="l"){v[i]=11;}
2064
+ if(s[i]=="m"){v[i]=12;}
2065
+ if(s[i]=="n"){v[i]=13;}
2066
+ if(s[i]=="o"){v[i]=14;}
2067
+ if(s[i]=="p"){v[i]=15;}
2068
+ if(s[i]=="q"){v[i]=16;}
2069
+ if(s[i]=="r"){v[i]=17;}
2070
+ if(s[i]=="s"){v[i]=18;}
2071
+ if(s[i]=="t"){v[i]=19;}
2072
+ if(s[i]=="u"){v[i]=20;}
2073
+ if(s[i]=="v"){v[i]=21;}
2074
+ if(s[i]=="w"){v[i]=22;}
2075
+ if(s[i]=="x"){v[i]=23;}
2076
+ if(s[i]=="y"){v[i]=24;}
2077
+ if(s[i]=="z"){v[i]=25;}
2078
+ if(s[i]==" "){v[i]=26;}
2079
+ }
2080
+ for(i=1;i<=size(s);i++)
2081
+ {
2082
+ n=n+v[i]*t^(i-1);
2083
+ }
2084
+ return(n);
2085
+ }
2086
+
2087
+ static proc numberToWord(bigint n)
2088
+ {
2089
+ int i,j;
2090
+ string v;
2091
+ list s;
2092
+ bigint t=27;
2093
+ bigint mm;
2094
+ bigint nn=n;
2095
+ while(nn>t)
2096
+ {
2097
+ j++;
2098
+ mm=nn mod t;
2099
+ s[j]=mm;
2100
+ nn=(nn-mm) div t;
2101
+ }
2102
+ j++;
2103
+ s[j]=nn;
2104
+ for(i=1;i<=j;i++)
2105
+ {
2106
+ if(s[i]==0){v=v+"a";}
2107
+ if(s[i]==1){v=v+"b";}
2108
+ if(s[i]==2){v=v+"c";}
2109
+ if(s[i]==3){v=v+"d";}
2110
+ if(s[i]==4){v=v+"e";}
2111
+ if(s[i]==5){v=v+"f";}
2112
+ if(s[i]==6){v=v+"g";}
2113
+ if(s[i]==7){v=v+"h";}
2114
+ if(s[i]==8){v=v+"i";}
2115
+ if(s[i]==9){v=v+"j";}
2116
+ if(s[i]==10){v=v+"k";}
2117
+ if(s[i]==11){v=v+"l";}
2118
+ if(s[i]==12){v=v+"m";}
2119
+ if(s[i]==13){v=v+"n";}
2120
+ if(s[i]==14){v=v+"o";}
2121
+ if(s[i]==15){v=v+"p";}
2122
+ if(s[i]==16){v=v+"q";}
2123
+ if(s[i]==17){v=v+"r";}
2124
+ if(s[i]==18){v=v+"s";}
2125
+ if(s[i]==19){v=v+"t";}
2126
+ if(s[i]==20){v=v+"u";}
2127
+ if(s[i]==21){v=v+"v";}
2128
+ if(s[i]==22){v=v+"w";}
2129
+ if(s[i]==23){v=v+"x";}
2130
+ if(s[i]==24){v=v+"y";}
2131
+ if(s[i]==25){v=v+"z";}
2132
+ if(s[i]==26){v=v+" ";}
2133
+ }
2134
+ return(v);
2135
+ }
2136
+
2137
+ proc code(string s)
2138
+ "USAGE: code(s); s a string
2139
+ ASSUME: s contains only small letters and space
2140
+ COMPUTE: a bigint, RSA-coding of the string s
2141
+ RETURN: return RSA-coding of the string s as string
2142
+ EXAMPLE: code; shows an example
2143
+ "
2144
+ {
2145
+ ring r=0,x,dp;
2146
+ bigint
2147
+ p=398075086424064937397125500550386491199064362342526708406385189575946388957261768583317;
2148
+ bigint
2149
+ q=472772146107435302536223071973048224632914695302097116459852171130520711256363590397527;
2150
+ bigint n=p*q;
2151
+ bigint phi=(p-1)*(q-1);
2152
+ bigint e=1234567891;
2153
+ //bigint d=extgcd(e,phi)[2];
2154
+ bigint m=wordToNumber(s);
2155
+ bigint c=powerN(m,e,n);
2156
+ string cc=string(c);
2157
+ return(cc);
2158
+ }
2159
+ example
2160
+ {"EXAMPLE:"; echo = 2;
2161
+ string s="i go to school";
2162
+ code(s);
2163
+ }
2164
+
2165
+ proc decodeString(string g)
2166
+ "USAGE: decodeString(s); s a string
2167
+ ASSUME: s is a string of a bigint, the output of code
2168
+ COMPUTE: a string, RSA-decoding of the string s
2169
+ RETURN: return RSA-decoding of the string s as string
2170
+ EXAMPLE: decodeString; shows an example
2171
+ "
2172
+ {
2173
+ bigint
2174
+ p=398075086424064937397125500550386491199064362342526708406385189575946388957261768583317;
2175
+ bigint
2176
+ q=472772146107435302536223071973048224632914695302097116459852171130520711256363590397527;
2177
+ bigint n=p*q;
2178
+ bigint phi=(p-1)*(q-1);
2179
+ bigint e=1234567891;
2180
+ bigint d=extgcd(e,phi)[2];
2181
+ execute("bigint c="+g+";");
2182
+ bigint f=powerN(c,d,n);
2183
+ string s=numberToWord(f);
2184
+ return(s);
2185
+ }
2186
+ example
2187
+ {"EXAMPLE:"; echo = 2;
2188
+ string
2189
+ s="78638618599886548153321853785991541374544958648147340831959482696082179852616053583234149080198937632782579537867262780982185252913122030800897193851413140758915381848932565";
2190
+ string t=decodeString(s);
2191
+ t;
2192
+ }
2193
+ /*----------------------------------------------------------------------------
2194
+ * set stuff
2195
+ * -------------------------------------------------------------------------*/
2196
+ static proc set_multiply_list_content(list h)
2197
+ "USAGE: set_multiply_list_content(h)
2198
+ RETURN: An integer c als product of all elements in h
2199
+ EXAMPLE: example set_multiply_list_content; shows an example;
2200
+ "
2201
+ {
2202
+ int c = 1;
2203
+ for (int i=1;i<=size(h);i++)
2204
+ {
2205
+ c = c*h[i];
2206
+ }
2207
+ return(c);
2208
+ }
2209
+ example
2210
+ {
2211
+ "EXAMPLE:"; echo = 2;
2212
+ list h=2,4,5;
2213
+ set_multiply_list_content(h);
2214
+ }
2215
+
2216
+ static proc set_delete_certain_element(list a, int e)
2217
+ "USAGE: set_delete_certain_element(a,e)
2218
+ RETURN: A list a without element e. If e was not in the list before, a will not be changed
2219
+ EXAMPLE: example set_delete_certain_element; shows an example.
2220
+ "
2221
+ {
2222
+ list output_list = a;
2223
+ for (int i=1;i<=size(a);i++)
2224
+ {
2225
+ if (a[i]==e)
2226
+ {
2227
+ output_list = delete(output_list,i);
2228
+ }
2229
+ }
2230
+ return(output_list);
2231
+ }
2232
+ example
2233
+ {
2234
+ "EXAMPLE:"; echo = 2;
2235
+ list h=2,4,5;
2236
+ set_delete_certain_element(h,4);
2237
+ set_delete_certain_element(h,10);
2238
+ }
2239
+
2240
+ static proc set_bubblesort_int(list output_list)
2241
+ "USAGE: set_bubblesort_int(output_list)
2242
+ RETURN: An ascending sorted list with integer values.
2243
+ EXAMPLE: set_bubblesort_int; shows an example.
2244
+ "
2245
+ {
2246
+ output_list = bubblesort(output_list);
2247
+ //Cast every value into an integer
2248
+ for (int i=1; i<=size(output_list);i++)
2249
+ {
2250
+ output_list[i] = int(output_list[i]);
2251
+ }
2252
+ return(output_list);
2253
+ }
2254
+ example
2255
+ {
2256
+ "EXAMPLE:"; echo = 2;
2257
+ list output_list=10,4,5,24,9;
2258
+ set_bubblesort_int(output_list);
2259
+ }
2260
+
2261
+ static proc set_is_set(list a)
2262
+ "USAGE: set_is_set(a)
2263
+ RETURN: 1 if the list is a set, 0 the list contains any duplicated elements
2264
+ EXAMPLE: set_is_set; shows an example.
2265
+ "
2266
+ {
2267
+ int i,v;
2268
+ for (v=1; v<=size(a); v++)
2269
+ {
2270
+ for (i=v+1; i<=size(a); i++)
2271
+ {
2272
+ if (a[i]==a[v])
2273
+ {
2274
+ return(0);
2275
+ }
2276
+ }
2277
+ }
2278
+ return(1);
2279
+ }
2280
+ example
2281
+ {
2282
+ "EXAMPLE:"; echo = 2;
2283
+ list set = 1,5,10,2;
2284
+ list noset = 1,5,10,2,5;
2285
+ set_is_set(set);
2286
+ set_is_set(noset);
2287
+ }
2288
+
2289
+ static proc set_contains(list a, int e)
2290
+ "USAGE: set_contains(a,e)
2291
+ RETURN: 1 if the list contains e, 0 otherwise
2292
+ EXAMPLE: set_contains; shows an example.
2293
+ "
2294
+ {
2295
+ for (int v=1; v<=size(a); v++)
2296
+ {
2297
+ if (a[v]==e)
2298
+ {
2299
+ return(1);
2300
+ }
2301
+ }
2302
+ return(0);
2303
+ }
2304
+ example
2305
+ {
2306
+ "EXAMPLE:"; echo = 2;
2307
+ list set = 1,5,10,2;
2308
+ set_contains(set,5);
2309
+ set_contains(set,40);
2310
+ }
2311
+
2312
+ static proc set_delete_duplicates(list a)
2313
+ "USAGE: set_delete_duplicates(a)
2314
+ RETURN: a list a without any duplicated elements
2315
+ EXAMPLE: set_delete_duplicates; shows an example.
2316
+ "
2317
+ {
2318
+ int i;
2319
+ list output_list = a[1];
2320
+ for (i=1; i<=size(a); i++)
2321
+ {
2322
+ if (set_contains(output_list,a[i])==0)
2323
+ {
2324
+ output_list = insert(output_list,a[i]);
2325
+ }
2326
+ }
2327
+ return(output_list);
2328
+ }
2329
+ example
2330
+ {
2331
+ "EXAMPLE:"; echo = 2;
2332
+ list set = 1,5,10,2,10,5;
2333
+ set_delete_duplicates(set);
2334
+ }
2335
+
2336
+ static proc set_equals(list a,list b)
2337
+ "USAGE: set_equals(a, b)
2338
+ RETURN: 1 if the lists are equal from a set-structure standpoint, 0 otherwise
2339
+ EXAMPLE: set_equals; shows an example.
2340
+ "
2341
+ {
2342
+ //Checks if the lists have the same length
2343
+ if (size(a)!=size(b))
2344
+ {
2345
+ return(0);
2346
+ }
2347
+
2348
+ //Sorts the lists
2349
+ a = set_bubblesort_int(a);
2350
+ b = set_bubblesort_int(b);
2351
+
2352
+ //Checks every single element of both lists
2353
+ for (int i=1; i<=size(a); i++)
2354
+ {
2355
+ if (a[i]!=b[i])
2356
+ {
2357
+ return(0);
2358
+ }
2359
+ }
2360
+ return(1);
2361
+ }
2362
+ example
2363
+ {
2364
+ "EXAMPLE:"; echo = 2;
2365
+ list set1 = 1,5,10,2;
2366
+ list set2 = 10,2,5,1;
2367
+ list set3 = 1,5,9,2;
2368
+ set_equals(set1,set2);
2369
+ set_equals(set1,set3);
2370
+ }
2371
+
2372
+ static proc set_insert(list a, int e)
2373
+ "USAGE: set_insert(a,e)
2374
+ RETURN: list a containing element e
2375
+ EXAMPLE: set_insert; shows an example.
2376
+ "
2377
+ {
2378
+ if(set_contains(a,e))
2379
+ {
2380
+ return(a);
2381
+ }
2382
+ else
2383
+ {
2384
+ a=insert(a,e);
2385
+ return(a);
2386
+ }
2387
+ }
2388
+ example
2389
+ {
2390
+ "EXAMPLE:"; echo = 2;
2391
+ list set = 1,5,10,2;
2392
+ set_insert(set,5);
2393
+ set_insert(set,22);
2394
+ }
2395
+
2396
+ static proc set_union(list a, list b)
2397
+ "USAGE: set_union(a, b)
2398
+ RETURN: list a as union of a and b
2399
+ EXAMPLE: set_union; shows an example.
2400
+ "
2401
+ {
2402
+ for (int i=1; i<=size(b); i++)
2403
+ {
2404
+ if (set_contains(a,b[i])==0)
2405
+ {
2406
+ a = insert(a,b[i]);
2407
+ }
2408
+ }
2409
+ return(a);
2410
+ }
2411
+ example
2412
+ {
2413
+ "EXAMPLE:"; echo = 2;
2414
+ list set1 = 1,5,10,2;
2415
+ list set2 = 5,10,93,58,29;
2416
+ set_union(set1,set2);
2417
+ }
2418
+
2419
+ static proc set_section(list a, list b)
2420
+ "USAGE: set_section(a, b)
2421
+ RETURN: list output_list as intersection of a and b
2422
+ EXAMPLE: set_section; shows an example.
2423
+ "
2424
+ {
2425
+ list output_list;
2426
+ for (int i=1; i<=size(a); i++)
2427
+ {
2428
+ if (set_contains(b,a[i])==1)
2429
+ {
2430
+ output_list = insert(output_list,a[i]);
2431
+ }
2432
+ }
2433
+ return(output_list);
2434
+ }
2435
+ example
2436
+ {
2437
+ "EXAMPLE:"; echo = 2;
2438
+ list set1 = 1,5,10,2;
2439
+ list set2 = 5,10,93,58,29;
2440
+ set_section(set1,set2);
2441
+ }
2442
+
2443
+ static proc set_list_delete_duplicates(list a)
2444
+ "USAGE: set_list_delete_duplicates(a)
2445
+ RETURN: list output_list with no duplicated lists
2446
+ EXAMPLE: set_list_delete_duplicates; shows an example.
2447
+ "
2448
+ {
2449
+ int v;
2450
+ int i;
2451
+ int counter;
2452
+ int out_size;
2453
+ list output_list=insert(output_list,a[1]);
2454
+ //Create a new list and try to insert every list element from a into that list. If a list is already inserted into the
2455
+ //new list, do nothing.
2456
+ for (i=2; i<=size(a); i++)
2457
+ {
2458
+ out_size = size(output_list);
2459
+ counter = 0;
2460
+
2461
+ for (v=1; v<=out_size; v++)
2462
+ {
2463
+ if (set_equals(output_list[v],a[i])==1)
2464
+ {
2465
+ counter++;
2466
+ }
2467
+ }
2468
+ if (counter==0)
2469
+ {
2470
+ output_list = insert(output_list,a[i]);
2471
+ }
2472
+ }
2473
+ return(output_list);
2474
+ }
2475
+ example
2476
+ {
2477
+ "EXAMPLE:"; echo = 2;
2478
+ list set1 = 1,5,10,2;
2479
+ list set2 = 1,10,2,5;
2480
+ list set3 = 1,2,3;
2481
+ list superset = set1,set2,set3;
2482
+ set_list_delete_duplicates(superset);
2483
+ }
2484
+
2485
+ static proc set_construct_increasing_set(int maxelement)
2486
+ "USAGE: set_construct_increasing_set(maxelement)
2487
+ RETURN: list output_list with increasing elements from 1 to maxelement
2488
+ EXAMPLE: set_construct_increasing_set; shows an example.
2489
+ "
2490
+ {
2491
+ list output_list;
2492
+ for (int i=1; i<=maxelement; i++)
2493
+ {
2494
+ output_list = insert(output_list, i);
2495
+ }
2496
+ return(output_list);
2497
+ }
2498
+ example
2499
+ {
2500
+ "EXAMPLE:"; echo = 2;
2501
+ set_construct_increasing_set(10);
2502
+ }
2503
+
2504
+ static proc set_addtoall(list a, int element)
2505
+ "USAGE: set_addtoall(a,alement)
2506
+ RETURN: Transformed list with e_i+element for every element e_i in list a
2507
+ EXAMPLE: set_addtoall; shows an example.
2508
+ "
2509
+ {
2510
+ list output_list;
2511
+ int c;
2512
+ for (int i=1; i<=size(a); i++)
2513
+ {
2514
+ c = a[i]+element;
2515
+ output_list = insert(output_list,c);
2516
+ }
2517
+ return(set_turn(output_list));
2518
+ }
2519
+ example
2520
+ {
2521
+ "EXAMPLE:"; echo = 2;
2522
+ list set = 1,5,10,2;
2523
+ set_addtoall(set,5);
2524
+ }
2525
+
2526
+ static proc set_turn(list a)
2527
+ "USAGE: set_turn(a)
2528
+ RETURN: Turned list a
2529
+ EXAMPLE: set_turn; shows an example.
2530
+ "
2531
+ {
2532
+ list output_list;
2533
+ for (int i=1; i<=size(a); i++)
2534
+ {
2535
+ output_list[size(a)+1-i] = a[i];
2536
+ }
2537
+ return(output_list);
2538
+ }
2539
+ example
2540
+ {
2541
+ "EXAMPLE:"; echo = 2;
2542
+ list set = 1,5,10;
2543
+ set_turn(set);
2544
+ }
2545
+
2546
+ static proc set_subset_set(list a)
2547
+ "USAGE: set_subset_set(a)
2548
+ RETURN: Set of subsets
2549
+ EXAMPLE: set_subset_set; shows an example.
2550
+ "
2551
+ {
2552
+ int v;
2553
+ int choice;
2554
+ list output_list;
2555
+ list start = a[1];
2556
+ list insertion_list;
2557
+ int output_length;
2558
+ output_list = insert(output_list,start);
2559
+
2560
+ for (int i=2; i<=size(a); i++)
2561
+ {
2562
+ choice = 0;
2563
+ start = a[i];
2564
+ output_list = insert(output_list,start);
2565
+ output_length = size(output_list);
2566
+ for (v=2; v<=output_length; v++)
2567
+ {
2568
+ insertion_list = set_insert(output_list[v],a[i]);
2569
+ output_list = insert(output_list, insertion_list,size(output_list));
2570
+ }
2571
+ }
2572
+ return(output_list);
2573
+ }
2574
+ example
2575
+ {
2576
+ "EXAMPLE:"; echo = 2;
2577
+ list set = 1,5,10;
2578
+ set_subset_set(set);
2579
+ }
2580
+ /* -----------------------------------------------------------------
2581
+ * knapsack_utilities: Utility functions needed for knapsack
2582
+ * -----------------------------------------------------------------*/
2583
+ proc calculate_ordering(bigint num1, bigint primitive, bigint mod1)
2584
+ "USAGE: calculate_ordering(num1, primitive, mod1)
2585
+ RETURN: x so that primitive^x == num1 mod mod1
2586
+ EXAMPLE: example calculate_ordering; shows an example;
2587
+ "
2588
+ {
2589
+ for (int i=1;i<=int((mod1-2));i++)
2590
+ {
2591
+ if ((primitive^i%mod1)==num1)
2592
+ {
2593
+ return(i);
2594
+ }
2595
+ }
2596
+ return(0);
2597
+ }
2598
+ example
2599
+ {
2600
+ "EXAMPLE:"; echo = 2;
2601
+ bigint mod1 = 33;
2602
+ bigint primitive = 14;
2603
+ bigint num1 = 5;
2604
+ calculate_ordering(num1,primitive,mod1);
2605
+ }
2606
+
2607
+ proc is_primitive_root(bigint primitive, bigint mod1)
2608
+ "USAGE: is_primitive_root(primitive, mod1)
2609
+ RETURN: 1 if primitive is a primitive root modulo mod1, 0 otherwise
2610
+ EXAMPLE: example is_primitive_root; shows an example;
2611
+ "
2612
+ {
2613
+ list output_list;
2614
+ for (int i=1;i<=int((mod1-1));i++)
2615
+ {
2616
+ output_list = set_insert(output_list,int((primitive^i%mod1)));
2617
+ }
2618
+ if (bigint(size(output_list))==bigint(mod1-1))
2619
+ {
2620
+ return(1);
2621
+ }
2622
+ else
2623
+ {
2624
+ return(0);
2625
+ }
2626
+ }
2627
+ example
2628
+ {
2629
+ "EXAMPLE:"; echo = 2;
2630
+ is_primitive_root(3,7);
2631
+ is_primitive_root(2,7);
2632
+ }
2633
+
2634
+ proc find_first_primitive_root(bigint mod1)
2635
+ "USAGE: find_first_primitive_root(mod1)
2636
+ RETURN: First primitive root modulo mod1, 0 if no root can be found.
2637
+ EXAMPLE: example find_first_primitive_root; shows an example;
2638
+ "
2639
+ {
2640
+ for (int i=0;i<=int(mod1-1);i++)
2641
+ {
2642
+ if (is_primitive_root(bigint(i),mod1)==1)
2643
+ {
2644
+ return(i);
2645
+ }
2646
+ }
2647
+ return(0);
2648
+ }
2649
+ example
2650
+ {
2651
+ "EXAMPLE:"; echo = 2;
2652
+ ring r = 0,x,lp;
2653
+ find_first_primitive_root(7);
2654
+ find_first_primitive_root(557);
2655
+ }
2656
+
2657
+ proc binary_add(list binary_list)
2658
+ "USAGE: binary_add(binary_list)
2659
+ RETURN: binary encoded list, increased by 1
2660
+ EXAMPLE: example binary_add; shows an example;
2661
+ "
2662
+ {
2663
+ int residual=1;
2664
+ int position = size(binary_list);
2665
+ while((residual==1)&&(position!=0))
2666
+ {
2667
+ if(binary_list[position]==0)
2668
+ {
2669
+ binary_list[position]=1;
2670
+ residual=0;
2671
+ }
2672
+ else
2673
+ {
2674
+ binary_list[position]=0;
2675
+ position--;
2676
+ }
2677
+ }
2678
+ if (position==0)
2679
+ {
2680
+ binary_list = insert(binary_list,1);
2681
+ }
2682
+ return(binary_list);
2683
+ }
2684
+ example
2685
+ {
2686
+ "EXAMPLE:"; echo = 2;
2687
+ ring r = 0,x,lp;
2688
+ list binary_list = 1,0,1,1,1;
2689
+ binary_add(binary_list);
2690
+ }
2691
+
2692
+ proc inverse_modulus(int num, int mod1)
2693
+ "USAGE: inverse_modulus(num, mod1)
2694
+ RETURN: inverse element of num modulo mod1
2695
+ EXAMPLE: example inverse_modulus; shows an example;
2696
+ "
2697
+ {
2698
+ if (num>=mod1)
2699
+ {
2700
+ return(0);
2701
+ }
2702
+ else
2703
+ {
2704
+ for (int i=1;i<mod1;i++)
2705
+ {
2706
+ if ((i*num%mod1)==1)
2707
+ {
2708
+ return(i);
2709
+ }
2710
+ }
2711
+ }
2712
+ }
2713
+ example
2714
+ {
2715
+ "EXAMPLE:"; echo = 2;
2716
+ ring r = 0,x,lp;
2717
+ int mod1 = 13;
2718
+ int num = 5;
2719
+ inverse_modulus(num,mod1);
2720
+ }
2721
+
2722
+ proc is_prime(int n)
2723
+ "USAGE: is_prime(n)
2724
+ RETURN: 1 if n is prime, 0 otherwise
2725
+ EXAMPLE: example is_prime; shows an example;
2726
+ "
2727
+ {
2728
+ int prime1 = 1;
2729
+ for (int i=n-1;i>1;i--)
2730
+ {
2731
+ if(n%i==0)
2732
+ {
2733
+ prime1 = 0;
2734
+ }
2735
+ }
2736
+ return(prime1);
2737
+ }
2738
+ example
2739
+ {
2740
+ "EXAMPLE:"; echo = 2;
2741
+ ring r = 0,x,lp;
2742
+ is_prime(10);
2743
+ is_prime(7);
2744
+ }
2745
+
2746
+ proc find_biggest_index(list a)
2747
+ "USAGE: find_biggest_index( a)
2748
+ RETURN: Returns the index of the biggest element of a
2749
+ EXAMPLE: example find_biggest_index; shows an example;
2750
+ "
2751
+ {
2752
+ list sortedlist = bubblesort(a);
2753
+ return(find_index(a,sortedlist[1]));
2754
+ }
2755
+
2756
+ proc find_index(list a, bigint e)
2757
+ "USAGE: find_index(a, e)
2758
+ RETURN: Returns the list index of element e in list a. Returns 0 if e is not in a
2759
+ EXAMPLE: example find_index; shows an example;
2760
+ "
2761
+ {
2762
+ for(int i=1;i<=size(a);i++)
2763
+ {
2764
+ if (bigint(a[i])==e)
2765
+ {
2766
+ return(i);
2767
+ }
2768
+ }
2769
+ return(0);
2770
+ }
2771
+ example
2772
+ {
2773
+ "EXAMPLE:"; echo = 2;
2774
+ list a = 1,5,20,6,37;
2775
+ find_index(a,20);
2776
+ find_index(a,6);
2777
+ find_index(a,100);
2778
+ }
2779
+ /* ------------------------------------------------------------------
2780
+ * Knapsack Algorithmus such as solving several knapsack problems,
2781
+ * kryptographic algorithms and algorithms for creatings suitable knapsacks
2782
+ * ---------------------------------------------------------------- */
2783
+ proc subset_sum01(list knapsack, int solution)
2784
+ "USAGE: subset_sum01(knapsack,solution)
2785
+ RETURN: binary list of the positions of the elements included in the subset sum or 0 if no solution exists
2786
+ NOTE: This will return the first solution of the ssk-problem, given be the smallest binary encoding. It wont return several solutions if they exist
2787
+ EXAMPLE: example subset_sum01; shows an example;
2788
+ "
2789
+ {
2790
+ int i;
2791
+ int v;
2792
+ int comparable;
2793
+ //Check if the knapsack is a set
2794
+ if (set_is_set(knapsack)==1)
2795
+ {
2796
+ //Create a binary list full of zeroes
2797
+ list binary_list;
2798
+ for (i=1;i<=size(knapsack);i++)
2799
+ {
2800
+ binary_list = insert(binary_list,0);
2801
+ }
2802
+ binary_list = binary_add(binary_list);
2803
+
2804
+ for(i=1;i<=2^(size(knapsack));i++)
2805
+ {
2806
+ comparable = 0;
2807
+ //Create the Subset-Sum for the actual binary coding of binary_list
2808
+ for (v=1;v<=size(knapsack);v++)
2809
+ {
2810
+ comparable = comparable+knapsack[v]*binary_list[v];
2811
+ }
2812
+ //Check if the sum equals the solution
2813
+ if (comparable==solution)
2814
+ {
2815
+ return(binary_list);
2816
+ }
2817
+ else
2818
+ {
2819
+ binary_list = binary_add(binary_list);
2820
+ }
2821
+ }
2822
+ return(0);
2823
+ }
2824
+ else
2825
+ {
2826
+ return(0);
2827
+ }
2828
+ }
2829
+ example
2830
+ {
2831
+ "EXAMPLE:"; echo = 2;
2832
+ list h=1,4,7,32;
2833
+ subset_sum01(h,20);
2834
+ subset_sum01(h,11);
2835
+ subset_sum01(h,33);
2836
+ }
2837
+
2838
+ proc subset_sum02(list knapsack, int sol)
2839
+ "USAGE: subset_sum02(knapsack,sol)
2840
+ RETURN: binary list of the positions of the elements included in the subset sum or 0 if no solution exists
2841
+ EXAMPLE: example subset_sum02; shows an example;
2842
+ "
2843
+ {
2844
+ list summands;
2845
+ int calcu;
2846
+ int i;
2847
+ //Create a sorted copy of the knapsack, calling it worksack
2848
+ list worksack = set_bubblesort_int(knapsack);
2849
+ int counter = 1;
2850
+ while((counter<=size(worksack))&&(sol>0))
2851
+ {
2852
+ //Try to subtract an element of the knapsack from the capacity. Create a list with all the summands used
2853
+ calcu = sol-worksack[counter];
2854
+ if (calcu>=0)
2855
+ {
2856
+ sol = sol-worksack[counter];
2857
+ summands = insert(summands,int(worksack[counter]));
2858
+ }
2859
+ counter++;
2860
+ }
2861
+ if(sol>0)
2862
+ {
2863
+ return(0);
2864
+ }
2865
+
2866
+ //Get the index of the summands of the original knapsack and change the bits in the binary list which will be the solution
2867
+ list binary_list;
2868
+ for (i=1;i<=size(knapsack);i++)
2869
+ {
2870
+ binary_list = insert(binary_list,0);
2871
+ }
2872
+
2873
+ for (i=1; i<=size(knapsack);i++)
2874
+ {
2875
+ if (set_contains(summands,knapsack[i])==1)
2876
+ {
2877
+ binary_list[i]=1;
2878
+ }
2879
+ }
2880
+ return(binary_list);
2881
+ }
2882
+ example
2883
+ {
2884
+ "EXAMPLE:"; echo = 2;
2885
+ list h=1,4,7,32;
2886
+ subset_sum02(h,20);
2887
+ subset_sum02(h,11);
2888
+ subset_sum02(h,33);
2889
+ }
2890
+
2891
+ proc unbounded_knapsack(list knapsack, list profit, int capacity)
2892
+ "USAGE: unbounded_knapsack(knapsack,profit,capacity)
2893
+ RETURN: list of maximum profit of each iteration. For example, output_list[2] contains the maximum profit that can be achieved if the knapsack has capacity 2.
2894
+ EXAMPLE: unbounded_knapsack; shows an example;
2895
+ "
2896
+ {
2897
+ int i;
2898
+ int v;
2899
+ list output_list;
2900
+ for (i=1;i<=capacity+1;i++)
2901
+ {
2902
+ output_list = insert(output_list,0);
2903
+ }
2904
+ for (i=1;i<=capacity+1;i++)
2905
+ {
2906
+ for(v=1;v<=size(knapsack);v++)
2907
+ {
2908
+ if (knapsack[v]<i)
2909
+ {
2910
+ if(output_list[i]<(output_list[i-knapsack[v]]+profit[v]))
2911
+ {
2912
+ output_list[i] = output_list[i-knapsack[v]]+profit[v];
2913
+ }
2914
+ }
2915
+ }
2916
+ }
2917
+ return(output_list);
2918
+ }
2919
+ example
2920
+ {
2921
+ "EXAMPLE:"; echo = 2;
2922
+ list h=1,4,7,32;
2923
+ list knapsack = 5,2;
2924
+ list profit = 10,3;
2925
+ int capacity = 5;
2926
+ unbounded_knapsack(knapsack,profit,capacity);
2927
+ }
2928
+
2929
+ proc multidimensional_knapsack(matrix m, list capacities, list profits)
2930
+ "USAGE: multidimensional_knapsack(m,capacities,profits)
2931
+ RETURN: binary list of the positions of the elements included in the optimal selection
2932
+ EXAMPLE: example multidimensional_knapsack; shows an example;
2933
+ "
2934
+ {
2935
+ int index;
2936
+ list output_list;
2937
+ list nolist;
2938
+ list y_list;
2939
+ list minmax_list;
2940
+ int i;
2941
+ int v;
2942
+ int checkint;
2943
+ //create the output_list full of zeroes with the length of all given selections
2944
+ for (i=1;i<=size(profits);i++)
2945
+ {
2946
+ output_list = insert(output_list,0);
2947
+ }
2948
+
2949
+ //Create the List E with all indices of the output_list that haven't been used yet.
2950
+ list E = set_turn(set_construct_increasing_set(size(profits)));
2951
+
2952
+ //Repeat till every index in E is used.
2953
+ while(size(E)>0)
2954
+ {
2955
+ y_list = nolist;
2956
+ for (i=1;i<=size(E);i++)
2957
+ {
2958
+ //Create all possible elements of y_i (y_list). minimax_list will be replaced of an empty list in each iteration
2959
+ minmax_list = nolist;
2960
+ for (v=1; v<=size(capacities);v++)
2961
+ {
2962
+ if (set_contains(E,v)==1)
2963
+ {
2964
+ minmax_list = insert(minmax_list, bigint(capacities[v])/bigint(m[v,E[i]]));
2965
+ }
2966
+ }
2967
+ //Sort the elements so that it is easy to pick the smallest one
2968
+ minmax_list = bubblesort(minmax_list);
2969
+
2970
+ //insert Element y_i into y_list, which is the smallest of (b_i/w_ij) like in the PECH algorithm description.
2971
+ y_list = insert(y_list,minmax_list[size(minmax_list)],size(y_list));
2972
+
2973
+
2974
+ }
2975
+
2976
+ //Check if all y_i in y_list are smaller than 1. If so, every additional selection will exceed the capacity and the algorithm stops.
2977
+ checkint=0;
2978
+ for(i=1;i<=size(y_list);i++)
2979
+ {
2980
+ if (y_list[i]>=1)
2981
+ {
2982
+ checkint=1;
2983
+ }
2984
+ }
2985
+ if (checkint==0)
2986
+ {
2987
+ return(output_list);
2988
+ }
2989
+
2990
+
2991
+ //Find the index of the selection and update the binary output_list
2992
+ minmax_list = nolist;
2993
+ for (i=1;i<=size(E);i++)
2994
+ {
2995
+ minmax_list = insert(minmax_list, profits[E[i]]*y_list[i],size(minmax_list));
2996
+ }
2997
+ index = find_biggest_index(minmax_list);
2998
+
2999
+ output_list[E[index]]=1;
3000
+
3001
+ //Update the capacities by subtracting the weights of the selection
3002
+ for (i=1;i<=size(capacities);i++)
3003
+ {
3004
+ capacities[i] = capacities[i]- m[i,E[index]];
3005
+ }
3006
+ E = set_delete_certain_element(E,index);
3007
+
3008
+ }
3009
+ return(output_list);
3010
+ }
3011
+ example
3012
+ {
3013
+ "EXAMPLE:"; echo = 2;
3014
+ ring r = 0,x,lp;
3015
+ matrix m[3][3] = 1,4,10,7,8,3,1,9,7;
3016
+ list c = 12,17,10;
3017
+ list p = 3,2,5;
3018
+ multidimensional_knapsack(m,c,p);
3019
+ }
3020
+
3021
+ proc naccache_stern_generation(int key, int primenum)
3022
+ "USAGE: naccache_stern_generation(key, primenum)
3023
+ RETURN: a hard knapsack list
3024
+ EXAMPLE: example naccache_stern_generation; shows an example;
3025
+ "
3026
+ {
3027
+ //Check if primenum is a prime and the gcd-Condition holds
3028
+ if ((is_prime(primenum)==0)||(gcd(key,(primenum-1))!=1))
3029
+ {
3030
+ return(0);
3031
+ }
3032
+ else
3033
+ {
3034
+ int i;
3035
+ int p;
3036
+ list primelist;
3037
+ int primecounter=2;
3038
+ //Generate the knapsack containing the smallest prime numbers so that primenum exceeds the product of all of them
3039
+ while(set_multiply_list_content(primelist)<primenum)
3040
+ {
3041
+ if (is_prime(primecounter)==1)
3042
+ {
3043
+ primelist = insert(primelist,primecounter);
3044
+ }
3045
+ primecounter++;
3046
+ }
3047
+ primelist = delete(primelist,1);
3048
+
3049
+
3050
+ //Generate the hard knapsack of the length of the prime numbers containing zeroes.
3051
+ list hardknapsack;
3052
+ for (i=1;i<=size(primelist);i++)
3053
+ {
3054
+ hardknapsack = insert(hardknapsack,0);
3055
+ }
3056
+
3057
+ //Create the elements of the hard knapsack
3058
+ primecounter = 1;
3059
+ bigint calcu;
3060
+ i=0;
3061
+ while (i<size(primelist))
3062
+ {
3063
+ //Create some v_i^key%primenum and store it in calcu
3064
+ calcu = bigint(primecounter)^key%bigint(primenum);
3065
+
3066
+ //If calcu is one of the prime numbers in the knapsack, find the index and insert v_i in the hard knapsack at that given index
3067
+ if(set_contains(primelist,int(calcu))==1)
3068
+ {
3069
+ p=find_index(primelist,int(calcu));
3070
+ hardknapsack[p] = primecounter;
3071
+ i++;
3072
+ }
3073
+ primecounter++;
3074
+ }
3075
+ return(hardknapsack);
3076
+ }
3077
+ }
3078
+ example
3079
+ {
3080
+ "EXAMPLE:"; echo = 2;
3081
+ naccache_stern_generation(5,292);
3082
+ naccache_stern_generation(5,293);
3083
+ }
3084
+
3085
+ proc naccache_stern_encryption(list knapsack, list message, int primenum)
3086
+ "USAGE: naccache_stern_encryption(knapsack, message, primenum)
3087
+ RETURN: an encrypted message as integer
3088
+ EXAMPLE: example naccache_stern_encryption; shows an example;
3089
+ "
3090
+ {
3091
+ bigint solution = 1;
3092
+ if (size(knapsack)==size(message))
3093
+ {
3094
+ for(int i=1;i<=size(knapsack);i++)
3095
+ {
3096
+ solution = solution*((bigint(knapsack[i])^message[i])%bigint(primenum));
3097
+ }
3098
+ return(solution);
3099
+ }
3100
+ else
3101
+ {
3102
+ return(0);
3103
+ }
3104
+
3105
+ }
3106
+ example
3107
+ {
3108
+ "EXAMPLE:"; echo = 2;
3109
+ //Please note that the values for primenum and hardknapsack have been obtained from the example of naccache_stern_generation!
3110
+ list hardknapsack = 85,164,117,44;
3111
+ int primenum = 293;
3112
+ list message = 1,0,1,0;
3113
+ naccache_stern_encryption(hardknapsack,message,primenum);
3114
+ }
3115
+
3116
+ proc naccache_stern_decryption(list knapsack, int key, int primenum, int message)
3117
+ "USAGE: naccache_stern_decryption(knapsack, key, primenum, message)
3118
+ RETURN: decrypted binary list
3119
+ EXAMPLE: example naccache_stern_decryption; shows an example;
3120
+ "
3121
+ {
3122
+ //create a binary list with the length of the knapsack containing zeros
3123
+ int k = int(bigint(message)^key%bigint(primenum));
3124
+ int i;
3125
+ list binary_list;
3126
+ for (i=1;i<=size(knapsack);i++)
3127
+ {
3128
+ binary_list = insert(binary_list,0);
3129
+ }
3130
+
3131
+ //create primelist like in int naccache_stern_generation process
3132
+ list primelist;
3133
+ int primecounter=2;
3134
+ while(size(primelist)<size(knapsack))
3135
+ {
3136
+ if (is_prime(primecounter)==1)
3137
+ {
3138
+ primelist = insert(primelist,primecounter);
3139
+ }
3140
+ primecounter++;
3141
+ }
3142
+
3143
+ //find divisors of k and update the binarylist in a way that the positions of the divisors in primelist are marked
3144
+ for (i=1;i<=size(primelist);i++)
3145
+ {
3146
+ if(k%primelist[i]==0)
3147
+ {
3148
+ binary_list[i]=1;
3149
+ }
3150
+ }
3151
+ return(binary_list);
3152
+
3153
+ }
3154
+ example
3155
+ {
3156
+ "EXAMPLE:"; echo = 2;
3157
+ //Please note that the values have been obtained from the example of naccache_stern_generation and naccache_stern_encryption!
3158
+ int primenum = 293;
3159
+ int message = 9945;
3160
+ int key = 5;
3161
+ list hardknapsack = 85,164,117,44;
3162
+ naccache_stern_decryption(hardknapsack,key,primenum,message);
3163
+ }
3164
+
3165
+ proc m_merkle_hellman_transformation(list knapsack, int primitive, int mod1)
3166
+ "USAGE: m_merkle_hellman_transformation(knapsack, primitive, mod1)
3167
+ RETURN: list containing a hard knapsack
3168
+ EXAMPLE: example m_merkle_hellman_transformation; shows an example;
3169
+ "
3170
+ {
3171
+ bigint new_element;
3172
+ list output_list;
3173
+ //calculate the primitiv root of every element in knapsack and insert it into a new knapsack
3174
+ for (int i=size(knapsack);i>=1;i--)
3175
+ {
3176
+ new_element = calculate_ordering(knapsack[i],primitive,mod1);
3177
+ output_list = insert(output_list,int(new_element));
3178
+ }
3179
+ return(output_list);
3180
+ }
3181
+ example
3182
+ {
3183
+ "EXAMPLE:"; echo = 2;
3184
+ //Please note that the values for primenum and hardknapsack have been obtained from the example of naccache_stern_generation and naccache_stern_encryption!
3185
+ list knapsack = 2,3,5,7;
3186
+ int mod1 = 211;
3187
+ int primitive = 2;
3188
+ m_merkle_hellman_transformation(knapsack,primitive,mod1);
3189
+ }
3190
+
3191
+ proc m_merkle_hellman_encryption(list knapsack, list message)
3192
+ "USAGE: m_merkle_hellman_encryption(knapsack, message)
3193
+ RETURN: an encrypted message as integer
3194
+ NOTE: This works in the same way as merkle_hellman_encryption. The additional function is created to keep consistency with the needed functions for every kryptosystem.
3195
+ EXAMPLE: example m_merkle_hellman_encryption; shows an example;
3196
+ "
3197
+ {
3198
+ return(merkle_hellman_encryption(knapsack,message));
3199
+ }
3200
+ example
3201
+ {
3202
+ "EXAMPLE:"; echo = 2;
3203
+ //Please note that the values for primenum and hardknapsack have been obtained from the example of m_merkle_hellman_transformation!
3204
+ list knapsack = 1,43,132,139;
3205
+ list message = 1,0,0,1;
3206
+ m_merkle_hellman_encryption(knapsack,message);
3207
+ }
3208
+
3209
+ proc m_merkle_hellman_decryption(list knapsack, bigint primitive, bigint mod1, int message)
3210
+ "USAGE: m_merkle_hellman_decryption(knapsack, primitive, mod1, message)
3211
+ RETURN: decrypted binary list
3212
+ EXAMPLE: example merkle_hellman_decryption; shows an example;
3213
+ "
3214
+ {
3215
+ //Convert message
3216
+ int factorizing = int((primitive^message)%mod1);
3217
+ int i;
3218
+
3219
+ //Create binary list of length of the knapsack, containing zeroes.
3220
+ list binary_list;
3221
+ for (i=1;i<=size(knapsack);i++)
3222
+ {
3223
+ binary_list = insert(binary_list,0);
3224
+ }
3225
+
3226
+ //factorize the converted message, mark the factor positions in knapsack as bits in binary_list
3227
+ for (i=1;i<=size(knapsack);i++)
3228
+ {
3229
+ if(factorizing%knapsack[i]==0)
3230
+ {
3231
+ binary_list[i]=1;
3232
+ }
3233
+ }
3234
+ return(binary_list);
3235
+ }
3236
+ example
3237
+ {
3238
+ "EXAMPLE:"; echo = 2;
3239
+ //Please note that the values have been obtained from the example of m_merkle_hellman_encryption and m_merkle_hellman_transformation!
3240
+ list knapsack = 2,3,5,7;
3241
+ int message = 140;
3242
+ bigint primitive = 2;
3243
+ bigint mod1 = 211;
3244
+ m_merkle_hellman_decryption(knapsack,primitive,mod1,message);
3245
+ }
3246
+
3247
+ proc merkle_hellman_transformation(list knapsack, int key, int mod1)
3248
+ "USAGE: merkle_hellman_transformation(knapsack, key, mod1)
3249
+ RETURN: hard knapsack
3250
+ EXAMPLE: example merkle_hellman_transformation; shows an example;
3251
+ "
3252
+ {
3253
+ list output_list;
3254
+ int new_element;
3255
+ //transform every element in the knapsack with normal strong modular multiplication
3256
+ for (int i=size(knapsack);i>=1;i--)
3257
+ {
3258
+ new_element=knapsack[i]*key%mod1;
3259
+ output_list = insert(output_list,new_element);
3260
+ }
3261
+ return(output_list);
3262
+ }
3263
+ example
3264
+ {
3265
+ "EXAMPLE:"; echo = 2;
3266
+ list knapsack = 1,3,5,12;
3267
+ int key = 3;
3268
+ int mod1 = 23;
3269
+ merkle_hellman_transformation(knapsack,key,mod1);
3270
+ }
3271
+
3272
+ proc merkle_hellman_encryption(list knapsack, list message)
3273
+ "USAGE: merkle_hellman_encryption(knapsack, message)
3274
+ RETURN: encrypted integer
3275
+ EXAMPLE: example merkle_hellman_encryption; shows an example;
3276
+ "
3277
+ {
3278
+ int solution = 0;
3279
+ if (size(knapsack)!=size(message)||(set_is_set(knapsack)==0))
3280
+ {
3281
+ return(0);
3282
+ }
3283
+ else
3284
+ {
3285
+ for (int i=1;i<=size(knapsack);i++)
3286
+ {
3287
+ solution = solution+knapsack[i]*message[i];
3288
+ }
3289
+ return(solution);
3290
+ }
3291
+ }
3292
+ example
3293
+ {
3294
+ "EXAMPLE:"; echo = 2;
3295
+ //Please note that the values have been obtained from the example of merkle_hellman_transformation!
3296
+ list hardknapsack =3,9,15,13;
3297
+ list message = 0,1,0,1;
3298
+ merkle_hellman_encryption(hardknapsack,message);
3299
+ }
3300
+
3301
+ proc merkle_hellman_decryption(list knapsack, int key, int mod1, int message)
3302
+ "USAGE: merkle_hellman_decryption(knapsack, key, mod1, message)
3303
+ RETURN: decrypted binary list
3304
+ EXAMPLE: example merkle_hellman_decryption; shows an example;
3305
+ "
3306
+ {
3307
+ int new_element;
3308
+ int t = inverse_modulus(key,mod1);
3309
+ int transformed_message;
3310
+ list binary_list;
3311
+ if ((set_is_set(knapsack)==1)&&(key<mod1))
3312
+ {
3313
+ //reconstruct easy knapsack be multiplying with the inverse modulus t
3314
+ list easy_knapsack;
3315
+ for (int i=size(knapsack);i>=1;i--)
3316
+ {
3317
+ new_element=knapsack[i]*t%mod1;
3318
+ easy_knapsack = insert(easy_knapsack,new_element);
3319
+ }
3320
+
3321
+ //solve the easy knapsack problem with subset_sum01 or subset_sum02
3322
+ transformed_message = (message*t)%mod1;
3323
+ transformed_message;
3324
+ binary_list = subset_sum01(easy_knapsack,transformed_message);
3325
+ return(binary_list)
3326
+ }
3327
+ else
3328
+ {
3329
+ return(0)
3330
+ }
3331
+ }
3332
+ example
3333
+ {
3334
+ "EXAMPLE:"; echo = 2;
3335
+ //Please note that the values have been obtained from the example of merkle_hellman_decryption and merkle_hellman_transformation!
3336
+ list hardknapsack =3,9,15,13;
3337
+ int key = 3;
3338
+ int message = 22;
3339
+ int mod1 = 23;
3340
+ merkle_hellman_decryption(hardknapsack, key, mod1, message);
3341
+ }
3342
+
3343
+ proc super_increasing_knapsack(int ksize)
3344
+ "USAGE: super_increasing_knapsack(ksize)
3345
+ RETURN: super-increasing knapsack list
3346
+ EXAMPLE: super_increasing_knapsack; shows an example;
3347
+ "
3348
+ {
3349
+ list output_list = insert(output_list,1);
3350
+ int next_element;
3351
+
3352
+ for (int i=2; i<=ksize; i++)
3353
+ {
3354
+ next_element = calculate_max_sum(output_list)+1;
3355
+ output_list = insert(output_list,next_element);
3356
+ }
3357
+ return(output_list);
3358
+ }
3359
+ example
3360
+ {
3361
+ "EXAMPLE:"; echo = 2;
3362
+ super_increasing_knapsack(10);
3363
+ }
3364
+
3365
+ proc h_increasing_knapsack(int ksize, int h)
3366
+ "USAGE: h_increasing_knapsack(ksize, h)
3367
+ RETURN: h-increasing knapsack list
3368
+ EXAMPLE: h_increasing_knapsack; shows an example;
3369
+ "
3370
+ {
3371
+ int v;
3372
+ if (ksize<=h+1)
3373
+ {
3374
+ return(set_turn(super_increasing_knapsack(ksize)))
3375
+ }
3376
+ else
3377
+ {
3378
+ list out = set_turn(super_increasing_knapsack(h+1));
3379
+ int next_element;
3380
+ for (int i=h+2; i<=ksize; i++)
3381
+ {
3382
+ next_element = 0;
3383
+ for (v=i-h; v<=i-1; v++)
3384
+ {
3385
+ next_element = next_element+out[v];
3386
+ }
3387
+ next_element++;
3388
+ out = insert(out,next_element,size(out));
3389
+ }
3390
+ return(out);
3391
+ }
3392
+ }
3393
+ example
3394
+ {
3395
+ "EXAMPLE:"; echo = 2;
3396
+ h_increasing_knapsack(10,5);
3397
+ }
3398
+
3399
+ proc injective_knapsack(int ksize, int kmaxelement)
3400
+ "USAGE: injective_knapsack(ksize, kmaxelement)
3401
+ RETURN: list of injective knapsacks with maximal element kmaxelement and size ksize
3402
+ EXAMPLE: injective_knapsack; shows an example;
3403
+ "
3404
+ {
3405
+ //Create a List of size ksize with the greatest possible elements keeping the set structure
3406
+ list list_of_lists;
3407
+ list A = insert(A,kmaxelement);
3408
+ int i;
3409
+ for (i=2;i<=ksize;i++)
3410
+ {
3411
+ A = insert(A,kmaxelement-(i-1));
3412
+ }
3413
+ A = set_turn(A);
3414
+ list_of_lists = insert(list_of_lists,A);
3415
+
3416
+ //Create all possible sets containing the possible elements of A
3417
+ int residual;
3418
+ int position;
3419
+ while(A[1]==kmaxelement)
3420
+ {
3421
+ residual=3;
3422
+ position = ksize;
3423
+ while((residual!=0))
3424
+ {
3425
+ if(A[position]==1)
3426
+ {
3427
+ A[position]=kmaxelement-position+1;
3428
+ residual=1;
3429
+ position--;
3430
+ }
3431
+ else
3432
+ {
3433
+ A[position]=A[position]-1;
3434
+ residual=0;
3435
+ }
3436
+ }
3437
+ //Insert the list into the overall list if its a set
3438
+ if (set_is_set(A)==1)
3439
+ {
3440
+ list_of_lists = insert(list_of_lists,A);
3441
+ }
3442
+ }
3443
+ //delete the first element since it is smaller than kmaxelement
3444
+ list_of_lists = delete(list_of_lists,1);
3445
+ //delete duplicates
3446
+ list_of_lists = set_list_delete_duplicates(list_of_lists);
3447
+
3448
+ //Check if the remaining knapsacks are injective
3449
+ list output_list;
3450
+ for(i=1;i<=size(list_of_lists);i++)
3451
+ {
3452
+ if (set_is_injective(list_of_lists[i])==1)
3453
+ {
3454
+ output_list=insert(output_list,list_of_lists[i]);
3455
+ }
3456
+ }
3457
+ return(output_list);
3458
+ }
3459
+ example
3460
+ {
3461
+ "EXAMPLE:"; echo = 2;
3462
+ injective_knapsack(3,9);
3463
+ }
3464
+
3465
+ proc calculate_max_sum(list a)
3466
+ "USAGE: calculate_max_sum(a)
3467
+ RETURN: sum of all elements in a
3468
+ EXAMPLE: calculate_max_sum; shows an example;
3469
+ "
3470
+ {
3471
+ int sum = a[1];
3472
+ for (int i=2; i<=size(a);i++)
3473
+ {
3474
+ sum = sum+a[i];
3475
+ }
3476
+ return(sum);
3477
+ }
3478
+ example
3479
+ {
3480
+ "EXAMPLE:"; echo = 2;
3481
+ list a = 1,5,3,2,12;
3482
+ calculate_max_sum(a);
3483
+ }
3484
+
3485
+ proc set_is_injective(list a)
3486
+ "USAGE: set_is_injective(a)
3487
+ RETURN: 1 if a is injective, 0 otherwise
3488
+ EXAMPLE: set_is_injective; shows an example;
3489
+ "
3490
+ {
3491
+ //Create all subsets of the set a
3492
+ list subsum = set_subset_set(a);
3493
+ list checklist=calculate_max_sum(subsum[1]);
3494
+ int calculator;
3495
+ for (int i=2; i<=size(subsum);i++)
3496
+ {
3497
+ //calculate the maximal subset_sum for every subset. Check if there are duplicated subset_sums. If so, a is not injective
3498
+ calculator = calculate_max_sum(subsum[i]);
3499
+ if (set_contains(checklist, calculator))
3500
+ {
3501
+ return(0);
3502
+ }
3503
+ else
3504
+ {
3505
+ checklist = insert(checklist,calculator);
3506
+ }
3507
+ }
3508
+ return(1);
3509
+ }
3510
+ example
3511
+ {
3512
+ "EXAMPLE:"; echo = 2;
3513
+ list inj = 1,5,7,41;
3514
+ list non_inj = 1,2,3,4;
3515
+ set_is_injective(inj);
3516
+ set_is_injective(non_inj);
3517
+ }
3518
+
3519
+ proc is_h_injective(list a, int h)
3520
+ "USAGE: is_h_injective(a, h)
3521
+ RETURN: 1 if a is h-injective, 0 otherwise
3522
+ EXAMPLE: is_h_injective; shows an example;
3523
+ "
3524
+ {
3525
+ //Create all sets of subsets
3526
+ list subsetlist = set_subset_set(a);
3527
+ list h_subsetlist;
3528
+ //delete every list with elements more than h+1 since they are not needed to check h-injectivity
3529
+ for (int i=1; i<=size(subsetlist); i++)
3530
+ {
3531
+ if(size(subsetlist[i])<=h)
3532
+ {
3533
+ h_subsetlist = insert(h_subsetlist,subsetlist[i]);
3534
+ }
3535
+ }
3536
+
3537
+ //Check if the remaining max_sums do not occure more than once
3538
+ list checklist=calculate_max_sum(h_subsetlist[1]);
3539
+ int calculator;
3540
+ for (i=2; i<=size(h_subsetlist);i++)
3541
+ {
3542
+ calculator = calculate_max_sum(h_subsetlist[i]);
3543
+ if (set_contains(checklist, calculator)==1)
3544
+ {
3545
+ return(0);
3546
+ }
3547
+ else
3548
+ {
3549
+ checklist = insert(checklist,calculator);
3550
+ }
3551
+ }
3552
+ return(1);
3553
+
3554
+ }
3555
+ example
3556
+ {
3557
+ "EXAMPLE:"; echo = 2;
3558
+ list h_inj = 1,2,4,10,17;
3559
+ is_h_injective(h_inj,3);
3560
+ //1+2+4+10=17
3561
+ is_h_injective(h_inj,4);
3562
+ }
3563
+
3564
+ proc is_fix_injective(list a)
3565
+ "USAGE: is_fix_injective(a)
3566
+ RETURN: 1 if a is fix-injective, 0 otherwise
3567
+ EXAMPLE: is_fix_injective; shows an example;
3568
+ "
3569
+ {
3570
+ //Generation of the list-list-list
3571
+ list subsetlist = set_subset_set(a);
3572
+ list alreadycreatedlist;
3573
+ list listoflists;
3574
+ list emptylist1;
3575
+ list worklist;
3576
+ int i;
3577
+ int v;
3578
+ list checklist;
3579
+ int calculator;
3580
+
3581
+ int set_destination;
3582
+
3583
+ //create list of lists which contain the lists of a certain length as elements
3584
+ for (i = 1; i<= size(subsetlist); i++)
3585
+ {
3586
+ //Determine the size of the actual list to choose where to insert it in the listoflists
3587
+ set_destination = size(subsetlist[i]);
3588
+ if (set_contains(alreadycreatedlist,set_destination)==1)
3589
+ {
3590
+ //There is already an element with the same set size, so just insert it
3591
+ listoflists[set_destination] = insert(listoflists[set_destination],subsetlist[i]);
3592
+ }
3593
+ else
3594
+ {
3595
+ //There is not yet an element with the same set size, so create a new one
3596
+ listoflists[set_destination] = insert(emptylist1,subsetlist[i]);
3597
+ alreadycreatedlist = set_insert(alreadycreatedlist,set_destination );
3598
+ }
3599
+ }
3600
+
3601
+ //Check for injectivity of each separate list. Works as in injectivity or h-injectivity
3602
+ for (v=1; v<=size(listoflists); v++)
3603
+ {
3604
+ worklist = listoflists[v];
3605
+
3606
+ checklist=calculate_max_sum(worklist[1]);
3607
+ for (i=2; i<=size(worklist); i++)
3608
+ {
3609
+ calculator = calculate_max_sum(worklist[i]);
3610
+ if (set_contains(checklist, calculator)==1)
3611
+ {
3612
+ return(0);
3613
+ }
3614
+ else
3615
+ {
3616
+ checklist = insert(checklist,calculator);
3617
+ }
3618
+ }
3619
+ }
3620
+ return(1);
3621
+ }
3622
+ example
3623
+ {
3624
+ "EXAMPLE:"; echo = 2;
3625
+ //this is fix-injective because 17=10+2+4+1 with different numbers of addens.
3626
+ list fix_inj = 1,2,4,10,17;
3627
+ //this is not fix-injective because 4+1=2+3.
3628
+ list not_fix_inj = 1,2,3,4;
3629
+ is_fix_injective(fix_inj);
3630
+ is_fix_injective(not_fix_inj);
3631
+ }
3632
+
3633
+ proc three_elements(list out, int iterations)
3634
+ "USAGE: three_elements(out, iterations)
3635
+ RETURN: Injective_knapsack created with the three elements method
3636
+ EXAMPLE: three_elements; shows an example;
3637
+ "
3638
+ {
3639
+ int a;
3640
+ int b;
3641
+ int c;
3642
+ int subsum;
3643
+ int adden = 1;
3644
+ int condition = 0;
3645
+ out = set_turn(out);
3646
+ if (set_is_injective(out)==0)
3647
+ {
3648
+ return(0);
3649
+ }
3650
+ else
3651
+ {
3652
+ for (int i=1; i<=iterations; i++)
3653
+ {
3654
+ while(condition==0)
3655
+ {
3656
+ subsum = calculate_max_sum(out);
3657
+ a = 2*subsum+adden;
3658
+ b = a+subsum+adden;
3659
+ c = b+subsum+1;
3660
+ if ((a+b)>(c+subsum))
3661
+ {
3662
+ condition=1;
3663
+ }
3664
+ else
3665
+ {
3666
+ adden++;
3667
+ }
3668
+ }
3669
+ adden =1;
3670
+ condition=0;
3671
+ out=set_insert(out, a);
3672
+ out=set_insert(out, b);
3673
+ out=set_insert(out, c);
3674
+ }
3675
+ return(out);
3676
+ }
3677
+ }
3678
+ example
3679
+ {
3680
+ "EXAMPLE:"; echo = 2;
3681
+ //this is fix-injective because 17=10+2+4+1 with different numbers of addens.
3682
+ list super_increasing = 1,2,4,10,20;
3683
+ list a = three_elements(super_increasing,2);
3684
+ a;
3685
+ set_is_injective(a);
3686
+ }
3687
+ /*
3688
+ //===============================================================
3689
+ //======= Example for DSA =====================================
3690
+ //===============================================================
3691
+ Suppose a file test is given.It contains "Oscar".
3692
+
3693
+ //Hash-function MD5 under Linux
3694
+
3695
+ md5sum test 8edfe37dae96cfd2466d77d3884d4196
3696
+
3697
+ //================================================================
3698
+
3699
+ ring R=0,x,dp;
3700
+
3701
+ number q=2^19+21; //524309
3702
+ number o=2*3*23*number(7883)*number(16170811);
3703
+
3704
+ number p=o*q+1; //9223372036869000547
3705
+ number b=2;
3706
+ number g=power(2,o,p); //8308467587808723131
3707
+
3708
+ number a=111111;
3709
+ number A=power(g,a,p); //8566038811843553785
3710
+
3711
+ number h =decimal("8edfe37dae96cfd2466d77d3884d4196");
3712
+
3713
+ //189912871665444375716340628395668619670
3714
+ h= h mod q; //259847
3715
+
3716
+ number k=123456;
3717
+
3718
+ number ki=exgcd(k,q)[1]; //50804
3719
+ //inverse von k mod q
3720
+
3721
+ number r= power(g,k,p) mod q; //76646
3722
+
3723
+ number s=ki*(h+a*r) mod q; //2065
3724
+
3725
+ //========== signature is (r,s)=(76646,2065) ====================
3726
+ //==================== verification ============================
3727
+
3728
+ number si=exgcd(s,q)[1]; //inverse von s mod q
3729
+ number e1=si*h mod q;
3730
+ number e2=si*r mod q;
3731
+ number rr=((power(g,e1,p)*power(A,e2,p)) mod p) mod q; //76646
3732
+
3733
+ //===============================================================
3734
+ //======= Example for knapsack ================================
3735
+ //===============================================================
3736
+ ring R=(5^5,t),x,dp;
3737
+ R;
3738
+ // # ground field : 3125
3739
+ // primitive element : t
3740
+ // minpoly : 1*t^5+4*t^1+2*t^0
3741
+ // number of vars : 1
3742
+ // block 1 : ordering dp
3743
+ // : names x
3744
+ // block 2 : ordering C
3745
+
3746
+ proc findEx(number n, number g)
3747
+ {
3748
+ int i;
3749
+ for(i=0;i<=size(basering)-1;i++)
3750
+ {
3751
+ if(g^i==n){return(i);}
3752
+ }
3753
+ }
3754
+
3755
+ number g=t^3; //choice of the primitive root
3756
+
3757
+ findEx(t+1,g);
3758
+ //2091
3759
+ findEx(t+2,g);
3760
+ //2291
3761
+ findEx(t+3,g);
3762
+ //1043
3763
+
3764
+ intvec b=1,2091,2291,1043; // k=4
3765
+ int z=199;
3766
+ intvec v=1043+z,1+z,2091+z,2291+z; //permutation pi=(0123)
3767
+ v;
3768
+ 1242,200,2290,2490
3769
+
3770
+ //(1101)=(e_3,e_2,e_1,e_0)
3771
+ //encoding 2490+2290+1242=6022 und 1+1+0+1=3
3772
+
3773
+ //(6022,3) decoding: c-z*c'=6022-199*3=5425
3774
+
3775
+ ring S=5,x,dp;
3776
+ poly F=x5+4x+2;
3777
+ poly G=reduce((x^3)^5425,std(F));
3778
+ G;
3779
+ //x3+x2+x+1
3780
+
3781
+ factorize(G);
3782
+ //[1]:
3783
+ // _[1]=1
3784
+ // _[2]=x+1
3785
+ // _[3]=x-2
3786
+ // _[4]=x+2
3787
+ //[2]:
3788
+ // 1,1,1,1
3789
+
3790
+ //factors x+1,x+2,x+3, i.e. (1110)=(e_pi(3),e_pi(2),e_pi(1),e_pi(0))
3791
+
3792
+ //pi(0)=1,pi(1)=2,pi(2)=3,pi(3)=0 gives: (1101)
3793
+
3794
+ */
3795
+