@mtcute/core 0.1.0 → 0.1.1
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/cjs/base-client.js +4 -1
- package/cjs/base-client.js.map +1 -1
- package/cjs/network/auth-key.d.ts +3 -3
- package/cjs/network/auth-key.js +12 -12
- package/cjs/network/auth-key.js.map +1 -1
- package/cjs/network/authorization.js +62 -57
- package/cjs/network/authorization.js.map +1 -1
- package/cjs/network/mtproto-session.d.ts +2 -2
- package/cjs/network/mtproto-session.js +2 -2
- package/cjs/network/mtproto-session.js.map +1 -1
- package/cjs/network/multi-session-connection.d.ts +1 -1
- package/cjs/network/multi-session-connection.js +2 -2
- package/cjs/network/multi-session-connection.js.map +1 -1
- package/cjs/network/network-manager.d.ts +1 -0
- package/cjs/network/network-manager.js +21 -27
- package/cjs/network/network-manager.js.map +1 -1
- package/cjs/network/session-connection.d.ts +2 -1
- package/cjs/network/session-connection.js +48 -35
- package/cjs/network/session-connection.js.map +1 -1
- package/cjs/network/transports/intermediate.d.ts +3 -0
- package/cjs/network/transports/intermediate.js +5 -3
- package/cjs/network/transports/intermediate.js.map +1 -1
- package/cjs/network/transports/obfuscated.js +14 -18
- package/cjs/network/transports/obfuscated.js.map +1 -1
- package/cjs/storage/abstract.d.ts +23 -2
- package/cjs/storage/abstract.js.map +1 -1
- package/cjs/storage/json.js +8 -9
- package/cjs/storage/json.js.map +1 -1
- package/cjs/storage/localstorage.js +5 -2
- package/cjs/storage/localstorage.js.map +1 -1
- package/cjs/storage/memory.d.ts +7 -8
- package/cjs/storage/memory.js +7 -7
- package/cjs/storage/memory.js.map +1 -1
- package/cjs/utils/bigint-utils.d.ts +18 -11
- package/cjs/utils/bigint-utils.js +148 -47
- package/cjs/utils/bigint-utils.js.map +1 -1
- package/cjs/utils/buffer-utils.d.ts +7 -1
- package/cjs/utils/buffer-utils.js +16 -3
- package/cjs/utils/buffer-utils.js.map +1 -1
- package/cjs/utils/crypto/abstract.d.ts +16 -9
- package/cjs/utils/crypto/abstract.js +6 -9
- package/cjs/utils/crypto/abstract.js.map +1 -1
- package/cjs/utils/crypto/factorization.d.ts +2 -1
- package/cjs/utils/crypto/factorization.js +28 -36
- package/cjs/utils/crypto/factorization.js.map +1 -1
- package/cjs/utils/crypto/index.d.ts +4 -0
- package/cjs/utils/crypto/index.js +4 -0
- package/cjs/utils/crypto/index.js.map +1 -1
- package/cjs/utils/crypto/keys.d.ts +2 -2
- package/cjs/utils/crypto/keys.js +4 -4
- package/cjs/utils/crypto/keys.js.map +1 -1
- package/cjs/utils/crypto/miller-rabin.d.ts +2 -2
- package/cjs/utils/crypto/miller-rabin.js +20 -22
- package/cjs/utils/crypto/miller-rabin.js.map +1 -1
- package/cjs/utils/crypto/mtproto.d.ts +3 -3
- package/cjs/utils/crypto/mtproto.js +12 -12
- package/cjs/utils/crypto/mtproto.js.map +1 -1
- package/cjs/utils/crypto/node.d.ts +21 -0
- package/cjs/utils/crypto/node.js +74 -0
- package/cjs/utils/crypto/node.js.map +1 -0
- package/cjs/utils/crypto/password.js +22 -33
- package/cjs/utils/crypto/password.js.map +1 -1
- package/cjs/utils/crypto/wasm.d.ts +22 -0
- package/cjs/utils/crypto/wasm.js +41 -0
- package/cjs/utils/crypto/wasm.js.map +1 -0
- package/cjs/utils/crypto/web.d.ts +11 -0
- package/cjs/utils/crypto/web.js +40 -0
- package/cjs/utils/crypto/web.js.map +1 -0
- package/cjs/utils/deque.d.ts +1 -1
- package/cjs/utils/deque.js +9 -3
- package/cjs/utils/deque.js.map +1 -1
- package/cjs/utils/function-utils.d.ts +4 -1
- package/cjs/utils/function-utils.js +8 -1
- package/cjs/utils/function-utils.js.map +1 -1
- package/cjs/utils/index.d.ts +0 -1
- package/cjs/utils/index.js +0 -1
- package/cjs/utils/index.js.map +1 -1
- package/cjs/utils/logger.d.ts +0 -1
- package/cjs/utils/logger.js +3 -4
- package/cjs/utils/logger.js.map +1 -1
- package/cjs/utils/lru-map.d.ts +1 -0
- package/cjs/utils/lru-map.js +6 -0
- package/cjs/utils/lru-map.js.map +1 -1
- package/cjs/utils/peer-utils.js +5 -1
- package/cjs/utils/peer-utils.js.map +1 -1
- package/cjs/utils/platform/crypto.js +2 -2
- package/cjs/utils/platform/crypto.js.map +1 -1
- package/cjs/utils/platform/crypto.web.js +2 -2
- package/cjs/utils/platform/crypto.web.js.map +1 -1
- package/cjs/utils/string-session.js +4 -2
- package/cjs/utils/string-session.js.map +1 -1
- package/esm/base-client.js +4 -1
- package/esm/base-client.js.map +1 -1
- package/esm/network/auth-key.d.ts +3 -3
- package/esm/network/auth-key.js +13 -13
- package/esm/network/auth-key.js.map +1 -1
- package/esm/network/authorization.js +64 -59
- package/esm/network/authorization.js.map +1 -1
- package/esm/network/mtproto-session.d.ts +2 -2
- package/esm/network/mtproto-session.js +2 -2
- package/esm/network/mtproto-session.js.map +1 -1
- package/esm/network/multi-session-connection.d.ts +1 -1
- package/esm/network/multi-session-connection.js +2 -2
- package/esm/network/multi-session-connection.js.map +1 -1
- package/esm/network/network-manager.d.ts +1 -0
- package/esm/network/network-manager.js +21 -27
- package/esm/network/network-manager.js.map +1 -1
- package/esm/network/session-connection.d.ts +2 -1
- package/esm/network/session-connection.js +50 -37
- package/esm/network/session-connection.js.map +1 -1
- package/esm/network/transports/intermediate.d.ts +3 -0
- package/esm/network/transports/intermediate.js +6 -4
- package/esm/network/transports/intermediate.js.map +1 -1
- package/esm/network/transports/obfuscated.js +15 -19
- package/esm/network/transports/obfuscated.js.map +1 -1
- package/esm/storage/abstract.d.ts +23 -2
- package/esm/storage/abstract.js.map +1 -1
- package/esm/storage/json.js +8 -9
- package/esm/storage/json.js.map +1 -1
- package/esm/storage/localstorage.js +5 -2
- package/esm/storage/localstorage.js.map +1 -1
- package/esm/storage/memory.d.ts +7 -8
- package/esm/storage/memory.js +7 -7
- package/esm/storage/memory.js.map +1 -1
- package/esm/utils/bigint-utils.d.ts +18 -11
- package/esm/utils/bigint-utils.js +142 -44
- package/esm/utils/bigint-utils.js.map +1 -1
- package/esm/utils/buffer-utils.d.ts +7 -1
- package/esm/utils/buffer-utils.js +14 -1
- package/esm/utils/buffer-utils.js.map +1 -1
- package/esm/utils/crypto/abstract.d.ts +16 -9
- package/esm/utils/crypto/abstract.js +6 -9
- package/esm/utils/crypto/abstract.js.map +1 -1
- package/esm/utils/crypto/factorization.d.ts +2 -1
- package/esm/utils/crypto/factorization.js +29 -34
- package/esm/utils/crypto/factorization.js.map +1 -1
- package/esm/utils/crypto/index.d.ts +4 -0
- package/esm/utils/crypto/index.js +4 -0
- package/esm/utils/crypto/index.js.map +1 -1
- package/esm/utils/crypto/keys.d.ts +2 -2
- package/esm/utils/crypto/keys.js +4 -4
- package/esm/utils/crypto/keys.js.map +1 -1
- package/esm/utils/crypto/miller-rabin.d.ts +2 -2
- package/esm/utils/crypto/miller-rabin.js +21 -20
- package/esm/utils/crypto/miller-rabin.js.map +1 -1
- package/esm/utils/crypto/mtproto.d.ts +3 -3
- package/esm/utils/crypto/mtproto.js +12 -12
- package/esm/utils/crypto/mtproto.js.map +1 -1
- package/esm/utils/crypto/node.d.ts +21 -0
- package/esm/utils/crypto/node.js +69 -0
- package/esm/utils/crypto/node.js.map +1 -0
- package/esm/utils/crypto/password.js +24 -32
- package/esm/utils/crypto/password.js.map +1 -1
- package/esm/utils/crypto/wasm.d.ts +22 -0
- package/esm/utils/crypto/wasm.js +37 -0
- package/esm/utils/crypto/wasm.js.map +1 -0
- package/esm/utils/crypto/web.d.ts +11 -0
- package/esm/utils/crypto/web.js +36 -0
- package/esm/utils/crypto/web.js.map +1 -0
- package/esm/utils/deque.d.ts +1 -1
- package/esm/utils/deque.js +9 -3
- package/esm/utils/deque.js.map +1 -1
- package/esm/utils/function-utils.d.ts +4 -1
- package/esm/utils/function-utils.js +8 -1
- package/esm/utils/function-utils.js.map +1 -1
- package/esm/utils/index.d.ts +0 -1
- package/esm/utils/index.js +0 -1
- package/esm/utils/index.js.map +1 -1
- package/esm/utils/logger.d.ts +0 -1
- package/esm/utils/logger.js +3 -4
- package/esm/utils/logger.js.map +1 -1
- package/esm/utils/lru-map.d.ts +1 -0
- package/esm/utils/lru-map.js +6 -0
- package/esm/utils/lru-map.js.map +1 -1
- package/esm/utils/peer-utils.js +5 -1
- package/esm/utils/peer-utils.js.map +1 -1
- package/esm/utils/platform/crypto.js +1 -1
- package/esm/utils/platform/crypto.js.map +1 -1
- package/esm/utils/platform/crypto.web.js +2 -2
- package/esm/utils/platform/crypto.web.js.map +1 -1
- package/esm/utils/string-session.js +4 -2
- package/esm/utils/string-session.js.map +1 -1
- package/package.json +4 -5
- package/cjs/utils/crypto/common.d.ts +0 -12
- package/cjs/utils/crypto/common.js +0 -54
- package/cjs/utils/crypto/common.js.map +0 -1
- package/cjs/utils/crypto/node-crypto.d.ts +0 -10
- package/cjs/utils/crypto/node-crypto.js +0 -46
- package/cjs/utils/crypto/node-crypto.js.map +0 -1
- package/cjs/utils/crypto/subtle.d.ts +0 -12
- package/cjs/utils/crypto/subtle.js +0 -86
- package/cjs/utils/crypto/subtle.js.map +0 -1
- package/cjs/utils/flood-control.d.ts +0 -14
- package/cjs/utils/flood-control.js +0 -65
- package/cjs/utils/flood-control.js.map +0 -1
- package/cjs/utils/platform/random.d.ts +0 -1
- package/cjs/utils/platform/random.js +0 -7
- package/cjs/utils/platform/random.js.map +0 -1
- package/cjs/utils/platform/random.web.d.ts +0 -1
- package/cjs/utils/platform/random.web.js +0 -10
- package/cjs/utils/platform/random.web.js.map +0 -1
- package/esm/utils/crypto/common.d.ts +0 -12
- package/esm/utils/crypto/common.js +0 -50
- package/esm/utils/crypto/common.js.map +0 -1
- package/esm/utils/crypto/node-crypto.d.ts +0 -10
- package/esm/utils/crypto/node-crypto.js +0 -42
- package/esm/utils/crypto/node-crypto.js.map +0 -1
- package/esm/utils/crypto/subtle.d.ts +0 -12
- package/esm/utils/crypto/subtle.js +0 -59
- package/esm/utils/crypto/subtle.js.map +0 -1
- package/esm/utils/flood-control.d.ts +0 -14
- package/esm/utils/flood-control.js +0 -61
- package/esm/utils/flood-control.js.map +0 -1
- package/esm/utils/platform/random.d.ts +0 -1
- package/esm/utils/platform/random.js +0 -4
- package/esm/utils/platform/random.js.map +0 -1
- package/esm/utils/platform/random.web.d.ts +0 -1
- package/esm/utils/platform/random.web.js +0 -6
- package/esm/utils/platform/random.web.js.map +0 -1
package/cjs/utils/crypto/keys.js
CHANGED
|
@@ -12,7 +12,7 @@ const asn1_parser_js_1 = require("../binary/asn1-parser.js");
|
|
|
12
12
|
* @param key PEM-encoded RSA public key
|
|
13
13
|
* @param old Whether this is an "old" key
|
|
14
14
|
*/
|
|
15
|
-
|
|
15
|
+
function parsePublicKey(crypto, key, old = false) {
|
|
16
16
|
const asn1 = (0, asn1_parser_js_1.parseAsn1)((0, asn1_parser_js_1.parsePemContents)(key));
|
|
17
17
|
const modulus = asn1.children?.[0].value;
|
|
18
18
|
const exponent = asn1.children?.[1].value;
|
|
@@ -23,7 +23,7 @@ async function parsePublicKey(crypto, key, old = false) {
|
|
|
23
23
|
writer.bytes(modulus);
|
|
24
24
|
writer.bytes(exponent);
|
|
25
25
|
const data = writer.result();
|
|
26
|
-
const sha =
|
|
26
|
+
const sha = crypto.sha1(data);
|
|
27
27
|
const fp = (0, tl_runtime_1.hexEncode)(sha.slice(-8).reverse());
|
|
28
28
|
return {
|
|
29
29
|
modulus: (0, tl_runtime_1.hexEncode)(modulus),
|
|
@@ -40,8 +40,8 @@ exports.parsePublicKey = parsePublicKey;
|
|
|
40
40
|
* @param key PEM-encoded RSA public key
|
|
41
41
|
* @param old Whether this is an "old" key
|
|
42
42
|
*/
|
|
43
|
-
|
|
44
|
-
const parsed =
|
|
43
|
+
function addPublicKey(crypto, key, old = false) {
|
|
44
|
+
const parsed = parsePublicKey(crypto, key, old);
|
|
45
45
|
rsa_keys_js_1.__publicKeyIndex[parsed.fingerprint] = parsed;
|
|
46
46
|
}
|
|
47
47
|
exports.addPublicKey = addPublicKey;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"keys.js","sourceRoot":"","sources":["../../../../src/utils/crypto/keys.ts"],"names":[],"mappings":";;;AAEA,+DAA0F;AAC1F,mDAA8D;AAE9D,6DAAsE;AAGtE;;;;;;;GAOG;
|
|
1
|
+
{"version":3,"file":"keys.js","sourceRoot":"","sources":["../../../../src/utils/crypto/keys.ts"],"names":[],"mappings":";;;AAEA,+DAA0F;AAC1F,mDAA8D;AAE9D,6DAAsE;AAGtE;;;;;;;GAOG;AACH,SAAgB,cAAc,CAAC,MAAuB,EAAE,GAAW,EAAE,GAAG,GAAG,KAAK;IAC5E,MAAM,IAAI,GAAG,IAAA,0BAAS,EAAC,IAAA,iCAAgB,EAAC,GAAG,CAAC,CAAC,CAAA;IAC7C,MAAM,OAAO,GAAG,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,CAAC,KAAK,CAAA;IACxC,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,CAAC,KAAK,CAAA;IACzC,IAAI,CAAC,OAAO,IAAI,CAAC,QAAQ;QAAE,MAAM,IAAI,KAAK,CAAC,oBAAoB,CAAC,CAAA;IAEhE,MAAM,MAAM,GAAG,2BAAc,CAAC,MAAM,CAAC,GAAG,CAAC,CAAA;IACzC,yDAAyD;IACzD,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,CAAA;IACrB,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAA;IAEtB,MAAM,IAAI,GAAG,MAAM,CAAC,MAAM,EAAE,CAAA;IAC5B,MAAM,GAAG,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;IAC7B,MAAM,EAAE,GAAG,IAAA,sBAAS,EAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAA;IAE7C,OAAO;QACH,OAAO,EAAE,IAAA,sBAAS,EAAC,OAAO,CAAC;QAC3B,QAAQ,EAAE,IAAA,sBAAS,EAAC,QAAQ,CAAC;QAC7B,WAAW,EAAE,EAAE;QACf,GAAG;KACN,CAAA;AACL,CAAC;AArBD,wCAqBC;AAED;;;;;;GAMG;AACH,SAAgB,YAAY,CAAC,MAAuB,EAAE,GAAW,EAAE,GAAG,GAAG,KAAK;IAC1E,MAAM,MAAM,GAAG,cAAc,CAAC,MAAM,EAAE,GAAG,EAAE,GAAG,CAAC,CAAA;IAC/C,8BAAS,CAAC,MAAM,CAAC,WAAW,CAAC,GAAG,MAAM,CAAA;AAC1C,CAAC;AAHD,oCAGC;AAED;;;;;GAKG;AACH,SAAgB,qBAAqB,CAAC,YAA+B,EAAE,QAAQ,GAAG,KAAK;IACnF,KAAK,IAAI,EAAE,IAAI,YAAY,EAAE;QACzB,IAAI,OAAO,EAAE,KAAK,QAAQ,EAAE;YACxB,EAAE,GAAG,EAAE,CAAC,UAAU,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAA;SACpC;QACD,IAAI,EAAE,IAAI,8BAAS,EAAE;YACjB,IAAI,8BAAS,CAAC,EAAE,CAAC,CAAC,GAAG,IAAI,CAAC,QAAQ;gBAAE,SAAQ;YAE5C,OAAO,8BAAS,CAAC,EAAE,CAAC,CAAA;SACvB;KACJ;IACD,IAAI,CAAC,QAAQ;QAAE,OAAO,qBAAqB,CAAC,YAAY,EAAE,IAAI,CAAC,CAAA;IAE/D,OAAO,IAAI,CAAA;AACf,CAAC;AAdD,sDAcC","sourcesContent":["import Long from 'long'\n\nimport { __publicKeyIndex as keysIndex, TlPublicKey } from '@mtcute/tl/binary/rsa-keys.js'\nimport { hexEncode, TlBinaryWriter } from '@mtcute/tl-runtime'\n\nimport { parseAsn1, parsePemContents } from '../binary/asn1-parser.js'\nimport { ICryptoProvider } from './abstract.js'\n\n/**\n * Parse PEM-encoded RSA public key information into modulus and exponent\n * and compute its fingerprint as defined by MTProto.\n *\n * @param crypto Crypto provider\n * @param key PEM-encoded RSA public key\n * @param old Whether this is an \"old\" key\n */\nexport function parsePublicKey(crypto: ICryptoProvider, key: string, old = false): TlPublicKey {\n const asn1 = parseAsn1(parsePemContents(key))\n const modulus = asn1.children?.[0].value\n const exponent = asn1.children?.[1].value\n if (!modulus || !exponent) throw new Error('Invalid public key')\n\n const writer = TlBinaryWriter.manual(512)\n // they are actually smaller, about 270 bytes, but idc :D\n writer.bytes(modulus)\n writer.bytes(exponent)\n\n const data = writer.result()\n const sha = crypto.sha1(data)\n const fp = hexEncode(sha.slice(-8).reverse())\n\n return {\n modulus: hexEncode(modulus),\n exponent: hexEncode(exponent),\n fingerprint: fp,\n old,\n }\n}\n\n/**\n * Add public key to the global index.\n *\n * @param crypto Crypto provider\n * @param key PEM-encoded RSA public key\n * @param old Whether this is an \"old\" key\n */\nexport function addPublicKey(crypto: ICryptoProvider, key: string, old = false): void {\n const parsed = parsePublicKey(crypto, key, old)\n keysIndex[parsed.fingerprint] = parsed\n}\n\n/**\n * Get public key by its fingerprint.\n *\n * @param fingerprints Fingerprints to match. The first one to match is returned.\n * @param allowOld Whether to allow \"old\" keys\n */\nexport function findKeyByFingerprints(fingerprints: (string | Long)[], allowOld = false): TlPublicKey | null {\n for (let fp of fingerprints) {\n if (typeof fp !== 'string') {\n fp = fp.toUnsigned().toString(16)\n }\n if (fp in keysIndex) {\n if (keysIndex[fp].old && !allowOld) continue\n\n return keysIndex[fp]\n }\n }\n if (!allowOld) return findKeyByFingerprints(fingerprints, true)\n\n return null\n}\n"]}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import {
|
|
2
|
-
export declare function millerRabin(n:
|
|
1
|
+
import { ICryptoProvider } from './abstract.js';
|
|
2
|
+
export declare function millerRabin(crypto: ICryptoProvider, n: bigint, rounds?: number): boolean;
|
|
@@ -1,41 +1,39 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
-
};
|
|
5
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
3
|
exports.millerRabin = void 0;
|
|
7
|
-
const big_integer_1 = __importDefault(require("big-integer"));
|
|
8
4
|
const bigint_utils_js_1 = require("../bigint-utils.js");
|
|
9
|
-
function millerRabin(n, rounds = 20) {
|
|
5
|
+
function millerRabin(crypto, n, rounds = 20) {
|
|
10
6
|
// small numbers: 0, 1 are not prime, 2, 3 are prime
|
|
11
|
-
if (n
|
|
12
|
-
return n
|
|
13
|
-
if (n
|
|
7
|
+
if (n < 4n)
|
|
8
|
+
return n > 1n;
|
|
9
|
+
if (n % 2n === 0n || n < 0n)
|
|
14
10
|
return false;
|
|
15
|
-
const nBits =
|
|
16
|
-
const nSub = n
|
|
11
|
+
const nBits = (0, bigint_utils_js_1.bigIntBitLength)(n);
|
|
12
|
+
const nSub = n - 1n;
|
|
17
13
|
const r = (0, bigint_utils_js_1.twoMultiplicity)(nSub);
|
|
18
|
-
const d = nSub
|
|
14
|
+
const d = nSub >> r;
|
|
19
15
|
for (let i = 0; i < rounds; i++) {
|
|
20
16
|
let base;
|
|
21
17
|
do {
|
|
22
|
-
base = (0, bigint_utils_js_1.randomBigIntBits)(nBits);
|
|
23
|
-
} while (base
|
|
24
|
-
let x =
|
|
25
|
-
if (x.eq(
|
|
18
|
+
base = (0, bigint_utils_js_1.randomBigIntBits)(crypto, nBits);
|
|
19
|
+
} while (base <= 1n || base >= nSub);
|
|
20
|
+
let x = (0, bigint_utils_js_1.bigIntModPow)(base, d, n);
|
|
21
|
+
// if (x.eq(bigInt.one) || x.eq(nSub)) continue
|
|
22
|
+
if (x === 1n || x === nSub)
|
|
26
23
|
continue;
|
|
27
|
-
let i =
|
|
24
|
+
let i = 0n;
|
|
28
25
|
let y;
|
|
29
|
-
while (i
|
|
30
|
-
y = x.modPow(
|
|
31
|
-
|
|
26
|
+
while (i < r) {
|
|
27
|
+
// y = x.modPow(bigInt[2], n)
|
|
28
|
+
y = (0, bigint_utils_js_1.bigIntModPow)(x, 2n, n);
|
|
29
|
+
if (x === 1n)
|
|
32
30
|
return false;
|
|
33
|
-
if (x
|
|
31
|
+
if (x === nSub)
|
|
34
32
|
break;
|
|
35
|
-
i
|
|
33
|
+
i += 1n;
|
|
36
34
|
x = y;
|
|
37
35
|
}
|
|
38
|
-
if (i
|
|
36
|
+
if (i === r)
|
|
39
37
|
return false;
|
|
40
38
|
}
|
|
41
39
|
return true;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"miller-rabin.js","sourceRoot":"","sources":["../../../../src/utils/crypto/miller-rabin.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"miller-rabin.js","sourceRoot":"","sources":["../../../../src/utils/crypto/miller-rabin.ts"],"names":[],"mappings":";;;AAAA,wDAAqG;AAGrG,SAAgB,WAAW,CAAC,MAAuB,EAAE,CAAS,EAAE,MAAM,GAAG,EAAE;IACvE,oDAAoD;IACpD,IAAI,CAAC,GAAG,EAAE;QAAE,OAAO,CAAC,GAAG,EAAE,CAAA;IACzB,IAAI,CAAC,GAAG,EAAE,KAAK,EAAE,IAAI,CAAC,GAAG,EAAE;QAAE,OAAO,KAAK,CAAA;IAEzC,MAAM,KAAK,GAAG,IAAA,iCAAe,EAAC,CAAC,CAAC,CAAA;IAChC,MAAM,IAAI,GAAG,CAAC,GAAG,EAAE,CAAA;IAEnB,MAAM,CAAC,GAAG,IAAA,iCAAe,EAAC,IAAI,CAAC,CAAA;IAC/B,MAAM,CAAC,GAAG,IAAI,IAAI,CAAC,CAAA;IAEnB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,MAAM,EAAE,CAAC,EAAE,EAAE;QAC7B,IAAI,IAAI,CAAA;QAER,GAAG;YACC,IAAI,GAAG,IAAA,kCAAgB,EAAC,MAAM,EAAE,KAAK,CAAC,CAAA;SACzC,QAAQ,IAAI,IAAI,EAAE,IAAI,IAAI,IAAI,IAAI,EAAC;QAEpC,IAAI,CAAC,GAAG,IAAA,8BAAY,EAAC,IAAI,EAAE,CAAC,EAAE,CAAC,CAAC,CAAA;QAChC,+CAA+C;QAC/C,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,KAAK,IAAI;YAAE,SAAQ;QAEpC,IAAI,CAAC,GAAG,EAAE,CAAA;QACV,IAAI,CAAS,CAAA;QAEb,OAAO,CAAC,GAAG,CAAC,EAAE;YACV,6BAA6B;YAC7B,CAAC,GAAG,IAAA,8BAAY,EAAC,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,CAAA;YAE1B,IAAI,CAAC,KAAK,EAAE;gBAAE,OAAO,KAAK,CAAA;YAC1B,IAAI,CAAC,KAAK,IAAI;gBAAE,MAAK;YACrB,CAAC,IAAI,EAAE,CAAA;YAEP,CAAC,GAAG,CAAC,CAAA;SACR;QAED,IAAI,CAAC,KAAK,CAAC;YAAE,OAAO,KAAK,CAAA;KAC5B;IAED,OAAO,IAAI,CAAA;AACf,CAAC;AAxCD,kCAwCC","sourcesContent":["import { bigIntBitLength, bigIntModPow, randomBigIntBits, twoMultiplicity } from '../bigint-utils.js'\nimport { ICryptoProvider } from './abstract.js'\n\nexport function millerRabin(crypto: ICryptoProvider, n: bigint, rounds = 20): boolean {\n // small numbers: 0, 1 are not prime, 2, 3 are prime\n if (n < 4n) return n > 1n\n if (n % 2n === 0n || n < 0n) return false\n\n const nBits = bigIntBitLength(n)\n const nSub = n - 1n\n\n const r = twoMultiplicity(nSub)\n const d = nSub >> r\n\n for (let i = 0; i < rounds; i++) {\n let base\n\n do {\n base = randomBigIntBits(crypto, nBits)\n } while (base <= 1n || base >= nSub)\n\n let x = bigIntModPow(base, d, n)\n // if (x.eq(bigInt.one) || x.eq(nSub)) continue\n if (x === 1n || x === nSub) continue\n\n let i = 0n\n let y: bigint\n\n while (i < r) {\n // y = x.modPow(bigInt[2], n)\n y = bigIntModPow(x, 2n, n)\n\n if (x === 1n) return false\n if (x === nSub) break\n i += 1n\n\n x = y\n }\n\n if (i === r) return false\n }\n\n return true\n}\n"]}
|
|
@@ -8,7 +8,7 @@ import { ICryptoProvider, IEncryptionScheme } from './abstract.js';
|
|
|
8
8
|
* @param newNonce New nonce
|
|
9
9
|
* @returns Tuple: `[key, iv]`
|
|
10
10
|
*/
|
|
11
|
-
export declare function generateKeyAndIvFromNonce(crypto: ICryptoProvider, serverNonce: Uint8Array, newNonce: Uint8Array):
|
|
11
|
+
export declare function generateKeyAndIvFromNonce(crypto: ICryptoProvider, serverNonce: Uint8Array, newNonce: Uint8Array): [Uint8Array, Uint8Array];
|
|
12
12
|
/**
|
|
13
13
|
* Create AES IGE instance for message (given auth key and message key)
|
|
14
14
|
* as defined by MTProto v2.
|
|
@@ -18,7 +18,7 @@ export declare function generateKeyAndIvFromNonce(crypto: ICryptoProvider, serve
|
|
|
18
18
|
* @param messageKey Message key
|
|
19
19
|
* @param client Whether this is a client to server message
|
|
20
20
|
*/
|
|
21
|
-
export declare function createAesIgeForMessage(crypto: ICryptoProvider, authKey: Uint8Array, messageKey: Uint8Array, client: boolean):
|
|
21
|
+
export declare function createAesIgeForMessage(crypto: ICryptoProvider, authKey: Uint8Array, messageKey: Uint8Array, client: boolean): IEncryptionScheme;
|
|
22
22
|
/**
|
|
23
23
|
* Create AES IGE instance for file (given auth key and message key)
|
|
24
24
|
* as defined by MTProto v1.
|
|
@@ -28,4 +28,4 @@ export declare function createAesIgeForMessage(crypto: ICryptoProvider, authKey:
|
|
|
28
28
|
* @param messageKey Message key
|
|
29
29
|
* @param client Whether this is a client to server message
|
|
30
30
|
*/
|
|
31
|
-
export declare function createAesIgeForMessageOld(crypto: ICryptoProvider, authKey: Uint8Array, messageKey: Uint8Array, client: boolean):
|
|
31
|
+
export declare function createAesIgeForMessageOld(crypto: ICryptoProvider, authKey: Uint8Array, messageKey: Uint8Array, client: boolean): IEncryptionScheme;
|
|
@@ -11,10 +11,10 @@ const buffer_utils_js_1 = require("../buffer-utils.js");
|
|
|
11
11
|
* @param newNonce New nonce
|
|
12
12
|
* @returns Tuple: `[key, iv]`
|
|
13
13
|
*/
|
|
14
|
-
|
|
15
|
-
const hash1 =
|
|
16
|
-
const hash2 =
|
|
17
|
-
const hash3 =
|
|
14
|
+
function generateKeyAndIvFromNonce(crypto, serverNonce, newNonce) {
|
|
15
|
+
const hash1 = crypto.sha1((0, buffer_utils_js_1.concatBuffers)([newNonce, serverNonce]));
|
|
16
|
+
const hash2 = crypto.sha1((0, buffer_utils_js_1.concatBuffers)([serverNonce, newNonce]));
|
|
17
|
+
const hash3 = crypto.sha1((0, buffer_utils_js_1.concatBuffers)([newNonce, newNonce]));
|
|
18
18
|
const key = (0, buffer_utils_js_1.concatBuffers)([hash1, hash2.subarray(0, 12)]);
|
|
19
19
|
const iv = (0, buffer_utils_js_1.concatBuffers)([hash2.subarray(12, 20), hash3, newNonce.subarray(0, 4)]);
|
|
20
20
|
return [key, iv];
|
|
@@ -29,10 +29,10 @@ exports.generateKeyAndIvFromNonce = generateKeyAndIvFromNonce;
|
|
|
29
29
|
* @param messageKey Message key
|
|
30
30
|
* @param client Whether this is a client to server message
|
|
31
31
|
*/
|
|
32
|
-
|
|
32
|
+
function createAesIgeForMessage(crypto, authKey, messageKey, client) {
|
|
33
33
|
const x = client ? 0 : 8;
|
|
34
|
-
const sha256a =
|
|
35
|
-
const sha256b =
|
|
34
|
+
const sha256a = crypto.sha256((0, buffer_utils_js_1.concatBuffers)([messageKey, authKey.subarray(x, 36 + x)]));
|
|
35
|
+
const sha256b = crypto.sha256((0, buffer_utils_js_1.concatBuffers)([authKey.subarray(40 + x, 76 + x), messageKey]));
|
|
36
36
|
const key = (0, buffer_utils_js_1.concatBuffers)([sha256a.subarray(0, 8), sha256b.subarray(8, 24), sha256a.subarray(24, 32)]);
|
|
37
37
|
const iv = (0, buffer_utils_js_1.concatBuffers)([sha256b.subarray(0, 8), sha256a.subarray(8, 24), sha256b.subarray(24, 32)]);
|
|
38
38
|
return crypto.createAesIge(key, iv);
|
|
@@ -47,12 +47,12 @@ exports.createAesIgeForMessage = createAesIgeForMessage;
|
|
|
47
47
|
* @param messageKey Message key
|
|
48
48
|
* @param client Whether this is a client to server message
|
|
49
49
|
*/
|
|
50
|
-
|
|
50
|
+
function createAesIgeForMessageOld(crypto, authKey, messageKey, client) {
|
|
51
51
|
const x = client ? 0 : 8;
|
|
52
|
-
const sha1a =
|
|
53
|
-
const sha1b =
|
|
54
|
-
const sha1c =
|
|
55
|
-
const sha1d =
|
|
52
|
+
const sha1a = crypto.sha1((0, buffer_utils_js_1.concatBuffers)([messageKey, authKey.subarray(x, 32 + x)]));
|
|
53
|
+
const sha1b = crypto.sha1((0, buffer_utils_js_1.concatBuffers)([authKey.subarray(32 + x, 48 + x), messageKey, authKey.subarray(48 + x, 64 + x)]));
|
|
54
|
+
const sha1c = crypto.sha1((0, buffer_utils_js_1.concatBuffers)([authKey.subarray(64 + x, 96 + x), messageKey]));
|
|
55
|
+
const sha1d = crypto.sha1((0, buffer_utils_js_1.concatBuffers)([messageKey, authKey.subarray(96 + x, 128 + x)]));
|
|
56
56
|
const key = (0, buffer_utils_js_1.concatBuffers)([sha1a.subarray(0, 8), sha1b.subarray(8, 20), sha1c.subarray(4, 16)]);
|
|
57
57
|
const iv = (0, buffer_utils_js_1.concatBuffers)([
|
|
58
58
|
sha1a.subarray(8, 20),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mtproto.js","sourceRoot":"","sources":["../../../../src/utils/crypto/mtproto.ts"],"names":[],"mappings":";;;AAAA,wDAAkD;AAGlD;;;;;;;;GAQG;
|
|
1
|
+
{"version":3,"file":"mtproto.js","sourceRoot":"","sources":["../../../../src/utils/crypto/mtproto.ts"],"names":[],"mappings":"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","sourcesContent":["import { concatBuffers } from '../buffer-utils.js'\nimport { ICryptoProvider, IEncryptionScheme } from './abstract.js'\n\n/**\n * Generate AES key and IV from nonces as defined by MTProto.\n * Used in authorization flow.\n *\n * @param crypto Crypto provider\n * @param serverNonce Server nonce\n * @param newNonce New nonce\n * @returns Tuple: `[key, iv]`\n */\nexport function generateKeyAndIvFromNonce(\n crypto: ICryptoProvider,\n serverNonce: Uint8Array,\n newNonce: Uint8Array,\n): [Uint8Array, Uint8Array] {\n const hash1 = crypto.sha1(concatBuffers([newNonce, serverNonce]))\n const hash2 = crypto.sha1(concatBuffers([serverNonce, newNonce]))\n const hash3 = crypto.sha1(concatBuffers([newNonce, newNonce]))\n\n const key = concatBuffers([hash1, hash2.subarray(0, 12)])\n const iv = concatBuffers([hash2.subarray(12, 20), hash3, newNonce.subarray(0, 4)])\n\n return [key, iv]\n}\n\n/**\n * Create AES IGE instance for message (given auth key and message key)\n * as defined by MTProto v2.\n *\n * @param crypto Crypto provider\n * @param authKey Authorization key\n * @param messageKey Message key\n * @param client Whether this is a client to server message\n */\nexport function createAesIgeForMessage(\n crypto: ICryptoProvider,\n authKey: Uint8Array,\n messageKey: Uint8Array,\n client: boolean,\n): IEncryptionScheme {\n const x = client ? 0 : 8\n const sha256a = crypto.sha256(concatBuffers([messageKey, authKey.subarray(x, 36 + x)]))\n const sha256b = crypto.sha256(concatBuffers([authKey.subarray(40 + x, 76 + x), messageKey]))\n\n const key = concatBuffers([sha256a.subarray(0, 8), sha256b.subarray(8, 24), sha256a.subarray(24, 32)])\n const iv = concatBuffers([sha256b.subarray(0, 8), sha256a.subarray(8, 24), sha256b.subarray(24, 32)])\n\n return crypto.createAesIge(key, iv)\n}\n\n/**\n * Create AES IGE instance for file (given auth key and message key)\n * as defined by MTProto v1.\n *\n * @param crypto Crypto provider\n * @param authKey Authorization key\n * @param messageKey Message key\n * @param client Whether this is a client to server message\n */\nexport function createAesIgeForMessageOld(\n crypto: ICryptoProvider,\n authKey: Uint8Array,\n messageKey: Uint8Array,\n client: boolean,\n): IEncryptionScheme {\n const x = client ? 0 : 8\n const sha1a = crypto.sha1(concatBuffers([messageKey, authKey.subarray(x, 32 + x)]))\n const sha1b = crypto.sha1(\n concatBuffers([authKey.subarray(32 + x, 48 + x), messageKey, authKey.subarray(48 + x, 64 + x)]),\n )\n const sha1c = crypto.sha1(concatBuffers([authKey.subarray(64 + x, 96 + x), messageKey]))\n const sha1d = crypto.sha1(concatBuffers([messageKey, authKey.subarray(96 + x, 128 + x)]))\n\n const key = concatBuffers([sha1a.subarray(0, 8), sha1b.subarray(8, 20), sha1c.subarray(4, 16)])\n const iv = concatBuffers([\n sha1a.subarray(8, 20),\n sha1b.subarray(0, 8),\n sha1c.subarray(16, 20),\n sha1d.subarray(0, 8),\n ])\n\n return crypto.createAesIge(key, iv)\n}\n"]}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { InitInput } from '@mtcute/wasm';
|
|
2
|
+
import { MaybeAsync } from '../../types/index.js';
|
|
3
|
+
import { BaseCryptoProvider, IAesCtr, ICryptoProvider, IEncryptionScheme } from './abstract.js';
|
|
4
|
+
export declare abstract class BaseNodeCryptoProvider extends BaseCryptoProvider {
|
|
5
|
+
createAesCtr(key: Uint8Array, iv: Uint8Array): IAesCtr;
|
|
6
|
+
pbkdf2(password: Uint8Array, salt: Uint8Array, iterations: number, keylen?: number, algo?: string): MaybeAsync<Uint8Array>;
|
|
7
|
+
sha1(data: Uint8Array): Uint8Array;
|
|
8
|
+
sha256(data: Uint8Array): Uint8Array;
|
|
9
|
+
hmacSha256(data: Uint8Array, key: Uint8Array): Uint8Array;
|
|
10
|
+
gzip(data: Uint8Array, maxSize: number): Uint8Array | null;
|
|
11
|
+
gunzip(data: Uint8Array): Uint8Array;
|
|
12
|
+
randomFill(buf: Uint8Array): void;
|
|
13
|
+
}
|
|
14
|
+
export declare class NodeCryptoProvider extends BaseNodeCryptoProvider implements ICryptoProvider {
|
|
15
|
+
private wasmInput?;
|
|
16
|
+
constructor(params?: {
|
|
17
|
+
wasmInput?: InitInput;
|
|
18
|
+
});
|
|
19
|
+
initialize(): Promise<void>;
|
|
20
|
+
createAesIge(key: Uint8Array, iv: Uint8Array): IEncryptionScheme;
|
|
21
|
+
}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.NodeCryptoProvider = exports.BaseNodeCryptoProvider = void 0;
|
|
4
|
+
// eslint-disable-next-line no-restricted-imports
|
|
5
|
+
const crypto_1 = require("crypto");
|
|
6
|
+
const zlib_1 = require("zlib");
|
|
7
|
+
const wasm_1 = require("@mtcute/wasm");
|
|
8
|
+
const abstract_js_1 = require("./abstract.js");
|
|
9
|
+
class BaseNodeCryptoProvider extends abstract_js_1.BaseCryptoProvider {
|
|
10
|
+
createAesCtr(key, iv) {
|
|
11
|
+
const cipher = (0, crypto_1.createCipheriv)(`aes-${key.length * 8}-ctr`, key, iv);
|
|
12
|
+
const update = (data) => cipher.update(data);
|
|
13
|
+
return {
|
|
14
|
+
process: update,
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
pbkdf2(password, salt, iterations, keylen = 64, algo = 'sha512') {
|
|
18
|
+
return new Promise((resolve, reject) => (0, crypto_1.pbkdf2)(password, salt, iterations, keylen, algo, (err, buf) => err !== null ? reject(err) : resolve(buf)));
|
|
19
|
+
}
|
|
20
|
+
sha1(data) {
|
|
21
|
+
return (0, crypto_1.createHash)('sha1').update(data).digest();
|
|
22
|
+
}
|
|
23
|
+
sha256(data) {
|
|
24
|
+
return (0, crypto_1.createHash)('sha256').update(data).digest();
|
|
25
|
+
}
|
|
26
|
+
hmacSha256(data, key) {
|
|
27
|
+
return (0, crypto_1.createHmac)('sha256', key).update(data).digest();
|
|
28
|
+
}
|
|
29
|
+
gzip(data, maxSize) {
|
|
30
|
+
// todo: test if wasm impl is better fit here
|
|
31
|
+
try {
|
|
32
|
+
// telegram accepts both zlib and gzip, but zlib is faster and has less overhead, so we use it here
|
|
33
|
+
return (0, zlib_1.deflateSync)(data, {
|
|
34
|
+
maxOutputLength: maxSize,
|
|
35
|
+
});
|
|
36
|
+
// hot path, avoid additional runtime checks
|
|
37
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
38
|
+
}
|
|
39
|
+
catch (e) {
|
|
40
|
+
if (e.code === 'ERR_BUFFER_TOO_LARGE') {
|
|
41
|
+
return null;
|
|
42
|
+
}
|
|
43
|
+
throw e;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
gunzip(data) {
|
|
47
|
+
return (0, zlib_1.gunzipSync)(data);
|
|
48
|
+
}
|
|
49
|
+
randomFill(buf) {
|
|
50
|
+
(0, crypto_1.randomFillSync)(buf);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
exports.BaseNodeCryptoProvider = BaseNodeCryptoProvider;
|
|
54
|
+
class NodeCryptoProvider extends BaseNodeCryptoProvider {
|
|
55
|
+
constructor(params) {
|
|
56
|
+
super();
|
|
57
|
+
this.wasmInput = params?.wasmInput;
|
|
58
|
+
}
|
|
59
|
+
initialize() {
|
|
60
|
+
return (0, wasm_1.initAsync)(this.wasmInput);
|
|
61
|
+
}
|
|
62
|
+
createAesIge(key, iv) {
|
|
63
|
+
return {
|
|
64
|
+
encrypt(data) {
|
|
65
|
+
return (0, wasm_1.ige256Encrypt)(data, key, iv);
|
|
66
|
+
},
|
|
67
|
+
decrypt(data) {
|
|
68
|
+
return (0, wasm_1.ige256Decrypt)(data, key, iv);
|
|
69
|
+
},
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
exports.NodeCryptoProvider = NodeCryptoProvider;
|
|
74
|
+
//# sourceMappingURL=node.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"node.js","sourceRoot":"","sources":["../../../../src/utils/crypto/node.ts"],"names":[],"mappings":"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","sourcesContent":["// eslint-disable-next-line no-restricted-imports\nimport { createCipheriv, createHash, createHmac, pbkdf2, randomFillSync } from 'crypto'\nimport { deflateSync, gunzipSync } from 'zlib'\n\nimport { ige256Decrypt, ige256Encrypt, initAsync, InitInput } from '@mtcute/wasm'\n\nimport { MaybeAsync } from '../../types/index.js'\nimport { BaseCryptoProvider, IAesCtr, ICryptoProvider, IEncryptionScheme } from './abstract.js'\n\nexport abstract class BaseNodeCryptoProvider extends BaseCryptoProvider {\n createAesCtr(key: Uint8Array, iv: Uint8Array): IAesCtr {\n const cipher = createCipheriv(`aes-${key.length * 8}-ctr`, key, iv)\n\n const update = (data: Uint8Array) => cipher.update(data)\n\n return {\n process: update,\n }\n }\n\n pbkdf2(\n password: Uint8Array,\n salt: Uint8Array,\n iterations: number,\n keylen = 64,\n algo = 'sha512',\n ): MaybeAsync<Uint8Array> {\n return new Promise((resolve, reject) =>\n pbkdf2(password, salt, iterations, keylen, algo, (err: Error | null, buf: Uint8Array) =>\n err !== null ? reject(err) : resolve(buf),\n ),\n )\n }\n\n sha1(data: Uint8Array): Uint8Array {\n return createHash('sha1').update(data).digest()\n }\n\n sha256(data: Uint8Array): Uint8Array {\n return createHash('sha256').update(data).digest()\n }\n\n hmacSha256(data: Uint8Array, key: Uint8Array): Uint8Array {\n return createHmac('sha256', key).update(data).digest()\n }\n\n gzip(data: Uint8Array, maxSize: number): Uint8Array | null {\n // todo: test if wasm impl is better fit here\n try {\n // telegram accepts both zlib and gzip, but zlib is faster and has less overhead, so we use it here\n return deflateSync(data, {\n maxOutputLength: maxSize,\n })\n // hot path, avoid additional runtime checks\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n } catch (e: any) {\n if (e.code === 'ERR_BUFFER_TOO_LARGE') {\n return null\n }\n\n throw e\n }\n }\n\n gunzip(data: Uint8Array): Uint8Array {\n return gunzipSync(data)\n }\n\n randomFill(buf: Uint8Array) {\n randomFillSync(buf)\n }\n}\n\nexport class NodeCryptoProvider extends BaseNodeCryptoProvider implements ICryptoProvider {\n private wasmInput?: InitInput\n\n constructor(params?: { wasmInput?: InitInput }) {\n super()\n this.wasmInput = params?.wasmInput\n }\n\n initialize(): Promise<void> {\n return initAsync(this.wasmInput)\n }\n\n createAesIge(key: Uint8Array, iv: Uint8Array): IEncryptionScheme {\n return {\n encrypt(data: Uint8Array): Uint8Array {\n return ige256Encrypt(data, key, iv)\n },\n decrypt(data: Uint8Array): Uint8Array {\n return ige256Decrypt(data, key, iv)\n },\n }\n }\n}\n"]}
|
|
@@ -1,10 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
-
};
|
|
5
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
3
|
exports.computeSrpParams = exports.computeNewPasswordHash = exports.computePasswordHash = void 0;
|
|
7
|
-
const big_integer_1 = __importDefault(require("big-integer"));
|
|
8
4
|
const tl_runtime_1 = require("@mtcute/tl-runtime");
|
|
9
5
|
const errors_js_1 = require("../../types/errors.js");
|
|
10
6
|
const bigint_utils_js_1 = require("../bigint-utils.js");
|
|
@@ -22,8 +18,8 @@ const utils_js_1 = require("./utils.js");
|
|
|
22
18
|
*/
|
|
23
19
|
async function computePasswordHash(crypto, password, salt1, salt2) {
|
|
24
20
|
const SH = (data, salt) => crypto.sha256((0, buffer_utils_js_1.concatBuffers)([salt, data, salt]));
|
|
25
|
-
const PH1 =
|
|
26
|
-
return SH(await crypto.pbkdf2(
|
|
21
|
+
const PH1 = (pwd, salt1, salt2) => SH(SH(pwd, salt1), salt2);
|
|
22
|
+
return SH(await crypto.pbkdf2(PH1(password, salt1, salt2), salt1, 100000), salt2);
|
|
27
23
|
}
|
|
28
24
|
exports.computePasswordHash = computePasswordHash;
|
|
29
25
|
/**
|
|
@@ -34,12 +30,15 @@ exports.computePasswordHash = computePasswordHash;
|
|
|
34
30
|
* @param password Password
|
|
35
31
|
*/
|
|
36
32
|
async function computeNewPasswordHash(crypto, algo, password) {
|
|
37
|
-
|
|
33
|
+
const salt1 = new Uint8Array(algo.salt1.length + 32);
|
|
34
|
+
salt1.set(algo.salt1);
|
|
35
|
+
crypto.randomFill(salt1.subarray(algo.salt1.length));
|
|
36
|
+
algo.salt1 = salt1;
|
|
38
37
|
const _x = await computePasswordHash(crypto, (0, tl_runtime_1.utf8EncodeToBuffer)(password), algo.salt1, algo.salt2);
|
|
39
|
-
const g = (
|
|
38
|
+
const g = BigInt(algo.g);
|
|
40
39
|
const p = (0, bigint_utils_js_1.bufferToBigInt)(algo.p);
|
|
41
40
|
const x = (0, bigint_utils_js_1.bufferToBigInt)(_x);
|
|
42
|
-
return (0, bigint_utils_js_1.bigIntToBuffer)(
|
|
41
|
+
return (0, bigint_utils_js_1.bigIntToBuffer)((0, bigint_utils_js_1.bigIntModPow)(g, x, p), 256);
|
|
43
42
|
}
|
|
44
43
|
exports.computeNewPasswordHash = computeNewPasswordHash;
|
|
45
44
|
/**
|
|
@@ -63,38 +62,28 @@ async function computeSrpParams(crypto, request, password) {
|
|
|
63
62
|
if (!request.srpId) {
|
|
64
63
|
throw new errors_js_1.MtSecurityError('SRP_ID is not present in the request');
|
|
65
64
|
}
|
|
66
|
-
const g = (
|
|
65
|
+
const g = BigInt(algo.g);
|
|
67
66
|
const _g = (0, bigint_utils_js_1.bigIntToBuffer)(g, 256);
|
|
68
67
|
const p = (0, bigint_utils_js_1.bufferToBigInt)(algo.p);
|
|
69
68
|
const gB = (0, bigint_utils_js_1.bufferToBigInt)(request.srpB);
|
|
70
|
-
const a = (0, bigint_utils_js_1.bufferToBigInt)(
|
|
71
|
-
const gA =
|
|
69
|
+
const a = (0, bigint_utils_js_1.bufferToBigInt)(crypto.randomBytes(256));
|
|
70
|
+
const gA = (0, bigint_utils_js_1.bigIntModPow)(g, a, p);
|
|
72
71
|
const _gA = (0, bigint_utils_js_1.bigIntToBuffer)(gA, 256);
|
|
73
72
|
const H = (data) => crypto.sha256(data);
|
|
74
|
-
const
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
/* u = */ crypto.sha256((0, buffer_utils_js_1.concatBuffers)([_gA, request.srpB])),
|
|
78
|
-
/* x = */ computePasswordHash(crypto, (0, tl_runtime_1.utf8EncodeToBuffer)(password), algo.salt1, algo.salt2),
|
|
79
|
-
]);
|
|
73
|
+
const _k = crypto.sha256((0, buffer_utils_js_1.concatBuffers)([algo.p, _g]));
|
|
74
|
+
const _u = crypto.sha256((0, buffer_utils_js_1.concatBuffers)([_gA, request.srpB]));
|
|
75
|
+
const _x = await computePasswordHash(crypto, (0, tl_runtime_1.utf8EncodeToBuffer)(password), algo.salt1, algo.salt2);
|
|
80
76
|
const k = (0, bigint_utils_js_1.bufferToBigInt)(_k);
|
|
81
77
|
const u = (0, bigint_utils_js_1.bufferToBigInt)(_u);
|
|
82
78
|
const x = (0, bigint_utils_js_1.bufferToBigInt)(_x);
|
|
83
|
-
const v =
|
|
84
|
-
const kV = k
|
|
85
|
-
let t = gB
|
|
86
|
-
if (t
|
|
87
|
-
t
|
|
88
|
-
const sA =
|
|
89
|
-
const _kA =
|
|
90
|
-
const _M1 =
|
|
91
|
-
(0, utils_js_1.xorBuffer)(await H(algo.p), await H(_g)),
|
|
92
|
-
await H(algo.salt1),
|
|
93
|
-
await H(algo.salt2),
|
|
94
|
-
_gA,
|
|
95
|
-
request.srpB,
|
|
96
|
-
_kA,
|
|
97
|
-
]));
|
|
79
|
+
const v = (0, bigint_utils_js_1.bigIntModPow)(g, x, p);
|
|
80
|
+
const kV = (k * v) % p;
|
|
81
|
+
let t = gB - kV;
|
|
82
|
+
if (t < 0n)
|
|
83
|
+
t += p;
|
|
84
|
+
const sA = (0, bigint_utils_js_1.bigIntModPow)(t, a + u * x, p);
|
|
85
|
+
const _kA = H((0, bigint_utils_js_1.bigIntToBuffer)(sA, 256));
|
|
86
|
+
const _M1 = H((0, buffer_utils_js_1.concatBuffers)([(0, utils_js_1.xorBuffer)(H(algo.p), H(_g)), H(algo.salt1), H(algo.salt2), _gA, request.srpB, _kA]));
|
|
98
87
|
return {
|
|
99
88
|
_: 'inputCheckPasswordSRP',
|
|
100
89
|
srpId: request.srpId,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"password.js","sourceRoot":"","sources":["../../../../src/utils/crypto/password.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"password.js","sourceRoot":"","sources":["../../../../src/utils/crypto/password.ts"],"names":[],"mappings":"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","sourcesContent":["import { tl } from '@mtcute/tl'\nimport { utf8EncodeToBuffer } from '@mtcute/tl-runtime'\n\nimport { MtSecurityError, MtUnsupportedError } from '../../types/errors.js'\nimport { bigIntModPow, bigIntToBuffer, bufferToBigInt } from '../bigint-utils.js'\nimport { concatBuffers } from '../buffer-utils.js'\nimport { ICryptoProvider } from './abstract.js'\nimport { xorBuffer } from './utils.js'\n\n/**\n * Compute password hash as defined by MTProto.\n *\n * See https://core.telegram.org/api/srp#checking-the-password-with-srp\n *\n * @param crypto Crypto provider\n * @param password Password\n * @param salt1 Salt 1\n * @param salt2 Salt 2\n */\nexport async function computePasswordHash(\n crypto: ICryptoProvider,\n password: Uint8Array,\n salt1: Uint8Array,\n salt2: Uint8Array,\n): Promise<Uint8Array> {\n const SH = (data: Uint8Array, salt: Uint8Array) => crypto.sha256(concatBuffers([salt, data, salt]))\n const PH1 = (pwd: Uint8Array, salt1: Uint8Array, salt2: Uint8Array) => SH(SH(pwd, salt1), salt2)\n\n return SH(await crypto.pbkdf2(PH1(password, salt1, salt2), salt1, 100000), salt2)\n}\n\n/**\n * Compute new password SRP hash as defined by MTProto.\n *\n * @param crypto Crypto provider\n * @param algo KDF algorithm\n * @param password Password\n */\nexport async function computeNewPasswordHash(\n crypto: ICryptoProvider,\n algo: tl.RawPasswordKdfAlgoSHA256SHA256PBKDF2HMACSHA512iter100000SHA256ModPow,\n password: string,\n): Promise<Uint8Array> {\n const salt1 = new Uint8Array(algo.salt1.length + 32)\n salt1.set(algo.salt1)\n crypto.randomFill(salt1.subarray(algo.salt1.length))\n ;(algo as tl.Mutable<typeof algo>).salt1 = salt1\n\n const _x = await computePasswordHash(crypto, utf8EncodeToBuffer(password), algo.salt1, algo.salt2)\n\n const g = BigInt(algo.g)\n const p = bufferToBigInt(algo.p)\n const x = bufferToBigInt(_x)\n\n return bigIntToBuffer(bigIntModPow(g, x, p), 256)\n}\n\n/**\n * Compute SRP check parameters for 2fa password as defined by MTProto.\n *\n * @param crypto Crypto provider\n * @param request SRP request\n * @param password 2fa password\n */\nexport async function computeSrpParams(\n crypto: ICryptoProvider,\n request: tl.account.RawPassword,\n password: string,\n): Promise<tl.RawInputCheckPasswordSRP> {\n // nice naming thx durov\n if (\n !request.currentAlgo ||\n request.currentAlgo._ !== 'passwordKdfAlgoSHA256SHA256PBKDF2HMACSHA512iter100000SHA256ModPow'\n ) {\n throw new MtUnsupportedError(`Unknown algo ${request.currentAlgo?._}`)\n }\n\n const algo = request.currentAlgo\n\n // here and after: underscored variables are buffers, non-underscored are bigInts\n\n if (!request.srpB) {\n throw new MtSecurityError('SRP_B is not present in the request')\n }\n\n if (!request.srpId) {\n throw new MtSecurityError('SRP_ID is not present in the request')\n }\n\n const g = BigInt(algo.g)\n const _g = bigIntToBuffer(g, 256)\n const p = bufferToBigInt(algo.p)\n const gB = bufferToBigInt(request.srpB)\n\n const a = bufferToBigInt(crypto.randomBytes(256))\n const gA = bigIntModPow(g, a, p)\n const _gA = bigIntToBuffer(gA, 256)\n\n const H = (data: Uint8Array) => crypto.sha256(data)\n\n const _k = crypto.sha256(concatBuffers([algo.p, _g]))\n const _u = crypto.sha256(concatBuffers([_gA, request.srpB]))\n const _x = await computePasswordHash(crypto, utf8EncodeToBuffer(password), algo.salt1, algo.salt2)\n const k = bufferToBigInt(_k)\n const u = bufferToBigInt(_u)\n const x = bufferToBigInt(_x)\n\n const v = bigIntModPow(g, x, p)\n const kV = (k * v) % p\n\n let t = gB - kV\n if (t < 0n) t += p\n const sA = bigIntModPow(t, a + u * x, p)\n const _kA = H(bigIntToBuffer(sA, 256))\n\n const _M1 = H(concatBuffers([xorBuffer(H(algo.p), H(_g)), H(algo.salt1), H(algo.salt2), _gA, request.srpB, _kA]))\n\n return {\n _: 'inputCheckPasswordSRP',\n srpId: request.srpId,\n A: _gA,\n M1: _M1,\n }\n}\n"]}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { InitInput } from '@mtcute/wasm';
|
|
2
|
+
import { BaseCryptoProvider, IAesCtr, ICryptoProvider, IEncryptionScheme } from './abstract.js';
|
|
3
|
+
export interface WasmCryptoProviderOptions {
|
|
4
|
+
/**
|
|
5
|
+
* WASM blob to use for crypto operations.
|
|
6
|
+
*
|
|
7
|
+
* Must conform to `@mtcute/wasm` interface.
|
|
8
|
+
*/
|
|
9
|
+
wasmInput?: InitInput;
|
|
10
|
+
}
|
|
11
|
+
export declare abstract class WasmCryptoProvider extends BaseCryptoProvider implements Partial<ICryptoProvider> {
|
|
12
|
+
readonly wasmInput?: InitInput;
|
|
13
|
+
abstract randomFill(buf: Uint8Array): void;
|
|
14
|
+
constructor(params?: WasmCryptoProviderOptions);
|
|
15
|
+
initialize(): Promise<void>;
|
|
16
|
+
sha1(data: Uint8Array): Uint8Array;
|
|
17
|
+
sha256(data: Uint8Array): Uint8Array;
|
|
18
|
+
createAesCtr(key: Uint8Array, iv: Uint8Array): IAesCtr;
|
|
19
|
+
createAesIge(key: Uint8Array, iv: Uint8Array): IEncryptionScheme;
|
|
20
|
+
gzip(data: Uint8Array, maxSize: number): Uint8Array | null;
|
|
21
|
+
gunzip(data: Uint8Array): Uint8Array;
|
|
22
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.WasmCryptoProvider = void 0;
|
|
4
|
+
const wasm_1 = require("@mtcute/wasm");
|
|
5
|
+
const abstract_js_1 = require("./abstract.js");
|
|
6
|
+
class WasmCryptoProvider extends abstract_js_1.BaseCryptoProvider {
|
|
7
|
+
constructor(params) {
|
|
8
|
+
super();
|
|
9
|
+
this.wasmInput = params?.wasmInput;
|
|
10
|
+
}
|
|
11
|
+
initialize() {
|
|
12
|
+
return (0, wasm_1.initAsync)(this.wasmInput);
|
|
13
|
+
}
|
|
14
|
+
sha1(data) {
|
|
15
|
+
return (0, wasm_1.sha1)(data);
|
|
16
|
+
}
|
|
17
|
+
sha256(data) {
|
|
18
|
+
return (0, wasm_1.sha256)(data);
|
|
19
|
+
}
|
|
20
|
+
createAesCtr(key, iv) {
|
|
21
|
+
const ctx = (0, wasm_1.createCtr256)(key, iv);
|
|
22
|
+
return {
|
|
23
|
+
process: (data) => (0, wasm_1.ctr256)(ctx, data),
|
|
24
|
+
close: () => (0, wasm_1.freeCtr256)(ctx),
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
createAesIge(key, iv) {
|
|
28
|
+
return {
|
|
29
|
+
encrypt: (data) => (0, wasm_1.ige256Encrypt)(data, key, iv),
|
|
30
|
+
decrypt: (data) => (0, wasm_1.ige256Decrypt)(data, key, iv),
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
gzip(data, maxSize) {
|
|
34
|
+
return (0, wasm_1.deflateMaxSize)(data, maxSize);
|
|
35
|
+
}
|
|
36
|
+
gunzip(data) {
|
|
37
|
+
return (0, wasm_1.gunzip)(data);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
exports.WasmCryptoProvider = WasmCryptoProvider;
|
|
41
|
+
//# sourceMappingURL=wasm.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"wasm.js","sourceRoot":"","sources":["../../../../src/utils/crypto/wasm.ts"],"names":[],"mappings":";;;AAAA,uCAYqB;AAErB,+CAA+F;AAW/F,MAAsB,kBAAmB,SAAQ,gCAAkB;IAK/D,YAAY,MAAkC;QAC1C,KAAK,EAAE,CAAA;QACP,IAAI,CAAC,SAAS,GAAG,MAAM,EAAE,SAAS,CAAA;IACtC,CAAC;IAED,UAAU;QACN,OAAO,IAAA,gBAAS,EAAC,IAAI,CAAC,SAAS,CAAC,CAAA;IACpC,CAAC;IAED,IAAI,CAAC,IAAgB;QACjB,OAAO,IAAA,WAAI,EAAC,IAAI,CAAC,CAAA;IACrB,CAAC;IAED,MAAM,CAAC,IAAgB;QACnB,OAAO,IAAA,aAAM,EAAC,IAAI,CAAC,CAAA;IACvB,CAAC;IAED,YAAY,CAAC,GAAe,EAAE,EAAc;QACxC,MAAM,GAAG,GAAG,IAAA,mBAAY,EAAC,GAAG,EAAE,EAAE,CAAC,CAAA;QAEjC,OAAO;YACH,OAAO,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,IAAA,aAAM,EAAC,GAAG,EAAE,IAAI,CAAC;YACpC,KAAK,EAAE,GAAG,EAAE,CAAC,IAAA,iBAAU,EAAC,GAAG,CAAC;SAC/B,CAAA;IACL,CAAC;IAED,YAAY,CAAC,GAAe,EAAE,EAAc;QACxC,OAAO;YACH,OAAO,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,IAAA,oBAAa,EAAC,IAAI,EAAE,GAAG,EAAE,EAAE,CAAC;YAC/C,OAAO,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,IAAA,oBAAa,EAAC,IAAI,EAAE,GAAG,EAAE,EAAE,CAAC;SAClD,CAAA;IACL,CAAC;IAED,IAAI,CAAC,IAAgB,EAAE,OAAe;QAClC,OAAO,IAAA,qBAAc,EAAC,IAAI,EAAE,OAAO,CAAC,CAAA;IACxC,CAAC;IAED,MAAM,CAAC,IAAgB;QACnB,OAAO,IAAA,aAAM,EAAC,IAAI,CAAC,CAAA;IACvB,CAAC;CACJ;AA7CD,gDA6CC","sourcesContent":["import {\n createCtr256,\n ctr256,\n deflateMaxSize,\n freeCtr256,\n gunzip,\n ige256Decrypt,\n ige256Encrypt,\n initAsync,\n InitInput,\n sha1,\n sha256,\n} from '@mtcute/wasm'\n\nimport { BaseCryptoProvider, IAesCtr, ICryptoProvider, IEncryptionScheme } from './abstract.js'\n\nexport interface WasmCryptoProviderOptions {\n /**\n * WASM blob to use for crypto operations.\n *\n * Must conform to `@mtcute/wasm` interface.\n */\n wasmInput?: InitInput\n}\n\nexport abstract class WasmCryptoProvider extends BaseCryptoProvider implements Partial<ICryptoProvider> {\n readonly wasmInput?: InitInput\n\n abstract randomFill(buf: Uint8Array): void\n\n constructor(params?: WasmCryptoProviderOptions) {\n super()\n this.wasmInput = params?.wasmInput\n }\n\n initialize(): Promise<void> {\n return initAsync(this.wasmInput)\n }\n\n sha1(data: Uint8Array): Uint8Array {\n return sha1(data)\n }\n\n sha256(data: Uint8Array): Uint8Array {\n return sha256(data)\n }\n\n createAesCtr(key: Uint8Array, iv: Uint8Array): IAesCtr {\n const ctx = createCtr256(key, iv)\n\n return {\n process: (data) => ctr256(ctx, data),\n close: () => freeCtr256(ctx),\n }\n }\n\n createAesIge(key: Uint8Array, iv: Uint8Array): IEncryptionScheme {\n return {\n encrypt: (data) => ige256Encrypt(data, key, iv),\n decrypt: (data) => ige256Decrypt(data, key, iv),\n }\n }\n\n gzip(data: Uint8Array, maxSize: number): Uint8Array | null {\n return deflateMaxSize(data, maxSize)\n }\n\n gunzip(data: Uint8Array): Uint8Array {\n return gunzip(data)\n }\n}\n"]}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { ICryptoProvider } from './abstract.js';
|
|
2
|
+
import { WasmCryptoProvider, WasmCryptoProviderOptions } from './wasm.js';
|
|
3
|
+
export declare class WebCryptoProvider extends WasmCryptoProvider implements ICryptoProvider {
|
|
4
|
+
readonly crypto: Crypto;
|
|
5
|
+
constructor(params?: WasmCryptoProviderOptions & {
|
|
6
|
+
crypto?: Crypto;
|
|
7
|
+
});
|
|
8
|
+
pbkdf2(password: Uint8Array, salt: Uint8Array, iterations: number, keylen?: number | undefined, algo?: string | undefined): Promise<Uint8Array>;
|
|
9
|
+
hmacSha256(data: Uint8Array, key: Uint8Array): Promise<Uint8Array>;
|
|
10
|
+
randomFill(buf: Uint8Array): void;
|
|
11
|
+
}
|