@quenty/ellipticcurvecryptography 1.12.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 CHANGED
@@ -3,6 +3,12 @@
3
3
  All notable changes to this project will be documented in this file.
4
4
  See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
5
5
 
6
+ # [1.13.0](https://github.com/Quenty/NevermoreEngine/compare/@quenty/ellipticcurvecryptography@1.12.0...@quenty/ellipticcurvecryptography@1.13.0) (2026-07-14)
7
+
8
+ ### Features
9
+
10
+ - **ellipticcurvecryptography:** convert package to --!strict ([48e814a](https://github.com/Quenty/NevermoreEngine/commit/48e814abb5f01f54627dd4f827a287fb98f405bc))
11
+
6
12
  # [1.12.0](https://github.com/Quenty/NevermoreEngine/compare/@quenty/ellipticcurvecryptography@1.11.0...@quenty/ellipticcurvecryptography@1.12.0) (2026-05-29)
7
13
 
8
14
  **Note:** Version bump only for package @quenty/ellipticcurvecryptography
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@quenty/ellipticcurvecryptography",
3
- "version": "1.12.0",
3
+ "version": "1.13.0",
4
4
  "description": "Elliptic curve cryptography forked from BoatBomber, forked from ComputerCraft",
5
5
  "keywords": [
6
6
  "Roblox",
@@ -35,5 +35,5 @@
35
35
  "publishConfig": {
36
36
  "access": "public"
37
37
  },
38
- "gitHead": "f4a374a0a294ee8900aa5cb68ab138b0acf3e0ae"
38
+ "gitHead": "13f0162f4971a77378e55e9b7236aea94f0dd3a8"
39
39
  }
@@ -1,9 +1,12 @@
1
- --!nonstrict
1
+ --!strict
2
2
  -- Big integer arithmetic for 168-bit (and 336-bit) numbers
3
3
  -- Numbers are represented as little-endian tables of 24-bit integers
4
4
  local twoPower = require(script.Parent.twoPower)
5
5
 
6
- local function isEqual(a, b)
6
+ type BigInt = { number }
7
+ type DoubleInt = { number }
8
+
9
+ local function isEqual(a: BigInt, b: BigInt): boolean
7
10
  return a[1] == b[1]
8
11
  and a[2] == b[2]
9
12
  and a[3] == b[3]
@@ -13,7 +16,7 @@ local function isEqual(a, b)
13
16
  and a[7] == b[7]
14
17
  end
15
18
 
16
- local function compare(a, b)
19
+ local function compare(a: BigInt, b: BigInt): number
17
20
  for i = 7, 1, -1 do
18
21
  if a[i] > b[i] then
19
22
  return 1
@@ -25,7 +28,7 @@ local function compare(a, b)
25
28
  return 0
26
29
  end
27
30
 
28
- local function add(a, b)
31
+ local function add(a: BigInt, b: BigInt): BigInt
29
32
  -- c7 may be greater than 2^24 before reduction
30
33
  local c1 = a[1] + b[1]
31
34
  local c2 = a[2] + b[2]
@@ -63,7 +66,7 @@ local function add(a, b)
63
66
  return { c1, c2, c3, c4, c5, c6, c7 }
64
67
  end
65
68
 
66
- local function sub(a, b)
69
+ local function sub(a: BigInt, b: BigInt): BigInt
67
70
  -- c7 may be negative before reduction
68
71
  local c1 = a[1] - b[1]
69
72
  local c2 = a[2] - b[2]
@@ -101,7 +104,7 @@ local function sub(a, b)
101
104
  return { c1, c2, c3, c4, c5, c6, c7 }
102
105
  end
103
106
 
104
- local function rShift(a)
107
+ local function rShift(a: BigInt): BigInt
105
108
  local c1 = a[1]
106
109
  local c2 = a[2]
107
110
  local c3 = a[3]
@@ -134,7 +137,7 @@ local function rShift(a)
134
137
  return { c1, c2, c3, c4, c5, c6, c7 }
135
138
  end
136
139
 
137
- local function addDouble(a, b)
140
+ local function addDouble(a: DoubleInt, b: DoubleInt): DoubleInt
138
141
  -- a and b are 336-bit integers (14 words)
139
142
  local c1 = a[1] + b[1]
140
143
  local c2 = a[2] + b[2]
@@ -207,7 +210,7 @@ local function addDouble(a, b)
207
210
  return { c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13, c14 }
208
211
  end
209
212
 
210
- local function mult(a, b, half_multiply)
213
+ local function mult(a: BigInt, b: BigInt, half_multiply: boolean): DoubleInt
211
214
  local a1, a2, a3, a4, a5, a6, a7 = a[1], a[2], a[3], a[4], a[5], a[6], a[7]
212
215
  local b1, b2, b3, b4, b5, b6, b7 = b[1], b[2], b[3], b[4], b[5], b[6], b[7]
213
216
 
@@ -218,7 +221,13 @@ local function mult(a, b, half_multiply)
218
221
  local c5 = a1 * b5 + a2 * b4 + a3 * b3 + a4 * b2 + a5 * b1
219
222
  local c6 = a1 * b6 + a2 * b5 + a3 * b4 + a4 * b3 + a5 * b2 + a6 * b1
220
223
  local c7 = a1 * b7 + a2 * b6 + a3 * b5 + a4 * b4 + a5 * b3 + a6 * b2 + a7 * b1
221
- local c8, c9, c10, c11, c12, c13, c14
224
+ local c8: number = 0
225
+ local c9: number = 0
226
+ local c10: number = 0
227
+ local c11: number = 0
228
+ local c12: number = 0
229
+ local c13: number = 0
230
+ local c14: number = 0
222
231
  if not half_multiply then
223
232
  c8 = a2 * b7 + a3 * b6 + a4 * b5 + a5 * b4 + a6 * b3 + a7 * b2
224
233
  c9 = a3 * b7 + a4 * b6 + a5 * b5 + a6 * b4 + a7 * b3
@@ -277,7 +286,7 @@ local function mult(a, b, half_multiply)
277
286
  return { c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13, c14 }
278
287
  end
279
288
 
280
- local function square(a)
289
+ local function square(a: BigInt): DoubleInt
281
290
  -- returns a 336-bit integer (14 words)
282
291
  local a1, a2, a3, a4, a5, a6, a7 = a[1], a[2], a[3], a[4], a[5], a[6], a[7]
283
292
 
@@ -340,8 +349,8 @@ local function square(a)
340
349
  return { c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13, c14 }
341
350
  end
342
351
 
343
- local function encodeInt(a)
344
- local enc = table.create(21)
352
+ local function encodeInt(a: BigInt): { number }
353
+ local enc: { number } = table.create(21)
345
354
 
346
355
  for i = 1, 7 do
347
356
  local word = a[i]
@@ -354,9 +363,9 @@ local function encodeInt(a)
354
363
  return enc
355
364
  end
356
365
 
357
- local function decodeInt(enc)
358
- local a = {}
359
- local encCopy = table.create(21)
366
+ local function decodeInt(enc: { number }): BigInt
367
+ local a: BigInt = {}
368
+ local encCopy: { number } = table.create(21)
360
369
 
361
370
  for i = 1, 21 do
362
371
  local byte = enc[i]
@@ -379,26 +388,27 @@ local function decodeInt(enc)
379
388
  return a
380
389
  end
381
390
 
382
- local function mods(d, w)
383
- local result = d[1] % twoPower[w]
391
+ local function mods(d: BigInt, w: number): number
392
+ local result = d[1] % (twoPower :: any)[w]
384
393
 
385
- if result >= twoPower[w - 1] then
386
- result -= twoPower[w]
394
+ if result >= (twoPower :: any)[w - 1] then
395
+ result -= (twoPower :: any)[w]
387
396
  end
388
397
 
389
398
  return result
390
399
  end
391
400
 
392
401
  -- Represents a 168-bit number as the (2^w)-ary Non-Adjacent Form
393
- local function NAF(d, w)
394
- local t, t_len = {}, 0
395
- local newD = { table.unpack(d) }
402
+ local function NAF(d: BigInt, w: number): { number }
403
+ local t: { number } = {}
404
+ local t_len = 0
405
+ local newD: BigInt = { table.unpack(d) }
396
406
 
397
407
  for _ = 1, 168 do
398
408
  if newD[1] % 2 == 1 then
399
409
  t_len += 1
400
410
  t[t_len] = mods(newD, w)
401
- newD = sub(newD, { t[#t], 0, 0, 0, 0, 0, 0 })
411
+ newD = sub(newD, { t[t_len], 0, 0, 0, 0, 0, 0 })
402
412
  else
403
413
  t_len += 1
404
414
  t[t_len] = 0
@@ -1,4 +1,4 @@
1
- --!nonstrict
1
+ --!strict
2
2
  --!native
3
3
 
4
4
  -- Chacha20 cipher in ComputerCraft
@@ -8,7 +8,7 @@
8
8
  -- http://www.computercraft.info/forums2/index.php?/user/12870-anavrins
9
9
  -- http://pastebin.com/GPzf9JSa
10
10
  -- Last update: April 17, 2017
11
- local twoPower = require(script.Parent.twoPower)
11
+ local twoPower: any = require(script.Parent.twoPower)
12
12
  local util = require(script.Parent.util)
13
13
 
14
14
  local bxor = bit32.bxor
@@ -20,13 +20,13 @@ local mod = 2 ^ 32
20
20
  local tau = table.pack(string.byte("expand 16-byte k", 1, -1))
21
21
  local sigma = table.pack(string.byte("expand 32-byte k", 1, -1))
22
22
 
23
- local function rotl(n, b)
23
+ local function rotl(n: number, b: number): number
24
24
  local s = n / twoPower[32 - b]
25
25
  local f = s % 1
26
26
  return (s - f) + f * mod
27
27
  end
28
28
 
29
- local function quarterRound(s, a, b, c, d)
29
+ local function quarterRound(s: { number }, a: number, b: number, c: number, d: number): { number }
30
30
  s[a] = (s[a] + s[b]) % mod
31
31
  s[d] = rotl(bxor(s[d], s[a]), 16)
32
32
  s[c] = (s[c] + s[d]) % mod
@@ -38,8 +38,8 @@ local function quarterRound(s, a, b, c, d)
38
38
  return s
39
39
  end
40
40
 
41
- local function hashBlock(state, rnd)
42
- local s = { table.unpack(state) }
41
+ local function hashBlock(state: { number }, rnd: number): { number }
42
+ local s: { number } = { table.unpack(state) }
43
43
  for i = 1, rnd do
44
44
  local r = i % 2 == 1
45
45
  s = r and quarterRound(s, 1, 5, 9, 13) or quarterRound(s, 1, 6, 11, 16)
@@ -55,17 +55,17 @@ local function hashBlock(state, rnd)
55
55
  return s
56
56
  end
57
57
 
58
- local function LE_toInt(bs, i)
58
+ local function LE_toInt(bs: { number }, i: number): number
59
59
  return (bs[i + 1] or 0)
60
60
  + blshift((bs[i + 2] or 0), 8)
61
61
  + blshift((bs[i + 3] or 0), 16)
62
62
  + blshift((bs[i + 4] or 0), 24)
63
63
  end
64
64
 
65
- local function initState(key, nonce, counter)
65
+ local function initState(key: { number }, nonce: { number }, counter: number): { number }
66
66
  local isKey256 = #key == 32
67
- local const = isKey256 and sigma or tau
68
- local state = table.create(16)
67
+ local const: { number } = isKey256 and sigma or tau
68
+ local state: { number } = table.create(16)
69
69
 
70
70
  state[1] = LE_toInt(const, 0)
71
71
  state[2] = LE_toInt(const, 4)
@@ -89,8 +89,9 @@ local function initState(key, nonce, counter)
89
89
  return state
90
90
  end
91
91
 
92
- local function serialize(state)
93
- local r, len_r = table.create(16), 0
92
+ local function serialize(state: { number }): { number }
93
+ local r: { number } = table.create(16)
94
+ local len_r = 0
94
95
  for i = 1, 16 do
95
96
  r[len_r + 1] = band(state[i], 0xFF)
96
97
  r[len_r + 2] = band(brshift(state[i], 8), 0xFF)
@@ -102,24 +103,34 @@ local function serialize(state)
102
103
  return r
103
104
  end
104
105
 
105
- local function crypt(data, key, nonce, cntr, round)
106
+ export type ByteTable = typeof(setmetatable({} :: { number }, {} :: typeof(util.byteTableMT)))
107
+
108
+ local function crypt(
109
+ data: string | { number },
110
+ key: { number },
111
+ nonce: { number },
112
+ cntr: number?,
113
+ round: number?
114
+ ): ByteTable
106
115
  assert(type(key) == "table", "ChaCha20: Invalid key format (" .. type(key) .. "), must be table")
107
116
  assert(type(nonce) == "table", "ChaCha20: Invalid nonce format (" .. type(nonce) .. "), must be table")
108
117
  assert(#key == 16 or #key == 32, "ChaCha20: Invalid key length (" .. #key .. "), must be 16 or 32")
109
118
  assert(#nonce == 12, "ChaCha20: Invalid nonce length (" .. #nonce .. "), must be 12")
110
119
 
111
- local newData = type(data) == "table" and { table.unpack(data) } or util.stringToByteArray(data)
112
- cntr = tonumber(cntr) or 1
113
- round = tonumber(round) or 20
120
+ local newData: { number } = type(data) == "table" and { table.unpack(data :: { number }) }
121
+ or util.stringToByteArray(data :: string)
122
+ local counter = tonumber(cntr) or 1
123
+ local rounds = tonumber(round) or 20
114
124
 
115
- local out, out_len = {}, 0
116
- local state = initState(key, nonce, cntr)
125
+ local out: { number } = {}
126
+ local out_len = 0
127
+ local state = initState(key, nonce, counter)
117
128
  local blockAmt = math.floor(#newData / 64)
118
129
  for i = 0, blockAmt do
119
- local ks = serialize(hashBlock(state, round))
130
+ local ks = serialize(hashBlock(state, rounds))
120
131
  state[13] = (state[13] + 1) % mod
121
132
 
122
- local block = table.create(64)
133
+ local block: { number } = table.create(64)
123
134
  for j = 1, 64 do
124
135
  block[j] = newData[(i * 64) + j]
125
136
  end
@@ -1,4 +1,4 @@
1
- --!nonstrict
1
+ --!strict
2
2
  --!native
3
3
 
4
4
  --[=[
@@ -49,7 +49,7 @@ local montgomeryModP = modp.montgomeryModP
49
49
  local expModP = modp.expModP
50
50
  local inverseMontgomeryModQ = modq.inverseMontgomeryModQ
51
51
 
52
- local pointMT
52
+ local pointMT: any
53
53
  local ZERO = table.create(7, 0)
54
54
  local ONE = montgomeryModP({ 1, 0, 0, 0, 0, 0, 0 })
55
55
 
@@ -193,9 +193,9 @@ end
193
193
  local function scalarMult(multiplier, P1)
194
194
  -- w = 5
195
195
  local naf = NAF(multiplier, 5)
196
- local PTable = { P1 }
196
+ local PTable: { any } = { P1 }
197
197
  local P2 = pointDouble(P1)
198
- local Q = { table.create(7, 0), { table.unpack(ONE) }, { table.unpack(ONE) } }
198
+ local Q: any = { table.create(7, 0), { table.unpack(ONE) }, { table.unpack(ONE) } }
199
199
 
200
200
  for i = 3, 31, 2 do
201
201
  PTable[i] = pointAdd(PTable[i - 2], P2)
@@ -215,14 +215,14 @@ end
215
215
 
216
216
  -- Lookup table 4-ary NAF method for scalar multiplication by G.
217
217
  -- Precomputations for the regular NAF method are done before the multiplication.
218
- local GTable = { G }
218
+ local GTable: { any } = { G }
219
219
  for i = 2, 168 do
220
220
  GTable[i] = pointDouble(GTable[i - 1])
221
221
  end
222
222
 
223
223
  local function scalarMultG(multiplier)
224
224
  local naf = NAF(multiplier, 2)
225
- local Q = { table.create(7, 0), { table.unpack(ONE) }, { table.unpack(ONE) } }
225
+ local Q: any = { table.create(7, 0), { table.unpack(ONE) }, { table.unpack(ONE) } }
226
226
 
227
227
  for i = 1, 168 do
228
228
  if naf[i] == 1 then
@@ -237,7 +237,7 @@ end
237
237
 
238
238
  -- Point compression and encoding.
239
239
  -- Compresses curve points to 22 bytes.
240
- local function pointEncode(P1)
240
+ local function pointEncode(P1: any)
241
241
  P1 = pointScale(P1)
242
242
  local result = {}
243
243
  local x, y = P1[1], P1[2]
@@ -321,7 +321,7 @@ pointMT = {
321
321
  return pointIsEqual(P1, P2)
322
322
  end,
323
323
 
324
- __mul = function(P1, s)
324
+ __mul = function(P1: any, s: any)
325
325
  if type(P1) == "number" then
326
326
  return s * P1
327
327
  end
@@ -1,4 +1,4 @@
1
- --!nonstrict
1
+ --!strict
2
2
  --!native
3
3
 
4
4
  --[=[
@@ -39,6 +39,9 @@ local modq = require(script.modq)
39
39
  local random = require(script.random)
40
40
  local sha256 = require(script.sha256)
41
41
  local util = require(script.util)
42
+
43
+ type ByteTable = typeof(setmetatable({} :: { number }, {} :: typeof(util.byteTableMT)))
44
+
42
45
  local EllipticCurveCryptography = {}
43
46
 
44
47
  EllipticCurveCryptography.chacha20 = chacha20
@@ -52,7 +55,7 @@ EllipticCurveCryptography._byteMetatable = assert(util.byteTableMT, "No byteTabl
52
55
  @param key any
53
56
  @return boolean
54
57
  ]=]
55
- function EllipticCurveCryptography.isByteTable(key)
58
+ function EllipticCurveCryptography.isByteTable(key: any): boolean
56
59
  return type(key) == "table" and getmetatable(key) == EllipticCurveCryptography._byteMetatable
57
60
  end
58
61
 
@@ -61,14 +64,14 @@ end
61
64
 
62
65
  @param value any
63
66
  ]=]
64
- function EllipticCurveCryptography.createByteTable(value)
67
+ function EllipticCurveCryptography.createByteTable(value: { number }): ByteTable
65
68
  assert(type(value) == "table", "Bad value")
66
69
 
67
70
  return setmetatable(table.clone(value), EllipticCurveCryptography._byteMetatable)
68
71
  end
69
72
 
70
- function EllipticCurveCryptography._getNonceFromEpoch()
71
- local nonce = table.create(12)
73
+ function EllipticCurveCryptography._getNonceFromEpoch(): { number }
74
+ local nonce: { number } = table.create(12)
72
75
  local epoch = DateTime.now().UnixTimestampMillis
73
76
  for i = 1, 12 do
74
77
  nonce[i] = epoch % 256
@@ -98,23 +101,23 @@ end
98
101
  @param key ByteTable
99
102
  @return ByteTable
100
103
  ]=]
101
- function EllipticCurveCryptography.encrypt(data, key)
104
+ function EllipticCurveCryptography.encrypt(data: string | ByteTable, key: ByteTable): ByteTable
102
105
  assert(type(data) == "string" or EllipticCurveCryptography.isByteTable(data), "Bad data")
103
106
  assert(EllipticCurveCryptography.isByteTable(key), "Bad key")
104
107
 
105
- local encKey = sha256.hmac("encKey", key)
106
- local macKey = sha256.hmac("macKey", key)
108
+ local encKey = sha256.hmac("encKey", (key :: any) :: { number })
109
+ local macKey = sha256.hmac("macKey", (key :: any) :: { number })
107
110
  local nonce = EllipticCurveCryptography._getNonceFromEpoch()
108
111
 
109
- local ciphertext = chacha20.crypt(data, encKey, nonce)
112
+ local ciphertext = chacha20.crypt(data :: any, (encKey :: any) :: { number }, nonce)
110
113
 
111
- local result = nonce
112
- for _, value in ipairs(ciphertext) do
114
+ local result: { number } = nonce
115
+ for _, value in ipairs(ciphertext :: any) do
113
116
  table.insert(result, value)
114
117
  end
115
118
 
116
- local mac = sha256.hmac(result, macKey)
117
- for _, value in ipairs(mac) do
119
+ local mac = sha256.hmac(result, (macKey :: any) :: { number })
120
+ for _, value in ipairs((mac :: any) :: { number }) do
118
121
  table.insert(result, value)
119
122
  end
120
123
 
@@ -135,21 +138,22 @@ end
135
138
  @param key ByteTable
136
139
  @return ByteTable
137
140
  ]=]
138
- function EllipticCurveCryptography.decrypt(data, key)
141
+ function EllipticCurveCryptography.decrypt(data: string | ByteTable, key: ByteTable): ByteTable
139
142
  assert(type(data) == "string" or EllipticCurveCryptography.isByteTable(data), "Bad data")
140
143
  assert(EllipticCurveCryptography.isByteTable(key), "Bad key")
141
144
 
142
- local actualData = type(data) == "table" and { table.unpack(data) } or { string.byte(tostring(data), 1, -1) }
143
- local encKey = sha256.hmac("encKey", key)
144
- local macKey = sha256.hmac("macKey", key)
145
- local mac = sha256.hmac({ table.unpack(actualData, 1, #actualData - 32) }, macKey)
145
+ local actualData: { number } = type(data) == "table" and { table.unpack(data :: any) }
146
+ or { string.byte(tostring(data), 1, -1) }
147
+ local encKey = sha256.hmac("encKey", (key :: any) :: { number })
148
+ local macKey = sha256.hmac("macKey", (key :: any) :: { number })
149
+ local mac = sha256.hmac({ table.unpack(actualData, 1, #actualData - 32) }, (macKey :: any) :: { number })
146
150
  local messageMac = { table.unpack(actualData, #actualData - 31) }
147
- assert(mac:isEqual(messageMac), "invalid mac")
151
+ assert((mac :: any):isEqual(messageMac), "invalid mac")
148
152
  local nonce = { table.unpack(actualData, 1, 12) }
149
153
  local ciphertext = { table.unpack(actualData, 13, #actualData - 32) }
150
- local result = chacha20.crypt(ciphertext, encKey, nonce)
154
+ local result: ByteTable = chacha20.crypt(ciphertext, (encKey :: any) :: { number }, nonce)
151
155
 
152
- return setmetatable(result, util.byteTableMT)
156
+ return result
153
157
  end
154
158
 
155
159
  --[=[
@@ -167,10 +171,10 @@ end
167
171
  @return ByteTable -- privateKey
168
172
  @return ByteTable -- publicKey
169
173
  ]=]
170
- function EllipticCurveCryptography.keypair(seed)
174
+ function EllipticCurveCryptography.keypair(seed: number): (ByteTable, ByteTable)
171
175
  assert(type(seed) == "number", "Bad seed")
172
176
 
173
- local x
177
+ local x: any
174
178
  if seed then
175
179
  x = modq.hashModQ(seed)
176
180
  else
@@ -179,8 +183,8 @@ function EllipticCurveCryptography.keypair(seed)
179
183
 
180
184
  local Y = curve.G * x
181
185
 
182
- local privateKey = x:encode()
183
- local publicKey = Y:encode()
186
+ local privateKey: ByteTable = x:encode()
187
+ local publicKey: ByteTable = Y:encode()
184
188
 
185
189
  return privateKey, publicKey
186
190
  end
@@ -203,15 +207,15 @@ end
203
207
  @param publicKey ByteTable
204
208
  @return ByteTable
205
209
  ]=]
206
- function EllipticCurveCryptography.exchange(privateKey, publicKey)
210
+ function EllipticCurveCryptography.exchange(privateKey: ByteTable, publicKey: ByteTable): ByteTable
207
211
  assert(EllipticCurveCryptography.isByteTable(privateKey), "Bad privateKey")
208
212
  assert(EllipticCurveCryptography.isByteTable(publicKey), "Bad publicKey")
209
213
 
210
214
  local x = modq.decodeModQ(privateKey)
211
- local Y = curve.pointDecode(publicKey)
215
+ local Y = curve.pointDecode(publicKey :: any)
212
216
  local Z = Y * x
213
217
 
214
- local sharedSecret = sha256.digest(Z:encode())
218
+ local sharedSecret: ByteTable = sha256.digest(Z:encode())
215
219
 
216
220
  return sharedSecret
217
221
  end
@@ -227,24 +231,25 @@ end
227
231
  @param message string | EncodedMessage
228
232
  @return ByteTable
229
233
  ]=]
230
- function EllipticCurveCryptography.sign(privateKey, message)
234
+ function EllipticCurveCryptography.sign(privateKey: ByteTable, message: string | ByteTable): ByteTable
231
235
  assert(EllipticCurveCryptography.isByteTable(privateKey), "Bad privateKey")
232
236
  assert(type(message) == "string" or EllipticCurveCryptography.isByteTable(message), "Bad message")
233
237
 
234
- local actualMessage = type(message) == "table" and string.char(table.unpack(message)) or tostring(message)
235
- local actualPrivateKey = type(privateKey) == "table" and string.char(table.unpack(privateKey))
238
+ local actualMessage = type(message) == "table" and string.char(table.unpack(message :: any)) or tostring(message)
239
+ local actualPrivateKey = type(privateKey) == "table" and string.char(table.unpack(privateKey :: any))
236
240
  or tostring(privateKey)
237
241
 
238
- local x = modq.decodeModQ(actualPrivateKey)
239
- local k = modq.randomModQ()
242
+ local x: any = modq.decodeModQ(actualPrivateKey)
243
+ local k: any = modq.randomModQ()
240
244
  local R = curve.G * k
241
- local e = modq.hashModQ(actualMessage .. tostring(R))
245
+ local e: any = modq.hashModQ(actualMessage .. tostring(R))
242
246
  local s = k - x * e
243
247
 
244
248
  e = e:encode()
245
249
  s = s:encode()
246
250
 
247
- local result, result_len = e, #e
251
+ local result: { number } = e
252
+ local result_len = #e
248
253
  for index, value in ipairs(s) do
249
254
  result[result_len + index] = value
250
255
  end
@@ -265,16 +270,20 @@ end
265
270
  @param message ByteTable | string
266
271
  @param signature ByteTable
267
272
  ]=]
268
- function EllipticCurveCryptography.verify(publicKey, message, signature)
273
+ function EllipticCurveCryptography.verify(
274
+ publicKey: ByteTable,
275
+ message: string | ByteTable,
276
+ signature: ByteTable
277
+ ): boolean
269
278
  assert(EllipticCurveCryptography.isByteTable(publicKey), "Bad privateKey")
270
279
  assert(type(message) == "string" or EllipticCurveCryptography.isByteTable(message), "Bad message")
271
280
  assert(EllipticCurveCryptography.isByteTable(signature), "Bad signature")
272
281
 
273
- local actualMessage = type(message) == "table" and string.char(table.unpack(message)) or tostring(message)
282
+ local actualMessage = type(message) == "table" and string.char(table.unpack(message :: any)) or tostring(message)
274
283
  local sigLen = #signature
275
- local Y = curve.pointDecode(publicKey)
276
- local e = modq.decodeModQ({ table.unpack(signature, 1, sigLen / 2) })
277
- local s = modq.decodeModQ({ table.unpack(signature, sigLen / 2 + 1) })
284
+ local Y = curve.pointDecode(publicKey :: any)
285
+ local e = modq.decodeModQ({ table.unpack(signature :: any, 1, sigLen / 2) })
286
+ local s = modq.decodeModQ({ table.unpack(signature :: any, sigLen / 2 + 1) })
278
287
  local Rv = curve.G * s + Y * e
279
288
  local ev = modq.hashModQ(actualMessage .. tostring(Rv))
280
289
 
@@ -1,4 +1,4 @@
1
- --!nonstrict
1
+ --!strict
2
2
  -- Arithmetic on the finite field of integers modulo p
3
3
  -- Where p is the finite field modulus
4
4
  local arith = require(script.Parent.arith)
@@ -8,17 +8,20 @@ local addDouble = arith.addDouble
8
8
  local mult = arith.mult
9
9
  local square = arith.square
10
10
 
11
- local p = { 3, 0, 0, 0, 0, 0, 15761408 }
11
+ type BigInt = { number }
12
+ type DoubleInt = { number }
13
+
14
+ local p: BigInt = { 3, 0, 0, 0, 0, 0, 15761408 }
12
15
 
13
16
  -- We're using the Montgomery Reduction for fast modular multiplication.
14
17
  -- https://en.wikipedia.org/wiki/Montgomery_modular_multiplication
15
18
  -- r = 2^168
16
19
  -- p * pInverse = -1 (mod r)
17
20
  -- r2 = r * r (mod p)
18
- local pInverse = { 5592405, 5592405, 5592405, 5592405, 5592405, 5592405, 14800213 }
19
- local r2 = { 13533400, 837116, 6278376, 13533388, 837116, 6278376, 7504076 }
21
+ local pInverse: BigInt = { 5592405, 5592405, 5592405, 5592405, 5592405, 5592405, 14800213 }
22
+ local r2: BigInt = { 13533400, 837116, 6278376, 13533388, 837116, 6278376, 7504076 }
20
23
 
21
- local function multByP(a)
24
+ local function multByP(a: BigInt): DoubleInt
22
25
  local a1, a2, a3, a4, a5, a6, a7 = a[1], a[2], a[3], a[4], a[5], a[6], a[7]
23
26
 
24
27
  local c1 = a1 * 3
@@ -82,7 +85,7 @@ local function multByP(a)
82
85
  end
83
86
 
84
87
  -- Reduces a number from [0, 2p - 1] to [0, p - 1]
85
- local function reduceModP(a)
88
+ local function reduceModP(a: BigInt): BigInt
86
89
  -- a < p
87
90
  if a[7] < 15761408 or a[7] == 15761408 and a[1] < 3 then
88
91
  return { table.unpack(a) }
@@ -133,11 +136,11 @@ local function reduceModP(a)
133
136
  return { c1, c2, c3, c4, c5, c6, c7 }
134
137
  end
135
138
 
136
- local function addModP(a, b)
139
+ local function addModP(a: BigInt, b: BigInt): BigInt
137
140
  return reduceModP(add(a, b))
138
141
  end
139
142
 
140
- local function subModP(a, b)
143
+ local function subModP(a: BigInt, b: BigInt): BigInt
141
144
  local result = sub(a, b)
142
145
 
143
146
  if result[7] < 0 then
@@ -149,29 +152,29 @@ end
149
152
 
150
153
  -- Montgomery REDC algorithn
151
154
  -- Reduces a number from [0, p^2 - 1] to [0, p - 1]
152
- local function REDC(T)
155
+ local function REDC(T: DoubleInt): BigInt
153
156
  local m = mult(T, pInverse, true)
154
- local t = { table.unpack(addDouble(T, multByP(m)), 8, 14) }
157
+ local t: BigInt = { table.unpack(addDouble(T, multByP(m)), 8, 14) }
155
158
 
156
159
  return reduceModP(t)
157
160
  end
158
161
 
159
- local function multModP(a, b)
162
+ local function multModP(a: BigInt, b: BigInt): BigInt
160
163
  -- Only works with a, b in Montgomery form
161
- return REDC(mult(a, b))
164
+ return REDC(mult(a, b, false))
162
165
  end
163
166
 
164
- local function squareModP(a)
167
+ local function squareModP(a: BigInt): BigInt
165
168
  -- Only works with a in Montgomery form
166
169
  return REDC(square(a))
167
170
  end
168
171
 
169
- local function montgomeryModP(a)
172
+ local function montgomeryModP(a: BigInt): BigInt
170
173
  return multModP(a, r2)
171
174
  end
172
175
 
173
- local function inverseMontgomeryModP(a)
174
- local newA = { table.unpack(a) }
176
+ local function inverseMontgomeryModP(a: BigInt): BigInt
177
+ local newA: DoubleInt = { table.unpack(a) }
175
178
 
176
179
  for i = 8, 14 do
177
180
  newA[i] = 0
@@ -180,11 +183,11 @@ local function inverseMontgomeryModP(a)
180
183
  return REDC(newA)
181
184
  end
182
185
 
183
- local ONE = montgomeryModP({ 1, 0, 0, 0, 0, 0, 0 })
186
+ local ONE: BigInt = montgomeryModP({ 1, 0, 0, 0, 0, 0, 0 })
184
187
 
185
- local function expModP(base, exponentBinary)
186
- local newBase = { table.unpack(base) }
187
- local result = { table.unpack(ONE) }
188
+ local function expModP(base: BigInt, exponentBinary: { number }): BigInt
189
+ local newBase: BigInt = { table.unpack(base) }
190
+ local result: BigInt = { table.unpack(ONE) }
188
191
 
189
192
  for i = 1, 168 do
190
193
  if exponentBinary[i] == 1 then
@@ -1,4 +1,4 @@
1
- --!nonstrict
1
+ --!strict
2
2
  --!native
3
3
 
4
4
  -- Arithmetic on the Finite Field of Integers modulo q
@@ -8,6 +8,8 @@ local random = require(script.Parent.random)
8
8
  local sha256 = require(script.Parent.sha256)
9
9
  local util = require(script.Parent.util)
10
10
 
11
+ type BigInt = { number }
12
+
11
13
  local isEqual = arith.isEqual
12
14
  local compare = arith.compare
13
15
  local add = arith.add
@@ -18,11 +20,11 @@ local square = arith.square
18
20
  local encodeInt = arith.encodeInt
19
21
  local decodeInt = arith.decodeInt
20
22
 
21
- local modQMT
23
+ local modQMT: any
22
24
 
23
- local q = { 9622359, 6699217, 13940450, 16775734, 16777215, 16777215, 3940351 }
25
+ local q: BigInt = { 9622359, 6699217, 13940450, 16775734, 16777215, 16777215, 3940351 }
24
26
  -- this isn't an optimization, it just shortens the amount of time I have to scroll
25
- local qMinusTwoBinary = table.create(166, 1)
27
+ local qMinusTwoBinary: { number } = table.create(166, 1)
26
28
  qMinusTwoBinary[2] = 0
27
29
  qMinusTwoBinary[4] = 0
28
30
  qMinusTwoBinary[6] = 0
@@ -76,59 +78,59 @@ qMinusTwoBinary[162] = 0
76
78
  -- r = 2^168
77
79
  -- q * qInverse = -1 (mod r)
78
80
  -- r2 = r * r (mod q)
79
- local qInverse = { 15218585, 5740955, 3271338, 9903997, 9067368, 7173545, 6988392 }
80
- local r2 = { 1336213, 11071705, 9716828, 11083885, 9188643, 1494868, 3306114 }
81
+ local qInverse: BigInt = { 15218585, 5740955, 3271338, 9903997, 9067368, 7173545, 6988392 }
82
+ local r2: BigInt = { 1336213, 11071705, 9716828, 11083885, 9188643, 1494868, 3306114 }
81
83
 
82
84
  -- Reduces a number from [0, 2q - 1] to [0, q - 1]
83
- local function reduceModQ(a)
84
- local result = { table.unpack(a) }
85
+ local function reduceModQ(a: BigInt): BigInt
86
+ local result: BigInt = { table.unpack(a) }
85
87
 
86
88
  if compare(result, q) >= 0 then
87
89
  result = sub(result, q)
88
90
  end
89
91
 
90
- return setmetatable(result, modQMT)
92
+ return setmetatable(result, modQMT) :: any
91
93
  end
92
94
 
93
- local function addModQ(a, b)
95
+ local function addModQ(a: BigInt, b: BigInt): BigInt
94
96
  return reduceModQ(add(a, b))
95
97
  end
96
98
 
97
- local function subModQ(a, b)
98
- local result = sub(a, b)
99
+ local function subModQ(a: BigInt, b: BigInt): BigInt
100
+ local result: BigInt = sub(a, b)
99
101
 
100
102
  if result[7] < 0 then
101
103
  result = add(result, q)
102
104
  end
103
105
 
104
- return setmetatable(result, modQMT)
106
+ return setmetatable(result, modQMT) :: any
105
107
  end
106
108
 
107
109
  -- Montgomery REDC algorithn
108
110
  -- Reduces a number from [0, q^2 - 1] to [0, q - 1]
109
- local function REDC(T)
110
- local m = { table.unpack(mult({ table.unpack(T, 1, 7) }, qInverse, true), 1, 7) }
111
- local t = { table.unpack(addDouble(T, mult(m, q)), 8, 14) }
111
+ local function REDC(T: { number }): BigInt
112
+ local m: BigInt = { table.unpack(mult({ table.unpack(T, 1, 7) }, qInverse, true), 1, 7) }
113
+ local t: BigInt = { table.unpack(addDouble(T, mult(m, q, false)), 8, 14) }
112
114
 
113
115
  return reduceModQ(t)
114
116
  end
115
117
 
116
- local function multModQ(a, b)
118
+ local function multModQ(a: BigInt, b: BigInt): BigInt
117
119
  -- Only works with a, b in Montgomery form
118
- return REDC(mult(a, b))
120
+ return REDC(mult(a, b, false))
119
121
  end
120
122
 
121
- local function squareModQ(a)
123
+ local function squareModQ(a: BigInt): BigInt
122
124
  -- Only works with a in Montgomery form
123
125
  return REDC(square(a))
124
126
  end
125
127
 
126
- local function montgomeryModQ(a)
128
+ local function montgomeryModQ(a: BigInt): BigInt
127
129
  return multModQ(a, r2)
128
130
  end
129
131
 
130
- local function inverseMontgomeryModQ(a)
131
- local newA = { table.unpack(a) }
132
+ local function inverseMontgomeryModQ(a: BigInt): BigInt
133
+ local newA: { number } = { table.unpack(a) }
132
134
 
133
135
  for i = 8, 14 do
134
136
  newA[i] = 0
@@ -137,11 +139,11 @@ local function inverseMontgomeryModQ(a)
137
139
  return REDC(newA)
138
140
  end
139
141
 
140
- local ONE = montgomeryModQ({ 1, 0, 0, 0, 0, 0, 0 })
142
+ local ONE: BigInt = montgomeryModQ({ 1, 0, 0, 0, 0, 0, 0 })
141
143
 
142
- local function expModQ(base, exponentBinary)
143
- local newBase = { table.unpack(base) }
144
- local result = { table.unpack(ONE) }
144
+ local function expModQ(base: BigInt, exponentBinary: { number }): BigInt
145
+ local newBase: BigInt = { table.unpack(base) }
146
+ local result: BigInt = { table.unpack(ONE) }
145
147
 
146
148
  for i = 1, 168 do
147
149
  if exponentBinary[i] == 1 then
@@ -154,9 +156,9 @@ local function expModQ(base, exponentBinary)
154
156
  return result
155
157
  end
156
158
 
157
- local function intExpModQ(base, exponent)
158
- local newBase = { table.unpack(base) }
159
- local result = setmetatable({ table.unpack(ONE) }, modQMT)
159
+ local function intExpModQ(base: BigInt, exponent: number): BigInt
160
+ local newBase: BigInt = { table.unpack(base) }
161
+ local result: BigInt = setmetatable({ table.unpack(ONE) }, modQMT) :: any
160
162
 
161
163
  if exponent < 0 then
162
164
  newBase = expModQ(newBase, qMinusTwoBinary)
@@ -175,46 +177,46 @@ local function intExpModQ(base, exponent)
175
177
  return result
176
178
  end
177
179
 
178
- local function encodeModQ(a)
180
+ local function encodeModQ(a: BigInt): { number }
179
181
  local result = encodeInt(a)
180
182
 
181
- return setmetatable(result, util.byteTableMT)
183
+ return setmetatable(result, util.byteTableMT) :: any
182
184
  end
183
185
 
184
- local function decodeModQ(s)
185
- s = type(s) == "table" and { table.unpack(s, 1, 21) } or { string.byte(tostring(s), 1, 21) }
186
- local result = decodeInt(s)
186
+ local function decodeModQ(s: any): BigInt
187
+ s = type(s) == "table" and { table.unpack(s :: { number }, 1, 21) } or { string.byte(tostring(s), 1, 21) }
188
+ local result: BigInt = decodeInt(s)
187
189
  result[7] %= q[7]
188
190
 
189
- return setmetatable(result, modQMT)
191
+ return setmetatable(result, modQMT) :: any
190
192
  end
191
193
 
192
- local function randomModQ()
194
+ local function randomModQ(): BigInt
193
195
  while true do
194
- local s = { table.unpack(random.random(), 1, 21) }
195
- local result = decodeInt(s)
196
+ local s: { number } = { table.unpack(random.random() :: any, 1, 21) }
197
+ local result: BigInt = decodeInt(s)
196
198
  if result[7] < q[7] then
197
- return setmetatable(result, modQMT)
199
+ return setmetatable(result, modQMT) :: any
198
200
  end
199
201
  end
200
202
  end
201
203
 
202
- local function hashModQ(data)
204
+ local function hashModQ(data: any): BigInt
203
205
  return decodeModQ(sha256.digest(data))
204
206
  end
205
207
 
206
208
  modQMT = {
207
209
  __index = {
208
- encode = function(self)
210
+ encode = function(self: BigInt): { number }
209
211
  return encodeModQ(self)
210
212
  end,
211
213
  },
212
214
 
213
- __tostring = function(self)
214
- return self:encode():toHex()
215
+ __tostring = function(self: BigInt): string
216
+ return (self :: any):encode():toHex()
215
217
  end,
216
218
 
217
- __add = function(self, other)
219
+ __add = function(self: any, other: any): BigInt
218
220
  if type(self) == "number" then
219
221
  return other + self
220
222
  end
@@ -227,7 +229,7 @@ modQMT = {
227
229
  return addModQ(self, other)
228
230
  end,
229
231
 
230
- __sub = function(a, b)
232
+ __sub = function(a: any, b: any): BigInt
231
233
  if type(a) == "number" then
232
234
  assert(a < 16777216, "number operand too big")
233
235
  a = montgomeryModQ({ a, 0, 0, 0, 0, 0, 0 })
@@ -241,15 +243,15 @@ modQMT = {
241
243
  return subModQ(a, b)
242
244
  end,
243
245
 
244
- __unm = function(self)
246
+ __unm = function(self: BigInt): BigInt
245
247
  return subModQ(q, self)
246
248
  end,
247
249
 
248
- __eq = function(self, other)
250
+ __eq = function(self: BigInt, other: BigInt): boolean
249
251
  return isEqual(self, other)
250
252
  end,
251
253
 
252
- __mul = function(self, other)
254
+ __mul = function(self: any, other: any): BigInt
253
255
  if type(self) == "number" then
254
256
  return other * self
255
257
  end
@@ -268,7 +270,7 @@ modQMT = {
268
270
  return multModQ(self, other)
269
271
  end,
270
272
 
271
- __div = function(a, b)
273
+ __div = function(a: any, b: any): BigInt
272
274
  if type(a) == "number" then
273
275
  assert(a < 16777216, "number operand too big")
274
276
  a = montgomeryModQ({ a, 0, 0, 0, 0, 0, 0 })
@@ -279,12 +281,12 @@ modQMT = {
279
281
  b = montgomeryModQ({ b, 0, 0, 0, 0, 0, 0 })
280
282
  end
281
283
 
282
- local bInv = expModQ(b, qMinusTwoBinary)
284
+ local bInv: BigInt = expModQ(b, qMinusTwoBinary)
283
285
 
284
286
  return multModQ(a, bInv)
285
287
  end,
286
288
 
287
- __pow = function(self, other)
289
+ __pow = function(self: BigInt, other: number): BigInt
288
290
  return intExpModQ(self, other)
289
291
  end,
290
292
  }
@@ -1,15 +1,16 @@
1
- --!nonstrict
1
+ --!strict
2
2
  --!native
3
3
 
4
4
  -- random.lua - Random Byte Generator
5
5
  local sha256 = require(script.Parent.sha256)
6
6
 
7
- local entropy = ""
8
- local accumulator, accumulator_len = {}, 0
7
+ local entropy: string = ""
8
+ local accumulator: { string } = {}
9
+ local accumulator_len: number = 0
9
10
 
10
11
  local random = {}
11
12
 
12
- local function feed(data)
13
+ local function feed(data: any)
13
14
  accumulator_len += 1
14
15
  accumulator[accumulator_len] = tostring(data or "")
15
16
  end
@@ -21,7 +22,7 @@ local function digest()
21
22
  accumulator_len = 0
22
23
  end
23
24
 
24
- local entropyInitialized = false
25
+ local entropyInitialized: boolean = false
25
26
 
26
27
  -- Defer this initialization until requested
27
28
  local function ensureEntropyInit()
@@ -55,7 +56,7 @@ local function ensureEntropyInit()
55
56
  -- TODO: Suppress this warning
56
57
  warn(
57
58
  string.format(
58
- "[EllipticCurveCryptography.random] - Generating entropy took %s ms",
59
+ "[EllipticCurveCryptography.random] - Generating entropy took %g ms",
59
60
  1000 * (os.clock() - startTime)
60
61
  )
61
62
  )
@@ -72,7 +73,7 @@ function random.save()
72
73
  entropy = tostring(sha256.digest(entropy))
73
74
  end
74
75
 
75
- function random.seed(data)
76
+ function random.seed(data: any)
76
77
  ensureEntropyInit()
77
78
 
78
79
  feed("seed")
@@ -83,7 +84,7 @@ function random.seed(data)
83
84
  random.save()
84
85
  end
85
86
 
86
- function random.random()
87
+ function random.random(): any
87
88
  ensureEntropyInit()
88
89
 
89
90
  feed("random")
@@ -1,4 +1,4 @@
1
- --!nonstrict
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
- data = data or ""
194
- data = type(data) == "table" and { table.unpack(data) } or util.stringToByteArray(data)
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
- data = preprocess(data)
197
- local C = { table.unpack(H) }
198
- for _, value in ipairs(data) do
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) } or util.stringToByteArray(data)
207
- local actualKey = type(key) == "table" and { table.unpack(key) } or util.stringToByteArray(key)
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
- ipad = digest(ipad)
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] = ipad[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 or util.stringToByteArray(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
- --!nonstrict
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