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