Inverse calculator modulo Python

237 Views Asked by At

The inverse of 154 in mod 543 is 67, my code tell me its 58. This is my Python Code:

def inverse(modulo, number):
    ri1 = number
    ri2 = modulo
    ti1 = 1
    ti2 = 0
    qi = 0
    ti = 0
    qi = 0
    ri = 0
    while ri1 != 0:
        ri = ri2 % ri1
        qi = (ri2 - ri) / ri1
        ti = ti2 - (qi * ti-1)
        ri2 = ri1
        ri1 = ri
        ti2 = ti1
        ti1 = ti
    return ti1
print(inverse(543, 154))
2

There are 2 best solutions below

0
On

The following code works:

def inverse(modulo, number):
    ri1 = number
    ri2 = modulo
    ti1 = 1
    ti2 = 0
    qi = 0
    ti = 0
    ri = 0
    while ri2 != 0:
        qi = ri1 // ri2
        ti = ri2
        ri2 = ri1 % ri2
        
        ri1 = ti
        ti = ti2
        ti2 = ti1-qi*ti2
        ti1 = ti
    
    if (ti1 < 0):
        ti1 = ti1 + modulo

    return ti1
print(inverse(543, 154))
0
On

Hi I think you have a typo in your code, and perhaps you haven't implemented the algorithm as best as you could.

In my answer below, I'm going to follow the pseudo code on this page.

That looks like this:

function extended_gcd(a, b)
    (old_r, r) := (a, b)
    (old_s, s) := (1, 0)
    (old_t, t) := (0, 1)
    
    while r ≠ 0 do
        quotient := old_r div r
        (old_r, r) := (r, old_r − quotient × r)
        (old_s, s) := (s, old_s − quotient × s)
        (old_t, t) := (t, old_t − quotient × t)
    
    output "Bézout coefficients:", (old_s, old_t)
    output "greatest common divisor:", old_r
    output "quotients by the gcd:", (t, s)

I've updated your code below, but the key 'flaw' in your approach is that you are returning t rather than s.

def inverse(modulo, number):
    ri1 = number # a
    ri2 = modulo # b
    ti1 = 0 # old_t
    ti2 = 1 # t
    ti = 0
    
    si1 = 1 # old_s
    si2 = 0 # s
    ti = 0
    
    ri = 0 
    while ri1 != 0:
        ri = ri2 % ri1
        qi = (ri2 - ri) / ri1
        ti = ti2 - (qi * ti1)
        si = si2 - (qi * si1)
        ri2 = ri1
        ri1 = ri
        ti2 = ti1
        ti1 = ti
        si2 = si1
        si1 = si
            
    print(f"Bézout coefficients: ({si1}, {ti1})")
    print(f"greatest common divisor: {ri2}")
    print(f"quotients by the gcd: ({ti2}, {si2})")
    print(f"modulo inverse {si2}")
print(inverse(543, 154))

We could streamline this code to just get the value si2 as follows:

def inverse(modulo, number):
    ri1 = number # a
    ri2 = modulo # b
    ri = 0 
    
    
    si1 = 1 # old_s
    si2 = 0 # s
    
    while ri1 != 0:
        ri = ri2 % ri1
        qi = (ri2 - ri) / ri1
        si1, si2 = si2 - (qi * si1), si1
        ri2 = ri1
        ri1 = ri
            
    return si2
print(inverse(543, 154))

Which does the trick.