-- test bigint library
-- transcribed for Zahl from lhf's example

local version, $, tostring, invmod, text, powmod in imath
print (version)

------------------------------------------------------------------------------
print ""
print "RSA"

local header = "="
assert (#header == 1)

local hex = \ (x) => tostring(x,16) end

mktext = \ (x)
	x = x:totext ( )
	assert ( x:sub (1,1) == header)
	=> x:sub(2)
end

-- https://primes.utm.edu/lists/small/
local p = $ "2074722246773485207821695222\z
1076085874809964747211172927529925899\z
12196684750549658310084416732550077"
local q = $ "5802166458563979118118402595044024839822\z
613606951693823249368750582247183653682429882273371034\z
225069773999682593823264194067085762451410312598613405\z
0997697160127301547995788468137887651823707102007839"

local public = "10001"

local d = $ (public,16)
	print "public key"
	print (d)

local n = (p - 1) * (q - 1)
local e = invmod (d, n)
	print "private key"
	print (e)
	assert ((d * e) % n == $1)

n=p*q
	print "modulus"
	print (n)
	print ""

local message = "The quick brown fox jumps over the lazy dog"
	print "message as text"
	print (message)

local m = text (header..message)
	print "encoded message in decimal"
	print (m)
	print "encoded message in hex"
	print (hex (m))
	assert (m < n)
	assert (message == mktext (m))

local x = powmod (m, e, n)
	print "encrypted message in decimal"
	print (x)
	print "encrypted message in hex"
	print (hex (x))

local y = powmod (x, d, n)
	print "decrypted message in decimal"
	print (y)
	print "decrypted message in hex"
	print (hex (y))
	assert (y == m)

y = mktext (y)
	print "decoded message as text"
	print (y)
	assert (y == message)

------------------------------------------------------------------------------
print ""
print (version)
