Exemplo n.º 1
0
def sample_matrix(d, lattice_type="qary", seed=None):
    """
    Sample a matrix in dimension `d`.

    :param d: lattice dimension
    :param lattice_type: see module level documentation
    :param seed: optional random seed
    :returns: LLL-reduced integer matrix

    .. note :: This function seeds the FPLLL RNG, i.e. it is deterministic.

    """

    if seed is None:
        FPLLL.set_random_seed(d)
    else:
        FPLLL.set_random_seed(seed)

    if lattice_type == "qary":
        A = IntegerMatrix.random(d, "qary", bits=30, k=d // 2, int_type="long")
    elif lattice_type == "qary-lv":
        A = IntegerMatrix.random(d, "qary", bits=10 * d, k=d // 2)
    else:
        raise ValueError("Lattice type '%s' not supported." % lattice_type)

    A = LLL.reduction(A)
    return A
Exemplo n.º 2
0
def svp_time(seed, params, return_queue=None):
    """Run SVP reduction of AutoBKZ on ``A`` using ``params``.

    :param A: a matrix
    :param params: AutoBKZ parameters
    :param queue: if not ``None``, the result is put on this queue.

    """
    FPLLL.set_random_seed(seed)
    FPLLL.set_threads(params["threads"])
    q = 33554393
    k = params.block_size // 2
    A = IntegerMatrix.random(params.block_size,
                             "qary",
                             q=q,
                             k=k,
                             int_type="long")

    M = GSO.Mat(A)
    bkz = BKZ2(M)
    tracer = BKZTreeTracer(bkz, start_clocks=True)

    with tracer.context(("tour", 0)):
        bkz.svp_reduction(0, params.block_size, params, tracer)
        bkz.M.update_gso()

    tracer.exit()

    log_delta = (log(A[0].norm()) - log(q) *
                 (k / float(params.block_size))) / float(params.block_size)
    tracer.trace.data["delta"] = exp(log_delta)
    if return_queue:
        return_queue.put(tracer.trace)
    else:
        return tracer.trace
Exemplo n.º 3
0
def worker_process(seed, params, queue=None):
    """
    This function is called to collect statistics.

    :param A: basis
    :param params: BKZ parameters
    :param queue: queue used for communication

    """
    FPLLL.set_random_seed(seed)
    A = IntegerMatrix.random(params.block_size,
                             "qary",
                             bits=30,
                             k=params.block_size // 2,
                             int_type="long")

    M = GSO.Mat(A)
    bkz = CallbackBKZ(M)  # suppresses initial LLL call
    tracer = BKZTreeTracer(bkz, start_clocks=True)

    with tracer.context(("tour", 0)):
        bkz.svp_reduction(0, params.block_size, params, tracer)
        M.update_gso()

    tracer.exit()
    try:
        # close connection
        params.strategies[params.block_size].connection.send(None)
    except AttributeError:
        pass
    if queue:
        queue.put(tracer.trace)
    else:
        return tracer.trace
Exemplo n.º 4
0
def worker_process(seed, params, queue=None):
    """
    This function is called to collect statistics.

    :param A: basis
    :param params: BKZ parameters
    :param queue: queue used for communication

    """
    FPLLL.set_random_seed(seed)
    A = IntegerMatrix.random(params.block_size, "qary", bits=30, k=params.block_size//2, int_type="long")

    M = GSO.Mat(A)
    bkz = CallbackBKZ(M)  # suppresses initial LLL call
    tracer = BKZTreeTracer(bkz, start_clocks=True)

    with tracer.context(("tour", 0)):
        bkz.svp_reduction(0, params.block_size, params, tracer)
        M.update_gso()

    tracer.exit()
    try:
        # close connection
        params.strategies[params.block_size].connection.send(None)
    except AttributeError:
        pass
    if queue:
        queue.put(tracer.trace)
    else:
        return tracer.trace
Exemplo n.º 5
0
def main(n=150,
         block_size=60,
         float_type="d",
         logq=40,
         verbose=False,
         seed=0xdeadbeef):
    print "= n: %3d, β: %2d, bits: %3d, float_type: %s, seed: 0x%08x =" % (
        n, block_size, logq, float_type, seed)
    print
    set_random_seed(seed)
    A = IntegerMatrix.random(n, "qary", k=n // 2, bits=logq)
    A = LLL.reduction(A)

    params = BKZ.Param(block_size=block_size,
                       max_loops=4,
                       strategies=BKZ.DEFAULT_STRATEGY,
                       flags=BKZ.MAX_LOOPS | BKZ.VERBOSE)
    bkz = BKZReduction(GSO.Mat(copy.copy(A), float_type=float_type))
    bkz(params)

    print bkz.trace

    bkz2 = BKZ2(GSO.Mat(copy.copy(A), float_type=float_type))
    bkz2(params)

    print bkz2.trace

    if verbose:
        print
        print bkz.trace.report()
Exemplo n.º 6
0
def test_callback_enum(d=40):

    FPLLL.set_random_seed(0x1337)
    A = LLL.reduction(IntegerMatrix.random(100, "qary", k=50, q=7681))
    M = GSO.Mat(A)
    M.update_gso()

    # we are not imposing a constraint
    enum_obj = Enumeration(M)
    solutions = enum_obj.enumerate(0, d, 0.99*M.get_r(0, 0), 0)
    max_dist, sol = solutions[0]
    assert(A.multiply_left(sol)[0] != 2)

    # now we do
    def callback(new_sol_coord):
        if A.multiply_left(new_sol_coord)[0] == 2:
            return True
        else:
            return False

    enum_obj = Enumeration(M, callbackf=callback)
    solutions = enum_obj.enumerate(0, d, 0.99*M.get_r(0, 0), 0)
    max_dist, sol = solutions[0]

    assert(A.multiply_left(sol)[0] == 2)
Exemplo n.º 7
0
def svp_time(seed, params, return_queue=None):
    """Run SVP reduction of AutoBKZ on ``A`` using ``params``.

    :param A: a matrix
    :param params: AutoBKZ parameters
    :param queue: if not ``None``, the result is put on this queue.

    """
    FPLLL.set_random_seed(seed)
    A = IntegerMatrix.random(params.block_size, "qary", bits=30,
                             k=params.block_size//2, int_type="long")

    M = GSO.Mat(A)
    bkz = BKZ2(M)
    tracer = BKZTreeTracer(bkz, start_clocks=True)

    with tracer.context(("tour", 0)):
        bkz.svp_reduction(0, params.block_size, params, tracer)
        bkz.M.update_gso()

    tracer.exit()

    tracer.trace.data["|A_0|"] = A[0].norm()

    if return_queue:
        return_queue.put(tracer.trace)
    else:
        return tracer.trace
Exemplo n.º 8
0
def compare_bkz(classes,
                matrixf,
                dimensions,
                block_sizes,
                progressive_step_size,
                seed,
                threads=2,
                samples=2,
                tours=1,
                pickle_jar=None,
                logger="compare"):
    """
    Compare BKZ-style lattice reduction.

    :param classes: a list of BKZ classes to test.  See caveat above.
    :param matrixf: A function to create matrices for a given dimension and block size
    :param dimensions: a list of dimensions to test
    :param block_sizes: a list of block sizes to test
    :param progressive_step_size: step size for the progressive strategy; ``None`` to disable it
    :param seed: A random seed, each matrix will be created with seed increased by one
    :param threads: number of threads to use
    :param samples: number of reductions to perform
    :param tours: number of BKZ tours to run
    :param log_filename: log to this file if not ``None``

    """

    jobs = []

    for dimension in dimensions:

        jobs.append((dimension, []))

        for block_size in block_sizes:
            if dimension < block_size:
                continue

            seed_ = seed
            jobs_ = []

            matrixf_ = matrixf(dimension=dimension, block_size=block_size)

            for i in range(samples):
                FPLLL.set_random_seed(seed_)
                A = IntegerMatrix.random(dimension, **matrixf_)

                for BKZ_ in classes:
                    args = (BKZ_, A, block_size, tours, progressive_step_size)
                    jobs_.append(((BKZ_.__name__, seed_), args))
                seed_ += 1

            jobs[-1][1].append((block_size, jobs_))

    conductor = Conductor(threads=threads,
                          pickle_jar=pickle_jar,
                          logger=logger)
    return conductor(jobs)
Exemplo n.º 9
0
def test_linear_pruning():
    A = IntegerMatrix.random(25, "qary", k=15, q=127)
    block_size = 10
    preprocessing = 3
    strategies = [Strategy(i) for i in range(5)]

    for b in range(5, block_size + 1):
        strategies.append(
            Strategy(b, [preprocessing], [Pruning.LinearPruning(b, 2)]))

    param = BKZ.Param(block_size=block_size, strategies=strategies)
    BKZ.reduction(A, param)
Exemplo n.º 10
0
def load_prebkz(n, s=0, blocksize=40):
    """
    """

    filename = "qarychallenge/prebkz-%02d-dim-%03d-seed-%02d.txt" % (blocksize,
                                                                     n, s)

    if not os.path.isdir("qarychallenge"):
        os.mkdir("qarychallenge")

    if os.path.isfile(filename) is False:
        set_random_seed(s)
        A = IntegerMatrix.random(n, "qary", q=2**30, k=n // 2)
        print "Did not find '{filename}'. Creating and reducing".format(
            filename=filename)
        print "created, ",
        sys.stdout.flush()
        A = LLL.reduction(A)
        print "LLLed, ",
        sys.stdout.flush()

        if A.nrows >= 160:
            float_type = "long double"
        elif A.nrows >= 200:
            float_type = "dd"
        else:
            float_type = "double"

        M = GSO.Mat(A, float_type=float_type, flags=GSO.ROW_EXPO)

        bkz = BKZReduction(M)

        for b in range(10, blocksize + 1):
            print "\r created, LLLed, BKZed %d" % b,
            sys.stdout.flush()

            par = fplll_bkz.Param(b,
                                  strategies=fplll_bkz.DEFAULT_STRATEGY,
                                  max_loops=1,
                                  flags=fplll_bkz.MAX_LOOPS)
            bkz(par)

        print

        fn = open(filename, "w")
        fn.write(str(A))
        fn.close()

    return load_matrix_file(filename, randomize=False)
Exemplo n.º 11
0
def test_bkz_postprocessing():
    A = IntegerMatrix.random(20, "qary", bits=20, k=10, int_type="long")
    LLL.reduction(A)

    bkz = BKZ(A)
    bkz.M.update_gso()
    tracer = BKZTreeTracer(bkz)

    solution = (2, 2, 0, 3, 4, 5, 7)

    v = A.multiply_left(solution, 3)
    bkz.svp_postprocessing(3, len(solution), solution, tracer)
    w = tuple(A[3])
    assert v == w

    solution = (2, 1, 0, 3, 4, 5, 7)

    v = A.multiply_left(solution, 3)
    bkz.svp_postprocessing(3, len(solution), solution, tracer)
    w = tuple(A[3])
    assert v == w
Exemplo n.º 12
0
def gso_workerf(args):
    import copy

    d, q, seed, params, procrastinating, what = args

    dummy = [1.0] * d

    if procrastinating:
        from impl import BKZReduction
        from simu import ProcrastinatingBKZSimulation as BKZSimulation
        from simu import (
            ProcrastinatingBKZQualitySimulation as BKZQualitySimulation, )
    else:
        from fpylll.algorithms.bkz2 import BKZReduction
        from simu import BKZSimulation
        from simu import BKZQualitySimulation

    FPLLL.set_random_seed(seed)
    A = LLL.reduction(IntegerMatrix.random(d, "qary", k=d // 2, q=q))

    if "qs" in what:
        qsimu_r = BKZQualitySimulation(copy.copy(A))(params)
    else:
        qsimu_r = dummy

    if "fs" in what:
        fsimu_r = BKZSimulation(copy.copy(A))(params)
    else:
        fsimu_r = dummy

    if "r" in what:
        BKZReduction(A)(params)
        M = GSO.Mat(A)
        M.update_gso()
        real_r = M.r()
    else:
        real_r = dummy

    return qsimu_r, fsimu_r, real_r
Exemplo n.º 13
0
Arquivo: gen_ntru.py Projeto: obqq/g6k
def gen_lwe_challenge(n, q):
    '''
	Uses sage to generate
	'''
    Amat = IntegerMatrix.random(n, "uniform", bits=floor(log(q, 2)))
    A = matrix(ZZ, [Amat[i] for i in range(Amat.nrows)])
    w = int(n / 3.)
    s = vector(ZZ, gen_small(w, n))

    e = vector(ZZ, gen_small(w, n))
    b = s * A + e
    b = vector([b[i] % q for i in range(n)])

    file_path = os.path.join(LWE_BASEDIR, 'lwe_n_' + str(n) + '.txt')

    f = open(file_path, 'w')
    f.write(str(q) + '\n')
    for i in range(A.nrows()):
        f.write(str(A[i]).replace(',', '') + '\n')
    f.write(str(b).replace(',', '') + '\n')
    f.write(str(s).replace(',', '') + '\n')
    f.write(str(e).replace(',', '') + '\n')
    f.close()
Exemplo n.º 14
0
def run_timing_test(n,
                    block_size=60,
                    bits=30,
                    ncores=8,
                    min_success_probability=0.5,
                    max_loops=4):
    A = IntegerMatrix.random(n, "qary", k=n // 2, bits=bits)
    default_strategies = load_strategies_json(BKZ.DEFAULT_STRATEGY)

    param = BKZ.Param(block_size,
                      strategies=default_strategies,
                      min_success_probability=min_success_probability,
                      max_loops=max_loops,
                      flags=BKZ.VERBOSE | BKZ.MAX_LOOPS)

    random.seed(1)
    bkz = ParallelBKZ(copy(A), ncores=ncores)
    t = time.time()
    bkz(param)
    t = time.time() - t
    trace_p = bkz.trace
    print "Parallel(%d): %.2fs" % (ncores, t)

    random.seed(1)
    param = BKZ.Param(block_size,
                      strategies=default_strategies,
                      min_success_probability=min_success_probability,
                      max_loops=max_loops,
                      flags=BKZ.VERBOSE | BKZ.MAX_LOOPS)
    t = time.time()
    bkz = BKZ2(copy(A))
    bkz(param)
    trace_s = bkz.trace

    t = time.time() - t
    print "  Sequential: %.2fs" % (t, )
    return trace_p, trace_s
Exemplo n.º 15
0
def make_integer_matrix(n):
    A = IntegerMatrix.random(n, "ntrulike", bits=30)
    return A
Exemplo n.º 16
0
def make_integer_matrix(n):
    A = IntegerMatrix.random(n, "ntrulike", bits=30)
    return A
Exemplo n.º 17
0
def prepare(n, m):
    A = [IntegerMatrix.random(n, "qary", bits=n, k=n) for _ in range(m)]
    M = [GSO.Mat(a) for a in A]
    L = [LLL.Reduction(m) for m in M]
    [l() for l in L]
    return M
Exemplo n.º 18
0
from random import randint
from math import log, sqrt, floor
from time import time
from fpylll import BKZ, LLL, GSO, IntegerMatrix, Enumeration, EnumerationError
from fpylll.algorithms.bkz import BKZReduction as BKZ1
from fpylll.tools.bkz_stats import BKZTreeTracer, dummy_tracer
from fpylll.algorithms.bkz2 import BKZReduction as BKZ2
from fpylll.util import gaussian_heuristic
from fpylll.fplll.pruner import prune
from fpylll.fplll.pruner import Pruning

preproc_cost = 2**40
NPS = 60 * [2.**29] + 5 * [2.**27] + 5 * [2.**26] + 1000 * [2.**25]
block_size = 60

A = IntegerMatrix.random(60, "intrel", bits=600)
_ = LLL.reduction(A)
M = GSO.Mat(A)
_ = M.update_gso()
pr = Pruning.Pruner(M.get_r(0, 0) * 0.99,
                    NPS[block_size] * preproc_cost, [M.r()],
                    0.0099,
                    flags=0)
c = pr.optimize_coefficients([1. for _ in range(M.d)])
cost, details = pr.single_enum_cost(c, True)
print cost, details

kappa = 0
print "start"
print "kappa: ", kappa
NPS = 60 * [2.**29] + 5 * [2.**27] + 5 * [2.**26] + 1000 * [2.**25]
Exemplo n.º 19
0
    def __call__(self, seed, threads=2, samples=2, tours=1):
        """

        :param seed: A random seed, each matrix will be created with seed increased by one
        :param threads: number of threads to use
        :param samples: number of reductions to perform
        :param tours: number of BKZ tours to run

        """

        logger = logging.getLogger("compare")

        results = OrderedDict()

        fmtstring = "  %%%ds" % max(
            [len(BKZ_.__name__) for BKZ_ in self.classes])

        for dimension in self.dimensions:
            results[dimension] = OrderedDict()

            for block_size in self.block_sizes:

                seed_ = seed

                if dimension < block_size:
                    continue

                L = OrderedDict([(BKZ_.__name__, OrderedDict())
                                 for BKZ_ in self.classes])

                logger.info("dimension: %3d, block_size: %2d" %
                            (dimension, block_size))

                tasks = []

                matrixf = self.matrixf(dimension=dimension,
                                       block_size=block_size)

                for i in range(samples):
                    set_random_seed(seed_)
                    A = IntegerMatrix.random(dimension, **matrixf)

                    for BKZ_ in self.classes:
                        args = (BKZ_, A, block_size, tours,
                                self.progressive_step_size)
                        tasks.append(((seed_, BKZ_), args))

                    seed_ += 1

                if threads > 1:
                    pool = Pool(processes=threads)
                    tasks = dict([(key, pool.apply_async(bkz_call, args_))
                                  for key, args_ in tasks])
                    pool.close()

                    while tasks:
                        ready = [key for key in tasks if tasks[key].ready()]
                        for key in ready:
                            seed_, BKZ_ = key
                            try:
                                trace_ = tasks[key].get()
                                L[BKZ_.__name__][seed_] = trace_
                                logger.debug(fmtstring % (BKZ_.__name__) +
                                             " 0x%08x %s" %
                                             (seed_, pretty_dict(trace_.data)))
                            except ReductionError:
                                logger.debug(
                                    "ReductionError in %s with seed 0x%08x" %
                                    (BKZ_.__name__, seed_))
                            del tasks[key]

                        time.sleep(1)
                else:
                    for key, args_ in tasks:
                        seed_, BKZ_ = key
                        try:
                            trace_ = apply(bkz_call, args_)
                            L[BKZ_.__name__][seed_] = trace_
                            logger.debug(fmtstring % (BKZ_.__name__) +
                                         " 0x%08x %s" %
                                         (seed_, pretty_dict(trace_.data)))
                        except ReductionError:
                            logger.debug(
                                "ReductionError in %s with seed 0x%08x" %
                                (BKZ_.__name__, seed_))

                logger.debug("")
                for name, vals in L.items():
                    if vals:
                        vals = OrderedDict(
                            zip(
                                vals.items()[0][1].data,
                                zip(*
                                    [d[1].data.values()
                                     for d in vals.items()])))
                        vals = OrderedDict((k, float(sum(v)) / len(v))
                                           for k, v in vals.items())
                        logger.info(fmtstring % (name) + "    average %s" %
                                    (pretty_dict(vals)))

                logger.info("")
                results[dimension][block_size] = L

                self.write_log(results)

        return results
from sage.all import log, exp
from sage.all import line, save, load, identity_matrix, matrix
from fpylll import IntegerMatrix, GSO, LLL, FPLLL, BKZ
from fpylll.tools.bkz_simulator import simulate as CN11_simulate
import BSW18
import og

# n_halfs, block_size, max_loops = 50, 45, 2000
n_halfs, block_size, max_loops = 90, 170, 60
# n_halfs, block_size, max_loops = 75, 60, 50
# n_halfs, block_size, max_loops = 75, 60, 20000

# generate lattice instance
FPLLL.set_random_seed(1337)
q = 2**30
mat = IntegerMatrix.random(2 * n_halfs, "qary", q=q, k=n_halfs)
A = LLL.reduction(mat)
M = GSO.Mat(A)
M.update_gso()

cn11 = CN11_simulate(M, BKZ.Param(block_size=block_size, max_loops=max_loops))
bsw18 = BSW18.simulate(M, BKZ.Param(block_size=block_size,
                                    max_loops=max_loops))
og = og.simulate(M, BKZ.Param(block_size=block_size, max_loops=max_loops))
g = line([(i, log(cn11[0][i])/2 - log(q)/2) for i in range(len(cn11[0]))]) \
    + line([(i, log(bsw18[0][i])/2 - log(q)/2) for i in range(len(bsw18[0]))], color='red', thickness=2) \
    + line([(i, log(og[0][i])/2 - log(q)/2) for i in range(len(og[0]))], color='green')
save(g, "test.png", dpi=150)

log_vol_cn11 = sum(map(lambda x: log(x) / 2, cn11[0]))
log_vol_bsw18 = sum(map(lambda x: log(x) / 2, bsw18[0]))
Exemplo n.º 21
0
def prepare(n):
    A = IntegerMatrix.random(n, "qary", bits=n/2, k=n/2)
    M = GSO.Mat(A)
    L = LLL.Reduction(M)
    L()
    return M
Exemplo n.º 22
0
    def __call__(self, b, tours=8):
        self.M.discover_all_rows()

        for i in range(tours):
            print
            with self.tracer.context("tour", i):
                self.tour(b)
            print "proba %.4f" % self.tuners[b].proba,
            i += 1
            # best = max(self.tuners[b].data, key=self.tuners[b].data.get)
            for x in sorted(self.tuners[b].data.keys()):
                try:
                    print x, "\t %d \t %.2f " % (self.tuners[b].counts[x],
                                                 self.tuners[b].data[x])
                except:
                    pass
            print

        # self.tracer.exit()


n = 160
b = 40
A = IntegerMatrix.random(n, "qary", k=n // 2, bits=30)
yBKZ = YoloBKZ(A)

t = time()
yBKZ(b)
t = time() - t
print "  time: %.2fs" % (t, )
Exemplo n.º 23
0
#   but WITHOUT ANY WARRANTY; without even the implied warranty of
#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
#   GNU General Public License for more details.
#
#   You should have received a copy of the GNU General Public License
#   along with G6K. If not, see <http://www.gnu.org/licenses/>.
#
####



from fpylll import IntegerMatrix
try:
    from g6k import Siever
except ImportError:
    raise ImportError("g6k not installed. Please run './setup.py install' from ../")
from simple_pump import pump


n = 80

A = IntegerMatrix.random(n, "qary", k=40, bits=20)
g6k = Siever(A)
print("Squared length of the 5 first GS vectors")

# Do a Workout (pumps of increasing effort), and printout basis shape at each step.
for dim4free in range(50, 15, -1):
    pump(g6k, 0, n, dim4free)
    print("dims4free: %d/%d \t %.3e\t%.3e\t%.3e\t%.3e\t%.3e\t"  %   
          tuple([dim4free, n]+[g6k.M.get_r(i, i) for i in range(5)]))
Exemplo n.º 24
0
def make_integer_matrix(n):
    A = IntegerMatrix.random(n, "uniform", bits=30)
    return A
Exemplo n.º 25
0
def prepare(n):
    A = IntegerMatrix.random(n, "qary", bits=n / 2, k=n / 2)
    M = GSO.Mat(A)
    L = LLL.Reduction(M)
    L()
    return M
Exemplo n.º 26
0
def make_integer_matrix(n):
    A = IntegerMatrix.random(n, "qary", k=n // 2, bits=30)
    return A
Exemplo n.º 27
0
# This file was *autogenerated* from the file my_pruner.sage
from sage.all_cmdline import *   # import sage library

_sage_const_2 = Integer(2); _sage_const_0 = Integer(0); _sage_const_60 = Integer(60); _sage_const_600 = Integer(600); _sage_const_0p51 = RealNumber('0.51'); _sage_const_1p = RealNumber('1.')
from fpylll import IntegerMatrix, GSO, LLL, Pruning, FPLLL

A = IntegerMatrix.random(_sage_const_60 , "intrel", bits=_sage_const_600 )
_ = LLL.reduction(A)
M = GSO.Mat(A)
_ = M.update_gso()
pr = Pruning.Pruner(M.get_r(_sage_const_0 ,_sage_const_0 ), _sage_const_2 **_sage_const_60 , [M.r()], _sage_const_0p51 )
c = pr.optimize_coefficients([_sage_const_1p  for _ in range(M.d)])
cost, details = pr.single_enum_cost(c, True)
cost

Exemplo n.º 28
0
def make_integer_matrix(n):
    A = IntegerMatrix.random(n, "uniform", bits=30)
    return A
Exemplo n.º 29
0
from fpylll import IntegerMatrix, LLL
from multiprocessing import Pool

d, workers, tasks = 100, 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=300) for _ in range(tasks)]
A = run_it(Pool(workers), LLL.reduction, A)