vxste

HashLib

Aug 19th, 2024 (edited)
37,111
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 53.09 KB | None | 0 0
  1. local Alphabet = {}
  2. local Indexes = {}
  3.  
  4. local byte, char, sub, rep, format, gsub, gmatch = string.byte, string.char, string.sub, string.rep, string.format, string.gsub, string.gmatch
  5. local tconcat, tcreate, tunpack, tpack, tinsert = table.concat, table.create, table.unpack, table.pack, table.unpack
  6. local floor, min, max, sqrt, abs, modf, sin, ceil = math.floor, math.min, math.max, math.sqrt, math.abs, math.modf, math.sin, math.ceil
  7.  
  8. -- A-Z
  9. for Index = 65, 90 do
  10. tinsert(Alphabet, Index)
  11. end
  12.  
  13. -- a-z
  14. for Index = 97, 122 do
  15. tinsert(Alphabet, Index)
  16. end
  17.  
  18. -- 0-9
  19. for Index = 48, 57 do
  20. tinsert(Alphabet, Index)
  21. end
  22.  
  23. tinsert(Alphabet, 43) -- +
  24. tinsert(Alphabet, 47) -- /
  25.  
  26. for Index, Character in ipairs(Alphabet) do
  27. Indexes[Character] = Index
  28. end
  29.  
  30. local Base64 = {}
  31.  
  32. local bit32_rshift = bit32.rshift
  33. local bit32_lshift = bit32.lshift
  34. local bit32_band = bit32.band
  35.  
  36. --[[**
  37. Encodes a string in Base64.
  38. @param [t:string] Input The input string to encode.
  39. @returns [t:string] The string encoded in Base64.
  40. **--]]
  41. function Base64.Encode(Input)
  42. local Output = {}
  43. local Length = 0
  44.  
  45. for Index = 1, #Input, 3 do
  46. local C1, C2, C3 = byte(Input, Index, Index + 2)
  47.  
  48. local A = bit32_rshift(C1, 2)
  49. local B = bit32_lshift(bit32_band(C1, 3), 4) + bit32_rshift(C2 or 0, 4)
  50. local C = bit32_lshift(bit32_band(C2 or 0, 15), 2) + bit32_rshift(C3 or 0, 6)
  51. local D = bit32_band(C3 or 0, 63)
  52.  
  53. Length = Length + 1
  54. Output[Length] = Alphabet[A + 1]
  55.  
  56. Length = Length + 1
  57. Output[Length] = Alphabet[B + 1]
  58.  
  59. Length = Length + 1
  60. Output[Length] = C2 and Alphabet[C + 1] or 61
  61.  
  62. Length = Length + 1
  63. Output[Length] = C3 and Alphabet[D + 1] or 61
  64. end
  65.  
  66. local NewOutput = {}
  67. local NewLength = 0
  68. local IndexAdd4096Sub1
  69.  
  70. for Index = 1, Length, 4096 do
  71. NewLength = NewLength + 1
  72. IndexAdd4096Sub1 = Index + 4096 - 1
  73.  
  74. NewOutput[NewLength] = char(tunpack(
  75. Output,
  76. Index,
  77. IndexAdd4096Sub1 > Length and Length or IndexAdd4096Sub1
  78. ))
  79. end
  80.  
  81. return tconcat(NewOutput)
  82. end
  83.  
  84. --[[**
  85. Decodes a string from Base64.
  86. @param [t:string] Input The input string to decode.
  87. @returns [t:string] The newly decoded string.
  88. **--]]
  89. function Base64.Decode(Input)
  90. local Output = {}
  91. local Length = 0
  92.  
  93. for Index = 1, #Input, 4 do
  94. local C1, C2, C3, C4 = byte(Input, Index, Index + 3)
  95.  
  96. local I1 = Indexes[C1] - 1
  97. local I2 = Indexes[C2] - 1
  98. local I3 = (Indexes[C3] or 1) - 1
  99. local I4 = (Indexes[C4] or 1) - 1
  100.  
  101. local A = bit32_lshift(I1, 2) + bit32_rshift(I2, 4)
  102. local B = bit32_lshift(bit32_band(I2, 15), 4) + bit32_rshift(I3, 2)
  103. local C = bit32_lshift(bit32_band(I3, 3), 6) + I4
  104.  
  105. Length = Length + 1
  106. Output[Length] = A
  107.  
  108. if C3 ~= 61 then
  109. Length = Length + 1
  110. Output[Length] = B
  111. end
  112.  
  113. if C4 ~= 61 then
  114. Length = Length + 1
  115. Output[Length] = C
  116. end
  117. end
  118.  
  119. local NewOutput = {}
  120. local NewLength = 0
  121. local IndexAdd4096Sub1
  122.  
  123. for Index = 1, Length, 4096 do
  124. NewLength = NewLength + 1
  125. IndexAdd4096Sub1 = Index + 4096 - 1
  126.  
  127. NewOutput[NewLength] = char(tunpack(
  128. Output,
  129. Index,
  130. IndexAdd4096Sub1 > Length and Length or IndexAdd4096Sub1
  131. ))
  132. end
  133.  
  134. return tconcat(NewOutput)
  135. end
  136.  
  137. --------------------------------------------------------------------------------
  138. -- LOCALIZATION FOR VM OPTIMIZATIONS
  139. --------------------------------------------------------------------------------
  140.  
  141. local ipairs = ipairs
  142.  
  143. --------------------------------------------------------------------------------
  144. -- 32-BIT BITWISE FUNCTIONS
  145. --------------------------------------------------------------------------------
  146. -- Only low 32 bits of function arguments matter, high bits are ignored
  147. -- The result of all functions (except HEX) is an integer inside "correct range":
  148. -- for "bit" library: (-TWO_POW_31)..(TWO_POW_31-1)
  149. -- for "bit32" library: 0..(TWO_POW_32-1)
  150. local bit32_bor = bit32.bor -- 2 arguments
  151. local bit32_bxor = bit32.bxor -- 2..5 arguments
  152. local bit32_lrotate = bit32.lrotate -- second argument is integer 0..31
  153. local bit32_rrotate = bit32.rrotate -- second argument is integer 0..31
  154.  
  155. --------------------------------------------------------------------------------
  156. -- CREATING OPTIMIZED INNER LOOP
  157. --------------------------------------------------------------------------------
  158. -- Arrays of SHA2 "magic numbers" (in "INT64" and "FFI" branches "*_lo" arrays contain 64-bit values)
  159. local sha2_K_lo, sha2_K_hi, sha2_H_lo, sha2_H_hi, sha3_RC_lo, sha3_RC_hi = {}, {}, {}, {}, {}, {}
  160. local sha2_H_ext256 = {
  161. [224] = {};
  162. [256] = sha2_H_hi;
  163. }
  164.  
  165. local sha2_H_ext512_lo, sha2_H_ext512_hi = {
  166. [384] = {};
  167. [512] = sha2_H_lo;
  168. }, {
  169. [384] = {};
  170. [512] = sha2_H_hi;
  171. }
  172.  
  173. local md5_K, md5_sha1_H = {}, {0x67452301, 0xEFCDAB89, 0x98BADCFE, 0x10325476, 0xC3D2E1F0}
  174. local md5_next_shift = {0, 0, 0, 0, 0, 0, 0, 0, 28, 25, 26, 27, 0, 0, 10, 9, 11, 12, 0, 15, 16, 17, 18, 0, 20, 22, 23, 21}
  175. local HEX64, XOR64A5, lanes_index_base -- defined only for branches that internally use 64-bit integers: "INT64" and "FFI"
  176. local common_W = {} -- temporary table shared between all calculations (to avoid creating new temporary table every time)
  177. local K_lo_modulo, hi_factor, hi_factor_keccak = 4294967296, 0, 0
  178.  
  179. local TWO_POW_NEG_56 = 2 ^ -56
  180. local TWO_POW_NEG_17 = 2 ^ -17
  181.  
  182. local TWO_POW_2 = 2 ^ 2
  183. local TWO_POW_3 = 2 ^ 3
  184. local TWO_POW_4 = 2 ^ 4
  185. local TWO_POW_5 = 2 ^ 5
  186. local TWO_POW_6 = 2 ^ 6
  187. local TWO_POW_7 = 2 ^ 7
  188. local TWO_POW_8 = 2 ^ 8
  189. local TWO_POW_9 = 2 ^ 9
  190. local TWO_POW_10 = 2 ^ 10
  191. local TWO_POW_11 = 2 ^ 11
  192. local TWO_POW_12 = 2 ^ 12
  193. local TWO_POW_13 = 2 ^ 13
  194. local TWO_POW_14 = 2 ^ 14
  195. local TWO_POW_15 = 2 ^ 15
  196. local TWO_POW_16 = 2 ^ 16
  197. local TWO_POW_17 = 2 ^ 17
  198. local TWO_POW_18 = 2 ^ 18
  199. local TWO_POW_19 = 2 ^ 19
  200. local TWO_POW_20 = 2 ^ 20
  201. local TWO_POW_21 = 2 ^ 21
  202. local TWO_POW_22 = 2 ^ 22
  203. local TWO_POW_23 = 2 ^ 23
  204. local TWO_POW_24 = 2 ^ 24
  205. local TWO_POW_25 = 2 ^ 25
  206. local TWO_POW_26 = 2 ^ 26
  207. local TWO_POW_27 = 2 ^ 27
  208. local TWO_POW_28 = 2 ^ 28
  209. local TWO_POW_29 = 2 ^ 29
  210. local TWO_POW_30 = 2 ^ 30
  211. local TWO_POW_31 = 2 ^ 31
  212. local TWO_POW_32 = 2 ^ 32
  213. local TWO_POW_40 = 2 ^ 40
  214.  
  215. local TWO56_POW_7 = 256 ^ 7
  216.  
  217. -- Implementation for Lua 5.1/5.2 (with or without bitwise library available)
  218. local function sha256_feed_64(H, str, offs, size)
  219. -- offs >= 0, size >= 0, size is multiple of 64
  220. local W, K = common_W, sha2_K_hi
  221. local h1, h2, h3, h4, h5, h6, h7, h8 = H[1], H[2], H[3], H[4], H[5], H[6], H[7], H[8]
  222. for pos = offs, offs + size - 1, 64 do
  223. for j = 1, 16 do
  224. pos = pos + 4
  225. local a, b, c, d = byte(str, pos - 3, pos)
  226. W[j] = ((a * 256 + b) * 256 + c) * 256 + d
  227. end
  228.  
  229. for j = 17, 64 do
  230. local a, b = W[j - 15], W[j - 2]
  231. W[j] = bit32_bxor(bit32_rrotate(a, 7), bit32_lrotate(a, 14), bit32_rshift(a, 3)) + bit32_bxor(bit32_lrotate(b, 15), bit32_lrotate(b, 13), bit32_rshift(b, 10)) + W[j - 7] + W[j - 16]
  232. end
  233.  
  234. local a, b, c, d, e, f, g, h = h1, h2, h3, h4, h5, h6, h7, h8
  235. for j = 1, 64 do
  236. local z = bit32_bxor(bit32_rrotate(e, 6), bit32_rrotate(e, 11), bit32_lrotate(e, 7)) + bit32_band(e, f) + bit32_band(-1 - e, g) + h + K[j] + W[j]
  237. h = g
  238. g = f
  239. f = e
  240. e = z + d
  241. d = c
  242. c = b
  243. b = a
  244. a = z + bit32_band(d, c) + bit32_band(a, bit32_bxor(d, c)) + bit32_bxor(bit32_rrotate(a, 2), bit32_rrotate(a, 13), bit32_lrotate(a, 10))
  245. end
  246.  
  247. h1, h2, h3, h4 = (a + h1) % 4294967296, (b + h2) % 4294967296, (c + h3) % 4294967296, (d + h4) % 4294967296
  248. h5, h6, h7, h8 = (e + h5) % 4294967296, (f + h6) % 4294967296, (g + h7) % 4294967296, (h + h8) % 4294967296
  249. end
  250.  
  251. H[1], H[2], H[3], H[4], H[5], H[6], H[7], H[8] = h1, h2, h3, h4, h5, h6, h7, h8
  252. end
  253.  
  254. local function sha512_feed_128(H_lo, H_hi, str, offs, size)
  255. -- offs >= 0, size >= 0, size is multiple of 128
  256. -- W1_hi, W1_lo, W2_hi, W2_lo, ... Wk_hi = W[2*k-1], Wk_lo = W[2*k]
  257. local W, K_lo, K_hi = common_W, sha2_K_lo, sha2_K_hi
  258. local h1_lo, h2_lo, h3_lo, h4_lo, h5_lo, h6_lo, h7_lo, h8_lo = H_lo[1], H_lo[2], H_lo[3], H_lo[4], H_lo[5], H_lo[6], H_lo[7], H_lo[8]
  259. local h1_hi, h2_hi, h3_hi, h4_hi, h5_hi, h6_hi, h7_hi, h8_hi = H_hi[1], H_hi[2], H_hi[3], H_hi[4], H_hi[5], H_hi[6], H_hi[7], H_hi[8]
  260. for pos = offs, offs + size - 1, 128 do
  261. for j = 1, 16 * 2 do
  262. pos = pos + 4
  263. local a, b, c, d = byte(str, pos - 3, pos)
  264. W[j] = ((a * 256 + b) * 256 + c) * 256 + d
  265. end
  266.  
  267. for jj = 34, 160, 2 do
  268. local a_lo, a_hi, b_lo, b_hi = W[jj - 30], W[jj - 31], W[jj - 4], W[jj - 5]
  269. local tmp1 = bit32_bxor(bit32_rshift(a_lo, 1) + bit32_lshift(a_hi, 31), bit32_rshift(a_lo, 8) + bit32_lshift(a_hi, 24), bit32_rshift(a_lo, 7) + bit32_lshift(a_hi, 25)) % 4294967296 +
  270. bit32_bxor(bit32_rshift(b_lo, 19) + bit32_lshift(b_hi, 13), bit32_lshift(b_lo, 3) + bit32_rshift(b_hi, 29), bit32_rshift(b_lo, 6) + bit32_lshift(b_hi, 26)) % 4294967296 +
  271. W[jj - 14] + W[jj - 32]
  272.  
  273. local tmp2 = tmp1 % 4294967296
  274. W[jj - 1] = bit32_bxor(bit32_rshift(a_hi, 1) + bit32_lshift(a_lo, 31), bit32_rshift(a_hi, 8) + bit32_lshift(a_lo, 24), bit32_rshift(a_hi, 7)) +
  275. bit32_bxor(bit32_rshift(b_hi, 19) + bit32_lshift(b_lo, 13), bit32_lshift(b_hi, 3) + bit32_rshift(b_lo, 29), bit32_rshift(b_hi, 6)) +
  276. W[jj - 15] + W[jj - 33] + (tmp1 - tmp2) / 4294967296
  277.  
  278. W[jj] = tmp2
  279. end
  280.  
  281. local a_lo, b_lo, c_lo, d_lo, e_lo, f_lo, g_lo, h_lo = h1_lo, h2_lo, h3_lo, h4_lo, h5_lo, h6_lo, h7_lo, h8_lo
  282. local a_hi, b_hi, c_hi, d_hi, e_hi, f_hi, g_hi, h_hi = h1_hi, h2_hi, h3_hi, h4_hi, h5_hi, h6_hi, h7_hi, h8_hi
  283. for j = 1, 80 do
  284. local jj = 2 * j
  285. local tmp1 = bit32_bxor(bit32_rshift(e_lo, 14) + bit32_lshift(e_hi, 18), bit32_rshift(e_lo, 18) + bit32_lshift(e_hi, 14), bit32_lshift(e_lo, 23) + bit32_rshift(e_hi, 9)) % 4294967296 +
  286. (bit32_band(e_lo, f_lo) + bit32_band(-1 - e_lo, g_lo)) % 4294967296 +
  287. h_lo + K_lo[j] + W[jj]
  288.  
  289. local z_lo = tmp1 % 4294967296
  290. local z_hi = bit32_bxor(bit32_rshift(e_hi, 14) + bit32_lshift(e_lo, 18), bit32_rshift(e_hi, 18) + bit32_lshift(e_lo, 14), bit32_lshift(e_hi, 23) + bit32_rshift(e_lo, 9)) +
  291. bit32_band(e_hi, f_hi) + bit32_band(-1 - e_hi, g_hi) +
  292. h_hi + K_hi[j] + W[jj - 1] +
  293. (tmp1 - z_lo) / 4294967296
  294.  
  295. h_lo = g_lo
  296. h_hi = g_hi
  297. g_lo = f_lo
  298. g_hi = f_hi
  299. f_lo = e_lo
  300. f_hi = e_hi
  301. tmp1 = z_lo + d_lo
  302. e_lo = tmp1 % 4294967296
  303. e_hi = z_hi + d_hi + (tmp1 - e_lo) / 4294967296
  304. d_lo = c_lo
  305. d_hi = c_hi
  306. c_lo = b_lo
  307. c_hi = b_hi
  308. b_lo = a_lo
  309. b_hi = a_hi
  310. tmp1 = z_lo + (bit32_band(d_lo, c_lo) + bit32_band(b_lo, bit32_bxor(d_lo, c_lo))) % 4294967296 + bit32_bxor(bit32_rshift(b_lo, 28) + bit32_lshift(b_hi, 4), bit32_lshift(b_lo, 30) + bit32_rshift(b_hi, 2), bit32_lshift(b_lo, 25) + bit32_rshift(b_hi, 7)) % 4294967296
  311. a_lo = tmp1 % 4294967296
  312. a_hi = z_hi + (bit32_band(d_hi, c_hi) + bit32_band(b_hi, bit32_bxor(d_hi, c_hi))) + bit32_bxor(bit32_rshift(b_hi, 28) + bit32_lshift(b_lo, 4), bit32_lshift(b_hi, 30) + bit32_rshift(b_lo, 2), bit32_lshift(b_hi, 25) + bit32_rshift(b_lo, 7)) + (tmp1 - a_lo) / 4294967296
  313. end
  314.  
  315. a_lo = h1_lo + a_lo
  316. h1_lo = a_lo % 4294967296
  317. h1_hi = (h1_hi + a_hi + (a_lo - h1_lo) / 4294967296) % 4294967296
  318. a_lo = h2_lo + b_lo
  319. h2_lo = a_lo % 4294967296
  320. h2_hi = (h2_hi + b_hi + (a_lo - h2_lo) / 4294967296) % 4294967296
  321. a_lo = h3_lo + c_lo
  322. h3_lo = a_lo % 4294967296
  323. h3_hi = (h3_hi + c_hi + (a_lo - h3_lo) / 4294967296) % 4294967296
  324. a_lo = h4_lo + d_lo
  325. h4_lo = a_lo % 4294967296
  326. h4_hi = (h4_hi + d_hi + (a_lo - h4_lo) / 4294967296) % 4294967296
  327. a_lo = h5_lo + e_lo
  328. h5_lo = a_lo % 4294967296
  329. h5_hi = (h5_hi + e_hi + (a_lo - h5_lo) / 4294967296) % 4294967296
  330. a_lo = h6_lo + f_lo
  331. h6_lo = a_lo % 4294967296
  332. h6_hi = (h6_hi + f_hi + (a_lo - h6_lo) / 4294967296) % 4294967296
  333. a_lo = h7_lo + g_lo
  334. h7_lo = a_lo % 4294967296
  335. h7_hi = (h7_hi + g_hi + (a_lo - h7_lo) / 4294967296) % 4294967296
  336. a_lo = h8_lo + h_lo
  337. h8_lo = a_lo % 4294967296
  338. h8_hi = (h8_hi + h_hi + (a_lo - h8_lo) / 4294967296) % 4294967296
  339. end
  340.  
  341. H_lo[1], H_lo[2], H_lo[3], H_lo[4], H_lo[5], H_lo[6], H_lo[7], H_lo[8] = h1_lo, h2_lo, h3_lo, h4_lo, h5_lo, h6_lo, h7_lo, h8_lo
  342. H_hi[1], H_hi[2], H_hi[3], H_hi[4], H_hi[5], H_hi[6], H_hi[7], H_hi[8] = h1_hi, h2_hi, h3_hi, h4_hi, h5_hi, h6_hi, h7_hi, h8_hi
  343. end
  344.  
  345. local function md5_feed_64(H, str, offs, size)
  346. -- offs >= 0, size >= 0, size is multiple of 64
  347. local W, K, md5_next_shift = common_W, md5_K, md5_next_shift
  348. local h1, h2, h3, h4 = H[1], H[2], H[3], H[4]
  349. for pos = offs, offs + size - 1, 64 do
  350. for j = 1, 16 do
  351. pos = pos + 4
  352. local a, b, c, d = byte(str, pos - 3, pos)
  353. W[j] = ((d * 256 + c) * 256 + b) * 256 + a
  354. end
  355.  
  356. local a, b, c, d = h1, h2, h3, h4
  357. local s = 25
  358. for j = 1, 16 do
  359. local F = bit32_rrotate(bit32_band(b, c) + bit32_band(-1 - b, d) + a + K[j] + W[j], s) + b
  360. s = md5_next_shift[s]
  361. a = d
  362. d = c
  363. c = b
  364. b = F
  365. end
  366.  
  367. s = 27
  368. for j = 17, 32 do
  369. local F = bit32_rrotate(bit32_band(d, b) + bit32_band(-1 - d, c) + a + K[j] + W[(5 * j - 4) % 16 + 1], s) + b
  370. s = md5_next_shift[s]
  371. a = d
  372. d = c
  373. c = b
  374. b = F
  375. end
  376.  
  377. s = 28
  378. for j = 33, 48 do
  379. local F = bit32_rrotate(bit32_bxor(bit32_bxor(b, c), d) + a + K[j] + W[(3 * j + 2) % 16 + 1], s) + b
  380. s = md5_next_shift[s]
  381. a = d
  382. d = c
  383. c = b
  384. b = F
  385. end
  386.  
  387. s = 26
  388. for j = 49, 64 do
  389. local F = bit32_rrotate(bit32_bxor(c, bit32_bor(b, -1 - d)) + a + K[j] + W[(j * 7 - 7) % 16 + 1], s) + b
  390. s = md5_next_shift[s]
  391. a = d
  392. d = c
  393. c = b
  394. b = F
  395. end
  396.  
  397. h1 = (a + h1) % 4294967296
  398. h2 = (b + h2) % 4294967296
  399. h3 = (c + h3) % 4294967296
  400. h4 = (d + h4) % 4294967296
  401. end
  402.  
  403. H[1], H[2], H[3], H[4] = h1, h2, h3, h4
  404. end
  405.  
  406. local function sha1_feed_64(H, str, offs, size)
  407. -- offs >= 0, size >= 0, size is multiple of 64
  408. local W = common_W
  409. local h1, h2, h3, h4, h5 = H[1], H[2], H[3], H[4], H[5]
  410. for pos = offs, offs + size - 1, 64 do
  411. for j = 1, 16 do
  412. pos = pos + 4
  413. local a, b, c, d = byte(str, pos - 3, pos)
  414. W[j] = ((a * 256 + b) * 256 + c) * 256 + d
  415. end
  416.  
  417. for j = 17, 80 do
  418. W[j] = bit32_lrotate(bit32_bxor(W[j - 3], W[j - 8], W[j - 14], W[j - 16]), 1)
  419. end
  420.  
  421. local a, b, c, d, e = h1, h2, h3, h4, h5
  422. for j = 1, 20 do
  423. local z = bit32_lrotate(a, 5) + bit32_band(b, c) + bit32_band(-1 - b, d) + 0x5A827999 + W[j] + e -- constant = floor(TWO_POW_30 * sqrt(2))
  424. e = d
  425. d = c
  426. c = bit32_rrotate(b, 2)
  427. b = a
  428. a = z
  429. end
  430.  
  431. for j = 21, 40 do
  432. local z = bit32_lrotate(a, 5) + bit32_bxor(b, c, d) + 0x6ED9EBA1 + W[j] + e -- TWO_POW_30 * sqrt(3)
  433. e = d
  434. d = c
  435. c = bit32_rrotate(b, 2)
  436. b = a
  437. a = z
  438. end
  439.  
  440. for j = 41, 60 do
  441. local z = bit32_lrotate(a, 5) + bit32_band(d, c) + bit32_band(b, bit32_bxor(d, c)) + 0x8F1BBCDC + W[j] + e -- TWO_POW_30 * sqrt(5)
  442. e = d
  443. d = c
  444. c = bit32_rrotate(b, 2)
  445. b = a
  446. a = z
  447. end
  448.  
  449. for j = 61, 80 do
  450. local z = bit32_lrotate(a, 5) + bit32_bxor(b, c, d) + 0xCA62C1D6 + W[j] + e -- TWO_POW_30 * sqrt(10)
  451. e = d
  452. d = c
  453. c = bit32_rrotate(b, 2)
  454. b = a
  455. a = z
  456. end
  457.  
  458. h1 = (a + h1) % 4294967296
  459. h2 = (b + h2) % 4294967296
  460. h3 = (c + h3) % 4294967296
  461. h4 = (d + h4) % 4294967296
  462. h5 = (e + h5) % 4294967296
  463. end
  464.  
  465. H[1], H[2], H[3], H[4], H[5] = h1, h2, h3, h4, h5
  466. end
  467.  
  468. local function keccak_feed(lanes_lo, lanes_hi, str, offs, size, block_size_in_bytes)
  469. -- This is an example of a Lua function having 79 local variables :-)
  470. -- offs >= 0, size >= 0, size is multiple of block_size_in_bytes, block_size_in_bytes is positive multiple of 8
  471. local RC_lo, RC_hi = sha3_RC_lo, sha3_RC_hi
  472. local qwords_qty = block_size_in_bytes / 8
  473. for pos = offs, offs + size - 1, block_size_in_bytes do
  474. for j = 1, qwords_qty do
  475. local a, b, c, d = byte(str, pos + 1, pos + 4)
  476. lanes_lo[j] = bit32_bxor(lanes_lo[j], ((d * 256 + c) * 256 + b) * 256 + a)
  477. pos = pos + 8
  478. a, b, c, d = byte(str, pos - 3, pos)
  479. lanes_hi[j] = bit32_bxor(lanes_hi[j], ((d * 256 + c) * 256 + b) * 256 + a)
  480. end
  481.  
  482. local L01_lo, L01_hi, L02_lo, L02_hi, L03_lo, L03_hi, L04_lo, L04_hi, L05_lo, L05_hi, L06_lo, L06_hi, L07_lo, L07_hi, L08_lo, L08_hi, L09_lo, L09_hi, L10_lo, L10_hi, L11_lo, L11_hi, L12_lo, L12_hi, L13_lo, L13_hi, L14_lo, L14_hi, L15_lo, L15_hi, L16_lo, L16_hi, L17_lo, L17_hi, L18_lo, L18_hi, L19_lo, L19_hi, L20_lo, L20_hi, L21_lo, L21_hi, L22_lo, L22_hi, L23_lo, L23_hi, L24_lo, L24_hi, L25_lo, L25_hi = lanes_lo[1], lanes_hi[1], lanes_lo[2], lanes_hi[2], lanes_lo[3], lanes_hi[3], lanes_lo[4], lanes_hi[4], lanes_lo[5], lanes_hi[5], lanes_lo[6], lanes_hi[6], lanes_lo[7], lanes_hi[7], lanes_lo[8], lanes_hi[8], lanes_lo[9], lanes_hi[9], lanes_lo[10], lanes_hi[10], lanes_lo[11], lanes_hi[11], lanes_lo[12], lanes_hi[12], lanes_lo[13], lanes_hi[13], lanes_lo[14], lanes_hi[14], lanes_lo[15], lanes_hi[15], lanes_lo[16], lanes_hi[16], lanes_lo[17], lanes_hi[17], lanes_lo[18], lanes_hi[18], lanes_lo[19], lanes_hi[19], lanes_lo[20], lanes_hi[20], lanes_lo[21], lanes_hi[21], lanes_lo[22], lanes_hi[22], lanes_lo[23], lanes_hi[23], lanes_lo[24], lanes_hi[24], lanes_lo[25], lanes_hi[25]
  483.  
  484. for round_idx = 1, 24 do
  485. local C1_lo = bit32_bxor(L01_lo, L06_lo, L11_lo, L16_lo, L21_lo)
  486. local C1_hi = bit32_bxor(L01_hi, L06_hi, L11_hi, L16_hi, L21_hi)
  487. local C2_lo = bit32_bxor(L02_lo, L07_lo, L12_lo, L17_lo, L22_lo)
  488. local C2_hi = bit32_bxor(L02_hi, L07_hi, L12_hi, L17_hi, L22_hi)
  489. local C3_lo = bit32_bxor(L03_lo, L08_lo, L13_lo, L18_lo, L23_lo)
  490. local C3_hi = bit32_bxor(L03_hi, L08_hi, L13_hi, L18_hi, L23_hi)
  491. local C4_lo = bit32_bxor(L04_lo, L09_lo, L14_lo, L19_lo, L24_lo)
  492. local C4_hi = bit32_bxor(L04_hi, L09_hi, L14_hi, L19_hi, L24_hi)
  493. local C5_lo = bit32_bxor(L05_lo, L10_lo, L15_lo, L20_lo, L25_lo)
  494. local C5_hi = bit32_bxor(L05_hi, L10_hi, L15_hi, L20_hi, L25_hi)
  495.  
  496. local D_lo = bit32_bxor(C1_lo, C3_lo * 2 + (C3_hi % TWO_POW_32 - C3_hi % TWO_POW_31) / TWO_POW_31)
  497. local D_hi = bit32_bxor(C1_hi, C3_hi * 2 + (C3_lo % TWO_POW_32 - C3_lo % TWO_POW_31) / TWO_POW_31)
  498.  
  499. local T0_lo = bit32_bxor(D_lo, L02_lo)
  500. local T0_hi = bit32_bxor(D_hi, L02_hi)
  501. local T1_lo = bit32_bxor(D_lo, L07_lo)
  502. local T1_hi = bit32_bxor(D_hi, L07_hi)
  503. local T2_lo = bit32_bxor(D_lo, L12_lo)
  504. local T2_hi = bit32_bxor(D_hi, L12_hi)
  505. local T3_lo = bit32_bxor(D_lo, L17_lo)
  506. local T3_hi = bit32_bxor(D_hi, L17_hi)
  507. local T4_lo = bit32_bxor(D_lo, L22_lo)
  508. local T4_hi = bit32_bxor(D_hi, L22_hi)
  509.  
  510. L02_lo = (T1_lo % TWO_POW_32 - T1_lo % TWO_POW_20) / TWO_POW_20 + T1_hi * TWO_POW_12
  511. L02_hi = (T1_hi % TWO_POW_32 - T1_hi % TWO_POW_20) / TWO_POW_20 + T1_lo * TWO_POW_12
  512. L07_lo = (T3_lo % TWO_POW_32 - T3_lo % TWO_POW_19) / TWO_POW_19 + T3_hi * TWO_POW_13
  513. L07_hi = (T3_hi % TWO_POW_32 - T3_hi % TWO_POW_19) / TWO_POW_19 + T3_lo * TWO_POW_13
  514. L12_lo = T0_lo * 2 + (T0_hi % TWO_POW_32 - T0_hi % TWO_POW_31) / TWO_POW_31
  515. L12_hi = T0_hi * 2 + (T0_lo % TWO_POW_32 - T0_lo % TWO_POW_31) / TWO_POW_31
  516. L17_lo = T2_lo * TWO_POW_10 + (T2_hi % TWO_POW_32 - T2_hi % TWO_POW_22) / TWO_POW_22
  517. L17_hi = T2_hi * TWO_POW_10 + (T2_lo % TWO_POW_32 - T2_lo % TWO_POW_22) / TWO_POW_22
  518. L22_lo = T4_lo * TWO_POW_2 + (T4_hi % TWO_POW_32 - T4_hi % TWO_POW_30) / TWO_POW_30
  519. L22_hi = T4_hi * TWO_POW_2 + (T4_lo % TWO_POW_32 - T4_lo % TWO_POW_30) / TWO_POW_30
  520.  
  521. D_lo = bit32_bxor(C2_lo, C4_lo * 2 + (C4_hi % TWO_POW_32 - C4_hi % TWO_POW_31) / TWO_POW_31)
  522. D_hi = bit32_bxor(C2_hi, C4_hi * 2 + (C4_lo % TWO_POW_32 - C4_lo % TWO_POW_31) / TWO_POW_31)
  523.  
  524. T0_lo = bit32_bxor(D_lo, L03_lo)
  525. T0_hi = bit32_bxor(D_hi, L03_hi)
  526. T1_lo = bit32_bxor(D_lo, L08_lo)
  527. T1_hi = bit32_bxor(D_hi, L08_hi)
  528. T2_lo = bit32_bxor(D_lo, L13_lo)
  529. T2_hi = bit32_bxor(D_hi, L13_hi)
  530. T3_lo = bit32_bxor(D_lo, L18_lo)
  531. T3_hi = bit32_bxor(D_hi, L18_hi)
  532. T4_lo = bit32_bxor(D_lo, L23_lo)
  533. T4_hi = bit32_bxor(D_hi, L23_hi)
  534.  
  535. L03_lo = (T2_lo % TWO_POW_32 - T2_lo % TWO_POW_21) / TWO_POW_21 + T2_hi * TWO_POW_11
  536. L03_hi = (T2_hi % TWO_POW_32 - T2_hi % TWO_POW_21) / TWO_POW_21 + T2_lo * TWO_POW_11
  537. L08_lo = (T4_lo % TWO_POW_32 - T4_lo % TWO_POW_3) / TWO_POW_3 + T4_hi * TWO_POW_29 % TWO_POW_32
  538. L08_hi = (T4_hi % TWO_POW_32 - T4_hi % TWO_POW_3) / TWO_POW_3 + T4_lo * TWO_POW_29 % TWO_POW_32
  539. L13_lo = T1_lo * TWO_POW_6 + (T1_hi % TWO_POW_32 - T1_hi % TWO_POW_26) / TWO_POW_26
  540. L13_hi = T1_hi * TWO_POW_6 + (T1_lo % TWO_POW_32 - T1_lo % TWO_POW_26) / TWO_POW_26
  541. L18_lo = T3_lo * TWO_POW_15 + (T3_hi % TWO_POW_32 - T3_hi % TWO_POW_17) / TWO_POW_17
  542. L18_hi = T3_hi * TWO_POW_15 + (T3_lo % TWO_POW_32 - T3_lo % TWO_POW_17) / TWO_POW_17
  543. L23_lo = (T0_lo % TWO_POW_32 - T0_lo % TWO_POW_2) / TWO_POW_2 + T0_hi * TWO_POW_30 % TWO_POW_32
  544. L23_hi = (T0_hi % TWO_POW_32 - T0_hi % TWO_POW_2) / TWO_POW_2 + T0_lo * TWO_POW_30 % TWO_POW_32
  545.  
  546. D_lo = bit32_bxor(C3_lo, C5_lo * 2 + (C5_hi % TWO_POW_32 - C5_hi % TWO_POW_31) / TWO_POW_31)
  547. D_hi = bit32_bxor(C3_hi, C5_hi * 2 + (C5_lo % TWO_POW_32 - C5_lo % TWO_POW_31) / TWO_POW_31)
  548.  
  549. T0_lo = bit32_bxor(D_lo, L04_lo)
  550. T0_hi = bit32_bxor(D_hi, L04_hi)
  551. T1_lo = bit32_bxor(D_lo, L09_lo)
  552. T1_hi = bit32_bxor(D_hi, L09_hi)
  553. T2_lo = bit32_bxor(D_lo, L14_lo)
  554. T2_hi = bit32_bxor(D_hi, L14_hi)
  555. T3_lo = bit32_bxor(D_lo, L19_lo)
  556. T3_hi = bit32_bxor(D_hi, L19_hi)
  557. T4_lo = bit32_bxor(D_lo, L24_lo)
  558. T4_hi = bit32_bxor(D_hi, L24_hi)
  559.  
  560. L04_lo = T3_lo * TWO_POW_21 % TWO_POW_32 + (T3_hi % TWO_POW_32 - T3_hi % TWO_POW_11) / TWO_POW_11
  561. L04_hi = T3_hi * TWO_POW_21 % TWO_POW_32 + (T3_lo % TWO_POW_32 - T3_lo % TWO_POW_11) / TWO_POW_11
  562. L09_lo = T0_lo * TWO_POW_28 % TWO_POW_32 + (T0_hi % TWO_POW_32 - T0_hi % TWO_POW_4) / TWO_POW_4
  563. L09_hi = T0_hi * TWO_POW_28 % TWO_POW_32 + (T0_lo % TWO_POW_32 - T0_lo % TWO_POW_4) / TWO_POW_4
  564. L14_lo = T2_lo * TWO_POW_25 % TWO_POW_32 + (T2_hi % TWO_POW_32 - T2_hi % TWO_POW_7) / TWO_POW_7
  565. L14_hi = T2_hi * TWO_POW_25 % TWO_POW_32 + (T2_lo % TWO_POW_32 - T2_lo % TWO_POW_7) / TWO_POW_7
  566. L19_lo = (T4_lo % TWO_POW_32 - T4_lo % TWO_POW_8) / TWO_POW_8 + T4_hi * TWO_POW_24 % TWO_POW_32
  567. L19_hi = (T4_hi % TWO_POW_32 - T4_hi % TWO_POW_8) / TWO_POW_8 + T4_lo * TWO_POW_24 % TWO_POW_32
  568. L24_lo = (T1_lo % TWO_POW_32 - T1_lo % TWO_POW_9) / TWO_POW_9 + T1_hi * TWO_POW_23 % TWO_POW_32
  569. L24_hi = (T1_hi % TWO_POW_32 - T1_hi % TWO_POW_9) / TWO_POW_9 + T1_lo * TWO_POW_23 % TWO_POW_32
  570.  
  571. D_lo = bit32_bxor(C4_lo, C1_lo * 2 + (C1_hi % TWO_POW_32 - C1_hi % TWO_POW_31) / TWO_POW_31)
  572. D_hi = bit32_bxor(C4_hi, C1_hi * 2 + (C1_lo % TWO_POW_32 - C1_lo % TWO_POW_31) / TWO_POW_31)
  573.  
  574. T0_lo = bit32_bxor(D_lo, L05_lo)
  575. T0_hi = bit32_bxor(D_hi, L05_hi)
  576. T1_lo = bit32_bxor(D_lo, L10_lo)
  577. T1_hi = bit32_bxor(D_hi, L10_hi)
  578. T2_lo = bit32_bxor(D_lo, L15_lo)
  579. T2_hi = bit32_bxor(D_hi, L15_hi)
  580. T3_lo = bit32_bxor(D_lo, L20_lo)
  581. T3_hi = bit32_bxor(D_hi, L20_hi)
  582. T4_lo = bit32_bxor(D_lo, L25_lo)
  583. T4_hi = bit32_bxor(D_hi, L25_hi)
  584.  
  585. L05_lo = T4_lo * TWO_POW_14 + (T4_hi % TWO_POW_32 - T4_hi % TWO_POW_18) / TWO_POW_18
  586. L05_hi = T4_hi * TWO_POW_14 + (T4_lo % TWO_POW_32 - T4_lo % TWO_POW_18) / TWO_POW_18
  587. L10_lo = T1_lo * TWO_POW_20 % TWO_POW_32 + (T1_hi % TWO_POW_32 - T1_hi % TWO_POW_12) / TWO_POW_12
  588. L10_hi = T1_hi * TWO_POW_20 % TWO_POW_32 + (T1_lo % TWO_POW_32 - T1_lo % TWO_POW_12) / TWO_POW_12
  589. L15_lo = T3_lo * TWO_POW_8 + (T3_hi % TWO_POW_32 - T3_hi % TWO_POW_24) / TWO_POW_24
  590. L15_hi = T3_hi * TWO_POW_8 + (T3_lo % TWO_POW_32 - T3_lo % TWO_POW_24) / TWO_POW_24
  591. L20_lo = T0_lo * TWO_POW_27 % TWO_POW_32 + (T0_hi % TWO_POW_32 - T0_hi % TWO_POW_5) / TWO_POW_5
  592. L20_hi = T0_hi * TWO_POW_27 % TWO_POW_32 + (T0_lo % TWO_POW_32 - T0_lo % TWO_POW_5) / TWO_POW_5
  593. L25_lo = (T2_lo % TWO_POW_32 - T2_lo % TWO_POW_25) / TWO_POW_25 + T2_hi * TWO_POW_7
  594. L25_hi = (T2_hi % TWO_POW_32 - T2_hi % TWO_POW_25) / TWO_POW_25 + T2_lo * TWO_POW_7
  595.  
  596. D_lo = bit32_bxor(C5_lo, C2_lo * 2 + (C2_hi % TWO_POW_32 - C2_hi % TWO_POW_31) / TWO_POW_31)
  597. D_hi = bit32_bxor(C5_hi, C2_hi * 2 + (C2_lo % TWO_POW_32 - C2_lo % TWO_POW_31) / TWO_POW_31)
  598.  
  599. T1_lo = bit32_bxor(D_lo, L06_lo)
  600. T1_hi = bit32_bxor(D_hi, L06_hi)
  601. T2_lo = bit32_bxor(D_lo, L11_lo)
  602. T2_hi = bit32_bxor(D_hi, L11_hi)
  603. T3_lo = bit32_bxor(D_lo, L16_lo)
  604. T3_hi = bit32_bxor(D_hi, L16_hi)
  605. T4_lo = bit32_bxor(D_lo, L21_lo)
  606. T4_hi = bit32_bxor(D_hi, L21_hi)
  607.  
  608. L06_lo = T2_lo * TWO_POW_3 + (T2_hi % TWO_POW_32 - T2_hi % TWO_POW_29) / TWO_POW_29
  609. L06_hi = T2_hi * TWO_POW_3 + (T2_lo % TWO_POW_32 - T2_lo % TWO_POW_29) / TWO_POW_29
  610. L11_lo = T4_lo * TWO_POW_18 + (T4_hi % TWO_POW_32 - T4_hi % TWO_POW_14) / TWO_POW_14
  611. L11_hi = T4_hi * TWO_POW_18 + (T4_lo % TWO_POW_32 - T4_lo % TWO_POW_14) / TWO_POW_14
  612. L16_lo = (T1_lo % TWO_POW_32 - T1_lo % TWO_POW_28) / TWO_POW_28 + T1_hi * TWO_POW_4
  613. L16_hi = (T1_hi % TWO_POW_32 - T1_hi % TWO_POW_28) / TWO_POW_28 + T1_lo * TWO_POW_4
  614. L21_lo = (T3_lo % TWO_POW_32 - T3_lo % TWO_POW_23) / TWO_POW_23 + T3_hi * TWO_POW_9
  615. L21_hi = (T3_hi % TWO_POW_32 - T3_hi % TWO_POW_23) / TWO_POW_23 + T3_lo * TWO_POW_9
  616.  
  617. L01_lo = bit32_bxor(D_lo, L01_lo)
  618. L01_hi = bit32_bxor(D_hi, L01_hi)
  619. L01_lo, L02_lo, L03_lo, L04_lo, L05_lo = bit32_bxor(L01_lo, bit32_band(-1 - L02_lo, L03_lo)), bit32_bxor(L02_lo, bit32_band(-1 - L03_lo, L04_lo)), bit32_bxor(L03_lo, bit32_band(-1 - L04_lo, L05_lo)), bit32_bxor(L04_lo, bit32_band(-1 - L05_lo, L01_lo)), bit32_bxor(L05_lo, bit32_band(-1 - L01_lo, L02_lo))
  620. L01_hi, L02_hi, L03_hi, L04_hi, L05_hi = bit32_bxor(L01_hi, bit32_band(-1 - L02_hi, L03_hi)), bit32_bxor(L02_hi, bit32_band(-1 - L03_hi, L04_hi)), bit32_bxor(L03_hi, bit32_band(-1 - L04_hi, L05_hi)), bit32_bxor(L04_hi, bit32_band(-1 - L05_hi, L01_hi)), bit32_bxor(L05_hi, bit32_band(-1 - L01_hi, L02_hi))
  621. L06_lo, L07_lo, L08_lo, L09_lo, L10_lo = bit32_bxor(L09_lo, bit32_band(-1 - L10_lo, L06_lo)), bit32_bxor(L10_lo, bit32_band(-1 - L06_lo, L07_lo)), bit32_bxor(L06_lo, bit32_band(-1 - L07_lo, L08_lo)), bit32_bxor(L07_lo, bit32_band(-1 - L08_lo, L09_lo)), bit32_bxor(L08_lo, bit32_band(-1 - L09_lo, L10_lo))
  622. L06_hi, L07_hi, L08_hi, L09_hi, L10_hi = bit32_bxor(L09_hi, bit32_band(-1 - L10_hi, L06_hi)), bit32_bxor(L10_hi, bit32_band(-1 - L06_hi, L07_hi)), bit32_bxor(L06_hi, bit32_band(-1 - L07_hi, L08_hi)), bit32_bxor(L07_hi, bit32_band(-1 - L08_hi, L09_hi)), bit32_bxor(L08_hi, bit32_band(-1 - L09_hi, L10_hi))
  623. L11_lo, L12_lo, L13_lo, L14_lo, L15_lo = bit32_bxor(L12_lo, bit32_band(-1 - L13_lo, L14_lo)), bit32_bxor(L13_lo, bit32_band(-1 - L14_lo, L15_lo)), bit32_bxor(L14_lo, bit32_band(-1 - L15_lo, L11_lo)), bit32_bxor(L15_lo, bit32_band(-1 - L11_lo, L12_lo)), bit32_bxor(L11_lo, bit32_band(-1 - L12_lo, L13_lo))
  624. L11_hi, L12_hi, L13_hi, L14_hi, L15_hi = bit32_bxor(L12_hi, bit32_band(-1 - L13_hi, L14_hi)), bit32_bxor(L13_hi, bit32_band(-1 - L14_hi, L15_hi)), bit32_bxor(L14_hi, bit32_band(-1 - L15_hi, L11_hi)), bit32_bxor(L15_hi, bit32_band(-1 - L11_hi, L12_hi)), bit32_bxor(L11_hi, bit32_band(-1 - L12_hi, L13_hi))
  625. L16_lo, L17_lo, L18_lo, L19_lo, L20_lo = bit32_bxor(L20_lo, bit32_band(-1 - L16_lo, L17_lo)), bit32_bxor(L16_lo, bit32_band(-1 - L17_lo, L18_lo)), bit32_bxor(L17_lo, bit32_band(-1 - L18_lo, L19_lo)), bit32_bxor(L18_lo, bit32_band(-1 - L19_lo, L20_lo)), bit32_bxor(L19_lo, bit32_band(-1 - L20_lo, L16_lo))
  626. L16_hi, L17_hi, L18_hi, L19_hi, L20_hi = bit32_bxor(L20_hi, bit32_band(-1 - L16_hi, L17_hi)), bit32_bxor(L16_hi, bit32_band(-1 - L17_hi, L18_hi)), bit32_bxor(L17_hi, bit32_band(-1 - L18_hi, L19_hi)), bit32_bxor(L18_hi, bit32_band(-1 - L19_hi, L20_hi)), bit32_bxor(L19_hi, bit32_band(-1 - L20_hi, L16_hi))
  627. L21_lo, L22_lo, L23_lo, L24_lo, L25_lo = bit32_bxor(L23_lo, bit32_band(-1 - L24_lo, L25_lo)), bit32_bxor(L24_lo, bit32_band(-1 - L25_lo, L21_lo)), bit32_bxor(L25_lo, bit32_band(-1 - L21_lo, L22_lo)), bit32_bxor(L21_lo, bit32_band(-1 - L22_lo, L23_lo)), bit32_bxor(L22_lo, bit32_band(-1 - L23_lo, L24_lo))
  628. L21_hi, L22_hi, L23_hi, L24_hi, L25_hi = bit32_bxor(L23_hi, bit32_band(-1 - L24_hi, L25_hi)), bit32_bxor(L24_hi, bit32_band(-1 - L25_hi, L21_hi)), bit32_bxor(L25_hi, bit32_band(-1 - L21_hi, L22_hi)), bit32_bxor(L21_hi, bit32_band(-1 - L22_hi, L23_hi)), bit32_bxor(L22_hi, bit32_band(-1 - L23_hi, L24_hi))
  629. L01_lo = bit32_bxor(L01_lo, RC_lo[round_idx])
  630. L01_hi = L01_hi + RC_hi[round_idx] -- RC_hi[] is either 0 or 0x80000000, so we could use fast addition instead of slow XOR
  631. end
  632.  
  633. lanes_lo[1] = L01_lo
  634. lanes_hi[1] = L01_hi
  635. lanes_lo[2] = L02_lo
  636. lanes_hi[2] = L02_hi
  637. lanes_lo[3] = L03_lo
  638. lanes_hi[3] = L03_hi
  639. lanes_lo[4] = L04_lo
  640. lanes_hi[4] = L04_hi
  641. lanes_lo[5] = L05_lo
  642. lanes_hi[5] = L05_hi
  643. lanes_lo[6] = L06_lo
  644. lanes_hi[6] = L06_hi
  645. lanes_lo[7] = L07_lo
  646. lanes_hi[7] = L07_hi
  647. lanes_lo[8] = L08_lo
  648. lanes_hi[8] = L08_hi
  649. lanes_lo[9] = L09_lo
  650. lanes_hi[9] = L09_hi
  651. lanes_lo[10] = L10_lo
  652. lanes_hi[10] = L10_hi
  653. lanes_lo[11] = L11_lo
  654. lanes_hi[11] = L11_hi
  655. lanes_lo[12] = L12_lo
  656. lanes_hi[12] = L12_hi
  657. lanes_lo[13] = L13_lo
  658. lanes_hi[13] = L13_hi
  659. lanes_lo[14] = L14_lo
  660. lanes_hi[14] = L14_hi
  661. lanes_lo[15] = L15_lo
  662. lanes_hi[15] = L15_hi
  663. lanes_lo[16] = L16_lo
  664. lanes_hi[16] = L16_hi
  665. lanes_lo[17] = L17_lo
  666. lanes_hi[17] = L17_hi
  667. lanes_lo[18] = L18_lo
  668. lanes_hi[18] = L18_hi
  669. lanes_lo[19] = L19_lo
  670. lanes_hi[19] = L19_hi
  671. lanes_lo[20] = L20_lo
  672. lanes_hi[20] = L20_hi
  673. lanes_lo[21] = L21_lo
  674. lanes_hi[21] = L21_hi
  675. lanes_lo[22] = L22_lo
  676. lanes_hi[22] = L22_hi
  677. lanes_lo[23] = L23_lo
  678. lanes_hi[23] = L23_hi
  679. lanes_lo[24] = L24_lo
  680. lanes_hi[24] = L24_hi
  681. lanes_lo[25] = L25_lo
  682. lanes_hi[25] = L25_hi
  683. end
  684. end
  685.  
  686. --------------------------------------------------------------------------------
  687. -- MAGIC NUMBERS CALCULATOR
  688. --------------------------------------------------------------------------------
  689. -- Q:
  690. -- Is 53-bit "double" math enough to calculate square roots and cube roots of primes with 64 correct bits after decimal point?
  691. -- A:
  692. -- Yes, 53-bit "double" arithmetic is enough.
  693. -- We could obtain first 40 bits by direct calculation of p^(1/3) and next 40 bits by one step of Newton's method.
  694. do
  695. local function mul(src1, src2, factor, result_length)
  696. -- src1, src2 - long integers (arrays of digits in base TWO_POW_24)
  697. -- factor - small integer
  698. -- returns long integer result (src1 * src2 * factor) and its floating point approximation
  699. local result, carry, value, weight = tcreate(result_length), 0, 0, 1
  700. for j = 1, result_length do
  701. for k = max(1, j + 1 - #src2), min(j, #src1) do
  702. carry = carry + factor * src1[k] * src2[j + 1 - k] -- "int32" is not enough for multiplication result, that's why "factor" must be of type "double"
  703. end
  704.  
  705. local digit = carry % TWO_POW_24
  706. result[j] = floor(digit)
  707. carry = (carry - digit) / TWO_POW_24
  708. value = value + digit * weight
  709. weight = weight * TWO_POW_24
  710. end
  711.  
  712. return result, value
  713. end
  714.  
  715. local idx, step, p, one, sqrt_hi, sqrt_lo = 0, {4, 1, 2, -2, 2}, 4, {1}, sha2_H_hi, sha2_H_lo
  716. repeat
  717. p = p + step[p % 6]
  718. local d = 1
  719. repeat
  720. d = d + step[d % 6]
  721. if d * d > p then
  722. -- next prime number is found
  723. local root = p ^ (1 / 3)
  724. local R = root * TWO_POW_40
  725. R = mul(tcreate(1, floor(R)), one, 1, 2)
  726. local _, delta = mul(R, mul(R, R, 1, 4), -1, 4)
  727. local hi = R[2] % 65536 * 65536 + floor(R[1] / 256)
  728. local lo = R[1] % 256 * 16777216 + floor(delta * (TWO_POW_NEG_56 / 3) * root / p)
  729.  
  730. if idx < 16 then
  731. root = sqrt(p)
  732. R = root * TWO_POW_40
  733. R = mul(tcreate(1, floor(R)), one, 1, 2)
  734. _, delta = mul(R, R, -1, 2)
  735. local hi = R[2] % 65536 * 65536 + floor(R[1] / 256)
  736. local lo = R[1] % 256 * 16777216 + floor(delta * TWO_POW_NEG_17 / root)
  737. local idx = idx % 8 + 1
  738. sha2_H_ext256[224][idx] = lo
  739. sqrt_hi[idx], sqrt_lo[idx] = hi, lo + hi * hi_factor
  740. if idx > 7 then
  741. sqrt_hi, sqrt_lo = sha2_H_ext512_hi[384], sha2_H_ext512_lo[384]
  742. end
  743. end
  744.  
  745. idx = idx + 1
  746. sha2_K_hi[idx], sha2_K_lo[idx] = hi, lo % K_lo_modulo + hi * hi_factor
  747. break
  748. end
  749. until p % d == 0
  750. until idx > 79
  751. end
  752.  
  753. -- Calculating IVs for SHA512/224 and SHA512/256
  754. for width = 224, 256, 32 do
  755. local H_lo, H_hi = {}, nil
  756. if XOR64A5 then
  757. for j = 1, 8 do
  758. H_lo[j] = XOR64A5(sha2_H_lo[j])
  759. end
  760. else
  761. H_hi = {}
  762. for j = 1, 8 do
  763. H_lo[j] = bit32_bxor(sha2_H_lo[j], 0xA5A5A5A5) % 4294967296
  764. H_hi[j] = bit32_bxor(sha2_H_hi[j], 0xA5A5A5A5) % 4294967296
  765. end
  766. end
  767.  
  768. sha512_feed_128(H_lo, H_hi, "SHA-512/" .. tostring(width) .. "\128" .. rep("\0", 115) .. "\88", 0, 128)
  769. sha2_H_ext512_lo[width] = H_lo
  770. sha2_H_ext512_hi[width] = H_hi
  771. end
  772.  
  773. -- Constants for MD5
  774. do
  775. for idx = 1, 64 do
  776. -- we can't use formula floor(abs(sin(idx))*TWO_POW_32) because its result may be beyond integer range on Lua built with 32-bit integers
  777. local hi, lo = modf(abs(sin(idx)) * TWO_POW_16)
  778. md5_K[idx] = hi * 65536 + floor(lo * TWO_POW_16)
  779. end
  780. end
  781.  
  782. -- Constants for SHA3
  783. do
  784. local sh_reg = 29
  785. local function next_bit()
  786. local r = sh_reg % 2
  787. sh_reg = bit32_bxor((sh_reg - r) / 2, 142 * r)
  788. return r
  789. end
  790.  
  791. for idx = 1, 24 do
  792. local lo, m = 0, nil
  793. for _ = 1, 6 do
  794. m = m and m * m * 2 or 1
  795. lo = lo + next_bit() * m
  796. end
  797.  
  798. local hi = next_bit() * m
  799. sha3_RC_hi[idx], sha3_RC_lo[idx] = hi, lo + hi * hi_factor_keccak
  800. end
  801. end
  802.  
  803. --------------------------------------------------------------------------------
  804. -- MAIN FUNCTIONS
  805. --------------------------------------------------------------------------------
  806. local function sha256ext(width, message)
  807. -- Create an instance (private objects for current calculation)
  808. local Array256 = sha2_H_ext256[width] -- # == 8
  809. local length, tail = 0, ""
  810. local H = tcreate(8)
  811. H[1], H[2], H[3], H[4], H[5], H[6], H[7], H[8] = Array256[1], Array256[2], Array256[3], Array256[4], Array256[5], Array256[6], Array256[7], Array256[8]
  812.  
  813. local function partial(message_part)
  814. if message_part then
  815. local partLength = #message_part
  816. if tail then
  817. length = length + partLength
  818. local offs = 0
  819. local tailLength = #tail
  820. if tail ~= "" and tailLength + partLength >= 64 then
  821. offs = 64 - tailLength
  822. sha256_feed_64(H, tail .. sub(message_part, 1, offs), 0, 64)
  823. tail = ""
  824. end
  825.  
  826. local size = partLength - offs
  827. local size_tail = size % 64
  828. sha256_feed_64(H, message_part, offs, size - size_tail)
  829. tail = tail .. sub(message_part, partLength + 1 - size_tail)
  830. return partial
  831. else
  832. error("Adding more chunks is not allowed after receiving the result", 2)
  833. end
  834. else
  835. if tail then
  836. local final_blocks = tcreate(10) --{tail, "\128", rep("\0", (-9 - length) % 64 + 1)}
  837. final_blocks[1] = tail
  838. final_blocks[2] = "\128"
  839. final_blocks[3] = rep("\0", (-9 - length) % 64 + 1)
  840.  
  841. tail = nil
  842. -- Assuming user data length is shorter than (TWO_POW_53)-9 bytes
  843. -- Anyway, it looks very unrealistic that someone would spend more than a year of calculations to process TWO_POW_53 bytes of data by using this Lua script :-)
  844. -- TWO_POW_53 bytes = TWO_POW_56 bits, so "bit-counter" fits in 7 bytes
  845. length = length * (8 / TWO56_POW_7) -- convert "byte-counter" to "bit-counter" and move decimal point to the left
  846. for j = 4, 10 do
  847. length = length % 1 * 256
  848. final_blocks[j] = char(floor(length))
  849. end
  850.  
  851. final_blocks = tconcat(final_blocks)
  852. sha256_feed_64(H, final_blocks, 0, #final_blocks)
  853. local max_reg = width / 32
  854. for j = 1, max_reg do
  855. H[j] = format("%08x", H[j] % 4294967296)
  856. end
  857.  
  858. H = tconcat(H, "", 1, max_reg)
  859. end
  860.  
  861. return H
  862. end
  863. end
  864.  
  865. if message then
  866. -- Actually perform calculations and return the SHA256 digest of a message
  867. return partial(message)()
  868. else
  869. -- Return function for chunk-by-chunk loading
  870. -- User should feed every chunk of input data as single argument to this function and finally get SHA256 digest by invoking this function without an argument
  871. return partial
  872. end
  873. end
  874.  
  875. local function sha512ext(width, message)
  876.  
  877. -- Create an instance (private objects for current calculation)
  878. local length, tail, H_lo, H_hi = 0, "", tpack(tunpack(sha2_H_ext512_lo[width])), not HEX64 and tpack(tunpack(sha2_H_ext512_hi[width]))
  879.  
  880. local function partial(message_part)
  881. if message_part then
  882. local partLength = #message_part
  883. if tail then
  884. length = length + partLength
  885. local offs = 0
  886. if tail ~= "" and #tail + partLength >= 128 then
  887. offs = 128 - #tail
  888. sha512_feed_128(H_lo, H_hi, tail .. sub(message_part, 1, offs), 0, 128)
  889. tail = ""
  890. end
  891.  
  892. local size = partLength - offs
  893. local size_tail = size % 128
  894. sha512_feed_128(H_lo, H_hi, message_part, offs, size - size_tail)
  895. tail = tail .. sub(message_part, partLength + 1 - size_tail)
  896. return partial
  897. else
  898. error("Adding more chunks is not allowed after receiving the result", 2)
  899. end
  900. else
  901. if tail then
  902. local final_blocks = tcreate(3) --{tail, "\128", rep("\0", (-17-length) % 128 + 9)}
  903. final_blocks[1] = tail
  904. final_blocks[2] = "\128"
  905. final_blocks[3] = rep("\0", (-17 - length) % 128 + 9)
  906.  
  907. tail = nil
  908. -- Assuming user data length is shorter than (TWO_POW_53)-17 bytes
  909. -- TWO_POW_53 bytes = TWO_POW_56 bits, so "bit-counter" fits in 7 bytes
  910. length = length * (8 / TWO56_POW_7) -- convert "byte-counter" to "bit-counter" and move floating point to the left
  911. for j = 4, 10 do
  912. length = length % 1 * 256
  913. final_blocks[j] = char(floor(length))
  914. end
  915.  
  916. final_blocks = tconcat(final_blocks)
  917. sha512_feed_128(H_lo, H_hi, final_blocks, 0, #final_blocks)
  918. local max_reg = ceil(width / 64)
  919.  
  920. if HEX64 then
  921. for j = 1, max_reg do
  922. H_lo[j] = HEX64(H_lo[j])
  923. end
  924. else
  925. for j = 1, max_reg do
  926. H_lo[j] = format("%08x", H_hi[j] % 4294967296) .. format("%08x", H_lo[j] % 4294967296)
  927. end
  928.  
  929. H_hi = nil
  930. end
  931.  
  932. H_lo = sub(tconcat(H_lo, "", 1, max_reg), 1, width / 4)
  933. end
  934.  
  935. return H_lo
  936. end
  937. end
  938.  
  939. if message then
  940. -- Actually perform calculations and return the SHA512 digest of a message
  941. return partial(message)()
  942. else
  943. -- Return function for chunk-by-chunk loading
  944. -- User should feed every chunk of input data as single argument to this function and finally get SHA512 digest by invoking this function without an argument
  945. return partial
  946. end
  947. end
  948.  
  949. local function md5(message)
  950.  
  951. -- Create an instance (private objects for current calculation)
  952. local H, length, tail = tcreate(4), 0, ""
  953. H[1], H[2], H[3], H[4] = md5_sha1_H[1], md5_sha1_H[2], md5_sha1_H[3], md5_sha1_H[4]
  954.  
  955. local function partial(message_part)
  956. if message_part then
  957. local partLength = #message_part
  958. if tail then
  959. length = length + partLength
  960. local offs = 0
  961. if tail ~= "" and #tail + partLength >= 64 then
  962. offs = 64 - #tail
  963. md5_feed_64(H, tail .. sub(message_part, 1, offs), 0, 64)
  964. tail = ""
  965. end
  966.  
  967. local size = partLength - offs
  968. local size_tail = size % 64
  969. md5_feed_64(H, message_part, offs, size - size_tail)
  970. tail = tail .. sub(message_part, partLength + 1 - size_tail)
  971. return partial
  972. else
  973. error("Adding more chunks is not allowed after receiving the result", 2)
  974. end
  975. else
  976. if tail then
  977. local final_blocks = tcreate(3) --{tail, "\128", rep("\0", (-9 - length) % 64)}
  978. final_blocks[1] = tail
  979. final_blocks[2] = "\128"
  980. final_blocks[3] = rep("\0", (-9 - length) % 64)
  981. tail = nil
  982. length = length * 8 -- convert "byte-counter" to "bit-counter"
  983. for j = 4, 11 do
  984. local low_byte = length % 256
  985. final_blocks[j] = char(low_byte)
  986. length = (length - low_byte) / 256
  987. end
  988.  
  989. final_blocks = tconcat(final_blocks)
  990. md5_feed_64(H, final_blocks, 0, #final_blocks)
  991. for j = 1, 4 do
  992. H[j] = format("%08x", H[j] % 4294967296)
  993. end
  994.  
  995. H = gsub(tconcat(H), "(..)(..)(..)(..)", "%4%3%2%1")
  996. end
  997.  
  998. return H
  999. end
  1000. end
  1001.  
  1002. if message then
  1003. -- Actually perform calculations and return the MD5 digest of a message
  1004. return partial(message)()
  1005. else
  1006. -- Return function for chunk-by-chunk loading
  1007. -- User should feed every chunk of input data as single argument to this function and finally get MD5 digest by invoking this function without an argument
  1008. return partial
  1009. end
  1010. end
  1011.  
  1012. local function sha1(message)
  1013. -- Create an instance (private objects for current calculation)
  1014. local H, length, tail = tpack(tunpack(md5_sha1_H)), 0, ""
  1015.  
  1016. local function partial(message_part)
  1017. if message_part then
  1018. local partLength = #message_part
  1019. if tail then
  1020. length = length + partLength
  1021. local offs = 0
  1022. if tail ~= "" and #tail + partLength >= 64 then
  1023. offs = 64 - #tail
  1024. sha1_feed_64(H, tail .. sub(message_part, 1, offs), 0, 64)
  1025. tail = ""
  1026. end
  1027.  
  1028. local size = partLength - offs
  1029. local size_tail = size % 64
  1030. sha1_feed_64(H, message_part, offs, size - size_tail)
  1031. tail = tail .. sub(message_part, partLength + 1 - size_tail)
  1032. return partial
  1033. else
  1034. error("Adding more chunks is not allowed after receiving the result", 2)
  1035. end
  1036. else
  1037. if tail then
  1038. local final_blocks = tcreate(10) --{tail, "\128", rep("\0", (-9 - length) % 64 + 1)}
  1039. final_blocks[1] = tail
  1040. final_blocks[2] = "\128"
  1041. final_blocks[3] = rep("\0", (-9 - length) % 64 + 1)
  1042. tail = nil
  1043.  
  1044. -- Assuming user data length is shorter than (TWO_POW_53)-9 bytes
  1045. -- TWO_POW_53 bytes = TWO_POW_56 bits, so "bit-counter" fits in 7 bytes
  1046. length = length * (8 / TWO56_POW_7) -- convert "byte-counter" to "bit-counter" and move decimal point to the left
  1047. for j = 4, 10 do
  1048. length = length % 1 * 256
  1049. final_blocks[j] = char(floor(length))
  1050. end
  1051.  
  1052. final_blocks = tconcat(final_blocks)
  1053. sha1_feed_64(H, final_blocks, 0, #final_blocks)
  1054. for j = 1, 5 do
  1055. H[j] = format("%08x", H[j] % 4294967296)
  1056. end
  1057.  
  1058. H = tconcat(H)
  1059. end
  1060.  
  1061. return H
  1062. end
  1063. end
  1064.  
  1065. if message then
  1066. -- Actually perform calculations and return the SHA-1 digest of a message
  1067. return partial(message)()
  1068. else
  1069. -- Return function for chunk-by-chunk loading
  1070. -- User should feed every chunk of input data as single argument to this function and finally get SHA-1 digest by invoking this function without an argument
  1071. return partial
  1072. end
  1073. end
  1074.  
  1075. local function keccak(block_size_in_bytes, digest_size_in_bytes, is_SHAKE, message)
  1076. -- "block_size_in_bytes" is multiple of 8
  1077. if type(digest_size_in_bytes) ~= "number" then
  1078. -- arguments in SHAKE are swapped:
  1079. -- NIST FIPS 202 defines SHAKE(message,num_bits)
  1080. -- this module defines SHAKE(num_bytes,message)
  1081. -- it's easy to forget about this swap, hence the check
  1082. error("Argument 'digest_size_in_bytes' must be a number", 2)
  1083. end
  1084.  
  1085. -- Create an instance (private objects for current calculation)
  1086. local tail, lanes_lo, lanes_hi = "", tcreate(25, 0), hi_factor_keccak == 0 and tcreate(25, 0)
  1087. local result
  1088.  
  1089. --~ pad the input N using the pad function, yielding a padded bit string P with a length divisible by r (such that n = len(P)/r is integer),
  1090. --~ break P into n consecutive r-bit pieces P0, ..., Pn-1 (last is zero-padded)
  1091. --~ initialize the state S to a string of b 0 bits.
  1092. --~ absorb the input into the state: For each block Pi,
  1093. --~ extend Pi at the end by a string of c 0 bits, yielding one of length b,
  1094. --~ XOR that with S and
  1095. --~ apply the block permutation f to the result, yielding a new state S
  1096. --~ initialize Z to be the empty string
  1097. --~ while the length of Z is less than d:
  1098. --~ append the first r bits of S to Z
  1099. --~ if Z is still less than d bits long, apply f to S, yielding a new state S.
  1100. --~ truncate Z to d bits
  1101. local function partial(message_part)
  1102. if message_part then
  1103. local partLength = #message_part
  1104. if tail then
  1105. local offs = 0
  1106. if tail ~= "" and #tail + partLength >= block_size_in_bytes then
  1107. offs = block_size_in_bytes - #tail
  1108. keccak_feed(lanes_lo, lanes_hi, tail .. sub(message_part, 1, offs), 0, block_size_in_bytes, block_size_in_bytes)
  1109. tail = ""
  1110. end
  1111.  
  1112. local size = partLength - offs
  1113. local size_tail = size % block_size_in_bytes
  1114. keccak_feed(lanes_lo, lanes_hi, message_part, offs, size - size_tail, block_size_in_bytes)
  1115. tail = tail .. sub(message_part, partLength + 1 - size_tail)
  1116. return partial
  1117. else
  1118. error("Adding more chunks is not allowed after receiving the result", 2)
  1119. end
  1120. else
  1121. if tail then
  1122. -- append the following bits to the message: for usual SHA3: 011(0*)1, for SHAKE: 11111(0*)1
  1123. local gap_start = is_SHAKE and 31 or 6
  1124. tail = tail .. (#tail + 1 == block_size_in_bytes and char(gap_start + 128) or char(gap_start) .. rep("\0", (-2 - #tail) % block_size_in_bytes) .. "\128")
  1125. keccak_feed(lanes_lo, lanes_hi, tail, 0, #tail, block_size_in_bytes)
  1126. tail = nil
  1127.  
  1128. local lanes_used = 0
  1129. local total_lanes = floor(block_size_in_bytes / 8)
  1130. local qwords = {}
  1131.  
  1132. local function get_next_qwords_of_digest(qwords_qty)
  1133. -- returns not more than 'qwords_qty' qwords ('qwords_qty' might be non-integer)
  1134. -- doesn't go across keccak-buffer boundary
  1135. -- block_size_in_bytes is a multiple of 8, so, keccak-buffer contains integer number of qwords
  1136. if lanes_used >= total_lanes then
  1137. keccak_feed(lanes_lo, lanes_hi, "\0\0\0\0\0\0\0\0", 0, 8, 8)
  1138. lanes_used = 0
  1139. end
  1140.  
  1141. qwords_qty = floor(min(qwords_qty, total_lanes - lanes_used))
  1142. if hi_factor_keccak ~= 0 then
  1143. for j = 1, qwords_qty do
  1144. qwords[j] = HEX64(lanes_lo[lanes_used + j - 1 + lanes_index_base])
  1145. end
  1146. else
  1147. for j = 1, qwords_qty do
  1148. qwords[j] = format("%08x", lanes_hi[lanes_used + j] % 4294967296) .. format("%08x", lanes_lo[lanes_used + j] % 4294967296)
  1149. end
  1150. end
  1151.  
  1152. lanes_used = lanes_used + qwords_qty
  1153. return gsub(tconcat(qwords, "", 1, qwords_qty), "(..)(..)(..)(..)(..)(..)(..)(..)", "%8%7%6%5%4%3%2%1"), qwords_qty * 8
  1154. end
  1155.  
  1156. local parts = {} -- digest parts
  1157. local last_part, last_part_size = "", 0
  1158.  
  1159. local function get_next_part_of_digest(bytes_needed)
  1160. -- returns 'bytes_needed' bytes, for arbitrary integer 'bytes_needed'
  1161. bytes_needed = bytes_needed or 1
  1162. if bytes_needed <= last_part_size then
  1163. last_part_size = last_part_size - bytes_needed
  1164. local part_size_in_nibbles = bytes_needed * 2
  1165. local result = sub(last_part, 1, part_size_in_nibbles)
  1166. last_part = sub(last_part, part_size_in_nibbles + 1)
  1167. return result
  1168. end
  1169.  
  1170. local parts_qty = 0
  1171. if last_part_size > 0 then
  1172. parts_qty = 1
  1173. parts[parts_qty] = last_part
  1174. bytes_needed = bytes_needed - last_part_size
  1175. end
  1176.  
  1177. -- repeats until the length is enough
  1178. while bytes_needed >= 8 do
  1179. local next_part, next_part_size = get_next_qwords_of_digest(bytes_needed / 8)
  1180. parts_qty = parts_qty + 1
  1181. parts[parts_qty] = next_part
  1182. bytes_needed = bytes_needed - next_part_size
  1183. end
  1184.  
  1185. if bytes_needed > 0 then
  1186. last_part, last_part_size = get_next_qwords_of_digest(1)
  1187. parts_qty = parts_qty + 1
  1188. parts[parts_qty] = get_next_part_of_digest(bytes_needed)
  1189. else
  1190. last_part, last_part_size = "", 0
  1191. end
  1192.  
  1193. return tconcat(parts, "", 1, parts_qty)
  1194. end
  1195.  
  1196. if digest_size_in_bytes < 0 then
  1197. result = get_next_part_of_digest
  1198. else
  1199. result = get_next_part_of_digest(digest_size_in_bytes)
  1200. end
  1201.  
  1202. end
  1203.  
  1204. return result
  1205. end
  1206. end
  1207.  
  1208. if message then
  1209. -- Actually perform calculations and return the SHA3 digest of a message
  1210. return partial(message)()
  1211. else
  1212. -- Return function for chunk-by-chunk loading
  1213. -- User should feed every chunk of input data as single argument to this function and finally get SHA3 digest by invoking this function without an argument
  1214. return partial
  1215. end
  1216. end
  1217.  
  1218. local function HexToBinFunction(hh)
  1219. return char(tonumber(hh, 16))
  1220. end
  1221.  
  1222. local function hex2bin(hex_string)
  1223. return (gsub(hex_string, "%x%x", HexToBinFunction))
  1224. end
  1225.  
  1226. local base64_symbols = {
  1227. ["+"] = 62, ["-"] = 62, [62] = "+";
  1228. ["/"] = 63, ["_"] = 63, [63] = "/";
  1229. ["="] = -1, ["."] = -1, [-1] = "=";
  1230. }
  1231.  
  1232. local symbol_index = 0
  1233. for j, pair in ipairs{"AZ", "az", "09"} do
  1234. for ascii = byte(pair), byte(pair, 2) do
  1235. local ch = char(ascii)
  1236. base64_symbols[ch] = symbol_index
  1237. base64_symbols[symbol_index] = ch
  1238. symbol_index = symbol_index + 1
  1239. end
  1240. end
  1241.  
  1242. local function bin2base64(binary_string)
  1243. local stringLength = #binary_string
  1244. local result = tcreate(ceil(stringLength / 3))
  1245. local length = 0
  1246.  
  1247. for pos = 1, #binary_string, 3 do
  1248. local c1, c2, c3, c4 = byte(sub(binary_string, pos, pos + 2) .. '\0', 1, -1)
  1249. length = length + 1
  1250. result[length] =
  1251. base64_symbols[floor(c1 / 4)] ..
  1252. base64_symbols[c1 % 4 * 16 + floor(c2 / 16)] ..
  1253. base64_symbols[c3 and c2 % 16 * 4 + floor(c3 / 64) or -1] ..
  1254. base64_symbols[c4 and c3 % 64 or -1]
  1255. end
  1256.  
  1257. return tconcat(result)
  1258. end
  1259.  
  1260. local function base642bin(base64_string)
  1261. local result, chars_qty = {}, 3
  1262. for pos, ch in gmatch(gsub(base64_string, "%s+", ""), "()(.)") do
  1263. local code = base64_symbols[ch]
  1264. if code < 0 then
  1265. chars_qty = chars_qty - 1
  1266. code = 0
  1267. end
  1268.  
  1269. local idx = pos % 4
  1270. if idx > 0 then
  1271. result[-idx] = code
  1272. else
  1273. local c1 = result[-1] * 4 + floor(result[-2] / 16)
  1274. local c2 = (result[-2] % 16) * 16 + floor(result[-3] / 4)
  1275. local c3 = (result[-3] % 4) * 64 + code
  1276. result[#result + 1] = sub(char(c1, c2, c3), 1, chars_qty)
  1277. end
  1278. end
  1279.  
  1280. return tconcat(result)
  1281. end
  1282.  
  1283. local block_size_for_HMAC -- this table will be initialized at the end of the module
  1284. --local function pad_and_xor(str, result_length, byte_for_xor)
  1285. -- return gsub(str, ".", function(c)
  1286. -- return char(bit32_bxor(byte(c), byte_for_xor))
  1287. -- end) .. rep(char(byte_for_xor), result_length - #str)
  1288. --end
  1289.  
  1290. -- For the sake of speed of converting hexes to strings, there's a map of the conversions here
  1291. local BinaryStringMap = {}
  1292. for Index = 0, 255 do
  1293. BinaryStringMap[format("%02x", Index)] = char(Index)
  1294. end
  1295.  
  1296. -- Update 02.14.20 - added AsBinary for easy GameAnalytics replacement.
  1297. local function hmac(hash_func, key, message, AsBinary)
  1298. -- Create an instance (private objects for current calculation)
  1299. local block_size = block_size_for_HMAC[hash_func]
  1300. if not block_size then
  1301. error("Unknown hash function", 2)
  1302. end
  1303.  
  1304. local KeyLength = #key
  1305. if KeyLength > block_size then
  1306. key = gsub(hash_func(key), "%x%x", HexToBinFunction)
  1307. KeyLength = #key
  1308. end
  1309.  
  1310. local append = hash_func()(gsub(key, ".", function(c)
  1311. return char(bit32_bxor(byte(c), 0x36))
  1312. end) .. rep("6", block_size - KeyLength)) -- 6 = char(0x36)
  1313.  
  1314. local result
  1315.  
  1316. local function partial(message_part)
  1317. if not message_part then
  1318. result = result or hash_func(
  1319. gsub(key, ".", function(c)
  1320. return char(bit32_bxor(byte(c), 0x5c))
  1321. end) .. rep("\\", block_size - KeyLength) -- \ = char(0x5c)
  1322. .. (gsub(append(), "%x%x", HexToBinFunction))
  1323. )
  1324.  
  1325. return result
  1326. elseif result then
  1327. error("Adding more chunks is not allowed after receiving the result", 2)
  1328. else
  1329. append(message_part)
  1330. return partial
  1331. end
  1332. end
  1333.  
  1334. if message then
  1335. -- Actually perform calculations and return the HMAC of a message
  1336. local FinalMessage = partial(message)()
  1337. return AsBinary and (gsub(FinalMessage, "%x%x", BinaryStringMap)) or FinalMessage
  1338. else
  1339. -- Return function for chunk-by-chunk loading of a message
  1340. -- User should feed every chunk of the message as single argument to this function and finally get HMAC by invoking this function without an argument
  1341. return partial
  1342. end
  1343. end
  1344.  
  1345. local sha = {
  1346. md5 = md5,
  1347. sha1 = sha1,
  1348. -- SHA2 hash functions:
  1349. sha224 = function(message)
  1350. return sha256ext(224, message)
  1351. end;
  1352.  
  1353. sha256 = function(message)
  1354. return sha256ext(256, message)
  1355. end;
  1356.  
  1357. sha512_224 = function(message)
  1358. return sha512ext(224, message)
  1359. end;
  1360.  
  1361. sha512_256 = function(message)
  1362. return sha512ext(256, message)
  1363. end;
  1364.  
  1365. sha384 = function(message)
  1366. return sha512ext(384, message)
  1367. end;
  1368.  
  1369. sha512 = function(message)
  1370. return sha512ext(512, message)
  1371. end;
  1372.  
  1373. -- SHA3 hash functions:
  1374. sha3_224 = function(message)
  1375. return keccak((1600 - 2 * 224) / 8, 224 / 8, false, message)
  1376. end;
  1377.  
  1378. sha3_256 = function(message)
  1379. return keccak((1600 - 2 * 256) / 8, 256 / 8, false, message)
  1380. end;
  1381.  
  1382. sha3_384 = function(message)
  1383. return keccak((1600 - 2 * 384) / 8, 384 / 8, false, message)
  1384. end;
  1385.  
  1386. sha3_512 = function(message)
  1387. return keccak((1600 - 2 * 512) / 8, 512 / 8, false, message)
  1388. end;
  1389.  
  1390. shake128 = function(message, digest_size_in_bytes)
  1391. return keccak((1600 - 2 * 128) / 8, digest_size_in_bytes, true, message)
  1392. end;
  1393.  
  1394. shake256 = function(message, digest_size_in_bytes)
  1395. return keccak((1600 - 2 * 256) / 8, digest_size_in_bytes, true, message)
  1396. end;
  1397.  
  1398. -- misc utilities:
  1399. hmac = hmac; -- HMAC(hash_func, key, message) is applicable to any hash function from this module except SHAKE*
  1400. hex_to_bin = hex2bin; -- converts hexadecimal representation to binary string
  1401. base64_to_bin = base642bin; -- converts base64 representation to binary string
  1402. bin_to_base64 = bin2base64; -- converts binary string to base64 representation
  1403. base64_encode = Base64.Encode;
  1404. base64_decode = Base64.Decode;
  1405. }
  1406.  
  1407. block_size_for_HMAC = {
  1408. [sha.md5] = 64;
  1409. [sha.sha1] = 64;
  1410. [sha.sha224] = 64;
  1411. [sha.sha256] = 64;
  1412. [sha.sha512_224] = 128;
  1413. [sha.sha512_256] = 128;
  1414. [sha.sha384] = 128;
  1415. [sha.sha512] = 128;
  1416. [sha.sha3_224] = (1600 - 2 * 224) / 8;
  1417. [sha.sha3_256] = (1600 - 2 * 256) / 8;
  1418. [sha.sha3_384] = (1600 - 2 * 384) / 8;
  1419. [sha.sha3_512] = (1600 - 2 * 512) / 8;
  1420. }
  1421.  
  1422. return sha
Add Comment
Please, Sign In to add comment