How to resolve the algorithm Modular inverse step by step in the Ruby programming language
How to resolve the algorithm Modular inverse step by step in the Ruby programming language
Table of Contents
Problem Statement
From Wikipedia: In modular arithmetic, the modular multiplicative inverse of an integer a modulo m is an integer x such that Or in other words, such that: It can be shown that such an inverse exists if and only if a and m are coprime, but we will ignore this for this task.
Either by implementing the algorithm, by using a dedicated library or by using a built-in function in your language, compute the modular inverse of 42 modulo 2017.
Let's start with the solution:
Step by Step solution about How to resolve the algorithm Modular inverse step by step in the Ruby programming language
The provided Ruby code implements mathematical functions related to modular arithmetic and extended Euclidean algorithms. Modular arithmetic involves operations performed on integers with respect to a modulus (a fixed positive integer), and the extended Euclidean algorithm efficiently finds the greatest common divisor (GCD) of two integers.
Here's a detailed explanation of each function:
-
extended_gcd
:- This function takes two integers,
a
andb
, and computes their greatest common divisor (GCD) using the extended Euclidean algorithm. - It initializes
last_remainder
andremainder
to the absolute values ofa
andb
, respectively. - It also initializes four variables,
x
,last_x
,y
, andlast_y
, to keep track of intermediate values during the algorithm. - The algorithm iterates until
remainder
becomes 0. - Inside the loop, it updates
last_remainder
,remainder
,x
,last_x
,y
, andlast_y
based on the current values and the result of dividinglast_remainder
byremainder
. - Finally, it returns the GCD (
last_remainder
) and the value oflast_x
, which is a Bézout coefficient representing the multiplicative inverse ofa
modulob
.
- This function takes two integers,
-
invmod
:- This function takes two integers,
e
andet
, and computes the modular inverse ofe
moduloet
using the extended Euclidean algorithm. - It calls
extended_gcd
to find the GCD and the multiplicative inverse (x
). - It checks if the GCD is not equal to 1, which means
e
andet
are not coprime (have a GCD greater than 1), and raises an exception in that case. - If the GCD is 1, it returns the modular inverse (
x
) moduloet
.
- This function takes two integers,
-
modinv
:- This function takes two integers,
a
andm
, and computes the modular inverse ofa
modulom
. - It first checks if
a
andm
are coprime (have a GCD of 1) and raises an exception if they are not. - If they are coprime, it initializes
m0
,inv
, andx0
tom
, 1, and 0, respectively. - It then enters a loop that iterates while
a
is greater than 1. - Inside the loop, it updates
inv
,a
,m
,inv
, andx0
based on the current values and the result of dividinga
bym
. - Finally, it adjusts
inv
if it is negative and returns the modular inverse.
- This function takes two integers,
-
require 'openssl'
:- This line imports the OpenSSL library, which provides cryptographic functions in Ruby.
-
OpenSSL::BN.new(42).mod_inverse(2017).to_i
:- This line demonstrates the use of the OpenSSL library to perform modular exponentiation.
- It creates a new
BN
(Bignum) object with the value 42, computes the modular inverse of 42 modulo 2017 using themod_inverse
method, and converts the result to an integer using theto_i
method.
Source code in the ruby programming language
#based on pseudo code from http://en.wikipedia.org/wiki/Extended_Euclidean_algorithm#Iterative_method_2 and from translating the python implementation.
def extended_gcd(a, b)
last_remainder, remainder = a.abs, b.abs
x, last_x, y, last_y = 0, 1, 1, 0
while remainder != 0
last_remainder, (quotient, remainder) = remainder, last_remainder.divmod(remainder)
x, last_x = last_x - quotient*x, x
y, last_y = last_y - quotient*y, y
end
return last_remainder, last_x * (a < 0 ? -1 : 1)
end
def invmod(e, et)
g, x = extended_gcd(e, et)
if g != 1
raise 'The maths are broken!'
end
x % et
end
def modinv(a, m) # compute a^-1 mod m if possible
raise "NO INVERSE - #{a} and #{m} not coprime" unless a.gcd(m) == 1
return m if m == 1
m0, inv, x0 = m, 1, 0
while a > 1
inv -= (a / m) * x0
a, m = m, a % m
inv, x0 = x0, inv
end
inv += m0 if inv < 0
inv
end
require 'openssl'
p OpenSSL::BN.new(42).mod_inverse(2017).to_i
You may also check:How to resolve the algorithm Left factorials step by step in the ALGOL 68 programming language
You may also check:How to resolve the algorithm Vampire number step by step in the FreeBASIC programming language
You may also check:How to resolve the algorithm List rooted trees step by step in the Ruby programming language
You may also check:How to resolve the algorithm Jaro-Winkler distance step by step in the ALGOL 68 programming language
You may also check:How to resolve the algorithm Exponentiation order step by step in the Raku programming language