procedure main() # rsa demonstration n := 9516311845790656153499716760847001433441357 e := 65537 d := 5617843187844953170308463622230283376298685 b := 2^integer(log(n,2)) # for blocking write("RSA Demo using\n n = ",n,"\n e = ",e,"\n d = ",d,"\n b = ",b) every m := !["Rosetta Code", "Hello Word!", "This message is too long.", repl("x",*decode(n+1))] do { write("\nMessage = ",image(m)) write( "Encoded = ",m := encode(m)) if m := rsa(m,e,n) then { # unblocked write( "Encrypt = ",m) write( "Decrypt = ",m := rsa(m,d,n)) } else { # blocked every put(C := [], rsa(!block(m,b),e,n)) writes("Encrypt = ") ; every writes(!C," ") ; write() every put(P := [], rsa(!C,d,n)) writes("Decrypt = ") ; every writes(!P," ") ; write() write("Unblocked = ",m := unblock(P,b)) } write( "Decoded = ",image(decode(m))) } end procedure mod_power(base, exponent, modulus) # fast modular exponentation result := 1 while exponent > 0 do { if exponent % 2 = 1 then result := (result * base) % modulus exponent /:= 2 base := base ^ 2 % modulus } return result end procedure rsa(text,e,n) # return rsa encryption of numerically encoded message; fail if text < n return mod_power(text,e,text < n) end procedure encode(text) # numerically encode ascii text as int every (message := 0) := ord(!text) + 256 * message return message end procedure decode(message) # numerically decode int to ascii text text := "" while text ||:= char((0 < message) % 256) do message /:= 256 return reverse(text) end procedure block(m,b) # break lg int into blocks of size b M := [] while push(M, x := (0 < m) % b) do m /:= b return M end procedure unblock(M,b) # reassemble blocks of size b into lg int every (m := 0) := !M + b * m return m end