[Python-modules-commits] [fpylll] 01/03: Import fpylll_0.2.3+ds.orig.tar.xz
Jerome Benoit
calculus-guest at moszumanska.debian.org
Fri Oct 21 03:29:52 UTC 2016
This is an automated email from the git hooks/post-receive script.
calculus-guest pushed a commit to branch master
in repository fpylll.
commit 51c07eecbd45c663b8c1f800e2c1b70ccc2e31b5
Author: Jerome Benoit <calculus at rezozer.net>
Date: Fri Oct 21 04:04:33 2016 +0100
Import fpylll_0.2.3+ds.orig.tar.xz
---
PKG-INFO | 226 +++++++
README.rst | 216 ++++++
requirements.txt | 4 +
setup.py | 132 ++++
src/fpylll/__init__.py | 13 +
src/fpylll/algorithms/__init__.py | 0
src/fpylll/algorithms/bkz.py | 252 +++++++
src/fpylll/algorithms/bkz2.py | 126 ++++
src/fpylll/algorithms/bkz_stats.py | 191 ++++++
src/fpylll/algorithms/simple_bkz.py | 111 ++++
src/fpylll/algorithms/simple_dbkz.py | 80 +++
src/fpylll/config.pyx | 24 +
src/fpylll/fplll/__init__.py | 0
src/fpylll/fplll/bkz.pxd | 24 +
src/fpylll/fplll/bkz.pyx | 820 +++++++++++++++++++++++
src/fpylll/fplll/bkz_param.pxd | 40 ++
src/fpylll/fplll/bkz_param.pyx | 501 ++++++++++++++
src/fpylll/fplll/decl.pxd | 263 ++++++++
src/fpylll/fplll/enumeration.pxd | 9 +
src/fpylll/fplll/enumeration.pyx | 254 +++++++
src/fpylll/fplll/fplll.pxd | 607 +++++++++++++++++
src/fpylll/fplll/gso.pxd | 12 +
src/fpylll/fplll/gso.pyx | 1081 ++++++++++++++++++++++++++++++
src/fpylll/fplll/integer_matrix.pxd | 11 +
src/fpylll/fplll/integer_matrix.pyx | 1211 ++++++++++++++++++++++++++++++++++
src/fpylll/fplll/lll.pxd | 13 +
src/fpylll/fplll/lll.pyx | 483 ++++++++++++++
src/fpylll/fplll/pruner.pyx | 289 ++++++++
src/fpylll/fplll/svpcvp.pyx | 143 ++++
src/fpylll/fplll/wrapper.pxd | 12 +
src/fpylll/fplll/wrapper.pyx | 74 +++
src/fpylll/gmp/__init__.py | 0
src/fpylll/gmp/all.pxd | 6 +
src/fpylll/gmp/misc.pxd | 8 +
src/fpylll/gmp/mpf.pxd | 88 +++
src/fpylll/gmp/mpn.pxd | 57 ++
src/fpylll/gmp/mpq.pxd | 57 ++
src/fpylll/gmp/mpz.pxd | 199 ++++++
src/fpylll/gmp/pylong.pxd | 25 +
src/fpylll/gmp/pylong.pyx | 104 +++
src/fpylll/gmp/random.pxd | 25 +
src/fpylll/gmp/types.pxd | 54 ++
src/fpylll/io.pxd | 9 +
src/fpylll/io.pyx | 54 ++
src/fpylll/mpfr/__init__.py | 0
src/fpylll/mpfr/mpfr.pxd | 317 +++++++++
src/fpylll/numpy.pyx | 101 +++
src/fpylll/qd/__init__.py | 0
src/fpylll/qd/qd.pxd | 12 +
src/fpylll/tools/__init__.py | 3 +
src/fpylll/tools/benchmark.py | 33 +
src/fpylll/util.pxd | 10 +
src/fpylll/util.pyx | 209 ++++++
suggestions.txt | 4 +
tests/test_bkz.py | 42 ++
tests/test_bkz_python.py | 48 ++
tests/test_gso.py | 84 +++
tests/test_lll.py | 38 ++
tests/test_numpy.py | 38 ++
tests/test_precision.py | 9 +
tests/test_pruner.py | 36 +
tests/test_random.py | 19 +
tests/test_simple_bkz.py | 37 ++
63 files changed, 8948 insertions(+)
diff --git a/PKG-INFO b/PKG-INFO
new file mode 100644
index 0000000..dfb10af
--- /dev/null
+++ b/PKG-INFO
@@ -0,0 +1,226 @@
+Metadata-Version: 1.0
+Name: fpylll
+Version: 0.2.3dev
+Summary: A Python interface for https://github.com/fplll/fplll
+Home-page: https://github.com/fplll/fpylll
+Author: Martin R. Albrecht
+Author-email: fplll-devel at googlegroups.com
+License: GNU General Public License, version 2 or later
+Description: fpylll
+ ======
+
+ A Python (2 and 3) wrapper for `fplll <https://github.com/fplll/fplll>`__.
+
+ .. image:: https://travis-ci.org/fplll/fpylll.svg?branch=master
+ :target: https://travis-ci.org/fplll/fpylll
+
+ .. code-block:: python
+
+ >>> from fpylll import *
+
+ >>> A = IntegerMatrix(50, 50)
+ >>> A.randomize("ntrulike", bits=50, q=127)
+ >>> A[0].norm()
+ 3564748886669202.5
+
+ >>> M = GSO.Mat(A)
+ >>> M.update_gso()
+ >>> M.get_mu(1,0)
+ 0.815748944429783
+
+ >>> L = LLL.Reduction(M)
+ >>> L()
+ >>> M.get_mu(1,0)
+ 0.41812865497076024
+ >>> A[0].norm()
+ 24.06241883103193
+
+ The basic BKZ algorithm can be implemented in about 60 pretty readable lines of Python code (cf. `simple_bkz.py <https://github.com/fplll/fpylll/blob/master/src/fpylll/algorithms/simple_bkz.py>`__).
+
+ Requirements
+ ------------
+
+ **fpylll** relies on the following C/C++ libraries:
+
+ - `GMP <https://gmplib.org>`__ or `MPIR <http://mpir.org>`__ for arbitrary precision integer arithmetic.
+ - `MPFR <http://www.mpfr.org>`__ for arbitrary precision floating point arithmetic.
+ - `QD <http://crd-legacy.lbl.gov/~dhbailey/mpdist/>`__ for double double and quad double arithmetic (optional).
+ - `fplll <https://github.com/fplll/fplll>`__ for pretty much everything.
+
+ **fpylll** also relies on
+
+ - `Cython <http://cython.org>`__ for linking Python and C/C++.
+ - `cysignals <https://github.com/sagemath/cysignals>`__ for signal handling such as interrupting C++ code.
+ - `py.test <http://pytest.org/latest/>`__ for testing Python.
+ - `flake8 <https://flake8.readthedocs.org/en/latest/>`__ for linting.
+
+ We also suggest
+
+ - `IPython <https://ipython.org>`__ for interacting with Python
+ - `Numpy <http://www.numpy.org>`__ for numerical computations (e.g. with Gram-Schmidt values)
+
+ Getting Started
+ ---------------
+
+ We recommend `virtualenv <https://virtualenv.readthedocs.org/>`__ for isolating Python build environments and `virtualenvwrapper <https://virtualenvwrapper.readthedocs.org/>`__ to manage virtual environments.
+
+ 1. Create a new virtualenv and activate it:
+
+ .. code-block:: bash
+
+ $ virtualenv env
+ $ source ./env/bin/activate
+
+ We indicate active virtualenvs by the prefix ``(fpylll)``.
+
+ 2. Install the required libraries – `GMP <https://gmplib.org>`__ or `MPIR <http://mpir.org>`__ and `MPFR <http://www.mpfr.org>`__ – if not available already. You may also want to install `QD <http://crd-legacy.lbl.gov/~dhbailey/mpdist/>`__.
+
+ 3. Install fplll:
+
+ .. code-block:: bash
+
+ $ (fpylll) ./install-dependencies.sh $VIRTUAL_ENV
+
+ 4. Then, execute:
+
+ .. code-block:: bash
+
+ $ (fpylll) pip install Cython
+ $ (fpylll) pip install -r requirements.txt
+
+ to install the required Python packages (see above).
+
+ 5. If you are so inclined, run:
+
+ .. code-block:: bash
+
+ $ (fpylll) pip install -r suggestions.txt
+
+ to install suggested Python packages as well (optional).
+
+ 6. Build the Python extension:
+
+ .. code-block:: bash
+
+ $ (fpylll) export PKG_CONFIG_PATH="$VIRTUAL_ENV/lib/pkgconfig:$PKG_CONFIG_PATH"
+ $ (fpylll) python setup.py build_ext
+ $ (fpylll) python setup.py install
+
+ 7. To run **fpylll**, you will need to:
+
+ .. code-block:: bash
+
+ $ (fpylll) export LD_LIBRARY_PATH="$VIRTUAL_ENV/lib"
+
+ so that Python can find fplll and friends.
+
+ 8. Start Python:
+
+ .. code-block:: bash
+
+ $ (fpylll) ipython
+
+ To reactivate the virtual environment later, simply run:
+
+ .. code-block:: bash
+
+ $ source ./env/bin/activate
+
+ Note that you can also patch ``activate`` to set ``LD_LIBRRY_PATH``. For this, add:
+
+ .. code-block:: bash
+
+ ### LD_LIBRARY_HACK
+ _OLD_LD_LIBRARY_PATH="$LD_LIBRARY_PATH"
+ LD_LIBRARY_PATH="$VIRTUAL_ENV/lib:$LD_LIBRARY_PATH"
+ export LD_LIBRARY_PATH
+ ### END_LD_LIBRARY_HACK
+
+ ### PKG_CONFIG_HACK
+ _OLD_PKG_CONFIG_PATH="$PKG_CONFIG_PATH"
+ PKG_CONFIG_PATH="$VIRTUAL_ENV/lib/pkgconfig:$PKG_CONFIG_PATH"
+ export PKG_CONFIG_PATH
+ ### END_PKG_CONFIG_HACK
+
+ towards the end and:
+
+ .. code-block:: bash
+
+ ### LD_LIBRARY_HACK
+ if ! [ -z ${_OLD_LD_LIBRARY_PATH+x} ] ; then
+ LD_LIBRARY_PATH="$_OLD_LD_LIBRARY_PATH"
+ export LD_LIBRARY_PATH
+ unset _OLD_LD_LIBRARY_PATH
+ fi
+ ### END_LD_LIBRARY_HACK
+
+ ### PKG_CONFIG_HACK
+ if ! [ -z ${_OLD_PKG_CONFIG_PATH+x} ] ; then
+ PKG_CONFIG_PATH="$_OLD_PKG_CONFIG_PATH"
+ export PKG_CONFIG_PATH
+ unset _OLD_PKG_CONFIG_PATH
+ fi
+ ### END_PKG_CONFIG_HACK
+
+ in the ``deactivate`` function in the ``activate`` script.
+
+ Multicore Support
+ -----------------
+
+ **fpylll** supports parallelisation on multiple cores. For all C++ support to drop the `GIL <https://wiki.python.org/moin/GlobalInterpreterLock>`_ is enabled, allowing the use of threads to parallelise. Note, however, that because fplll’s enumeration is not thread safe, we using `locks <https://docs.python.org/2/library/threading.html#lock-objects>`_ to enforce only one thread calls it at any one point. Also, **fpylll** does not actually drop the GIL in all calls to C++ functions [...]
+
+ The example below calls ``LLL.reduction`` on 128 matrices of dimension 30 on four worker processes.
+
+ .. code-block:: python
+
+ from fpylll import IntegerMatrix, LLL
+ from multiprocessing import Pool
+
+ d, workers, tasks = 30, 4, 128
+
+ def run_it(p, f, A, prefix=""):
+ """Print status during parallel execution."""
+ import sys
+ r = []
+ for i, retval in enumerate(p.imap_unordered(f, A, 1)):
+ r.append(retval)
+ sys.stderr.write('\r{0} done: {1:.2%}'.format(prefix, float(i)/len(A)))
+ sys.stderr.flush()
+ sys.stderr.write('\r{0} done {1:.2%}\n'.format(prefix, float(i+1)/len(A)))
+ return r
+
+ A = [IntegerMatrix.random(d, "uniform", bits=30) for _ in range(tasks)]
+ A = run_it(Pool(workers), LLL.reduction)
+
+ To test threading simply replace the line ``from multiprocessing import Pool`` with ``from multiprocessing.pool import ThreadPool as Pool``. For calling ``BKZ.reduction`` this way, which expects a second parameter with options, using `functools.partial <https://docs.python.org/2/library/functools.html#functools.partial>`_ is a good choice.
+
+ Contributing
+ ------------
+
+ **fpylll** welcomes contributions, cf. the list of `open issues <https://github.com/fplll/fpylll/issues>`_. To contribute, clone this repository, commit your code on a separate branch and send a pull request. Please write tests for your code. You can run them by calling::
+
+ $ (fpylll) py.test
+
+ from the top-level directory which runs all tests in ``tests/test_*.py``. We run `flake8 <https://flake8.readthedocs.org/en/latest/>`_ on every commit automatically, In particular, we run::
+
+ $ (fpylll) flake8 --max-line-length=120 --max-complexity=16 --ignore=E22,E241 src
+
+ Note that **fpylll** supports Python 2 and 3. In particular, tests are run using Python 2.7 and 3.5. See `.travis.yml <https://github.com/fplll/fpylll/blob/master/.travis.yml>`_ for details on automated testing.
+
+ Attribution & License
+ ---------------------
+
+ **fpylll** is maintained by Martin Albrecht.
+
+ The following people have contributed to **fpylll**
+
+ - Martin Albrecht
+ - Guillaume Bonnoron
+ - Leo Ducas
+ - Omer Katz
+
+ We copied a decent bit of code over from Sage, mostly from it’s fpLLL interface.
+
+ **fpylll** is licensed under the GPLv2+.
+
+Platform: UNKNOWN
diff --git a/README.rst b/README.rst
new file mode 100644
index 0000000..c94f60e
--- /dev/null
+++ b/README.rst
@@ -0,0 +1,216 @@
+fpylll
+======
+
+A Python (2 and 3) wrapper for `fplll <https://github.com/fplll/fplll>`__.
+
+.. image:: https://travis-ci.org/fplll/fpylll.svg?branch=master
+ :target: https://travis-ci.org/fplll/fpylll
+
+.. code-block:: python
+
+ >>> from fpylll import *
+
+ >>> A = IntegerMatrix(50, 50)
+ >>> A.randomize("ntrulike", bits=50, q=127)
+ >>> A[0].norm()
+ 3564748886669202.5
+
+ >>> M = GSO.Mat(A)
+ >>> M.update_gso()
+ >>> M.get_mu(1,0)
+ 0.815748944429783
+
+ >>> L = LLL.Reduction(M)
+ >>> L()
+ >>> M.get_mu(1,0)
+ 0.41812865497076024
+ >>> A[0].norm()
+ 24.06241883103193
+
+The basic BKZ algorithm can be implemented in about 60 pretty readable lines of Python code (cf. `simple_bkz.py <https://github.com/fplll/fpylll/blob/master/src/fpylll/algorithms/simple_bkz.py>`__).
+
+Requirements
+------------
+
+**fpylll** relies on the following C/C++ libraries:
+
+- `GMP <https://gmplib.org>`__ or `MPIR <http://mpir.org>`__ for arbitrary precision integer arithmetic.
+- `MPFR <http://www.mpfr.org>`__ for arbitrary precision floating point arithmetic.
+- `QD <http://crd-legacy.lbl.gov/~dhbailey/mpdist/>`__ for double double and quad double arithmetic (optional).
+- `fplll <https://github.com/fplll/fplll>`__ for pretty much everything.
+
+**fpylll** also relies on
+
+- `Cython <http://cython.org>`__ for linking Python and C/C++.
+- `cysignals <https://github.com/sagemath/cysignals>`__ for signal handling such as interrupting C++ code.
+- `py.test <http://pytest.org/latest/>`__ for testing Python.
+- `flake8 <https://flake8.readthedocs.org/en/latest/>`__ for linting.
+
+We also suggest
+
+- `IPython <https://ipython.org>`__ for interacting with Python
+- `Numpy <http://www.numpy.org>`__ for numerical computations (e.g. with Gram-Schmidt values)
+
+Getting Started
+---------------
+
+We recommend `virtualenv <https://virtualenv.readthedocs.org/>`__ for isolating Python build environments and `virtualenvwrapper <https://virtualenvwrapper.readthedocs.org/>`__ to manage virtual environments.
+
+1. Create a new virtualenv and activate it:
+
+ .. code-block:: bash
+
+ $ virtualenv env
+ $ source ./env/bin/activate
+
+ We indicate active virtualenvs by the prefix ``(fpylll)``.
+
+2. Install the required libraries – `GMP <https://gmplib.org>`__ or `MPIR <http://mpir.org>`__ and `MPFR <http://www.mpfr.org>`__ – if not available already. You may also want to install `QD <http://crd-legacy.lbl.gov/~dhbailey/mpdist/>`__.
+
+3. Install fplll:
+
+ .. code-block:: bash
+
+ $ (fpylll) ./install-dependencies.sh $VIRTUAL_ENV
+
+4. Then, execute:
+
+ .. code-block:: bash
+
+ $ (fpylll) pip install Cython
+ $ (fpylll) pip install -r requirements.txt
+
+ to install the required Python packages (see above).
+
+5. If you are so inclined, run:
+
+ .. code-block:: bash
+
+ $ (fpylll) pip install -r suggestions.txt
+
+ to install suggested Python packages as well (optional).
+
+6. Build the Python extension:
+
+ .. code-block:: bash
+
+ $ (fpylll) export PKG_CONFIG_PATH="$VIRTUAL_ENV/lib/pkgconfig:$PKG_CONFIG_PATH"
+ $ (fpylll) python setup.py build_ext
+ $ (fpylll) python setup.py install
+
+7. To run **fpylll**, you will need to:
+
+ .. code-block:: bash
+
+ $ (fpylll) export LD_LIBRARY_PATH="$VIRTUAL_ENV/lib"
+
+ so that Python can find fplll and friends.
+
+8. Start Python:
+
+ .. code-block:: bash
+
+ $ (fpylll) ipython
+
+To reactivate the virtual environment later, simply run:
+
+ .. code-block:: bash
+
+ $ source ./env/bin/activate
+
+Note that you can also patch ``activate`` to set ``LD_LIBRRY_PATH``. For this, add:
+
+.. code-block:: bash
+
+ ### LD_LIBRARY_HACK
+ _OLD_LD_LIBRARY_PATH="$LD_LIBRARY_PATH"
+ LD_LIBRARY_PATH="$VIRTUAL_ENV/lib:$LD_LIBRARY_PATH"
+ export LD_LIBRARY_PATH
+ ### END_LD_LIBRARY_HACK
+
+ ### PKG_CONFIG_HACK
+ _OLD_PKG_CONFIG_PATH="$PKG_CONFIG_PATH"
+ PKG_CONFIG_PATH="$VIRTUAL_ENV/lib/pkgconfig:$PKG_CONFIG_PATH"
+ export PKG_CONFIG_PATH
+ ### END_PKG_CONFIG_HACK
+
+towards the end and:
+
+.. code-block:: bash
+
+ ### LD_LIBRARY_HACK
+ if ! [ -z ${_OLD_LD_LIBRARY_PATH+x} ] ; then
+ LD_LIBRARY_PATH="$_OLD_LD_LIBRARY_PATH"
+ export LD_LIBRARY_PATH
+ unset _OLD_LD_LIBRARY_PATH
+ fi
+ ### END_LD_LIBRARY_HACK
+
+ ### PKG_CONFIG_HACK
+ if ! [ -z ${_OLD_PKG_CONFIG_PATH+x} ] ; then
+ PKG_CONFIG_PATH="$_OLD_PKG_CONFIG_PATH"
+ export PKG_CONFIG_PATH
+ unset _OLD_PKG_CONFIG_PATH
+ fi
+ ### END_PKG_CONFIG_HACK
+
+in the ``deactivate`` function in the ``activate`` script.
+
+Multicore Support
+-----------------
+
+**fpylll** supports parallelisation on multiple cores. For all C++ support to drop the `GIL <https://wiki.python.org/moin/GlobalInterpreterLock>`_ is enabled, allowing the use of threads to parallelise. Note, however, that because fplll’s enumeration is not thread safe, we using `locks <https://docs.python.org/2/library/threading.html#lock-objects>`_ to enforce only one thread calls it at any one point. Also, **fpylll** does not actually drop the GIL in all calls to C++ functions yet. In [...]
+
+The example below calls ``LLL.reduction`` on 128 matrices of dimension 30 on four worker processes.
+
+.. code-block:: python
+
+ from fpylll import IntegerMatrix, LLL
+ from multiprocessing import Pool
+
+ d, workers, tasks = 30, 4, 128
+
+ def run_it(p, f, A, prefix=""):
+ """Print status during parallel execution."""
+ import sys
+ r = []
+ for i, retval in enumerate(p.imap_unordered(f, A, 1)):
+ r.append(retval)
+ sys.stderr.write('\r{0} done: {1:.2%}'.format(prefix, float(i)/len(A)))
+ sys.stderr.flush()
+ sys.stderr.write('\r{0} done {1:.2%}\n'.format(prefix, float(i+1)/len(A)))
+ return r
+
+ A = [IntegerMatrix.random(d, "uniform", bits=30) for _ in range(tasks)]
+ A = run_it(Pool(workers), LLL.reduction)
+
+To test threading simply replace the line ``from multiprocessing import Pool`` with ``from multiprocessing.pool import ThreadPool as Pool``. For calling ``BKZ.reduction`` this way, which expects a second parameter with options, using `functools.partial <https://docs.python.org/2/library/functools.html#functools.partial>`_ is a good choice.
+
+Contributing
+------------
+
+**fpylll** welcomes contributions, cf. the list of `open issues <https://github.com/fplll/fpylll/issues>`_. To contribute, clone this repository, commit your code on a separate branch and send a pull request. Please write tests for your code. You can run them by calling::
+
+ $ (fpylll) py.test
+
+from the top-level directory which runs all tests in ``tests/test_*.py``. We run `flake8 <https://flake8.readthedocs.org/en/latest/>`_ on every commit automatically, In particular, we run::
+
+ $ (fpylll) flake8 --max-line-length=120 --max-complexity=16 --ignore=E22,E241 src
+
+Note that **fpylll** supports Python 2 and 3. In particular, tests are run using Python 2.7 and 3.5. See `.travis.yml <https://github.com/fplll/fpylll/blob/master/.travis.yml>`_ for details on automated testing.
+
+Attribution & License
+---------------------
+
+**fpylll** is maintained by Martin Albrecht.
+
+The following people have contributed to **fpylll**
+
+- Martin Albrecht
+- Guillaume Bonnoron
+- Leo Ducas
+- Omer Katz
+
+We copied a decent bit of code over from Sage, mostly from it’s fpLLL interface.
+
+**fpylll** is licensed under the GPLv2+.
diff --git a/requirements.txt b/requirements.txt
new file mode 100644
index 0000000..b394ecb
--- /dev/null
+++ b/requirements.txt
@@ -0,0 +1,4 @@
+Cython
+pytest
+cysignals
+flake8
diff --git a/setup.py b/setup.py
new file mode 100755
index 0000000..bea6dd3
--- /dev/null
+++ b/setup.py
@@ -0,0 +1,132 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+from distutils.core import setup
+from distutils.extension import Extension
+import Cython.Build
+
+import os
+import subprocess
+import sys
+from copy import copy
+
+
+# CONFIG VARIABLES
+
+cythonize_dir = "build"
+
+fplll = {"include_dirs": [],
+ "library_dirs": [],
+ "language": "c++",
+ "libraries": ["gmp", "mpfr", "fplll"],
+ "extra_compile_args": ["-std=c++11"],
+ "extra_link_args": ["-std=c++11"]}
+
+other = {"include_dirs": [],
+ "library_dirs": [],
+ "libraries": ["gmp"]}
+
+config_pxi = []
+
+
+# VIRTUALENVS
+
+if "VIRTUAL_ENV" in os.environ:
+ prefix = os.environ["VIRTUAL_ENV"]
+ fplll["include_dirs"] = [os.path.join(prefix, "include")]
+ fplll["library_dirs"] = [os.path.join(prefix, "lib")]
+ other["include_dirs"] = [os.path.join(prefix, "include")]
+ other["library_dirs"] = [os.path.join(prefix, "lib")]
+
+
+# QD
+have_qd = False
+
+try:
+ libs = subprocess.check_output(["pkg-config", "fplll", "--libs"])
+ if b"-lqd" in libs:
+ have_qd = True
+except subprocess.CalledProcessError:
+ pass
+
+if have_qd:
+ fplll["libraries"].append("qd")
+ config_pxi.append("DEF HAVE_QD=True")
+else:
+ config_pxi.append("DEF HAVE_QD=False")
+
+
+# NUMPY
+
+try:
+ import numpy
+ have_numpy = True
+except ImportError:
+ have_numpy = False
+
+if have_numpy:
+ config_pxi.append("DEF HAVE_NUMPY=True")
+ numpy_args = copy(fplll)
+ numpy_args["include_dirs"].append(numpy.get_include())
+else:
+ config_pxi.append("DEF HAVE_NUMPY=False")
+
+# Ideally this would check the fplll headers explicitly for the
+# the FPLLL_WITH_LONG_DOUBLE define, but for now it suffices to
+# say that long double support is disabled on Cygwin
+have_long_double = not sys.platform.startswith('cygwin')
+config_pxi.append("DEF HAVE_LONG_DOUBLE={0}".format(have_long_double))
+
+
+# CONFIG.PXI
+config_pxi_path = os.path.join(".", "src", "fpylll", "config.pxi")
+config_pxi = "\n".join(config_pxi) + "\n"
+
+try:
+ cur_config_pxi = open(config_pxi_path, "r").read()
+except IOError:
+ cur_config_pxi = ""
+
+if cur_config_pxi != config_pxi: # check if we need to write
+ with open(config_pxi_path, "w") as fw:
+ fw.write(config_pxi)
+
+
+# EXTENSIONS
+
+extensions = [
+ Extension("gmp.pylong", ["src/fpylll/gmp/pylong.pyx"], **other),
+ Extension("fplll.integer_matrix", ["src/fpylll/fplll/integer_matrix.pyx"], **fplll),
+ Extension("fplll.gso", ["src/fpylll/fplll/gso.pyx"], **fplll),
+ Extension("fplll.lll", ["src/fpylll/fplll/lll.pyx"], **fplll),
+ Extension("fplll.wrapper", ["src/fpylll/fplll/wrapper.pyx"], **fplll),
+ Extension("fplll.bkz_param", ["src/fpylll/fplll/bkz_param.pyx"], **fplll),
+ Extension("fplll.bkz", ["src/fpylll/fplll/bkz.pyx"], **fplll),
+ Extension("fplll.enumeration", ["src/fpylll/fplll/enumeration.pyx"], **fplll),
+ Extension("fplll.svpcvp", ["src/fpylll/fplll/svpcvp.pyx"], **fplll),
+ Extension("fplll.pruner", ["src/fpylll/fplll/pruner.pyx"], **fplll),
+ Extension("util", ["src/fpylll/util.pyx"], **fplll),
+ Extension("io", ["src/fpylll/io.pyx"], **fplll),
+ Extension("config", ["src/fpylll/config.pyx"], **fplll),
+]
+
+if have_numpy:
+ extensions.append(Extension("numpy", ["src/fpylll/numpy.pyx"], **numpy_args))
+
+
+setup(
+ name="fpylll",
+ description="A Python interface for https://github.com/fplll/fplll",
+ author=u"Martin R. Albrecht",
+ author_email="fplll-devel at googlegroups.com",
+ url="https://github.com/fplll/fpylll",
+ version='0.2.3dev',
+ ext_package='fpylll',
+ ext_modules=Cython.Build.cythonize(extensions,
+ include_path=["src"] + sys.path,
+ build_dir=cythonize_dir,
+ compiler_directives={'embedsignature': True}),
+ package_dir={"": "src"},
+ packages=["fpylll", "fpylll.gmp", "fpylll.fplll", "fpylll.algorithms", "fpylll.tools"],
+ license='GNU General Public License, version 2 or later',
+ long_description=open('README.rst').read(),
+)
diff --git a/src/fpylll/__init__.py b/src/fpylll/__init__.py
new file mode 100644
index 0000000..8f83fe3
--- /dev/null
+++ b/src/fpylll/__init__.py
@@ -0,0 +1,13 @@
+# flake8: noqa
+from __future__ import absolute_import
+from .fplll.integer_matrix import IntegerMatrix
+from .fplll.gso import GSO
+from .fplll.lll import LLL
+from .fplll.enumeration import Enumeration, EnumerationError
+from .fplll.bkz import BKZ
+from .fplll.bkz_param import load_strategies_json
+from .fplll.svpcvp import SVP
+from .fplll.svpcvp import CVP
+from .fplll.pruner import prune
+from .util import ReductionError
+from .util import set_random_seed, set_precision, get_precision
diff --git a/src/fpylll/algorithms/__init__.py b/src/fpylll/algorithms/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/src/fpylll/algorithms/bkz.py b/src/fpylll/algorithms/bkz.py
new file mode 100644
index 0000000..4e6d288
--- /dev/null
+++ b/src/fpylll/algorithms/bkz.py
@@ -0,0 +1,252 @@
+# -*- coding: utf-8 -*-
+"""
+Block Korkine Zolotarev algorithm in Python.
+
+.. moduleauthor:: Martin R. Albrecht <martinralbrecht+fpylll at googlemail.com>
+
+This module reimplements fplll's BKZ algorithm in Python. It has feature parity with the C++
+implementation in fplll's core. Additionally, this implementation collects some additional
+statistics. Hence, it should provide a good basis for implementing variants of this algorithm.
+"""
+from __future__ import absolute_import
+import time
+from fpylll import IntegerMatrix, GSO, LLL
+from fpylll import BKZ
+from fpylll import Enumeration
+from fpylll import EnumerationError
+from fpylll.util import gaussian_heuristic
+from .bkz_stats import BKZStats
+
+
+class BKZReduction:
+ """
+ An implementation of the BKZ algorithm in Python.
+
+ This class has feature parity with the C++ implementation in fplll's core. Additionally, this
+ implementation collects some additional statistics. Hence, it should provide a good basis for
+ implementing variants of this algorithm.
+ """
+ def __init__(self, A):
+ """Construct a new instance of the BKZ algorithm.
+
+ :param A: an integer matrix, a GSO object or an LLL object
+
+ """
+ if isinstance(A, GSO.Mat):
+ L = None
+ M = A
+ A = M.B
+ elif isinstance(A, LLL.Reduction):
+ L = A
+ M = L.M
+ A = M.B
+ elif isinstance(A, IntegerMatrix):
+ L = None
+ M = None
+ A = A
+ else:
+ raise TypeError("Matrix must be IntegerMatrix but got type '%s'"%type(A))
+
+ if M is None and L is None:
+ # run LLL first, but only if a matrix was passed
+ wrapper = LLL.Wrapper(A)
+ wrapper()
+
+ self.A = A
+ if M is None:
+ self.M = GSO.Mat(A, flags=GSO.ROW_EXPO)
+ else:
+ self.M = M
+ if L is None:
+ self.lll_obj = LLL.Reduction(self.M, flags=LLL.DEFAULT)
+ else:
+ self.lll_obj = L
+
+ self.lll_obj()
+
+ def __call__(self, params, min_row=0, max_row=-1):
+ """Run the BKZ algorithm with parameters `param`.
+
+ :param params: BKZ parameters
+ :param min_row: start processing in this row
+ :param max_row: stop processing in this row (exclusive)
+
+ """
+ stats = BKZStats(self, verbose=params.flags & BKZ.VERBOSE)
+
+ if params.flags & BKZ.AUTO_ABORT:
+ auto_abort = BKZ.AutoAbort(self.M, self.A.nrows)
+
+ cputime_start = time.clock()
+
+ self.M.discover_all_rows()
+
+ i = 0
+ while True:
+ with stats.context("tour"):
+ clean = self.tour(params, min_row, max_row, stats)
+ i += 1
+ if clean or params.block_size >= self.A.nrows:
+ break
+ if (params.flags & BKZ.AUTO_ABORT) and auto_abort.test_abort():
+ break
+ if (params.flags & BKZ.MAX_LOOPS) and i >= params.max_loops:
+ break
+ if (params.flags & BKZ.MAX_TIME) and time.clock() - cputime_start >= params.max_time:
+ break
+
+ stats.finalize()
+ self.stats = stats
+ return clean
+
+ def tour(self, params, min_row=0, max_row=-1, stats=None):
+ """One BKZ loop over all indices.
+
+ :param params: BKZ parameters
+ :param min_row: start index ≥ 0
+ :param max_row: last index ≤ n
+
+ :returns: ``True`` if no change was made and ``False`` otherwise
+ """
+ if max_row == -1:
+ max_row = self.A.nrows
+
+ clean = True
+
+ for kappa in range(min_row, max_row-2):
+ block_size = min(params.block_size, max_row - kappa)
+ clean &= self.svp_reduction(kappa, block_size, params, stats)
+ if stats:
+ stats.log_clean_kappa(kappa, clean)
+
+ return clean
+
+ def svp_preprocessing(self, kappa, block_size, params, stats):
+ """Perform preprocessing for calling the SVP oracle
+
+ :param kappa: current index
+ :param params: BKZ parameters
+ :param block_size: block size
+ :param stats: object for maintaining statistics
+
+ :returns: ``True`` if no change was made and ``False`` otherwise
+
+ .. note::
+
+ ``block_size`` may be smaller than ``params.block_size`` for the last blocks.
+
+ """
+ clean = True
+
+ lll_start = kappa if params.flags & BKZ.BOUNDED_LLL else 0
+ with stats.context("lll"):
+ self.lll_obj(lll_start, lll_start, kappa + block_size)
+ if self.lll_obj.nswaps > 0:
+ clean = False
+
+ return clean
+
+ def svp_call(self, kappa, block_size, params, stats=None):
+ """Call SVP oracle
+
+ :param kappa: current index
+ :param params: BKZ parameters
+ :param block_size: block size
+ :param stats: object for maintaining statistics
+
+ :returns: Coordinates of SVP solution or ``None`` if none was found.
+
+ .. note::
+
+ ``block_size`` may be smaller than ``params.block_size`` for the last blocks.
+ """
+ max_dist, expo = self.M.get_r_exp(kappa, kappa)
+ delta_max_dist = self.lll_obj.delta * max_dist
+
+ if params.flags & BKZ.GH_BND:
+ root_det = self.M.get_root_det(kappa, kappa+block_size)
+ max_dist, expo = gaussian_heuristic(max_dist, expo, block_size, root_det, params.gh_factor)
+
+ try:
+ E = Enumeration(self.M)
+ solution, max_dist = E.enumerate(kappa, kappa + block_size, max_dist, expo)
+ stats.current_tour["enum nodes"] += E.get_nodes()
+ except EnumerationError as msg:
+ if params.flags & BKZ.GH_BND:
+ return None
+ else:
+ raise EnumerationError(msg)
+
+ if max_dist >= delta_max_dist:
+ return None
+ else:
+ return solution
+
+ def svp_postprocessing(self, kappa, block_size, solution, stats):
+ """Insert SVP solution into basis and LLL reduce.
+
+ :param solution: coordinates of an SVP solution
+ :param kappa: current index
+ :param block_size: block size
+ :param stats: object for maintaining statistics
+
+ :returns: ``True`` if no change was made and ``False`` otherwise
+ """
+ if solution is None:
+ return True
+
+ nonzero_vectors = len([x for x in solution if x])
+ if nonzero_vectors == 1:
+ first_nonzero_vector = None
+ for i in range(block_size):
+ if abs(solution[i]) == 1:
+ first_nonzero_vector = i
+ break
+
+ self.M.move_row(kappa + first_nonzero_vector, kappa)
+ with stats.context("lll"):
+ self.lll_obj.size_reduction(kappa, kappa + first_nonzero_vector + 1)
+
+ else:
+ d = self.M.d
+ self.M.create_row()
+
+ with self.M.row_ops(d, d+1):
+ for i in range(block_size):
+ self.M.row_addmul(d, kappa + i, solution[i])
+
+ self.M.move_row(d, kappa)
+ with stats.context("lll"):
+ self.lll_obj(kappa, kappa, kappa + block_size + 1)
+ self.M.move_row(kappa + block_size, d)
+ self.M.remove_last_row()
+
+ return False
+
+ def svp_reduction(self, kappa, block_size, params, stats=None):
+ """Find shortest vector in projected lattice of dimension ``block_size`` and insert into
+ current basis.
+
+ :param kappa: current index
+ :param params: BKZ parameters
+ :param block_size: block size
+ :param stats: object for maintaining statistics
+
+ :returns: ``True`` if no change was made and ``False`` otherwise
+ """
+ if stats is None:
+ stats = BKZStats(self)
+
+ clean = True
+ with stats.context("preproc"):
+ clean_pre = self.svp_preprocessing(kappa, block_size, params, stats)
+ clean &= clean_pre
+
+ with stats.context("svp"):
+ solution = self.svp_call(kappa, block_size, params, stats)
+
+ with stats.context("postproc"):
+ clean_post = self.svp_postprocessing(kappa, block_size, solution, stats)
+ clean &= clean_post
+
+ return clean
diff --git a/src/fpylll/algorithms/bkz2.py b/src/fpylll/algorithms/bkz2.py
new file mode 100644
index 0000000..a2ab3f1
--- /dev/null
+++ b/src/fpylll/algorithms/bkz2.py
@@ -0,0 +1,126 @@
+# -*- coding: utf-8 -*-
+
+from random import randint
+from fpylll import BKZ, Enumeration, EnumerationError
+from fpylll.algorithms.bkz import BKZReduction as BKZBase
+from fpylll.algorithms.bkz_stats import DummyStats
+from fpylll.util import gaussian_heuristic
+
+
+class BKZReduction(BKZBase):
+
+ def __init__(self, A):
+ """Create new BKZ object.
+
+ :param A: an integer matrix, a GSO object or an LLL object
+
+ """
+ BKZBase.__init__(self, A)
+ self.M.discover_all_rows() # TODO: this belongs in __call__ (?)
+
+ def get_pruning(self, kappa, block_size, param, stats=None):
+ strategy = param.strategies[block_size]
+
+ radius, re = self.M.get_r_exp(kappa, kappa)
+ root_det = self.M.get_root_det(kappa, kappa + block_size)
+ gh_radius, ge = gaussian_heuristic(radius, re, block_size, root_det, 1.0)
+ return strategy.get_pruning(radius * 2**re, gh_radius * 2**ge)
+
+ def randomize_block(self, min_row, max_row, stats, density=0):
+ """Randomize basis between from ``min_row`` and ``max_row`` (exclusive)
+
+ 1. permute rows
+
+ 2. apply lower triangular matrix with coefficients in -1,0,1
+
+ 3. LLL reduce result
+
+ :param min_row: start in this row
+ :param max_row: stop at this row (exclusive)
+ :param stats: object for maintaining statistics
+ :param density: number of non-zero coefficients in lower triangular transformation matrix
... 8382 lines suppressed ...
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/python-modules/packages/fpylll.git
More information about the Python-modules-commits
mailing list