@quenty/ellipticcurvecryptography 1.11.0 → 1.13.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +21 -87
- package/deploy.nevermore.json +10 -0
- package/package.json +2 -2
- package/src/Shared/EllipticCurveCryptography/arith.lua +33 -23
- package/src/Shared/EllipticCurveCryptography/chacha20.lua +31 -20
- package/src/Shared/EllipticCurveCryptography/curve.lua +8 -8
- package/src/Shared/EllipticCurveCryptography/init.lua +49 -40
- package/src/Shared/EllipticCurveCryptography/modp.lua +23 -20
- package/src/Shared/EllipticCurveCryptography/modq.lua +53 -51
- package/src/Shared/EllipticCurveCryptography/random.lua +9 -8
- package/src/Shared/EllipticCurveCryptography/sha256.lua +43 -33
- package/src/Shared/EllipticCurveCryptography/twoPower.lua +4 -4
- package/test/default.project.json +25 -0
- package/test/scripts/Server/ServerMain.server.lua +13 -0
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
--!
|
|
1
|
+
--!strict
|
|
2
2
|
--!native
|
|
3
3
|
|
|
4
4
|
-- SHA-256, HMAC and PBKDF2 functions in ComputerCraft
|
|
@@ -10,22 +10,24 @@
|
|
|
10
10
|
-- Last update: October 10, 2017
|
|
11
11
|
-- Updated by Quenty December 4th, 2023
|
|
12
12
|
|
|
13
|
-
local twoPower = require(script.Parent.twoPower)
|
|
13
|
+
local twoPower: { [number]: number } = require(script.Parent.twoPower) :: any
|
|
14
14
|
local util = require(script.Parent.util)
|
|
15
15
|
|
|
16
|
+
type ByteTable = typeof(setmetatable({} :: { number }, {} :: typeof(util.byteTableMT)))
|
|
17
|
+
|
|
16
18
|
local mod32 = 2 ^ 32
|
|
17
19
|
local band = bit32.band
|
|
18
20
|
local bnot = bit32.bnot
|
|
19
21
|
local bxor = bit32.bxor
|
|
20
22
|
local blshift = bit32.lshift
|
|
21
23
|
|
|
22
|
-
local function rrotate(n, b)
|
|
24
|
+
local function rrotate(n: number, b: number): number
|
|
23
25
|
local s = n / twoPower[b]
|
|
24
26
|
local f = s % 1
|
|
25
27
|
return (s - f) + f * mod32
|
|
26
28
|
end
|
|
27
29
|
|
|
28
|
-
local function brshift(int, by) -- Thanks bit32 for bad rshift
|
|
30
|
+
local function brshift(int: number, by: number): number -- Thanks bit32 for bad rshift
|
|
29
31
|
return math.floor(int / twoPower[by])
|
|
30
32
|
end
|
|
31
33
|
|
|
@@ -107,7 +109,7 @@ local K = {
|
|
|
107
109
|
0xc67178f2,
|
|
108
110
|
}
|
|
109
111
|
|
|
110
|
-
local function counter(incr)
|
|
112
|
+
local function counter(incr: number): (number, number)
|
|
111
113
|
local t1, t2 = 0, 0
|
|
112
114
|
if 0xFFFFFFFF - t1 < incr then
|
|
113
115
|
t2 = t2 + 1
|
|
@@ -119,11 +121,11 @@ local function counter(incr)
|
|
|
119
121
|
return t2, t1
|
|
120
122
|
end
|
|
121
123
|
|
|
122
|
-
local function BE_toInt(bs, i)
|
|
124
|
+
local function BE_toInt(bs: { number }, i: number): number
|
|
123
125
|
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)
|
|
124
126
|
end
|
|
125
127
|
|
|
126
|
-
local function preprocess(data)
|
|
128
|
+
local function preprocess(data: { number }): { { number } }
|
|
127
129
|
local len = #data
|
|
128
130
|
local data_len = #data + 1
|
|
129
131
|
|
|
@@ -135,9 +137,9 @@ local function preprocess(data)
|
|
|
135
137
|
|
|
136
138
|
local blocks = math.ceil(data_len / 64)
|
|
137
139
|
|
|
138
|
-
local proc = table.create(blocks)
|
|
140
|
+
local proc: { { number } } = table.create(blocks)
|
|
139
141
|
for i = 1, blocks do
|
|
140
|
-
local block = table.create(16)
|
|
142
|
+
local block: { number } = table.create(16)
|
|
141
143
|
proc[i] = block
|
|
142
144
|
for j = 1, 16 do
|
|
143
145
|
block[j] = BE_toInt(data, 1 + ((i - 1) * 64) + ((j - 1) * 4))
|
|
@@ -148,7 +150,7 @@ local function preprocess(data)
|
|
|
148
150
|
return proc
|
|
149
151
|
end
|
|
150
152
|
|
|
151
|
-
local function digestblock(w, C)
|
|
153
|
+
local function digestblock(w: { number }, C: { number }): { number }
|
|
152
154
|
for j = 17, 64 do
|
|
153
155
|
local s0 = bxor(bxor(rrotate(w[j - 15], 7), rrotate(w[j - 15], 18)), brshift(w[j - 15], 3))
|
|
154
156
|
local s1 = bxor(bxor(rrotate(w[j - 2], 17), rrotate(w[j - 2], 19)), brshift(w[j - 2], 10))
|
|
@@ -177,8 +179,8 @@ local function digestblock(w, C)
|
|
|
177
179
|
return C
|
|
178
180
|
end
|
|
179
181
|
|
|
180
|
-
local function toBytes(t, n)
|
|
181
|
-
local b = table.create(n * 4)
|
|
182
|
+
local function toBytes(t: { number }, n: number): ByteTable
|
|
183
|
+
local b: { number } = table.create(n * 4)
|
|
182
184
|
for i = 1, n do
|
|
183
185
|
b[(i - 1) * 4 + 1] = band(brshift(t[i], 24), 0xFF)
|
|
184
186
|
b[(i - 1) * 4 + 2] = band(brshift(t[i], 16), 0xFF)
|
|
@@ -189,29 +191,36 @@ local function toBytes(t, n)
|
|
|
189
191
|
return setmetatable(b, util.byteTableMT)
|
|
190
192
|
end
|
|
191
193
|
|
|
192
|
-
local function digest(data)
|
|
193
|
-
|
|
194
|
-
|
|
194
|
+
local function digest(data: (string | { number })?): ByteTable
|
|
195
|
+
local rawData: string | { number } = data or ""
|
|
196
|
+
local byteData: { number }
|
|
197
|
+
if type(rawData) == "table" then
|
|
198
|
+
byteData = { table.unpack(rawData) }
|
|
199
|
+
else
|
|
200
|
+
byteData = util.stringToByteArray(rawData)
|
|
201
|
+
end
|
|
195
202
|
|
|
196
|
-
|
|
197
|
-
local C = { table.unpack(H) }
|
|
198
|
-
for _, value in ipairs(
|
|
203
|
+
local proc = preprocess(byteData)
|
|
204
|
+
local C: { number } = { table.unpack(H) }
|
|
205
|
+
for _, value in ipairs(proc) do
|
|
199
206
|
C = digestblock(value, C)
|
|
200
207
|
end
|
|
201
208
|
|
|
202
209
|
return toBytes(C, 8)
|
|
203
210
|
end
|
|
204
211
|
|
|
205
|
-
local function hmac(data, key)
|
|
206
|
-
local actualData = type(data) == "table" and { table.unpack(data
|
|
207
|
-
|
|
212
|
+
local function hmac(data: string | { number }, key: string | { number }): ByteTable
|
|
213
|
+
local actualData: { number } = type(data) == "table" and { table.unpack(data :: { number }) }
|
|
214
|
+
or util.stringToByteArray(data :: string)
|
|
215
|
+
local actualKey: { number } = type(key) == "table" and { table.unpack(key :: { number }) }
|
|
216
|
+
or util.stringToByteArray(key :: string)
|
|
208
217
|
|
|
209
218
|
local blocksize = 64
|
|
210
219
|
|
|
211
|
-
actualKey = #actualKey > blocksize and digest(actualKey) or actualKey
|
|
220
|
+
actualKey = #actualKey > blocksize and (digest(actualKey) :: any) or actualKey
|
|
212
221
|
|
|
213
|
-
local ipad = table.create(blocksize)
|
|
214
|
-
local opad = table.create(blocksize)
|
|
222
|
+
local ipad: { number } = table.create(blocksize)
|
|
223
|
+
local opad: { number } = table.create(blocksize)
|
|
215
224
|
|
|
216
225
|
for i = 1, blocksize do
|
|
217
226
|
ipad[i] = bxor(0x36, actualKey[i] or 0)
|
|
@@ -222,26 +231,27 @@ local function hmac(data, key)
|
|
|
222
231
|
ipad[blocksize + i] = value
|
|
223
232
|
end
|
|
224
233
|
|
|
225
|
-
|
|
226
|
-
local padded_key = table.create(blocksize * 2)
|
|
234
|
+
local ipadDigest = digest(ipad)
|
|
235
|
+
local padded_key: { number } = table.create(blocksize * 2)
|
|
227
236
|
for i = 1, blocksize do
|
|
228
237
|
padded_key[i] = opad[i]
|
|
229
|
-
padded_key[blocksize + i] =
|
|
238
|
+
padded_key[blocksize + i] = ipadDigest[i]
|
|
230
239
|
end
|
|
231
240
|
|
|
232
241
|
return digest(padded_key)
|
|
233
242
|
end
|
|
234
243
|
|
|
235
|
-
local function pbkdf2(pass, salt, iter, dklen)
|
|
236
|
-
local actualSalt = type(salt) == "table" and salt
|
|
244
|
+
local function pbkdf2(pass: string | { number }, salt: string | { number }, iter: number, dklen: number?): ByteTable
|
|
245
|
+
local actualSalt: { number } = type(salt) == "table" and salt :: { number }
|
|
246
|
+
or util.stringToByteArray(salt :: string)
|
|
237
247
|
local hashlen = 32
|
|
238
248
|
local actualDklen = dklen or 32
|
|
239
249
|
local block = 1
|
|
240
|
-
local out = {}
|
|
250
|
+
local out: { number } = {}
|
|
241
251
|
|
|
242
252
|
while actualDklen > 0 do
|
|
243
|
-
local ikey = {}
|
|
244
|
-
local isalt = { table.unpack(actualSalt) }
|
|
253
|
+
local ikey: { number } = {}
|
|
254
|
+
local isalt: { number } = { table.unpack(actualSalt) }
|
|
245
255
|
local isalt_len = #isalt
|
|
246
256
|
local clen = actualDklen > hashlen and hashlen or actualDklen
|
|
247
257
|
|
|
@@ -253,7 +263,7 @@ local function pbkdf2(pass, salt, iter, dklen)
|
|
|
253
263
|
isalt_len += 4
|
|
254
264
|
|
|
255
265
|
for _ = 1, iter do
|
|
256
|
-
isalt = hmac(isalt, pass)
|
|
266
|
+
isalt = hmac(isalt, pass) :: any
|
|
257
267
|
for k = 1, clen do
|
|
258
268
|
ikey[k] = bxor(isalt[k], ikey[k] or 0)
|
|
259
269
|
end
|
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
--!
|
|
2
|
-
local twoPower = setmetatable({}, {
|
|
3
|
-
__index = function(self, index)
|
|
1
|
+
--!strict
|
|
2
|
+
local twoPower: { [number]: number } = setmetatable({}, {
|
|
3
|
+
__index = function(self: { [number]: number }, index: number): number
|
|
4
4
|
local value = 2 ^ index
|
|
5
5
|
self[index] = value
|
|
6
6
|
return value
|
|
7
7
|
end,
|
|
8
|
-
})
|
|
8
|
+
}) :: any
|
|
9
9
|
|
|
10
10
|
-- NOTE: This takes somewhere between 1.5 ms to 4 ms
|
|
11
11
|
-- precache
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "EllipticcurvecryptographyTest",
|
|
3
|
+
"globIgnorePaths": [
|
|
4
|
+
"**/.package-lock.json",
|
|
5
|
+
"**/.pnpm",
|
|
6
|
+
"**/.pnpm-workspace-state-v1.json",
|
|
7
|
+
"**/.modules.yaml",
|
|
8
|
+
"**/.ignored",
|
|
9
|
+
"**/.ignored_*"
|
|
10
|
+
],
|
|
11
|
+
"tree": {
|
|
12
|
+
"$className": "DataModel",
|
|
13
|
+
"ServerScriptService": {
|
|
14
|
+
"$properties": {
|
|
15
|
+
"LoadStringEnabled": true
|
|
16
|
+
},
|
|
17
|
+
"ellipticcurvecryptography": {
|
|
18
|
+
"$path": ".."
|
|
19
|
+
},
|
|
20
|
+
"Script": {
|
|
21
|
+
"$path": "scripts/Server"
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
--[[
|
|
2
|
+
@class ServerMain
|
|
3
|
+
]]
|
|
4
|
+
local ServerScriptService = game:GetService("ServerScriptService")
|
|
5
|
+
|
|
6
|
+
local root = ServerScriptService.ellipticcurvecryptography
|
|
7
|
+
local loader = root:FindFirstChild("LoaderUtils", true).Parent
|
|
8
|
+
local require = require(loader).bootstrapGame(root)
|
|
9
|
+
|
|
10
|
+
local NevermoreTestRunnerUtils = require("NevermoreTestRunnerUtils")
|
|
11
|
+
if NevermoreTestRunnerUtils.runTestsIfNeededAsync(root) then
|
|
12
|
+
return
|
|
13
|
+
end
|