UNPKG

@tgsnake/core

Version:

Pure Telegram MTProto library for nodejs

93 lines (92 loc) 2.94 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.xor = xor; exports.computePasswordHash = computePasswordHash; exports.computePasswordCheck = computePasswordCheck; const index_js_1 = require("../raw/index.js"); const platform_node_js_1 = require("../platform.node.js"); const helpers_js_1 = require("../helpers.js"); function sha256(data) { return platform_node_js_1.crypto.createHash('sha256').update(data).digest(); } function xor(a, b) { const length = Math.min(platform_node_js_1.Buffer.byteLength(a), platform_node_js_1.Buffer.byteLength(b)); for (let i = 0; i < length; i++) { a[i] = a[i] ^ b[i]; } return a; } function computePasswordHash(algo, password) { const hash1 = sha256(platform_node_js_1.Buffer.concat([ algo.salt1, platform_node_js_1.Buffer.from(password, 'utf8'), algo.salt1, ])); const hash2 = sha256(platform_node_js_1.Buffer.concat([ algo.salt2, hash1, algo.salt2, ])); const hash3 = platform_node_js_1.crypto.pbkdf2Sync(hash2, algo.salt1, 100000, 64, 'sha512'); return sha256(platform_node_js_1.Buffer.concat([ algo.salt2, hash3, algo.salt2, ])); } function computePasswordCheck(r, password) { const algo = r.currentAlgo; const pBytes = algo.p; const p = btoi(pBytes); const g = algo.g; const gBytes = itob(BigInt(g)); const BBytes = r.srpB; const B = btoi(BBytes); const srpId = r.srpId; const xBytes = computePasswordHash(algo, password); const x = btoi(xBytes); const gX = (0, helpers_js_1.bigIntPow)(BigInt(g), x, p); const kBytes = sha256(platform_node_js_1.Buffer.concat([pBytes, gBytes])); const k = btoi(kBytes); const kGX = (0, helpers_js_1.bigIntMod)(k * gX, p); let aBytes; let a; let A; let ABytes; let u; while (true) { aBytes = platform_node_js_1.crypto.randomBytes(256); a = btoi(aBytes); A = (0, helpers_js_1.bigIntPow)(BigInt(g), a, p); ABytes = itob(A); u = btoi(sha256(platform_node_js_1.Buffer.concat([ABytes, BBytes]))); if (u > BigInt(0)) break; } const gB = (0, helpers_js_1.bigIntMod)(B - kGX, p); const uX = u * x; const aUX = a + uX; const S = (0, helpers_js_1.bigIntPow)(gB, aUX, p); const SBytes = itob(S); const KBytes = sha256(SBytes); const M1Bytes = sha256(platform_node_js_1.Buffer.concat([ xor(sha256(pBytes), sha256(gBytes)), sha256(algo.salt1), sha256(algo.salt2), ABytes, BBytes, KBytes, ])); return new index_js_1.Raw.InputCheckPasswordSRP({ srpId: srpId, a: ABytes, m1: M1Bytes, }); } function btoi(b) { return (0, helpers_js_1.bufferToBigint)(b, false); } function itob(i) { return (0, helpers_js_1.bigintToBuffer)(i, 256, false); }