Last active
November 4, 2024 18:01
-
-
Save 1lann/6604c8d3d8e5fdad0832 to your computer and use it in GitHub Desktop.
RSA encryption and decryption library in pure Lua for ComputerCraft
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
-- | |
-- RSA Encryption/Decryption Library | |
-- By 1lann | |
-- | |
-- Refer to license: http://pastebin.com/9gWSyqQt | |
-- | |
-- See gists comment at the bottom of the page for FAQ and updates! | |
-- | |
-- | |
-- Start of third-party libraries/helpers | |
-- | |
-- two functions to help make Lua act more like C | |
local function fl(x) | |
if x < 0 then | |
return math.ceil(x) + 0 -- make -0 go away | |
else | |
return math.floor(x) | |
end | |
end | |
local function cmod(a, b) | |
local x = a % b | |
if a < 0 and x > 0 then | |
x = x - b | |
end | |
return x | |
end | |
local radix = 2^24 -- maybe up to 2^26 is safe? | |
local radix_sqrt = fl(math.sqrt(radix)) | |
local bigintmt -- forward decl | |
local function alloc() | |
local bi = {} | |
setmetatable(bi, bigintmt) | |
bi.comps = {} | |
bi.sign = 1; | |
return bi | |
end | |
local function clone(a) | |
local bi = alloc() | |
bi.sign = a.sign | |
local c = bi.comps | |
local ac = a.comps | |
for i = 1, #ac do | |
c[i] = ac[i] | |
end | |
return bi | |
end | |
local function normalize(bi, notrunc) | |
local c = bi.comps | |
local v | |
-- borrow for negative components | |
for i = 1, #c - 1 do | |
v = c[i] | |
if v < 0 then | |
c[i+1] = c[i+1] + fl(v / radix) - 1 | |
v = cmod(v, radix) | |
if v ~= 0 then | |
c[i] = v + radix | |
else | |
c[i] = v | |
c[i+1] = c[i+1] + 1 | |
end | |
end | |
end | |
-- is top component negative? | |
if c[#c] < 0 then | |
-- switch the sign and fix components | |
bi.sign = -bi.sign | |
for i = 1, #c - 1 do | |
v = c[i] | |
c[i] = radix - v | |
c[i+1] = c[i+1] + 1 | |
end | |
c[#c] = -c[#c] | |
end | |
-- carry for components larger than radix | |
for i = 1, #c do | |
v = c[i] | |
if v > radix then | |
c[i+1] = (c[i+1] or 0) + fl(v / radix) | |
c[i] = cmod(v, radix) | |
end | |
end | |
-- trim off leading zeros | |
if not notrunc then | |
for i = #c, 2, -1 do | |
if c[i] == 0 then | |
c[i] = nil | |
else | |
break | |
end | |
end | |
end | |
-- check for -0 | |
if #c == 1 and c[1] == 0 and bi.sign == -1 then | |
bi.sign = 1 | |
end | |
end | |
local function negate(a) | |
local bi = clone(a) | |
bi.sign = -bi.sign | |
return bi | |
end | |
local function compare(a, b) | |
local ac, bc = a.comps, b.comps | |
local as, bs = a.sign, b.sign | |
if ac == bc then | |
return 0 | |
elseif as > bs then | |
return 1 | |
elseif as < bs then | |
return -1 | |
elseif #ac > #bc then | |
return as | |
elseif #ac < #bc then | |
return -as | |
end | |
for i = #ac, 1, -1 do | |
if ac[i] > bc[i] then | |
return as | |
elseif ac[i] < bc[i] then | |
return -as | |
end | |
end | |
return 0 | |
end | |
local function lt(a, b) | |
return compare(a, b) < 0 | |
end | |
local function eq(a, b) | |
return compare(a, b) == 0 | |
end | |
local function le(a, b) | |
return compare(a, b) <= 0 | |
end | |
local function addint(a, n) | |
local bi = clone(a) | |
if bi.sign == 1 then | |
bi.comps[1] = bi.comps[1] + n | |
else | |
bi.comps[1] = bi.comps[1] - n | |
end | |
normalize(bi) | |
return bi | |
end | |
local function add(a, b) | |
if type(a) == "number" then | |
return addint(b, a) | |
elseif type(b) == "number" then | |
return addint(a, b) | |
end | |
local bi = clone(a) | |
local sign = bi.sign == b.sign | |
local c = bi.comps | |
for i = #c + 1, #b.comps do | |
c[i] = 0 | |
end | |
local bc = b.comps | |
for i = 1, #bc do | |
local v = bc[i] | |
if sign then | |
c[i] = c[i] + v | |
else | |
c[i] = c[i] - v | |
end | |
end | |
normalize(bi) | |
return bi | |
end | |
local function sub(a, b) | |
if type(b) == "number" then | |
return addint(a, -b) | |
elseif type(a) == "number" then | |
a = bigint(a) | |
end | |
return add(a, negate(b)) | |
end | |
local function mulint(a, b) | |
local bi = clone(a) | |
if b < 0 then | |
b = -b | |
bi.sign = -bi.sign | |
end | |
local bc = bi.comps | |
for i = 1, #bc do | |
bc[i] = bc[i] * b | |
end | |
normalize(bi) | |
return bi | |
end | |
local function multiply(a, b) | |
local bi = alloc() | |
local c = bi.comps | |
local ac, bc = a.comps, b.comps | |
for i = 1, #ac + #bc do | |
c[i] = 0 | |
end | |
for i = 1, #ac do | |
for j = 1, #bc do | |
c[i+j-1] = c[i+j-1] + ac[i] * bc[j] | |
end | |
-- keep the zeroes | |
normalize(bi, true) | |
end | |
normalize(bi) | |
if bi ~= bigint(0) then | |
bi.sign = a.sign * b.sign | |
end | |
return bi | |
end | |
local function kmul(a, b) | |
local ac, bc = a.comps, b.comps | |
local an, bn = #a.comps, #b.comps | |
local bi, bj, bk, bl = alloc(), alloc(), alloc(), alloc() | |
local ic, jc, kc, lc = bi.comps, bj.comps, bk.comps, bl.comps | |
local n = fl((math.max(an, bn) + 1) / 2) | |
for i = 1, n do | |
ic[i] = (i + n <= an) and ac[i+n] or 0 | |
jc[i] = (i <= an) and ac[i] or 0 | |
kc[i] = (i + n <= bn) and bc[i+n] or 0 | |
lc[i] = (i <= bn) and bc[i] or 0 | |
end | |
normalize(bi) | |
normalize(bj) | |
normalize(bk) | |
normalize(bl) | |
local ik = bi * bk | |
local jl = bj * bl | |
local mid = (bi + bj) * (bk + bl) - ik - jl | |
local mc = mid.comps | |
local ikc = ik.comps | |
local jlc = jl.comps | |
for i = 1, #ikc + n*2 do -- fill it up | |
jlc[i] = jlc[i] or 0 | |
end | |
for i = 1, #mc do | |
jlc[i+n] = jlc[i+n] + mc[i] | |
end | |
for i = 1, #ikc do | |
jlc[i+n*2] = jlc[i+n*2] + ikc[i] | |
end | |
jl.sign = a.sign * b.sign | |
normalize(jl) | |
return jl | |
end | |
local kthresh = 12 | |
local function mul(a, b) | |
if type(a) == "number" then | |
return mulint(b, a) | |
elseif type(b) == "number" then | |
return mulint(a, b) | |
end | |
if #a.comps < kthresh or #b.comps < kthresh then | |
return multiply(a, b) | |
end | |
return kmul(a, b) | |
end | |
local function divint(numer, denom) | |
local bi = clone(numer) | |
if denom < 0 then | |
denom = -denom | |
bi.sign = -bi.sign | |
end | |
local r = 0 | |
local c = bi.comps | |
for i = #c, 1, -1 do | |
r = r * radix + c[i] | |
c[i] = fl(r / denom) | |
r = cmod(r, denom) | |
end | |
normalize(bi) | |
return bi | |
end | |
local function multi_divide(numer, denom) | |
local n = #denom.comps | |
local approx = divint(numer, denom.comps[n]) | |
for i = n, #approx.comps do | |
approx.comps[i - n + 1] = approx.comps[i] | |
end | |
for i = #approx.comps, #approx.comps - n + 2, -1 do | |
approx.comps[i] = nil | |
end | |
local rem = approx * denom - numer | |
if rem < denom then | |
quotient = approx | |
else | |
quotient = approx - multi_divide(rem, denom) | |
end | |
return quotient | |
end | |
local function multi_divide_wrap(numer, denom) | |
-- we use a successive approximation method, but it doesn't work | |
-- if the high order component is too small. adjust if needed. | |
if denom.comps[#denom.comps] < radix_sqrt then | |
numer = mulint(numer, radix_sqrt) | |
denom = mulint(denom, radix_sqrt) | |
end | |
return multi_divide(numer, denom) | |
end | |
local function div(numer, denom) | |
if type(denom) == "number" then | |
if denom == 0 then | |
error("divide by 0", 2) | |
end | |
return divint(numer, denom) | |
elseif type(numer) == "number" then | |
numer = bigint(numer) | |
end | |
-- check signs and trivial cases | |
local sign = 1 | |
local cmp = compare(denom, bigint(0)) | |
if cmp == 0 then | |
error("divide by 0", 2) | |
elseif cmp == -1 then | |
sign = -sign | |
denom = negate(denom) | |
end | |
cmp = compare(numer, bigint(0)) | |
if cmp == 0 then | |
return bigint(0) | |
elseif cmp == -1 then | |
sign = -sign | |
numer = negate(numer) | |
end | |
cmp = compare(numer, denom) | |
if cmp == -1 then | |
return bigint(0) | |
elseif cmp == 0 then | |
return bigint(sign) | |
end | |
local bi | |
-- if small enough, do it the easy way | |
if #denom.comps == 1 then | |
bi = divint(numer, denom.comps[1]) | |
else | |
bi = multi_divide_wrap(numer, denom) | |
end | |
if sign == -1 then | |
bi = negate(bi) | |
end | |
return bi | |
end | |
local function intrem(bi, m) | |
if m < 0 then | |
m = -m | |
end | |
local rad_r = 1 | |
local r = 0 | |
local bc = bi.comps | |
for i = 1, #bc do | |
local v = bc[i] | |
r = cmod(r + v * rad_r, m) | |
rad_r = cmod(rad_r * radix, m) | |
end | |
if bi.sign < 1 then | |
r = -r | |
end | |
return r | |
end | |
local function intmod(bi, m) | |
local r = intrem(bi, m) | |
if r < 0 then | |
r = r + m | |
end | |
return r | |
end | |
local function rem(bi, m) | |
if type(m) == "number" then | |
return bigint(intrem(bi, m)) | |
elseif type(bi) == "number" then | |
bi = bigint(bi) | |
end | |
return bi - ((bi / m) * m) | |
end | |
local function mod(a, m) | |
local bi = rem(a, m) | |
if bi.sign == -1 then | |
bi = bi + m | |
end | |
return bi | |
end | |
local printscale = 10000000 | |
local printscalefmt = string.format("%%.%dd", math.log10(printscale)) | |
local function makestr(bi, s) | |
if bi >= bigint(printscale) then | |
makestr(divint(bi, printscale), s) | |
end | |
table.insert(s, string.format(printscalefmt, intmod(bi, printscale))) | |
end | |
local function biginttostring(bi) | |
local s = {} | |
if bi < bigint(0) then | |
bi = negate(bi) | |
table.insert(s, "-") | |
end | |
makestr(bi, s) | |
s = table.concat(s):gsub("^0*", "") | |
if s == "" then s = "0" end | |
return s | |
end | |
local function biginttonumber(bi) | |
return tonumber(biginttostring(bi)) | |
end | |
bigintmt = { | |
__add = add, | |
__sub = sub, | |
__mul = mul, | |
__div = div, | |
__mod = mod, | |
__unm = negate, | |
__eq = eq, | |
__lt = lt, | |
__le = le, | |
__tostring = biginttostring, | |
} | |
local cache = {} | |
local ncache = 0 | |
function bigint(n) | |
if cache[n] then | |
return cache[n] | |
end | |
local bi | |
if type(n) == "string" then | |
local digits = { n:byte(1, -1) } | |
for i = 1, #digits do | |
digits[i] = string.char(digits[i]) | |
end | |
local start = 1 | |
local sign = 1 | |
if digits[i] == '-' then | |
sign = -1 | |
start = 2 | |
end | |
bi = bigint(0) | |
for i = start, #digits do | |
bi = addint(mulint(bi, 10), tonumber(digits[i])) | |
end | |
bi = mulint(bi, sign) | |
else | |
bi = alloc() | |
bi.comps[1] = n | |
normalize(bi) | |
end | |
if ncache > 100 then | |
cache = {} | |
ncache = 0 | |
end | |
cache[n] = bi | |
ncache = ncache + 1 | |
return bi | |
end | |
-- | |
-- Start of my code | |
-- | |
local powersTwo = { | |
bigint("2"), | |
bigint("4"), | |
bigint("8"), | |
bigint("16"), | |
bigint("32"), | |
bigint("64"), | |
bigint("128"), | |
bigint("256"), | |
bigint("512"), | |
bigint("1024"), | |
bigint("2048"), | |
bigint("4096"), | |
bigint("8192"), | |
bigint("16384"), | |
bigint("32768"), | |
bigint("65536"), | |
bigint("131072"), | |
bigint("262144"), | |
bigint("524288"), | |
bigint("1048576"), | |
bigint("2097152"), | |
bigint("4194304"), | |
bigint("8388608"), | |
bigint("16777216"), | |
bigint("33554432"), | |
bigint("67108864"), | |
bigint("134217728"), | |
bigint("268435456"), | |
bigint("536870912"), | |
bigint("1073741824"), | |
bigint("2147483648"), | |
bigint("4294967296"), | |
bigint("8589934592"), | |
bigint("17179869184"), | |
bigint("34359738368"), | |
bigint("68719476736"), | |
bigint("137438953472"), | |
bigint("274877906944"), | |
bigint("549755813888"), | |
bigint("1099511627776"), | |
bigint("2199023255552"), | |
bigint("4398046511104"), | |
bigint("8796093022208"), | |
bigint("17592186044416"), | |
bigint("35184372088832"), | |
bigint("70368744177664"), | |
bigint("140737488355328"), | |
bigint("281474976710656"), | |
bigint("562949953421312"), | |
bigint("1125899906842624"), | |
bigint("2251799813685248"), | |
bigint("4503599627370496"), | |
bigint("9007199254740992"), | |
bigint("18014398509481984"), | |
bigint("36028797018963968"), | |
bigint("72057594037927936"), | |
bigint("144115188075855872"), | |
bigint("288230376151711744"), | |
bigint("576460752303423488"), | |
bigint("1152921504606846976"), | |
bigint("2305843009213693952"), | |
bigint("4611686018427387904"), | |
bigint("9223372036854775808"), | |
bigint("18446744073709551616"), | |
bigint("36893488147419103232"), | |
bigint("73786976294838206464"), | |
bigint("147573952589676412928"), | |
bigint("295147905179352825856"), | |
bigint("590295810358705651712"), | |
bigint("1180591620717411303424"), | |
bigint("2361183241434822606848"), | |
bigint("4722366482869645213696"), | |
bigint("9444732965739290427392"), | |
bigint("18889465931478580854784"), | |
bigint("37778931862957161709568"), | |
bigint("75557863725914323419136"), | |
bigint("151115727451828646838272"), | |
bigint("302231454903657293676544"), | |
bigint("604462909807314587353088"), | |
bigint("1208925819614629174706176"), | |
bigint("2417851639229258349412352"), | |
bigint("4835703278458516698824704"), | |
bigint("9671406556917033397649408"), | |
bigint("19342813113834066795298816"), | |
bigint("38685626227668133590597632"), | |
bigint("77371252455336267181195264"), | |
bigint("154742504910672534362390528"), | |
bigint("309485009821345068724781056"), | |
bigint("618970019642690137449562112"), | |
bigint("1237940039285380274899124224"), | |
bigint("2475880078570760549798248448"), | |
bigint("4951760157141521099596496896"), | |
bigint("9903520314283042199192993792"), | |
bigint("19807040628566084398385987584"), | |
bigint("39614081257132168796771975168"), | |
bigint("79228162514264337593543950336"), | |
bigint("158456325028528675187087900672"), | |
bigint("316912650057057350374175801344"), | |
bigint("633825300114114700748351602688"), | |
bigint("1267650600228229401496703205376"), | |
bigint("2535301200456458802993406410752"), | |
bigint("5070602400912917605986812821504"), | |
bigint("10141204801825835211973625643008"), | |
bigint("20282409603651670423947251286016"), | |
bigint("40564819207303340847894502572032"), | |
bigint("81129638414606681695789005144064"), | |
bigint("162259276829213363391578010288128"), | |
bigint("324518553658426726783156020576256"), | |
bigint("649037107316853453566312041152512"), | |
bigint("1298074214633706907132624082305024"), | |
bigint("2596148429267413814265248164610048"), | |
bigint("5192296858534827628530496329220096"), | |
bigint("10384593717069655257060992658440192"), | |
bigint("20769187434139310514121985316880384"), | |
bigint("41538374868278621028243970633760768"), | |
bigint("83076749736557242056487941267521536"), | |
bigint("166153499473114484112975882535043072"), | |
bigint("332306998946228968225951765070086144"), | |
bigint("664613997892457936451903530140172288"), | |
bigint("1329227995784915872903807060280344576"), | |
bigint("2658455991569831745807614120560689152"), | |
bigint("5316911983139663491615228241121378304"), | |
bigint("10633823966279326983230456482242756608"), | |
bigint("21267647932558653966460912964485513216"), | |
bigint("42535295865117307932921825928971026432"), | |
bigint("85070591730234615865843651857942052864"), | |
bigint("170141183460469231731687303715884105728"), | |
bigint("340282366920938463463374607431768211456"), | |
bigint("680564733841876926926749214863536422912"), | |
bigint("1361129467683753853853498429727072845824"), | |
bigint("2722258935367507707706996859454145691648"), | |
bigint("5444517870735015415413993718908291383296"), | |
bigint("10889035741470030830827987437816582766592"), | |
bigint("21778071482940061661655974875633165533184"), | |
bigint("43556142965880123323311949751266331066368"), | |
bigint("87112285931760246646623899502532662132736"), | |
bigint("174224571863520493293247799005065324265472"), | |
bigint("348449143727040986586495598010130648530944"), | |
bigint("696898287454081973172991196020261297061888"), | |
bigint("1393796574908163946345982392040522594123776"), | |
bigint("2787593149816327892691964784081045188247552"), | |
bigint("5575186299632655785383929568162090376495104"), | |
bigint("11150372599265311570767859136324180752990208"), | |
bigint("22300745198530623141535718272648361505980416"), | |
bigint("44601490397061246283071436545296723011960832"), | |
bigint("89202980794122492566142873090593446023921664"), | |
bigint("178405961588244985132285746181186892047843328"), | |
bigint("356811923176489970264571492362373784095686656"), | |
bigint("713623846352979940529142984724747568191373312"), | |
bigint("1427247692705959881058285969449495136382746624"), | |
bigint("2854495385411919762116571938898990272765493248"), | |
bigint("5708990770823839524233143877797980545530986496"), | |
bigint("11417981541647679048466287755595961091061972992"), | |
bigint("22835963083295358096932575511191922182123945984"), | |
bigint("45671926166590716193865151022383844364247891968"), | |
bigint("91343852333181432387730302044767688728495783936"), | |
bigint("182687704666362864775460604089535377456991567872"), | |
bigint("365375409332725729550921208179070754913983135744"), | |
bigint("730750818665451459101842416358141509827966271488"), | |
bigint("1461501637330902918203684832716283019655932542976"), | |
bigint("2923003274661805836407369665432566039311865085952"), | |
bigint("5846006549323611672814739330865132078623730171904"), | |
bigint("11692013098647223345629478661730264157247460343808"), | |
bigint("23384026197294446691258957323460528314494920687616"), | |
bigint("46768052394588893382517914646921056628989841375232"), | |
bigint("93536104789177786765035829293842113257979682750464"), | |
bigint("187072209578355573530071658587684226515959365500928"), | |
bigint("374144419156711147060143317175368453031918731001856"), | |
bigint("748288838313422294120286634350736906063837462003712"), | |
bigint("1496577676626844588240573268701473812127674924007424"), | |
bigint("2993155353253689176481146537402947624255349848014848"), | |
bigint("5986310706507378352962293074805895248510699696029696"), | |
bigint("11972621413014756705924586149611790497021399392059392"), | |
bigint("23945242826029513411849172299223580994042798784118784"), | |
bigint("47890485652059026823698344598447161988085597568237568"), | |
bigint("95780971304118053647396689196894323976171195136475136"), | |
bigint("191561942608236107294793378393788647952342390272950272"), | |
bigint("383123885216472214589586756787577295904684780545900544"), | |
bigint("766247770432944429179173513575154591809369561091801088"), | |
bigint("1532495540865888858358347027150309183618739122183602176"), | |
bigint("3064991081731777716716694054300618367237478244367204352"), | |
bigint("6129982163463555433433388108601236734474956488734408704"), | |
bigint("12259964326927110866866776217202473468949912977468817408"), | |
bigint("24519928653854221733733552434404946937899825954937634816"), | |
bigint("49039857307708443467467104868809893875799651909875269632"), | |
bigint("98079714615416886934934209737619787751599303819750539264"), | |
bigint("196159429230833773869868419475239575503198607639501078528"), | |
bigint("392318858461667547739736838950479151006397215279002157056"), | |
bigint("784637716923335095479473677900958302012794430558004314112"), | |
bigint("1569275433846670190958947355801916604025588861116008628224"), | |
bigint("3138550867693340381917894711603833208051177722232017256448"), | |
bigint("6277101735386680763835789423207666416102355444464034512896"), | |
bigint("12554203470773361527671578846415332832204710888928069025792"), | |
bigint("25108406941546723055343157692830665664409421777856138051584"), | |
bigint("50216813883093446110686315385661331328818843555712276103168"), | |
bigint("100433627766186892221372630771322662657637687111424552206336"), | |
bigint("200867255532373784442745261542645325315275374222849104412672"), | |
bigint("401734511064747568885490523085290650630550748445698208825344"), | |
bigint("803469022129495137770981046170581301261101496891396417650688"), | |
bigint("1606938044258990275541962092341162602522202993782792835301376"), | |
bigint("3213876088517980551083924184682325205044405987565585670602752"), | |
bigint("6427752177035961102167848369364650410088811975131171341205504"), | |
bigint("12855504354071922204335696738729300820177623950262342682411008"), | |
bigint("25711008708143844408671393477458601640355247900524685364822016"), | |
bigint("51422017416287688817342786954917203280710495801049370729644032"), | |
bigint("102844034832575377634685573909834406561420991602098741459288064"), | |
bigint("205688069665150755269371147819668813122841983204197482918576128"), | |
bigint("411376139330301510538742295639337626245683966408394965837152256"), | |
bigint("822752278660603021077484591278675252491367932816789931674304512"), | |
bigint("1645504557321206042154969182557350504982735865633579863348609024"), | |
bigint("3291009114642412084309938365114701009965471731267159726697218048"), | |
bigint("6582018229284824168619876730229402019930943462534319453394436096"), | |
bigint("13164036458569648337239753460458804039861886925068638906788872192"), | |
bigint("26328072917139296674479506920917608079723773850137277813577744384"), | |
bigint("52656145834278593348959013841835216159447547700274555627155488768"), | |
bigint("105312291668557186697918027683670432318895095400549111254310977536"), | |
bigint("210624583337114373395836055367340864637790190801098222508621955072"), | |
bigint("421249166674228746791672110734681729275580381602196445017243910144"), | |
bigint("842498333348457493583344221469363458551160763204392890034487820288"), | |
bigint("1684996666696914987166688442938726917102321526408785780068975640576"), | |
bigint("3369993333393829974333376885877453834204643052817571560137951281152"), | |
bigint("6739986666787659948666753771754907668409286105635143120275902562304"), | |
bigint("13479973333575319897333507543509815336818572211270286240551805124608"), | |
bigint("26959946667150639794667015087019630673637144422540572481103610249216"), | |
bigint("53919893334301279589334030174039261347274288845081144962207220498432"), | |
bigint("107839786668602559178668060348078522694548577690162289924414440996864"), | |
bigint("215679573337205118357336120696157045389097155380324579848828881993728"), | |
bigint("431359146674410236714672241392314090778194310760649159697657763987456"), | |
bigint("862718293348820473429344482784628181556388621521298319395315527974912"), | |
bigint("1725436586697640946858688965569256363112777243042596638790631055949824"), | |
bigint("3450873173395281893717377931138512726225554486085193277581262111899648"), | |
bigint("6901746346790563787434755862277025452451108972170386555162524223799296"), | |
bigint("13803492693581127574869511724554050904902217944340773110325048447598592"), | |
bigint("27606985387162255149739023449108101809804435888681546220650096895197184"), | |
bigint("55213970774324510299478046898216203619608871777363092441300193790394368"), | |
bigint("110427941548649020598956093796432407239217743554726184882600387580788736"), | |
bigint("220855883097298041197912187592864814478435487109452369765200775161577472"), | |
bigint("441711766194596082395824375185729628956870974218904739530401550323154944"), | |
bigint("883423532389192164791648750371459257913741948437809479060803100646309888"), | |
bigint("1766847064778384329583297500742918515827483896875618958121606201292619776"), | |
bigint("3533694129556768659166595001485837031654967793751237916243212402585239552"), | |
bigint("7067388259113537318333190002971674063309935587502475832486424805170479104"), | |
bigint("14134776518227074636666380005943348126619871175004951664972849610340958208"), | |
bigint("28269553036454149273332760011886696253239742350009903329945699220681916416"), | |
bigint("56539106072908298546665520023773392506479484700019806659891398441363832832"), | |
bigint("113078212145816597093331040047546785012958969400039613319782796882727665664"), | |
bigint("226156424291633194186662080095093570025917938800079226639565593765455331328"), | |
bigint("452312848583266388373324160190187140051835877600158453279131187530910662656"), | |
bigint("904625697166532776746648320380374280103671755200316906558262375061821325312"), | |
bigint("1809251394333065553493296640760748560207343510400633813116524750123642650624"), | |
bigint("3618502788666131106986593281521497120414687020801267626233049500247285301248"), | |
bigint("7237005577332262213973186563042994240829374041602535252466099000494570602496"), | |
bigint("14474011154664524427946373126085988481658748083205070504932198000989141204992"), | |
bigint("28948022309329048855892746252171976963317496166410141009864396001978282409984"), | |
bigint("57896044618658097711785492504343953926634992332820282019728792003956564819968"), | |
bigint("115792089237316195423570985008687907853269984665640564039457584007913129639936"), | |
} | |
powersTwo[0] = bigint("1") | |
local bigZero = bigint(0) | |
local bigOne = bigint(1) | |
local function numberToBytes(num, bits, byteSize) | |
if bits > #powersTwo then | |
error("Too many bits. Must be <= " .. #powersTwo .. ".") | |
end | |
num = bigint(num) | |
local resultBits = {} | |
resultBits[1] = {} | |
for i = bits - 1, 0, -1 do | |
local expVal = powersTwo[i] | |
local resultant = num - expVal | |
if expVal <= resultant then | |
-- Invalid data! | |
return nil | |
end | |
if resultant < bigZero then | |
-- A zero bit | |
if #(resultBits[#resultBits]) >= byteSize then | |
table.insert(resultBits, {0}) | |
else | |
table.insert(resultBits[#resultBits], 0) | |
end | |
else | |
-- A one bit | |
num = resultant | |
if #(resultBits[#resultBits]) >= byteSize then | |
table.insert(resultBits, {1}) | |
else | |
table.insert(resultBits[#resultBits], 1) | |
end | |
end | |
if num == bigint(0) then | |
break | |
end | |
end | |
local results = {} | |
for _, binarySeq in pairs(resultBits) do | |
local thisResult = 0 | |
for k, bin in pairs(binarySeq) do | |
if bin == 1 then | |
thisResult = thisResult + 2^(byteSize - k) | |
end | |
end | |
table.insert(results, thisResult) | |
end | |
return results | |
end | |
local function bytesToNumber(bytes, bits, byteSize) | |
if bits > #powersTwo then | |
error("Too many bits. Must be <= " .. #powersTwo .. ".") | |
end | |
if #bytes > bits/byteSize then | |
error("Too many bytes to store into the number of bits available. Must be <= " .. | |
bits/byteSize .. ".") | |
end | |
local binary = {} | |
for _, byte in pairs(bytes) do | |
for i = byteSize - 1, 0, -1 do | |
if byte - (2 ^ i) < 0 then | |
table.insert(binary, 0) | |
else | |
table.insert(binary, 1) | |
byte = byte - (2 ^ i) | |
end | |
end | |
end | |
local num = bigint(0) | |
for i = 1, #binary do | |
if binary[i] == 1 then | |
num = num + powersTwo[bits - i] | |
end | |
end | |
return tostring(num) | |
end | |
local function encodeBigNumbers(numbers) | |
for k, v in pairs(numbers) do | |
numbers[k] = tostring(v) | |
end | |
return numbers | |
end | |
local function stringToBytes(str) | |
local result = {} | |
for i = 1, #str do | |
table.insert(result, string.byte(str, i)) | |
end | |
return result | |
end | |
local function bytesToString(bytes) | |
local str = "" | |
for _, v in pairs(bytes) do | |
str = str .. string.char(v) | |
end | |
return str | |
end | |
local function modexp(base, exponent, modulus) | |
local r = 1 | |
while true do | |
if exponent % 2 == bigOne then | |
r = r * base % modulus | |
end | |
exponent = exponent / 2 | |
if exponent == bigZero then | |
break | |
end | |
base = base * base % modulus | |
end | |
return r | |
end | |
local function crypt(key, number) | |
local exp | |
if key.public then | |
exp = bigint(key.public) | |
else | |
exp = bigint(key.private) | |
end | |
return tostring(modexp(bigint(number), exp, bigint(key.shared))) | |
end | |
-- | |
-- END OF LIBRARY | |
-- | |
-- DEMO ENCRYPTION AND DECRYPTION | |
-- | |
local f = io.open("/public.key", "r") | |
local publicKey = textutils.unserialize(f:read("*a")) | |
f:close() | |
f = io.open("/private.key", "r") | |
local privateKey = textutils.unserialize(f:read("*a")) | |
f:close() | |
local byteSize = 8 | |
local bits = 256 | |
local msg = "hello" -- Maximum message size is bits / byteSize | |
local startTime = os.clock() | |
-- Encrypting | |
local res = bytesToNumber(stringToBytes(msg), bits, byteSize) | |
local encrypted = crypt(publicKey, res) | |
print("Took " .. os.clock() - startTime .. " seconds to encrypt.") | |
-- You may transmit "encrypted" in public. "encrypted" is a string. | |
sleep(0.1) | |
startTime = os.clock() | |
-- Decrypting | |
local decrypted = crypt(privateKey, encrypted) | |
local decryptedBytes = numberToBytes(decrypted, bits, byteSize) | |
print("Took " .. os.clock() - startTime .. " seconds to decrypt.") | |
print(bytesToString(decryptedBytes)) |
this dose not work do not bother
it works in computercraft, which is what it is intended for.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
this dose not work do not bother