Hydrax_Animatez

windhashlua

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