from Crypto.Util.number import * from sage.allimport * from re import findall from subprocess import check_output, CalledProcessError import subprocess import time n = ... c = ... p_lb = ... PR = PolynomialRing(Zmod(n), "x") x = PR.gen() f = x*2**256 + p_lb f = f.monic() count = 0
defflatter(M): global count # compile https://github.com/keeganryan/flatter and put it in $PATH z = "[[" + "]\n[".join(" ".join(map(str, row)) for row in M) + "]]" ret = check_output(["flatter"], input=z.encode()) return matrix(M.nrows(), M.ncols(), map(int, findall(b"-?\\d+", ret)))
defsmall_roots(self, X=None, beta=1.0, epsilon=None, **kwds): from sage.misc.verbose import verbose from sage.matrix.constructor import Matrix from sage.rings.real_mpfr import RR
N = self.parent().characteristic()
ifnot self.is_monic(): raise ArithmeticError("Polynomial must be monic.")
beta = RR(beta) if beta <= 0.0or beta > 1.0: raise ValueError("0.0 < beta <= 1.0 not satisfied.")
m = max(beta**2 / (delta * epsilon), 7 * beta / delta).ceil() verbose("m = %d" % m, level=2)
t = int((delta * m * (1 / beta - 1)).floor()) verbose("t = %d" % t, level=2)
if X isNone: X = (0.5 * N ** (beta**2 / delta - epsilon)).ceil() verbose("X = %s" % X, level=2)
# we could do this much faster, but this is a cheap step # compared to LLL g = [x**j * N ** (m - i) * f**i for i inrange(m) for j inrange(delta)] g.extend([x**i * f**m for i inrange(t)]) # h
B = Matrix(ZZ, len(g), delta * m + max(delta, t)) for i inrange(B.nrows()): for j inrange(g[i].degree() + 1): B[i, j] = g[i][j] * X**j
B = flatter(B) # B = B.LLL(**kwds)
f = sum([ZZ(B[0, i] // X**i) * x**i for i inrange(B.ncols())]) R = f.roots()
ZmodN = self.base_ring() roots = set([ZmodN(r) for r, m in R ifabs(r) <= X]) Nbeta = N**beta return [root for root in roots if N.gcd(ZZ(self(root))) >= Nbeta]