refactor: address lint and formatting issues

This commit is contained in:
Erica Marigold 2024-03-27 17:09:50 +05:30
parent c9301f4eb4
commit 0e398939ce
No known key found for this signature in database
GPG key ID: 2768CC0C23D245D1
7 changed files with 256 additions and 370 deletions

View file

@ -1,6 +1,6 @@
{ {
"printWidth": 120, "printWidth": 120,
"tabWidth": 4, "tabWidth": 5,
"trailingComma": "all", "trailingComma": "all",
"useTabs": true "useTabs": true
} }

35
.vscode/settings.json vendored
View file

@ -1,22 +1,23 @@
{ {
// Lune // Lune
"luau-lsp.require.mode": "relativeToFile", "luau-lsp.require.mode": "relativeToFile",
"luau-lsp.require.directoryAliases": { "luau-lsp.require.directoryAliases": {
"@lune/": "~/.lune/.typedefs/0.8.2/" "@lune/": "~/.lune/.typedefs/0.8.2/"
}, },
// Formatting // Formatting
"editor.formatOnSave": true, "editor.formatOnSave": true,
"editor.defaultFormatter": "esbenp.prettier-vscode", "editor.defaultFormatter": "esbenp.prettier-vscode",
"[luau][lua]": { "[luau][lua]": {
"editor.defaultFormatter": "JohnnyMorganz.stylua" "editor.defaultFormatter": "JohnnyMorganz.stylua"
}, },
// Linting // Linting
"eslint.run": "onType", "eslint.run": "onType",
"eslint.format.enable": true, "eslint.format.enable": true,
"cSpell.enabled": false,
// Misc // Misc
"typescript.tsdk": "node_modules/typescript/lib", "typescript.tsdk": "node_modules/typescript/lib",
"files.eol": "\n" "files.eol": "\n"
} }

View file

@ -7,7 +7,9 @@
"build": "rbxtsc", "build": "rbxtsc",
"watch": "rbxtsc -w", "watch": "rbxtsc -w",
"lint": "eslint src", "lint": "eslint src",
"fmt": "prettier .", "check_fmt": "prettier -c src/",
"check": "pnpm lint && pnpm check_fmt",
"fmt": "prettier -w src/",
"postinstall": "patch -f node_modules/@rbxts/types/include/roblox.d.ts < lune_require_patch.diff", "postinstall": "patch -f node_modules/@rbxts/types/include/roblox.d.ts < lune_require_patch.diff",
"prepublishOnly": "pnpm run build" "prepublishOnly": "pnpm run build"
}, },

View file

