MTH 225 Lecture-Module #11:
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?

another e.g. for 8 multiplicative inverse is  and

generally,  x * <multiplicative_inverse_of_x> := 1

anyway, mathematicians playing with numbers taken modulo a prime value f
noticed that such numbers can do all arithmetic operations including multiplicative inverse
e.g. when f is 7:
first, what are all the numbers modulo 7?
i.e. what are all the possible values of x mod 7?
{}
well it turns out that we can do all arithmetic using only those numbers as follows:
e.g.  5 + 4 :=  :=   (mod 7)
    which is written as "5 + 4 ≡ 2  (mod 7)"
    or maybe as "5 + 4 ≅ 2  (mod 7)"
e.g.  6 + 1 :=  :=   (mod 7)
    which is written as "6 + 1 ≡ 0  (mod 7)"
    or maybe as "6 + 1 ≅ 0  (mod 7)"
e.g.  1 - 4 :=  :=   (mod 7)
    which is written as "2 - 4 ≡ 5  (mod 7)"
    or maybe as "2 - 4 ≅ 5  (mod 7)"
e.g.  2 - 3 :=  :=   (mod 7)
    which is written as . . .
e.g.  5 * 2 :=  :=   (mod 7)
    which is written as "5 * 2 ≡ 3  (mod 7)"
    or maybe as "5 * 2 ≅ 3  (mod 7)"
e.g.  3 * 4 :=  :=   (mod 7)
    . . .
e.g.  6 * 3 :=  :=   (mod 7)
could do a multiplication table, as follows:
    * (mod 7) | 0 1 2 3 4 5 6
    ----------+--------------
            0 | 0 0 0 0 0 0 0
            1 | 0 1 2 3 4 5 6
            2 | 0 2 4 6 1 3 5
            3 | 0 3 6 2 5 1 4
            4 | 0 4 1 5 2 6 3
            5 | 0 5 3 1 6 4 2
            6 | 0 6 5 4 3 2 1
see below for division; before that here actually multiplicative inverses:
for each value x other than 0, need a multiplicative inverse value (x-1)
so that  x * <multiplicative_inverse_of_x> := 1  (mod 7)
    i.e.  x * x-1 := 1  (mod 7) :
e.g.  5 *  :=  := 1  (mod 7)
    thus  5-1 :=   (mod 7)
    and by the way  3-1 :=   (mod 7)
e.g.  2 *  :=  := 1  (mod 7)
    thus  2-1 :=   (mod 7)
    and by the way  4-1 :=   (mod 7)
e.g.  6 *  :=  := 1  (mod 7)
    thus . . .
e.g.  1 *  := 1  (mod 7)

continuing with general arithmetic  (mod 7),
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 can achieve division  x/y (mod f)  by
remembering  x/y == x * 1/y  i.e.  x * y-1
e.g.   2/5  :=  2 * 5-1  :=  2 *   :=    (mod 7)
e.g.   6/4  :=  6 * 4-1  :=  6 *   :=    :=    (mod 7)
e.g.   3/3  :=  3 * 3-1  :=  3 *   :=    :=    (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  is relatively prime to  f  (and  0 < e < 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:
    
        while ( x != 0 ) {
            
            int x_next = y % x,  y_next = x;
            x = x_next;
            y = y_next;
            }
        
        }
e.g. trace invocation of  multiplicative_inverse_of_e_mod_f(5,9) :
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    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    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    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 5 (mod 9)

e.g. trace invocation of  multiplicative_inverse_of_e_mod_f(3,7) :
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    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    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 3 (mod 7)



intriguing observation:
if m := p·q where p and q are distinct 
and d is a multiplicative inverse of e (mod f)
    where f is φ(m) which is 
    (I didn't say in the preceding lecture module,
    but there is a formula for φ()),
then generally for each integer a (less than m),
(ae)d mod m  :=  
e.g. if p is 3 and q is 11, then m := 
    and  f := φ(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. encoding "GVSU" yields ""
(I have seen "GVSU" used as a password in some systems here!)
e.g. "HELPME" yields ""
decode by reversing...
e.g. decoding "JRQRZ" returns ""
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 (page 480 of) 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 multiplicative inverses (mod f) is
denoted  (initials of inventors Rivest, Shamir, Adleman)

addresses an issue of preceding schemes:
though encrypted message "JYVX" or "KSCS" 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 distinct 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 := 0708  i.e. 708
sender transmits  Me mod m
(sender doesn't need to know any further key information such as p,q)
e.g. suppose e is 91 and m is 10001
then sender would transmit  70891 mod 10001  which is 
    calculated via 
eavesdropper can see this value 2419 being transmitted
but cannot determine real message value (0708) from that

receiver receives this value 2419 (which is  Me mod m)
how can receiver extract original message value M from that???
well, receiver secretly knows m := 10001 :=  · 
    thus the distinct primes p and q are 73 and 137
and from mathematicians such as Fermat and Euler,
(Me mod m)d mod m :=   if d is multiplicative inverse of e (mod f)
where  f := φ(m) := (p-1)·(q-1) := · :=   here
to obtain d, invoke  multiplicative_inverse_of_e_mod_f(91, 9792)
yielding d := 
so receiver calculates  (Me mod m)d mod m := 24194627 mod 10001 := 
    using 

Alice and Bob


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