def create_poly(xs: List[int], p: int) -> nmod_poly: """ returns the polynomial (z - x[0]) ... (z - x[N-1]) mod p """ ans: nmod_poly = nmod_poly([1], p) for x in xs: ans *= nmod_poly([-x, 1], p) return ans
def ring_generate(irr, p): power_dict = {(1, ): 0} element_dict = {0: [1]} test_poly = flint.nmod_poly([1], 2) alpha_poly = flint.nmod_poly([0, 1], 2) for i in range(1, p**irr.degree() - 1): test_poly = (test_poly * alpha_poly) % irr.poly coeffs = tuple(int(e) for e in test_poly.coeffs()) if coeffs in power_dict: return power_dict, element_dict power_dict[coeffs] = i element_dict[i] = list(coeffs) return power_dict, element_dict
def get_phigh(tlist: List[int], s: int, p: int) -> nmod_poly: """ return a polynomial object where the caller specfies the highest coefficents except the highest cofficent which takes the value 1 """ nzeros: int = s - len(tlist) coeffs: List[int] = [0] * nzeros coeffs.extend(tlist) coeffs.append(1) return nmod_poly(coeffs, p)
def has_repeated_roots(poly: nmod_poly, prime: int) -> bool: """ returns True if the polynomial has repeated roots """ if prime < 2 or not isprime(prime): raise FuzzyError("prime is not prime") temp: List[int] = [0] * (prime + 1) temp[-1] = 1 temp[1] = -1 zpoly: nmod_poly = nmod_poly(temp, prime) result: nmod_poly = zpoly % poly return result.coeffs() != []
def Berlekamp_Welch( aList: List[int], # inputs bList: List[int], # received codeword k: int, t: int, p: int # prime ) -> nmod_poly: """ Berlekamp-Welsch-Decoder This function throws an exception if no solution exists see https://en.wikipedia.org/wiki/Berlekamp%E2%80%93Welch_algorithm """ if len(aList) < 1: raise FuzzyError("aList is empty") if len(aList) != len(bList): raise FuzzyError("bList is empty") if k < 1 or t < 1: raise FuzzyError("k={0} and t={1} are not consistent".format(k, t)) if p < 2 or not isprime(p): raise FuzzyError("p is not prime") n = len(aList) # Create the Berlekamp-Welch system of equations # and store them as an n x n matrix 'm' and a # constant source vector 'y' of length n m_entries: List[nmod] = [] y_entries: List[nmod] = [] for i in range(n): a: int = aList[i] b: int = bList[i] apowers: List[nmod] = mod_get_powers(a, k + t, p) for j in range(k+t): m_entries.append(apowers[j]) for j in range(t): m_entries.append(-b * apowers[j]) y_entries.append(b * apowers[t]) m: nmod_mat = nmod_mat(n, n, m_entries, p) y: nmod_mat = nmod_mat(n, 1, y_entries, p) # solve the linear system of equations m * x = y for x try: x = gauss.solve(m, y).entries() except gauss.NoSolutionError: raise FuzzyError("No solution exists") # create the polynomials Q and E Qs: List[nmod] = x[:k+t] Es: List[nmod] = x[k+t:] Es.append(nmod(1, p)) Q: nmod_poly = nmod_poly(Qs, p) E: nmod_poly = nmod_poly(Es, p) Answer: nmod_poly = Q // E Remainder: nmod_poly = Q - Answer * E if len(Remainder.coeffs()) > 0: raise FuzzyError("Remainder is not zero") return Answer
def from_numpy(arr): return GF2Poly(flint.nmod_poly([int(e) for e in arr.flat], 2))
def from_list(arr): return GF2Poly(flint.nmod_poly(arr, 2))