Advertisement
tacenda

CC-bank crypt

Jun 17th, 2015
183
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 11.50 KB | None | 0 0
  1. --[[
  2.     CC-Bank
  3.     Copyright © 2012  Yingtong Li
  4.  
  5.     CC-Bank is free software: you can redistribute it and/or modify
  6.     it under the terms of the GNU General Public License as published by
  7.     the Free Software Foundation, either version 3 of the License, or
  8.     (at your option) any later version.
  9.  
  10.     CC-Bank is distributed in the hope that it will be useful,
  11.     but WITHOUT ANY WARRANTY; without even the implied warranty of
  12.     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13.     GNU General Public License for more details.
  14.  
  15.     You should have received a copy of the GNU General Public License
  16.     along with CC-Bank.  If not, see <http://www.gnu.org/licenses/>.
  17. --]]
  18.  
  19. -------------------------------------------------------------------------------
  20. -- SHA-1 secure hash computation, and HMAC-SHA1 signature computation,
  21. -- in pure Lua (tested on Lua 5.1)
  22. -- License: GPL
  23. --
  24. -- Usage:
  25. --   local hash_as_hex   = sha1(message)            -- returns a hex string
  26. --   local hash_as_data  = sha1_binary(message)     -- returns raw bytes
  27. --
  28. -- Pass sha1() a string, and it returns a hash as a 40-character hex string.
  29. --
  30. -- The "_binary" version does the same, but returns the 20-byte string of raw
  31. -- data that the 40-byte hex string represents.
  32. --
  33. -------------------------------------------------------------------------------
  34. -- based on Zet's implementation (which I found too big)
  35. -- > http://cube3d.de/uploads/Main/sha1.txt
  36. -- > > based on Jeffrey Friedl's implementation (which I found a bit too slow)
  37. -- > > jfriedl@yahoo.com
  38. -- > > http://regex.info/blog/
  39. -- > > Version 1 [May 28, 2009]
  40. -- Algorithm: http://www.itl.nist.gov/fipspubs/fip180-1.htm
  41.  
  42. -------------------------------------------------------------------------------
  43. -------------------------------------------------------------------------------
  44.  
  45. -- set this to false if you don't want to build several 64k sized tables when
  46. -- loading this file (takes a while but grants a boost of factor 13)
  47. local cfg_caching = false
  48.  
  49. -- local storing of global functions (minor speedup)
  50. local floor,modf = math.floor,math.modf
  51. local char,format,rep = string.char,string.format,string.rep
  52.  
  53. -- merge 4 bytes to an 32 bit word
  54. local function bytes_to_w32 (a,b,c,d) return a*0x1000000+b*0x10000+c*0x100+d end
  55. -- split a 32 bit word into four 8 bit numbers
  56. local function w32_to_bytes (i)
  57.     return floor(i/0x1000000)%0x100,floor(i/0x10000)%0x100,floor(i/0x100)%0x100,i%0x100
  58. end
  59.  
  60. -- shift the bits of a 32 bit word. Don't use negative values for "bits"
  61. local function w32_rot (bits,a)
  62.     local b2 = 2^(32-bits)
  63.     local a,b = modf(a/b2)
  64.     return a+b*b2*(2^(bits))
  65. end
  66.  
  67. -- caching function for functions that accept 2 arguments, both of values between
  68. -- 0 and 255. The function to be cached is passed, all values are calculated
  69. -- during loading and a function is returned that returns the cached values (only)
  70. local function cache2arg (fn)
  71.     if not cfg_caching then return fn end
  72.     local lut = {}
  73.     for i=0,0xffff do
  74.         local a,b = floor(i/0x100),i%0x100
  75.         lut[i] = fn(a,b)
  76.     end
  77.     return function (a,b)
  78.         return lut[a*0x100+b]
  79.     end
  80. end
  81.  
  82. -- splits an 8-bit number into 8 bits, returning all 8 bits as booleans
  83. local function byte_to_bits (b)
  84.     local b = function (n)
  85.         local b = floor(b/n)
  86.         return b%2==1
  87.     end
  88.     return b(1),b(2),b(4),b(8),b(16),b(32),b(64),b(128)
  89. end
  90.  
  91. -- builds an 8bit number from 8 booleans
  92. local function bits_to_byte (a,b,c,d,e,f,g,h)
  93.     local function n(b,x) return b and x or 0 end
  94.     return n(a,1)+n(b,2)+n(c,4)+n(d,8)+n(e,16)+n(f,32)+n(g,64)+n(h,128)
  95. end
  96.  
  97. -- debug function for visualizing bits in a string
  98. local function bits_to_string (a,b,c,d,e,f,g,h)
  99.     local function x(b) return b and "1" or "0" end
  100.     return ("%s%s%s%s %s%s%s%s"):format(x(a),x(b),x(c),x(d),x(e),x(f),x(g),x(h))
  101. end
  102.  
  103. -- debug function for converting a 8-bit number as bit string
  104. local function byte_to_bit_string (b)
  105.     return bits_to_string(byte_to_bits(b))
  106. end
  107.  
  108. -- debug function for converting a 32 bit number as bit string
  109. local function w32_to_bit_string(a)
  110.     if type(a) == "string" then return a end
  111.     local aa,ab,ac,ad = w32_to_bytes(a)
  112.     local s = byte_to_bit_string
  113.     return ("%s %s %s %s"):format(s(aa):reverse(),s(ab):reverse(),s(ac):reverse(),s(ad):reverse()):reverse()
  114. end
  115.  
  116. -- bitwise "and" function for 2 8bit number
  117. local band = cache2arg (function(a,b)
  118.     local A,B,C,D,E,F,G,H = byte_to_bits(b)
  119.     local a,b,c,d,e,f,g,h = byte_to_bits(a)
  120.     return bits_to_byte(
  121.         A and a, B and b, C and c, D and d,
  122.         E and e, F and f, G and g, H and h)
  123. end)
  124.  
  125. -- bitwise "or" function for 2 8bit numbers
  126. local bor = cache2arg(function(a,b)
  127.     local A,B,C,D,E,F,G,H = byte_to_bits(b)
  128.     local a,b,c,d,e,f,g,h = byte_to_bits(a)
  129.     return bits_to_byte(
  130.         A or a, B or b, C or c, D or d,
  131.         E or e, F or f, G or g, H or h)
  132. end)
  133.  
  134. -- bitwise "xor" function for 2 8bit numbers
  135. local bxor = cache2arg(function(a,b)
  136.     local A,B,C,D,E,F,G,H = byte_to_bits(b)
  137.     local a,b,c,d,e,f,g,h = byte_to_bits(a)
  138.     return bits_to_byte(
  139.         A ~= a, B ~= b, C ~= c, D ~= d,
  140.         E ~= e, F ~= f, G ~= g, H ~= h)
  141. end)
  142.  
  143. -- bitwise complement for one 8bit number
  144. local function bnot (x)
  145.     return 255-(x % 256)
  146. end
  147.  
  148. -- creates a function to combine to 32bit numbers using an 8bit combination function
  149. local function w32_comb(fn)
  150.     return function (a,b)
  151.         local aa,ab,ac,ad = w32_to_bytes(a)
  152.         local ba,bb,bc,bd = w32_to_bytes(b)
  153.         return bytes_to_w32(fn(aa,ba),fn(ab,bb),fn(ac,bc),fn(ad,bd))
  154.     end
  155. end
  156.  
  157. -- create functions for and, xor and or, all for 2 32bit numbers
  158. local w32_and = w32_comb(band)
  159. local w32_xor = w32_comb(bxor)
  160. local w32_or = w32_comb(bor)
  161.  
  162. -- xor function that may receive a variable number of arguments
  163. local function w32_xor_n (a,...)
  164.     local aa,ab,ac,ad = w32_to_bytes(a)
  165.     for i=1,select('#',...) do
  166.         local ba,bb,bc,bd = w32_to_bytes(select(i,...))
  167.         aa,ab,ac,ad = bxor(aa,ba),bxor(ab,bb),bxor(ac,bc),bxor(ad,bd)
  168.     end
  169.     return bytes_to_w32(aa,ab,ac,ad)
  170. end
  171.  
  172. -- combining 3 32bit numbers through binary "or" operation
  173. local function w32_or3 (a,b,c)
  174.     local aa,ab,ac,ad = w32_to_bytes(a)
  175.     local ba,bb,bc,bd = w32_to_bytes(b)
  176.     local ca,cb,cc,cd = w32_to_bytes(c)
  177.     return bytes_to_w32(
  178.         bor(aa,bor(ba,ca)), bor(ab,bor(bb,cb)), bor(ac,bor(bc,cc)), bor(ad,bor(bd,cd))
  179.     )
  180. end
  181.  
  182. -- binary complement for 32bit numbers
  183. local function w32_not (a)
  184.     return 4294967295-(a % 4294967296)
  185. end
  186.  
  187. -- adding 2 32bit numbers, cutting off the remainder on 33th bit
  188. local function w32_add (a,b) return (a+b) % 4294967296 end
  189.  
  190. -- adding n 32bit numbers, cutting off the remainder (again)
  191. local function w32_add_n (a,...)
  192.     for i=1,select('#',...) do
  193.         a = (a+select(i,...)) % 4294967296
  194.     end
  195.     return a
  196. end
  197. -- converting the number to a hexadecimal string
  198. local function w32_to_hexstring (w) return format("%08x",w) end
  199.  
  200. -- calculating the SHA1 for some text
  201. function sha1(msg)
  202.     local H0,H1,H2,H3,H4 = 0x67452301,0xEFCDAB89,0x98BADCFE,0x10325476,0xC3D2E1F0
  203.     local msg_len_in_bits = #msg * 8
  204.  
  205.     local first_append = char(0x80) -- append a '1' bit plus seven '0' bits
  206.  
  207.     local non_zero_message_bytes = #msg +1 +8 -- the +1 is the appended bit 1, the +8 are for the final appended length
  208.     local current_mod = non_zero_message_bytes % 64
  209.     local second_append = current_mod>0 and rep(char(0), 64 - current_mod) or ""
  210.  
  211.     -- now to append the length as a 64-bit number.
  212.     local B1, R1 = modf(msg_len_in_bits  / 0x01000000)
  213.     local B2, R2 = modf( 0x01000000 * R1 / 0x00010000)
  214.     local B3, R3 = modf( 0x00010000 * R2 / 0x00000100)
  215.     local B4      = 0x00000100 * R3
  216.  
  217.     local L64 = char( 0) .. char( 0) .. char( 0) .. char( 0) -- high 32 bits
  218.                 .. char(B1) .. char(B2) .. char(B3) .. char(B4) --  low 32 bits
  219.  
  220.     msg = msg .. first_append .. second_append .. L64
  221.  
  222.     assert(#msg % 64 == 0)
  223.  
  224.     local chunks = #msg / 64
  225.  
  226.     local W = { }
  227.     local start, A, B, C, D, E, f, K, TEMP
  228.     local chunk = 0
  229.  
  230.     while chunk < chunks do
  231.         --
  232.         -- break chunk up into W[0] through W[15]
  233.         --
  234.         start,chunk = chunk * 64 + 1,chunk + 1
  235.  
  236.         for t = 0, 15 do
  237.             W[t] = bytes_to_w32(msg:byte(start, start + 3))
  238.             start = start + 4
  239.         end
  240.  
  241.         --
  242.         -- build W[16] through W[79]
  243.         --
  244.         for t = 16, 79 do
  245.             -- For t = 16 to 79 let Wt = S1(Wt-3 XOR Wt-8 XOR Wt-14 XOR Wt-16).
  246.             W[t] = w32_rot(1, w32_xor_n(W[t-3], W[t-8], W[t-14], W[t-16]))
  247.         end
  248.  
  249.         A,B,C,D,E = H0,H1,H2,H3,H4
  250.  
  251.         for t = 0, 79 do
  252.             if t <= 19 then
  253.                 -- (B AND C) OR ((NOT B) AND D)
  254.                 f = w32_or(w32_and(B, C), w32_and(w32_not(B), D))
  255.                 K = 0x5A827999
  256.             elseif t <= 39 then
  257.                 -- B XOR C XOR D
  258.                 f = w32_xor_n(B, C, D)
  259.                 K = 0x6ED9EBA1
  260.             elseif t <= 59 then
  261.                 -- (B AND C) OR (B AND D) OR (C AND D
  262.                 f = w32_or3(w32_and(B, C), w32_and(B, D), w32_and(C, D))
  263.                 K = 0x8F1BBCDC
  264.             else
  265.                 -- B XOR C XOR D
  266.                 f = w32_xor_n(B, C, D)
  267.                 K = 0xCA62C1D6
  268.             end
  269.  
  270.             -- TEMP = S5(A) + ft(B,C,D) + E + Wt + Kt;
  271.             A,B,C,D,E = w32_add_n(w32_rot(5, A), f, E, W[t], K),
  272.                 A, w32_rot(30, B), C, D
  273.         end
  274.         -- Let H0 = H0 + A, H1 = H1 + B, H2 = H2 + C, H3 = H3 + D, H4 = H4 + E.
  275.         H0,H1,H2,H3,H4 = w32_add(H0, A),w32_add(H1, B),w32_add(H2, C),w32_add(H3, D),w32_add(H4, E)
  276.     end
  277.     local f = w32_to_hexstring
  278.     return f(H0) .. f(H1) .. f(H2) .. f(H3) .. f(H4)
  279. end
  280.  
  281. local function hex_to_binary(hex)
  282.     return hex:gsub('..', function(hexval)
  283.         return string.char(tonumber(hexval, 16))
  284.     end)
  285. end
  286.  
  287. function sha1_binary(msg)
  288.     return hex_to_binary(sha1(msg))
  289. end
  290.  
  291. local xor_with_0x5c = {}
  292. local xor_with_0x36 = {}
  293. -- building the lookuptables ahead of time (instead of littering the source code
  294. -- with precalculated values)
  295. for i=0,0xff do
  296.     xor_with_0x5c[char(i)] = char(bxor(i,0x5c))
  297.     xor_with_0x36[char(i)] = char(bxor(i,0x36))
  298. end
  299.  
  300. -- String Randomizer API --
  301. local chars = {}
  302. for loop = 0, 255 do
  303.    chars[loop+1] = string.char(loop)
  304. end
  305. local string = table.concat(chars)
  306.  
  307. local built = {['.'] = chars}
  308.  
  309. local addLookup = function(charSet)
  310.    local substitute = string.gsub(string, '[^'..charSet..']', '')
  311.    local lookup = {}
  312.    for loop = 1, string.len(substitute) do
  313.        lookup[loop] = string.sub(substitute, loop, loop)
  314.    end
  315.    built[charSet] = lookup
  316.  
  317.    return lookup
  318. end
  319.  
  320. function random(length, charSet)
  321.    -- length (number)
  322.    -- charSet (string, optional); e.g. %l%d for lower case letters and digits
  323.  
  324.    local charSet = charSet or '.'
  325.  
  326.    if charSet == '' then
  327.       return ''
  328.    else
  329.       local result = {}
  330.       local lookup = built[charSet] or addLookup(charSet)
  331.       local range = table.getn(lookup)
  332.  
  333.       for loop = 1,length do
  334.          result[loop] = lookup[math.random(1, range)]
  335.       end
  336.  
  337.       return table.concat(result)
  338.    end
  339. end
  340.  
  341. function randomULN(length)
  342.    return random(length, "qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM0123456789")
  343. end
  344.  
  345. -- Hashing API --
  346. function hashPassword(password)
  347.    local salt = string.sub(sha1(randomULN(20)), 1, 12)
  348.    local hash = sha1(salt .. password)
  349.    local saltPos = string.len(password)
  350.    if saltPos > string.len(hash) then
  351.       saltPos = string.len(hash)
  352.    end
  353.    return string.sub(hash, 1, saltPos) .. salt .. string.sub(hash, saltPos + 1, string.len(hash))
  354. end
  355.  
  356. function checkPassword(input, correct)
  357.    local saltPos = string.len(correct)
  358.    if saltPos > string.len(input) - 12 then
  359.       saltPos = string.len(input) - 12
  360.    end
  361.    local salt = string.sub(input, saltPos + 1, saltPos + 12)
  362.    local password = sha1(salt .. correct)
  363.    return (password == (string.sub(input, 1, saltPos) .. string.sub(input, saltPos + 13, string.len(input))))
  364. end
  365.  
  366. -- crypt.checkPassword(crypt.hashPassword("password"), "password")
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement