Search code examples
pythonalgorithmmodulodiscrete-mathematicsinverse

Algorithm for calculating the smallest, positive inverse of a modulo m. I'm not getting right answers for some inputs


So I've used Bezout Coefficients and GCD functions(that I created for my previous coding assignments) to create an inverse modulo function as shown below. I'm getting right answers for some inputs like (101, 4620), but wrong answers for (3, 7) and (7, 19). What should I do?

The Bezout Coefficients and GCD functions used are correct.

# Writing a function that returns the smallest, positive inverse of a modulo m
def modinv(a,m):
    # Storing the result after calling the result of the gcd function
    GCD_Calculation = gcd(a,m)

    if GCD_Calculation != 1: # Checking if a and m are relatively prime
        raise ValueError("The given values are not relatively prime") # Raising an error if a and m are not relatively prime
    elif m < 1:
        raise ValueError("\'m\' has to be a positive integer") # Raising an error if m is not greater than 1
    else: # When the basic requirements above are met
        # Calling the bezout_coeffs function to find the coefficients of a and m
        a_m_coeffs = bezout_coeffs(a, m)
        # Setting up variables to store the coefficients of a and m
        s_coeff_a = a_m_coeffs[a] # Coefficient of a -> s
        t_coeff_m = a_m_coeffs[m] # Coefficient of m -> t

        correct_value = 0 # Variable to store the value of the inverse of 'a' modulo 'm'

        # Setting up conditonal statments to check coefficients are in the range [0, m-1]
        if s_coeff_a >= 0 and s_coeff_a < m:
            correct_value = s_coeff_a 
        elif t_coeff_m >= 0 and t_coeff_m < m:
            correct_value = t_coeff_m
        else:
            raise ValueError("The inverse of \'a\' modulo \'m\' does not exist")
        
        mod_inv_value = correct_value

    return mod_inv_value # Returning the value of x as the inverse of 'a' modulo 'm'

I just observed how inverse of a modulo is calculated mathematically and tried to implement the observation into code. I'm getting right answers for the some inputs, and wrong for other inputs.


Solution

  • https://en.wikipedia.org/wiki/Extended_Euclidean_algorithm#Modular_integers says:

    Also, for getting a result which is positive and lower than n, one may use the fact that the integer t provided by the algorithm satisfies |t| < n. That is, if t < 0, one must add n to it at the end."

    Due to the way Python defines modulus, t_coeff_m % m should give you the right answer.