In this lesson, we will try to solve a
very famous problem in the number theory
that forms the basis of some of the most
famous
algorithms in cryptography and the
problem is to calculate
modular exponentiation. Now in a previous
lesoson,
we had seen or devised an algorithm
and efficient algorithm for
exponentiation,
which was calculating X to the power N
for two variables X and N.
Modular exponentiation is the remainder
upon dividing X to the power N with
another variable another positive number
M. So X,
N and M are three positive numbers here and
we want to calculate
X to the power N mod M. So let's pick
up some example, let's say is equal to 5
and N is equal 2 and we
want to
take a modulo by 7
so M is equal to 7.
So this will be equal to 25 and we can
also use this particular sign that we use
in a programming language for modulo and
it will be equal to
4, the remainder upon dividing 25 by
seven
is 4. Similarly if we want to calculate
5 to power 3 modulo 7, it will be equal
to 125 modulo 7 which will be
equal to 6. So one simplest approach is that
we can first
calculate X to the power N and then take
a mod
by M but there is a practical problem here.
Even for small values of X
and N, X to the power N can be
really really large and it may not fit
in
a data type of the language. For example
integer is often
stored in 32 bits and
one bit is for the presenting the sign
so the value ranges from -2 to the power 31
to 2 to the power 31.
So if you want to calculate if we want
to calculate
2 to the power 100 say then it will not fit
in an
integer variable. We can have a variable
like long or double
that stores higher values but still they
will not be good enough to store
X to power N
even for some moderately high values of
X and N.
Now we want to calculate X to the power N
mod M.
Let's see what we can do here.
Fortunately,
all these laws of associativity, commutativity
and distributivity
that apply to normal arithmetic, also apply
to modular arithmetic.
So for example A into B modulo M
is equal to A modulo M
into B modulo M and
an overall modulo M for this
particular expression.
So for example if we want to
calculate say
5 into 7 modulo 3 then
it is simply simply equal to 35
modulo 3,
So upon dividing 35 modulo 3
the remainder would be 2. Now let's
try to solve this using the expression
in the right hand side,
so this will be equal to 5 modulo 3
into 7 modulo 3 and
and overall modulo 3.
So 5 modulo 3 is 2 and 7 modulo 3 is
4 so this will be 4 into 2 modulo 3
which is 8 modulo 3 and again this
is equal to
2, and you can pick up some other values
of
A and B validate that this is true. Now
here, We can write X to the power N
as X into X to power N - 1,
so this a overall expression would be X
into X to the power N - 1 modulo M.
So we can also write this as
X modulo M, so here A is X and B
is X to power N - 1 into X to the power N
- 1 modulo M
and an overall modulo M and I'll
clear some of this calculation
in the left. So again if
N is even then we can write X to the power N
as X to the power N by 2 into
X to the power N by 2. So this
expression can also reduce to
X to the power N by 2 modulo M into
X to the power N by 2 modulo M
and an overall modulo M.
So we have a recurrence relation here
once again,
so I can write, i'll write this
in a little neat manner, X to the power N
modulo M
is equal X to the power N by 2 modulo M 
into X to the power N by 2 modulo M
overall modulo M if N is
even.
it is equal to X modulo M into
X to the power N - 1
overall modulo M if N is odd
and it is simply equal to 1
for N is equal to 0.
Now this reccurence relation is very similar
to what we had
used to calculate X to the power N
in previous lesson
so N is equal to zero is our base-case
and for N even and N odd 
we have two different reccurence relations.
Now let's write a program function to
implement this recursion. Let's say
we write a method
mod takes its argument
X, N and M
and it goes like this. If N is zero
simply return one else
if N is even which is the same as
saying N modulo 2 is zero
then first calculate  X to the power N by 2
modulo M
so we make a recursive call to calculate X
to power N by 2
modulo M and then we return
Y into Y modulo M. Once again
instead of writing these two
expressions, we could have written
mod of X to the power N by 2
sorry, X to the power N by 2 mod M into 
X to the power N by 2 mod M overall mod M
but in this case, we would
have unnecessarily
make two recursive calls us
calculate be would have unnecessarily
calculate
same value twice which is the bad.
So we calculate X to the power N by 2
mod M once
and store it in a variable and then
return
Y into Y modulo M, where Y stores this value.
Now if N is
odd then in that case we simply
return
X modulo M into
X to power N - 1 modulo M which is
calculated by
this recursive call and an overall
modulo M.
So this gives us recursive algorithm
to calculate
X to the power N modulo M and
this algorithm
to calculate modular exponentiation is
very similar to
the previous algorithm that we had
shown to calculate X to the power
N in our previous lesson. The time
complexity for this algorithm is
order of log n or O(logn)
We will try to deduce that how this time
complexity is 
is order of log n in another lesson.
But nevertheless, log n time complexity is the best time
complexity to have.
So, thanks for watching.
