<?xml version="1.0" encoding="UTF-8"?>
<Worksheet><Version major="6" minor="1"/><View-Properties><Zoom percentage="150"/></View-Properties><Styles><Layout alignment="left" bullet="none" linespacing="0.0" name="Heading 2" spaceabove="8.0" spacebelow="2.0"/><Layout alignment="left" bullet="none" linespacing="0.0" name="Heading 1" spaceabove="8.0" spacebelow="4.0"/><Layout alignment="left" bullet="none" firstindent="0.0" leftmargin="0.0" linebreak="space" linespacing="0.0" name="Normal" rightmargin="0.0" spaceabove="0.0" spacebelow="0.0"/><Font background="[0,0,0]" bold="true" executable="true" family="Monospaced" foreground="[255,0,0]" name="Maple Input" opaque="false" size="12"/><Font background="[0,0,0]" bold="false" executable="false" family="Times New Roman" foreground="[0,0,0]" italic="false" name="Text" opaque="false" size="12" underline="false"/><Font background="[0,0,0]" bold="true" family="Serif" name="Heading 2" opaque="false" size="16"/><Font background="[0,0,0]" bold="true" family="Serif" name="Heading 1" opaque="false" size="18"/></Styles><Group><Input><Text-field alignment="centred" firstindent="0.0" layout="Heading 1" leftmargin="0.0" linebreak="space" rightmargin="0.0" style="Heading 1"><Font executable="false" foreground="[0,0,0]" italic="false" underline="false">RSA Cryptography</Font></Text-field><Text-field alignment="centred" firstindent="0.0" layout="Heading 1" leftmargin="0.0" linebreak="space" rightmargin="0.0" style="Heading 1"><Font bold="false" italic="true" size="12">John Hutchinson</Font></Text-field></Input></Group><Group><Input><Text-field layout="Normal" prompt="&gt; " style="Maple Input">restart;</Text-field></Input></Group><Section><Title><Text-field layout="Heading 1" style="Heading 1">Translating Between Messages and Numbers</Text-field></Title><Group><Input><Text-field layout="Normal" style="Text">Here are two functions <Font bold="true" foreground="[255,0,0]">message_to_number</Font> and <Font bold="true" foreground="[255,0,0]">number_to_message</Font> which convert messages to numbers and conversely.  The letters {a, b, ... , z } are replaced by {10, 11, ... , 35}, {A, B, ... , Z } by {36, 37, ... , 61}, {0, 1, ... , 9 } by {62, 63, ... , 71}, and the characters { ,  .  ;  :  -  / "space" } by {72, 73, 74, 75, 76, 77, 78 } respectively.  (If the input number does not correspond to a message then an error message is given.)</Text-field><Text-field layout="Normal" style="Text"><Font italic="true">Ignore the code describing these two functions.</Font> </Text-field></Input></Group><Group><Input><Text-field layout="Normal" prompt="&gt; " style="Maple Input">message_to_number := proc(message)
local message_bytes, message_numlist, length_of_message, number_string :
     # We first use the ASCII coding
message_bytes:= convert(message,bytes): 
     # We next convert to a simpler but more restricted translation 
     # as described above, using 2 digits rather than 3. 
message_numlist := map(proc(x) if (97&lt;=x and x&lt;=122) then x-87 elif (65&lt;=x and x&lt;=90) then x-29 elif (48&lt;=x and x&lt;=57) then x+14 elif x=44 then 72 elif x=46 then 73 elif x=59 then 74 elif x=58 then 75 elif x=45 then 76 elif x=47 then 77 elif x=32 then 78 end if end proc , message_bytes ):
length_of_message := nops(message_numlist):
     # The sequence of 2 digit numbers is next concatenated  
number_string := cat(seq(message_numlist[i],i=1..length_of_message)):
     #  And finally turned into an integer 
convert(number_string,decimal,10):
end:
</Text-field></Input></Group><Group><Input><Text-field layout="Normal" prompt="&gt; " style="Maple Input">number_to_message := proc(number)
local message_length, number_string, message_string, message_numlist, message_bytes, i :
message_length := length(number)/2 :
     #  The number is first converted into a string of digits
number_string := convert(number,string) :
     #  And then into a vector of numbers between 10 and 99   
message_string := linalg[vector](message_length):
for i from 1 to message_length do
message_string[i] := convert(substring(number_string,2*i-1..2*i), decimal, 10);
od:
     #  And then into a list of numbers
message_numlist := convert(message_string,list):
     #  And then into standard ASCII coding
message_bytes := map(proc(x) if (10&lt;=x and x&lt;=35) then x+87 elif (36&lt;=x and x&lt;=61) then x+29 elif (62&lt;=x and x&lt;=71) then x-14 elif x=72 then 44 elif x=73 then 46 elif x=74 then 59 elif x=75 then 58 elif x=76 then 45 elif x=77 then 47 elif x=78 then 32 else "*" end if end proc , message_numlist) :
     #  And then into standard ASCII characters
