Example #1
0
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
Example #2
0
    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