Homepage Solution manuals David S. Dummit Abstract Algebra Exercise 0.3.16 ($\mathbb{Z}/n\mathbb{Z}$ in Python)

Exercise 0.3.16 ($\mathbb{Z}/n\mathbb{Z}$ in Python)

Write a computer program to add and multiply mod n , for any n given as input. The output of these operations should be the least residues of the sums and products of two integers. Also include the feature that if ( a , n ) = 1 , an integer c between 1 and n 1 such that a ¯ c ¯ = 1 ¯ may be printed on request. (Your program should not, of course, simply quote “mod” functions already build into many systems).

Answers

Proof. I give an homemade class in an Object Oriented Program in Python to represent elements of 𝑛ℤ (in a file “Zn.py”).

import random

class Mod:
    "class of integers modulo n"

    def bezout(a,b):
        """input  : integers (a,b)
            output : (x,y,d),
            (x,y) solution of ax+by =d, d = gcd(a,b)
        """
        sgn_a = 1 if a >= 0 else -1
        sgn_b = 1 if b >= 0 else -1
        (r0, r1)=(abs(a), abs(b))
        (u0, v0) = (1, 0)
        (u1, v1) = (0, 1)
        while r1 != 0:
            q = r0 // r1
            (r2, u2, v2) = (r0 - q * r1, u0 - q * u1, v0 - q * v1)
            (r0, r1) = (r1, r2)
            (u0, u1) = (u1, u2)
            (v0, v1) = (v1, v2)
        x , y, d  = sgn_a * u0, sgn_b * v0, r0
        if x <= 0: x, y = x + abs(b), y - sgn_b * a
        return x, y, d

    def least_residue(a,n):
        r = a % n
        if r > n//2:
            r -= n
        return r

    def __init__(self, a, n):
        self.residu = Mod.least_residue(a,n)
        self.modulo = n

    def lift(self):
        return self.residu

    def __str__(self):
        return f"Mod({self.residu}, {self.modulo})"

                                                                  

                                                                  
    def __repr__(self):
        return f"{self.residu}"

    def __eq__(self,other):
        if isinstance(other,int):
            return self.residu == other % self.modulo
        return self.residu == other.residu and self.modulo == other.modulo

    def __hash__(self):
        return (11 * self.residu + self.modulo) // 16

    def __add__(self,other):
        if self.modulo == other.modulo:
            return Mod(self.residu + other.residu, self.modulo)

    def __sub__(self,other):
        if self.modulo == other.modulo:
            return Mod(self.residu - other.residu, self.modulo)

    def __mul__(self,other):
        if self.modulo == other.modulo:
            return Mod(self.residu * other.residu, self.modulo)

    def __rmul__(self, a):
        return Mod(a*self.residu, self.modulo)

    def __neg__(self):
        return Mod(-self.residu, self.modulo)

    def __pos__(self):
        return self

    def __pow__(self,n):
        if n>=0:
            resu = Mod(1,self.modulo)
            a = self
            while n!= 0:
                if n % 2 != 0:
                    resu = resu * a
                a = a * a
                n = n // 2
            return resu
        else:
            return (self ** -n).inverse()

    def inverse(self):
                                                                  

                                                                  
        inv,_,_ = Mod.bezout(self.residu, self.modulo)
        return Mod(inv, self.modulo)

    def _exporapide_(gamma,n,a,p):
        """ returns gamma^n, where gamma = (x,y) element of F_p(x)/<x^2-a>"""

        x,y = gamma[0],gamma[1]
        # multiplication in F_p(x)/<x^2-a> :
        mult = lambda l : ((l[0][0] * l[1][0] + a * l[0][1] * l[1][1]) % p,
                           (l[0][0] * l[1][1] + l[0][1] * l[1][0])%p)
        (u,v) = (1,0)
        (r,s) = (x,y)
        n = (p-1)//2
        while n != 0:
            if n % 2 != 0:
                (u,v) = mult(((r,s),(u,v)))
            (r,s) = mult(((r,s),(r,s)))
            n = n //2
        return (u,v)


    def sqrt(self):
        """ returns a square root in F_p= Z/pZ
       if the modulo p is an odd prime, and if a is a square in F_p"""

        a = self.residu
        p = self.modulo
        if a == 0: return Mod(0,p)

        if p % 4 == 3:
            resultat = Mod(a,p)**((p+1)//4)
            return Mod(abs(resultat.lift()),p)
        pas_trouve = True
        resultat = 0
        while pas_trouve:
            z = random.randint(1,p-1)
            (u,v) = Mod._exporapide_((1,z),(p-1)//2,a,p)
            if  v!= 0:
                pas_trouve = False
                U, V = Mod(u,p), Mod(v,p)
                un = Mod(1,p)
                W1 = (un - U)  * V.inverse()
                W2 = (-un - U) * V.inverse()
                W3 = - U * V.inverse()
                if W1*W1 == a:
                    resultat = W1
                                                                  

                                                                  
                elif W2 * W2 == a:
                    resultat = W2
                elif W3 * W3 == a:
                    resultat = W3
        return Mod(abs(resultat.lift()),p)

Example with Ipython:

In [1]: from Zn import Mod

In [2]: a = Mod (11,17)

In [3]: b = Mod(9, 17)

In [4]: a * b
Out[4]: -3

In [5]: a = Mod(11, 1234567891234567891234567891)

In [6]: b = a.inverse(); b
Out[6]: 336700333973063970336700334

In [7]: b ** -1
Out[7]: 11

In [8]: r = a.sqrt(); r
Out[8]: 261925641728901579479400386

In [9]: r ** 2
Out[9]: 11

User profile picture
2026-01-07 11:32
Comments