class RC4 { constructor(key) { this.key = Buffer.isBuffer(key) ? key : Buffer.from(key, "utf8") this.s = new Array(256) this.init() } init() { for (let i = 0; i < 256; i++) { this.s[i] = i } let j = 0 for (let i = 0; i < 256; i++) { j = (j + this.s[i] + this.key[i % this.key.length]) % 256 this.swap(i, j) } } swap(i, j) { const temp = this.s[i] this.s[i] = this.s[j] this.s[j] = temp } encrypt(data) { const input = Buffer.isBuffer(data) ? data : Buffer.from(data, "utf8") const output = Buffer.alloc(input.length) let i = 0, j = 0 for (let k = 0; k < input.length; k++) { i = (i + 1) % 256 j = (j + this.s[i]) % 256 this.swap(i, j) const keystream = this.s[(this.s[i] + this.s[j]) % 256] output[k] = input[k] ^ keystream } return output } decrypt(data) { return this.encrypt(data) } } class Crypto { constructor(config) { this.config = config this.rc4 = new RC4(config.rc4Key) this.nonce = Buffer.from(config.nonce, "utf8") } encrypt(data) { if (!this.config.enabled) return data const buffer = Buffer.isBuffer(data) ? data : Buffer.from(data) return this.rc4.encrypt(buffer) } decrypt(data) { if (!this.config.enabled) return data const buffer = Buffer.isBuffer(data) ? data : Buffer.from(data) return this.rc4.decrypt(buffer) } generateNonce() { const timestamp = Date.now() const high = Math.floor(timestamp / 0x100000000) >>> 0 const low = (timestamp >>> 0) const random = Math.floor(Math.random() * 0xffffffff) >>> 0 const nonceBuffer = Buffer.alloc(16) nonceBuffer.writeUInt32BE(high, 0) nonceBuffer.writeUInt32BE(low, 4) nonceBuffer.writeUInt32BE(random, 8) nonceBuffer.writeUInt32BE((random ^ low) >>> 0, 12) return nonceBuffer } hash(data) { const crypto = require("crypto") return crypto.createHash("sha256").update(data).digest() } xorWithNonce(data) { const buffer = Buffer.isBuffer(data) ? data : Buffer.from(data) const result = Buffer.alloc(buffer.length) for (let i = 0; i < buffer.length; i++) { result[i] = buffer[i] ^ this.nonce[i % this.nonce.length] } return result } } module.exports = { RC4, Crypto }