cwave.eu5.org
Also see: http://www.angelfire.com/dragon/letstry
cwave04 at yahoo dot com
Free Guestbook
My Guestbook

Last updated on Fri May 21 11:50:24 IST 2010.

Modular exponentiation

We shall now learn how to compute ab (mod m) where a, b and m are given numbers. The main problem is as for modular multiplication: we cannot compute ab directly as it might be too large.

We have already learned from modular multiplication that we should break the problem into steps, and perform modul reduction after each step. This prevents the numbers from growing too much. The question is: How to break up the computation of ab into steps.

A simple way to compute ab step by step is to compute a, a2, a3 and so on, performing modular reduction at each step. This works, but if b is too large (say, 100 digits) this will take l...o...n...g!!!

We shall now learn another way to break the problem into steps. For this we start by expressing the number b in binary. Let the bits of b be
bk-1, bk-2, ..., b1, b0.

Example: If b=53 we shall write (using k=8 bits, say)
b = (00110101)2.
Thus here

b0 = 1
b1 = 0
b2 = 1
b3 = 0
b4 = 1
b5 = 1
b6 = 0
b7 = 0

Then
b = b0 20 + ..., + bk-1 2k-1,
and so
ab = (c0)b0 (c1)b0 ... (ck-1)bk-1.
where
ci = a2i.
Observe that
c0 = a
and
ci = ci-1 2
We shall perform all the computation modulo m.

Example: Taking a=3 we comoute ci's as follows (with k=8 and m=6254):

c0 = 3
c1 = 9
c2 = 81
c3 = 307
c4 = 439
c5 = 5101
c6 = 3561
c7 = 3863
c8 = 725

Now observe that the product in (**) is basically the product of those ci's for which bi's are 1.

Example: In our example, b0 = b2 = b4 = b5 = 1. So we need to form the product
c0 c2 c4 c5 (mod m).

c0 c2           = 3 * 81     = 243
(c0 c2) c4     = 243 * 439  = 359
(c0 c2 c4) c5 = 359 * 5101 = 5091

Thus we finally see that
353 = 5091 (mod 6254).

Let us package this as a C function that we can use later:

unsigned int modExpo(unsigned int a, unsigned int b, unsigned int m) {
  unsigned int ans, ci;

  ci = a % m;
  ans = 1;
  for(i=0;i<k;i++) {
    ci = modMult(ci, ci, m);
    if((b & (1<<i)) != 0) {
      ans = modMult(ans, ci, m);
    }
  }  

  return ans;
}

Testing

Here is a complete C program ready to be compiled and run:

#include <stdio.h>
int k = 32;
unsigned int modMult(unsigned int a, unsigned int b, unsigned int m) {
  unsigned int ans, ci;

  di = a % m;
  ans = 0;
  for(i=0;i<k;i++) {
    di = (ci << 1) % m;
    if((b & (1<<i)) != 0) {
      ans = ans + di;
    }
  }  

  return ans;
}
unsigned int modExpo(unsigned int a, unsigned int b, unsigned int m) {
  unsigned int ans, ci;

  ci = a % m;
  ans = 1;
  for(i=0;i<k;i++) {
    ci = modMult(ci, ci, m);
    if((b & (1<<i)) != 0) {
      ans = modMult(ans, ci, m);
    }
  }  

  return ans;
}

main() {
  unsigned int y;

  y = modExpo(3,53,6254);
  printf("3 to the power 53 = %u mod 6254.\n",y);
} 

Where do we stand?

In this and the last page we have learned how to perform modular multiplication and modular exponentiation. These are important building blocks in many cryptosystems, including RSA.

We shall not extend these algorithms any further. In the next page we shall learn how to compute gcd of two numbers using the Extended Euclidean Algorithm. This algorithm has nothing to do with modular multiplication or exponentiation.

PrevNext
© Arnab Chakraborty (2010)