def plain_sieve_kernel(arg0, params=None, seed=None): # Pool.map only supports a single parameter if params is None and seed is None: n, params, seed = arg0 else: n = arg0 alg = params.pop("alg") reserved_n = n params = params.new(reserved_n=reserved_n, otf_lift=False) A, _ = load_svpchallenge_and_randomize(n, s=0, seed=seed) g6k = Siever(A, params, seed=seed) tracer = SieveTreeTracer(g6k, root_label=("plain-sieve", n), start_clocks=True) g6k.initialize_local(0, 0, n) g6k(alg=alg, tracer=tracer) tracer.exit() return tracer.trace
def run(self): self.thread_name = current_thread().name if self.thread_name == "MainThread": self.thread_name = " " self.thread_start = time.time() self.tried = set() dim = self.params["dimension"] if self.params["bounds"]["type"] in ("known", "knownre"): sigs = self.signatures self.signatures = [] blens = [] for sig in sigs: blen = int(self.recompute_nonce(sig)).bit_length() i = bisect(blens, blen) if i < dim: blens.insert(i, blen) self.signatures.insert(i, sig) if len(blens) > dim: blens.pop() self.signatures.pop() pairs = [(sig.t, sig.u) for sig in self.signatures[:dim]] nonces = [] for sig in self.signatures[:dim]: nonces.append(int(self.recompute_nonce(sig))) real_bitlens = [nonce.bit_length() for nonce in nonces] real_infos = [ self.curve.group.n.bit_length() - bitlen for bitlen in real_bitlens ] real_info = sum(real_infos) if self.params["bounds"]["type"] == "constant": value = self.const_bound_func(self.params["bounds"]) self.bounds = [value for _ in range(dim)] elif self.params["bounds"]["type"] == "geom": self.bounds = [ self.geom_bound_func(i, dim, self.params["bounds"]) for i in range(dim) ] elif self.params["bounds"]["type"] == "geomN": self.bounds = [ self.geomN_bound_func(i, self.params["attack"]["num"], self.params["bounds"]) for i in range(dim) ] elif self.params["bounds"]["type"] == "known" or self.params["bounds"][ "type"] == "knownre": self.bounds = [self.known_bound_func(i, dim) for i in range(dim)] elif self.params["bounds"]["type"] == "template": self.bounds = [0 for _ in range(dim)] templates = copy(self.params["bounds"]) del templates["type"] for k, v in templates.items(): for i in range(*v): self.bounds[i] = self.curve.group.n.bit_length() - int(k) bnds = [self.bounds[i] for i in range(dim)] info = sum(bnds) overhead = info / self.curve.bit_size() self.log( "Building lattice with {} bits of information (overhead {:.2f}).". format(info, overhead)) liars = 0 bad_info = 0 good_info = 0 liarpos = [] for i, real, our in zip(range(dim), real_infos, bnds): if real < our: liars += 1 bad_info += real liarpos.append(str(i) + "@" + str(our - real)) else: good_info += real self.log("Real info: {}".format(real_info)) self.log("Liars: {}".format(liars)) self.log("Good info: {}".format(good_info)) self.log("Bad info: {}".format(bad_info)) self.log("Liar positions: {}".format(";".join(liarpos))) self.svp = self.params["attack"]["method"] == "svp" self.sieve = self.params["attack"]["method"] == "sieve" self.np = self.params["attack"]["method"] == "np" self.round = self.params["attack"]["method"] == "round" if self.svp or self.sieve: lattice = self.build_svp_lattice(pairs, dim, self.params["bounds"]) elif self.np or self.round: lattice = self.build_cvp_lattice(pairs, dim, self.params["bounds"]) target = self.build_target(pairs, dim, self.params["bounds"]) else: self.log("Bad method: {}".format(self.params["attack"]["method"])) return if self.sieve: self.reduce_lattice(lattice, None) g6k = Siever(lattice) self.log("Start SIEVE.") g6k.initialize_local(0, 0, dim) try: g6k() except SaturationError as e: pass short = self.verify_sieve(lattice, g6k.best_lifts()) if short is not None: i, res = short self.log("Result row: {}".format(i)) norm = self.norm(res) self.log("Result normdist: {}".format(norm)) return reds = [None] + self.params["betas"] for beta in reds: lattice = self.reduce_lattice(lattice, beta) gso = GSO.Mat(lattice) gso.update_gso() if self.svp: short = self.verify_shortest(lattice, self.pubkey) if short is not None: i, res = short self.log("Result row: {}".format(i)) norm = self.norm(res) self.log("Result normdist: {}".format(norm)) break if self.round: closest = self.babai_round(lattice, target) if self.verify_closest(closest, self.pubkey): dist = self.dist(closest, target) self.log("Result normdist: {}".format(dist)) break if self.np: closest = self.babai_np(lattice, gso, target) if self.verify_closest(closest, self.pubkey) is not None: dist = self.dist(closest, target) self.log("Result normdist: {}".format(dist)) break