passagemath-modules 10.6.31rc3__cp314-cp314-musllinux_1_2_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-modules might be problematic. Click here for more details.
- passagemath_modules-10.6.31rc3.dist-info/METADATA +281 -0
- passagemath_modules-10.6.31rc3.dist-info/RECORD +807 -0
- passagemath_modules-10.6.31rc3.dist-info/WHEEL +5 -0
- passagemath_modules-10.6.31rc3.dist-info/top_level.txt +2 -0
- passagemath_modules.libs/libgcc_s-2d945d6c.so.1 +0 -0
- passagemath_modules.libs/libgfortran-67378ab2.so.5.0.0 +0 -0
- passagemath_modules.libs/libgmp-28992bcb.so.10.5.0 +0 -0
- passagemath_modules.libs/libgsl-23768756.so.28.0.0 +0 -0
- passagemath_modules.libs/libmpc-7897025b.so.3.3.1 +0 -0
- passagemath_modules.libs/libmpfr-e34bb864.so.6.2.1 +0 -0
- passagemath_modules.libs/libopenblasp-r0-503f0c35.3.29.so +0 -0
- sage/algebras/all__sagemath_modules.py +20 -0
- sage/algebras/catalog.py +148 -0
- sage/algebras/clifford_algebra.py +3107 -0
- sage/algebras/clifford_algebra_element.cpython-314-aarch64-linux-musl.so +0 -0
- sage/algebras/clifford_algebra_element.pxd +16 -0
- sage/algebras/clifford_algebra_element.pyx +997 -0
- sage/algebras/commutative_dga.py +4252 -0
- sage/algebras/exterior_algebra_groebner.cpython-314-aarch64-linux-musl.so +0 -0
- sage/algebras/exterior_algebra_groebner.pxd +55 -0
- sage/algebras/exterior_algebra_groebner.pyx +727 -0
- sage/algebras/finite_dimensional_algebras/all.py +2 -0
- sage/algebras/finite_dimensional_algebras/finite_dimensional_algebra.py +1029 -0
- sage/algebras/finite_dimensional_algebras/finite_dimensional_algebra_element.cpython-314-aarch64-linux-musl.so +0 -0
- sage/algebras/finite_dimensional_algebras/finite_dimensional_algebra_element.pxd +12 -0
- sage/algebras/finite_dimensional_algebras/finite_dimensional_algebra_element.pyx +706 -0
- sage/algebras/finite_dimensional_algebras/finite_dimensional_algebra_ideal.py +196 -0
- sage/algebras/finite_dimensional_algebras/finite_dimensional_algebra_morphism.py +255 -0
- sage/algebras/finite_gca.py +528 -0
- sage/algebras/group_algebra.py +232 -0
- sage/algebras/lie_algebras/abelian.py +197 -0
- sage/algebras/lie_algebras/affine_lie_algebra.py +1213 -0
- sage/algebras/lie_algebras/all.py +25 -0
- sage/algebras/lie_algebras/all__sagemath_modules.py +1 -0
- sage/algebras/lie_algebras/bch.py +177 -0
- sage/algebras/lie_algebras/bgg_dual_module.py +1184 -0
- sage/algebras/lie_algebras/bgg_resolution.py +232 -0
- sage/algebras/lie_algebras/center_uea.py +767 -0
- sage/algebras/lie_algebras/classical_lie_algebra.py +2516 -0
- sage/algebras/lie_algebras/examples.py +683 -0
- sage/algebras/lie_algebras/free_lie_algebra.py +973 -0
- sage/algebras/lie_algebras/heisenberg.py +820 -0
- sage/algebras/lie_algebras/lie_algebra.py +1562 -0
- sage/algebras/lie_algebras/lie_algebra_element.cpython-314-aarch64-linux-musl.so +0 -0
- sage/algebras/lie_algebras/lie_algebra_element.pxd +68 -0
- sage/algebras/lie_algebras/lie_algebra_element.pyx +2122 -0
- sage/algebras/lie_algebras/morphism.py +661 -0
- sage/algebras/lie_algebras/nilpotent_lie_algebra.py +457 -0
- sage/algebras/lie_algebras/onsager.py +1324 -0
- sage/algebras/lie_algebras/poincare_birkhoff_witt.py +816 -0
- sage/algebras/lie_algebras/quotient.py +462 -0
- sage/algebras/lie_algebras/rank_two_heisenberg_virasoro.py +355 -0
- sage/algebras/lie_algebras/representation.py +1040 -0
- sage/algebras/lie_algebras/structure_coefficients.py +459 -0
- sage/algebras/lie_algebras/subalgebra.py +967 -0
- sage/algebras/lie_algebras/symplectic_derivation.py +289 -0
- sage/algebras/lie_algebras/verma_module.py +1630 -0
- sage/algebras/lie_algebras/virasoro.py +1186 -0
- sage/algebras/octonion_algebra.cpython-314-aarch64-linux-musl.so +0 -0
- sage/algebras/octonion_algebra.pxd +20 -0
- sage/algebras/octonion_algebra.pyx +987 -0
- sage/algebras/orlik_solomon.py +907 -0
- sage/algebras/orlik_terao.py +779 -0
- sage/algebras/steenrod/all.py +7 -0
- sage/algebras/steenrod/steenrod_algebra.py +4258 -0
- sage/algebras/steenrod/steenrod_algebra_bases.py +1179 -0
- sage/algebras/steenrod/steenrod_algebra_misc.py +1167 -0
- sage/algebras/steenrod/steenrod_algebra_mult.py +954 -0
- sage/algebras/weyl_algebra.py +1126 -0
- sage/all__sagemath_modules.py +62 -0
- sage/calculus/all__sagemath_modules.py +19 -0
- sage/calculus/expr.py +205 -0
- sage/calculus/integration.cpython-314-aarch64-linux-musl.so +0 -0
- sage/calculus/integration.pyx +698 -0
- sage/calculus/interpolation.cpython-314-aarch64-linux-musl.so +0 -0
- sage/calculus/interpolation.pxd +13 -0
- sage/calculus/interpolation.pyx +387 -0
- sage/calculus/interpolators.cpython-314-aarch64-linux-musl.so +0 -0
- sage/calculus/interpolators.pyx +326 -0
- sage/calculus/ode.cpython-314-aarch64-linux-musl.so +0 -0
- sage/calculus/ode.pxd +5 -0
- sage/calculus/ode.pyx +610 -0
- sage/calculus/riemann.cpython-314-aarch64-linux-musl.so +0 -0
- sage/calculus/riemann.pyx +1521 -0
- sage/calculus/test_sympy.py +201 -0
- sage/calculus/transforms/all.py +7 -0
- sage/calculus/transforms/dft.py +844 -0
- sage/calculus/transforms/dwt.cpython-314-aarch64-linux-musl.so +0 -0
- sage/calculus/transforms/dwt.pxd +7 -0
- sage/calculus/transforms/dwt.pyx +160 -0
- sage/calculus/transforms/fft.cpython-314-aarch64-linux-musl.so +0 -0
- sage/calculus/transforms/fft.pxd +12 -0
- sage/calculus/transforms/fft.pyx +487 -0
- sage/calculus/wester.py +662 -0
- sage/coding/abstract_code.py +1108 -0
- sage/coding/ag_code.py +868 -0
- sage/coding/ag_code_decoders.cpython-314-aarch64-linux-musl.so +0 -0
- sage/coding/ag_code_decoders.pyx +2639 -0
- sage/coding/all.py +15 -0
- sage/coding/bch_code.py +494 -0
- sage/coding/binary_code.cpython-314-aarch64-linux-musl.so +0 -0
- sage/coding/binary_code.pxd +124 -0
- sage/coding/binary_code.pyx +4139 -0
- sage/coding/bounds_catalog.py +43 -0
- sage/coding/channel.py +819 -0
- sage/coding/channels_catalog.py +29 -0
- sage/coding/code_bounds.py +755 -0
- sage/coding/code_constructions.py +804 -0
- sage/coding/codes_catalog.py +111 -0
- sage/coding/cyclic_code.py +1329 -0
- sage/coding/databases.py +316 -0
- sage/coding/decoder.py +373 -0
- sage/coding/decoders_catalog.py +88 -0
- sage/coding/delsarte_bounds.py +709 -0
- sage/coding/encoder.py +390 -0
- sage/coding/encoders_catalog.py +64 -0
- sage/coding/extended_code.py +468 -0
- sage/coding/gabidulin_code.py +1058 -0
- sage/coding/golay_code.py +404 -0
- sage/coding/goppa_code.py +441 -0
- sage/coding/grs_code.py +2371 -0
- sage/coding/guava.py +107 -0
- sage/coding/guruswami_sudan/all.py +1 -0
- sage/coding/guruswami_sudan/gs_decoder.py +897 -0
- sage/coding/guruswami_sudan/interpolation.py +409 -0
- sage/coding/guruswami_sudan/utils.py +176 -0
- sage/coding/hamming_code.py +176 -0
- sage/coding/information_set_decoder.py +1032 -0
- sage/coding/kasami_codes.cpython-314-aarch64-linux-musl.so +0 -0
- sage/coding/kasami_codes.pyx +351 -0
- sage/coding/linear_code.py +3067 -0
- sage/coding/linear_code_no_metric.py +1354 -0
- sage/coding/linear_rank_metric.py +961 -0
- sage/coding/parity_check_code.py +353 -0
- sage/coding/punctured_code.py +719 -0
- sage/coding/reed_muller_code.py +999 -0
- sage/coding/self_dual_codes.py +942 -0
- sage/coding/source_coding/all.py +2 -0
- sage/coding/source_coding/huffman.py +553 -0
- sage/coding/subfield_subcode.py +423 -0
- sage/coding/two_weight_db.py +399 -0
- sage/combinat/all__sagemath_modules.py +7 -0
- sage/combinat/cartesian_product.py +347 -0
- sage/combinat/family.py +11 -0
- sage/combinat/free_module.py +1977 -0
- sage/combinat/root_system/all.py +147 -0
- sage/combinat/root_system/ambient_space.py +527 -0
- sage/combinat/root_system/associahedron.py +471 -0
- sage/combinat/root_system/braid_move_calculator.py +143 -0
- sage/combinat/root_system/braid_orbit.cpython-314-aarch64-linux-musl.so +0 -0
- sage/combinat/root_system/braid_orbit.pyx +144 -0
- sage/combinat/root_system/branching_rules.py +2301 -0
- sage/combinat/root_system/cartan_matrix.py +1245 -0
- sage/combinat/root_system/cartan_type.py +3069 -0
- sage/combinat/root_system/coxeter_group.py +162 -0
- sage/combinat/root_system/coxeter_matrix.py +1261 -0
- sage/combinat/root_system/coxeter_type.py +681 -0
- sage/combinat/root_system/dynkin_diagram.py +900 -0
- sage/combinat/root_system/extended_affine_weyl_group.py +2993 -0
- sage/combinat/root_system/fundamental_group.py +795 -0
- sage/combinat/root_system/hecke_algebra_representation.py +1203 -0
- sage/combinat/root_system/integrable_representations.py +1227 -0
- sage/combinat/root_system/non_symmetric_macdonald_polynomials.py +1965 -0
- sage/combinat/root_system/pieri_factors.py +1147 -0
- sage/combinat/root_system/plot.py +1615 -0
- sage/combinat/root_system/root_lattice_realization_algebras.py +1214 -0
- sage/combinat/root_system/root_lattice_realizations.py +4628 -0
- sage/combinat/root_system/root_space.py +487 -0
- sage/combinat/root_system/root_system.py +882 -0
- sage/combinat/root_system/type_A.py +348 -0
- sage/combinat/root_system/type_A_affine.py +227 -0
- sage/combinat/root_system/type_A_infinity.py +241 -0
- sage/combinat/root_system/type_B.py +347 -0
- sage/combinat/root_system/type_BC_affine.py +287 -0
- sage/combinat/root_system/type_B_affine.py +216 -0
- sage/combinat/root_system/type_C.py +317 -0
- sage/combinat/root_system/type_C_affine.py +188 -0
- sage/combinat/root_system/type_D.py +357 -0
- sage/combinat/root_system/type_D_affine.py +208 -0
- sage/combinat/root_system/type_E.py +641 -0
- sage/combinat/root_system/type_E_affine.py +231 -0
- sage/combinat/root_system/type_F.py +387 -0
- sage/combinat/root_system/type_F_affine.py +137 -0
- sage/combinat/root_system/type_G.py +293 -0
- sage/combinat/root_system/type_G_affine.py +132 -0
- sage/combinat/root_system/type_H.py +105 -0
- sage/combinat/root_system/type_I.py +110 -0
- sage/combinat/root_system/type_Q.py +150 -0
- sage/combinat/root_system/type_affine.py +509 -0
- sage/combinat/root_system/type_dual.py +704 -0
- sage/combinat/root_system/type_folded.py +301 -0
- sage/combinat/root_system/type_marked.py +748 -0
- sage/combinat/root_system/type_reducible.py +601 -0
- sage/combinat/root_system/type_relabel.py +730 -0
- sage/combinat/root_system/type_super_A.py +837 -0
- sage/combinat/root_system/weight_lattice_realizations.py +1188 -0
- sage/combinat/root_system/weight_space.py +639 -0
- sage/combinat/root_system/weyl_characters.py +2238 -0
- sage/crypto/__init__.py +4 -0
- sage/crypto/all.py +28 -0
- sage/crypto/block_cipher/all.py +7 -0
- sage/crypto/block_cipher/des.py +1065 -0
- sage/crypto/block_cipher/miniaes.py +2171 -0
- sage/crypto/block_cipher/present.py +909 -0
- sage/crypto/block_cipher/sdes.py +1527 -0
- sage/crypto/boolean_function.cpython-314-aarch64-linux-musl.so +0 -0
- sage/crypto/boolean_function.pxd +10 -0
- sage/crypto/boolean_function.pyx +1487 -0
- sage/crypto/cipher.py +78 -0
- sage/crypto/classical.py +3668 -0
- sage/crypto/classical_cipher.py +569 -0
- sage/crypto/cryptosystem.py +387 -0
- sage/crypto/key_exchange/all.py +7 -0
- sage/crypto/key_exchange/catalog.py +24 -0
- sage/crypto/key_exchange/diffie_hellman.py +323 -0
- sage/crypto/key_exchange/key_exchange_scheme.py +107 -0
- sage/crypto/lattice.py +312 -0
- sage/crypto/lfsr.py +295 -0
- sage/crypto/lwe.py +840 -0
- sage/crypto/mq/__init__.py +4 -0
- sage/crypto/mq/mpolynomialsystemgenerator.py +204 -0
- sage/crypto/mq/rijndael_gf.py +2345 -0
- sage/crypto/mq/sbox.py +7 -0
- sage/crypto/mq/sr.py +3344 -0
- sage/crypto/public_key/all.py +5 -0
- sage/crypto/public_key/blum_goldwasser.py +776 -0
- sage/crypto/sbox.cpython-314-aarch64-linux-musl.so +0 -0
- sage/crypto/sbox.pyx +2090 -0
- sage/crypto/sboxes.py +2090 -0
- sage/crypto/stream.py +390 -0
- sage/crypto/stream_cipher.py +297 -0
- sage/crypto/util.py +519 -0
- sage/ext/all__sagemath_modules.py +1 -0
- sage/ext/interpreters/__init__.py +1 -0
- sage/ext/interpreters/all__sagemath_modules.py +2 -0
- sage/ext/interpreters/wrapper_cc.cpython-314-aarch64-linux-musl.so +0 -0
- sage/ext/interpreters/wrapper_cc.pxd +30 -0
- sage/ext/interpreters/wrapper_cc.pyx +252 -0
- sage/ext/interpreters/wrapper_cdf.cpython-314-aarch64-linux-musl.so +0 -0
- sage/ext/interpreters/wrapper_cdf.pxd +26 -0
- sage/ext/interpreters/wrapper_cdf.pyx +245 -0
- sage/ext/interpreters/wrapper_rdf.cpython-314-aarch64-linux-musl.so +0 -0
- sage/ext/interpreters/wrapper_rdf.pxd +23 -0
- sage/ext/interpreters/wrapper_rdf.pyx +221 -0
- sage/ext/interpreters/wrapper_rr.cpython-314-aarch64-linux-musl.so +0 -0
- sage/ext/interpreters/wrapper_rr.pxd +28 -0
- sage/ext/interpreters/wrapper_rr.pyx +335 -0
- sage/geometry/all__sagemath_modules.py +5 -0
- sage/geometry/toric_lattice.py +1745 -0
- sage/geometry/toric_lattice_element.cpython-314-aarch64-linux-musl.so +0 -0
- sage/geometry/toric_lattice_element.pyx +432 -0
- sage/groups/abelian_gps/abelian_group.py +1925 -0
- sage/groups/abelian_gps/abelian_group_element.py +164 -0
- sage/groups/abelian_gps/all__sagemath_modules.py +5 -0
- sage/groups/abelian_gps/dual_abelian_group.py +421 -0
- sage/groups/abelian_gps/dual_abelian_group_element.py +179 -0
- sage/groups/abelian_gps/element_base.py +341 -0
- sage/groups/abelian_gps/values.py +488 -0
- sage/groups/additive_abelian/additive_abelian_group.py +476 -0
- sage/groups/additive_abelian/additive_abelian_wrapper.py +857 -0
- sage/groups/additive_abelian/all.py +4 -0
- sage/groups/additive_abelian/qmodnz.py +231 -0
- sage/groups/additive_abelian/qmodnz_element.py +349 -0
- sage/groups/affine_gps/affine_group.py +535 -0
- sage/groups/affine_gps/all.py +1 -0
- sage/groups/affine_gps/catalog.py +17 -0
- sage/groups/affine_gps/euclidean_group.py +246 -0
- sage/groups/affine_gps/group_element.py +562 -0
- sage/groups/all__sagemath_modules.py +12 -0
- sage/groups/galois_group.py +479 -0
- sage/groups/matrix_gps/all.py +4 -0
- sage/groups/matrix_gps/all__sagemath_modules.py +13 -0
- sage/groups/matrix_gps/catalog.py +26 -0
- sage/groups/matrix_gps/coxeter_group.py +927 -0
- sage/groups/matrix_gps/finitely_generated.py +487 -0
- sage/groups/matrix_gps/group_element.cpython-314-aarch64-linux-musl.so +0 -0
- sage/groups/matrix_gps/group_element.pxd +11 -0
- sage/groups/matrix_gps/group_element.pyx +431 -0
- sage/groups/matrix_gps/linear.py +440 -0
- sage/groups/matrix_gps/matrix_group.py +617 -0
- sage/groups/matrix_gps/named_group.py +296 -0
- sage/groups/matrix_gps/orthogonal.py +544 -0
- sage/groups/matrix_gps/symplectic.py +251 -0
- sage/groups/matrix_gps/unitary.py +436 -0
- sage/groups/misc_gps/all__sagemath_modules.py +1 -0
- sage/groups/misc_gps/argument_groups.py +1905 -0
- sage/groups/misc_gps/imaginary_groups.py +479 -0
- sage/groups/perm_gps/all__sagemath_modules.py +1 -0
- sage/groups/perm_gps/partn_ref/all__sagemath_modules.py +1 -0
- sage/groups/perm_gps/partn_ref/refinement_binary.cpython-314-aarch64-linux-musl.so +0 -0
- sage/groups/perm_gps/partn_ref/refinement_binary.pxd +41 -0
- sage/groups/perm_gps/partn_ref/refinement_binary.pyx +1167 -0
- sage/groups/perm_gps/partn_ref/refinement_matrices.cpython-314-aarch64-linux-musl.so +0 -0
- sage/groups/perm_gps/partn_ref/refinement_matrices.pxd +31 -0
- sage/groups/perm_gps/partn_ref/refinement_matrices.pyx +385 -0
- sage/homology/algebraic_topological_model.py +595 -0
- sage/homology/all.py +2 -0
- sage/homology/all__sagemath_modules.py +8 -0
- sage/homology/chain_complex.py +2148 -0
- sage/homology/chain_complex_homspace.py +165 -0
- sage/homology/chain_complex_morphism.py +629 -0
- sage/homology/chain_homotopy.py +604 -0
- sage/homology/chains.py +653 -0
- sage/homology/free_resolution.py +923 -0
- sage/homology/graded_resolution.py +567 -0
- sage/homology/hochschild_complex.py +756 -0
- sage/homology/homology_group.py +188 -0
- sage/homology/homology_morphism.py +422 -0
- sage/homology/homology_vector_space_with_basis.py +1454 -0
- sage/homology/koszul_complex.py +169 -0
- sage/homology/matrix_utils.py +205 -0
- sage/libs/all__sagemath_modules.py +1 -0
- sage/libs/gsl/__init__.py +1 -0
- sage/libs/gsl/airy.pxd +56 -0
- sage/libs/gsl/all.pxd +66 -0
- sage/libs/gsl/array.cpython-314-aarch64-linux-musl.so +0 -0
- sage/libs/gsl/array.pxd +5 -0
- sage/libs/gsl/array.pyx +102 -0
- sage/libs/gsl/bessel.pxd +208 -0
- sage/libs/gsl/blas.pxd +116 -0
- sage/libs/gsl/blas_types.pxd +34 -0
- sage/libs/gsl/block.pxd +52 -0
- sage/libs/gsl/chebyshev.pxd +37 -0
- sage/libs/gsl/clausen.pxd +12 -0
- sage/libs/gsl/combination.pxd +47 -0
- sage/libs/gsl/complex.pxd +151 -0
- sage/libs/gsl/coulomb.pxd +30 -0
- sage/libs/gsl/coupling.pxd +21 -0
- sage/libs/gsl/dawson.pxd +12 -0
- sage/libs/gsl/debye.pxd +24 -0
- sage/libs/gsl/dilog.pxd +14 -0
- sage/libs/gsl/eigen.pxd +46 -0
- sage/libs/gsl/elementary.pxd +12 -0
- sage/libs/gsl/ellint.pxd +48 -0
- sage/libs/gsl/elljac.pxd +8 -0
- sage/libs/gsl/erf.pxd +32 -0
- sage/libs/gsl/errno.pxd +26 -0
- sage/libs/gsl/exp.pxd +44 -0
- sage/libs/gsl/expint.pxd +44 -0
- sage/libs/gsl/fermi_dirac.pxd +44 -0
- sage/libs/gsl/fft.pxd +121 -0
- sage/libs/gsl/fit.pxd +50 -0
- sage/libs/gsl/gamma.pxd +94 -0
- sage/libs/gsl/gegenbauer.pxd +26 -0
- sage/libs/gsl/histogram.pxd +176 -0
- sage/libs/gsl/hyperg.pxd +52 -0
- sage/libs/gsl/integration.pxd +69 -0
- sage/libs/gsl/interp.pxd +109 -0
- sage/libs/gsl/laguerre.pxd +24 -0
- sage/libs/gsl/lambert.pxd +16 -0
- sage/libs/gsl/legendre.pxd +90 -0
- sage/libs/gsl/linalg.pxd +185 -0
- sage/libs/gsl/log.pxd +26 -0
- sage/libs/gsl/math.pxd +43 -0
- sage/libs/gsl/matrix.pxd +143 -0
- sage/libs/gsl/matrix_complex.pxd +130 -0
- sage/libs/gsl/min.pxd +67 -0
- sage/libs/gsl/monte.pxd +56 -0
- sage/libs/gsl/ntuple.pxd +32 -0
- sage/libs/gsl/odeiv.pxd +70 -0
- sage/libs/gsl/permutation.pxd +78 -0
- sage/libs/gsl/poly.pxd +40 -0
- sage/libs/gsl/pow_int.pxd +12 -0
- sage/libs/gsl/psi.pxd +28 -0
- sage/libs/gsl/qrng.pxd +29 -0
- sage/libs/gsl/random.pxd +257 -0
- sage/libs/gsl/rng.pxd +100 -0
- sage/libs/gsl/roots.pxd +72 -0
- sage/libs/gsl/sort.pxd +36 -0
- sage/libs/gsl/statistics.pxd +59 -0
- sage/libs/gsl/sum.pxd +55 -0
- sage/libs/gsl/synchrotron.pxd +16 -0
- sage/libs/gsl/transport.pxd +24 -0
- sage/libs/gsl/trig.pxd +58 -0
- sage/libs/gsl/types.pxd +137 -0
- sage/libs/gsl/vector.pxd +101 -0
- sage/libs/gsl/vector_complex.pxd +83 -0
- sage/libs/gsl/wavelet.pxd +49 -0
- sage/libs/gsl/zeta.pxd +28 -0
- sage/libs/mpc/__init__.pxd +114 -0
- sage/libs/mpc/types.pxd +28 -0
- sage/libs/mpfr/__init__.pxd +299 -0
- sage/libs/mpfr/types.pxd +26 -0
- sage/libs/mpmath/__init__.py +1 -0
- sage/libs/mpmath/all.py +27 -0
- sage/libs/mpmath/all__sagemath_modules.py +1 -0
- sage/libs/mpmath/utils.cpython-314-aarch64-linux-musl.so +0 -0
- sage/libs/mpmath/utils.pxd +4 -0
- sage/libs/mpmath/utils.pyx +319 -0
- sage/matrix/action.cpython-314-aarch64-linux-musl.so +0 -0
- sage/matrix/action.pxd +26 -0
- sage/matrix/action.pyx +596 -0
- sage/matrix/all.py +9 -0
- sage/matrix/args.cpython-314-aarch64-linux-musl.so +0 -0
- sage/matrix/args.pxd +144 -0
- sage/matrix/args.pyx +1668 -0
- sage/matrix/benchmark.py +1258 -0
- sage/matrix/berlekamp_massey.py +95 -0
- sage/matrix/compute_J_ideal.py +926 -0
- sage/matrix/constructor.cpython-314-aarch64-linux-musl.so +0 -0
- sage/matrix/constructor.pyx +750 -0
- sage/matrix/docs.py +430 -0
- sage/matrix/echelon_matrix.cpython-314-aarch64-linux-musl.so +0 -0
- sage/matrix/echelon_matrix.pyx +155 -0
- sage/matrix/matrix.pxd +2 -0
- sage/matrix/matrix0.cpython-314-aarch64-linux-musl.so +0 -0
- sage/matrix/matrix0.pxd +68 -0
- sage/matrix/matrix0.pyx +6324 -0
- sage/matrix/matrix1.cpython-314-aarch64-linux-musl.so +0 -0
- sage/matrix/matrix1.pxd +8 -0
- sage/matrix/matrix1.pyx +2851 -0
- sage/matrix/matrix2.cpython-314-aarch64-linux-musl.so +0 -0
- sage/matrix/matrix2.pxd +25 -0
- sage/matrix/matrix2.pyx +20181 -0
- sage/matrix/matrix_cdv.cpython-314-aarch64-linux-musl.so +0 -0
- sage/matrix/matrix_cdv.pxd +4 -0
- sage/matrix/matrix_cdv.pyx +93 -0
- sage/matrix/matrix_complex_double_dense.cpython-314-aarch64-linux-musl.so +0 -0
- sage/matrix/matrix_complex_double_dense.pxd +5 -0
- sage/matrix/matrix_complex_double_dense.pyx +98 -0
- sage/matrix/matrix_dense.cpython-314-aarch64-linux-musl.so +0 -0
- sage/matrix/matrix_dense.pxd +5 -0
- sage/matrix/matrix_dense.pyx +343 -0
- sage/matrix/matrix_domain_dense.pxd +5 -0
- sage/matrix/matrix_domain_sparse.pxd +5 -0
- sage/matrix/matrix_double_dense.cpython-314-aarch64-linux-musl.so +0 -0
- sage/matrix/matrix_double_dense.pxd +7 -0
- sage/matrix/matrix_double_dense.pyx +3906 -0
- sage/matrix/matrix_double_sparse.cpython-314-aarch64-linux-musl.so +0 -0
- sage/matrix/matrix_double_sparse.pxd +6 -0
- sage/matrix/matrix_double_sparse.pyx +248 -0
- sage/matrix/matrix_generic_dense.cpython-314-aarch64-linux-musl.so +0 -0
- sage/matrix/matrix_generic_dense.pxd +7 -0
- sage/matrix/matrix_generic_dense.pyx +354 -0
- sage/matrix/matrix_generic_sparse.cpython-314-aarch64-linux-musl.so +0 -0
- sage/matrix/matrix_generic_sparse.pxd +7 -0
- sage/matrix/matrix_generic_sparse.pyx +461 -0
- sage/matrix/matrix_laurent_mpolynomial_dense.cpython-314-aarch64-linux-musl.so +0 -0
- sage/matrix/matrix_laurent_mpolynomial_dense.pxd +5 -0
- sage/matrix/matrix_laurent_mpolynomial_dense.pyx +115 -0
- sage/matrix/matrix_misc.py +313 -0
- sage/matrix/matrix_numpy_dense.cpython-314-aarch64-linux-musl.so +0 -0
- sage/matrix/matrix_numpy_dense.pxd +14 -0
- sage/matrix/matrix_numpy_dense.pyx +450 -0
- sage/matrix/matrix_numpy_integer_dense.cpython-314-aarch64-linux-musl.so +0 -0
- sage/matrix/matrix_numpy_integer_dense.pxd +7 -0
- sage/matrix/matrix_numpy_integer_dense.pyx +59 -0
- sage/matrix/matrix_polynomial_dense.cpython-314-aarch64-linux-musl.so +0 -0
- sage/matrix/matrix_polynomial_dense.pxd +5 -0
- sage/matrix/matrix_polynomial_dense.pyx +5341 -0
- sage/matrix/matrix_real_double_dense.cpython-314-aarch64-linux-musl.so +0 -0
- sage/matrix/matrix_real_double_dense.pxd +7 -0
- sage/matrix/matrix_real_double_dense.pyx +122 -0
- sage/matrix/matrix_space.py +2848 -0
- sage/matrix/matrix_sparse.cpython-314-aarch64-linux-musl.so +0 -0
- sage/matrix/matrix_sparse.pxd +5 -0
- sage/matrix/matrix_sparse.pyx +1222 -0
- sage/matrix/matrix_window.cpython-314-aarch64-linux-musl.so +0 -0
- sage/matrix/matrix_window.pxd +37 -0
- sage/matrix/matrix_window.pyx +242 -0
- sage/matrix/misc_mpfr.cpython-314-aarch64-linux-musl.so +0 -0
- sage/matrix/misc_mpfr.pyx +80 -0
- sage/matrix/operation_table.py +1182 -0
- sage/matrix/special.py +3666 -0
- sage/matrix/strassen.cpython-314-aarch64-linux-musl.so +0 -0
- sage/matrix/strassen.pyx +851 -0
- sage/matrix/symplectic_basis.py +541 -0
- sage/matrix/template.pxd +6 -0
- sage/matrix/tests.py +71 -0
- sage/matroids/advanced.py +77 -0
- sage/matroids/all.py +13 -0
- sage/matroids/basis_exchange_matroid.cpython-314-aarch64-linux-musl.so +0 -0
- sage/matroids/basis_exchange_matroid.pxd +96 -0
- sage/matroids/basis_exchange_matroid.pyx +2344 -0
- sage/matroids/basis_matroid.cpython-314-aarch64-linux-musl.so +0 -0
- sage/matroids/basis_matroid.pxd +45 -0
- sage/matroids/basis_matroid.pyx +1217 -0
- sage/matroids/catalog.py +44 -0
- sage/matroids/chow_ring.py +473 -0
- sage/matroids/chow_ring_ideal.py +849 -0
- sage/matroids/circuit_closures_matroid.cpython-314-aarch64-linux-musl.so +0 -0
- sage/matroids/circuit_closures_matroid.pxd +16 -0
- sage/matroids/circuit_closures_matroid.pyx +559 -0
- sage/matroids/circuits_matroid.cpython-314-aarch64-linux-musl.so +0 -0
- sage/matroids/circuits_matroid.pxd +38 -0
- sage/matroids/circuits_matroid.pyx +947 -0
- sage/matroids/constructor.py +1086 -0
- sage/matroids/database_collections.py +365 -0
- sage/matroids/database_matroids.py +5338 -0
- sage/matroids/dual_matroid.py +583 -0
- sage/matroids/extension.cpython-314-aarch64-linux-musl.so +0 -0
- sage/matroids/extension.pxd +34 -0
- sage/matroids/extension.pyx +519 -0
- sage/matroids/flats_matroid.cpython-314-aarch64-linux-musl.so +0 -0
- sage/matroids/flats_matroid.pxd +28 -0
- sage/matroids/flats_matroid.pyx +715 -0
- sage/matroids/gammoid.py +600 -0
- sage/matroids/graphic_matroid.cpython-314-aarch64-linux-musl.so +0 -0
- sage/matroids/graphic_matroid.pxd +39 -0
- sage/matroids/graphic_matroid.pyx +2024 -0
- sage/matroids/lean_matrix.cpython-314-aarch64-linux-musl.so +0 -0
- sage/matroids/lean_matrix.pxd +126 -0
- sage/matroids/lean_matrix.pyx +3667 -0
- sage/matroids/linear_matroid.cpython-314-aarch64-linux-musl.so +0 -0
- sage/matroids/linear_matroid.pxd +180 -0
- sage/matroids/linear_matroid.pyx +6649 -0
- sage/matroids/matroid.cpython-314-aarch64-linux-musl.so +0 -0
- sage/matroids/matroid.pxd +243 -0
- sage/matroids/matroid.pyx +8759 -0
- sage/matroids/matroids_catalog.py +190 -0
- sage/matroids/matroids_plot_helpers.py +890 -0
- sage/matroids/minor_matroid.py +480 -0
- sage/matroids/minorfix.h +9 -0
- sage/matroids/named_matroids.py +5 -0
- sage/matroids/rank_matroid.py +268 -0
- sage/matroids/set_system.cpython-314-aarch64-linux-musl.so +0 -0
- sage/matroids/set_system.pxd +38 -0
- sage/matroids/set_system.pyx +800 -0
- sage/matroids/transversal_matroid.cpython-314-aarch64-linux-musl.so +0 -0
- sage/matroids/transversal_matroid.pxd +14 -0
- sage/matroids/transversal_matroid.pyx +893 -0
- sage/matroids/union_matroid.cpython-314-aarch64-linux-musl.so +0 -0
- sage/matroids/union_matroid.pxd +20 -0
- sage/matroids/union_matroid.pyx +331 -0
- sage/matroids/unpickling.cpython-314-aarch64-linux-musl.so +0 -0
- sage/matroids/unpickling.pyx +843 -0
- sage/matroids/utilities.py +809 -0
- sage/misc/all__sagemath_modules.py +20 -0
- sage/misc/c3.cpython-314-aarch64-linux-musl.so +0 -0
- sage/misc/c3.pyx +238 -0
- sage/misc/compat.py +87 -0
- sage/misc/element_with_label.py +173 -0
- sage/misc/func_persist.py +79 -0
- sage/misc/pickle_old.cpython-314-aarch64-linux-musl.so +0 -0
- sage/misc/pickle_old.pyx +19 -0
- sage/misc/proof.py +7 -0
- sage/misc/replace_dot_all.py +472 -0
- sage/misc/sagedoc_conf.py +168 -0
- sage/misc/sphinxify.py +167 -0
- sage/misc/test_class_pickling.py +85 -0
- sage/modules/all.py +42 -0
- sage/modules/complex_double_vector.py +25 -0
- sage/modules/diamond_cutting.py +380 -0
- sage/modules/fg_pid/all.py +1 -0
- sage/modules/fg_pid/fgp_element.py +456 -0
- sage/modules/fg_pid/fgp_module.py +2091 -0
- sage/modules/fg_pid/fgp_morphism.py +550 -0
- sage/modules/filtered_vector_space.py +1271 -0
- sage/modules/finite_submodule_iter.cpython-314-aarch64-linux-musl.so +0 -0
- sage/modules/finite_submodule_iter.pxd +27 -0
- sage/modules/finite_submodule_iter.pyx +452 -0
- sage/modules/fp_graded/all.py +1 -0
- sage/modules/fp_graded/element.py +346 -0
- sage/modules/fp_graded/free_element.py +298 -0
- sage/modules/fp_graded/free_homspace.py +53 -0
- sage/modules/fp_graded/free_module.py +1060 -0
- sage/modules/fp_graded/free_morphism.py +217 -0
- sage/modules/fp_graded/homspace.py +563 -0
- sage/modules/fp_graded/module.py +1340 -0
- sage/modules/fp_graded/morphism.py +1990 -0
- sage/modules/fp_graded/steenrod/all.py +1 -0
- sage/modules/fp_graded/steenrod/homspace.py +65 -0
- sage/modules/fp_graded/steenrod/module.py +477 -0
- sage/modules/fp_graded/steenrod/morphism.py +404 -0
- sage/modules/fp_graded/steenrod/profile.py +241 -0
- sage/modules/free_module.py +8447 -0
- sage/modules/free_module_element.cpython-314-aarch64-linux-musl.so +0 -0
- sage/modules/free_module_element.pxd +22 -0
- sage/modules/free_module_element.pyx +5445 -0
- sage/modules/free_module_homspace.py +369 -0
- sage/modules/free_module_integer.py +896 -0
- sage/modules/free_module_morphism.py +823 -0
- sage/modules/free_module_pseudohomspace.py +352 -0
- sage/modules/free_module_pseudomorphism.py +578 -0
- sage/modules/free_quadratic_module.py +1706 -0
- sage/modules/free_quadratic_module_integer_symmetric.py +1790 -0
- sage/modules/matrix_morphism.py +1745 -0
- sage/modules/misc.py +103 -0
- sage/modules/module_functors.py +192 -0
- sage/modules/multi_filtered_vector_space.py +719 -0
- sage/modules/ore_module.py +2208 -0
- sage/modules/ore_module_element.py +178 -0
- sage/modules/ore_module_homspace.py +147 -0
- sage/modules/ore_module_morphism.py +968 -0
- sage/modules/quotient_module.py +699 -0
- sage/modules/real_double_vector.py +22 -0
- sage/modules/submodule.py +255 -0
- sage/modules/tensor_operations.py +567 -0
- sage/modules/torsion_quadratic_module.py +1352 -0
- sage/modules/tutorial_free_modules.py +248 -0
- sage/modules/vector_complex_double_dense.cpython-314-aarch64-linux-musl.so +0 -0
- sage/modules/vector_complex_double_dense.pxd +6 -0
- sage/modules/vector_complex_double_dense.pyx +117 -0
- sage/modules/vector_double_dense.cpython-314-aarch64-linux-musl.so +0 -0
- sage/modules/vector_double_dense.pxd +6 -0
- sage/modules/vector_double_dense.pyx +604 -0
- sage/modules/vector_integer_dense.cpython-314-aarch64-linux-musl.so +0 -0
- sage/modules/vector_integer_dense.pxd +15 -0
- sage/modules/vector_integer_dense.pyx +361 -0
- sage/modules/vector_integer_sparse.cpython-314-aarch64-linux-musl.so +0 -0
- sage/modules/vector_integer_sparse.pxd +29 -0
- sage/modules/vector_integer_sparse.pyx +406 -0
- sage/modules/vector_modn_dense.cpython-314-aarch64-linux-musl.so +0 -0
- sage/modules/vector_modn_dense.pxd +12 -0
- sage/modules/vector_modn_dense.pyx +394 -0
- sage/modules/vector_modn_sparse.cpython-314-aarch64-linux-musl.so +0 -0
- sage/modules/vector_modn_sparse.pxd +21 -0
- sage/modules/vector_modn_sparse.pyx +298 -0
- sage/modules/vector_numpy_dense.cpython-314-aarch64-linux-musl.so +0 -0
- sage/modules/vector_numpy_dense.pxd +15 -0
- sage/modules/vector_numpy_dense.pyx +304 -0
- sage/modules/vector_numpy_integer_dense.cpython-314-aarch64-linux-musl.so +0 -0
- sage/modules/vector_numpy_integer_dense.pxd +7 -0
- sage/modules/vector_numpy_integer_dense.pyx +54 -0
- sage/modules/vector_rational_dense.cpython-314-aarch64-linux-musl.so +0 -0
- sage/modules/vector_rational_dense.pxd +15 -0
- sage/modules/vector_rational_dense.pyx +387 -0
- sage/modules/vector_rational_sparse.cpython-314-aarch64-linux-musl.so +0 -0
- sage/modules/vector_rational_sparse.pxd +30 -0
- sage/modules/vector_rational_sparse.pyx +413 -0
- sage/modules/vector_real_double_dense.cpython-314-aarch64-linux-musl.so +0 -0
- sage/modules/vector_real_double_dense.pxd +6 -0
- sage/modules/vector_real_double_dense.pyx +126 -0
- sage/modules/vector_space_homspace.py +430 -0
- sage/modules/vector_space_morphism.py +989 -0
- sage/modules/with_basis/all.py +15 -0
- sage/modules/with_basis/cell_module.py +494 -0
- sage/modules/with_basis/indexed_element.cpython-314-aarch64-linux-musl.so +0 -0
- sage/modules/with_basis/indexed_element.pxd +13 -0
- sage/modules/with_basis/indexed_element.pyx +1058 -0
- sage/modules/with_basis/invariant.py +1075 -0
- sage/modules/with_basis/morphism.py +1636 -0
- sage/modules/with_basis/representation.py +2939 -0
- sage/modules/with_basis/subquotient.py +685 -0
- sage/numerical/all__sagemath_modules.py +6 -0
- sage/numerical/gauss_legendre.cpython-314-aarch64-linux-musl.so +0 -0
- sage/numerical/gauss_legendre.pyx +381 -0
- sage/numerical/optimize.py +910 -0
- sage/probability/all.py +10 -0
- sage/probability/probability_distribution.cpython-314-aarch64-linux-musl.so +0 -0
- sage/probability/probability_distribution.pyx +1242 -0
- sage/probability/random_variable.py +411 -0
- sage/quadratic_forms/all.py +4 -0
- sage/quadratic_forms/all__sagemath_modules.py +15 -0
- sage/quadratic_forms/binary_qf.py +2042 -0
- sage/quadratic_forms/bqf_class_group.py +748 -0
- sage/quadratic_forms/constructions.py +93 -0
- sage/quadratic_forms/count_local_2.cpython-314-aarch64-linux-musl.so +0 -0
- sage/quadratic_forms/count_local_2.pyx +365 -0
- sage/quadratic_forms/extras.py +195 -0
- sage/quadratic_forms/quadratic_form.py +1753 -0
- sage/quadratic_forms/quadratic_form__count_local_2.py +221 -0
- sage/quadratic_forms/quadratic_form__equivalence_testing.py +708 -0
- sage/quadratic_forms/quadratic_form__evaluate.cpython-314-aarch64-linux-musl.so +0 -0
- sage/quadratic_forms/quadratic_form__evaluate.pyx +139 -0
- sage/quadratic_forms/quadratic_form__local_density_congruence.py +977 -0
- sage/quadratic_forms/quadratic_form__local_field_invariants.py +1072 -0
- sage/quadratic_forms/quadratic_form__neighbors.py +424 -0
- sage/quadratic_forms/quadratic_form__reduction_theory.py +488 -0
- sage/quadratic_forms/quadratic_form__split_local_covering.py +416 -0
- sage/quadratic_forms/quadratic_form__ternary_Tornaria.py +657 -0
- sage/quadratic_forms/quadratic_form__theta.py +352 -0
- sage/quadratic_forms/quadratic_form__variable_substitutions.py +370 -0
- sage/quadratic_forms/random_quadraticform.py +209 -0
- sage/quadratic_forms/ternary.cpython-314-aarch64-linux-musl.so +0 -0
- sage/quadratic_forms/ternary.pyx +1154 -0
- sage/quadratic_forms/ternary_qf.py +2027 -0
- sage/rings/all__sagemath_modules.py +28 -0
- sage/rings/asymptotic/all__sagemath_modules.py +1 -0
- sage/rings/asymptotic/misc.py +1252 -0
- sage/rings/cc.py +4 -0
- sage/rings/cfinite_sequence.py +1306 -0
- sage/rings/complex_conversion.cpython-314-aarch64-linux-musl.so +0 -0
- sage/rings/complex_conversion.pxd +8 -0
- sage/rings/complex_conversion.pyx +23 -0
- sage/rings/complex_double.cpython-314-aarch64-linux-musl.so +0 -0
- sage/rings/complex_double.pxd +21 -0
- sage/rings/complex_double.pyx +2654 -0
- sage/rings/complex_mpc.cpython-314-aarch64-linux-musl.so +0 -0
- sage/rings/complex_mpc.pxd +21 -0
- sage/rings/complex_mpc.pyx +2576 -0
- sage/rings/complex_mpfr.cpython-314-aarch64-linux-musl.so +0 -0
- sage/rings/complex_mpfr.pxd +18 -0
- sage/rings/complex_mpfr.pyx +3602 -0
- sage/rings/derivation.py +2334 -0
- sage/rings/finite_rings/all__sagemath_modules.py +1 -0
- sage/rings/finite_rings/maps_finite_field.py +191 -0
- sage/rings/function_field/all__sagemath_modules.py +8 -0
- sage/rings/function_field/derivations.py +102 -0
- sage/rings/function_field/derivations_rational.py +132 -0
- sage/rings/function_field/differential.py +853 -0
- sage/rings/function_field/divisor.py +1107 -0
- sage/rings/function_field/drinfeld_modules/action.py +199 -0
- sage/rings/function_field/drinfeld_modules/all.py +1 -0
- sage/rings/function_field/drinfeld_modules/charzero_drinfeld_module.py +673 -0
- sage/rings/function_field/drinfeld_modules/drinfeld_module.py +2087 -0
- sage/rings/function_field/drinfeld_modules/finite_drinfeld_module.py +1131 -0
- sage/rings/function_field/drinfeld_modules/homset.py +420 -0
- sage/rings/function_field/drinfeld_modules/morphism.py +820 -0
- sage/rings/function_field/hermite_form_polynomial.cpython-314-aarch64-linux-musl.so +0 -0
- sage/rings/function_field/hermite_form_polynomial.pyx +188 -0
- sage/rings/function_field/khuri_makdisi.cpython-314-aarch64-linux-musl.so +0 -0
- sage/rings/function_field/khuri_makdisi.pyx +935 -0
- sage/rings/invariants/all.py +4 -0
- sage/rings/invariants/invariant_theory.py +4597 -0
- sage/rings/invariants/reconstruction.py +395 -0
- sage/rings/polynomial/all__sagemath_modules.py +17 -0
- sage/rings/polynomial/integer_valued_polynomials.py +1230 -0
- sage/rings/polynomial/laurent_polynomial_mpair.cpython-314-aarch64-linux-musl.so +0 -0
- sage/rings/polynomial/laurent_polynomial_mpair.pxd +15 -0
- sage/rings/polynomial/laurent_polynomial_mpair.pyx +2023 -0
- sage/rings/polynomial/ore_function_element.py +952 -0
- sage/rings/polynomial/ore_function_field.py +1028 -0
- sage/rings/polynomial/ore_polynomial_element.cpython-314-aarch64-linux-musl.so +0 -0
- sage/rings/polynomial/ore_polynomial_element.pxd +48 -0
- sage/rings/polynomial/ore_polynomial_element.pyx +3145 -0
- sage/rings/polynomial/ore_polynomial_ring.py +1334 -0
- sage/rings/polynomial/polynomial_real_mpfr_dense.cpython-314-aarch64-linux-musl.so +0 -0
- sage/rings/polynomial/polynomial_real_mpfr_dense.pyx +788 -0
- sage/rings/polynomial/q_integer_valued_polynomials.py +1264 -0
- sage/rings/polynomial/skew_polynomial_element.cpython-314-aarch64-linux-musl.so +0 -0
- sage/rings/polynomial/skew_polynomial_element.pxd +9 -0
- sage/rings/polynomial/skew_polynomial_element.pyx +684 -0
- sage/rings/polynomial/skew_polynomial_finite_field.cpython-314-aarch64-linux-musl.so +0 -0
- sage/rings/polynomial/skew_polynomial_finite_field.pxd +19 -0
- sage/rings/polynomial/skew_polynomial_finite_field.pyx +1093 -0
- sage/rings/polynomial/skew_polynomial_finite_order.cpython-314-aarch64-linux-musl.so +0 -0
- sage/rings/polynomial/skew_polynomial_finite_order.pxd +10 -0
- sage/rings/polynomial/skew_polynomial_finite_order.pyx +567 -0
- sage/rings/polynomial/skew_polynomial_ring.py +908 -0
- sage/rings/real_double_element_gsl.cpython-314-aarch64-linux-musl.so +0 -0
- sage/rings/real_double_element_gsl.pxd +8 -0
- sage/rings/real_double_element_gsl.pyx +794 -0
- sage/rings/real_field.py +58 -0
- sage/rings/real_mpfr.cpython-314-aarch64-linux-musl.so +0 -0
- sage/rings/real_mpfr.pxd +29 -0
- sage/rings/real_mpfr.pyx +6122 -0
- sage/rings/ring_extension.cpython-314-aarch64-linux-musl.so +0 -0
- sage/rings/ring_extension.pxd +42 -0
- sage/rings/ring_extension.pyx +2779 -0
- sage/rings/ring_extension_conversion.cpython-314-aarch64-linux-musl.so +0 -0
- sage/rings/ring_extension_conversion.pxd +16 -0
- sage/rings/ring_extension_conversion.pyx +462 -0
- sage/rings/ring_extension_element.cpython-314-aarch64-linux-musl.so +0 -0
- sage/rings/ring_extension_element.pxd +21 -0
- sage/rings/ring_extension_element.pyx +1635 -0
- sage/rings/ring_extension_homset.py +64 -0
- sage/rings/ring_extension_morphism.cpython-314-aarch64-linux-musl.so +0 -0
- sage/rings/ring_extension_morphism.pxd +35 -0
- sage/rings/ring_extension_morphism.pyx +920 -0
- sage/schemes/all__sagemath_modules.py +1 -0
- sage/schemes/projective/all__sagemath_modules.py +1 -0
- sage/schemes/projective/coherent_sheaf.py +300 -0
- sage/schemes/projective/cohomology.py +510 -0
- sage/stats/all.py +15 -0
- sage/stats/basic_stats.py +489 -0
- sage/stats/distributions/all.py +7 -0
- sage/stats/distributions/catalog.py +34 -0
- sage/stats/distributions/dgs.h +50 -0
- sage/stats/distributions/dgs.pxd +111 -0
- sage/stats/distributions/dgs_bern.h +400 -0
- sage/stats/distributions/dgs_gauss.h +614 -0
- sage/stats/distributions/dgs_misc.h +104 -0
- sage/stats/distributions/discrete_gaussian_integer.cpython-314-aarch64-linux-musl.so +0 -0
- sage/stats/distributions/discrete_gaussian_integer.pxd +14 -0
- sage/stats/distributions/discrete_gaussian_integer.pyx +498 -0
- sage/stats/distributions/discrete_gaussian_lattice.py +908 -0
- sage/stats/distributions/discrete_gaussian_polynomial.py +141 -0
- sage/stats/hmm/all.py +15 -0
- sage/stats/hmm/chmm.cpython-314-aarch64-linux-musl.so +0 -0
- sage/stats/hmm/chmm.pyx +1595 -0
- sage/stats/hmm/distributions.cpython-314-aarch64-linux-musl.so +0 -0
- sage/stats/hmm/distributions.pxd +29 -0
- sage/stats/hmm/distributions.pyx +531 -0
- sage/stats/hmm/hmm.cpython-314-aarch64-linux-musl.so +0 -0
- sage/stats/hmm/hmm.pxd +17 -0
- sage/stats/hmm/hmm.pyx +1388 -0
- sage/stats/hmm/util.cpython-314-aarch64-linux-musl.so +0 -0
- sage/stats/hmm/util.pxd +7 -0
- sage/stats/hmm/util.pyx +165 -0
- sage/stats/intlist.cpython-314-aarch64-linux-musl.so +0 -0
- sage/stats/intlist.pxd +14 -0
- sage/stats/intlist.pyx +588 -0
- sage/stats/r.py +49 -0
- sage/stats/time_series.cpython-314-aarch64-linux-musl.so +0 -0
- sage/stats/time_series.pxd +6 -0
- sage/stats/time_series.pyx +2546 -0
- sage/tensor/all.py +2 -0
- sage/tensor/modules/all.py +8 -0
- sage/tensor/modules/alternating_contr_tensor.py +761 -0
- sage/tensor/modules/comp.py +5598 -0
- sage/tensor/modules/ext_pow_free_module.py +824 -0
- sage/tensor/modules/finite_rank_free_module.py +3589 -0
- sage/tensor/modules/format_utilities.py +333 -0
- sage/tensor/modules/free_module_alt_form.py +858 -0
- sage/tensor/modules/free_module_automorphism.py +1207 -0
- sage/tensor/modules/free_module_basis.py +1074 -0
- sage/tensor/modules/free_module_element.py +284 -0
- sage/tensor/modules/free_module_homset.py +652 -0
- sage/tensor/modules/free_module_linear_group.py +564 -0
- sage/tensor/modules/free_module_morphism.py +1581 -0
- sage/tensor/modules/free_module_tensor.py +3289 -0
- sage/tensor/modules/reflexive_module.py +386 -0
- sage/tensor/modules/tensor_free_module.py +780 -0
- sage/tensor/modules/tensor_free_submodule.py +538 -0
- sage/tensor/modules/tensor_free_submodule_basis.py +140 -0
- sage/tensor/modules/tensor_with_indices.py +1043 -0
|
@@ -0,0 +1,909 @@
|
|
|
1
|
+
# sage_setup: distribution = sagemath-modules
|
|
2
|
+
# sage.doctest: needs sage.modules sage.rings.finite_rings
|
|
3
|
+
r"""
|
|
4
|
+
PRESENT
|
|
5
|
+
|
|
6
|
+
An ultra-lightweight block cipher.
|
|
7
|
+
|
|
8
|
+
This file implements the PRESENT block cipher and the corresponding key
|
|
9
|
+
schedule as described in [BKLPPRSV2007]_. PRESENT is an example of an
|
|
10
|
+
SP-network and consists of 31 rounds. The block length is 64 bits and two key
|
|
11
|
+
lengths of 80 and 128 bits are supported.
|
|
12
|
+
|
|
13
|
+
This implementation is meant for experimental and educational usage only,
|
|
14
|
+
do not use it in production code!
|
|
15
|
+
|
|
16
|
+
EXAMPLES:
|
|
17
|
+
|
|
18
|
+
Encrypt a message::
|
|
19
|
+
|
|
20
|
+
sage: from sage.crypto.block_cipher.present import PRESENT
|
|
21
|
+
sage: present = PRESENT()
|
|
22
|
+
sage: present.encrypt(plaintext=0, key=0).hex()
|
|
23
|
+
'2844b365c06992a3'
|
|
24
|
+
|
|
25
|
+
And decrypt it again::
|
|
26
|
+
|
|
27
|
+
sage: present.decrypt(ciphertext=0x2844b365c06992a3, key=0)
|
|
28
|
+
0
|
|
29
|
+
|
|
30
|
+
Have a look at the used round keys::
|
|
31
|
+
|
|
32
|
+
sage: from sage.crypto.block_cipher.present import PRESENT_KS
|
|
33
|
+
sage: ks = PRESENT_KS()
|
|
34
|
+
sage: [k.hex() for k in ks(0)]
|
|
35
|
+
['0',
|
|
36
|
+
'c000000000000000',
|
|
37
|
+
...
|
|
38
|
+
'6dab31744f41d700']
|
|
39
|
+
|
|
40
|
+
Tweak around with the cipher::
|
|
41
|
+
|
|
42
|
+
sage: from sage.crypto.sbox import SBox
|
|
43
|
+
sage: cipher = PRESENT(rounds=1, doFinalRound=False)
|
|
44
|
+
sage: cipher.sbox = SBox(range(16))
|
|
45
|
+
sage: cipher.keySchedule = lambda x: [0, 0] # return the 0 keys as round keys
|
|
46
|
+
sage: cipher.encrypt(plaintext=0x1234, key=0x0).hex()
|
|
47
|
+
'1234'
|
|
48
|
+
|
|
49
|
+
AUTHORS:
|
|
50
|
+
|
|
51
|
+
- Lukas Stennes (2019-02-01): initial version
|
|
52
|
+
"""
|
|
53
|
+
|
|
54
|
+
# ****************************************************************************
|
|
55
|
+
# Copyright (C) 2013 Lukas Stennes <lukas.stennes@rub.de>
|
|
56
|
+
#
|
|
57
|
+
# This program is free software: you can redistribute it and/or modify
|
|
58
|
+
# it under the terms of the GNU General Public License as published by
|
|
59
|
+
# the Free Software Foundation, either version 2 of the License, or
|
|
60
|
+
# (at your option) any later version.
|
|
61
|
+
# https://www.gnu.org/licenses/
|
|
62
|
+
# ****************************************************************************
|
|
63
|
+
from sage.structure.sage_object import SageObject
|
|
64
|
+
from sage.rings.integer_ring import ZZ
|
|
65
|
+
from sage.rings.integer import Integer
|
|
66
|
+
from sage.modules.free_module_element import vector
|
|
67
|
+
from sage.rings.finite_rings.finite_field_constructor import GF
|
|
68
|
+
from sage.structure.element import Vector
|
|
69
|
+
from sage.crypto.sboxes import PRESENT as PRESENTSBOX
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
def _smallscale_present_linearlayer(nsboxes=16):
|
|
73
|
+
"""
|
|
74
|
+
.. TODO::
|
|
75
|
+
|
|
76
|
+
switch to sage.crypto.linearlayer
|
|
77
|
+
(:issue:`25735`) as soon as it is included in sage
|
|
78
|
+
|
|
79
|
+
EXAMPLES::
|
|
80
|
+
|
|
81
|
+
sage: from sage.crypto.block_cipher.present import _smallscale_present_linearlayer
|
|
82
|
+
sage: _smallscale_present_linearlayer(4)
|
|
83
|
+
[1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
|
|
84
|
+
[0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0]
|
|
85
|
+
[0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0]
|
|
86
|
+
[0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0]
|
|
87
|
+
[0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
|
|
88
|
+
[0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0]
|
|
89
|
+
[0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0]
|
|
90
|
+
[0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0]
|
|
91
|
+
[0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0]
|
|
92
|
+
[0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0]
|
|
93
|
+
[0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0]
|
|
94
|
+
[0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0]
|
|
95
|
+
[0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0]
|
|
96
|
+
[0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0]
|
|
97
|
+
[0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0]
|
|
98
|
+
[0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1]
|
|
99
|
+
"""
|
|
100
|
+
from sage.modules.free_module import VectorSpace
|
|
101
|
+
from sage.modules.free_module_element import vector
|
|
102
|
+
from sage.matrix.constructor import Matrix
|
|
103
|
+
from sage.rings.finite_rings.finite_field_constructor import GF
|
|
104
|
+
|
|
105
|
+
def present_llayer(n, x):
|
|
106
|
+
dim = 4*n
|
|
107
|
+
y = [0]*dim
|
|
108
|
+
for i in range(dim-1):
|
|
109
|
+
y[i] = x[(n * i) % (dim - 1)]
|
|
110
|
+
y[dim-1] = x[dim-1]
|
|
111
|
+
return vector(GF(2), y)
|
|
112
|
+
|
|
113
|
+
m = Matrix(GF(2), [present_llayer(nsboxes, ei)
|
|
114
|
+
for ei in VectorSpace(GF(2), 4*nsboxes).basis()])
|
|
115
|
+
return m
|
|
116
|
+
|
|
117
|
+
|
|
118
|
+
class PRESENT(SageObject):
|
|
119
|
+
r"""
|
|
120
|
+
This class implements PRESENT described in [BKLPPRSV2007]_.
|
|
121
|
+
|
|
122
|
+
EXAMPLES:
|
|
123
|
+
|
|
124
|
+
You can invoke PRESENT encryption/decryption either by calling PRESENT with
|
|
125
|
+
an appropriate flag::
|
|
126
|
+
|
|
127
|
+
sage: from sage.crypto.block_cipher.present import PRESENT
|
|
128
|
+
sage: present = PRESENT()
|
|
129
|
+
sage: P = 0xFFFFFFFFFFFFFFFF
|
|
130
|
+
sage: K = 0x0
|
|
131
|
+
sage: present(present(P, K, 'encrypt'), K, 'decrypt') == P
|
|
132
|
+
True
|
|
133
|
+
|
|
134
|
+
Or by calling encryption/decryption methods directly::
|
|
135
|
+
|
|
136
|
+
sage: C = present.encrypt(P, K)
|
|
137
|
+
sage: P == present.decrypt(C, K)
|
|
138
|
+
True
|
|
139
|
+
|
|
140
|
+
The number of rounds can be reduced easily::
|
|
141
|
+
|
|
142
|
+
sage: present = PRESENT(rounds=15)
|
|
143
|
+
sage: present(present(P, K, 'encrypt'), K, 'decrypt') == P
|
|
144
|
+
True
|
|
145
|
+
|
|
146
|
+
You can use integers or a list-like bit representation for the inputs. If
|
|
147
|
+
the input is an integer the output will be too. If it is list-like the
|
|
148
|
+
output will be a bit vector::
|
|
149
|
+
|
|
150
|
+
sage: P = ZZ(0).digits(2,padto=64)
|
|
151
|
+
sage: K = ZZ(0).digits(2,padto=80)
|
|
152
|
+
sage: list(present(present(P, K, 'encrypt'), K, 'decrypt')) == P
|
|
153
|
+
True
|
|
154
|
+
sage: P = ZZ(0).digits(2,padto=64)
|
|
155
|
+
sage: K = 0x0
|
|
156
|
+
sage: list(present(present(P, K, 'encrypt'), K, 'decrypt')) == P
|
|
157
|
+
True
|
|
158
|
+
|
|
159
|
+
The 80-bit version of PRESENT is used by default but the 128-bit version is
|
|
160
|
+
also implemented::
|
|
161
|
+
|
|
162
|
+
sage: present = PRESENT(128)
|
|
163
|
+
sage: P = 0x0123456789abcdef
|
|
164
|
+
sage: K = 0x00112233445566778899aabbccddeeff
|
|
165
|
+
sage: present(present(P, K, 'encrypt'), K, 'decrypt') == P
|
|
166
|
+
True
|
|
167
|
+
|
|
168
|
+
.. SEEALSO::
|
|
169
|
+
|
|
170
|
+
:class:`PRESENT_KS`
|
|
171
|
+
:mod:`sage.crypto.sboxes`
|
|
172
|
+
|
|
173
|
+
.. automethod:: __init__
|
|
174
|
+
.. automethod:: __call__
|
|
175
|
+
"""
|
|
176
|
+
|
|
177
|
+
def __init__(self, keySchedule=80, rounds=None, doFinalRound=False):
|
|
178
|
+
r"""
|
|
179
|
+
Construct an instance of PRESENT.
|
|
180
|
+
|
|
181
|
+
INPUT:
|
|
182
|
+
|
|
183
|
+
- ``keySchedule`` -- (default: ``80``) the key schedule that will be
|
|
184
|
+
used for encryption and decryption. Use ``80`` or ``128`` as a
|
|
185
|
+
shortcut for the original key schedules from [BKLPPRSV2007]_.
|
|
186
|
+
|
|
187
|
+
- ``rounds`` -- integer (default: ``None``); the number of rounds. If
|
|
188
|
+
``None`` the number of rounds of the key schedule is used.
|
|
189
|
+
|
|
190
|
+
- ``doFinalRound`` -- boolean (default: ``False``); flag to
|
|
191
|
+
control whether the linear layer in the last round should take place
|
|
192
|
+
or not. Since the last linear layer does not add any security, it
|
|
193
|
+
usually does not take place in real world implementations for
|
|
194
|
+
performance reasons.
|
|
195
|
+
|
|
196
|
+
EXAMPLES:
|
|
197
|
+
|
|
198
|
+
By default a 80-bit version with 31 rounds is created::
|
|
199
|
+
|
|
200
|
+
sage: from sage.crypto.block_cipher.present import PRESENT
|
|
201
|
+
sage: PRESENT() # indirect doctest
|
|
202
|
+
PRESENT block cipher with 31 rounds, deactivated linear layer in
|
|
203
|
+
last round and the following key schedule:
|
|
204
|
+
Original PRESENT key schedule with 80-bit keys and 31 rounds
|
|
205
|
+
|
|
206
|
+
The 128-bit version is also implemented::
|
|
207
|
+
|
|
208
|
+
sage: PRESENT(128) # indirect doctest
|
|
209
|
+
PRESENT block cipher with 31 rounds, deactivated linear layer in
|
|
210
|
+
last round and the following key schedule:
|
|
211
|
+
Original PRESENT key schedule with 128-bit keys and 31 rounds
|
|
212
|
+
|
|
213
|
+
Reducing the number of rounds is simple. But increasing it is not
|
|
214
|
+
possible::
|
|
215
|
+
|
|
216
|
+
sage: PRESENT(keySchedule=80, rounds=23) # indirect doctest
|
|
217
|
+
PRESENT block cipher with 23 rounds, deactivated linear layer in
|
|
218
|
+
last round and the following key schedule:
|
|
219
|
+
Original PRESENT key schedule with 80-bit keys and 31 rounds
|
|
220
|
+
sage: PRESENT(80, 32) # indirect doctest
|
|
221
|
+
Traceback (most recent call last):
|
|
222
|
+
...
|
|
223
|
+
ValueError: number of rounds must be less or equal to the number
|
|
224
|
+
of rounds of the key schedule
|
|
225
|
+
|
|
226
|
+
|
|
227
|
+
By default the linear layer operation in the last round is omitted but
|
|
228
|
+
of course you can enable it::
|
|
229
|
+
|
|
230
|
+
sage: PRESENT(doFinalRound=True) # indirect doctest
|
|
231
|
+
PRESENT block cipher with 31 rounds, activated linear layer in
|
|
232
|
+
last round and the following key schedule:
|
|
233
|
+
Original PRESENT key schedule with 80-bit keys and 31 rounds
|
|
234
|
+
|
|
235
|
+
You can use arbitrary key schedules. Since it is the only one
|
|
236
|
+
implemented here the original key schedule is used for demonstration::
|
|
237
|
+
|
|
238
|
+
sage: from sage.crypto.block_cipher.present import PRESENT_KS
|
|
239
|
+
sage: PRESENT(keySchedule=PRESENT_KS(80, 15)) # indirect doctest
|
|
240
|
+
PRESENT block cipher with 15 rounds, deactivated linear layer in
|
|
241
|
+
last round and the following key schedule:
|
|
242
|
+
Original PRESENT key schedule with 80-bit keys and 15 rounds
|
|
243
|
+
|
|
244
|
+
.. SEEALSO::
|
|
245
|
+
|
|
246
|
+
:class:`PRESENT_KS`
|
|
247
|
+
"""
|
|
248
|
+
if keySchedule == 80:
|
|
249
|
+
self.keySchedule = PRESENT_KS()
|
|
250
|
+
self._keysize = 80
|
|
251
|
+
elif keySchedule == 128:
|
|
252
|
+
self.keySchedule = PRESENT_KS(128)
|
|
253
|
+
self._keysize = 128
|
|
254
|
+
else:
|
|
255
|
+
self.keySchedule = keySchedule
|
|
256
|
+
if rounds is None:
|
|
257
|
+
self._rounds = self.keySchedule._rounds
|
|
258
|
+
elif rounds <= self.keySchedule._rounds:
|
|
259
|
+
self._rounds = rounds
|
|
260
|
+
else:
|
|
261
|
+
raise ValueError('number of rounds must be less or equal to the '
|
|
262
|
+
'number of rounds of the key schedule')
|
|
263
|
+
self._blocksize = 64
|
|
264
|
+
self.sbox = PRESENTSBOX
|
|
265
|
+
self._permutationMatrix = _smallscale_present_linearlayer()
|
|
266
|
+
self._inversePermutationMatrix = self._permutationMatrix.inverse()
|
|
267
|
+
self._doFinalRound = doFinalRound
|
|
268
|
+
|
|
269
|
+
def __call__(self, block, key, algorithm='encrypt'):
|
|
270
|
+
r"""
|
|
271
|
+
Apply PRESENT encryption or decryption on ``block`` using ``key``.
|
|
272
|
+
The flag ``algorithm`` controls what action is to be performed on
|
|
273
|
+
``block``.
|
|
274
|
+
|
|
275
|
+
INPUT:
|
|
276
|
+
|
|
277
|
+
- ``block`` -- integer or bit list-like; the plaintext or ciphertext
|
|
278
|
+
|
|
279
|
+
- ``K`` -- integer or bit list-like; the key
|
|
280
|
+
|
|
281
|
+
- ``algorithm`` -- string (default: ``'encrypt'``); a flag to signify
|
|
282
|
+
whether encryption or decryption is to be applied to ``B``. The
|
|
283
|
+
encryption flag is ``'encrypt'`` and the decryption flag is
|
|
284
|
+
``'decrypt'``
|
|
285
|
+
|
|
286
|
+
OUTPUT:
|
|
287
|
+
|
|
288
|
+
- The plaintext or ciphertext corresponding to ``block``, obtained using
|
|
289
|
+
the ``key``. If ``block`` is an integer the output will be too. If
|
|
290
|
+
``block`` is list-like the output will be a bit vector.
|
|
291
|
+
|
|
292
|
+
EXAMPLES::
|
|
293
|
+
|
|
294
|
+
sage: from sage.crypto.block_cipher.present import PRESENT
|
|
295
|
+
sage: present = PRESENT(doFinalRound=True)
|
|
296
|
+
sage: P = 0xFFFFFFFFFFFFFFFF
|
|
297
|
+
sage: K = 0x0
|
|
298
|
+
sage: present(P, K, 'encrypt').hex()
|
|
299
|
+
'a112ffc72f68417b'
|
|
300
|
+
"""
|
|
301
|
+
if algorithm == 'encrypt':
|
|
302
|
+
return self.encrypt(block, key)
|
|
303
|
+
elif algorithm == 'decrypt':
|
|
304
|
+
return self.decrypt(block, key)
|
|
305
|
+
else:
|
|
306
|
+
raise ValueError('Algorithm must be \'encrypt\' or \'decrypt\' and'
|
|
307
|
+
' not \'%s\'' % algorithm)
|
|
308
|
+
|
|
309
|
+
def __eq__(self, other):
|
|
310
|
+
r"""
|
|
311
|
+
Compare ``self`` with ``other``.
|
|
312
|
+
|
|
313
|
+
PRESENT objects are the same if all attributes are the same.
|
|
314
|
+
|
|
315
|
+
EXAMPLES::
|
|
316
|
+
|
|
317
|
+
sage: from sage.crypto.block_cipher.present import PRESENT
|
|
318
|
+
sage: PRESENT(80) == PRESENT(80) # indirect doctest
|
|
319
|
+
True
|
|
320
|
+
sage: PRESENT(80) == PRESENT(128) # indirect doctest
|
|
321
|
+
False
|
|
322
|
+
sage: PRESENT(80) == 80 # indirect doctest
|
|
323
|
+
False
|
|
324
|
+
sage: present = PRESENT()
|
|
325
|
+
sage: present.sbox = present.sbox.inverse()
|
|
326
|
+
sage: present == PRESENT() # indirect doctest
|
|
327
|
+
False
|
|
328
|
+
"""
|
|
329
|
+
if not isinstance(other, PRESENT):
|
|
330
|
+
return False
|
|
331
|
+
else:
|
|
332
|
+
return self.__dict__ == other.__dict__
|
|
333
|
+
|
|
334
|
+
def __repr__(self):
|
|
335
|
+
r"""
|
|
336
|
+
A string representation of this PRESENT.
|
|
337
|
+
|
|
338
|
+
EXAMPLES::
|
|
339
|
+
|
|
340
|
+
sage: from sage.crypto.block_cipher.present import PRESENT
|
|
341
|
+
sage: PRESENT() # indirect doctest
|
|
342
|
+
PRESENT block cipher with 31 rounds, deactivated linear layer in
|
|
343
|
+
last round and the following key schedule:
|
|
344
|
+
Original PRESENT key schedule with 80-bit keys and 31 rounds
|
|
345
|
+
"""
|
|
346
|
+
return ('PRESENT block cipher with %s rounds, %s linear layer in last '
|
|
347
|
+
'round and the following key schedule:\n%s'
|
|
348
|
+
% (self._rounds, 'activated' if self._doFinalRound else
|
|
349
|
+
'deactivated', self.keySchedule.__repr__()))
|
|
350
|
+
|
|
351
|
+
def encrypt(self, plaintext, key):
|
|
352
|
+
r"""
|
|
353
|
+
Return the ciphertext corresponding to ``plaintext``, using PRESENT
|
|
354
|
+
encryption with ``key``.
|
|
355
|
+
|
|
356
|
+
INPUT:
|
|
357
|
+
|
|
358
|
+
- ``plaintext`` -- integer or bit list-like; the plaintext that will be
|
|
359
|
+
encrypted
|
|
360
|
+
|
|
361
|
+
- ``key`` -- integer or bit list-like; the key
|
|
362
|
+
|
|
363
|
+
OUTPUT:
|
|
364
|
+
|
|
365
|
+
- The ciphertext corresponding to ``plaintext``, obtained using the
|
|
366
|
+
``key``. If ``plaintext`` is an integer the output will be too. If
|
|
367
|
+
``plaintext`` is list-like the output will be a bit vector.
|
|
368
|
+
|
|
369
|
+
EXAMPLES:
|
|
370
|
+
|
|
371
|
+
The test vectors from [BKLPPRSV2007]_ are checked here::
|
|
372
|
+
|
|
373
|
+
sage: from sage.crypto.block_cipher.present import PRESENT
|
|
374
|
+
sage: present = PRESENT(doFinalRound=True)
|
|
375
|
+
sage: p1 = 0x0
|
|
376
|
+
sage: k1 = 0x0
|
|
377
|
+
sage: c1 = 0x5579C1387B228445
|
|
378
|
+
sage: present.encrypt(p1, k1) == c1
|
|
379
|
+
True
|
|
380
|
+
sage: p2 = 0x0
|
|
381
|
+
sage: k2 = 0xFFFFFFFFFFFFFFFFFFFF
|
|
382
|
+
sage: c2 = 0xE72C46C0F5945049
|
|
383
|
+
sage: present.encrypt(p2, k2) == c2
|
|
384
|
+
True
|
|
385
|
+
sage: p3 = 0xFFFFFFFFFFFFFFFF
|
|
386
|
+
sage: k3 = 0x0
|
|
387
|
+
sage: c3 = 0xA112FFC72F68417B
|
|
388
|
+
sage: present.encrypt(p3, k3) == c3
|
|
389
|
+
True
|
|
390
|
+
sage: p4 = 0xFFFFFFFFFFFFFFFF
|
|
391
|
+
sage: k4 = 0xFFFFFFFFFFFFFFFFFFFF
|
|
392
|
+
sage: c4 = 0x3333DCD3213210D2
|
|
393
|
+
sage: present.encrypt(p4, k4) == c4
|
|
394
|
+
True
|
|
395
|
+
|
|
396
|
+
ALGORITHM:
|
|
397
|
+
|
|
398
|
+
Description of the encryption function based on [BKLPPRSV2007]_:
|
|
399
|
+
|
|
400
|
+
A top-level algorithmic description of PRESENT encryption::
|
|
401
|
+
|
|
402
|
+
generateRoundKeys()
|
|
403
|
+
for i = 1 to 31 do
|
|
404
|
+
addRoundkey(STATE, K_i)
|
|
405
|
+
sBoxLayer(STATE)
|
|
406
|
+
pLayer(STATE)
|
|
407
|
+
end for
|
|
408
|
+
addRoundkey(STATE, K_{32})
|
|
409
|
+
|
|
410
|
+
Each of the 31 rounds consists of an XOR operation to introduce a round
|
|
411
|
+
key `K_i` for `1 \leq i \leq 32`, where `K_{32}` is used for
|
|
412
|
+
post-whitening, a linear bitwise permutation and a non-linear
|
|
413
|
+
substitution layer. The non-linear layer uses a single 4-bit S-box
|
|
414
|
+
which is applied 16 times in parallel in each round. Each stage but
|
|
415
|
+
addRoundkey is specified in its corresponding function.
|
|
416
|
+
|
|
417
|
+
**addRoundkey:**
|
|
418
|
+
Given round key `K_i = \kappa^i_{63} \dots \kappa^i_0` for `1 \leq i
|
|
419
|
+
\leq 32` and current STATE `b_{63} \dots b_0`, addRoundkey consists of
|
|
420
|
+
the operation for `0 \leq j \leq 63`, `b_j = b_j \oplus \kappa^i_j`.
|
|
421
|
+
"""
|
|
422
|
+
if isinstance(plaintext, (list, tuple, Vector)):
|
|
423
|
+
inputType = 'vector'
|
|
424
|
+
elif isinstance(plaintext, (Integer, int)):
|
|
425
|
+
inputType = 'integer'
|
|
426
|
+
state = convert_to_vector(plaintext, 64)
|
|
427
|
+
key = convert_to_vector(key, self._keysize)
|
|
428
|
+
roundKeys = self.keySchedule(key)
|
|
429
|
+
for r, K in enumerate(roundKeys[:self._rounds]):
|
|
430
|
+
state = self.round(state, r, K)
|
|
431
|
+
state = state + roundKeys[self._rounds]
|
|
432
|
+
return state if inputType == 'vector' else ZZ(list(state), 2)
|
|
433
|
+
|
|
434
|
+
def decrypt(self, ciphertext, key):
|
|
435
|
+
r"""
|
|
436
|
+
Return the plaintext corresponding to the ``ciphertext``, using PRESENT decryption with ``key``.
|
|
437
|
+
|
|
438
|
+
INPUT:
|
|
439
|
+
|
|
440
|
+
- ``ciphertext`` -- integer or bit list-like; the ciphertext that will
|
|
441
|
+
be decrypted
|
|
442
|
+
|
|
443
|
+
- ``key`` -- integer or bit list-like; the key
|
|
444
|
+
|
|
445
|
+
OUTPUT:
|
|
446
|
+
|
|
447
|
+
- The plaintext corresponding to ``ciphertext``, obtained using the
|
|
448
|
+
``key``. If ``ciphertext`` is an integer the output will be too. If
|
|
449
|
+
``ciphertext`` is list-like the output will be a bit vector.
|
|
450
|
+
|
|
451
|
+
EXAMPLES:
|
|
452
|
+
|
|
453
|
+
The test vectors from [BKLPPRSV2007]_ are checked here::
|
|
454
|
+
|
|
455
|
+
sage: from sage.crypto.block_cipher.present import PRESENT
|
|
456
|
+
sage: present = PRESENT(doFinalRound=True)
|
|
457
|
+
sage: p1 = 0x0
|
|
458
|
+
sage: k1 = 0x0
|
|
459
|
+
sage: c1 = 0x5579C1387B228445
|
|
460
|
+
sage: present.decrypt(c1, k1) == p1
|
|
461
|
+
True
|
|
462
|
+
sage: p2 = 0x0
|
|
463
|
+
sage: k2 = 0xFFFFFFFFFFFFFFFFFFFF
|
|
464
|
+
sage: c2 = 0xE72C46C0F5945049
|
|
465
|
+
sage: present.decrypt(c2, k2) == p2
|
|
466
|
+
True
|
|
467
|
+
sage: p3 = 0xFFFFFFFFFFFFFFFF
|
|
468
|
+
sage: k3 = 0x0
|
|
469
|
+
sage: c3 = 0xA112FFC72F68417B
|
|
470
|
+
sage: present.decrypt(c3, k3) == p3
|
|
471
|
+
True
|
|
472
|
+
sage: p4 = 0xFFFFFFFFFFFFFFFF
|
|
473
|
+
sage: k4 = 0xFFFFFFFFFFFFFFFFFFFF
|
|
474
|
+
sage: c4 = 0x3333DCD3213210D2
|
|
475
|
+
sage: present.decrypt(c4, k4) == p4
|
|
476
|
+
True
|
|
477
|
+
"""
|
|
478
|
+
if isinstance(ciphertext, (list, tuple, Vector)):
|
|
479
|
+
inputType = 'vector'
|
|
480
|
+
elif isinstance(ciphertext, (Integer, int)):
|
|
481
|
+
inputType = 'integer'
|
|
482
|
+
state = convert_to_vector(ciphertext, 64)
|
|
483
|
+
key = convert_to_vector(key, self._keysize)
|
|
484
|
+
roundKeys = self.keySchedule(key)
|
|
485
|
+
state = state + roundKeys[self._rounds]
|
|
486
|
+
for r, K in enumerate(roundKeys[:self._rounds][::-1]):
|
|
487
|
+
state = self.round(state, r, K, inverse=True)
|
|
488
|
+
return state if inputType == 'vector' else ZZ(list(state), 2)
|
|
489
|
+
|
|
490
|
+
def round(self, state, round_counter, round_key, inverse=False):
|
|
491
|
+
"""
|
|
492
|
+
Apply one round of PRESENT to ``state`` and return the result.
|
|
493
|
+
|
|
494
|
+
EXAMPLES::
|
|
495
|
+
|
|
496
|
+
sage: from sage.crypto.block_cipher.present import PRESENT
|
|
497
|
+
sage: from sage.crypto.block_cipher.present import convert_to_vector
|
|
498
|
+
sage: present = PRESENT(128)
|
|
499
|
+
sage: k = convert_to_vector(0x0011223344556677, 64)
|
|
500
|
+
sage: p = convert_to_vector(0x0123456789abcdef, 64)
|
|
501
|
+
sage: ZZ(list(present.round(p, 0, k)), 2).hex()
|
|
502
|
+
'ad0ed4ca386b6559'
|
|
503
|
+
"""
|
|
504
|
+
out = state[:]
|
|
505
|
+
if not inverse:
|
|
506
|
+
out = out + round_key
|
|
507
|
+
out = self.sbox_layer(out)
|
|
508
|
+
if self._doFinalRound or round_counter != self._rounds - 1:
|
|
509
|
+
out = self.linear_layer(out)
|
|
510
|
+
else:
|
|
511
|
+
if self._doFinalRound or round_counter != 0:
|
|
512
|
+
out = self.linear_layer(out, inverse=True)
|
|
513
|
+
out = self.sbox_layer(out, inverse=True)
|
|
514
|
+
out = out + round_key
|
|
515
|
+
return out
|
|
516
|
+
|
|
517
|
+
def sbox_layer(self, state, inverse=False):
|
|
518
|
+
r"""
|
|
519
|
+
Apply the sBoxLayer of PRESENT to the bit vector ``state`` and return
|
|
520
|
+
the result.
|
|
521
|
+
|
|
522
|
+
The S-box used in PRESENT is a 4-bit to 4-bit S-box. The action of this
|
|
523
|
+
box in hexadecimal notation is given by the following table.
|
|
524
|
+
|
|
525
|
+
+------+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|
|
526
|
+
| x | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | A | B | C | D | E | F |
|
|
527
|
+
+------+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|
|
528
|
+
| S[x] | C | 5 | 6 | B | 9 | 0 | A | D | 3 | E | F | 8 | 4 | 7 | 1 | 2 |
|
|
529
|
+
+------+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|
|
530
|
+
|
|
531
|
+
For sBoxLayer the current STATE `b_{63} \dots b_0` is considered as
|
|
532
|
+
sixteen 4-bit words `w_{15} \dots w_0` where `w_i =
|
|
533
|
+
b_{4i+3}||b_{4i+2}||b_{4i+1}||b_{4i}` for `0 \leq i \leq 15` and the
|
|
534
|
+
output nibble S[`w_i`] provides the updated state values in the obvious
|
|
535
|
+
way.
|
|
536
|
+
|
|
537
|
+
EXAMPLES::
|
|
538
|
+
|
|
539
|
+
sage: from sage.crypto.block_cipher.present import PRESENT
|
|
540
|
+
sage: present = PRESENT()
|
|
541
|
+
sage: state = vector(GF(2), 64, [0]*64)
|
|
542
|
+
sage: present.sbox_layer(state)
|
|
543
|
+
(0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0,
|
|
544
|
+
1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1,
|
|
545
|
+
0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1)
|
|
546
|
+
sage: state = vector(GF(2), 64, [1]+[0]*63)
|
|
547
|
+
sage: present.sbox_layer(state)
|
|
548
|
+
(1, 0, 1, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0,
|
|
549
|
+
1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1,
|
|
550
|
+
0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1)
|
|
551
|
+
|
|
552
|
+
.. NOTE::
|
|
553
|
+
|
|
554
|
+
:mod:`sage.crypto.sbox` uses big endian by default whereas most of
|
|
555
|
+
Sage uses little endian. So to use the big endian PRESENT Sbox from
|
|
556
|
+
:mod:`sage.crypto.sboxes` :func:`sbox_layer` has to do some endian
|
|
557
|
+
conversion (i.e. reverse input and output of the Sbox). Keep this in
|
|
558
|
+
mind if you change the Sbox or :func:`sbox_layer`.
|
|
559
|
+
"""
|
|
560
|
+
sbox = self.sbox if not inverse else self.sbox.inverse()
|
|
561
|
+
out = vector(GF(2), 64)
|
|
562
|
+
for nibble in [slice(4*j, 4*j+4) for j in range(16)]:
|
|
563
|
+
out[nibble] = sbox(state[nibble][::-1])[::-1]
|
|
564
|
+
return out
|
|
565
|
+
|
|
566
|
+
def linear_layer(self, state, inverse=False):
|
|
567
|
+
"""
|
|
568
|
+
Apply the pLayer of PRESENT to the bit vector ``state`` and return the
|
|
569
|
+
result.
|
|
570
|
+
|
|
571
|
+
The bit permutation used in PRESENT is given by the following
|
|
572
|
+
table. Bit `i` of STATE is moved to bit position `P(i)`.
|
|
573
|
+
|
|
574
|
+
+------+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+
|
|
575
|
+
| i | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 |
|
|
576
|
+
+------+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+
|
|
577
|
+
| P(i) | 0 | 16 | 32 | 48 | 1 | 17 | 33 | 49 | 2 | 18 | 34 | 50 | 3 | 19 | 35 | 51 |
|
|
578
|
+
+------+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+
|
|
579
|
+
+------+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+
|
|
580
|
+
| i | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 |
|
|
581
|
+
+------+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+
|
|
582
|
+
| P(i) | 4 | 20 | 36 | 52 | 5 | 21 | 37 | 53 | 6 | 22 | 38 | 54 | 7 | 23 | 39 | 55 |
|
|
583
|
+
+------+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+
|
|
584
|
+
+------+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+
|
|
585
|
+
| i | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 |
|
|
586
|
+
+------+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+
|
|
587
|
+
| P(i) | 8 | 24 | 40 | 56 | 9 | 25 | 41 | 57 | 10 | 26 | 42 | 58 | 11 | 27 | 43 | 59 |
|
|
588
|
+
+------+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+
|
|
589
|
+
+------+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+
|
|
590
|
+
| i | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 |
|
|
591
|
+
+------+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+
|
|
592
|
+
| P(i) | 12 | 28 | 44 | 60 | 13 | 29 | 45 | 61 | 14 | 30 | 46 | 62 | 15 | 31 | 47 | 63 |
|
|
593
|
+
+------+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+
|
|
594
|
+
|
|
595
|
+
EXAMPLES::
|
|
596
|
+
|
|
597
|
+
sage: from sage.crypto.block_cipher.present import PRESENT
|
|
598
|
+
sage: present = PRESENT()
|
|
599
|
+
sage: state = vector(GF(2), 64, [0, 1]+[0]*62)
|
|
600
|
+
sage: present.linear_layer(state)
|
|
601
|
+
(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0,
|
|
602
|
+
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
603
|
+
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)
|
|
604
|
+
"""
|
|
605
|
+
m = self._permutationMatrix if not inverse else self._inversePermutationMatrix
|
|
606
|
+
return m * state
|
|
607
|
+
|
|
608
|
+
|
|
609
|
+
class PRESENT_KS(SageObject):
|
|
610
|
+
r"""
|
|
611
|
+
This class implements the PRESENT key schedules for both 80-bit and 128-bit
|
|
612
|
+
keys as described in [BKLPPRSV2007]_.
|
|
613
|
+
|
|
614
|
+
EXAMPLES:
|
|
615
|
+
|
|
616
|
+
Initialise the key schedule with a `master\_key` to use it as an iterable::
|
|
617
|
+
|
|
618
|
+
sage: from sage.crypto.block_cipher.present import PRESENT_KS
|
|
619
|
+
sage: ks = PRESENT_KS(master_key=0)
|
|
620
|
+
sage: ks[0] == 0x0
|
|
621
|
+
True
|
|
622
|
+
sage: ks[31] == 0x6dab31744f41d700
|
|
623
|
+
True
|
|
624
|
+
|
|
625
|
+
Or omit the `master\_key` and pass a key when calling the key schedule::
|
|
626
|
+
|
|
627
|
+
sage: ks = PRESENT_KS(keysize=128)
|
|
628
|
+
sage: K = ks(0x00112233445566778899aabbccddeeff)
|
|
629
|
+
sage: K[0] == 0x0011223344556677
|
|
630
|
+
True
|
|
631
|
+
sage: K[31] == 0x091989a5ae8eab21
|
|
632
|
+
True
|
|
633
|
+
|
|
634
|
+
ALGORITHM:
|
|
635
|
+
|
|
636
|
+
Description of the key schedule for 64-bit and 128-bit keys from
|
|
637
|
+
[BKLPPRSV2007]_:
|
|
638
|
+
|
|
639
|
+
The key schedule for 64-bit keys works as follows:
|
|
640
|
+
|
|
641
|
+
At round `i` the 64-bit round key `K_i = \kappa_{63}\kappa_{62} \dots
|
|
642
|
+
\kappa_0` consists of the 64 leftmost bits of the current contents of
|
|
643
|
+
register `K`. Thus at round `i` we have that:
|
|
644
|
+
|
|
645
|
+
.. MATH::
|
|
646
|
+
|
|
647
|
+
K_i = \kappa_{63}\kappa_{62}\dots \kappa_0 = k_{79}k_{78}\dots k_{16}.
|
|
648
|
+
|
|
649
|
+
After extracting the round key `K_i`, the key register `K = k_{79}k_{78}
|
|
650
|
+
\dots k_0` is updated as follows:
|
|
651
|
+
|
|
652
|
+
.. MATH::
|
|
653
|
+
|
|
654
|
+
\begin{aligned}
|
|
655
|
+
\ [k_{79}k_{78}\dots k_{1}k_{0}] &= [k_{18}k_{17}\dots k_{20}k_{19}] \\
|
|
656
|
+
[k_{79}k_{78}k_{77}k_{76}] &= S[k_{79}k_{78}k_{77}k_{76}] \\
|
|
657
|
+
[k_{19}k_{18}k_{17}k_{16}k_{15}] &= [k_{19}k_{18}k_{17}k_{16}k_{15}]
|
|
658
|
+
\oplus round\_counter
|
|
659
|
+
\end{aligned}
|
|
660
|
+
|
|
661
|
+
Thus, the key register is rotated by 61 bit positions to the left, the
|
|
662
|
+
left-most four bits are passed through the PRESENT S-box, and the
|
|
663
|
+
round_counter value `i` is exclusive-ored with bits `k_{19}k_{18}k_{17}
|
|
664
|
+
k_{16}k_{15}` of `K` with the least significant bit of round_counter on
|
|
665
|
+
the right.
|
|
666
|
+
|
|
667
|
+
The key schedule for 128-bit keys works as follows:
|
|
668
|
+
|
|
669
|
+
At round `i` the 64-bit round key `K_i = \kappa_{63}\kappa_{62} \dots
|
|
670
|
+
\kappa_0` consists of the 64 leftmost bits fo the current contents of
|
|
671
|
+
register `K`. Thus at round `i` we have that:
|
|
672
|
+
|
|
673
|
+
.. MATH::
|
|
674
|
+
|
|
675
|
+
K_i = \kappa_{63}\kappa_{62}\dots \kappa_0 = k_{127}k_{126}\dots k_{64}
|
|
676
|
+
|
|
677
|
+
After extracting the round key `K_i`, the key register `K = k_{127}k_{126}
|
|
678
|
+
\dots k_0` is updated as follows:
|
|
679
|
+
|
|
680
|
+
.. MATH::
|
|
681
|
+
|
|
682
|
+
\begin{aligned}
|
|
683
|
+
\ [k_{127}k_{126}\dots k_{1}k_{0}] &= [k_{66}k_{65}\dots k_{68}k_{67}]
|
|
684
|
+
\\
|
|
685
|
+
[k_{127}k_{126}k_{125}k_{124}] &= S[k_{127}k_{126}k_{125}k_{124}]\\
|
|
686
|
+
[k_{123}k_{122}k_{121}k_{120}] &= S[k_{123}k_{122}k_{121}k_{120}]\\
|
|
687
|
+
[k_{66}k_{65}k_{64}k_{63}k_{62}] &= [k_{66}k_{65}k_{64}k_{63}k_{62}]
|
|
688
|
+
\oplus round\_counter
|
|
689
|
+
\end{aligned}
|
|
690
|
+
|
|
691
|
+
Thus, the key register is rotated by 61 bit positions to the left, the
|
|
692
|
+
left-most eight bits are passed through two PRESENT S-boxes, and the
|
|
693
|
+
round_counter value `i` is exclusive-ored with bits `k_{66}k_{65}k_{64}
|
|
694
|
+
k_{63}k_{62}` of `K` with the least significant bit of round_counter on
|
|
695
|
+
the right.
|
|
696
|
+
|
|
697
|
+
.. SEEALSO::
|
|
698
|
+
|
|
699
|
+
:class:`PRESENT`
|
|
700
|
+
:mod:`sage.crypto.sboxes`
|
|
701
|
+
|
|
702
|
+
.. NOTE::
|
|
703
|
+
|
|
704
|
+
:mod:`sage.crypto.sbox` uses big endian by default whereas most of Sage
|
|
705
|
+
uses little endian. So to use the big endian PRESENT Sbox from
|
|
706
|
+
:mod:`sage.crypto.sboxes` :class:`PRESENT_KS` has to do some endian
|
|
707
|
+
conversion (i.e. reverse input and output of the Sbox). Keep this in
|
|
708
|
+
mind if you change the Sbox or :func:`__call__`.
|
|
709
|
+
|
|
710
|
+
.. automethod:: __init__
|
|
711
|
+
.. automethod:: __call__
|
|
712
|
+
"""
|
|
713
|
+
|
|
714
|
+
def __init__(self, keysize=80, rounds=31, master_key=None):
|
|
715
|
+
r"""
|
|
716
|
+
Construct an instance of PRESENT_KS.
|
|
717
|
+
|
|
718
|
+
INPUT:
|
|
719
|
+
|
|
720
|
+
- ``keysize`` -- integer (default: 80); the size of the keys that
|
|
721
|
+
will be used in bits. It must be either 80 or 128.
|
|
722
|
+
|
|
723
|
+
- ``rounds`` -- integer (default: 31); the number of rounds
|
|
724
|
+
``self`` can create keys for
|
|
725
|
+
|
|
726
|
+
- ``master_key`` -- integer or bit list-like (default: ``None``); the
|
|
727
|
+
key that will be used
|
|
728
|
+
|
|
729
|
+
EXAMPLES::
|
|
730
|
+
|
|
731
|
+
sage: from sage.crypto.block_cipher.present import PRESENT_KS
|
|
732
|
+
sage: PRESENT_KS()
|
|
733
|
+
Original PRESENT key schedule with 80-bit keys and 31 rounds
|
|
734
|
+
|
|
735
|
+
.. NOTE::
|
|
736
|
+
|
|
737
|
+
If you want to use a PRESENT_KS object as an iterable you have to
|
|
738
|
+
pass a ``master_key`` value on initialisation. Otherwise you can
|
|
739
|
+
omit ``master_key`` and pass a key when you call the object.
|
|
740
|
+
"""
|
|
741
|
+
if keysize != 80 and keysize != 128:
|
|
742
|
+
raise ValueError('keysize must bei either 80 or 128 and not %s'
|
|
743
|
+
% keysize)
|
|
744
|
+
self._keysize = keysize
|
|
745
|
+
self._rounds = rounds
|
|
746
|
+
self.sbox = PRESENTSBOX
|
|
747
|
+
self._master_key = master_key
|
|
748
|
+
|
|
749
|
+
def __call__(self, K):
|
|
750
|
+
r"""
|
|
751
|
+
Return all round keys in a list.
|
|
752
|
+
|
|
753
|
+
INPUT:
|
|
754
|
+
|
|
755
|
+
- ``K`` -- integer or bit list-like; the key
|
|
756
|
+
|
|
757
|
+
OUTPUT:
|
|
758
|
+
|
|
759
|
+
- A list containing ``rounds + 1`` round keys. Since addRoundkey takes
|
|
760
|
+
place in every round and after the last round there must be
|
|
761
|
+
``rounds + 1`` round keys. If ``K`` is an integer the elements of
|
|
762
|
+
the output list will be too. If ``K`` is list-like the element of the
|
|
763
|
+
output list will be bit vectors.
|
|
764
|
+
|
|
765
|
+
EXAMPLES::
|
|
766
|
+
|
|
767
|
+
sage: from sage.crypto.block_cipher.present import PRESENT_KS
|
|
768
|
+
sage: ks = PRESENT_KS()
|
|
769
|
+
sage: ks(0)[31] == 0x6dab31744f41d700
|
|
770
|
+
True
|
|
771
|
+
|
|
772
|
+
.. NOTE::
|
|
773
|
+
|
|
774
|
+
If you want to use a PRESENT_KS object as an iterable you have to
|
|
775
|
+
pass a ``master_key`` value on initialisation. Otherwise you can
|
|
776
|
+
omit ``master_key`` and pass a key when you call the object.
|
|
777
|
+
"""
|
|
778
|
+
if isinstance(K, (list, tuple, Vector)):
|
|
779
|
+
inputType = 'vector'
|
|
780
|
+
elif isinstance(K, (Integer, int)):
|
|
781
|
+
inputType = 'integer'
|
|
782
|
+
K = convert_to_vector(K, self._keysize)
|
|
783
|
+
roundKeys = []
|
|
784
|
+
if self._keysize == 80:
|
|
785
|
+
for i in range(1, self._rounds+1):
|
|
786
|
+
roundKeys.append(K[16:])
|
|
787
|
+
K[0:] = list(K[19:]) + list(K[:19])
|
|
788
|
+
K[76:] = self.sbox(K[76:][::-1])[::-1]
|
|
789
|
+
rc = vector(GF(2), ZZ(i).digits(2, padto=5))
|
|
790
|
+
K[15:20] = K[15:20] + rc
|
|
791
|
+
roundKeys.append(K[16:])
|
|
792
|
+
elif self._keysize == 128:
|
|
793
|
+
for i in range(1, self._rounds+1):
|
|
794
|
+
roundKeys.append(K[64:])
|
|
795
|
+
K[0:] = list(K[67:]) + list(K[:67])
|
|
796
|
+
K[124:] = self.sbox(K[124:][::-1])[::-1]
|
|
797
|
+
K[120:124] = self.sbox(K[120:124][::-1])[::-1]
|
|
798
|
+
rc = vector(GF(2), ZZ(i).digits(2, padto=5))
|
|
799
|
+
K[62:67] = K[62:67] + rc
|
|
800
|
+
roundKeys.append(K[64:])
|
|
801
|
+
return roundKeys if inputType == 'vector' else [ZZ(list(k), 2) for k in
|
|
802
|
+
roundKeys]
|
|
803
|
+
|
|
804
|
+
def __eq__(self, other):
|
|
805
|
+
r"""
|
|
806
|
+
Compare ``self`` with ``other``.
|
|
807
|
+
|
|
808
|
+
PRESENT_KS objects are the same if all attributes are the same.
|
|
809
|
+
|
|
810
|
+
EXAMPLES::
|
|
811
|
+
|
|
812
|
+
sage: from sage.crypto.block_cipher.present import PRESENT_KS
|
|
813
|
+
sage: PRESENT_KS(80) == PRESENT_KS(80) # indirect doctest
|
|
814
|
+
True
|
|
815
|
+
sage: PRESENT_KS(80) == PRESENT_KS(128) # indirect doctest
|
|
816
|
+
False
|
|
817
|
+
sage: PRESENT_KS(80) == 80 # indirect doctest
|
|
818
|
+
False
|
|
819
|
+
"""
|
|
820
|
+
if not isinstance(other, PRESENT_KS):
|
|
821
|
+
return False
|
|
822
|
+
else:
|
|
823
|
+
return self.__dict__ == other.__dict__
|
|
824
|
+
|
|
825
|
+
def __repr__(self):
|
|
826
|
+
r"""
|
|
827
|
+
A string representation of this PRESENT_KS.
|
|
828
|
+
|
|
829
|
+
EXAMPLES::
|
|
830
|
+
|
|
831
|
+
sage: from sage.crypto.block_cipher.present import PRESENT_KS
|
|
832
|
+
sage: PRESENT_KS() # indirect doctest
|
|
833
|
+
Original PRESENT key schedule with 80-bit keys and 31 rounds
|
|
834
|
+
"""
|
|
835
|
+
return ('Original PRESENT key schedule with %s-bit keys and %s rounds'
|
|
836
|
+
% (self._keysize, self._rounds))
|
|
837
|
+
|
|
838
|
+
def __getitem__(self, r):
|
|
839
|
+
r"""
|
|
840
|
+
Compute the sub key for round ``r`` derived from initial master key.
|
|
841
|
+
|
|
842
|
+
The key schedule object has to have been initialised with the
|
|
843
|
+
``master_key`` argument.
|
|
844
|
+
|
|
845
|
+
INPUT:
|
|
846
|
+
|
|
847
|
+
- ``r`` -- integer; the round for which the sub key is computed
|
|
848
|
+
|
|
849
|
+
EXAMPLES::
|
|
850
|
+
|
|
851
|
+
sage: from sage.crypto.block_cipher.present import PRESENT_KS
|
|
852
|
+
sage: ks = PRESENT_KS(master_key=0x0)
|
|
853
|
+
sage: ks[0] == 0x0 # indirect doctest
|
|
854
|
+
True
|
|
855
|
+
sage: ks[31] == 0x6dab31744f41d700 # indirect doctest
|
|
856
|
+
True
|
|
857
|
+
"""
|
|
858
|
+
if self._master_key is None:
|
|
859
|
+
raise ValueError('Key not set during initialisation')
|
|
860
|
+
return self(self._master_key)[r]
|
|
861
|
+
|
|
862
|
+
def __iter__(self):
|
|
863
|
+
"""
|
|
864
|
+
Iterate over the ``self._rounds + 1`` PRESENT round keys, derived from
|
|
865
|
+
``master_key``.
|
|
866
|
+
|
|
867
|
+
EXAMPLES::
|
|
868
|
+
|
|
869
|
+
sage: from sage.crypto.block_cipher.present import PRESENT_KS
|
|
870
|
+
sage: K = [k for k in PRESENT_KS(master_key=0x0)]
|
|
871
|
+
sage: K[0] == 0x0 # indirect doctest
|
|
872
|
+
True
|
|
873
|
+
sage: K[31] == 0x6dab31744f41d700 # indirect doctest
|
|
874
|
+
True
|
|
875
|
+
"""
|
|
876
|
+
if self._master_key is None:
|
|
877
|
+
raise ValueError('Key not set during initialisation')
|
|
878
|
+
return iter(self(self._master_key))
|
|
879
|
+
|
|
880
|
+
|
|
881
|
+
def convert_to_vector(I, L):
|
|
882
|
+
r"""
|
|
883
|
+
Convert ``I`` to a bit vector of length ``L``.
|
|
884
|
+
|
|
885
|
+
INPUT:
|
|
886
|
+
|
|
887
|
+
- ``I`` -- integer or bit list-like
|
|
888
|
+
|
|
889
|
+
- ``L`` -- integer; the desired bit length of the output
|
|
890
|
+
|
|
891
|
+
OUTPUT: the ``L``-bit vector representation of ``I``
|
|
892
|
+
|
|
893
|
+
EXAMPLES::
|
|
894
|
+
|
|
895
|
+
sage: from sage.crypto.block_cipher.present import convert_to_vector
|
|
896
|
+
sage: convert_to_vector(0x1F, 8)
|
|
897
|
+
(1, 1, 1, 1, 1, 0, 0, 0)
|
|
898
|
+
sage: v = vector(GF(2), 4, [1,0,1,0])
|
|
899
|
+
sage: convert_to_vector(v, 4)
|
|
900
|
+
(1, 0, 1, 0)
|
|
901
|
+
"""
|
|
902
|
+
try:
|
|
903
|
+
state = vector(GF(2), L, ZZ(I).digits(2, padto=L))
|
|
904
|
+
return state
|
|
905
|
+
except TypeError:
|
|
906
|
+
# ignore the error and try list-like types
|
|
907
|
+
pass
|
|
908
|
+
state = vector(GF(2), L, ZZ(list(I), 2).digits(2, padto=L))
|
|
909
|
+
return state
|