diff --git a/src/helpers/random.ts b/src/helpers/random.ts index 0f76df4e..ede11304 100644 --- a/src/helpers/random.ts +++ b/src/helpers/random.ts @@ -4,11 +4,17 @@ * https://github.com/morethanwords/tweb/blob/master/LICENSE */ -export function nextRandomInt(maxValue: number) { - return Math.floor(Math.random() * maxValue); +const arrays = { + 8: new Uint8Array(1), + 16: new Uint16Array(1), + 32: new Uint32Array(1), +}; +export function nextRandomUint(bits: 8 | 16 | 32) { + const array = arrays[bits]; + crypto.getRandomValues(array); + return array[0]; } export function randomLong() { - return '' + nextRandomInt(0xFFFFFFFF) + nextRandomInt(0xFFFFFF); - //return '' + parseInt(nextRandomInt(0xFFFFFFFF).toString(16) + nextRandomInt(0xFFFFFFFF).toString(16), 16); + return '' + nextRandomUint(32) + nextRandomUint(32); } diff --git a/src/lib/appManagers/appStateManager.ts b/src/lib/appManagers/appStateManager.ts index 34054f99..4c0b19c6 100644 --- a/src/lib/appManagers/appStateManager.ts +++ b/src/lib/appManagers/appStateManager.ts @@ -22,7 +22,7 @@ import { Chat } from '../../layer'; import { isMobile } from '../../helpers/userAgent'; import DATABASE_STATE from '../../config/databases/state'; import sessionStorage from '../sessionStorage'; -import { nextRandomInt } from '../../helpers/random'; +import { nextRandomUint } from '../../helpers/random'; const REFRESH_EVERY = 24 * 60 * 60 * 1000; // 1 day //const REFRESH_EVERY_WEEK = 24 * 60 * 60 * 1000 * 7; // 7 days @@ -156,7 +156,7 @@ export const STATE_INIT: State = { }, keepSigned: true, chatContextMenuHintWasShown: false, - stateId: nextRandomInt(0xFFFFFFFF) + stateId: nextRandomUint(32) }; const ALL_KEYS = Object.keys(STATE_INIT) as any as Array; diff --git a/src/lib/crypto/crypto_utils.ts b/src/lib/crypto/crypto_utils.ts index eee0f1ff..41cb274b 100644 --- a/src/lib/crypto/crypto_utils.ts +++ b/src/lib/crypto/crypto_utils.ts @@ -22,7 +22,7 @@ import {str2bigInt, bpe, equalsInt, greater, import { addPadding } from '../mtproto/bin_utils'; import { bytesToWordss, bytesFromWordss, bytesToHex, bytesFromHex, convertToUint8Array } from '../../helpers/bytes'; -import { nextRandomInt } from '../../helpers/random'; +import { nextRandomUint } from '../../helpers/random'; import type { RSAPublicKeyHex } from '../mtproto/rsaKeysManager'; const subtle = typeof(window) !== 'undefined' && 'crypto' in window ? window.crypto.subtle : self.crypto.subtle; @@ -200,8 +200,8 @@ export function pqPrimeLeemon(what: number[]): [Uint8Array, Uint8Array, number] var y = new Array(minLen); for(i = 0; i < 3; ++i) { - q = (nextRandomInt(128) & 15) + 17; - copyInt_(x, nextRandomInt(1000000000) + 1); + q = (nextRandomUint(8) & 15) + 17; + copyInt_(x, nextRandomUint(32) + 1); copy_(y, x); lim = 1 << (i + 18); diff --git a/src/lib/mtproto/apiFileManager.ts b/src/lib/mtproto/apiFileManager.ts index fe9bf29c..b2239532 100644 --- a/src/lib/mtproto/apiFileManager.ts +++ b/src/lib/mtproto/apiFileManager.ts @@ -16,7 +16,7 @@ import { readBlobAsArrayBuffer } from "../../helpers/blob"; import { CancellablePromise, deferredPromise } from "../../helpers/cancellablePromise"; import { notifyAll, notifySomeone } from "../../helpers/context"; import { getFileNameByLocation } from "../../helpers/fileName"; -import { nextRandomInt } from "../../helpers/random"; +import { randomLong } from "../../helpers/random"; import { InputFile, InputFileLocation, UploadFile } from "../../layer"; import { DcId, WorkerTaskVoidTemplate } from "../../types"; import CacheStorageController from "../cacheStorage"; @@ -524,7 +524,7 @@ export class ApiFileManager { const activeDelta = this.getDelta(partSize); const totalParts = Math.ceil(fileSize / partSize); - const fileId: [number, number] = [nextRandomInt(0xFFFFFFFF), nextRandomInt(0xFFFFFFFF)]; + const fileId = randomLong(); let _part = 0; diff --git a/src/lib/mtproto/bin_utils.ts b/src/lib/mtproto/bin_utils.ts index 5f4c7555..efb0ebea 100644 --- a/src/lib/mtproto/bin_utils.ts +++ b/src/lib/mtproto/bin_utils.ts @@ -11,7 +11,6 @@ import { bufferConcats } from '../../helpers/bytes'; import { add_, bigInt2str, cmp, leftShift_, str2bigInt } from '../../vendor/leemon'; -import { nextRandomInt } from '../../helpers/random'; /// #if !MTPROTO_WORKER // @ts-ignore @@ -141,15 +140,13 @@ export function addPadding( const needPadding = blockSizeAsTotalLength ? blockSize - len : blockSize - (len % blockSize); if(needPadding > 0 && needPadding < blockSize) { ////console.log('addPadding()', len, blockSize, needPadding); - const padding: number[] = new Array(needPadding); + const padding = new Uint8Array(needPadding); if(zeroes) { for(let i = 0; i < needPadding; ++i) { padding[i] = 0; } } else { - for(let i = 0; i < needPadding; ++i) { - padding[i] = nextRandomInt(255); - } + padding.randomize(); } if(bytes instanceof ArrayBuffer) { @@ -158,7 +155,7 @@ export function addPadding( return (prepend ? bufferConcats(padding, bytes) : bufferConcats(bytes, padding)) as T; } else { // @ts-ignore - return (prepend ? padding.concat(bytes) : bytes.concat(padding)) as T; + return (prepend ? [...padding].concat(bytes) : bytes.concat([...padding])) as T; } } diff --git a/src/lib/mtproto/networker.ts b/src/lib/mtproto/networker.ts index 627661ec..ad678a76 100644 --- a/src/lib/mtproto/networker.ts +++ b/src/lib/mtproto/networker.ts @@ -21,7 +21,7 @@ import { InvokeApiOptions } from '../../types'; import { longToBytes } from '../crypto/crypto_utils'; import MTTransport from './transports/transport'; import { convertToUint8Array, bytesCmp, bytesToHex, bufferConcats } from '../../helpers/bytes'; -import { nextRandomInt } from '../../helpers/random'; +import { nextRandomUint, randomLong } from '../../helpers/random'; import App from '../../config/app'; import DEBUG from '../../config/debug'; import Modes from '../../config/modes'; @@ -549,7 +549,7 @@ export default class MTPNetworker { this.checkConnectionTimeout = 0; const serializer = new TLSerialization({mtproto: true}); - const pingId = [nextRandomInt(0xFFFFFFFF), nextRandomInt(0xFFFFFFFF)]; + const pingId = randomLong(); serializer.storeMethod('ping', { ping_id: pingId @@ -1103,7 +1103,7 @@ export default class MTPNetworker { this.log.error('wrong length', dataBuffer, canBeLength, message.msg_id); } */ - const paddingLength = (16 - (data.getOffset() % 16)) + 16 * (1 + nextRandomInt(5)); + const paddingLength = (16 - (data.getOffset() % 16)) + 16 * (1 + nextRandomUint(8) % 5); const padding = /* (message as any).padding || */new Uint8Array(paddingLength).randomize()/* .fill(0) */; /* const padding = [167, 148, 207, 226, 86, 192, 193, 57, 124, 153, 174, 145, 159, 1, 5, 70, 127, 157, 51, 241, 46, 85, 141, 212, 139, 234, 213, 164, 197, 116, 245, 70, 184, 40, 40, 201, 233, 211, 150, diff --git a/src/lib/mtproto/singleInstance.ts b/src/lib/mtproto/singleInstance.ts index e41c57ef..319028be 100644 --- a/src/lib/mtproto/singleInstance.ts +++ b/src/lib/mtproto/singleInstance.ts @@ -10,7 +10,7 @@ */ import { MOUNT_CLASS_TO } from "../../config/debug"; -import { nextRandomInt } from "../../helpers/random"; +import { nextRandomUint } from "../../helpers/random"; import { logger } from "../logger"; import rootScope from "../rootScope"; import sessionStorage from "../sessionStorage"; @@ -53,7 +53,7 @@ export class SingleInstance { } public reset() { - this.instanceID = nextRandomInt(0xFFFFFFFF); + this.instanceID = nextRandomUint(32); this.masterInstance = false; if(this.deactivateTimeout) clearTimeout(this.deactivateTimeout); this.deactivateTimeout = 0; diff --git a/src/lib/mtproto/timeManager.ts b/src/lib/mtproto/timeManager.ts index 47068870..94f9f364 100644 --- a/src/lib/mtproto/timeManager.ts +++ b/src/lib/mtproto/timeManager.ts @@ -11,7 +11,7 @@ import sessionStorage from '../sessionStorage'; import { longFromInts } from './bin_utils'; -import { nextRandomInt } from '../../helpers/random'; +import { nextRandomUint } from '../../helpers/random'; import { MOUNT_CLASS_TO } from '../../config/debug'; import { WorkerTaskVoidTemplate } from '../../types'; import { notifySomeone } from '../../helpers/context'; @@ -44,7 +44,7 @@ export class TimeManager { const timeTicks = Date.now(), timeSec = Math.floor(timeTicks / 1000) + this.timeOffset, timeMSec = timeTicks % 1000, - random = nextRandomInt(0xFFFF); + random = nextRandomUint(16); let messageId: TimeManager['lastMessageId'] = [timeSec, (timeMSec << 21) | (random << 3) | 4]; if(this.lastMessageId[0] > messageId[0] || diff --git a/src/lib/mtproto/transports/padded.ts b/src/lib/mtproto/transports/padded.ts index f1b6c6fb..a9b6d023 100644 --- a/src/lib/mtproto/transports/padded.ts +++ b/src/lib/mtproto/transports/padded.ts @@ -4,7 +4,7 @@ * https://github.com/morethanwords/tweb/blob/master/LICENSE */ -import { nextRandomInt } from "../../../helpers/random"; +import { nextRandomUint } from "../../../helpers/random"; import { IntermediatePacketCodec } from "./intermediate"; /* Data packets are aligned to 4bytes. This codec adds random bytes of size from 0 to 3 bytes, which are ignored by decoder. */ @@ -13,7 +13,7 @@ class PaddedIntermediatePacketCodec extends IntermediatePacketCodec { public obfuscateTag = new Uint8Array([this.tag, this.tag, this.tag, this.tag]); public encodePacket(data: Uint8Array) { - let padding = new Uint8Array(nextRandomInt(3)).randomize(); + let padding = new Uint8Array(nextRandomUint(8) % 3).randomize(); let len = data.byteLength + padding.byteLength; let header = new Uint8Array(new Uint32Array([len]).buffer); diff --git a/src/vendor/leemon.ts b/src/vendor/leemon.ts index 1b8a5bf9..8af609f6 100644 --- a/src/vendor/leemon.ts +++ b/src/vendor/leemon.ts @@ -345,11 +345,11 @@ export function expand(x: number[], n: number): number[] { * @param {number} k * @returns {number[]} */ -export function randTruePrime(k: number): number[] { +/* export function randTruePrime(k: number): number[] { var ans = int2bigInt(0, k, 0) randTruePrime_(ans, k) return trim(ans, 1) -} +} */ /** * return a k-bit random probable prime with probability of error < 2^-80 @@ -358,7 +358,7 @@ export function randTruePrime(k: number): number[] { * @param {number} k * @returns {number[]} */ -export function randProbPrime(k: number): number[] { +/* export function randProbPrime(k: number): number[] { if (k >= 600) return randProbPrimeRounds(k, 2) //numbers from HAC table 4.3 if (k >= 550) return randProbPrimeRounds(k, 4) if (k >= 500) return randProbPrimeRounds(k, 5) @@ -370,7 +370,7 @@ export function randProbPrime(k: number): number[] { if (k >= 150) return randProbPrimeRounds(k, 18) if (k >= 100) return randProbPrimeRounds(k, 27) return randProbPrimeRounds(k, 40) //number from HAC remark 4.26 (only an estimate) -} +} */ /** * return a k-bit probable random prime using n rounds of Miller Rabin @@ -381,7 +381,7 @@ export function randProbPrime(k: number): number[] { * @param {number} n * @returns {number[]} */ -export function randProbPrimeRounds(k: number, n: number): number[] { +/* export function randProbPrimeRounds(k: number, n: number): number[] { var ans, i, divisible, B B = 30000 //B is largest prime to use in trial division ans = int2bigInt(0, k, 0) @@ -423,11 +423,7 @@ export function randProbPrimeRounds(k: number, n: number): number[] { if (!divisible) return ans } - /*:: - declare var never: empty - return never - */ -} +} */ /** * return a new bigInt equal to (x mod n) for bigInts x and n. @@ -450,11 +446,11 @@ export function mod(x: number[], n: number[]): number[] { * @param {number} n * @returns {number[]} */ -export function addInt(x: number[], n: number): number[] { +/* export function addInt(x: number[], n: number): number[] { var ans = expand(x, x.length + 1) addInt_(ans, n) return trim(ans, 1) -} +} */ /** * return x*y for bigInts x and y. This is faster when y=1). If s=1, then the most significant of those n bits is set to 1. @@ -722,13 +718,13 @@ export function randTruePrime_(ans: number[], k: number): void { * @param {number} s * @returns {number[]} */ -export function randBigInt(n: number, s: number): number[] { +/* export function randBigInt(n: number, s: number): number[] { var a, b a = Math.floor((n - 1) / bpe) + 2 //# array elements to hold the BigInt with a leading 0 element b = int2bigInt(0, 0, a) randBigInt_(b, n, s) return b -} +} */ /** * Set b to an n-bit random BigInt. If s=1, then the most significant of those n bits is set to 1. @@ -741,7 +737,7 @@ export function randBigInt(n: number, s: number): number[] { * @param {number} s * @return {void} */ -export function randBigInt_(b: number[], n: number, s: number): void { +/* export function randBigInt_(b: number[], n: number, s: number): void { var i, a for (i = 0; i < b.length; i++) b[i] = 0 a = Math.floor((n - 1) / bpe) + 1 //# array elements to hold the BigInt @@ -750,7 +746,7 @@ export function randBigInt_(b: number[], n: number, s: number): void { } b[a - 1] &= (2 << ((n - 1) % bpe)) - 1 if (s == 1) b[a - 1] |= 1 << ((n - 1) % bpe) -} +} */ /** * Return the greatest common divisor of bigInts x and y (each with same number of elements). @@ -852,7 +848,7 @@ export function GCD_(x: number[], y: number[]): void { * @param {number[]} n * @returns {(0 | 1)} */ -export function inverseMod_(x: number[], n: number[]): Bool { +/* export function inverseMod_(x: number[], n: number[]): Bool { var k = 1 + 2 * Math.max(x.length, n.length) if (!(x[0] & 1) && !(n[0] & 1)) { @@ -934,11 +930,7 @@ export function inverseMod_(x: number[], n: number[]): Bool { return 1 } } - /*:: - declare var never: empty - return never - */ -} +} */ /** * return x**(-1) mod n, for integers x and n. @@ -973,9 +965,9 @@ export function inverseModInt(x: number, n: number): number { } //this deprecated function is for backward compatibility only. -function inverseModInt_(x: number, n: number) { +/* function inverseModInt_(x: number, n: number) { return inverseModInt(x, n) -} +} */ /** * Given positive bigInts x and y, change the bigints v, a, and b to positive bigInts such that: