MTH 225 Lecture-Module #12:
Applications of Divisors


first some background (reviewing material which may be more basic):
basic arithmetic operations are addition, subtraction, multiplication, division
how about "multiplicative inverse" "x-1 "?
what does that mean?
e.g. what is multiplicative inverse of 5? 
how is that value relevant to 5? i.e. what can you do with 5 and that value?

and similarly for e.g. 8, right(?):

generally,  x * <multiplicative inverse of x> := 1

well, mathematicians playing with numbers taken modulo a prime value f
noticed that such numbers can do all arithmetic operations including multiplicative inverse
e.g. if f is 7:
numbers modulo 7 are only  {}
5 + 4 :=  (mod 7)
6 + 1 :=  (mod 7)
2 - 4 :=  (mod 7)
1 - 2 :=  (mod 7)
3*4 :=  (mod 7)
5*2 :=  (mod 7)
see below for division; before that here actually multiplicative inverses:
for each value x other than 0, need a multiplicative inverse value
so that  x * <multiplicative inverse of x> := 1 (mod 7):
5 *  := 1 (mod 7)
2 *  := 1 (mod 7)
6 *  := 1 (mod 7)
1 *  := 1 (mod 7)
then regarding division, at first glance it might be unclear what to do
e.g. for  2/5 (mod 7), what might be  0.4 mod 7??!?
but achieve division  x/y mod f  by doing  x * y-1 mod f
e.g.  2/5  :=  2 * 5-1  :=  2 *   :=   (mod 7)

if f isn't prime, most of those operations still work (mod f)
except multiplicative inverses available only for values that are relatively prime to f
e.g. if f is 9:
5 *  := 1 (mod 9)
4 *  := 1 (mod 9)
8 *  := 1 (mod 9)
3 *  := 1 (mod 9)
6 *  := 1 (mod 9)

'cute' trick:
if  e > 0  and e is relatively prime to  f
can use Euclidean algorithm (code) — with some additional processing —
to return value d which will be multiplicative inverse of e (mod f)
as follows:
    int multiplicative_inverse_of_e_mod_f(int e, int f) {
        
        while ( x != 0 ) {
            
            int x_next = y % x, y_next = x;
            x = x_next;
            y = y_next;
            }
        assert  y == 1;     // otherwise not obtaining multiplicative inverse
        return  z <= 0  ?  z + f  :  z;
        }
e.g. trace invocation of  multiplicative_inverse_of_e_mod_f(7,20) :
int multiplicative_inverse_of_e_mod_f(int e ,   int f )   {               
    assert  e > 0 ;                      x    y    q  z_prev  z
    int x = e, y = f;                              q  z_prev  z
    int q = 0, z_prev = 1, z = 0;             x    y          
    while ( x != 0    ) {                x    y    q  z_prev  z
        int z_next = z_prev - q*z             x    y    q  z_prev  z
                         - *            x    y    q  z_prev  z
                                  x    y    q  z_prev  z
        z_prev = z;                           x    y    q        z
        z = z_next;                           x    y    q  z_prev 
        q = y/x;                              x    y     z_prev  z
        int x_next = y % x, y_next = x;       x    y    q  z_prev  z
                                          x    y    q  z_prev  z
        x = x_next;                              y    q  z_prev  z
        y = y_next;                           x       q  z_prev  z
        }                                     x    y    q  z_prev  z
    while ( x != 0   ) {                 x    y    q  z_prev  z
        int z_next = z_prev - q*z             x    y    q  z_prev  z
                         - *            x    y    q  z_prev  z
                                  x    y    q  z_prev  z
        z_prev = z;                           x    y    q        z
        z = z_next;                           x    y    q  z_prev 
        q = y/x;                              x    y     z_prev  z
        int x_next = y % x, y_next = x;       x    y    q  z_prev  z
                                          x    y    q  z_prev  z
        x = x_next;                              y    q  z_prev  z
        y = y_next;                           x       q  z_prev  z
        }                                     x    y    q  z_prev  z
    while ( x != 0   ) {                 x    y    q  z_prev  z
        int z_next = z_prev - q*z             x    y    q  z_prev  z
                         - *           x    y    q  z_prev  z
                                 x    y    q  z_prev  z
        z_prev = z;                           x    y    q       z
        z = z_next;                           x    y    q  z_prev 
        q = y/x;                              x    y     z_prev  z
        int x_next = y % x, y_next = x;       x    y    q  z_prev  z
                                          x    y    q  z_prev  z
        x = x_next;                              y    q  z_prev  z
        y = y_next;                           x       q  z_prev  z
        }                                     x    y    q  z_prev  z
    while ( x != 0   )                  x    y    q  z_prev  z
    assert  y == 1   ;                   x    y    q  z_prev  z
    return  z <= 0  ?  z + f  :  z;           x    y    q  z_prev  z
                                      x    y    q  z_prev  z
    }
returns  which is indeed multiplicative inverse of 7 mod 20:
d*7 := 1 (mod 20) :


e.g. trace invocation of  multiplicative_inverse_of_e_mod_f(13,20) :
int multiplicative_inverse_of_e_mod_f(int e ,   int f )   {               
    assert  e > 0 ;                      x    y    q  z_prev  z
    int x = e, y = f;                             q  z_prev  z
    int q = 0, z_prev = 1, z = 0;             x    y          
    while ( x != 0    ) {                x    y    q  z_prev  z
        int z_next = z_prev - q*z             x    y    q  z_prev  z
                         - *            x    y    q  z_prev  z
                                 x    y    q  z_prev  z
        z_prev = z;                           x    y    q        z
        z = z_next;                           x    y    q  z_prev 
        q = y/x;                              x    y     z_prev  z
        int x_next = y % x, y_next = x;       x    y    q  z_prev  z
                                         x    y    q  z_prev  z
        x = x_next;                              y    q  z_prev  z
        y = y_next;                           x      q  z_prev  z
        }                                     x    y    q  z_prev  z
    while ( x != 0   ) {                 x    y    q  z_prev  z
        int z_next = z_prev - q*z             x    y    q  z_prev  z
                         - *            x    y    q  z_prev  z
                                  x    y    q  z_prev  z
        z_prev = z;                           x    y    q        z
        z = z_next;                           x    y    q  z_prev 
        q = y/x;                              x    y     z_prev  z
        int x_next = y % x, y_next = x;       x    y    q  z_prev  z
                                          x    y    q  z_prev  z
        x = x_next;                              y    q  z_prev  z
        y = y_next;                           x       q  z_prev  z
        }                                     x    y    q  z_prev  z
    while ( x != 0   ) {                 x    y    q  z_prev  z
        int z_next = z_prev - q*z             x    y    q  z_prev  z
                         - *           x    y    q  z_prev  z
                                 x    y    q  z_prev  z
        z_prev = z;                           x    y    q       z
        z = z_next;                           x    y    q  z_prev 
        q = y/x;                              x    y     z_prev  z
        int x_next = y % x, y_next = x;       x    y    q  z_prev  z
                                          x    y    q  z_prev  z
        x = x_next;                              y    q  z_prev  z
        y = y_next;                           x       q  z_prev  z
        }                                     x    y    q  z_prev  z
    while ( x != 0   ) {                 x    y    q  z_prev  z
        int z_next = z_prev - q*z             x    y    q  z_prev  z
                        - *            x    y    q  z_prev  z
                                 x    y    q  z_prev  z
        z_prev = z;                           x    y    q        z
        z = z_next;                           x    y    q  z_prev 
        q = y/x;                              x    y     z_prev  z
        int x_next = y % x, y_next = x;       x    y    q  z_prev  z
                                          x    y    q  z_prev  z
        x = x_next;                              y    q  z_prev  z
        y = y_next;                           x       q  z_prev  z
        }                                     x    y    q  z_prev  z
    while ( x != 0   )                  x    y    q  z_prev  z
    assert  y == 1   ;                   x    y    q  z_prev  z
    return  z <= 0  ?  z + f  :  z;           x    y    q  z_prev  z
                                 x    y    q  z_prev  z
                                      x    y    q  z_prev  z
    }
returns  which is indeed multiplicative inverse of 13 mod 20
d*13 := 1 (mod 20) :




intriguing observation:
if m := p*q where p and q are distinct 
and d is an  of e modulo φ(m)
    where φ(m) is ,
then generally for each integer a (less than m),
(ae)d mod m  =  a
e.g. if p:=3 and q:=11, then m :=  and  φ(m) := (p-1)*(q-1) := 
consider various values of e, ..., a
...
another e.g. p=, q=
consider various values of e, ..., a
...
justification: 




