66 lines
2.0 KiB
Plaintext
66 lines
2.0 KiB
Plaintext
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
|