Advertisement
PrinceOfCookies

Untitled

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