from subprocess import check_output from re import findall from sage.allimport *
defflatter(M): # flatter 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)))
defmatrix_overview(BB): # see the shape of matrix for ii inrange(BB.dimensions()[0]): a = ('%02d ' % ii) for jj inrange(BB.dimensions()[1]): a += '0'if BB[ii, jj] == 0else'X' if BB.dimensions()[0] < 60: a += ' ' print(a)
delta = f.degree() # 度delta N = f.parent().characteristic() # 模数N PR = PolynomialRing(ZZ, 'x') x = PR.gen()
Zm = f.base_ring() # Zmod(N) f = f.change_ring(ZZ) # ZZ下f(x) ifnot f.is_monic(): # 首一 f = f.monic() # f = f * f[delta].inverse_mod(N)
m = ceil(max(beta * beta / (delta * epsilon), 7 * beta / delta)) # m t = floor(delta * m * (1 / beta - 1)) # t #print('m={}, t={}'.format(m, t))
f_ij = [] for i inrange(m): for j inrange(delta): f_ij.append(x ** j * N ** (m - i) * f ** i) # shift g_ij(x) for i inrange(t): f_ij.append(x ** i * f ** m) # shift h_i(x)
monomials = [] for g in f_ij: monomials += g.monomials() # 统计所有出现的单项 x^i monomials = sorted(set(monomials)) # 去重并排序
M = Matrix(ZZ, len(f_ij), len(monomials)) # 行数为多项式个数,列数为所有单项可能个数 for i inrange(M.nrows()): for j, monomial inenumerate(monomials): M[i, j] = f_ij[i].monomial_coefficient(monomial) * monomial.subs(x=X) # g_ij(xX)和h_i(xX) #matrix_overview(M) # see assert M.nrows() == M.ncols() # 方阵 nrows()=ncols() B = flatter(M) # flater加速 #print('end LLL') for j inrange(M.nrows()): # 得到f(xX),构建f(x),求根检验 Cx = sum(ZZ(B[j, i] // monomials[i](X)) * monomials[i] for i inrange(M.ncols())) # construct polynomial, R = Cx.roots() # get roots roots = [Zm(r[0]) for r in R ifabs(r[0]) <= X] # check x0<=X roots = [r for r in roots if gcd(N, ZZ(f(r))) >= ZZ(floor(N ** beta))] # check gcd(f(x_0),N)>N^beta if roots: return roots # 返回root