passagemath-singular 10.6.31rc3__cp314-cp314-manylinux_2_27_aarch64.manylinux_2_28_aarch64.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.
- PySingular.cpython-314-aarch64-linux-gnu.so +0 -0
- passagemath_singular-10.6.31rc3.dist-info/METADATA +183 -0
- passagemath_singular-10.6.31rc3.dist-info/RECORD +490 -0
- passagemath_singular-10.6.31rc3.dist-info/WHEEL +6 -0
- passagemath_singular-10.6.31rc3.dist-info/top_level.txt +3 -0
- passagemath_singular.libs/libSingular-4-6a2a8666.4.1.so +0 -0
- passagemath_singular.libs/libcddgmp-ac579979.so.0.1.3 +0 -0
- passagemath_singular.libs/libfactory-4-66e33516.4.1.so +0 -0
- passagemath_singular.libs/libflint-81de1160.so.21.0.0 +0 -0
- passagemath_singular.libs/libgf2x-fbd36f80.so.3.0.0 +0 -0
- passagemath_singular.libs/libgfortran-e1b7dfc8.so.5.0.0 +0 -0
- passagemath_singular.libs/libgmp-93ebf16a.so.10.5.0 +0 -0
- passagemath_singular.libs/libgsl-e3525837.so.28.0.0 +0 -0
- passagemath_singular.libs/libmpfr-e0f11cf3.so.6.2.1 +0 -0
- passagemath_singular.libs/libntl-0043a3a2.so.44.0.1 +0 -0
- passagemath_singular.libs/libomalloc-0-06512335.9.6.so +0 -0
- passagemath_singular.libs/libopenblasp-r0-4c5b64b1.3.29.so +0 -0
- passagemath_singular.libs/libpolys-4-cb7246b5.4.1.so +0 -0
- passagemath_singular.libs/libreadline-28330744.so.8.2 +0 -0
- passagemath_singular.libs/libsingular_resources-4-8c425241.4.1.so +0 -0
- passagemath_singular.libs/libtinfo-f81c2d16.so.6.3 +0 -0
- sage/algebras/all__sagemath_singular.py +3 -0
- sage/algebras/fusion_rings/all.py +19 -0
- sage/algebras/fusion_rings/f_matrix.py +2448 -0
- sage/algebras/fusion_rings/fast_parallel_fmats_methods.cpython-314-aarch64-linux-gnu.so +0 -0
- sage/algebras/fusion_rings/fast_parallel_fmats_methods.pxd +5 -0
- sage/algebras/fusion_rings/fast_parallel_fmats_methods.pyx +538 -0
- sage/algebras/fusion_rings/fast_parallel_fusion_ring_braid_repn.cpython-314-aarch64-linux-gnu.so +0 -0
- sage/algebras/fusion_rings/fast_parallel_fusion_ring_braid_repn.pxd +3 -0
- sage/algebras/fusion_rings/fast_parallel_fusion_ring_braid_repn.pyx +331 -0
- sage/algebras/fusion_rings/fusion_double.py +899 -0
- sage/algebras/fusion_rings/fusion_ring.py +1580 -0
- sage/algebras/fusion_rings/poly_tup_engine.cpython-314-aarch64-linux-gnu.so +0 -0
- sage/algebras/fusion_rings/poly_tup_engine.pxd +24 -0
- sage/algebras/fusion_rings/poly_tup_engine.pyx +579 -0
- sage/algebras/fusion_rings/shm_managers.cpython-314-aarch64-linux-gnu.so +0 -0
- sage/algebras/fusion_rings/shm_managers.pxd +24 -0
- sage/algebras/fusion_rings/shm_managers.pyx +780 -0
- sage/algebras/letterplace/all.py +1 -0
- sage/algebras/letterplace/free_algebra_element_letterplace.cpython-314-aarch64-linux-gnu.so +0 -0
- sage/algebras/letterplace/free_algebra_element_letterplace.pxd +18 -0
- sage/algebras/letterplace/free_algebra_element_letterplace.pyx +755 -0
- sage/algebras/letterplace/free_algebra_letterplace.cpython-314-aarch64-linux-gnu.so +0 -0
- sage/algebras/letterplace/free_algebra_letterplace.pxd +35 -0
- sage/algebras/letterplace/free_algebra_letterplace.pyx +914 -0
- sage/algebras/letterplace/letterplace_ideal.cpython-314-aarch64-linux-gnu.so +0 -0
- sage/algebras/letterplace/letterplace_ideal.pyx +408 -0
- sage/algebras/quatalg/all.py +2 -0
- sage/algebras/quatalg/quaternion_algebra.py +4778 -0
- sage/algebras/quatalg/quaternion_algebra_cython.cpython-314-aarch64-linux-gnu.so +0 -0
- sage/algebras/quatalg/quaternion_algebra_cython.pyx +261 -0
- sage/algebras/quatalg/quaternion_algebra_element.cpython-314-aarch64-linux-gnu.so +0 -0
- sage/algebras/quatalg/quaternion_algebra_element.pxd +29 -0
- sage/algebras/quatalg/quaternion_algebra_element.pyx +2176 -0
- sage/all__sagemath_singular.py +11 -0
- sage/ext_data/all__sagemath_singular.py +1 -0
- sage/ext_data/singular/function_field/core.lib +98 -0
- sage/interfaces/all__sagemath_singular.py +1 -0
- sage/interfaces/singular.py +2835 -0
- sage/libs/all__sagemath_singular.py +1 -0
- sage/libs/singular/__init__.py +1 -0
- sage/libs/singular/decl.pxd +1168 -0
- sage/libs/singular/function.cpython-314-aarch64-linux-gnu.so +0 -0
- sage/libs/singular/function.pxd +87 -0
- sage/libs/singular/function.pyx +1901 -0
- sage/libs/singular/function_factory.py +61 -0
- sage/libs/singular/groebner_strategy.cpython-314-aarch64-linux-gnu.so +0 -0
- sage/libs/singular/groebner_strategy.pxd +22 -0
- sage/libs/singular/groebner_strategy.pyx +582 -0
- sage/libs/singular/option.cpython-314-aarch64-linux-gnu.so +0 -0
- sage/libs/singular/option.pyx +671 -0
- sage/libs/singular/polynomial.cpython-314-aarch64-linux-gnu.so +0 -0
- sage/libs/singular/polynomial.pxd +39 -0
- sage/libs/singular/polynomial.pyx +661 -0
- sage/libs/singular/ring.cpython-314-aarch64-linux-gnu.so +0 -0
- sage/libs/singular/ring.pxd +58 -0
- sage/libs/singular/ring.pyx +893 -0
- sage/libs/singular/singular.cpython-314-aarch64-linux-gnu.so +0 -0
- sage/libs/singular/singular.pxd +72 -0
- sage/libs/singular/singular.pyx +1944 -0
- sage/libs/singular/standard_options.py +145 -0
- sage/matrix/all__sagemath_singular.py +1 -0
- sage/matrix/matrix_mpolynomial_dense.cpython-314-aarch64-linux-gnu.so +0 -0
- sage/matrix/matrix_mpolynomial_dense.pxd +7 -0
- sage/matrix/matrix_mpolynomial_dense.pyx +615 -0
- sage/rings/all__sagemath_singular.py +1 -0
- sage/rings/function_field/all__sagemath_singular.py +1 -0
- sage/rings/function_field/derivations_polymod.py +911 -0
- sage/rings/function_field/element_polymod.cpython-314-aarch64-linux-gnu.so +0 -0
- sage/rings/function_field/element_polymod.pyx +406 -0
- sage/rings/function_field/function_field_polymod.py +2611 -0
- sage/rings/function_field/ideal_polymod.py +1775 -0
- sage/rings/function_field/order_polymod.py +1475 -0
- sage/rings/function_field/place_polymod.py +681 -0
- sage/rings/polynomial/all__sagemath_singular.py +1 -0
- sage/rings/polynomial/multi_polynomial_ideal_libsingular.cpython-314-aarch64-linux-gnu.so +0 -0
- sage/rings/polynomial/multi_polynomial_ideal_libsingular.pxd +5 -0
- sage/rings/polynomial/multi_polynomial_ideal_libsingular.pyx +339 -0
- sage/rings/polynomial/multi_polynomial_libsingular.cpython-314-aarch64-linux-gnu.so +0 -0
- sage/rings/polynomial/multi_polynomial_libsingular.pxd +30 -0
- sage/rings/polynomial/multi_polynomial_libsingular.pyx +6277 -0
- sage/rings/polynomial/plural.cpython-314-aarch64-linux-gnu.so +0 -0
- sage/rings/polynomial/plural.pxd +48 -0
- sage/rings/polynomial/plural.pyx +3171 -0
- sage/symbolic/all__sagemath_singular.py +1 -0
- sage/symbolic/comparison_impl.pxi +428 -0
- sage/symbolic/constants_c_impl.pxi +178 -0
- sage/symbolic/expression.cpython-314-aarch64-linux-gnu.so +0 -0
- sage/symbolic/expression.pxd +7 -0
- sage/symbolic/expression.pyx +14200 -0
- sage/symbolic/getitem_impl.pxi +202 -0
- sage/symbolic/pynac.pxi +572 -0
- sage/symbolic/pynac_constant_impl.pxi +133 -0
- sage/symbolic/pynac_function_impl.pxi +206 -0
- sage/symbolic/pynac_impl.pxi +2576 -0
- sage/symbolic/pynac_wrap.h +124 -0
- sage/symbolic/series_impl.pxi +272 -0
- sage/symbolic/substitution_map_impl.pxi +94 -0
- sage_wheels/bin/ESingular +0 -0
- sage_wheels/bin/Singular +0 -0
- sage_wheels/bin/TSingular +0 -0
- sage_wheels/lib/singular/MOD/cohomo.la +41 -0
- sage_wheels/lib/singular/MOD/cohomo.so +0 -0
- sage_wheels/lib/singular/MOD/customstd.la +41 -0
- sage_wheels/lib/singular/MOD/customstd.so +0 -0
- sage_wheels/lib/singular/MOD/freealgebra.la +41 -0
- sage_wheels/lib/singular/MOD/freealgebra.so +0 -0
- sage_wheels/lib/singular/MOD/gfanlib.la +41 -0
- sage_wheels/lib/singular/MOD/gfanlib.so +0 -0
- sage_wheels/lib/singular/MOD/gitfan.la +41 -0
- sage_wheels/lib/singular/MOD/gitfan.so +0 -0
- sage_wheels/lib/singular/MOD/interval.la +41 -0
- sage_wheels/lib/singular/MOD/interval.so +0 -0
- sage_wheels/lib/singular/MOD/loctriv.la +41 -0
- sage_wheels/lib/singular/MOD/loctriv.so +0 -0
- sage_wheels/lib/singular/MOD/machinelearning.la +41 -0
- sage_wheels/lib/singular/MOD/machinelearning.so +0 -0
- sage_wheels/lib/singular/MOD/p_Procs_FieldGeneral.la +41 -0
- sage_wheels/lib/singular/MOD/p_Procs_FieldGeneral.so +0 -0
- sage_wheels/lib/singular/MOD/p_Procs_FieldIndep.la +41 -0
- sage_wheels/lib/singular/MOD/p_Procs_FieldIndep.so +0 -0
- sage_wheels/lib/singular/MOD/p_Procs_FieldQ.la +41 -0
- sage_wheels/lib/singular/MOD/p_Procs_FieldQ.so +0 -0
- sage_wheels/lib/singular/MOD/p_Procs_FieldZp.la +41 -0
- sage_wheels/lib/singular/MOD/p_Procs_FieldZp.so +0 -0
- sage_wheels/lib/singular/MOD/partialgb.la +41 -0
- sage_wheels/lib/singular/MOD/partialgb.so +0 -0
- sage_wheels/lib/singular/MOD/pyobject.la +41 -0
- sage_wheels/lib/singular/MOD/pyobject.so +0 -0
- sage_wheels/lib/singular/MOD/singmathic.la +41 -0
- sage_wheels/lib/singular/MOD/singmathic.so +0 -0
- sage_wheels/lib/singular/MOD/sispasm.la +41 -0
- sage_wheels/lib/singular/MOD/sispasm.so +0 -0
- sage_wheels/lib/singular/MOD/subsets.la +41 -0
- sage_wheels/lib/singular/MOD/subsets.so +0 -0
- sage_wheels/lib/singular/MOD/systhreads.la +41 -0
- sage_wheels/lib/singular/MOD/systhreads.so +0 -0
- sage_wheels/lib/singular/MOD/syzextra.la +41 -0
- sage_wheels/lib/singular/MOD/syzextra.so +0 -0
- sage_wheels/libexec/singular/MOD/change_cost +0 -0
- sage_wheels/libexec/singular/MOD/singularsurf +11 -0
- sage_wheels/libexec/singular/MOD/singularsurf_jupyter +9 -0
- sage_wheels/libexec/singular/MOD/singularsurf_win +10 -0
- sage_wheels/libexec/singular/MOD/solve_IP +0 -0
- sage_wheels/libexec/singular/MOD/surfex +16 -0
- sage_wheels/libexec/singular/MOD/toric_ideal +0 -0
- sage_wheels/share/factory/gftables/10201 +342 -0
- sage_wheels/share/factory/gftables/1024 +37 -0
- sage_wheels/share/factory/gftables/10609 +356 -0
- sage_wheels/share/factory/gftables/11449 +384 -0
- sage_wheels/share/factory/gftables/11881 +398 -0
- sage_wheels/share/factory/gftables/121 +6 -0
- sage_wheels/share/factory/gftables/12167 +408 -0
- sage_wheels/share/factory/gftables/125 +7 -0
- sage_wheels/share/factory/gftables/12769 +428 -0
- sage_wheels/share/factory/gftables/128 +7 -0
- sage_wheels/share/factory/gftables/1331 +47 -0
- sage_wheels/share/factory/gftables/1369 +48 -0
- sage_wheels/share/factory/gftables/14641 +490 -0
- sage_wheels/share/factory/gftables/15625 +523 -0
- sage_wheels/share/factory/gftables/16 +3 -0
- sage_wheels/share/factory/gftables/16129 +540 -0
- sage_wheels/share/factory/gftables/16384 +549 -0
- sage_wheels/share/factory/gftables/16807 +563 -0
- sage_wheels/share/factory/gftables/1681 +58 -0
- sage_wheels/share/factory/gftables/169 +8 -0
- sage_wheels/share/factory/gftables/17161 +574 -0
- sage_wheels/share/factory/gftables/1849 +64 -0
- sage_wheels/share/factory/gftables/18769 +628 -0
- sage_wheels/share/factory/gftables/19321 +646 -0
- sage_wheels/share/factory/gftables/19683 +659 -0
- sage_wheels/share/factory/gftables/2048 +71 -0
- sage_wheels/share/factory/gftables/2187 +75 -0
- sage_wheels/share/factory/gftables/2197 +76 -0
- sage_wheels/share/factory/gftables/2209 +76 -0
- sage_wheels/share/factory/gftables/22201 +742 -0
- sage_wheels/share/factory/gftables/22801 +762 -0
- sage_wheels/share/factory/gftables/2401 +82 -0
- sage_wheels/share/factory/gftables/243 +11 -0
- sage_wheels/share/factory/gftables/24389 +815 -0
- sage_wheels/share/factory/gftables/24649 +824 -0
- sage_wheels/share/factory/gftables/25 +3 -0
- sage_wheels/share/factory/gftables/256 +11 -0
- sage_wheels/share/factory/gftables/26569 +888 -0
- sage_wheels/share/factory/gftables/27 +3 -0
- sage_wheels/share/factory/gftables/27889 +932 -0
- sage_wheels/share/factory/gftables/2809 +96 -0
- sage_wheels/share/factory/gftables/28561 +954 -0
- sage_wheels/share/factory/gftables/289 +12 -0
- sage_wheels/share/factory/gftables/29791 +995 -0
- sage_wheels/share/factory/gftables/29929 +1000 -0
- sage_wheels/share/factory/gftables/3125 +107 -0
- sage_wheels/share/factory/gftables/32 +4 -0
- sage_wheels/share/factory/gftables/32041 +1070 -0
- sage_wheels/share/factory/gftables/32761 +1094 -0
- sage_wheels/share/factory/gftables/32768 +1095 -0
- sage_wheels/share/factory/gftables/343 +14 -0
- sage_wheels/share/factory/gftables/3481 +118 -0
- sage_wheels/share/factory/gftables/361 +14 -0
- sage_wheels/share/factory/gftables/36481 +1218 -0
- sage_wheels/share/factory/gftables/3721 +126 -0
- sage_wheels/share/factory/gftables/37249 +1244 -0
- sage_wheels/share/factory/gftables/38809 +1296 -0
- sage_wheels/share/factory/gftables/39601 +1322 -0
- sage_wheels/share/factory/gftables/4 +3 -0
- sage_wheels/share/factory/gftables/4096 +139 -0
- sage_wheels/share/factory/gftables/44521 +1486 -0
- sage_wheels/share/factory/gftables/4489 +152 -0
- sage_wheels/share/factory/gftables/49 +4 -0
- sage_wheels/share/factory/gftables/4913 +166 -0
- sage_wheels/share/factory/gftables/49729 +1660 -0
- sage_wheels/share/factory/gftables/5041 +170 -0
- sage_wheels/share/factory/gftables/50653 +1691 -0
- sage_wheels/share/factory/gftables/512 +20 -0
- sage_wheels/share/factory/gftables/51529 +1720 -0
- sage_wheels/share/factory/gftables/52441 +1750 -0
- sage_wheels/share/factory/gftables/529 +20 -0
- sage_wheels/share/factory/gftables/5329 +180 -0
- sage_wheels/share/factory/gftables/54289 +1812 -0
- sage_wheels/share/factory/gftables/57121 +1906 -0
- sage_wheels/share/factory/gftables/58081 +1938 -0
- sage_wheels/share/factory/gftables/59049 +1971 -0
- sage_wheels/share/factory/gftables/6241 +210 -0
- sage_wheels/share/factory/gftables/625 +23 -0
- sage_wheels/share/factory/gftables/63001 +2102 -0
- sage_wheels/share/factory/gftables/64 +5 -0
- sage_wheels/share/factory/gftables/6561 +221 -0
- sage_wheels/share/factory/gftables/6859 +231 -0
- sage_wheels/share/factory/gftables/6889 +232 -0
- sage_wheels/share/factory/gftables/729 +27 -0
- sage_wheels/share/factory/gftables/7921 +266 -0
- sage_wheels/share/factory/gftables/8 +3 -0
- sage_wheels/share/factory/gftables/81 +5 -0
- sage_wheels/share/factory/gftables/8192 +276 -0
- sage_wheels/share/factory/gftables/841 +30 -0
- sage_wheels/share/factory/gftables/9 +3 -0
- sage_wheels/share/factory/gftables/9409 +316 -0
- sage_wheels/share/factory/gftables/961 +34 -0
- sage_wheels/share/info/singular.info +191898 -0
- sage_wheels/share/singular/LIB/GND.lib +1359 -0
- sage_wheels/share/singular/LIB/JMBTest.lib +976 -0
- sage_wheels/share/singular/LIB/JMSConst.lib +1363 -0
- sage_wheels/share/singular/LIB/KVequiv.lib +699 -0
- sage_wheels/share/singular/LIB/SingularityDBM.lib +491 -0
- sage_wheels/share/singular/LIB/VecField.lib +1542 -0
- sage_wheels/share/singular/LIB/absfact.lib +959 -0
- sage_wheels/share/singular/LIB/ainvar.lib +730 -0
- sage_wheels/share/singular/LIB/aksaka.lib +419 -0
- sage_wheels/share/singular/LIB/alexpoly.lib +2542 -0
- sage_wheels/share/singular/LIB/algebra.lib +1193 -0
- sage_wheels/share/singular/LIB/all.lib +136 -0
- sage_wheels/share/singular/LIB/arcpoint.lib +514 -0
- sage_wheels/share/singular/LIB/arnold.lib +4553 -0
- sage_wheels/share/singular/LIB/arnoldclassify.lib +2058 -0
- sage_wheels/share/singular/LIB/arr.lib +3486 -0
- sage_wheels/share/singular/LIB/assprimeszerodim.lib +755 -0
- sage_wheels/share/singular/LIB/autgradalg.lib +3361 -0
- sage_wheels/share/singular/LIB/bfun.lib +1964 -0
- sage_wheels/share/singular/LIB/bimodules.lib +774 -0
- sage_wheels/share/singular/LIB/brillnoether.lib +226 -0
- sage_wheels/share/singular/LIB/brnoeth.lib +5017 -0
- sage_wheels/share/singular/LIB/central.lib +2169 -0
- sage_wheels/share/singular/LIB/chern.lib +4162 -0
- sage_wheels/share/singular/LIB/cimonom.lib +571 -0
- sage_wheels/share/singular/LIB/cisimplicial.lib +1835 -0
- sage_wheels/share/singular/LIB/classify.lib +3239 -0
- sage_wheels/share/singular/LIB/classify2.lib +1462 -0
- sage_wheels/share/singular/LIB/classifyMapGerms.lib +1515 -0
- sage_wheels/share/singular/LIB/classify_aeq.lib +3253 -0
- sage_wheels/share/singular/LIB/classifyceq.lib +2092 -0
- sage_wheels/share/singular/LIB/classifyci.lib +1133 -0
- sage_wheels/share/singular/LIB/combinat.lib +91 -0
- sage_wheels/share/singular/LIB/compregb.lib +276 -0
- sage_wheels/share/singular/LIB/control.lib +1636 -0
- sage_wheels/share/singular/LIB/crypto.lib +3795 -0
- sage_wheels/share/singular/LIB/curveInv.lib +667 -0
- sage_wheels/share/singular/LIB/curvepar.lib +1817 -0
- sage_wheels/share/singular/LIB/customstd.lib +100 -0
- sage_wheels/share/singular/LIB/deRham.lib +5979 -0
- sage_wheels/share/singular/LIB/decodegb.lib +2134 -0
- sage_wheels/share/singular/LIB/decomp.lib +1655 -0
- sage_wheels/share/singular/LIB/deflation.lib +872 -0
- sage_wheels/share/singular/LIB/deform.lib +925 -0
- sage_wheels/share/singular/LIB/difform.lib +3055 -0
- sage_wheels/share/singular/LIB/divisors.lib +750 -0
- sage_wheels/share/singular/LIB/dmod.lib +5817 -0
- sage_wheels/share/singular/LIB/dmodapp.lib +3269 -0
- sage_wheels/share/singular/LIB/dmodideal.lib +1211 -0
- sage_wheels/share/singular/LIB/dmodloc.lib +2645 -0
- sage_wheels/share/singular/LIB/dmodvar.lib +818 -0
- sage_wheels/share/singular/LIB/dummy.lib +17 -0
- sage_wheels/share/singular/LIB/elim.lib +1009 -0
- sage_wheels/share/singular/LIB/ellipticcovers.lib +548 -0
- sage_wheels/share/singular/LIB/enumpoints.lib +146 -0
- sage_wheels/share/singular/LIB/equising.lib +2127 -0
- sage_wheels/share/singular/LIB/ffmodstd.lib +2384 -0
- sage_wheels/share/singular/LIB/ffsolve.lib +1289 -0
- sage_wheels/share/singular/LIB/findifs.lib +778 -0
- sage_wheels/share/singular/LIB/finitediff.lib +1768 -0
- sage_wheels/share/singular/LIB/finvar.lib +7989 -0
- sage_wheels/share/singular/LIB/fpadim.lib +2429 -0
- sage_wheels/share/singular/LIB/fpalgebras.lib +1666 -0
- sage_wheels/share/singular/LIB/fpaprops.lib +1462 -0
- sage_wheels/share/singular/LIB/freegb.lib +3853 -0
- sage_wheels/share/singular/LIB/general.lib +1350 -0
- sage_wheels/share/singular/LIB/gfan.lib +1768 -0
- sage_wheels/share/singular/LIB/gitfan.lib +3130 -0
- sage_wheels/share/singular/LIB/gkdim.lib +99 -0
- sage_wheels/share/singular/LIB/gmspoly.lib +589 -0
- sage_wheels/share/singular/LIB/gmssing.lib +1739 -0
- sage_wheels/share/singular/LIB/goettsche.lib +909 -0
- sage_wheels/share/singular/LIB/graal.lib +1366 -0
- sage_wheels/share/singular/LIB/gradedModules.lib +2541 -0
- sage_wheels/share/singular/LIB/graphics.lib +360 -0
- sage_wheels/share/singular/LIB/grobcov.lib +7706 -0
- sage_wheels/share/singular/LIB/groups.lib +1123 -0
- sage_wheels/share/singular/LIB/grwalk.lib +507 -0
- sage_wheels/share/singular/LIB/hdepth.lib +194 -0
- sage_wheels/share/singular/LIB/help.cnf +57 -0
- sage_wheels/share/singular/LIB/hess.lib +1946 -0
- sage_wheels/share/singular/LIB/hnoether.lib +4292 -0
- sage_wheels/share/singular/LIB/hodge.lib +400 -0
- sage_wheels/share/singular/LIB/homolog.lib +1965 -0
- sage_wheels/share/singular/LIB/hyperel.lib +975 -0
- sage_wheels/share/singular/LIB/inout.lib +679 -0
- sage_wheels/share/singular/LIB/integralbasis.lib +6224 -0
- sage_wheels/share/singular/LIB/interval.lib +1418 -0
- sage_wheels/share/singular/LIB/intprog.lib +778 -0
- sage_wheels/share/singular/LIB/invar.lib +443 -0
- sage_wheels/share/singular/LIB/involut.lib +980 -0
- sage_wheels/share/singular/LIB/jacobson.lib +1215 -0
- sage_wheels/share/singular/LIB/kskernel.lib +534 -0
- sage_wheels/share/singular/LIB/latex.lib +3146 -0
- sage_wheels/share/singular/LIB/lejeune.lib +651 -0
- sage_wheels/share/singular/LIB/linalg.lib +2040 -0
- sage_wheels/share/singular/LIB/locnormal.lib +212 -0
- sage_wheels/share/singular/LIB/lrcalc.lib +526 -0
- sage_wheels/share/singular/LIB/makedbm.lib +294 -0
- sage_wheels/share/singular/LIB/mathml.lib +813 -0
- sage_wheels/share/singular/LIB/matrix.lib +1372 -0
- sage_wheels/share/singular/LIB/maxlike.lib +1132 -0
- sage_wheels/share/singular/LIB/methods.lib +212 -0
- sage_wheels/share/singular/LIB/moddiq.lib +322 -0
- sage_wheels/share/singular/LIB/modfinduni.lib +181 -0
- sage_wheels/share/singular/LIB/modnormal.lib +218 -0
- sage_wheels/share/singular/LIB/modprimdec.lib +1278 -0
- sage_wheels/share/singular/LIB/modquotient.lib +269 -0
- sage_wheels/share/singular/LIB/modstd.lib +1024 -0
- sage_wheels/share/singular/LIB/modular.lib +545 -0
- sage_wheels/share/singular/LIB/modules.lib +2561 -0
- sage_wheels/share/singular/LIB/modwalk.lib +609 -0
- sage_wheels/share/singular/LIB/mondromy.lib +1016 -0
- sage_wheels/share/singular/LIB/monomialideal.lib +3851 -0
- sage_wheels/share/singular/LIB/mprimdec.lib +2353 -0
- sage_wheels/share/singular/LIB/mregular.lib +1863 -0
- sage_wheels/share/singular/LIB/multigrading.lib +5629 -0
- sage_wheels/share/singular/LIB/ncHilb.lib +777 -0
- sage_wheels/share/singular/LIB/ncModslimgb.lib +791 -0
- sage_wheels/share/singular/LIB/ncalg.lib +16311 -0
- sage_wheels/share/singular/LIB/ncall.lib +31 -0
- sage_wheels/share/singular/LIB/ncdecomp.lib +468 -0
- sage_wheels/share/singular/LIB/ncfactor.lib +13371 -0
- sage_wheels/share/singular/LIB/ncfrac.lib +1023 -0
- sage_wheels/share/singular/LIB/nchilbert.lib +448 -0
- sage_wheels/share/singular/LIB/nchomolog.lib +759 -0
- sage_wheels/share/singular/LIB/ncloc.lib +361 -0
- sage_wheels/share/singular/LIB/ncpreim.lib +795 -0
- sage_wheels/share/singular/LIB/ncrat.lib +2849 -0
- sage_wheels/share/singular/LIB/nctools.lib +1887 -0
- sage_wheels/share/singular/LIB/nets.lib +1456 -0
- sage_wheels/share/singular/LIB/nfmodstd.lib +1000 -0
- sage_wheels/share/singular/LIB/nfmodsyz.lib +732 -0
- sage_wheels/share/singular/LIB/noether.lib +1106 -0
- sage_wheels/share/singular/LIB/normal.lib +8700 -0
- sage_wheels/share/singular/LIB/normaliz.lib +2226 -0
- sage_wheels/share/singular/LIB/ntsolve.lib +362 -0
- sage_wheels/share/singular/LIB/numerAlg.lib +560 -0
- sage_wheels/share/singular/LIB/numerDecom.lib +2261 -0
- sage_wheels/share/singular/LIB/olga.lib +1933 -0
- sage_wheels/share/singular/LIB/orbitparam.lib +351 -0
- sage_wheels/share/singular/LIB/parallel.lib +319 -0
- sage_wheels/share/singular/LIB/paraplanecurves.lib +3110 -0
- sage_wheels/share/singular/LIB/perron.lib +202 -0
- sage_wheels/share/singular/LIB/pfd.lib +2223 -0
- sage_wheels/share/singular/LIB/phindex.lib +642 -0
- sage_wheels/share/singular/LIB/pointid.lib +673 -0
- sage_wheels/share/singular/LIB/polybori.lib +1430 -0
- sage_wheels/share/singular/LIB/polyclass.lib +525 -0
- sage_wheels/share/singular/LIB/polylib.lib +1174 -0
- sage_wheels/share/singular/LIB/polymake.lib +1902 -0
- sage_wheels/share/singular/LIB/presolve.lib +1533 -0
- sage_wheels/share/singular/LIB/primdec.lib +9576 -0
- sage_wheels/share/singular/LIB/primdecint.lib +1782 -0
- sage_wheels/share/singular/LIB/primitiv.lib +401 -0
- sage_wheels/share/singular/LIB/puiseuxexpansions.lib +1631 -0
- sage_wheels/share/singular/LIB/purityfiltration.lib +960 -0
- sage_wheels/share/singular/LIB/qhmoduli.lib +1561 -0
- sage_wheels/share/singular/LIB/qmatrix.lib +293 -0
- sage_wheels/share/singular/LIB/random.lib +455 -0
- sage_wheels/share/singular/LIB/ratgb.lib +489 -0
- sage_wheels/share/singular/LIB/realclassify.lib +5759 -0
- sage_wheels/share/singular/LIB/realizationMatroids.lib +772 -0
- sage_wheels/share/singular/LIB/realrad.lib +1197 -0
- sage_wheels/share/singular/LIB/recover.lib +2628 -0
- sage_wheels/share/singular/LIB/redcgs.lib +3984 -0
- sage_wheels/share/singular/LIB/reesclos.lib +465 -0
- sage_wheels/share/singular/LIB/resbinomial.lib +2802 -0
- sage_wheels/share/singular/LIB/resgraph.lib +789 -0
- sage_wheels/share/singular/LIB/resjung.lib +820 -0
- sage_wheels/share/singular/LIB/resolve.lib +5110 -0
- sage_wheels/share/singular/LIB/resources.lib +170 -0
- sage_wheels/share/singular/LIB/reszeta.lib +5473 -0
- sage_wheels/share/singular/LIB/ring.lib +1328 -0
- sage_wheels/share/singular/LIB/ringgb.lib +343 -0
- sage_wheels/share/singular/LIB/rinvar.lib +1153 -0
- sage_wheels/share/singular/LIB/rootisolation.lib +1481 -0
- sage_wheels/share/singular/LIB/rootsmr.lib +709 -0
- sage_wheels/share/singular/LIB/rootsur.lib +886 -0
- sage_wheels/share/singular/LIB/rstandard.lib +607 -0
- sage_wheels/share/singular/LIB/rwalk.lib +336 -0
- sage_wheels/share/singular/LIB/sagbi.lib +1353 -0
- sage_wheels/share/singular/LIB/sagbiNormaliz.lib +1622 -0
- sage_wheels/share/singular/LIB/sagbiNormaliz0.lib +1498 -0
- sage_wheels/share/singular/LIB/sagbigrob.lib +449 -0
- sage_wheels/share/singular/LIB/schreyer.lib +321 -0
- sage_wheels/share/singular/LIB/schubert.lib +2551 -0
- sage_wheels/share/singular/LIB/sets.lib +524 -0
- sage_wheels/share/singular/LIB/sheafcoh.lib +1663 -0
- sage_wheels/share/singular/LIB/signcond.lib +437 -0
- sage_wheels/share/singular/LIB/sing.lib +1094 -0
- sage_wheels/share/singular/LIB/sing4ti2.lib +419 -0
- sage_wheels/share/singular/LIB/solve.lib +2243 -0
- sage_wheels/share/singular/LIB/spcurve.lib +1077 -0
- sage_wheels/share/singular/LIB/spectrum.lib +62 -0
- sage_wheels/share/singular/LIB/sresext.lib +757 -0
- sage_wheels/share/singular/LIB/ssi.lib +143 -0
- sage_wheels/share/singular/LIB/standard.lib +2769 -0
- sage_wheels/share/singular/LIB/stanleyreisner.lib +473 -0
- sage_wheels/share/singular/LIB/stdmodule.lib +547 -0
- sage_wheels/share/singular/LIB/stratify.lib +1070 -0
- sage_wheels/share/singular/LIB/surf.lib +506 -0
- sage_wheels/share/singular/LIB/surf_jupyter.lib +223 -0
- sage_wheels/share/singular/LIB/surfacesignature.lib +522 -0
- sage_wheels/share/singular/LIB/surfex.lib +1462 -0
- sage_wheels/share/singular/LIB/swalk.lib +877 -0
- sage_wheels/share/singular/LIB/symodstd.lib +1570 -0
- sage_wheels/share/singular/LIB/systhreads.lib +74 -0
- sage_wheels/share/singular/LIB/tasks.lib +1324 -0
- sage_wheels/share/singular/LIB/tateProdCplxNegGrad.lib +2412 -0
- sage_wheels/share/singular/LIB/teachstd.lib +858 -0
- sage_wheels/share/singular/LIB/template.lib +116 -0
- sage_wheels/share/singular/LIB/toric.lib +1119 -0
- sage_wheels/share/singular/LIB/transformation.lib +116 -0
- sage_wheels/share/singular/LIB/triang.lib +1197 -0
- sage_wheels/share/singular/LIB/tropical.lib +8741 -0
- sage_wheels/share/singular/LIB/tropicalEllipticCovers.lib +2922 -0
- sage_wheels/share/singular/LIB/tropicalNewton.lib +1128 -0
- sage_wheels/share/singular/LIB/tst.lib +1108 -0
- sage_wheels/share/singular/LIB/weierstr.lib +241 -0
- sage_wheels/share/singular/LIB/zeroset.lib +1478 -0
- sage_wheels/share/singular/emacs/.emacs-general +184 -0
- sage_wheels/share/singular/emacs/.emacs-singular +234 -0
- sage_wheels/share/singular/emacs/COPYING +44 -0
- sage_wheels/share/singular/emacs/cmd-cmpl.el +241 -0
- sage_wheels/share/singular/emacs/ex-cmpl.el +1681 -0
- sage_wheels/share/singular/emacs/hlp-cmpl.el +4318 -0
- sage_wheels/share/singular/emacs/lib-cmpl.el +179 -0
- sage_wheels/share/singular/emacs/singular.el +4273 -0
- sage_wheels/share/singular/emacs/singular.xpm +39 -0
- 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
|
+
|