application:
messages such as Web-form submissions containing your
credit-card number, password, etc.
sent encrypted so hostile monitors reading network traffic
can't clearly see the data desired secret

ancient code simply use substitute letters
e.g. Caesar cipher:
  'A'→''
  'B'→''
  'C'→''
  'D'→''
  'E'→''
     ·
     ·
     ·
  'V'→''
  'W'→''
  'X'→''
  'Y'→''
  'Z'→''
e.g. "GVSU"→
(I have seen "GVSU" used as a password in some systems here!)
e.g. "HELPME"→
decode by reversing...
alternatively, mix things around,
e.g. 'A'→'R', 'B'→'D', 'C'→'M', ...
but regular or irregular, such a simple mapping scheme vulnerable to attack by:


different e.g.:
#!/usr/bin/perl -s
$f=$d?-1:1;$D=pack('C*',33..86);$p=shift;
$p=~y/a-z/A-Z/;$U='$D=~s/(.*)U$/U$1/;
$D=~s/U(.)/$1U/;';($V=$U)=~s/U/V/g;
$p=~s/[A-Z]/$k=ord($&)-64,&e/eg;$k=0;
while(<>){y/a-z/A-Z/;y/A-Z//dc;$o.=$_}$o.='X'
while length ($o)%5&&!$d;
$o=~s/./chr(($f*&e+ord($&)-13)%26+65)/eg;
$o=~s/X*$// if $d;$o=~s/.{5}/$& /g;
print"$o\n";sub v{$v=ord(substr($D,$_[0]))-32;
$v>53?53:$v}
sub w{$D=~s/(.{$_[0]})(.*)(.)/$2$1$3/}
sub e{eval"$U$V$V";$D=~s/(.*)([UV].*[UV])(.*)/$3$2$1/;
&w(&v(53));$k?(&w($k)):($c=&v(&v(0)),$c>52?&e:$c)}
The above code (pun intended! ;-) is from the book "Cryptonomicon", by Neal Stephenson.
That novel focuses on cryptography and other computer technology
which has been significant since World War II.
(You should understand all of the book after enough CS courses —
perhaps just through CS 251.
But you might appreciate the book even before you might complete such background.)
e.g.  "GVSU" → 


anyway, scheme using modular inverses is
denoted  (initials of inventors Rivest, Shamir, Adleman)

addresses an issue of preceding schemes:
though encrypted message  or  appears generally unintelligible,
eavesdropper could decrypt if knew scheme
and how could sender and receiver settle on scheme without eavesdropper learning?
in RSA scheme, some key information actually publicized
but eavesdropper still can't decrypt
called "public key cryptography"

the public information is e,m
e is somewhat arbitrary
receiver secretly knows m is p*q, where p and q are primes
even with m public, it's so far intractable for eavesdropper to factor m into p*q
e.g. for m =
254,435,922,729,433,783,405,728,309,074,724,768,038,518,155,
936,028,207,753,730,966,939,742,326,668,263,973,141,761,832,
178,367,619,452,096,404,235,502,133,896,576,209,664,966,728,
171,902,108,730,007,838,696,298,581

anyway sender represents (each segment of) message as number M
e.g. "HI" represented as  M = 0910
sender transmits  Me mod m
(sender doesn't need to know any further key information such as p,q)
e.g. suppose e is 37 and m is 10807
then sender would transmit  091037 mod 10807  which is 
    calculated via 
eavesdropper can see this value 9899 being transmitted
but cannot determine real message-value (0910) from that

receiver receives this value 9899 (which is  Me mod 10807)
how can receiver extract original message-value M from that???
well, receiver secretly knows m=10807 factors as (p)*(q)
and from mathematicians such as Fermat and Euler,
(Me)d mod m = M  if d is inverse of e modulo φ(m)
    where φ(m) or just φ := (p - 1)*(q - 1) 
for e=37, its inverse modulo φ=10600 is d=
    which is calculated as presented above using  gcd_st(φ, e)
so receiver calculates  ((Me))573 mod m = 
    using 


(Copyright © 2009 by Hugh McGuire   — for thoughts about this, see   http://www.cis.gvsu.edu/~mcguire/teaching/copyright_thoughts.html .)