 
 and
 and  be integers, and
 be integers, and  a nonnegative integer.
In this section we describe an efficient algorithm to compute
 a nonnegative integer.
In this section we describe an efficient algorithm to compute
 .  For the cryptography 
applications in Chapter 3,
.  For the cryptography 
applications in Chapter 3,  will have 
hundreds of digits.
 will have 
hundreds of digits.
The naive approach to computing 
 is to simply compute
 is to simply compute
 by repeatedly multiplying by
 by repeatedly multiplying by  and
reducing modulo
 and
reducing modulo  . Note that after each arithmetic operation is
completed, we reduce the result modulo
. Note that after each arithmetic operation is
completed, we reduce the result modulo  so that the sizes of the
numbers involved do not get too large.  Nonetheless, this algorithm is
horribly inefficient because it takes
 so that the sizes of the
numbers involved do not get too large.  Nonetheless, this algorithm is
horribly inefficient because it takes  multiplications, which 
is huge if
 multiplications, which 
is huge if  has hundreds of digits.
 has hundreds of digits.
A much more efficient algorithm for computing 
 involves
writing
 involves
writing  in binary, then expressing
 in binary, then expressing  as a product of
expressions
 as a product of
expressions  , for various
, for various  .  These latter expressions can
be computed by repeatedly squaring
.  These latter expressions can
be computed by repeatedly squaring  .  This more clever algorithm
is not ``simpler'', but it is vastly more efficient since the number
of operations needed grows with the number of binary digits of
.  This more clever algorithm
is not ``simpler'', but it is vastly more efficient since the number
of operations needed grows with the number of binary digits of  , whereas
with the naive algorithm above the number of operations is
, whereas
with the naive algorithm above the number of operations is  .
.
 be a nonnegative integer.  This algorithm writes
 be a nonnegative integer.  This algorithm writes  in
binary, so it finds
 in
binary, so it finds 
 such that
 such that
 with each
 with each 
 .
.
 .
.
 , terminate.
, terminate.
 is odd, set
 is odd, set 
 , otherwise
, otherwise 
 .
Increment
.
Increment  .
.
 ]  
Set
]  
Set 
 , the
greatest integer
, the
greatest integer  .  Goto step 2.
.  Goto step 2.
sage: 100.str(2) '1100100'Notice the above is the correct binary expansion:
sage: 0*2^0 + 0*2^1 + 1*2^2 + 0*2^3 + 0*2^4 + 1*2^5 + 1*2^6 100
 and
 and  be integers and
 be integers and  a nonnegative integer.
This algorithm computes
 a nonnegative integer.
This algorithm computes  modulo
 modulo  .
.
 in binary using Algorithm 2.3.11, so
 in binary using Algorithm 2.3.11, so
 
 ,
,   ,
, 
 ,
, 
 , etc., up
to
, etc., up
to  , where
, where  is the number of binary
digits of
 is the number of binary
digits of  .
. 
 such that
 such that 
 , 
always working modulo
, 
always working modulo  .
.
 digits of
 digits of  , by
finding
, by
finding 
 . 
First, because
. 
First, because 
 , we have by
Theorem 2.1.19 that
, we have by
Theorem 2.1.19 that
 .
Because
.
Because  is multiplicative,
 is multiplicative,
 
Thus
 , hence
, hence
 
We now compute
 using the above algorithm.
First, write
 using the above algorithm.
First, write  in binary by repeatedly dividing by
 in binary by repeatedly dividing by  .
.
|  |  | |
|  |  | |
|  |  | |
|  |  | 
 , 
  which we check:
, 
  which we check:
 
Next, compute
 and output
 and output
        
 .
We have
.
We have 
|  |  | |
|  |  | |
|  |  | |
|  |  | 
 by working modulo
 by working modulo  and
 and  and using the Chinese Remainder Theorem. 
Finally,
and using the Chinese Remainder Theorem. 
Finally,
 
sage: Mod(7,100)^91 43We can also, of course, directly compute
 in
SAGE, though we would not want to do this by hand:
 in
SAGE, though we would not want to do this by hand:
sage: 7^91 80153343160247310515380886994816022539378033762994852007501964604841680190743
William 2007-06-01