I have four big numbers (up to 100 digits) like m, y, n, r
that m * y mod n = r
. I know the value of m,n
and r
and I wanna find the value of y
. Is there a function in python3
to do this? (like the powmod
function in gmpy2
)
-
1Can't you just use the property `(m * y) mod n = (m mod n) * (y mod n) mod n` ? – Rojan Nov 22 '16 at 20:07
-
What you ask is nothing like `powmod`. You are asking for division in modular arithmetic, which usually uses the [extended Euclidean algorithm](https://en.wikipedia.org/wiki/Extended_Euclidean_algorithm). This is pretty easy to implement yourself, but be careful to check for error conditions. – Rory Daulton Nov 22 '16 at 20:07
-
I know, I just say an example that I need such this function @RoryDaulton – Richard Nov 22 '16 at 20:09
-
Are you asking how to do this, or specifically only if there is a built-in function that does this? – Rory Daulton Nov 22 '16 at 20:12
-
a built-in function @RoryDaulton – Richard Nov 22 '16 at 20:13
-
and how can this help, when (m mod n) and (y mod n) are the big numbers again? @RojanKarakaya – Richard Nov 22 '16 at 20:32
-
How can I pretty easy to implement this and find y? @RoryDaulton – Richard Nov 22 '16 at 20:48
1 Answers
If the value of r
in your problem is guaranteed to be 1
, there are some available Python functions, such as the invert
function in the gmpy or gmpy2 modules. I have not found the more general division function that you want. You could use the standard invert functions, but they will disallow some divisions that can actually be done.
Here is a function that I just wrote, based on sample code in Wikipedia, as efficient as I can make it. With your terminology, call divideresidues(r, m, n)
.
def divideresidues(dividend, divisor, modulus):
"""Return the dividend / divisor modulo modulus"""
r, newr = modulus, divisor
t, newt = 0, 1
while newr != 0:
quotient, remainder = divmod(r, newr)
r, newr = newr, remainder
t, newt = newt, t - quotient * newt
if t < 0:
t = t + modulus
quotient, remainder = divmod(dividend, r)
if remainder:
raise ValueError('Bad division in divideresidues()')
return t * quotient % modulus
This has the same efficiency as the Euclidean algorithm, namely five times the number of digits in the smaller of divisor
and modulus
. The size of dividend
is basically irrelevant. In your case that means at most 500 steps. This sounds like a large number but I tested it with larger numbers and it seems fast enough, and those 500 steps will happen rarely--basically when divisor
and modulus
are successive numbers in the Fibonacci sequence.

- 21,934
- 6
- 42
- 50