@ -1,117 +1,111 @@
const { slice } = require<{ const { slice } = require<{
slice: <T extends defined>(arr: T[], start: number, stop?: number) => T[]; slice: <T extends defined>(arr: T[], start: number, stop?: number) => T[];
}>("util"); }>("util");
function stringToBytes(str: string) { function stringToBytes(str: string) {
let result = []; const result = [];
for (let i = 0; i < str.size(); i++) { for (let i = 0; i < str.size(); i++) {
result.push(string.byte(str, i + 1)[0]); result.push(string.byte(str, i + 1)[0]);
} }
return result; return result;
} }
// Adapted from https://github.com/un-ts/ab64/blob/main/src/ponyfill.ts#L24 // Adapted from https://github.com/un-ts/ab64/blob/main/src/ponyfill.ts#L24
const _atob = (asc: string) => { const _atob = (asc: string) => {
const b64CharList = const b64CharList = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
const b64Chars = string.split(b64CharList, ""); const b64Chars = string.split(b64CharList, "");
const b64Table = b64Chars.reduce<Record<string, number>>( const b64Table = b64Chars.reduce<Record<string, number>>((acc, char, index) => {
(acc, char, index) => { acc[char] = index;
acc[char] = index; return acc;
return acc; }, {});
},
{}
);
const fromCharCode = string.char; const fromCharCode = string.char;
asc = string.gsub(asc, "%s+", "")[0]; asc = string.gsub(asc, "%s+", "")[0];
asc += string.char(...slice(stringToBytes("=="), 2 - (asc.size() & 3))); asc += string.char(...slice(stringToBytes("=="), 2 - (asc.size() & 3)));
let u24: number; let u24: number;
let binary = ""; let binary = "";
let r1: number; let r1: number;
let r2: number; let r2: number;
for (let i = 0; i < asc.size(); ) { for (let i = 0; i < asc.size(); ) {
u24 = u24 =
(b64Table[string.byte(asc, i++)[0]] << 18) | (b64Table[string.byte(asc, i++)[0]] << 18) |
(b64Table[string.byte(asc, i++)[0]] << 12) | (b64Table[string.byte(asc, i++)[0]] << 12) |
((r1 = b64Table[string.byte(asc, i++)[0]]) << 6) | ((r1 = b64Table[string.byte(asc, i++)[0]]) << 6) |
(r2 = b64Table[string.byte(asc, i++)[0]]); (r2 = b64Table[string.byte(asc, i++)[0]]);
binary += binary +=
r1 === 64 r1 === 64
? fromCharCode((u24 >> 16) & 255) ? fromCharCode((u24 >> 16) & 255)
: r2 === 64 : r2 === 64
? fromCharCode((u24 >> 16) & 255, (u24 >> 8) & 255) ? fromCharCode((u24 >> 16) & 255, (u24 >> 8) & 255)
: fromCharCode((u24 >> 16) & 255, (u24 >> 8) & 255, u24 & 255); : fromCharCode((u24 >> 16) & 255, (u24 >> 8) & 255, u24 & 255);
} }
return binary; return binary;
}; };
// Adapted from https://gist.github.com/jonleighton/958841 // Adapted from https://gist.github.com/jonleighton/958841
export function atob(buf: number[]): string { export function atob(buf: number[]): string {
let base64 = ""; let base64 = "";
let encodings = const encodings = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
let byteLength = buf.size(); const byteLength = buf.size();
let byteRemainder = byteLength % 3; const byteRemainder = byteLength % 3;
let mainLength = byteLength - byteRemainder; const mainLength = byteLength - byteRemainder;
let a: number, b: number, c: number, d: number; let a: number, b: number, c: number, d: number;
let chunk; let chunk;
// Main loop deals with bytes in chunks of 3 // Main loop deals with bytes in chunks of 3
for (let i = 0; i < mainLength; i = i + 3) { for (let i = 0; i < mainLength; i = i + 3) {
// Combine the three bytes into a single integer // Combine the three bytes into a single integer
chunk = (buf[i] << 16) | (buf[i + 1] << 8) | buf[i + 2]; chunk = (buf[i] << 16) | (buf[i + 1] << 8) | buf[i + 2];
// Use bitmasks to extract 6-bit segments from the triplet // Use bitmasks to extract 6-bit segments from the triplet
a = (chunk & 16515072) >> 18; // 16515072 = (2^6 - 1) << 18 a = (chunk & 16515072) >> 18;
b = (chunk & 258048) >> 12; // 258048 = (2^6 - 1) << 12 b = (chunk & 258048) >> 12;
c = (chunk & 4032) >> 6; // 4032 = (2^6 - 1) << 6 c = (chunk & 4032) >> 6;
d = chunk & 63; // 63 = 2^6 - 1 d = chunk & 63;
// Convert the raw binary segments to the appropriate ASCII encoding // Convert the raw binary segments to the appropriate ASCII encoding
base64 += base64 +=
string.char(string.byte(encodings, a + 1)[0]) + string.char(string.byte(encodings, a + 1)[0]) +
string.char(string.byte(encodings, b + 1)[0]) + string.char(string.byte(encodings, b + 1)[0]) +
string.char(string.byte(encodings, c + 1)[0]) + string.char(string.byte(encodings, c + 1)[0]) +
string.char(string.byte(encodings, d + 1)[0]); string.char(string.byte(encodings, d + 1)[0]);
} }
// Deal with the remaining bytes and padding // Deal with the remaining bytes and padding
if (byteRemainder === 1) { if (byteRemainder === 1) {
chunk = buf[mainLength]; chunk = buf[mainLength];
a = (chunk & 252) >> 2; // 252 = (2^6 - 1) << 2 a = (chunk & 252) >> 2;
// Set the 4 least significant bits to zero // Set the 4 least significant bits to zero
b = (chunk & 3) << 4; // 3 = 2^2 - 1 b = (chunk & 3) << 4;
base64 += base64 += string.byte(encodings, a)[0] + string.byte(encodings, b)[0] + "==";
string.byte(encodings, a)[0] + string.byte(encodings, b)[0] + "=="; } else if (byteRemainder === 2) {
} else if (byteRemainder === 2) { chunk = (buf[mainLength] << 8) | buf[mainLength + 1];
chunk = (buf[mainLength] << 8) | buf[mainLength + 1];
a = (chunk & 64512) >> 10; // 64512 = (2^6 - 1) << 10 a = (chunk & 64512) >> 10;
b = (chunk & 1008) >> 4; // 1008 = (2^6 - 1) << 4 b = (chunk & 1008) >> 4;
// Set the 2 least significant bits to zero // Set the 2 least significant bits to zero
c = (chunk & 15) << 2; // 15 = 2^4 - 1 c = (chunk & 15) << 2;
base64 += base64 +=
string.char(string.byte(encodings, a + 1)[0]) + string.char(string.byte(encodings, a + 1)[0]) +
string.char(string.byte(encodings, b + 1)[0]) + string.char(string.byte(encodings, b + 1)[0]) +
string.char(string.byte(encodings, c + 1)[0]) + string.char(string.byte(encodings, c + 1)[0]) +
"="; "=";
} }
return base64; return base64;
} }

