Advertisement
Tatantyler

RC4

Aug 1st, 2013
469
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 2.80 KB | None | 0 0
  1. -- ARC4
  2. -- By KillaVanilla
  3. -- Hey, go figure! I actually *was* able to write this on my own!
  4.  
  5. -- Best practice with RC4 (and stream ciphers in general, IIRC) is to combine your key and nonce (concentation works), then hash the combined result, and use that as the key.
  6.  
  7. local rc4_object = {
  8.     s = {},
  9.     i = 0,
  10.     j = 0,
  11.     key_schedule = function(self, key)
  12.         for i=0, 255 do
  13.             self.s[i] = i
  14.         end
  15.         self.j = 0
  16.         for i=0, 255 do
  17.             self.j = (self.j + self.s[i] + key[(i % #key)+1]) % 256
  18.             local temp = self.s[i]
  19.             self.s[i] = self.s[self.j]
  20.             self.s[self.j] = temp
  21.         end
  22.     end,
  23.     set_key = function(self, key)
  24.         if type(key) == "string" then
  25.             if #key == 0 then
  26.                 error("rc4-set_key: Invalid key length!", 2)
  27.             end
  28.             if #key > 256 then
  29.                 self:key_schedule({string.byte(key, 1, 256)})
  30.             else
  31.                 self:key_schedule({string.byte(key, 1, #key)})
  32.             end
  33.         elseif type(key) == "table" then
  34.             local filteredKey = {}
  35.             for i=1, #key do
  36.                 if (type(key[i]) == "number") and ((key[i] >= 0) and (key[i] <= 255)) then
  37.                     table.insert(filteredKey, key[i])
  38.                     if #filteredKey >= 256 then
  39.                         break
  40.                     end
  41.                 end
  42.             end
  43.             if #filteredKey == 0 then
  44.                 error("rc4-set_key: Invalid key length!", 2)
  45.             end
  46.             self:key_schedule(filteredKey)
  47.         end
  48.     end,
  49.     generate_byte = function(self)
  50.         self.i = (self.i + 1) % 256
  51.         self.j = (self.j+self.s[self.i]) % 256
  52.         local temp = self.s[self.i]
  53.         self.s[self.i] = self.s[self.j]
  54.         self.s[self.j] = temp
  55.         local k = self.s[(self.s[self.i] + self.s[self.j]) % 256]
  56.         return k
  57.     end,
  58.     discard_bytes = function(self, n)
  59.         for i=1, n do
  60.             self:generate_byte()
  61.         end
  62.     end,
  63.     crypt_array = function(self, iArray)
  64.         local oArray = {}
  65.         local lastPause = os.clock()
  66.         for ctr=1, #iArray do
  67.             local keystream = self:generate_byte()
  68.             oArray[ctr] = bit.bxor(keystream, iArray[ctr])
  69.             if (os.clock() - lastPause) >= 2.90 then
  70.                 os.queueEvent("")
  71.                 os.pullEvent("")
  72.                 lastPause = os.clock()
  73.             end
  74.         end
  75.         return oArray
  76.     end,
  77.     crypt_string = function(self, iStr)
  78.         local oStr = ""
  79.         local oArray = {}
  80.         local lastPause = os.clock()
  81.         for ctr=1, #iStr do
  82.             local keystream = self:generate_byte()
  83.             oArray[ctr] = bit.bxor(keystream, string.byte(iStr, ctr, ctr))
  84.             oStr = oStr..string.char(oArray[ctr])
  85.             if (os.clock() - lastPause) >= 2.90 then
  86.                 os.queueEvent("")
  87.                 os.pullEvent("")
  88.                 lastPause = os.clock()
  89.             end
  90.         end
  91.         return oStr, oArray
  92.     end,
  93. }
  94.  
  95. function new_rc4_object(key)
  96.     local cxt = {}
  97.     for i,v in pairs(rc4_object) do
  98.         cxt[i] = v
  99.     end
  100.     cxt:set_key(key)
  101.     cxt:discard_bytes(3072)
  102.     return cxt
  103. end
  104.  
  105. function encrypt(data, key)
  106.     local object = new_rc4_object(key)
  107.     if type(data) == "string" then
  108.         return object:crypt_string(data)
  109.     elseif type(data) == "table" then
  110.         return object:crypt_array(data)
  111.     end
  112. end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement