def wiedemann1(les: LinearEquationSystem): a, b, p, n = les.a, M.t(les.b)[0], les.p, les.n for trial in range(MAX_TRIALS): bs = [b] ys = [[0] * n] ds = [0] k = 0 while bs[k] != V.zero(n): u = [random.randint(0, p - 1) for _idx in range(n)] seq = [] for i in range(2 * (n - ds[k])): ai = M.power(a, i, p) aib = M.mul_vec(ai, b, p) uaib = V.mul_sum(u, aib, p) seq.append(uaib) if not len(seq): break f = berlekamp(seq, p) if f is None: break ys.append(V.add(ys[k], M.mul_vec(f_tilda(f, a, p), b, p), p)) bs.append(V.add(b, M.mul_vec(a, ys[k + 1], p), p)) ds.append(ds[k] + len(f)) k += 1 if bs[k] != V.zero(n): print(trial, end='\r') continue return V.mul_scalar(ys[k], -1, p)
def fa(f, a, p): res = M.zero(len(a), len(a)) for power, fi in enumerate(reversed(f)): res = M.sum(res, M.mul_scalar(M.power(a, power, p), fi, p), p) return res