View difference between Paste ID: nuvxHYu2 and 6UV4qfNF
SHOW: | | - or go back to the newest paste.
1
-- SHA-256, HMAC and PBKDF2 functions in ComputerCraft
2
-- By Anavrins
3
-- MIT License
4
-- Pastebin: https://pastebin.com/6UV4qfNF
5
-- Usage: https://pastebin.com/q2SQ7eRg
6-
-- Last updated: June 30 2024
6+
-- Last updated: March 27 2020
7
8
local mod32 = 2^32
9
local band    = bit32 and bit32.band or bit.band
10
local bnot    = bit32 and bit32.bnot or bit.bnot
11
local bxor    = bit32 and bit32.bxor or bit.bxor
12-
local upack   = table.unpack or unpack
12+
13
local upack   = unpack
14
15
local function rrotate(n, b)
16
	local s = n/(2^b)
17-
	return (s-f) + f * 2^32
17+
18
	return (s-f) + f*mod32
19
end
20
local function brshift(int, by)
21
	local s = int / (2^by)
22
	return s - s%1
23
end
24-
local H = { -- First 32 bits of the fractional parts of the square roots of the first 8 primes 2..19
24+
25
local H = {
26
	0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a,
27
	0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19,
28
}
29-
local K = { -- First 32 bits of the fractional parts of the cube roots of the first 64 primes 2..311
29+
30
local K = {
31
	0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
32
	0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
33
	0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
34
	0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
35
	0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
36
	0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
37
	0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
38
	0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2,
39
}
40
41
local function counter(incr)
42
	local t1, t2 = 0, 0
43
	if 0xFFFFFFFF - t1 < incr then
44-
		t1 = incr - (0xFFFFFFFF - t1) - 1
44+
45
		t1 = incr - (0xFFFFFFFF - t1) - 1		
46
	else t1 = t1 + incr
47
	end
48
	return t2, t1
49
end
50
51
local function BE_toInt(bs, i)
52
	return blshift((bs[i] or 0), 24) + blshift((bs[i+1] or 0), 16) + blshift((bs[i+2] or 0), 8) + (bs[i+3] or 0)
53
end
54
55
local function preprocess(data)
56
	local len = #data
57
	local proc = {}
58
	data[#data+1] = 0x80
59
	while #data%64~=56 do data[#data+1] = 0 end
60
	local blocks = math.ceil(#data/64)
61
	for i = 1, blocks do
62
		proc[i] = {}
63
		for j = 1, 16 do
64
			proc[i][j] = BE_toInt(data, 1+((i-1)*64)+((j-1)*4))
65
		end
66
	end
67
	proc[blocks][15], proc[blocks][16] = counter(len*8)
68
	return proc
69
end
70-
local function digestblock(w, C)
70+
71
function digestblock(w, C)
72
	for j = 17, 64 do
73-
		local u = w[j-2]
73+
74-
		local s0 = bxor(rrotate(v, 7), rrotate(v, 18), brshift(v, 3))
74+
		local s0 = bxor(rrotate(w[j-15], 7), rrotate(w[j-15], 18), brshift(w[j-15], 3))
75-
		local s1 = bxor(rrotate(u, 17), rrotate(u, 19), brshift(u, 10))
75+
		local s1 = bxor(rrotate(w[j-2], 17), rrotate(w[j-2], 19),brshift(w[j-2], 10))
76-
		w[j] = (w[j-16] + s0 + w[j-7] + s1) % 2^32
76+
		w[j] = (w[j-16] + s0 + w[j-7] + s1)%mod32
77
	end
78
	local a, b, c, d, e, f, g, h = upack(C)
79
	for j = 1, 64 do
80
		local S1 = bxor(rrotate(e, 6), rrotate(e, 11), rrotate(e, 25))
81
		local ch = bxor(band(e, f), band(bnot(e), g))
82-
		local temp1 = (h + S1 + ch + K[j] + w[j])
82+
		local temp1 = (h + S1 + ch + K[j] + w[j])%mod32
83
		local S0 = bxor(rrotate(a, 2), rrotate(a, 13), rrotate(a, 22))
84
		local maj = bxor(bxor(band(a, b), band(a, c)), band(b, c))
85-
		local temp2 = (S0 + maj)
85+
		local temp2 = (S0 + maj)%mod32
86-
		h, g, f, e, d, c, b, a = g, f, e, (d+temp1) % 2^32, c, b, a, (temp1+temp2) % 2^32
86+
		h, g, f, e, d, c, b, a = g, f, e, (d+temp1)%mod32, c, b, a, (temp1+temp2)%mod32
87
	end
88-
	C[1] = (C[1] + a) % 2^32
88+
	C[1] = (C[1] + a)%mod32
89-
	C[2] = (C[2] + b) % 2^32
89+
	C[2] = (C[2] + b)%mod32
90-
	C[3] = (C[3] + c) % 2^32
90+
	C[3] = (C[3] + c)%mod32
91-
	C[4] = (C[4] + d) % 2^32
91+
	C[4] = (C[4] + d)%mod32
92-
	C[5] = (C[5] + e) % 2^32
92+
	C[5] = (C[5] + e)%mod32
93-
	C[6] = (C[6] + f) % 2^32
93+
	C[6] = (C[6] + f)%mod32
94-
	C[7] = (C[7] + g) % 2^32
94+
	C[7] = (C[7] + g)%mod32
95-
	C[8] = (C[8] + h) % 2^32
95+
	C[8] = (C[8] + h)%mod32
96
	return C
97
end
98
99-
local mt = {}
99+
local mt = {
100-
mt = {
100+
	__tostring = function(a) return string.char(unpack(a)) end,
101-
	__tostring = function(a) return string.char(upack(a)) end,
101+
102
		toHex = function(self, s) return ("%02x"):rep(#self):format(unpack(self)) end,
103-
		toHex = function(self) return ("%02x"):rep(#self):format(upack(self)) end,
103+
104
			if type(t) ~= "table" then return false end
105
			if #self ~= #t then return false end
106
			local ret = 0
107
			for i = 1, #self do
108
				ret = bit32.bor(ret, bxor(self[i], t[i]))
109
			end
110
			return ret == 0
111
		end
112-
		end,
112+
113-
		sub = function(self, a, b)
113+
114-
			local len = #self+1
114+
115-
			local start = a%len
115+
function toBytes(t, n)
116-
			local stop = (b or len-1)%len
116+
117-
			local ret = {}
117+
118-
			local i = 1
118+
119-
			for j = start, stop, start<stop and 1 or -1 do
119+
120-
				ret[i] = self[j]
120+
121-
				i = i+1
121+
122
	end
123-
			return setmetatable(ret, mt)
123+
124-
		end,
124+
125
126
local function digest(data)
127
	local data = data or ""
128-
local function toBytes(t, n)
128+
129
130
	data = preprocess(data)
131
	local C = {upack(H)}
132
	for i = 1, #data do C = digestblock(data[i], C) end
133
	return toBytes(C, 8)
134
end
135
136
function hmac(data, key)
137
	local data = type(data) == "table" and {upack(data)} or {tostring(data):byte(1,-1)}
138
	local key = type(key) == "table" and {upack(key)} or {tostring(key):byte(1,-1)}
139
140
	local blocksize = 64
141
142
	key = #key > blocksize and digest(key) or key
143
144
	local ipad = {}
145
	local opad = {}
146
	local padded_key = {}
147
148
	for i = 1, blocksize do
149-
local function hmac(data, key)
149+
150
		opad[i] = bxor(0x5C, key[i] or 0)
151
	end
152
153
	for i = 1, #data do
154
		ipad[blocksize+i] = data[i]
155
	end
156
157
	ipad = digest(ipad)
158
159
	for i = 1, blocksize do
160
		padded_key[i] = opad[i]
161
		padded_key[blocksize+i] = ipad[i]
162
	end
163
164
	return digest(padded_key)
165
end
166
167
function pbkdf2(pass, salt, iter, dklen)
168
	local salt = type(salt) == "table" and salt or {tostring(salt):byte(1,-1)}
169
	local hashlen = 32
170
	local dklen = dklen or 32
171
	local block = 1
172
	local out = {}
173
174
	while dklen > 0 do
175
		local ikey = {}
176
		local isalt = {upack(salt)}
177
		local clen = dklen > hashlen and hashlen or dklen
178
179
		isalt[#isalt+1] = band(brshift(block, 24), 0xFF)
180-
local function pbkdf2(pass, salt, iter, dklen)
180+
181
		isalt[#isalt+1] = band(brshift(block, 8), 0xFF)
182
		isalt[#isalt+1] = band(block, 0xFF)
183
184
		for j = 1, iter do
185
			isalt = hmac(isalt, pass)
186
			for k = 1, clen do ikey[k] = bxor(isalt[k], ikey[k] or 0) end
187
			if j % 200 == 0 then os.queueEvent("PBKDF2", j) coroutine.yield("PBKDF2") end
188
		end
189
		dklen = dklen - clen
190
		block = block+1
191
		for k = 1, clen do out[#out+1] = ikey[k] end
192
	end
193
194
	return setmetatable(out, mt)
195
end
196
197
return {
198
	digest = digest,
199
	hmac   = hmac,
200
	pbkdf2 = pbkdf2,
201
}