예제 #1
0
    def test_lagrange_interp(self):
        """Test lagrangian interpolation."""
        modulus = 7
        mod7 = IntegersModP(modulus)
        polysOverMod = polynomials_over(mod7).factory
        xs = [mod7(1), mod7(6)]
        ys = [mod7(1), mod7(6)]
        interp = lagrange_interp(mod7, xs, ys)
        # interp should equal x
        assert interp == polysOverMod([0, 1])

        xs = [mod7(1), mod7(6)]
        ys = [mod7(0), mod7(0)]
        interp = lagrange_interp(mod7, xs, ys)
        # interp should equal 0
        assert interp == polysOverMod([0])

        # Test lagrange interp over general finite field
        Z5 = IntegersModP(5)
        F25 = FiniteField(5, 2)
        polysOverF = polynomials_over(F25).factory
        xs = [F25(1), F25(2)]
        ys = [F25(1), F25(2)]
        interp = lagrange_interp(F25, xs, ys)
        # interp should equal x
        assert interp == polysOverF([F25(0), F25(1)])
예제 #2
0
    def test_multi_inv(self):
        """Test of faster multiple inverse method."""
        # 6^-1 = 6
        modulus = 7
        mod7 = IntegersModP(modulus)
        outs = multi_inv(mod7, [mod7(6), mod7(6), mod7(6)])
        assert outs == [6, 6, 6]

        # 1^-1 = 1
        outs = multi_inv(mod7, [mod7(6), mod7(1), mod7(6)])
        assert outs == [6, 1, 6]

        outs = multi_inv(mod7, [mod7(0), mod7(1), mod7(1)])

        modulus = 2**256 - 2**32 * 351 + 1
        field = IntegersModP(modulus)
        ## Root of unity such that x^precision=1
        G2 = field(7)**((modulus - 1) // 4096)
        ### Powers of the higher-order root of unity
        xs = get_power_cycle(G2, field)
        xs_minus_1 = [x - 1 for x in xs]
        xs_minus_1_inv = multi_inv(field, xs_minus_1)
        # Skip 0 since xs_minus_1[0] == 0
        for i in range(1, 5):
            assert xs_minus_1[i] * xs_minus_1_inv[i] == 1

        steps = 512
        precision = 4096
        z_evals = [xs[(i * steps) % precision] - 1 for i in range(precision)]
        z_inv = multi_inv(field, z_evals)
        for i in range(1, 5):
            assert z_evals[i] * z_inv[i] == 1
예제 #3
0
    def test_modulus(self):
        """Basic test of polynomial modulus."""
        Mod5 = IntegersModP(5)
        Mod11 = IntegersModP(11)

        polysOverQ = polynomials_over(Fraction).factory
        polysMod5 = polynomials_over(Mod5).factory
        polysMod11 = polynomials_over(Mod11).factory
        for p in [polysOverQ, polysMod5, polysMod11]:
            # modulus
            assert p([]) == p([1, 7, 49]) % p([7])
            assert p([-7]) == p([-3, 10, -5, 3]) % p([1, 3])
예제 #4
0
    def test_equality(self):
        """Basic test of polynomial equality."""
        Mod5 = IntegersModP(5)
        Mod11 = IntegersModP(11)

        polysOverQ = polynomials_over(Fraction).factory
        polysMod5 = polynomials_over(Mod5).factory
        polysMod11 = polynomials_over(Mod11).factory
        for p in [polysOverQ, polysMod5, polysMod11]:
            # equality
            assert p([]) == p([])
            assert p([1, 2]) == p([1, 2])
            assert p([1, 2, 0]) == p([1, 2, 0, 0])
예제 #5
0
    def test_multiplication(self):
        """Basic test of polynomial multiplication."""
        Mod5 = IntegersModP(5)
        Mod11 = IntegersModP(11)

        polysOverQ = polynomials_over(Fraction).factory
        polysMod5 = polynomials_over(Mod5).factory
        polysMod11 = polynomials_over(Mod11).factory
        for p in [polysOverQ, polysMod5, polysMod11]:
            # multiplication
            assert p([1, 2, 1]) == p([1, 1]) * p([1, 1])
            assert p([2, 5, 5, 3]) == p([2, 3]) * p([1, 1, 1])
            assert p([0, 7, 49]) == p([0, 1, 7]) * p([7])
예제 #6
0
    def test_subtraction(self):
        """Basic test of polynomial subraction."""
        Mod5 = IntegersModP(5)
        Mod11 = IntegersModP(11)

        polysOverQ = polynomials_over(Fraction).factory
        polysMod5 = polynomials_over(Mod5).factory
        polysMod11 = polynomials_over(Mod11).factory
        for p in [polysOverQ, polysMod5, polysMod11]:
            # subtraction
            assert p([1, -2, 3]) == p([1, 0, 3]) - p([0, 2])
            assert p([1, 2, 3]) == p([1, 2, 3]) - p([])
            assert p([-1, -2, -3]) == p([]) - p([1, 2, 3])
예제 #7
0
    def test_addition(self):
        """Basic test of polynomial addition."""
        Mod5 = IntegersModP(5)
        Mod11 = IntegersModP(11)

        polysOverQ = polynomials_over(Fraction).factory
        polysMod5 = polynomials_over(Mod5).factory
        polysMod11 = polynomials_over(Mod11).factory
        for p in [polysOverQ, polysMod5, polysMod11]:
            # addition
            assert p([1, 2, 3]) == p([1, 0, 3]) + p([0, 2])
            assert p([1, 2, 3]) == p([1, 2, 3]) + p([])
            assert p([5, 2, 3]) == p([4]) + p([1, 2, 3])
            assert p([1, 2]) == p([1, 2, 3]) + p([0, 0, -3])
예제 #8
0
    def test_division_more(self):
        """More division tests"""
        Mod5 = IntegersModP(5)
        Mod11 = IntegersModP(11)

        polysOverQ = polynomials_over(Fraction).factory
        polysMod5 = polynomials_over(Mod5).factory
        polysMod11 = polynomials_over(Mod11).factory

        assert polysOverQ([Fraction(1, 7), 1,
                           7]) == polysOverQ([1, 7, 49]) / polysOverQ([7])
        assert polysMod5([1 / Mod5(7), 1,
                          7]) == polysMod5([1, 7, 49]) / polysMod5([7])
        assert polysMod11([1 / Mod11(7), 1,
                           7]) == polysMod11([1, 7, 49]) / polysMod11([7])
예제 #9
0
    def test_adfft_inverse(self):
        p = 2
        m = 4
        Zp = IntegersModP(p)
        polysOver = polynomials_over(Zp)
        coefficients = [Zp(0)] * 5
        coefficients[0] = Zp(1)
        coefficients[1] = Zp(1)
        coefficients[4] = Zp(1)
        poly = polysOver(coefficients)
        field = FiniteField(p, m, polynomialModulus=poly)

        mp = 3
        x = []
        y = []
        x.append(field(polysOver([1, 0, 0])))
        y.append(field(polysOver([1, 1])))
        x.append(field(polysOver([1, 1, 1])))
        y.append(field(polysOver([0, 0, 1])))
        x.append(field(polysOver([1, 0])))
        y.append(field(polysOver([0, 1])))
        x.append(field(polysOver([1, 1])))
        y.append(field(polysOver([0, 1, 1])))
        x.append(field(polysOver([1, 1, 1])))
        y.append(field(polysOver([1, 0, 1])))
        x.append(field(polysOver([1, 0, 0])))
        y.append(field(polysOver([1, 1, 1])))
        x.append(field(polysOver([1])))
        y.append(field(polysOver([0])))
        x.append(field(polysOver([1])))
        y.append(field(polysOver([1, 1])))

        obj = Additive_FFT(field)
        f = obj.adfft_inverse(x, y, mp)
예제 #10
0
 def test_merkletree_zmodp(self):
     """Constructs merkle tree of field elements."""
     modulus = 7
     mod7 = IntegersModP(modulus)
     l = [mod7(i) for i in range(128)]
     m_tree = merkelize(l)
     assert len(m_tree) == 256
예제 #11
0
 def test_mod_large_gcd(self):
     """Test that GCD works with a larger prime."""
     ModHuge = IntegersModP(9923)
     assert ModHuge(38) == gcd(ModHuge(4864), ModHuge(3458))
     assert (ModHuge(32), ModHuge(-45),
             ModHuge(38)) == extended_euclidean_algorithm(
                 ModHuge(4864), ModHuge(3458))
예제 #12
0
 def test_mod_7_gcd(self):
     """Test that the GCD works in mod-7 arithmetic."""
     Mod7 = IntegersModP(7)
     # TODO(rbharath): Why are these modular equations right? Is there a way to
     # do simple mental arithmetic to calculate these values?
     assert Mod7(6) == gcd(Mod7(6), Mod7(14))
     assert Mod7(2) == gcd(Mod7(6), Mod7(9))
예제 #13
0
    def test_get_witness(self):
        """Test that a witness can be extracted from the APR instance.

    # TODO(rbharath): Make this test non-trivial to check the witness has
    # required properties.
    """
        width = 2
        # Set the field small in tests since primitive polynomial generation is slow.
        p = 2
        m = 17
        Zp = IntegersModP(p)
        polysOver = polynomials_over(Zp)
        #x^17 + x^3 + 1 is primitive
        coefficients = [Zp(0)] * 18
        coefficients[0] = Zp(1)
        coefficients[3] = Zp(1)
        coefficients[17] = Zp(1)
        poly = polysOver(coefficients)
        field = FiniteField(p, m, polynomialModulus=poly)
        steps = 3
        extension_factor = 8
        inp = [field(0), field(1)]
        polysOver = multivariates_over(field, width).factory
        X_1 = polysOver({(1, 0): field(1)})
        X_2 = polysOver({(0, 1): field(1)})
        step_polys = [X_2, X_1 + X_2]
        air = AIR(field, width, inp, steps, step_polys, extension_factor)
        apr = APR(air)
        # TODO(rbharath): Uncomment this and reactivate it
        witness = apr.generate_witness()
예제 #14
0
    def test_multiplication(self):
        """Basic test of floating point multiplication."""

        p = 2
        m = 4
        Zp = IntegersModP(p)
        polysOver = polynomials_over(Zp)
        coefficients = [Zp(0)] * 5
        coefficients[0] = Zp(1)
        coefficients[1] = Zp(1)
        coefficients[4] = Zp(1)
        poly = polysOver(coefficients)
        field = FiniteField(p, m, polynomialModulus=poly)
        floating_point = FloatingPoint(field)

        assert floating_point(field(polysOver([0])), field(polysOver([
            0
        ])), 0, 0) == floating_point(field(polysOver(
            [0])), field(polysOver([0])), 0, 0) * floating_point(
                field(polysOver([1, 1, 1])), field(polysOver([1, 1, 1])), 0, 0)
        assert floating_point(field(polysOver([0])), field(polysOver(
            [0])), 0, 0) == floating_point(field(polysOver(
                [0])), field(polysOver([0])), 0, 0) * floating_point(
                    field(polysOver([0])), field(polysOver([0])), 0, 0)
        assert floating_point(field(polysOver([1, 1, 1])), field(polysOver(
            [1])), 0, 0) == floating_point(field(polysOver(
                [1])), field(polysOver([0])), 0, 0) * floating_point(
                    field(polysOver([1, 1, 1])), field(polysOver([1])), 0, 0)
        assert floating_point(field(polysOver([
            1, 1, 1, 1
        ])), field(polysOver([
            1, 0, 1
        ])), 0, 1) == floating_point(field(polysOver(
            [1, 0, 1])), field(polysOver([1, 1])), 0, 1) * floating_point(
                field(polysOver([1, 1])), field(polysOver([1, 1, 1])), 0, 0)
예제 #15
0
 def test_gauss(self):
     """Tests the construction of gaussian elimination."""
     p = 2
     m = 2
     t = 2
     Zp = IntegersModP(p)
     basePolys = polynomials_over(Zp)
     M = []
     row = 3
     field = FiniteField(p, m)
     M.append([
         basePolys([1, 1]),
         basePolys([0]),
         basePolys([0, 1]),
         basePolys([1])
     ])
     M.append([
         basePolys([1]),
         basePolys([0]),
         basePolys([0, 1]),
         basePolys([1, 1])
     ])
     M.append([
         basePolys([1, 0]),
         basePolys([0, 1]),
         basePolys([0, 1]),
         basePolys([1])
     ])
     result = gauss(M, row, field)
     assert result == [basePolys([1]), basePolys([1]), basePolys([1])]
예제 #16
0
 def test_construct_affine_vanishing_poly_Moore(self):
     """Tests the construction of an affine vanishing poly."""
     p = 2
     m = 2
     # Degree of space we construct
     t = 2
     Zp = IntegersModP(p)
     basePolys = polynomials_over(Zp)
     # g
     g = basePolys([0, 1])
     field = FiniteField(p, m)
     ################################################
     print("field")
     print(field)
     print("field.__name__")
     print(field.__name__)
     ################################################
     H0 = AffineSpace(Zp, [g**k for k in range(t - 1)])
     ################################################
     print("field")
     print(field)
     ################################################
     Z_H0 = construct_affine_vanishing_polynomial_Moore(field, H0)
     print(len(H0))
     for i in H0:
         print(Z_H0(field(i)))
예제 #17
0
        def __truediv__(self, other):
            '''
      if we are dividing A = (v_a, p_a, z_a, s_a) and B = (v_b, p_b, z_b, s_b), then:
        1- z_output = z_a
        2- s_output = s_a XOR s_b
        3- if z_output == 1, then v_output = 0; otherwise, v_output = v_a * inverse(v_b)
        4- if z_output == 1, then p_output = 0; otherwise, p_output = p_a - p_b + l 
      '''
            polysOver = polynomials_over(IntegersModP(field.p))

            if other.z == 1:
                raise ZeroDivisionError
            if other.v == field(polysOver([0])):
                raise ZeroDivisionError

            z_c = self.z | other.z

            s_c = self.s ^ other.s

            if z_c == 1:
                v_c = field(polysOver([0]))
            else:
                v_c = self.v / other.v

            if z_c == 1:
                p_c = field(polysOver([0]))
            else:
                p_c = self.p - other.p
                p_c = p_c + num_to_binary_list(
                    self.v.poly.degree() + other.v.inverse().poly.degree() -
                    (self.v.m - 1))

            output = Fp(v_c, p_c, z_c, s_c)
            return output
예제 #18
0
    def test_construct_multivariate_dirac_delta(self):
        """Tests the construct of the multivariate dirac delta."""
        modulus = 3
        mod7 = IntegersModP(modulus)
        n = 3
        # Let's make polynomials in (Z/7)[x, y, z]
        multi = multivariates_over(mod7, n).factory
        # Let's generate the dirac delta at x=0, y=0, z=0
        values = [mod7(0), mod7(0), mod7(0)]
        dirac = construct_multivariate_dirac_delta(mod7, values, n)

        # The dirac delta should be 1 at x=0, y=0, z=0
        assert dirac((0, 0, 0)) == 1
        # It should be 0 elsewhere
        assert dirac((1, 0, 0)) == 0
        assert dirac((0, 1, 0)) == 0
        assert dirac((0, 0, 1)) == 0

        # Let's generate the dirac delta at x=1, y=1, z=1
        values = [mod7(1), mod7(1), mod7(1)]
        dirac = construct_multivariate_dirac_delta(mod7, values, n)

        # The dirac delta should be 1 at x=1, y=1, z=1
        assert dirac((1, 1, 1)) == 1
        # It should be 0 elsewehre
        assert dirac((1, 0, 0)) == 0
        assert dirac((0, 1, 0)) == 0
        assert dirac((0, 0, 1)) == 0
예제 #19
0
        def __mul__(self, other):
            '''
      if we are multiplying A = (v_a, p_a, z_a, s_a) and B = (v_b, p_b, z_b, s_b), then:
        1- z_output = z_a OR z_b
        2- s_output = s_a XOR s_b
        3- if z_output == 1, then v_output = 0; otherwise, v_output = v_a * v_b
        4- if z_output == 1, then p_output = 0; otherwise, p_output = p_a + p_b + l 
      '''
            polysOver = polynomials_over(IntegersModP(field.p))

            z_c = self.z | other.z

            s_c = self.s ^ other.s

            if z_c == 1:
                v_c = field(polysOver([0]))
            else:
                v_c = self.v * other.v

            if z_c == 1:
                p_c = field(polysOver([0]))
            else:
                p_c = self.p + other.p
                p_c = p_c + num_to_binary_list(self.v.poly.degree() +
                                               self.v.poly.degree() -
                                               (self.v.m - 1))

            output = Fp(v_c, p_c, z_c, s_c)
            return output
예제 #20
0
 def test_binary_air(self):
     """"Test construction of a binary AIR."""
     steps = 512 - 1
     # This finite field is of size 2^17
     p = 2
     m = 17
     # TODO(rbharath): Extension factor shouldn't be an
     # argument.
     extension_factor = 8
     Zp = IntegersModP(p)
     polysOver = polynomials_over(Zp)
     #field = FiniteField(p, m)
     #x^17 + x^3 + 1 is primitive
     coefficients = [Zp(0)] * 18
     coefficients[0] = Zp(1)
     coefficients[3] = Zp(1)
     coefficients[17] = Zp(1)
     poly = polysOver(coefficients)
     field = FiniteField(p, m, polynomialModulus=poly)
     width = 2
     inp = [field(0), field(1)]
     polysOver = multivariates_over(field, width).factory
     [X_1, X_2] = generate_Xi_s(field, width)
     step_polys = [X_2, X_1 + X_2]
     air = AIR(field, width, inp, steps, step_polys, extension_factor)
예제 #21
0
def is_irreducible(polynomial: Poly, p: int) -> bool:
    """is_irreducible: Polynomial, int -> bool

  Determine if the given monic polynomial with coefficients in Z/p is
  irreducible over Z/p where p is the given integer
  Algorithm 4.69 in the Handbook of Applied Cryptography
  """
    ZmodP = IntegersModP(p)
    if polynomial.ring is not ZmodP:
        raise TypeError(
            "Given a polynomial that's not over %s, but instead %r" %
            (ZmodP.__name__, polynomial.ring.__name__))

    poly = polynomials_over(ZmodP).factory
    x = poly([0, 1])
    power_term = x
    is_unit = lambda p: p.degree() == 0

    for _ in range(int(polynomial.degree() / 2)):
        power_term = power_term.powmod(p, polynomial)
        gcd_over_Zmodp = gcd(polynomial, power_term - x)
        if not is_unit(gcd_over_Zmodp):
            return False

    return True
예제 #22
0
    def test_compress_fri(self):
        """
    Basic tests of compression
    """
        degree = 4
        modulus = 2**256 - 2**32 * 351 + 1
        field = IntegersModP(modulus)
        polysOver = polynomials_over(field).factory
        # 1 + 2x + 3x^2 + 4 x^3 mod 31
        poly = polysOver([val for val in range(degree)])
        # TODO(rbharath): How does the choice of the n-th root of
        # unity make a difference in the fft?

        # A root of unity is a number such that z^n = 1
        # This provides us a 6-th root of unity (z^6 = 1)
        root_of_unity = field(3)**((modulus - 1) // 8)

        fri = SmoothSubgroupFRI(field)
        proof = fri.generate_proximity_proof(poly, root_of_unity, degree,
                                             modulus)
        compressed = compress_fri(proof)
        length = bin_length(compressed)
        print("bin_length: %d" % length)
        # TODO(rbharath): This is a lame test that checks length
        # of compressed proof is > 0. Need better unit test.
        assert length > 0
예제 #23
0
 def test_apr_constructor(self):
     """Test that the APR class can be initialized."""
     width = 2
     # Set the field small in tests since primitive polynomial generation is slow.
     p = 2
     m = 2
     Zp = IntegersModP(p)
     polysOver = polynomials_over(Zp)
     field = FiniteField(p, m)
     #m = 17
     ##x^17 + x^3 + 1 is primitive
     #coefficients = [Zp(0)] * 18
     #coefficients[0] = Zp(1)
     #coefficients[3] = Zp(1)
     #coefficients[17] = Zp(1)
     #poly = polysOver(coefficients)
     #field = FiniteField(p, m, polynomialModulus=poly)
     steps = 7
     extension_factor = 8
     inp = [field(0), field(1)]
     polysOver = multivariates_over(field, width).factory
     X_1 = polysOver({(1, 0): field(1)})
     X_2 = polysOver({(0, 1): field(1)})
     step_polys = [X_2, X_1 + X_2]
     air = AIR(field, width, inp, steps, step_polys, extension_factor)
     apr = APR(air)
예제 #24
0
 def test_large_modulus(self):
     """Runs basic tests in large modulus needed for starks."""
     modulus = 2**256 - 2**32 * 351 + 1
     modM = IntegersModP(modulus)
     assert modM(5) != modM(11)
     assert modM(2**32) != modM(2**64)
     assert modM(2**64) != modM(2**128)
     assert modM(2**256) == modM(2**32 * 351 - 1)
예제 #25
0
 def test_exponentiation(self):
     """Tests that old and new multiplication match."""
     steps = 512
     modulus = 2**256 - 2**32 * 351 + 1
     mod = IntegersModP(modulus)
     Gorig = pow(7, (modulus - 1) // steps, modulus)
     G = mod(7)**((modulus - 1) // steps)
     assert int(G) == Gorig
예제 #26
0
        def Float_to_Fix(self):
            polysOver = polynomials_over(IntegersModP(field.p))
            if self.z == 1:
                return field(polysOver([0])), 0

            result_of_power = self.p.two_pow()
            output = self.v * result_of_power
            return output, self.s
예제 #27
0
    def test_division(self):
        """Basic test of polynomial division."""
        Mod5 = IntegersModP(5)
        Mod11 = IntegersModP(11)

        polysOverQ = polynomials_over(Fraction).factory
        polysMod5 = polynomials_over(Mod5).factory
        polysMod11 = polynomials_over(Mod11).factory
        for p in [polysOverQ, polysMod5, polysMod11]:
            # division
            assert p([1, 1, 1, 1, 1,
                      1]) == p([-1, 0, 0, 0, 0, 0, 1]) / p([-1, 1])
            assert p([-1, 1, -1, 1, -1,
                      1]) == p([1, 0, 0, 0, 0, 0, 1]) / p([1, 1])
            assert p([]) == p([]) / p([1, 1])
            assert p([1, 1]) == p([1, 1]) / p([1])
            assert p([1, 1]) == p([2, 2]) / p([2])
예제 #28
0
파일: fft.py 프로젝트: apguerrera/starks
    def Taylor_Expansion(self, Polys, n):
        #  Let F be any field of characteristic two, t > 1 any integer, so we consider as 2
        # if n <= t then return the original function
        if n <= 2:
            return Polys

        # Find k such that t * 2^k < n ≤ 2 * t * 2^k
        for x in range(n):
            if 2**(x + 1) < n and 2**(x + 2) >= n:
                k = x

        # Split f(x) into three blocks f0, f1, and f2 where f(x) = f0(x) + x^{t * 2^k} (f1(x) + x ^{(t-1) * 2^k} * f2(x))
        polysOver = polynomials_over(IntegersModP(2))
        list_f0 = []
        for i in range(2**(k + 1)):
            if i > Polys.poly.degree():
                list_f0.append(0)
            else:
                list_f0.append(int(str(Polys.poly.coefficients[i])[0]))

        list_f1 = []
        for i in range(2**(k)):
            if 2**(k + 1) + i > Polys.poly.degree():
                list_f1.append(0)
            else:
                list_f1.append(
                    int(str(Polys.poly.coefficients[2**(k + 1) + i])[0]))

        list_f2 = []
        for i in range(2**k):
            if 2**(k + 1) + 2**k + i > Polys.poly.degree():
                list_f2.append(0)
            else:
                list_f2.append(
                    int(
                        str(Polys.poly.coefficients[2**(k + 1) + 2**k +
                                                    i])[0]))

        f0 = self.field(polysOver(list_f0))
        f1 = self.field(polysOver(list_f1))
        f2 = self.field(polysOver(list_f2))

        # h = f1+f2, g0 = f0 + x^{2^k} * h, and g1 = h + x^{(t-1) * 2^k} * f2
        h = f1 + f2
        twoK = []
        for i in range(2**(k)):
            twoK.append(0)
        twoK.append(1)
        f_twoK = self.field(polysOver(twoK))

        g0 = f0 + f_twoK * h
        g1 = h + f_twoK * f2

        # recursive part
        V1 = self.Taylor_Expansion(g0, n / 2)
        V2 = self.Taylor_Expansion(g1, n / 2)

        return V1, V2
예제 #29
0
    def test_basic(self):
        """Basic test"""
        #field7 = PrimeField(7)
        mod7 = IntegersModP(7)
        # 12 % 7 == 5
        assert mod7(6) + mod7(6) == mod7(5)

        # 6^-1 = 6
        assert 1 / mod7(6) == mod7(6)
예제 #30
0
    def test_typecast(self):
        """Test typecasting operation"""
        mod3 = IntegersModP(3)
        Polynomial = polynomials_over(mod3)
        x = mod3(1)
        p = Polynomial([1, 2])

        x + p
        p + x