def is_polynomial_irreducible(f, p): """ Rabin's polynomial irreducibility test over finite fields. """ gf_degree = len(f) - 1 if gf_degree <= 1: return True monic_field = galois_field_monic(f, p) compare_polynomial = [1, 0] indices = {gf_degree // i for i in factorint(gf_degree)} monomial_base = gf_frobenius_monomial_base(monic_field, p, ZZ) h = monomial_base[1] for i in range(1, gf_degree): if i in indices: g = gf_sub(h, compare_polynomial, p, ZZ) if gf_gcd(monic_field, g, p, ZZ) != [1]: return False h = gf_frobenius_map(h, monic_field, monomial_base, p, ZZ) return h == compare_polynomial
def sub(self, x, y): return gf_sub(x, y, self.p, ZZ)
def test_gf_arith(): assert gf_neg([], 11, ZZ) == [] assert gf_neg([1], 11, ZZ) == [10] assert gf_neg([1,2,3], 11, ZZ) == [10,9,8] assert gf_add_ground([], 0, 11, ZZ) == [] assert gf_sub_ground([], 0, 11, ZZ) == [] assert gf_add_ground([], 3, 11, ZZ) == [3] assert gf_sub_ground([], 3, 11, ZZ) == [8] assert gf_add_ground([1], 3, 11, ZZ) == [4] assert gf_sub_ground([1], 3, 11, ZZ) == [9] assert gf_add_ground([8], 3, 11, ZZ) == [] assert gf_sub_ground([3], 3, 11, ZZ) == [] assert gf_add_ground([1,2,3], 3, 11, ZZ) == [1,2,6] assert gf_sub_ground([1,2,3], 3, 11, ZZ) == [1,2,0] assert gf_mul_ground([], 0, 11, ZZ) == [] assert gf_mul_ground([], 1, 11, ZZ) == [] assert gf_mul_ground([1], 0, 11, ZZ) == [] assert gf_mul_ground([1], 1, 11, ZZ) == [1] assert gf_mul_ground([1,2,3], 0, 11, ZZ) == [] assert gf_mul_ground([1,2,3], 1, 11, ZZ) == [1,2,3] assert gf_mul_ground([1,2,3], 7, 11, ZZ) == [7,3,10] assert gf_add([], [], 11, ZZ) == [] assert gf_add([1], [], 11, ZZ) == [1] assert gf_add([], [1], 11, ZZ) == [1] assert gf_add([1], [1], 11, ZZ) == [2] assert gf_add([1], [2], 11, ZZ) == [3] assert gf_add([1,2], [1], 11, ZZ) == [1,3] assert gf_add([1], [1,2], 11, ZZ) == [1,3] assert gf_add([1,2,3], [8,9,10], 11, ZZ) == [9,0,2] assert gf_sub([], [], 11, ZZ) == [] assert gf_sub([1], [], 11, ZZ) == [1] assert gf_sub([], [1], 11, ZZ) == [10] assert gf_sub([1], [1], 11, ZZ) == [] assert gf_sub([1], [2], 11, ZZ) == [10] assert gf_sub([1,2], [1], 11, ZZ) == [1,1] assert gf_sub([1], [1,2], 11, ZZ) == [10,10] assert gf_sub([3,2,1], [8,9,10], 11, ZZ) == [6,4,2] assert gf_add_mul([1,5,6], [7,3], [8,0,6,1], 11, ZZ) == [1,2,10,8,9] assert gf_sub_mul([1,5,6], [7,3], [8,0,6,1], 11, ZZ) == [10,9,3,2,3] assert gf_mul([], [], 11, ZZ) == [] assert gf_mul([], [1], 11, ZZ) == [] assert gf_mul([1], [], 11, ZZ) == [] assert gf_mul([1], [1], 11, ZZ) == [1] assert gf_mul([5], [7], 11, ZZ) == [2] assert gf_mul([3,0,0,6,1,2], [4,0,1,0], 11, ZZ) == [1,0,3,2,4,3,1,2,0] assert gf_mul([4,0,1,0], [3,0,0,6,1,2], 11, ZZ) == [1,0,3,2,4,3,1,2,0] assert gf_mul([2,0,0,1,7], [2,0,0,1,7], 11, ZZ) == [4,0,0,4,6,0,1,3,5] assert gf_sqr([], 11, ZZ) == [] assert gf_sqr([2], 11, ZZ) == [4] assert gf_sqr([1,2], 11, ZZ) == [1,4,4] assert gf_sqr([2,0,0,1,7], 11, ZZ) == [4,0,0,4,6,0,1,3,5]
def sub(self, x: list, y: list) -> list: return gf_sub(x, y, self.p, ZZ)