def usvp_pred_solve(A, predicate, squared_target_norm, invalidate_cache=lambda: None, solver=None, **kwds): """ Solve uSVP with predicate. Given a USVP instance ``A`` with ``predicate`` and a target of ``squared_target_norm`` solve this intance using ``solver``. :param A: An ``IntegerMatrix`` or a ``MatGSO`` object :param predicate: a predicate (this will inject ``M`` into its global namespace) :param squared_target_norm: the squared norm of the target :param invalidate_cache: a callable to invalidate caches for the predicate. :param solver: uSVP with predicate solver to use. """ from g6k import Siever try: solver = solvers[solver] except KeyError: pass try: A.update_gso() M = A except AttributeError: M = Siever.MatGSO(A) M.update_gso() predicate.__globals__["M"] = M if solver is None: cost, block_size = usvp_pred_bkz_enum_solve.estimate( M, squared_target_norm) if cost: # HACK if block_size >= 70: solver_name = "bkz-sieve" else: solver_name = "bkz-enum" else: gh = gaussian_heuristic(M.r()) if M.d < 40 or squared_target_norm / gh > 4 / 3.0: solver_name = "enum_pred" else: solver_name = "sieve_pred" solver = solvers[solver_name] logging.debug( "% solving with {solver_name}".format(solver_name=solver_name)) aux_kwds = kwds kwds = solver.parametersf(M, squared_target_norm) kwds.update(aux_kwds) logging.debug("% solving with {kwds}".format(kwds=kwds)) return solver(M, predicate, invalidate_cache=invalidate_cache, **kwds)
def svp_g6k(G): """ Returns the shortest vector of the lattice spanned by the rows of G. """ g6k = Siever(G) pump(g6k, dummy_tracer, 0, G.nrows, 0) return G[0]
def __call__(cls, M, predicate, block_size, invalidate_cache=lambda: None, threads=1, max_loops=8, **kwds): params = SieverParams(threads=threads) g6k = Siever(M, params) tracer = SieveTreeTracer(g6k, root_label="bkz-sieve", start_clocks=True) for b in range(20, block_size + 1, 10): pump_n_jump_bkz_tour(g6k, tracer, b, pump_params={"down_sieve": True}) auto_abort = BKZ.AutoAbort(M, M.d) found, ntests, solution = False, 0, None for tour in range(max_loops): pump_n_jump_bkz_tour(g6k, tracer, block_size, pump_params={"down_sieve": True}) invalidate_cache() if auto_abort.test_abort(): break with tracer.context("check"): for i, v in enumerate(M.B): ntests += 1 if predicate(v, standard_basis=True): solution = tuple([int(v_) for v_ in v]) found = True break if found: break tracer.exit() b0, b0e = M.get_r_exp(0, 0) return USVPPredSolverResults( success=found, ntests=ntests, solution=solution, b0=b0**(0.5) * 2**(b0e / 2.0), cputime=tracer.trace.data["cputime"], walltime=tracer.trace.data["walltime"], data=tracer.trace, )
def __call__(self, B, params=None): return Siever(B, params=params)
# 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)]))
from fpylll import IntegerMatrix from fpylll.util import gaussian_heuristic try: from g6k import Siever except ImportError: raise ImportError( "g6k not installed. Please run './setup.py install' from ../") from simple_pump import pump # Set up the instance n = 30 A = IntegerMatrix.random(n, "qary", k=n / 2, bits=8) g6k = Siever(A) g6k.lll(0, n) # Run a progressive sieve, to get an initial database saturating the 4/3 *gh^2 ball. # This makes the final computation saturating a larger ball faster than directly # running such a large sieve. # # G6K will use a database of size db_size_base * db_size_base^dim with default values # db_size_base = sqrt(4./3) and db_size_factor = 3.2 # # The sieve stops when a # 0.5 * saturation_ratio * saturation_radius^(dim/2) # # distinct vectors (modulo negation) of length less than saturation_radius have # been found
def __call__(cls, M, predicate, invalidate_cache=lambda: None, preproc_offset=20, threads=1, ph=0, **kwds): # TODO bkz_sieve would be neater here if preproc_offset and M.d >= 40: bkz_res = usvp_pred_bkz_enum_solve( M, predicate, block_size=max(M.d - preproc_offset, 2), max_loops=8, threads=threads, invalidate_cache=invalidate_cache, ) ntests = bkz_res.ntests if bkz_res.success: # this might be enough return bkz_res else: bkz_res = None ntests = 0 from fpylll import IntegerMatrix # reduce size of entries B = IntegerMatrix(M.B.nrows, M.B.ncols) for i in range(M.B.nrows): for j in range(M.B.ncols): B[i, j] = M.B[i, j] // 2**ph params = SieverParams(reserved_n=M.d, otf_lift=False, threads=threads) g6k = Siever(B, params) tracer = SieveTreeTracer(g6k, root_label="sieve", start_clocks=True) g6k.initialize_local(0, M.d // 2, M.d) while g6k.l: g6k.extend_left() with tracer.context("sieve"): try: g6k() except SaturationError: pass # fill the database with g6k.temp_params(**kwds): g6k() invalidate_cache() found, solution = False, None with tracer.context("check"): for v in g6k.itervalues(): # heuristic: v has very small entries ntests += 1 if predicate(v, standard_basis=False): found = True solution = tuple( [int(v_) for v_ in g6k.M.B.multiply_left(v)]) break tracer.exit() cputime = tracer.trace.data[ "cputime"] + bkz_res.cputime if bkz_res else 0 walltime = tracer.trace.data[ "walltime"] + bkz_res.walltime if bkz_res else 0 b0, b0e = M.get_r_exp(0, 0) return USVPPredSolverResults( success=found, ntests=ntests, solution=solution, b0=b0**(0.5) * 2**(b0e / 2.0), cputime=cputime, walltime=walltime, data=tracer.trace, )
def __call__(cls, M, predicate, invalidate_cache=lambda: None, preproc_offset=20, threads=1, **kwds): if preproc_offset and M.d >= 40: bkz_res = usvp_pred_bkz_sieve_solve( M, predicate, block_size=max(M.d - preproc_offset, 2), max_loops=8, threads=threads, invalidate_cache=invalidate_cache, ) ntests = bkz_res.ntests if bkz_res.success: # this might be enough return bkz_res else: bkz_res = None ntests = 0 params = SieverParams(reserved_n=M.d, otf_lift=False, threads=threads) g6k = Siever(M, params) tracer = SieveTreeTracer(g6k, root_label="sieve", start_clocks=True) workout(g6k, tracer, 0, M.d, dim4free_min=0, dim4free_dec=15) invalidate_cache() found, solution = False, None with tracer.context("check"): # check if the workout solved it for us for i in range(g6k.M.d): ntests += 1 if predicate(g6k.M.B[i], standard_basis=True): found = True solution = tuple([int(v_) for v_ in g6k.M.B[i]]) break if found: tracer.exit() b0, b0e = M.get_r_exp(0, 0) return USVPPredSolverResults( success=found, ntests=ntests, solution=solution, b0=b0**(0.5) * 2**(b0e / 2.0), cputime=tracer.trace.data["cputime"], walltime=tracer.trace.data["walltime"], data=tracer.trace, ) with tracer.context("sieve"): try: g6k() except SaturationError: pass while g6k.l: g6k.extend_left() with tracer.context("sieve"): try: g6k() except SaturationError: pass # fill the database with g6k.temp_params(**kwds): g6k() invalidate_cache() with tracer.context("check"): for i in range(g6k.M.d): ntests += 1 if predicate(g6k.M.B[i], standard_basis=True): found = True solution = tuple([int(v_) for v_ in g6k.M.B[i]]) break if not found: for v in g6k.itervalues(): ntests += 1 if predicate(v, standard_basis=False): found = True solution = tuple( [int(v_) for v_ in g6k.M.B.multiply_left(v)]) break tracer.exit() cputime = tracer.trace.data[ "cputime"] + bkz_res.cputime if bkz_res else 0 walltime = tracer.trace.data[ "walltime"] + bkz_res.walltime if bkz_res else 0 b0, b0e = M.get_r_exp(0, 0) return USVPPredSolverResults( success=found, ntests=ntests, solution=solution, b0=b0**(0.5) * 2**(b0e / 2.0), cputime=cputime, walltime=walltime, data=tracer.trace, )
# k = 128 ## n = 42 -> 7.10958185672e+37 ## n = 48 -> 9.40694696471e+37 ## n = 54 -> 1.23309364376e+38 ## n = 60 -> 1.48734754252e+38 ## n = if __name__ == '__main__': show_targets(0) #min_m_CVP(0) n = 64 G = getG(n, 2**128) print(sum([norm(x) for x in G])/n) #baseline = norm(G[0]) g6k = Siever(G) #print("baseline = {}".format(baseline)) for i in range(64): pump(g6k, dummy_tracer, 0, n, 0) print([norm(x) for x in G[0:8]]) #print(G[0]) #shortest = G[0] #print("pump result = {}".format(norm(shortest))) #for i, sqnorm, coeffs in g6k.best_lifts(): # v = G.multiply_left(coeffs) # if norm(v) < baseline: # baseline = norm(v) # print("**** new best from best_lifts ***** --> {}".format(baseline)) # for coeffs in g6k.itervalues():