convert(message_bytes,bytes) :
end:</Text-field></Input></Group><Group><Input><Text-field alignment="left" firstindent="0.0" leftmargin="0.0" linebreak="space" linespacing="0.0" prompt="&gt; " rightmargin="0.0" spaceabove="0.0" spacebelow="0.0"><Font italic="false" style="Maple Input" underline="false">message := "Beware the Ides of March, 15/3/07";</Font></Text-field></Input></Group><Group><Input><Text-field layout="Normal" prompt="&gt; " style="Maple Input">number := message_to_number(message);</Text-field></Input></Group><Group><Input><Text-field layout="Normal" prompt="&gt; " style="Maple Input">message := number_to_message(number);</Text-field></Input></Group></Section><Section><Title><Text-field layout="Heading 2" style="Heading 2">Finding Your Public "(n, e)" and Your Private Key "d" </Text-field></Title><Group><Input><Text-field layout="Normal" style="Text">Enter a random integer after "<Font bold="true" foreground="[255,0,0]">:=</Font>" , before  "<Font bold="true" foreground="[255,0,0]">;</Font>" and give it the name  "pp" .</Text-field><Text-field layout="Normal" style="Text">With 100 digits it will take over 100 million 5 GHz-Opteron-CPU years with current technology to crack your code.</Text-field><Text-field layout="Normal" style="Text">Each digit added (subtracted) increases (decreases) time to crack by a factor about 10. </Text-field><Text-field layout="Normal" style="Text">With 150 digits,  all the worlds current computers working in parallel for the lifetime of the universe will not crack your code.</Text-field><Text-field layout="Normal" prompt="&gt; " style="Maple Input">pp := 76398256649802838977659276645678008926455022098127;
length = length(pp);</Text-field></Input></Group><Group><Input><Text-field layout="Normal" style="Text">Find the first prime after pp, name it <Font bold="true" foreground="[255,0,51]">p</Font>.</Text-field><Text-field layout="Normal" prompt="&gt; " style="Maple Input">p := nextprime(pp);</Text-field></Input></Group><Group><Input><Text-field layout="Normal" style="Text">Enter a second random integer with about the same number of digits.    </Text-field><Text-field layout="Normal" prompt="&gt; " style="Maple Input">qq:= 49290864532859690887375854988876987997867279656298; 
length = length(qq);</Text-field></Input></Group><Group><Input><Text-field layout="Normal" style="Text">Find the first prime after qq,  name it <Font bold="true" foreground="[255,0,51]">q</Font>.</Text-field><Text-field layout="Normal" prompt="&gt; " style="Maple Input">q := nextprime(qq);</Text-field></Input></Group><Group><Input><Text-field layout="Normal" style="Text">Multiply <Font bold="true" foreground="[255,0,0]">p</Font> and <Font bold="true" foreground="[255,0,51]">q</Font> and call the result <Font bold="true" foreground="[255,0,51]">n</Font>.</Text-field><Text-field layout="Normal" prompt="&gt; " style="Maple Input">n := p*q;</Text-field></Input></Group><Group><Input><Text-field layout="Normal" style="Text">We now begin the calculation to find the <Font bold="true" italic="true">encryption</Font><Font italic="true"> </Font>exponent <Font bold="true" foreground="[255,0,51]">e</Font>, the second number in your public key.</Text-field><Text-field layout="Normal" prompt="&gt; " style="Maple Input">m := (p-1)*(q-1);</Text-field></Input></Group><Group><Input><Text-field layout="Normal" style="Text">Find <Font bold="true" foreground="[255,0,51]">e</Font> relatively prime to <Font bold="true" foreground="[255,0,0]">m</Font>.  </Text-field><Text-field layout="Normal" style="Text">We do this by successively testing 3, 4, 5, ... until we find<Font bold="true" foreground="[255,0,0]"> </Font>an integer which has no factor in common with <Font bold="true" foreground="[255,0,0]">m</Font>.</Text-field><Text-field layout="Normal" style="Text">The function <Font bold="true" foreground="[255,0,0]">igcd</Font> gives the (integer) greatest common divisor.</Text-field><Text-field layout="Normal" prompt="&gt; " style="Maple Input">e := 3 ; 'gcd' = igcd(m,e);
while igcd(m,e) &lt;&gt; 1 do 
e := e+1; 'gcd' = igcd(m,e);
od;   </Text-field></Input></Group><Group><Input><Text-field layout="Normal" style="Text">Find the multiplicative inverse of <Font bold="true" foreground="[255,0,51]">e</Font> mod <Font bold="true" foreground="[255,0,0]">m</Font>.</Text-field><Text-field layout="Normal" prompt="&gt; " style="Maple Input">d := 1/e mod m;</Text-field></Input></Group><Group><Input><Text-field layout="Normal" style="Text">You now have your<Font bold="true"> <Font foreground="[255,0,0]" italic="true">public key</Font><Font foreground="[255,0,51]"> (n,e)</Font> </Font>which you publish,<Font bold="true"> </Font>and your<Font bold="true"> <Font foreground="[255,0,51]" italic="true">private key</Font><Font foreground="[255,0,51]"> d</Font></Font><Font foreground="[255,0,51]">.</Font></Text-field></Input><Input><Text-field layout="Normal" prompt="&gt; " style="Maple Input">'(n,e)' = (n,e); 'd' = d;</Text-field></Input></Group></Section><Section><Title><Text-field layout="Heading 2" style="Heading 2">How Anyone Uses Your Public Key to Encode a Secret Message Only You can Decode</Text-field></Title><Group><Input><Text-field layout="Normal" style="Text">If someone has a secret message for you they first enter it into their computer. </Text-field><Text-field layout="Normal" style="Text">Only messages with small and capital letters, digits, { ,  .  ;  :  -  / "space" } work with this simple program.</Text-field><Text-field layout="Normal" prompt="&gt; " style="Maple Input">message := "The walk will be at 9am tomorrow." ;</Text-field></Input></Group><Group><Input><Text-field layout="Normal" style="Text">They then translate this secret message into a secret number <Font bold="true" foreground="[255,0,0]">W</Font> by replacing a by 10, b by 11, ... , A by 35, ..., etc. as before. </Text-field><Text-field layout="Normal" prompt="&gt; " style="Maple Input">W := message_to_number(message); </Text-field></Input></Group><Group><Input><Text-field layout="Normal" style="Text"><Font bold="true" foreground="[255,0,0]">W</Font> should be less than <Font bold="true" foreground="[255,0,51]">n</Font>.  
If <Font bold="true" foreground="[255,0,0]">W</Font> is less than <Font italic="true">half the length </Font>of <Font bold="true" foreground="[255,0,51]">n</Font> then for additional security it can be padded out at the beginning by random junk numbers.  We will not bother.  </Text-field><Text-field layout="Normal" style="Text">(Begin and end any junk with 99 and put random stuff in between which contains <Font italic="true">no</Font> 9's.  Then you will know after  later decoding where the junk begins and ends.) </Text-field><Text-field layout="Normal" prompt="&gt; " style="Maple Input">verify(W,n,less_than); 
verify(length(W),length(n)/2,greater_than) ;  </Text-field></Input></Group><Group><Input><Text-field layout="Normal" style="Text">They next find the coded number <Font bold="true" foreground="[255,0,0]">C</Font> from the secret number <Font bold="true" foreground="[255,0,0]">W </Font>by using your public key <Font bold="true" foreground="[255,0,0]">(n,e) </Font>to compute the remainder obtained after raising <Font bold="true" foreground="[255,0,0]">W </Font>to the power <Font bold="true" foreground="[255,0,0]">e</Font> and dividing by <Font bold="true" foreground="[255,0,0]">n</Font>.   </Text-field><Text-field layout="Normal" prompt="&gt; " style="Maple Input">C := W&amp;^e mod n;</Text-field></Input></Group><Group><Input><Text-field layout="Normal" style="Text">Finally, they publish the coded number <Font bold="true" foreground="[255,0,0]">C</Font>.</Text-field></Input></Group></Section><Section><Title><Text-field layout="Heading 2" style="Heading 2">How You Use Your Private Key to Decode the Coded Secret Message</Text-field></Title><Group><Input><Text-field layout="Normal" style="Text">You decode the coded number <Font bold="true" foreground="[255,0,0]">C</Font> by computing the remainder after raising <Font bold="true" foreground="[255,0,0]">C</Font> to the private decoding exponent <Font bold="true" foreground="[255,0,0]">d</Font> and dividing by the public number <Font bold="true" foreground="[255,0,0]">n</Font>.  The result will be the original secret number <Font bold="true" foreground="[255,0,0]">W.</Font></Text-field><Text-field layout="Normal" prompt="&gt; " style="Maple Input">DD := C&amp;^d mod n;</Text-field></Input></Group><Group><Input><Text-field layout="Normal" style="Text">The decoded number <Font bold="true" foreground="[255,0,0]">DD</Font> is translated back into the original secret message by replacing 10 by a, 11 by b, ... , 35 by A, ... etc. as previously discussed.</Text-field><Text-field layout="Normal" style="Text">(First strip off junk, if any, at the beginning -- it will begin and end with 99 and have no 9's between.)</Text-field><Text-field layout="Normal" prompt="&gt; " style="Maple Input">original_message := number_to_message(DD); </Text-field></Input></Group></Section><Text-field/><Text-field/><Text-field/><Text-field/><Text-field/><Text-field/><Text-field/><Text-field/><Text-field/></Worksheet>