Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- --
- -- RSA Encryption/Decryption Library
- -- By 1lann
- --
- -- Refer to license: http://pastebin.com/9gWSyqQt
- --
- --
- -- 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))
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement