passagemath-modules 10.6.31__cp314-cp314-macosx_13_0_x86_64.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of passagemath-modules might be problematic. Click here for more details.
- passagemath_modules-10.6.31.dist-info/METADATA +281 -0
- passagemath_modules-10.6.31.dist-info/RECORD +807 -0
- passagemath_modules-10.6.31.dist-info/WHEEL +6 -0
- passagemath_modules-10.6.31.dist-info/top_level.txt +2 -0
- passagemath_modules.dylibs/libgfortran.5.dylib +0 -0
- passagemath_modules.dylibs/libgmp.10.dylib +0 -0
- passagemath_modules.dylibs/libgsl.28.dylib +0 -0
- passagemath_modules.dylibs/libmpc.3.dylib +0 -0
- passagemath_modules.dylibs/libmpfr.6.dylib +0 -0
- passagemath_modules.dylibs/libopenblasp-r0.3.29.dylib +0 -0
- passagemath_modules.dylibs/libquadmath.0.dylib +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-darwin.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-darwin.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-darwin.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-darwin.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-darwin.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-darwin.so +0 -0
- sage/calculus/integration.pyx +698 -0
- sage/calculus/interpolation.cpython-314-darwin.so +0 -0
- sage/calculus/interpolation.pxd +13 -0
- sage/calculus/interpolation.pyx +387 -0
- sage/calculus/interpolators.cpython-314-darwin.so +0 -0
- sage/calculus/interpolators.pyx +326 -0
- sage/calculus/ode.cpython-314-darwin.so +0 -0
- sage/calculus/ode.pxd +5 -0
- sage/calculus/ode.pyx +610 -0
- sage/calculus/riemann.cpython-314-darwin.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-darwin.so +0 -0
- sage/calculus/transforms/dwt.pxd +7 -0
- sage/calculus/transforms/dwt.pyx +160 -0
- sage/calculus/transforms/fft.cpython-314-darwin.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-darwin.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-darwin.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-darwin.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-darwin.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-darwin.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-darwin.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-darwin.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-darwin.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-darwin.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-darwin.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-darwin.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-darwin.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-darwin.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-darwin.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-darwin.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-darwin.so +0 -0
- sage/libs/mpmath/utils.pxd +4 -0
- sage/libs/mpmath/utils.pyx +319 -0
- sage/matrix/action.cpython-314-darwin.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-darwin.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-darwin.so +0 -0
- sage/matrix/constructor.pyx +750 -0
- sage/matrix/docs.py +430 -0
- sage/matrix/echelon_matrix.cpython-314-darwin.so +0 -0
- sage/matrix/echelon_matrix.pyx +155 -0
- sage/matrix/matrix.pxd +2 -0
- sage/matrix/matrix0.cpython-314-darwin.so +0 -0
- sage/matrix/matrix0.pxd +68 -0
- sage/matrix/matrix0.pyx +6324 -0
- sage/matrix/matrix1.cpython-314-darwin.so +0 -0
- sage/matrix/matrix1.pxd +8 -0
- sage/matrix/matrix1.pyx +2851 -0
- sage/matrix/matrix2.cpython-314-darwin.so +0 -0
- sage/matrix/matrix2.pxd +25 -0
- sage/matrix/matrix2.pyx +20181 -0
- sage/matrix/matrix_cdv.cpython-314-darwin.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-darwin.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-darwin.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-darwin.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-darwin.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-darwin.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-darwin.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-darwin.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-darwin.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-darwin.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-darwin.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-darwin.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-darwin.so +0 -0
- sage/matrix/matrix_sparse.pxd +5 -0
- sage/matrix/matrix_sparse.pyx +1222 -0
- sage/matrix/matrix_window.cpython-314-darwin.so +0 -0
- sage/matrix/matrix_window.pxd +37 -0
- sage/matrix/matrix_window.pyx +242 -0
- sage/matrix/misc_mpfr.cpython-314-darwin.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-darwin.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-darwin.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-darwin.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-darwin.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-darwin.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-darwin.so +0 -0
- sage/matroids/extension.pxd +34 -0
- sage/matroids/extension.pyx +519 -0
- sage/matroids/flats_matroid.cpython-314-darwin.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-darwin.so +0 -0
- sage/matroids/graphic_matroid.pxd +39 -0
- sage/matroids/graphic_matroid.pyx +2024 -0
- sage/matroids/lean_matrix.cpython-314-darwin.so +0 -0
- sage/matroids/lean_matrix.pxd +126 -0
- sage/matroids/lean_matrix.pyx +3667 -0
- sage/matroids/linear_matroid.cpython-314-darwin.so +0 -0
- sage/matroids/linear_matroid.pxd +180 -0
- sage/matroids/linear_matroid.pyx +6649 -0
- sage/matroids/matroid.cpython-314-darwin.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-darwin.so +0 -0
- sage/matroids/set_system.pxd +38 -0
- sage/matroids/set_system.pyx +800 -0
- sage/matroids/transversal_matroid.cpython-314-darwin.so +0 -0
- sage/matroids/transversal_matroid.pxd +14 -0
- sage/matroids/transversal_matroid.pyx +893 -0
- sage/matroids/union_matroid.cpython-314-darwin.so +0 -0
- sage/matroids/union_matroid.pxd +20 -0
- sage/matroids/union_matroid.pyx +331 -0
- sage/matroids/unpickling.cpython-314-darwin.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-darwin.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-darwin.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-darwin.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-darwin.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-darwin.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-darwin.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-darwin.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-darwin.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-darwin.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-darwin.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-darwin.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-darwin.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-darwin.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-darwin.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-darwin.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-darwin.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-darwin.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-darwin.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-darwin.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-darwin.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-darwin.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-darwin.so +0 -0
- sage/rings/complex_conversion.pxd +8 -0
- sage/rings/complex_conversion.pyx +23 -0
- sage/rings/complex_double.cpython-314-darwin.so +0 -0
- sage/rings/complex_double.pxd +21 -0
- sage/rings/complex_double.pyx +2654 -0
- sage/rings/complex_mpc.cpython-314-darwin.so +0 -0
- sage/rings/complex_mpc.pxd +21 -0
- sage/rings/complex_mpc.pyx +2576 -0
- sage/rings/complex_mpfr.cpython-314-darwin.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-darwin.so +0 -0
- sage/rings/function_field/hermite_form_polynomial.pyx +188 -0
- sage/rings/function_field/khuri_makdisi.cpython-314-darwin.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-darwin.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-darwin.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-darwin.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-darwin.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-darwin.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-darwin.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-darwin.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-darwin.so +0 -0
- sage/rings/real_mpfr.pxd +29 -0
- sage/rings/real_mpfr.pyx +6122 -0
- sage/rings/ring_extension.cpython-314-darwin.so +0 -0
- sage/rings/ring_extension.pxd +42 -0
- sage/rings/ring_extension.pyx +2779 -0
- sage/rings/ring_extension_conversion.cpython-314-darwin.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-darwin.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-darwin.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-darwin.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-darwin.so +0 -0
- sage/stats/hmm/chmm.pyx +1595 -0
- sage/stats/hmm/distributions.cpython-314-darwin.so +0 -0
- sage/stats/hmm/distributions.pxd +29 -0
- sage/stats/hmm/distributions.pyx +531 -0
- sage/stats/hmm/hmm.cpython-314-darwin.so +0 -0
- sage/stats/hmm/hmm.pxd +17 -0
- sage/stats/hmm/hmm.pyx +1388 -0
- sage/stats/hmm/util.cpython-314-darwin.so +0 -0
- sage/stats/hmm/util.pxd +7 -0
- sage/stats/hmm/util.pyx +165 -0
- sage/stats/intlist.cpython-314-darwin.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-darwin.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
sage/crypto/lwe.py
ADDED
|
@@ -0,0 +1,840 @@
|
|
|
1
|
+
# sage_setup: distribution = sagemath-modules
|
|
2
|
+
# sage.doctest: needs scipy sage.symbolic
|
|
3
|
+
"""
|
|
4
|
+
(Ring-)LWE oracle generators
|
|
5
|
+
|
|
6
|
+
The Learning with Errors problem (LWE) is solving linear systems of equations
|
|
7
|
+
where the right hand side has been disturbed 'slightly' where 'slightly' is made
|
|
8
|
+
precise by a noise distribution - typically a discrete Gaussian
|
|
9
|
+
distribution. See [Reg09]_ for details.
|
|
10
|
+
|
|
11
|
+
The Ring Learning with Errors problem (LWE) is solving a set of univariate
|
|
12
|
+
polynomial equations - typically in a cyclotomic field - where the right hand
|
|
13
|
+
side was disturbed 'slightly'. See [LPR2010]_ for details.
|
|
14
|
+
|
|
15
|
+
This module implements generators of LWE samples where parameters are chosen
|
|
16
|
+
following proposals in the cryptographic literature.
|
|
17
|
+
|
|
18
|
+
EXAMPLES:
|
|
19
|
+
|
|
20
|
+
We get 30 samples from an LWE oracle parameterised by security parameter
|
|
21
|
+
``n=20`` and where the modulus and the standard deviation of the noise are
|
|
22
|
+
chosen as in [Reg09]_::
|
|
23
|
+
|
|
24
|
+
sage: from sage.crypto.lwe import samples
|
|
25
|
+
sage: S = samples(30, 20, 'Regev')
|
|
26
|
+
sage: len(S)
|
|
27
|
+
30
|
|
28
|
+
sage: S[0][0].parent(), S[0][1].parent()
|
|
29
|
+
(Vector space of dimension 20 over Ring of integers modulo 401,
|
|
30
|
+
Ring of integers modulo 401)
|
|
31
|
+
|
|
32
|
+
We may also pass classes to the samples function, which is useful for users
|
|
33
|
+
implementing their own oracles::
|
|
34
|
+
|
|
35
|
+
sage: from sage.crypto.lwe import samples, LindnerPeikert
|
|
36
|
+
sage: S = samples(30, 20, LindnerPeikert)
|
|
37
|
+
sage: len(S)
|
|
38
|
+
30
|
|
39
|
+
sage: S[0][0].parent(), S[0][1].parent()
|
|
40
|
+
(Vector space of dimension 20 over Ring of integers modulo 2053,
|
|
41
|
+
Ring of integers modulo 2053)
|
|
42
|
+
|
|
43
|
+
Finally, :func:`samples` also accepts instances of classes::
|
|
44
|
+
|
|
45
|
+
sage: from sage.crypto.lwe import LindnerPeikert
|
|
46
|
+
sage: lwe = LindnerPeikert(20)
|
|
47
|
+
sage: S = samples(30, 20, lwe)
|
|
48
|
+
sage: len(S)
|
|
49
|
+
30
|
|
50
|
+
sage: S[0][0].parent(), S[0][1].parent()
|
|
51
|
+
(Vector space of dimension 20 over Ring of integers modulo 2053,
|
|
52
|
+
Ring of integers modulo 2053)
|
|
53
|
+
|
|
54
|
+
Note that Ring-LWE samples are returned as vectors::
|
|
55
|
+
|
|
56
|
+
sage: # needs sage.libs.pari
|
|
57
|
+
sage: from sage.crypto.lwe import RingLWE
|
|
58
|
+
sage: from sage.stats.distributions.discrete_gaussian_polynomial import DiscreteGaussianDistributionPolynomialSampler
|
|
59
|
+
sage: D = DiscreteGaussianDistributionPolynomialSampler(ZZ['x'], euler_phi(16), 5)
|
|
60
|
+
sage: ringlwe = RingLWE(16, 257, D, secret_dist='uniform')
|
|
61
|
+
sage: p = samples(30, euler_phi(16), ringlwe)[0][0].parent(); p
|
|
62
|
+
Vector space of dimension 8 over Ring of integers modulo 257
|
|
63
|
+
sage: assert all(c.parent() is p for b in samples(30, euler_phi(16), ringlwe) for c in b)
|
|
64
|
+
|
|
65
|
+
One technical issue when working with these generators is that by default they
|
|
66
|
+
return vectors and scalars over/in rings modulo some `q`. These are represented
|
|
67
|
+
as elements in `(0,q-1)` by Sage. However, it usually is more natural to think
|
|
68
|
+
of these entries as integers in `(-q//2,q//2)`. To allow for this, this module
|
|
69
|
+
provides the option to balance the representation. In this case vectors and
|
|
70
|
+
scalars over/in the integers are returned::
|
|
71
|
+
|
|
72
|
+
sage: from sage.crypto.lwe import samples
|
|
73
|
+
sage: for s in samples(30, 20, 'Regev', balanced=True):
|
|
74
|
+
....: s1 = list(s[0]) + [s[1]]
|
|
75
|
+
....: assert all(-401//2 <= b <= 401//2 for b in s1)
|
|
76
|
+
|
|
77
|
+
AUTHORS:
|
|
78
|
+
|
|
79
|
+
- Martin Albrecht
|
|
80
|
+
- Robert Fitzpatrick
|
|
81
|
+
- Daniel Cabracas
|
|
82
|
+
- Florian Göpfert
|
|
83
|
+
- Michael Schneider
|
|
84
|
+
|
|
85
|
+
REFERENCES:
|
|
86
|
+
|
|
87
|
+
- [Reg09]_
|
|
88
|
+
|
|
89
|
+
- [LP2011]_
|
|
90
|
+
|
|
91
|
+
- [LPR2010]_
|
|
92
|
+
|
|
93
|
+
- [CGW2013]_
|
|
94
|
+
"""
|
|
95
|
+
|
|
96
|
+
from sage.arith.misc import euler_phi, next_prime
|
|
97
|
+
from sage.functions.log import log
|
|
98
|
+
from sage.functions.other import floor, ceil
|
|
99
|
+
from sage.misc.functional import cyclotomic_polynomial, round
|
|
100
|
+
from sage.misc.functional import sqrt
|
|
101
|
+
from sage.misc.prandom import randint
|
|
102
|
+
from sage.misc.randstate import set_random_seed
|
|
103
|
+
from sage.modules.free_module import FreeModule
|
|
104
|
+
from sage.modules.free_module_element import random_vector, vector
|
|
105
|
+
from sage.numerical.optimize import find_root
|
|
106
|
+
from sage.rings.finite_rings.integer_mod_ring import IntegerModRing
|
|
107
|
+
from sage.rings.integer_ring import ZZ
|
|
108
|
+
from sage.rings.real_mpfr import RR
|
|
109
|
+
from sage.stats.distributions.discrete_gaussian_integer import DiscreteGaussianDistributionIntegerSampler
|
|
110
|
+
from sage.stats.distributions.discrete_gaussian_polynomial import DiscreteGaussianDistributionPolynomialSampler
|
|
111
|
+
from sage.structure.element import parent
|
|
112
|
+
from sage.structure.sage_object import SageObject
|
|
113
|
+
from sage.symbolic.constants import pi
|
|
114
|
+
from sage.symbolic.ring import SR
|
|
115
|
+
|
|
116
|
+
|
|
117
|
+
class UniformSampler(SageObject):
|
|
118
|
+
"""
|
|
119
|
+
Uniform sampling in a range of integers.
|
|
120
|
+
|
|
121
|
+
EXAMPLES::
|
|
122
|
+
|
|
123
|
+
sage: from sage.crypto.lwe import UniformSampler
|
|
124
|
+
sage: sampler = UniformSampler(-2, 2); sampler
|
|
125
|
+
UniformSampler(-2, 2)
|
|
126
|
+
sage: sampler() in range(-2, 3)
|
|
127
|
+
True
|
|
128
|
+
|
|
129
|
+
.. automethod:: __init__
|
|
130
|
+
.. automethod:: __call__
|
|
131
|
+
"""
|
|
132
|
+
def __init__(self, lower_bound, upper_bound):
|
|
133
|
+
"""
|
|
134
|
+
Construct a uniform sampler with bounds ``lower_bound`` and
|
|
135
|
+
``upper_bound`` (both endpoints inclusive).
|
|
136
|
+
|
|
137
|
+
INPUT:
|
|
138
|
+
|
|
139
|
+
- ``lower_bound`` -- integer
|
|
140
|
+
- ``upper_bound`` -- integer
|
|
141
|
+
|
|
142
|
+
EXAMPLES::
|
|
143
|
+
|
|
144
|
+
sage: from sage.crypto.lwe import UniformSampler
|
|
145
|
+
sage: UniformSampler(-2, 2)
|
|
146
|
+
UniformSampler(-2, 2)
|
|
147
|
+
"""
|
|
148
|
+
if lower_bound > upper_bound:
|
|
149
|
+
raise TypeError("lower bound must be <= upper bound.")
|
|
150
|
+
self.lower_bound = ZZ(lower_bound)
|
|
151
|
+
self.upper_bound = ZZ(upper_bound)
|
|
152
|
+
|
|
153
|
+
def __call__(self):
|
|
154
|
+
"""
|
|
155
|
+
Return a new sample.
|
|
156
|
+
|
|
157
|
+
EXAMPLES::
|
|
158
|
+
|
|
159
|
+
sage: from sage.crypto.lwe import UniformSampler
|
|
160
|
+
sage: sampler = UniformSampler(-12, 12)
|
|
161
|
+
sage: sampler() in range(-12, 13)
|
|
162
|
+
True
|
|
163
|
+
"""
|
|
164
|
+
return randint(self.lower_bound, self.upper_bound)
|
|
165
|
+
|
|
166
|
+
def _repr_(self):
|
|
167
|
+
"""
|
|
168
|
+
EXAMPLES::
|
|
169
|
+
|
|
170
|
+
sage: from sage.crypto.lwe import UniformSampler
|
|
171
|
+
sage: UniformSampler(-2, 2)
|
|
172
|
+
UniformSampler(-2, 2)
|
|
173
|
+
"""
|
|
174
|
+
return "UniformSampler(%d, %d)" % (self.lower_bound, self.upper_bound)
|
|
175
|
+
|
|
176
|
+
|
|
177
|
+
class UniformPolynomialSampler(SageObject):
|
|
178
|
+
"""
|
|
179
|
+
Uniform sampler for polynomials.
|
|
180
|
+
|
|
181
|
+
EXAMPLES::
|
|
182
|
+
|
|
183
|
+
sage: from sage.crypto.lwe import UniformPolynomialSampler
|
|
184
|
+
sage: UniformPolynomialSampler(ZZ['x'], 8, -2, 2)().parent()
|
|
185
|
+
Univariate Polynomial Ring in x over Integer Ring
|
|
186
|
+
|
|
187
|
+
.. automethod:: __init__
|
|
188
|
+
.. automethod:: __call__
|
|
189
|
+
"""
|
|
190
|
+
def __init__(self, P, n, lower_bound, upper_bound):
|
|
191
|
+
"""
|
|
192
|
+
Construct a sampler for univariate polynomials of degree ``n-1`` where
|
|
193
|
+
coefficients are drawn uniformly at random between ``lower_bound`` and
|
|
194
|
+
``upper_bound`` (both endpoints inclusive).
|
|
195
|
+
|
|
196
|
+
INPUT:
|
|
197
|
+
|
|
198
|
+
- ``P`` -- a univariate polynomial ring over the Integers
|
|
199
|
+
- ``n`` -- number of coefficients to be sampled
|
|
200
|
+
- ``lower_bound`` -- integer
|
|
201
|
+
- ``upper_bound`` -- integer
|
|
202
|
+
|
|
203
|
+
EXAMPLES::
|
|
204
|
+
|
|
205
|
+
sage: from sage.crypto.lwe import UniformPolynomialSampler
|
|
206
|
+
sage: UniformPolynomialSampler(ZZ['x'], 10, -10, 10)
|
|
207
|
+
UniformPolynomialSampler(10, -10, 10)
|
|
208
|
+
"""
|
|
209
|
+
self.n = ZZ(n)
|
|
210
|
+
self.P = P
|
|
211
|
+
if lower_bound > upper_bound:
|
|
212
|
+
raise TypeError("lower bound must be <= upper bound.")
|
|
213
|
+
self.lower_bound = ZZ(lower_bound)
|
|
214
|
+
self.upper_bound = ZZ(upper_bound)
|
|
215
|
+
self.D = UniformSampler(self.lower_bound, self.upper_bound)
|
|
216
|
+
|
|
217
|
+
def __call__(self):
|
|
218
|
+
"""
|
|
219
|
+
Return a new sample.
|
|
220
|
+
|
|
221
|
+
EXAMPLES::
|
|
222
|
+
|
|
223
|
+
sage: from sage.crypto.lwe import UniformPolynomialSampler
|
|
224
|
+
sage: sampler = UniformPolynomialSampler(ZZ['x'], 8, -12, 12)
|
|
225
|
+
sage: sampler().parent()
|
|
226
|
+
Univariate Polynomial Ring in x over Integer Ring
|
|
227
|
+
"""
|
|
228
|
+
coeff = [self.D() for _ in range(self.n)]
|
|
229
|
+
f = self.P(coeff)
|
|
230
|
+
return f
|
|
231
|
+
|
|
232
|
+
def _repr_(self):
|
|
233
|
+
"""
|
|
234
|
+
EXAMPLES::
|
|
235
|
+
|
|
236
|
+
sage: from sage.crypto.lwe import UniformPolynomialSampler
|
|
237
|
+
sage: UniformPolynomialSampler(ZZ['x'], 8, -3, 3)
|
|
238
|
+
UniformPolynomialSampler(8, -3, 3)
|
|
239
|
+
"""
|
|
240
|
+
return "UniformPolynomialSampler(%d, %d, %d)" % (self.n, self.lower_bound, self.upper_bound)
|
|
241
|
+
|
|
242
|
+
|
|
243
|
+
class LWE(SageObject):
|
|
244
|
+
"""
|
|
245
|
+
Learning with Errors (LWE) oracle.
|
|
246
|
+
|
|
247
|
+
.. automethod:: __init__
|
|
248
|
+
.. automethod:: __call__
|
|
249
|
+
"""
|
|
250
|
+
def __init__(self, n, q, D, secret_dist='uniform', m=None):
|
|
251
|
+
r"""
|
|
252
|
+
Construct an LWE oracle in dimension ``n`` over a ring of order
|
|
253
|
+
``q`` with noise distribution ``D``.
|
|
254
|
+
|
|
255
|
+
INPUT:
|
|
256
|
+
|
|
257
|
+
- ``n`` -- dimension (integer > 0)
|
|
258
|
+
- ``q`` -- modulus typically > n (integer > 0)
|
|
259
|
+
- ``D`` -- an error distribution such as an instance of
|
|
260
|
+
:class:`DiscreteGaussianDistributionIntegerSampler` or :class:`UniformSampler`
|
|
261
|
+
- ``secret_dist`` -- distribution of the secret (default: ``'uniform'``); one of
|
|
262
|
+
|
|
263
|
+
- ``'uniform'`` -- secret follows the uniform distribution in `\Zmod{q}`
|
|
264
|
+
- ``'noise'`` -- secret follows the noise distribution
|
|
265
|
+
- ``(lb, ub)`` -- the secret is chosen uniformly from ``[lb,...,ub]``
|
|
266
|
+
including both endpoints
|
|
267
|
+
|
|
268
|
+
- ``m`` -- number of allowed samples or ``None`` if no such limit exists
|
|
269
|
+
(default: ``None``)
|
|
270
|
+
|
|
271
|
+
EXAMPLES:
|
|
272
|
+
|
|
273
|
+
First, we construct a noise distribution with standard deviation 3.0::
|
|
274
|
+
|
|
275
|
+
sage: from sage.stats.distributions.discrete_gaussian_integer import DiscreteGaussianDistributionIntegerSampler
|
|
276
|
+
sage: D = DiscreteGaussianDistributionIntegerSampler(3.0)
|
|
277
|
+
|
|
278
|
+
Next, we construct our oracle::
|
|
279
|
+
|
|
280
|
+
sage: from sage.crypto.lwe import LWE
|
|
281
|
+
sage: lwe = LWE(n=20, q=next_prime(400), D=D); lwe
|
|
282
|
+
LWE(20, 401, Discrete Gaussian sampler over the Integers with sigma = 3.000000 and c = 0.000000, 'uniform', None)
|
|
283
|
+
|
|
284
|
+
and sample 1000 samples::
|
|
285
|
+
|
|
286
|
+
sage: L = []
|
|
287
|
+
sage: def add_samples():
|
|
288
|
+
....: global L
|
|
289
|
+
....: L += [lwe() for _ in range(100)]
|
|
290
|
+
sage: add_samples()
|
|
291
|
+
|
|
292
|
+
To test the oracle, we use the internal secret to evaluate the samples
|
|
293
|
+
in the secret::
|
|
294
|
+
|
|
295
|
+
sage: S = lambda : [ZZ(a.dot_product(lwe._LWE__s) - c) for (a,c) in L]
|
|
296
|
+
|
|
297
|
+
However, while Sage represents finite field elements between 0 and q-1
|
|
298
|
+
we rely on a balanced representation of those elements here. Hence, we
|
|
299
|
+
fix the representation and recover the correct standard deviation of the
|
|
300
|
+
noise::
|
|
301
|
+
|
|
302
|
+
sage: from numpy import std # needs numpy
|
|
303
|
+
sage: while abs(std([e if e <= 200 else e-401 for e in S()]) - 3.0) > 0.01: # needs numpy
|
|
304
|
+
....: L = [] # reset L to avoid quadratic behaviour
|
|
305
|
+
....: add_samples()
|
|
306
|
+
|
|
307
|
+
If ``m`` is not ``None`` the number of available samples is restricted::
|
|
308
|
+
|
|
309
|
+
sage: from sage.crypto.lwe import LWE
|
|
310
|
+
sage: lwe = LWE(n=20, q=next_prime(400), D=D, m=30)
|
|
311
|
+
sage: _ = [lwe() for _ in range(30)]
|
|
312
|
+
sage: lwe() # 31
|
|
313
|
+
Traceback (most recent call last):
|
|
314
|
+
...
|
|
315
|
+
IndexError: Number of available samples exhausted.
|
|
316
|
+
"""
|
|
317
|
+
self.n = ZZ(n)
|
|
318
|
+
self.m = m
|
|
319
|
+
self.__i = 0
|
|
320
|
+
self.K = IntegerModRing(q)
|
|
321
|
+
self.FM = FreeModule(self.K, n)
|
|
322
|
+
self.D = D
|
|
323
|
+
|
|
324
|
+
self.secret_dist = secret_dist
|
|
325
|
+
if secret_dist == 'uniform':
|
|
326
|
+
self.__s = random_vector(self.K, self.n)
|
|
327
|
+
elif secret_dist == 'noise':
|
|
328
|
+
self.__s = vector(self.K, self.n, [self.D() for _ in range(n)])
|
|
329
|
+
else:
|
|
330
|
+
try:
|
|
331
|
+
lb, ub = map(ZZ, secret_dist)
|
|
332
|
+
self.__s = vector(self.K, self.n, [randint(lb,ub) for _ in range(n)])
|
|
333
|
+
except (IndexError, TypeError):
|
|
334
|
+
raise TypeError("Parameter secret_dist=%s not understood." % (secret_dist))
|
|
335
|
+
|
|
336
|
+
def _repr_(self):
|
|
337
|
+
"""
|
|
338
|
+
EXAMPLES::
|
|
339
|
+
|
|
340
|
+
sage: from sage.stats.distributions.discrete_gaussian_integer import DiscreteGaussianDistributionIntegerSampler
|
|
341
|
+
sage: from sage.crypto.lwe import LWE
|
|
342
|
+
sage: D = DiscreteGaussianDistributionIntegerSampler(3.0)
|
|
343
|
+
sage: lwe = LWE(n=20, q=next_prime(400), D=D); lwe
|
|
344
|
+
LWE(20, 401, Discrete Gaussian sampler over the Integers with sigma = 3.000000 and c = 0.000000, 'uniform', None)
|
|
345
|
+
|
|
346
|
+
sage: lwe = LWE(n=20, q=next_prime(400), D=D, secret_dist=(-3, 3)); lwe
|
|
347
|
+
LWE(20, 401, Discrete Gaussian sampler over the Integers with sigma = 3.000000 and c = 0.000000, (-3, 3), None)
|
|
348
|
+
"""
|
|
349
|
+
if isinstance(self.secret_dist, str):
|
|
350
|
+
return "LWE(%d, %d, %s, '%s', %s)" % (self.n,self.K.order(),self.D,self.secret_dist, self.m)
|
|
351
|
+
else:
|
|
352
|
+
return "LWE(%d, %d, %s, %s, %s)" % (self.n,self.K.order(),self.D,self.secret_dist, self.m)
|
|
353
|
+
|
|
354
|
+
def __call__(self):
|
|
355
|
+
"""
|
|
356
|
+
EXAMPLES::
|
|
357
|
+
|
|
358
|
+
sage: from sage.crypto.lwe import DiscreteGaussianDistributionIntegerSampler, LWE
|
|
359
|
+
sage: LWE(10, 401, DiscreteGaussianDistributionIntegerSampler(3))()[0].parent()
|
|
360
|
+
Vector space of dimension 10 over Ring of integers modulo 401
|
|
361
|
+
sage: LWE(10, 401, DiscreteGaussianDistributionIntegerSampler(3))()[1].parent()
|
|
362
|
+
Ring of integers modulo 401
|
|
363
|
+
"""
|
|
364
|
+
if self.m is not None:
|
|
365
|
+
if self.__i >= self.m:
|
|
366
|
+
raise IndexError("Number of available samples exhausted.")
|
|
367
|
+
self.__i += 1
|
|
368
|
+
a = self.FM.random_element()
|
|
369
|
+
return a, a.dot_product(self.__s) + self.K(self.D())
|
|
370
|
+
|
|
371
|
+
|
|
372
|
+
class Regev(LWE):
|
|
373
|
+
"""
|
|
374
|
+
LWE oracle with parameters as in [Reg09]_.
|
|
375
|
+
|
|
376
|
+
.. automethod:: __init__
|
|
377
|
+
"""
|
|
378
|
+
def __init__(self, n, secret_dist='uniform', m=None):
|
|
379
|
+
"""
|
|
380
|
+
Construct LWE instance parameterised by security parameter ``n`` where
|
|
381
|
+
the modulus ``q`` and the ``stddev`` of the noise are chosen as in
|
|
382
|
+
[Reg09]_.
|
|
383
|
+
|
|
384
|
+
INPUT:
|
|
385
|
+
|
|
386
|
+
- ``n`` -- security parameter (integer > 0)
|
|
387
|
+
- ``secret_dist`` -- distribution of the secret. See documentation of :class:`LWE`
|
|
388
|
+
for details (default='uniform')
|
|
389
|
+
- ``m`` -- number of allowed samples or ``None`` if no such limit exists
|
|
390
|
+
(default: ``None``)
|
|
391
|
+
|
|
392
|
+
EXAMPLES::
|
|
393
|
+
|
|
394
|
+
sage: from sage.crypto.lwe import Regev
|
|
395
|
+
sage: Regev(n=20)
|
|
396
|
+
LWE(20, 401, Discrete Gaussian sampler over the Integers with sigma = 1.915069 and c = 401.000000, 'uniform', None)
|
|
397
|
+
"""
|
|
398
|
+
q = ZZ(next_prime(n**2))
|
|
399
|
+
s = RR(1/(RR(n).sqrt() * log(n, 2)**2) * q)
|
|
400
|
+
D = DiscreteGaussianDistributionIntegerSampler(s/sqrt(2*pi.n()), q)
|
|
401
|
+
LWE.__init__(self, n=n, q=q, D=D, secret_dist=secret_dist, m=m)
|
|
402
|
+
|
|
403
|
+
|
|
404
|
+
class LindnerPeikert(LWE):
|
|
405
|
+
"""
|
|
406
|
+
LWE oracle with parameters as in [LP2011]_.
|
|
407
|
+
|
|
408
|
+
.. automethod:: __init__
|
|
409
|
+
"""
|
|
410
|
+
def __init__(self, n, delta=0.01, m=None):
|
|
411
|
+
"""
|
|
412
|
+
Construct LWE instance parameterised by security parameter ``n`` where
|
|
413
|
+
the modulus ``q`` and the ``stddev`` of the noise is chosen as in
|
|
414
|
+
[LP2011]_.
|
|
415
|
+
|
|
416
|
+
INPUT:
|
|
417
|
+
|
|
418
|
+
- ``n`` -- security parameter (integer > 0)
|
|
419
|
+
- ``delta`` -- error probability per symbol (default: 0.01)
|
|
420
|
+
- ``m`` -- number of allowed samples or ``None`` in which case ``m=2*n +
|
|
421
|
+
128`` as in [LP2011]_ (default: ``None``)
|
|
422
|
+
|
|
423
|
+
EXAMPLES::
|
|
424
|
+
|
|
425
|
+
sage: from sage.crypto.lwe import LindnerPeikert
|
|
426
|
+
sage: LindnerPeikert(n=20)
|
|
427
|
+
LWE(20, 2053, Discrete Gaussian sampler over the Integers with sigma = 3.600954 and c = 0.000000, 'noise', 168)
|
|
428
|
+
"""
|
|
429
|
+
if m is None:
|
|
430
|
+
m = 2*n + 128
|
|
431
|
+
# Find c>=1 such that c*exp((1-c**2)/2))**(2*n) == 2**-40
|
|
432
|
+
# (c*exp((1-c**2)/2))**(2*n) == 2**-40
|
|
433
|
+
# log((c*exp((1-c**2)/2))**(2*n)) == -40*log(2)
|
|
434
|
+
# (2*n)*log(c*exp((1-c**2)/2)) == -40*log(2)
|
|
435
|
+
# 2*n*(log(c)+log(exp((1-c**2)/2))) == -40*log(2)
|
|
436
|
+
# 2*n*(log(c)+(1-c**2)/2) == -40*log(2)
|
|
437
|
+
# 2*n*log(c)+n*(1-c**2) == -40*log(2)
|
|
438
|
+
# 2*n*log(c)+n*(1-c**2) + 40*log(2) == 0
|
|
439
|
+
c = SR.var('c')
|
|
440
|
+
c = find_root(2*n*log(c)+n*(1-c**2) + 40*log(2) == 0, 1, 10)
|
|
441
|
+
# Upper bound on s**2/t
|
|
442
|
+
s_t_bound = (sqrt(2) * pi / c / sqrt(2*n*log(2/delta))).n()
|
|
443
|
+
# Interpretation of "choose q just large enough to allow for a Gaussian parameter s>=8" in [LP2011]_
|
|
444
|
+
q = next_prime(floor(2**round(log(256 / s_t_bound, 2))))
|
|
445
|
+
# Gaussian parameter as defined in [LP2011]_
|
|
446
|
+
s = sqrt(s_t_bound*floor(q/4))
|
|
447
|
+
# Transform s into stddev
|
|
448
|
+
stddev = s/sqrt(2*pi.n())
|
|
449
|
+
D = DiscreteGaussianDistributionIntegerSampler(stddev)
|
|
450
|
+
LWE.__init__(self, n=n, q=q, D=D, secret_dist='noise', m=m)
|
|
451
|
+
|
|
452
|
+
|
|
453
|
+
class UniformNoiseLWE(LWE):
|
|
454
|
+
"""
|
|
455
|
+
LWE oracle with uniform secret with parameters as in [CGW2013]_.
|
|
456
|
+
|
|
457
|
+
.. automethod:: __init__
|
|
458
|
+
"""
|
|
459
|
+
def __init__(self, n, instance='key', m=None):
|
|
460
|
+
"""
|
|
461
|
+
Construct LWE instance parameterised by security parameter ``n`` where
|
|
462
|
+
all other parameters are chosen as in [CGW2013]_.
|
|
463
|
+
|
|
464
|
+
INPUT:
|
|
465
|
+
|
|
466
|
+
- ``n`` -- security parameter (integer >= 89)
|
|
467
|
+
- ``instance`` -- one of
|
|
468
|
+
|
|
469
|
+
- ``'key'`` -- the LWE-instance that hides the secret key is generated
|
|
470
|
+
- ``'encrypt'`` -- the LWE-instance that hides the message is generated
|
|
471
|
+
(default: ``'key'``)
|
|
472
|
+
|
|
473
|
+
- ``m`` -- number of allowed samples or ``None`` in which case ``m`` is
|
|
474
|
+
chosen as in [CGW2013]_. (default: ``None``)
|
|
475
|
+
|
|
476
|
+
EXAMPLES::
|
|
477
|
+
|
|
478
|
+
sage: from sage.crypto.lwe import UniformNoiseLWE
|
|
479
|
+
sage: UniformNoiseLWE(89)
|
|
480
|
+
LWE(89, 64311834871, UniformSampler(0, 6577), 'noise', 131)
|
|
481
|
+
|
|
482
|
+
sage: UniformNoiseLWE(89, instance='encrypt')
|
|
483
|
+
LWE(131, 64311834871, UniformSampler(0, 11109), 'noise', 181)
|
|
484
|
+
"""
|
|
485
|
+
|
|
486
|
+
if n < 89:
|
|
487
|
+
raise TypeError("Parameter too small")
|
|
488
|
+
|
|
489
|
+
n2 = n
|
|
490
|
+
C = 4/sqrt(2*pi)
|
|
491
|
+
kk = floor((n2-2*log(n2, 2)**2)/5)
|
|
492
|
+
n1 = (3*n2-5*kk) // 2
|
|
493
|
+
ke = floor((n1-2*log(n1, 2)**2)/5)
|
|
494
|
+
l = (3*n1-5*ke) // 2 - n2
|
|
495
|
+
sk = ceil((C*(n1+n2))**(ZZ(3)/2))
|
|
496
|
+
se = ceil((C*(n1+n2+l))**(ZZ(3)/2))
|
|
497
|
+
q = next_prime(max(ceil((4*sk)**(ZZ(n1+n2)/n1)),
|
|
498
|
+
ceil((4*se)**(ZZ(n1+n2+l)/(n2+l))),
|
|
499
|
+
ceil(4*(n1+n2)*se*sk+4*se+1)))
|
|
500
|
+
|
|
501
|
+
if kk <= 0:
|
|
502
|
+
raise TypeError("Parameter too small")
|
|
503
|
+
|
|
504
|
+
if instance == 'key':
|
|
505
|
+
D = UniformSampler(0, sk-1)
|
|
506
|
+
if m is None:
|
|
507
|
+
m = n1
|
|
508
|
+
LWE.__init__(self, n=n2, q=q, D=D, secret_dist='noise', m=m)
|
|
509
|
+
elif instance == 'encrypt':
|
|
510
|
+
D = UniformSampler(0, se-1)
|
|
511
|
+
if m is None:
|
|
512
|
+
m = n2+l
|
|
513
|
+
LWE.__init__(self, n=n1, q=q, D=D, secret_dist='noise', m=m)
|
|
514
|
+
else:
|
|
515
|
+
raise TypeError("Parameter instance=%s not understood." % (instance))
|
|
516
|
+
|
|
517
|
+
|
|
518
|
+
class RingLWE(SageObject):
|
|
519
|
+
"""
|
|
520
|
+
Ring Learning with Errors oracle.
|
|
521
|
+
|
|
522
|
+
.. automethod:: __init__
|
|
523
|
+
.. automethod:: __call__
|
|
524
|
+
"""
|
|
525
|
+
def __init__(self, N, q, D, poly=None, secret_dist='uniform', m=None):
|
|
526
|
+
"""
|
|
527
|
+
Construct a Ring-LWE oracle in dimension ``n=phi(N)`` over a ring of order
|
|
528
|
+
``q`` with noise distribution ``D``.
|
|
529
|
+
|
|
530
|
+
INPUT:
|
|
531
|
+
|
|
532
|
+
- ``N`` -- index of cyclotomic polynomial (integer > 0, must be power of 2)
|
|
533
|
+
- ``q`` -- modulus typically > N (integer > 0)
|
|
534
|
+
- ``D`` -- an error distribution such as an instance of
|
|
535
|
+
:class:`DiscreteGaussianDistributionPolynomialSampler` or :class:`UniformSampler`
|
|
536
|
+
- ``poly`` -- a polynomial of degree ``phi(N)``. If ``None`` the
|
|
537
|
+
cyclotomic polynomial used (default: ``None``).
|
|
538
|
+
- ``secret_dist`` -- distribution of the secret. See documentation of
|
|
539
|
+
:class:`LWE` for details (default='uniform')
|
|
540
|
+
- ``m`` -- number of allowed samples or ``None`` if no such limit exists
|
|
541
|
+
(default: ``None``)
|
|
542
|
+
|
|
543
|
+
EXAMPLES::
|
|
544
|
+
|
|
545
|
+
sage: from sage.crypto.lwe import RingLWE
|
|
546
|
+
sage: from sage.stats.distributions.discrete_gaussian_polynomial import DiscreteGaussianDistributionPolynomialSampler
|
|
547
|
+
sage: D = DiscreteGaussianDistributionPolynomialSampler(ZZ['x'], n=euler_phi(20), sigma=3.0) # needs sage.libs.pari
|
|
548
|
+
sage: RingLWE(N=20, q=next_prime(800), D=D) # needs sage.libs.pari
|
|
549
|
+
RingLWE(20, 809, Discrete Gaussian sampler for polynomials of degree < 8 with σ=3.000000 in each component, x^8 - x^6 + x^4 - x^2 + 1, 'uniform', None)
|
|
550
|
+
"""
|
|
551
|
+
self.N = ZZ(N)
|
|
552
|
+
self.n = euler_phi(N)
|
|
553
|
+
self.m = m
|
|
554
|
+
self.__i = 0
|
|
555
|
+
self.K = IntegerModRing(q)
|
|
556
|
+
|
|
557
|
+
if self.n != D.n:
|
|
558
|
+
raise ValueError("Noise distribution has dimensions %d != %d" % (D.n, self.n))
|
|
559
|
+
|
|
560
|
+
self.D = D
|
|
561
|
+
self.q = q
|
|
562
|
+
if poly is not None:
|
|
563
|
+
self.poly = poly
|
|
564
|
+
else:
|
|
565
|
+
self.poly = cyclotomic_polynomial(self.N, 'x')
|
|
566
|
+
|
|
567
|
+
self.R_q = self.K['x'].quotient(self.poly, 'x')
|
|
568
|
+
|
|
569
|
+
self.secret_dist = secret_dist
|
|
570
|
+
if secret_dist == 'uniform':
|
|
571
|
+
self.__s = self.R_q.random_element() # uniform sampling of secret
|
|
572
|
+
elif secret_dist == 'noise':
|
|
573
|
+
self.__s = self.D()
|
|
574
|
+
else:
|
|
575
|
+
raise TypeError("Parameter secret_dist=%s not understood." % (secret_dist))
|
|
576
|
+
|
|
577
|
+
def _repr_(self):
|
|
578
|
+
"""
|
|
579
|
+
EXAMPLES::
|
|
580
|
+
|
|
581
|
+
sage: from sage.crypto.lwe import DiscreteGaussianDistributionPolynomialSampler, RingLWE
|
|
582
|
+
sage: D = DiscreteGaussianDistributionPolynomialSampler(ZZ['x'], n=8, sigma=3.0)
|
|
583
|
+
sage: RingLWE(N=16, q=next_prime(400), D=D)
|
|
584
|
+
RingLWE(16, 401, Discrete Gaussian sampler for polynomials of degree < 8 with σ=3.000000 in each component, x^8 + 1, 'uniform', None)
|
|
585
|
+
"""
|
|
586
|
+
if isinstance(self.secret_dist, str):
|
|
587
|
+
return "RingLWE(%d, %d, %s, %s, '%s', %s)" % (self.N, self.K.order(), self.D, self.poly, self.secret_dist, self.m)
|
|
588
|
+
else:
|
|
589
|
+
return "RingLWE(%d, %d, %s, %s, %s, %s)" % (self.N, self.K.order(), self.D, self.poly, self.secret_dist, self.m)
|
|
590
|
+
|
|
591
|
+
def __call__(self):
|
|
592
|
+
"""
|
|
593
|
+
EXAMPLES::
|
|
594
|
+
|
|
595
|
+
sage: # needs sage.libs.pari
|
|
596
|
+
sage: from sage.crypto.lwe import DiscreteGaussianDistributionPolynomialSampler, RingLWE
|
|
597
|
+
sage: N = 16
|
|
598
|
+
sage: n = euler_phi(N)
|
|
599
|
+
sage: D = DiscreteGaussianDistributionPolynomialSampler(ZZ['x'], n, 5)
|
|
600
|
+
sage: ringlwe = RingLWE(N, 257, D, secret_dist='uniform')
|
|
601
|
+
sage: ringlwe()[0].parent()
|
|
602
|
+
Vector space of dimension 8 over Ring of integers modulo 257
|
|
603
|
+
sage: ringlwe()[1].parent()
|
|
604
|
+
Vector space of dimension 8 over Ring of integers modulo 257
|
|
605
|
+
"""
|
|
606
|
+
if self.m is not None:
|
|
607
|
+
if self.__i >= self.m:
|
|
608
|
+
raise IndexError("Number of available samples exhausted.")
|
|
609
|
+
self.__i += 1
|
|
610
|
+
a = self.R_q.random_element()
|
|
611
|
+
return vector(a), vector(a * (self.__s) + self.D())
|
|
612
|
+
|
|
613
|
+
|
|
614
|
+
class RingLindnerPeikert(RingLWE):
|
|
615
|
+
"""
|
|
616
|
+
Ring-LWE oracle with parameters as in [LP2011]_.
|
|
617
|
+
|
|
618
|
+
.. automethod:: __init__
|
|
619
|
+
"""
|
|
620
|
+
def __init__(self, N, delta=0.01, m=None):
|
|
621
|
+
"""
|
|
622
|
+
Construct a Ring-LWE oracle in dimension ``n=phi(N)`` where
|
|
623
|
+
the modulus ``q`` and the ``stddev`` of the noise is chosen as in
|
|
624
|
+
[LP2011]_.
|
|
625
|
+
|
|
626
|
+
INPUT:
|
|
627
|
+
|
|
628
|
+
- ``N`` -- index of cyclotomic polynomial (integer > 0, must be power of 2)
|
|
629
|
+
- ``delta`` -- error probability per symbol (default: 0.01)
|
|
630
|
+
- ``m`` -- number of allowed samples or ``None`` in which case ``3*n`` is
|
|
631
|
+
used (default: ``None``)
|
|
632
|
+
|
|
633
|
+
EXAMPLES::
|
|
634
|
+
|
|
635
|
+
sage: from sage.crypto.lwe import RingLindnerPeikert
|
|
636
|
+
sage: RingLindnerPeikert(N=16)
|
|
637
|
+
RingLWE(16, 1031, Discrete Gaussian sampler for polynomials of degree < 8 with σ=2.803372 in each component, x^8 + 1, 'noise', 24)
|
|
638
|
+
"""
|
|
639
|
+
n = euler_phi(N)
|
|
640
|
+
if m is None:
|
|
641
|
+
m = 3*n
|
|
642
|
+
# Find c>=1 such that c*exp((1-c**2)/2))**(2*n) == 2**-40
|
|
643
|
+
# i.e c>=1 such that 2*n*log(c)+n*(1-c**2) + 40*log(2) == 0
|
|
644
|
+
c = SR.var('c')
|
|
645
|
+
c = find_root(2*n*log(c)+n*(1-c**2) + 40*log(2) == 0, 1, 10)
|
|
646
|
+
# Upper bound on s**2/t
|
|
647
|
+
s_t_bound = (sqrt(2) * pi / c / sqrt(2*n*log(2/delta))).n()
|
|
648
|
+
# Interpretation of "choose q just large enough to allow for a Gaussian parameter s>=8" in [LP2011]_
|
|
649
|
+
q = next_prime(floor(2**round(log(256 / s_t_bound, 2))))
|
|
650
|
+
# Gaussian parameter as defined in [LP2011]_
|
|
651
|
+
s = sqrt(s_t_bound*floor(q/4))
|
|
652
|
+
# Transform s into stddev
|
|
653
|
+
stddev = s/sqrt(2*pi.n())
|
|
654
|
+
D = DiscreteGaussianDistributionPolynomialSampler(ZZ['x'], n, stddev)
|
|
655
|
+
RingLWE.__init__(self, N=N, q=q, D=D, poly=None, secret_dist='noise', m=m)
|
|
656
|
+
|
|
657
|
+
|
|
658
|
+
class RingLWEConverter(SageObject):
|
|
659
|
+
"""
|
|
660
|
+
Wrapper callable to convert Ring-LWE oracles into LWE oracles by
|
|
661
|
+
disregarding the additional structure.
|
|
662
|
+
|
|
663
|
+
.. automethod:: __init__
|
|
664
|
+
.. automethod:: __call__
|
|
665
|
+
"""
|
|
666
|
+
def __init__(self, ringlwe):
|
|
667
|
+
"""
|
|
668
|
+
INPUT:
|
|
669
|
+
|
|
670
|
+
- ``ringlwe`` -- an instance of a :class:`RingLWE`
|
|
671
|
+
|
|
672
|
+
EXAMPLES::
|
|
673
|
+
|
|
674
|
+
sage: from sage.crypto.lwe import DiscreteGaussianDistributionPolynomialSampler, RingLWE, RingLWEConverter
|
|
675
|
+
sage: D = DiscreteGaussianDistributionPolynomialSampler(ZZ['x'], euler_phi(16), 5)
|
|
676
|
+
sage: lwe = RingLWEConverter(RingLWE(16, 257, D, secret_dist='uniform'))
|
|
677
|
+
sage: set_random_seed(1337)
|
|
678
|
+
sage: lwe()
|
|
679
|
+
((171, 197, 58, 125, 3, 216, 32, 130), ...)
|
|
680
|
+
"""
|
|
681
|
+
self.ringlwe = ringlwe
|
|
682
|
+
self._i = 0
|
|
683
|
+
self._ac = None
|
|
684
|
+
self.n = self.ringlwe.n
|
|
685
|
+
|
|
686
|
+
def __call__(self):
|
|
687
|
+
"""
|
|
688
|
+
EXAMPLES::
|
|
689
|
+
|
|
690
|
+
sage: from sage.crypto.lwe import DiscreteGaussianDistributionPolynomialSampler, RingLWE, RingLWEConverter
|
|
691
|
+
sage: D = DiscreteGaussianDistributionPolynomialSampler(ZZ['x'], euler_phi(16), 5)
|
|
692
|
+
sage: lwe = RingLWEConverter(RingLWE(16, 257, D, secret_dist='uniform'))
|
|
693
|
+
sage: set_random_seed(1337)
|
|
694
|
+
sage: lwe()
|
|
695
|
+
((171, 197, 58, 125, 3, 216, 32, 130), ...)
|
|
696
|
+
"""
|
|
697
|
+
R_q = self.ringlwe.R_q
|
|
698
|
+
|
|
699
|
+
if (self._i % self.n) == 0:
|
|
700
|
+
self._ac = self.ringlwe()
|
|
701
|
+
a, c = self._ac
|
|
702
|
+
x = R_q.gen()
|
|
703
|
+
r = vector((x**(self._i % self.n) * R_q(a.list())).list()), c[self._i % self.n]
|
|
704
|
+
self._i += 1
|
|
705
|
+
return r
|
|
706
|
+
|
|
707
|
+
def _repr_(self):
|
|
708
|
+
"""
|
|
709
|
+
EXAMPLES::
|
|
710
|
+
|
|
711
|
+
sage: from sage.crypto.lwe import DiscreteGaussianDistributionPolynomialSampler, RingLWE, RingLWEConverter
|
|
712
|
+
sage: D = DiscreteGaussianDistributionPolynomialSampler(ZZ['x'], euler_phi(20), 5)
|
|
713
|
+
sage: rlwe = RingLWE(20, 257, D)
|
|
714
|
+
sage: lwe = RingLWEConverter(rlwe)
|
|
715
|
+
sage: lwe
|
|
716
|
+
RingLWEConverter(RingLWE(20, 257, Discrete Gaussian sampler for polynomials of degree < 8 with σ=5.000000 in each component, x^8 - x^6 + x^4 - x^2 + 1, 'uniform', None))
|
|
717
|
+
"""
|
|
718
|
+
return "RingLWEConverter(%s)" % str(self.ringlwe)
|
|
719
|
+
|
|
720
|
+
|
|
721
|
+
def samples(m, n, lwe, seed=None, balanced=False, **kwds):
|
|
722
|
+
"""
|
|
723
|
+
Return ``m`` LWE samples.
|
|
724
|
+
|
|
725
|
+
INPUT:
|
|
726
|
+
|
|
727
|
+
- ``m`` -- the number of samples (integer > 0)
|
|
728
|
+
- ``n`` -- the security parameter (integer > 0)
|
|
729
|
+
- ``lwe`` -- either
|
|
730
|
+
|
|
731
|
+
- a subclass of :class:`LWE` such as :class:`Regev` or :class:`LindnerPeikert`
|
|
732
|
+
- an instance of :class:`LWE` or any subclass
|
|
733
|
+
- the name of any such class (e.g., "Regev", "LindnerPeikert")
|
|
734
|
+
|
|
735
|
+
- ``seed`` -- seed to be used for generation or ``None`` if no specific seed
|
|
736
|
+
shall be set (default: ``None``)
|
|
737
|
+
- ``balanced`` -- use function :func:`balance_sample` to return balanced
|
|
738
|
+
representations of finite field elements (default: ``False``)
|
|
739
|
+
- ``**kwds`` -- passed through to LWE constructor
|
|
740
|
+
|
|
741
|
+
EXAMPLES::
|
|
742
|
+
|
|
743
|
+
sage: from sage.crypto.lwe import samples, Regev
|
|
744
|
+
sage: samples(2, 20, Regev, seed=1337)
|
|
745
|
+
[((199, 388, 337, 53, 200, 284, 336, 215, 75, 14, 274, 234, 97, 255, 246, 153, 268, 218, 396, 351), 15),
|
|
746
|
+
((365, 227, 333, 165, 76, 328, 288, 206, 286, 42, 175, 155, 190, 275, 114, 280, 45, 218, 304, 386), 143)]
|
|
747
|
+
|
|
748
|
+
sage: from sage.crypto.lwe import samples, Regev
|
|
749
|
+
sage: samples(2, 20, Regev, balanced=True, seed=1337)
|
|
750
|
+
[((199, -13, -64, 53, 200, -117, -65, -186, 75, 14, -127, -167, 97, -146, -155, 153, -133, -183, -5, -50), 15),
|
|
751
|
+
((-36, -174, -68, 165, 76, -73, -113, -195, -115, 42, 175, 155, 190, -126, 114, -121, 45, -183, -97, -15), 143)]
|
|
752
|
+
|
|
753
|
+
sage: from sage.crypto.lwe import samples
|
|
754
|
+
sage: samples(2, 20, 'LindnerPeikert')
|
|
755
|
+
[((506, 1205, 398, 0, 337, 106, 836, 75, 1242, 642, 840, 262, 1823, 1798, 1831, 1658, 1084, 915, 1994, 163), 1447),
|
|
756
|
+
((463, 250, 1226, 1906, 330, 933, 1014, 1061, 1322, 2035, 1849, 285, 1993, 1975, 864, 1341, 41, 1955, 1818, 1357), 312)]
|
|
757
|
+
"""
|
|
758
|
+
if seed is not None:
|
|
759
|
+
set_random_seed(seed)
|
|
760
|
+
|
|
761
|
+
if isinstance(lwe, str):
|
|
762
|
+
lwe = eval(lwe)
|
|
763
|
+
|
|
764
|
+
if isinstance(lwe, type):
|
|
765
|
+
lwe = lwe(n, m=m, **kwds)
|
|
766
|
+
else:
|
|
767
|
+
if lwe.n != n:
|
|
768
|
+
raise ValueError("Passed LWE instance has n=%d, but n=%d was passed to this function." % (lwe.n, n))
|
|
769
|
+
|
|
770
|
+
if balanced is False:
|
|
771
|
+
f = lambda a_c: a_c
|
|
772
|
+
else:
|
|
773
|
+
f = balance_sample
|
|
774
|
+
return [f(lwe()) for _ in range(m)]
|
|
775
|
+
|
|
776
|
+
|
|
777
|
+
def balance_sample(s, q=None):
|
|
778
|
+
r"""
|
|
779
|
+
Given ``(a,c) = s`` return a tuple ``(a',c')`` where ``a'`` is an integer
|
|
780
|
+
vector with entries between -q//2 and q//2 and ``c`` is also within these
|
|
781
|
+
bounds.
|
|
782
|
+
|
|
783
|
+
If ``q`` is given ``(a,c) = s`` may live in the integers. If ``q`` is not
|
|
784
|
+
given, then ``(a,c)`` are assumed to live in `\Zmod{q}`.
|
|
785
|
+
|
|
786
|
+
INPUT:
|
|
787
|
+
|
|
788
|
+
- ``s`` -- sample of the form (a,c) where a is a vector and c is a scalar
|
|
789
|
+
- ``q`` -- modulus (default: ``None``)
|
|
790
|
+
|
|
791
|
+
EXAMPLES::
|
|
792
|
+
|
|
793
|
+
sage: from sage.crypto.lwe import balance_sample, samples, Regev
|
|
794
|
+
sage: for s in samples(10, 5, Regev):
|
|
795
|
+
....: b = balance_sample(s)
|
|
796
|
+
....: assert all(-29//2 <= c <= 29//2 for c in b[0])
|
|
797
|
+
....: assert -29//2 <= b[1] <= 29//2
|
|
798
|
+
....: assert all(s[0][j] == b[0][j] % 29 for j in range(5))
|
|
799
|
+
....: assert s[1] == b[1] % 29
|
|
800
|
+
|
|
801
|
+
|
|
802
|
+
sage: from sage.crypto.lwe import balance_sample, DiscreteGaussianDistributionPolynomialSampler, RingLWE, samples
|
|
803
|
+
sage: D = DiscreteGaussianDistributionPolynomialSampler(ZZ['x'], 8, 5)
|
|
804
|
+
sage: rlwe = RingLWE(20, 257, D)
|
|
805
|
+
sage: for s in samples(10, 8, rlwe):
|
|
806
|
+
....: b = balance_sample(s)
|
|
807
|
+
....: assert all(-257//2 <= c <= 257//2 for bi in b for c in bi)
|
|
808
|
+
....: assert all(s[i][j] == b[i][j] % 257 for i in range(2) for j in range(8))
|
|
809
|
+
|
|
810
|
+
.. NOTE::
|
|
811
|
+
|
|
812
|
+
This function is useful to convert between Sage's standard
|
|
813
|
+
representation of elements in `\Zmod{q}` as integers between 0 and q-1
|
|
814
|
+
and the usual representation of such elements in lattice cryptography as
|
|
815
|
+
integers between -q//2 and q//2.
|
|
816
|
+
"""
|
|
817
|
+
a, c = s
|
|
818
|
+
|
|
819
|
+
try:
|
|
820
|
+
c[0]
|
|
821
|
+
scalar = False
|
|
822
|
+
except TypeError:
|
|
823
|
+
c = vector(c.parent(),[c])
|
|
824
|
+
scalar = True
|
|
825
|
+
|
|
826
|
+
if q is None:
|
|
827
|
+
q = parent(c[0]).order()
|
|
828
|
+
a = a.change_ring(ZZ)
|
|
829
|
+
c = c.change_ring(ZZ)
|
|
830
|
+
else:
|
|
831
|
+
K = IntegerModRing(q)
|
|
832
|
+
a = a.change_ring(K).change_ring(ZZ)
|
|
833
|
+
c = c.change_ring(K).change_ring(ZZ)
|
|
834
|
+
|
|
835
|
+
q2 = q//2
|
|
836
|
+
|
|
837
|
+
if scalar:
|
|
838
|
+
return vector(ZZ, len(a), [e if e <= q2 else e-q for e in a]), c[0] if c[0] <= q2 else c[0]-q
|
|
839
|
+
else:
|
|
840
|
+
return vector(ZZ, len(a), [e if e <= q2 else e-q for e in a]), vector(ZZ, len(c), [e if e <= q2 else e-q for e in c])
|