UNPKG

oicq

Version:
104 lines (103 loc) 3.25 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.decrypt = exports.encrypt = void 0; const BUF7 = Buffer.alloc(7); const deltas = [ 0x9e3779b9, 0x3c6ef372, 0xdaa66d2b, 0x78dde6e4, 0x1715609d, 0xb54cda56, 0x5384540f, 0xf1bbcdc8, 0x8ff34781, 0x2e2ac13a, 0xcc623af3, 0x6a99b4ac, 0x08d12e65, 0xa708a81e, 0x454021d7, 0xe3779b90, ]; function _toUInt32(num) { return num >>> 0; } function _encrypt(x, y, k0, k1, k2, k3) { for (let i = 0; i < 16; ++i) { let aa = (_toUInt32((y << 4 >>> 0) + k0) ^ _toUInt32(y + deltas[i])) >>> 0 ^ _toUInt32(~~(y / 32) + k1); aa >>>= 0; x = _toUInt32(x + aa); let bb = (_toUInt32((x << 4 >>> 0) + k2) ^ _toUInt32(x + deltas[i])) >>> 0 ^ _toUInt32(~~(x / 32) + k3); bb >>>= 0; y = _toUInt32(y + bb); } return [x, y]; } function encrypt(data, key) { let n = 6 - data.length >>> 0; n = n % 8 + 2; const v = Buffer.concat([ Buffer.from([(n - 2) | 0xF8]), Buffer.allocUnsafe(n), data, BUF7, ]); const k0 = key.readUInt32BE(0); const k1 = key.readUInt32BE(4); const k2 = key.readUInt32BE(8); const k3 = key.readUInt32BE(12); let r1 = 0, r2 = 0, t1 = 0, t2 = 0; for (let i = 0; i < v.length; i += 8) { const a1 = v.readUInt32BE(i); const a2 = v.readUInt32BE(i + 4); const b1 = a1 ^ r1; const b2 = a2 ^ r2; const [x, y] = _encrypt(b1 >>> 0, b2 >>> 0, k0, k1, k2, k3); r1 = x ^ t1; r2 = y ^ t2; t1 = b1; t2 = b2; v.writeInt32BE(r1, i); v.writeInt32BE(r2, i + 4); } return v; } exports.encrypt = encrypt; function _decrypt(x, y, k0, k1, k2, k3) { for (let i = 15; i >= 0; --i) { let aa = (_toUInt32((x << 4 >>> 0) + k2) ^ _toUInt32(x + deltas[i])) >>> 0 ^ _toUInt32(~~(x / 32) + k3); y = y - aa >>> 0; let bb = (_toUInt32((y << 4 >>> 0) + k0) ^ _toUInt32(y + deltas[i])) >>> 0 ^ _toUInt32(~~(y / 32) + k1); x = x - bb >>> 0; } return [x, y]; } function decrypt(encrypted, key) { if (encrypted.length % 8) throw ERROR_ENCRYPTED_LENGTH; const k0 = key.readUInt32BE(0); const k1 = key.readUInt32BE(4); const k2 = key.readUInt32BE(8); const k3 = key.readUInt32BE(12); let r1 = 0, r2 = 0, t1 = 0, t2 = 0, x = 0, y = 0; for (let i = 0; i < encrypted.length; i += 8) { const a1 = encrypted.readUInt32BE(i); const a2 = encrypted.readUInt32BE(i + 4); const b1 = a1 ^ x; const b2 = a2 ^ y; [x, y] = _decrypt(b1 >>> 0, b2 >>> 0, k0, k1, k2, k3); r1 = x ^ t1; r2 = y ^ t2; t1 = a1; t2 = a2; encrypted.writeInt32BE(r1, i); encrypted.writeInt32BE(r2, i + 4); } if (Buffer.compare(encrypted.slice(encrypted.length - 7), BUF7) !== 0) throw ERROR_ENCRYPTED_ILLEGAL; return encrypted.slice((encrypted[0] & 0x07) + 3, encrypted.length - 7); } exports.decrypt = decrypt; const ERROR_ENCRYPTED_LENGTH = new Error("length of encrypted data must be a multiple of 8"); const ERROR_ENCRYPTED_ILLEGAL = new Error("encrypted data is illegal");