View file

@ -1,26 +1,26 @@
const { generatePrivateKey, generatePublicKey } = require<{ const { generatePrivateKey, generatePublicKey } = require<{
generatePrivateKey: () => number[]; generatePrivateKey: () => number[];
generatePublicKey: (privateKey: number[]) => number[]; generatePublicKey: (privateKey: number[]) => number[];
}>("wg"); }>("wg");
const { atob } = require<{ atob: (buf: number[]) => string }>("base64"); const { atob } = require<{ atob: (buf: number[]) => string }>("base64");
export interface Keypair { export interface Keypair {
publicKey: string; publicKey: string;
privateKey: string; privateKey: string;
} }
export interface Wireguard { export interface Wireguard {
generateKeypair(): Keypair; generateKeypair(): Keypair;
} }
export const wireguard: Wireguard = { export const wireguard: Wireguard = {
generateKeypair: function () { generateKeypair: function () {
const privateKey = generatePrivateKey(); const privateKey = generatePrivateKey();
const publicKey = generatePublicKey(privateKey); const publicKey = generatePublicKey(privateKey);
return { return {
publicKey: atob(publicKey), publicKey: atob(publicKey),
privateKey: atob(privateKey), privateKey: atob(privateKey),
}; };
}, },
}; };

View file

@ -1,21 +1,21 @@
export function slice<T extends defined>(arr: T[], start: number, stop?: number): T[] { export function slice<T extends defined>(arr: T[], start: number, stop?: number): T[] {
const length = arr.size(); const length = arr.size();
if (start < 0) { if (start < 0) {
start = math.max(length + start, 0); start = math.max(length + start, 0);
} }
if (stop === undefined) { if (stop === undefined) {
stop = length; stop = length;
} else if (stop < 0) { } else if (stop < 0) {
stop = math.max(length + stop, 0); stop = math.max(length + stop, 0);
} }
const result: T[] = []; const result: T[] = [];
for (let i = start; i < stop; i++) { for (let i = start; i < stop; i++) {
result.push(arr[i]); result.push(arr[i]);
} }
return result; return result;
} }

367
src/wg.ts
View file

@ -1,282 +1,171 @@
const { atob } = require<{ atob: (buf: number[]) => string }>("base64"); const { atob } = require<{ atob: (buf: number[]) => string }>("base64");
function gf(init?: number[]): number[] { function gf(init?: number[]): number[] {
const r = new Array<number>(16, 0); const r = new Array<number>(16, 0);
if (init) { if (init) {
for (let i = 0; i < init.size(); ++i) { for (let i = 0; i < init.size(); ++i) {
r[i] = init[i]; r[i] = init[i];
} }
} }
return r; return r;
} }
function pack(o: number[], n: number[]) { function pack(o: number[], n: number[]) {
let b: number, let b: number;
m = gf(), const m = gf(),
t = gf(); t = gf();
for (let i = 0; i < 16; ++i) { for (let i = 0; i < 16; ++i) {
t[i] = n[i]; t[i] = n[i];
} }
carry(t); carry(t);
carry(t); carry(t);
carry(t); carry(t);
for (let j = 0; j < 2; ++j) { for (let j = 0; j < 2; ++j) {
m[0] = t[0] - 0xffed; m[0] = t[0] - 0xffed;
for (let i = 1; i < 15; ++i) { for (let i = 1; i < 15; ++i) {
m[i] = t[i] - 0xffff - ((m[i - 1] >> 16) & 1); m[i] = t[i] - 0xffff - ((m[i - 1] >> 16) & 1);
m[i - 1] &= 0xffff; m[i - 1] &= 0xffff;
} }
m[15] = t[15] - 0x7fff - ((m[14] >> 16) & 1); m[15] = t[15] - 0x7fff - ((m[14] >> 16) & 1);
b = (m[15] >> 16) & 1; b = (m[15] >> 16) & 1;
m[14] &= 0xffff; m[14] &= 0xffff;
cswap(t, m, 1 - b); cswap(t, m, 1 - b);
} }
for (let i = 0; i < 16; ++i) { for (let i = 0; i < 16; ++i) {
o[2 * i] = t[i] & 0xff; o[2 * i] = t[i] & 0xff;
o[2 * i + 1] = t[i] >> 8; o[2 * i + 1] = t[i] >> 8;
} }
} }
function carry(o: number[]) { function carry(o: number[]) {
let c: number; let c: number;
for (let i = 0; i < 16; ++i) { for (let i = 0; i < 16; ++i) {
o[(i + 1) % 16] += (i < 15 ? 1 : 38) * math.floor(o[i] / 65536); o[(i + 1) % 16] += (i < 15 ? 1 : 38) * math.floor(o[i] / 65536);
o[i] &= 0xffff; o[i] &= 0xffff;
} }
} }
function cswap(p: number[], q: number[], b: number) { function cswap(p: number[], q: number[], b: number) {
let t: number, let t: number;
c = ~(b - 1); const c = ~(b - 1);
for (let i = 0; i < 16; ++i) { for (let i = 0; i < 16; ++i) {
t = c & (p[i] ^ q[i]); t = c & (p[i] ^ q[i]);
p[i] ^= t; p[i] ^= t;
q[i] ^= t; q[i] ^= t;
} }
} }
function add(o: number[], a: number[], b: number[]) { function add(o: number[], a: number[], b: number[]) {
for (let i = 0; i < 16; ++i) { for (let i = 0; i < 16; ++i) {
o[i] = (a[i] + b[i]) | 0; o[i] = (a[i] + b[i]) | 0;
} }
} }
function subtract(o: number[], a: number[], b: number[]) { function subtract(o: number[], a: number[], b: number[]) {
for (let i = 0; i < 16; ++i) { for (let i = 0; i < 16; ++i) {
o[i] = (a[i] - b[i]) | 0; o[i] = (a[i] - b[i]) | 0;
} }
} }
function multmod(o: number[], a: number[], b: number[]) { function multmod(o: number[], a: number[], b: number[]) {
const t = new Array<number>(31, 0); const t = new Array<number>(31, 0);
for (let i = 0; i < 16; ++i) { for (let i = 0; i < 16; ++i) {
for (let j = 0; j < 16; ++j) { for (let j = 0; j < 16; ++j) {
t[i + j] += a[i] * b[j]; t[i + j] += a[i] * b[j];
} }
} }
for (let i = 0; i < 15; ++i) { for (let i = 0; i < 15; ++i) {
t[i] += 38 * t[i + 16]; t[i] += 38 * t[i + 16];
} }
for (let i = 0; i < 16; ++i) { for (let i = 0; i < 16; ++i) {
o[i] = t[i]; o[i] = t[i];
} }
carry(o); carry(o);
carry(o); carry(o);
} }
function invert(o: number[], i: number[]) { function invert(o: number[], i: number[]) {
const c = gf(); const c = gf();
for (let a = 0; a < 16; ++a) { for (let a = 0; a < 16; ++a) {
c[a] = i[a]; c[a] = i[a];
} }
for (let a = 253; a >= 0; --a) { for (let a = 253; a >= 0; --a) {
multmod(c, c, c); multmod(c, c, c);
if (a !== 2 && a !== 4) { if (a !== 2 && a !== 4) {
multmod(c, c, i); multmod(c, c, i);
} }
} }
for (let a = 0; a < 16; ++a) { for (let a = 0; a < 16; ++a) {
o[a] = c[a]; o[a] = c[a];
} }
} }
let Base64 = {
_keyStr: "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",
encode: function (e: string) {
let t = "";
let n: number, r: number, i: number, s, o, u, a;
let f = 0;
e = Base64._utf8_encode(e);
while (f < e.size()) {
n = string.byte(e, f++)[0];
r = string.byte(e, f++)[0];
i = string.byte(e, f++)[0];
s = n >> 2;
o = ((n & 3) << 4) | (r >> 4);
u = ((r & 15) << 2) | (i >> 6);
a = i & 63;
if (r !== r) {
u = a = 64;
} else if (i !== i) {
a = 64;
}
t =
t +
string.byte(this._keyStr, s)[0] +
string.byte(this._keyStr, o)[0] +
string.byte(this._keyStr, u)[0] +
string.byte(this._keyStr, a)[0];
}
return t;
},
decode: function (e: string) {
let t = "";
let n, r, i;
let s: number, o: number, u: number, a: number;
let f = 0;
e = string.gsub(e, "[^A-Za-z0-9%+%/%=]", "")[0];
while (f < e.size()) {
s = string.find(
this._keyStr,
string.char(string.byte(e, f++)[0])
)[0] as number;
o = string.find(
this._keyStr,
string.char(string.byte(e, f++)[0])
)[0] as number;
u = string.find(
this._keyStr,
string.char(string.byte(e, f++)[0])
)[0] as number;
a = string.find(
this._keyStr,
string.char(string.byte(e, f++)[0])
)[0] as number;
n = (s << 2) | (o >> 4);
r = ((o & 15) << 4) | (u >> 2);
i = ((u & 3) << 6) | a;
t = t + string.char(n);
if (u !== 64) {
t = t + string.char(r);
}
if (a !== 64) {
t = t + string.char(i);
}
}
t = Base64._utf8_decode(t);
return t;
},
_utf8_encode: function (e: string) {
e = string.gsub(e, "\r\n", "\n")[0];
let t = "";
for (let n = 0; n < e.size(); n++) {
let r = string.byte(e, n)[0];
if (r < 128) {
t += string.char(r);
} else if (r > 127 && r < 2048) {
t += string.char((r >> 6) | 192);
t += string.char((r & 63) | 128);
} else {
t += string.char((r >> 12) | 224);
t += string.char(((r >> 6) & 63) | 128);
t += string.char((r & 63) | 128);
}
}
return t;
},
_utf8_decode: function (e: string) {
let t = "";
let n = 0;
let r = 0;
let c1 = 0;
let c2 = 0;
let c3 = 0;
while (n < e.size()) {
r = string.byte(e, n)[0];
if (r < 128) {
t += string.char(r);
n++;
} else if (r > 191 && r < 224) {
c2 = string.byte(e, n + 1)[0];
t += string.char(((r & 31) << 6) | (c2 & 63));
n += 2;
} else {
c2 = string.byte(e, n + 1)[0];
c3 = string.byte(e, n + 2)[0];
t += string.char(((r & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63));
n += 3;
}
}
return t;
},
};
function clamp(z: number[]) { function clamp(z: number[]) {
z[31] = (z[31] & 127) | 64; z[31] = (z[31] & 127) | 64;
z[0] &= 248; z[0] &= 248;
} }
export function generatePublicKey(privateKey: number[]): number[] { export function generatePublicKey(privateKey: number[]): number[] {
let r: number, let r: number;
z = new Array<number>(32, 0); const z = new Array<number>(32, 0),
let a = gf([1]), a = gf([1]),
b = gf([9]), b = gf([9]),
c = gf(), c = gf(),
d = gf([1]), d = gf([1]),
e = gf(), e = gf(),
f = gf(), f = gf(),
_121665 = gf([0xdb41, 1]), _121665 = gf([0xdb41, 1]),
_9 = gf([9]); _9 = gf([9]);
for (let i = 0; i < 32; ++i) { for (let i = 0; i < 32; ++i) {
z[i] = privateKey[i]; z[i] = privateKey[i];
} }
clamp(z); clamp(z);
for (let i = 254; i >= 0; --i) { for (let i = 254; i >= 0; --i) {
r = (z[i >>> 3] >>> (i & 7)) & 1; r = (z[i >>> 3] >>> (i & 7)) & 1;
cswap(a, b, r); cswap(a, b, r);
cswap(c, d, r); cswap(c, d, r);
add(e, a, c); add(e, a, c);
subtract(a, a, c); subtract(a, a, c);
add(c, b, d); add(c, b, d);
subtract(b, b, d); subtract(b, b, d);
multmod(d, e, e); multmod(d, e, e);
multmod(f, a, a); multmod(f, a, a);
multmod(a, c, a); multmod(a, c, a);
multmod(c, b, e); multmod(c, b, e);
add(e, a, c); add(e, a, c);
subtract(a, a, c); subtract(a, a, c);
multmod(b, a, a); multmod(b, a, a);
subtract(c, d, f); subtract(c, d, f);
multmod(a, c, _121665); multmod(a, c, _121665);
add(a, a, d); add(a, a, d);
multmod(c, c, a); multmod(c, c, a);
multmod(a, d, f); multmod(a, d, f);
multmod(d, b, _9); multmod(d, b, _9);
multmod(b, e, e); multmod(b, e, e);
cswap(a, b, r); cswap(a, b, r);
cswap(c, d, r); cswap(c, d, r);
} }
invert(c, c); invert(c, c);
multmod(a, a, c); multmod(a, a, c);
pack(z, a); pack(z, a);
return z; return z;
} }
function generatePresharedKey(): number[] { function generatePresharedKey(): number[] {
let privateKey = new Array(32, 0).map(() => { const privateKey = new Array(32, 0).map(() => {
return math.floor(math.random() * 256); return math.floor(math.random() * 256);
}); });
return privateKey; return privateKey;
} }
export function generatePrivateKey(): number[] { export function generatePrivateKey(): number[] {
const privateKey = generatePresharedKey(); const privateKey = generatePresharedKey();
clamp(privateKey); clamp(privateKey);
return privateKey; return privateKey;
} }