Advertisement
PrinceOfCookies

os/utils.lua

Jan 25th, 2023 (edited)
88
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 14.22 KB | Source Code | 0 0
  1. --[[ UTILS ]]
  2.  
  3. -- technically it makes everything slower but also makes more compatible with other Lua based stuff
  4. -- Computercraft uses a bit api instead of operators (~, &, |) so it's a bit slower
  5. -- OpenComputers should have support for bit operators afaik
  6. local bitXor = bit.bxor
  7. local bitAnd = bit.band
  8. local bitOr = bit.bor
  9. local bitNot = bit.bnot
  10.  
  11. local bitShiftLeft = bit.blshift
  12. local bitShiftRight = bit.brshift
  13.  
  14. local spack, sunpack = string.pack, string.unpack
  15.  
  16. --[[ MD5 ]]
  17. ------------------------------------------------------------------------
  18. -- md5 hash - see RFC 1321 - https://www.ietf.org/rfc/rfc1321.txt
  19.  
  20.  
  21. local function FF(a, b, c, d, x, s, ac)
  22.     a = bitAnd((a + bitOr(bitAnd(b,c), bitAnd(bitNot(b), d)) + x + ac), 0xffffffff)
  23.     a = bitAnd(bitOr(bitShiftLeft(a, s), bitShiftRight(a, (32-s))), 0xffffffff)
  24.     a = bitAnd((a + b), 0xffffffff)
  25.     return a
  26. end
  27.  
  28. local function GG(a, b, c, d, x, s, ac)
  29.     a = bitAnd((a + bitOr(bitAnd(b, d), bitAnd(c, bitNot(d))) + x + ac), 0xffffffff)
  30.     a = bitAnd(bitOr(bitShiftLeft(a, s), bitShiftRight(a, (32-s))), 0xffffffff)
  31.     a = bitAnd((a + b), 0xffffffff)
  32.     return a
  33. end
  34.  
  35. local function HH(a, b, c, d, x, s, ac)
  36.     a = bitAnd((a + ((bitXor(bitXor(b, c), d))) + x + ac), 0xffffffff)
  37.     a = bitAnd(bitOr(bitShiftLeft(a, s), bitShiftRight(a, (32-s))), 0xffffffff)
  38.     a = bitAnd((a + b), 0xffffffff)
  39.     return a
  40. end
  41.  
  42. local function II(a, b, c, d, x, s, ac)
  43.     a = bitAnd((a + bitXor(c, bitOr(b, bitNot(d))) + x + ac), 0xffffffff)
  44.     a = bitAnd(bitOr(bitShiftLeft(a, s), bitShiftRight(a, (32-s))), 0xffffffff)
  45.     a = bitAnd((a + b), 0xffffffff)
  46.     return a
  47. end
  48.  
  49. local function transform(state, input, i, t)
  50.     -- process the 64-byte input block in string 'input' at offset 'i'
  51.     -- t is a uint32[16] array. It is passed as a parameter
  52.     -- for performance reasons
  53.     --
  54.     local a, b, c, d = state[1], state[2], state[3], state[4]
  55.  
  56.     -- load array
  57.     for j = 1, 16 do
  58.         t[j] = sunpack("<I4", input, i)
  59.         i = i + 4
  60.     end
  61.  
  62.     -- Round 1
  63.     a = FF (a, b, c, d, t[ 1], 7, 0xd76aa478)
  64.     d = FF (d, a, b, c, t[ 2], 12, 0xe8c7b756)
  65.     c = FF (c, d, a, b, t[ 3], 17, 0x242070db)
  66.     b = FF (b, c, d, a, t[ 4], 22, 0xc1bdceee)
  67.     a = FF (a, b, c, d, t[ 5], 7, 0xf57c0faf)
  68.     d = FF (d, a, b, c, t[ 6], 12, 0x4787c62a)
  69.     c = FF (c, d, a, b, t[ 7], 17, 0xa8304613)
  70.     b = FF (b, c, d, a, t[ 8], 22, 0xfd469501)
  71.     a = FF (a, b, c, d, t[ 9], 7, 0x698098d8)
  72.     d = FF (d, a, b, c, t[10], 12, 0x8b44f7af)
  73.     c = FF (c, d, a, b, t[11], 17, 0xffff5bb1)
  74.     b = FF (b, c, d, a, t[12], 22, 0x895cd7be)
  75.     a = FF (a, b, c, d, t[13], 7, 0x6b901122)
  76.     d = FF (d, a, b, c, t[14], 12, 0xfd987193)
  77.     c = FF (c, d, a, b, t[15], 17, 0xa679438e)
  78.     b = FF (b, c, d, a, t[16], 22, 0x49b40821)
  79.  
  80.     -- Round 2
  81.     a = GG (a, b, c, d, t[ 2], 5, 0xf61e2562)
  82.     d = GG (d, a, b, c, t[ 7], 9, 0xc040b340)
  83.     c = GG (c, d, a, b, t[12], 14, 0x265e5a51)
  84.     b = GG (b, c, d, a, t[ 1], 20, 0xe9b6c7aa)
  85.     a = GG (a, b, c, d, t[ 6], 5, 0xd62f105d)
  86.     d = GG (d, a, b, c, t[11], 9,  0x2441453)
  87.     c = GG (c, d, a, b, t[16], 14, 0xd8a1e681)
  88.     b = GG (b, c, d, a, t[ 5], 20, 0xe7d3fbc8)
  89.     a = GG (a, b, c, d, t[10], 5, 0x21e1cde6)
  90.     d = GG (d, a, b, c, t[15], 9, 0xc33707d6)
  91.     c = GG (c, d, a, b, t[ 4], 14, 0xf4d50d87)
  92.     b = GG (b, c, d, a, t[ 9], 20, 0x455a14ed)
  93.     a = GG (a, b, c, d, t[14], 5, 0xa9e3e905)
  94.     d = GG (d, a, b, c, t[ 3], 9, 0xfcefa3f8)
  95.     c = GG (c, d, a, b, t[ 8], 14, 0x676f02d9)
  96.     b = GG (b, c, d, a, t[13], 20, 0x8d2a4c8a)
  97.  
  98.     -- Round 3
  99.     a = HH (a, b, c, d, t[ 6], 4, 0xfffa3942)
  100.     d = HH (d, a, b, c, t[ 9], 11, 0x8771f681)
  101.     c = HH (c, d, a, b, t[12], 16, 0x6d9d6122)
  102.     b = HH (b, c, d, a, t[15], 23, 0xfde5380c)
  103.     a = HH (a, b, c, d, t[ 2], 4, 0xa4beea44)
  104.     d = HH (d, a, b, c, t[ 5], 11, 0x4bdecfa9)
  105.     c = HH (c, d, a, b, t[ 8], 16, 0xf6bb4b60)
  106.     b = HH (b, c, d, a, t[11], 23, 0xbebfbc70)
  107.     a = HH (a, b, c, d, t[14], 4, 0x289b7ec6)
  108.     d = HH (d, a, b, c, t[ 1], 11, 0xeaa127fa)
  109.     c = HH (c, d, a, b, t[ 4], 16, 0xd4ef3085)
  110.     b = HH (b, c, d, a, t[ 7], 23,  0x4881d05)
  111.     a = HH (a, b, c, d, t[10], 4, 0xd9d4d039)
  112.     d = HH (d, a, b, c, t[13], 11, 0xe6db99e5)
  113.     c = HH (c, d, a, b, t[16], 16, 0x1fa27cf8)
  114.     b = HH (b, c, d, a, t[ 3], 23, 0xc4ac5665)
  115.  
  116.     -- Round 4
  117.     a = II (a, b, c, d, t[ 1], 6, 0xf4292244)
  118.     d = II (d, a, b, c, t[ 8], 10, 0x432aff97)
  119.     c = II (c, d, a, b, t[15], 15, 0xab9423a7)
  120.     b = II (b, c, d, a, t[ 6], 21, 0xfc93a039)
  121.     a = II (a, b, c, d, t[13], 6, 0x655b59c3)
  122.     d = II (d, a, b, c, t[ 4], 10, 0x8f0ccc92)
  123.     c = II (c, d, a, b, t[11], 15, 0xffeff47d)
  124.     b = II (b, c, d, a, t[ 2], 21, 0x85845dd1)
  125.     a = II (a, b, c, d, t[ 9], 6, 0x6fa87e4f)
  126.     d = II (d, a, b, c, t[16], 10, 0xfe2ce6e0)
  127.     c = II (c, d, a, b, t[ 7], 15, 0xa3014314)
  128.     b = II (b, c, d, a, t[14], 21, 0x4e0811a1)
  129.     a = II (a, b, c, d, t[ 5], 6, 0xf7537e82)
  130.     d = II (d, a, b, c, t[12], 10, 0xbd3af235)
  131.     c = II (c, d, a, b, t[ 3], 15, 0x2ad7d2bb)
  132.     b = II (b, c, d, a, t[10], 21, 0xeb86d391)
  133.  
  134.     state[1] = bitAnd(state[1] + a, 0xffffffff)
  135.     state[2] = bitAnd(state[2] + b, 0xffffffff)
  136.     state[3] = bitAnd(state[3] + c, 0xffffffff)
  137.     state[4] = bitAnd(state[4] + d, 0xffffffff)
  138. end --transform()
  139.  
  140. local function md5(input)
  141.     -- initialize state
  142.     local state = { 0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476 }
  143.     local inputlen = #input
  144.     local inputbits = inputlen * 8 -- input length in bits
  145.     local r = inputlen -- number of unprocessed bytes
  146.     local i = 1 -- index in input string
  147.     local ibt = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0} -- input block uint32[16]
  148.     -- process as many 64-byte blocks as possible
  149.     while r >= 64 do
  150.         -- process block
  151.         transform(state, input, i, ibt)
  152.         i = i + 64 -- update input index
  153.         r = r - 64 -- update number of unprocessed bytes
  154.     end
  155.     -- finalize.  must append to input a mandatory 0x80 byte, some
  156.     --  padding, and the input bit-length ('inputbits')
  157.     local lastblock -- the rest of input .. some padding .. inputbits
  158.     local padlen -- padding length in bytes
  159.     if r < 56 then padlen = 55 - r else padlen = 119 - r end
  160.     lastblock = input:sub(i) -- remaining input
  161.         .. '\x80' .. ('\0'):rep(padlen)  --padding
  162.         .. spack("<I8", inputbits) -- length in bits
  163.     assert(#lastblock == 64 or #lastblock == 128)
  164.     transform(state, lastblock, 1, ibt)
  165.     if #lastblock == 128 then
  166.         transform(state, lastblock, 65, ibt)
  167.     end
  168.     -- return the digest
  169.     local digest = spack("<I4I4I4I4", state[1], state[2], state[3], state[4])
  170.     return digest
  171. end --md5()
  172.  
  173. --[[ rc4 encryption / decryption ]]
  174.  
  175. local byte, char, concat = string.byte, string.char, table.concat
  176.  
  177. local function keysched(key)
  178.     -- key must be a 16-byte string
  179.     assert(#key == 16, "key must be a 16-byte string")
  180.     local s = {}
  181.     local j,ii,jj
  182.     for i = 0, 255 do s[i+1] = i end
  183.     j = 0
  184.     for i = 0, 255 do
  185.         ii = i+1
  186.         j = bitAnd((j + s[ii] + byte(key, (i % 16) + 1)), 0xff)
  187.         jj = j+1
  188.         s[ii], s[jj] = s[jj], s[ii]
  189.     end
  190.     return s
  191. end
  192.  
  193. local function step(s, i, j)
  194.     i = bitAnd((i + 1), 0xff)
  195.     local ii = i + 1
  196.     j = bitAnd((j + s[ii]), 0xff)
  197.     local jj = j + 1
  198.     s[ii], s[jj] = s[jj], s[ii]
  199.     local k = s[ bitAnd((s[ii] + s[jj]), 0xff) + 1 ]
  200.     return s, i, j, k
  201. end
  202.  
  203. local function rc4raw(key, plain)
  204.     -- raw encryption
  205.     -- key must be a 16-byte string
  206.     local s = keysched(key)
  207.     local i, j = 0, 0
  208.     local k
  209.     local t = {}
  210.     for n = 1, #plain do
  211.         s, i, j, k = step(s, i, j)
  212.         t[n] = char(bitXor(byte(plain, n), k))
  213.     end
  214.     return concat(t)
  215. end
  216.  
  217. local function rc4(key, plain, drop)
  218.     -- encrypt 'plain', return encrypted text
  219.     -- key must be a 16-byte string
  220.     -- optional drop (default = 256): ignore first 'drop' iterations
  221.     drop = drop or 256
  222.     local s = keysched(key)
  223.     local i, j = 0, 0
  224.     local k
  225.     local t = {}
  226.     -- run and ignore 'drop' iterations
  227.     for _ = 1, drop do
  228.         s, i, j = step(s, i, j)
  229.     end
  230.     -- now start to encrypt
  231.     for n = 1, #plain do
  232.         s, i, j, k = step(s, i, j)
  233.         t[n] = char(bitXor(byte(plain, n), k))
  234.     end
  235.     return concat(t)
  236. end
  237.  
  238. --[[ COMPRESSION ]]
  239. local char = string.char
  240. local type = type
  241. local select = select
  242. local sub = string.sub
  243. local tconcat = table.concat
  244.  
  245. local basedictcompress = {}
  246. local basedictdecompress = {}
  247. for i = 0, 255 do
  248.     local ic, iic = char(i), char(i, 0)
  249.     basedictcompress[ic] = iic
  250.     basedictdecompress[iic] = ic
  251. end
  252.  
  253. local function dictAddA(str, dict, a, b)
  254.     if a >= 256 then
  255.         a, b = 0, b+1
  256.         if b >= 256 then
  257.             dict = {}
  258.             b = 1
  259.         end
  260.     end
  261.     dict[str] = char(a,b)
  262.     a = a+1
  263.     return dict, a, b
  264. end
  265.  
  266. local function compress(input, ignoreSize)
  267.     if type(input) ~= "string" then
  268.         return nil, "string expected, got "..type(input)
  269.     end
  270.     local len = #input
  271.     if len <= 1 then
  272.         return "u"..input
  273.     end
  274.  
  275.     local dict = {}
  276.     local a, b = 0, 1
  277.  
  278.     local result = {"c"}
  279.     local resultlen = 1
  280.     local n = 2
  281.     local word = ""
  282.     for i = 1, len do
  283.         local c = sub(input, i, i)
  284.         local wc = word..c
  285.         if not (basedictcompress[wc] or dict[wc]) then
  286.             local write = basedictcompress[word] or dict[word]
  287.             if not write then
  288.                 return nil, "algorithm error, could not fetch word"
  289.             end
  290.             result[n] = write
  291.             resultlen = resultlen + #write
  292.             n = n+1
  293.             if  len <= resultlen and ignoreSize ~= true then
  294.                 return "u"..input
  295.             end
  296.             dict, a, b = dictAddA(wc, dict, a, b)
  297.             word = c
  298.         else
  299.             word = wc
  300.         end
  301.     end
  302.     result[n] = basedictcompress[word] or dict[word]
  303.     resultlen = resultlen+#result[n]
  304.     n = n+1
  305.     if  len <= resultlen and ignoreSize ~= true then
  306.         return "u"..input
  307.     end
  308.     return tconcat(result)
  309. end
  310.  
  311. local function dictAddB(str, dict, a, b)
  312.     if a >= 256 then
  313.         a, b = 0, b+1
  314.         if b >= 256 then
  315.             dict = {}
  316.             b = 1
  317.         end
  318.     end
  319.     dict[char(a,b)] = str
  320.     a = a+1
  321.     return dict, a, b
  322. end
  323.  
  324. local function decompress(input)
  325.     if type(input) ~= "string" then
  326.         return nil, "string expected, got "..type(input)
  327.     end
  328.  
  329.     if #input < 1 then
  330.         return nil, "invalid input - not a compressed string"
  331.     end
  332.  
  333.     local control = sub(input, 1, 1)
  334.     if control == "u" then
  335.         return sub(input, 2)
  336.     elseif control ~= "c" then
  337.         return nil, "invalid input - not a compressed string"
  338.     end
  339.     input = sub(input, 2)
  340.     local len = #input
  341.  
  342.     if len < 2 then
  343.         return nil, "invalid input - not a compressed string"
  344.     end
  345.  
  346.     local dict = {}
  347.     local a, b = 0, 1
  348.  
  349.     local result = {}
  350.     local n = 1
  351.     local last = sub(input, 1, 2)
  352.     result[n] = basedictdecompress[last] or dict[last]
  353.     n = n+1
  354.     for i = 3, len, 2 do
  355.         local code = sub(input, i, i+1)
  356.         local lastStr = basedictdecompress[last] or dict[last]
  357.         if not lastStr then
  358.             return nil, "could not find last from dict. Invalid input?"
  359.         end
  360.         local toAdd = basedictdecompress[code] or dict[code]
  361.         if toAdd then
  362.             result[n] = toAdd
  363.             n = n+1
  364.             dict, a, b = dictAddB(lastStr..sub(toAdd, 1, 1), dict, a, b)
  365.         else
  366.             local tmp = lastStr..sub(lastStr, 1, 1)
  367.             result[n] = tmp
  368.             n = n+1
  369.             dict, a, b = dictAddB(tmp, dict, a, b)
  370.         end
  371.         last = code
  372.     end
  373.     return tconcat(result)
  374. end
  375.  
  376. function fromhex(str)
  377.     return (str:gsub('..', function (cc)
  378.         return string.char(tonumber(cc, 16))
  379.     end))
  380. end
  381.  
  382. function tohex(str)
  383.     return (str:gsub('.', function (c)
  384.         return string.format('%02X', string.byte(c))
  385.     end))
  386. end
  387.  
  388. --[[
  389.     Steps:
  390.     1. Encrypt the plaintext with RC4
  391.     2. Compress the plaintext with LZW
  392.     3. Attach MD5 hash of Compressed data to the compressed data
  393.     4. Return the compressed data
  394. ]]
  395. function Package(KEY, data)
  396.     if type(KEY) ~= "string" then
  397.         return nil, "string expected, got "..type(KEY)
  398.     end
  399.  
  400.     local encryptedData = rc4(KEY, data) -- encrypt data
  401.     local compressedData = compress(encryptedData) -- compress data
  402.  
  403.     compressedData = compressedData .. md5(KEY .. compressedData) -- add md5 hash to compressed data to verify integrity
  404.  
  405.     return compressedData
  406. end
  407.  
  408. --[[
  409.     Steps:
  410.     1. Decompress the compressed data
  411.     2. Decrypt the decompressed data
  412.     3. Verify the integrity of the data
  413.     4. Return the decompressed data
  414. ]]
  415. function UnPackage(KEY, encryptedData)
  416.     local compressedData = sub(encryptedData, 1, -17) -- get compressed data without md5 hash
  417.     local md5Hash = sub(encryptedData, -16) -- get md5 hash of compressed data
  418.  
  419.     if md5(KEY .. compressedData) ~= md5Hash then -- verify integrity of compressed data
  420.         return nil, "invalid data - integrity check failed"
  421.     end
  422.  
  423.     local decompressedData = decompress(compressedData) -- decompress data
  424.     if not decompressedData then
  425.         return nil, "invalid data - decompression failed"
  426.     end
  427.  
  428.     local decryptedData = rc4(KEY, decompressedData) -- decrypt data
  429.     return decryptedData
  430. end
  431.  
  432. -- Globals for Computercraft
  433. if os and os.version then
  434.     Compress = compress
  435.     Decompress = decompress
  436.     Encrypt = rc4
  437.     Decrypt = rc4
  438.     MD5 = md5
  439. end
  440.  
  441. --[[
  442.     Usage:
  443.         compress(data [string], disableSizeCheck [bool] ):
  444.             Tries to compress the given data. if disableSizeCheck is true it wont bother
  445.             with the size before and after compression.
  446.            
  447.         decompress(data [string]):
  448.             Decompresses data
  449.        
  450.         rc4(key, plain, drop):
  451.             Encrypts plain with the given key. drop is the number of iterations to ignore.
  452.             Also Decrypts data the same way.
  453.             Secure enough for minecraft i guess
  454. ]]
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement