Browse Source

Use crypto.getRandomValues() everywhere

master
Eduard Kuzmenko 3 years ago
parent
commit
37da386b9c
  1. 14
      src/helpers/random.ts
  2. 4
      src/lib/appManagers/appStateManager.ts
  3. 6
      src/lib/crypto/crypto_utils.ts
  4. 4
      src/lib/mtproto/apiFileManager.ts
  5. 9
      src/lib/mtproto/bin_utils.ts
  6. 6
      src/lib/mtproto/networker.ts
  7. 4
      src/lib/mtproto/singleInstance.ts
  8. 4
      src/lib/mtproto/timeManager.ts
  9. 4
      src/lib/mtproto/transports/padded.ts
  10. 48
      src/vendor/leemon.ts

14
src/helpers/random.ts

@ -4,11 +4,17 @@ @@ -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);
}

4
src/lib/appManagers/appStateManager.ts

@ -22,7 +22,7 @@ import { Chat } from '../../layer'; @@ -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 = { @@ -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<keyof State>;

6
src/lib/crypto/crypto_utils.ts

@ -22,7 +22,7 @@ import {str2bigInt, bpe, equalsInt, greater, @@ -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] @@ -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);

4
src/lib/mtproto/apiFileManager.ts

@ -16,7 +16,7 @@ import { readBlobAsArrayBuffer } from "../../helpers/blob"; @@ -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 { @@ -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;

9
src/lib/mtproto/bin_utils.ts

@ -11,7 +11,6 @@ @@ -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<T extends number[] | ArrayBuffer | Uint8Array>( @@ -141,15 +140,13 @@ export function addPadding<T extends number[] | ArrayBuffer | Uint8Array>(
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<T extends number[] | ArrayBuffer | Uint8Array>( @@ -158,7 +155,7 @@ export function addPadding<T extends number[] | ArrayBuffer | Uint8Array>(
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;
}
}

6
src/lib/mtproto/networker.ts

@ -21,7 +21,7 @@ import { InvokeApiOptions } from '../../types'; @@ -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 { @@ -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 { @@ -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,

4
src/lib/mtproto/singleInstance.ts

@ -10,7 +10,7 @@ @@ -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 { @@ -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;

4
src/lib/mtproto/timeManager.ts

@ -11,7 +11,7 @@ @@ -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 { @@ -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] ||

4
src/lib/mtproto/transports/padded.ts

@ -4,7 +4,7 @@ @@ -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 { @@ -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);

48
src/vendor/leemon.ts vendored

@ -345,11 +345,11 @@ export function expand(x: number[], n: number): number[] { @@ -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[] { @@ -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[] { @@ -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[] { @@ -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[] { @@ -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[] { @@ -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<x.
@ -547,11 +543,11 @@ export function add(x: number[], y: number[]): number[] { @@ -547,11 +543,11 @@ export function add(x: number[], y: number[]): number[] {
* @param {number[]} n
* @returns {(number[] | null)}
*/
export function inverseMod(x: number[], n: number[]): number[] | null {
/* export function inverseMod(x: number[], n: number[]): number[] | null {
var ans = expand(x, n.length)
var s = inverseMod_(ans, n)
return s ? trim(ans, 1) : null
}
} */
/**
* return (x*y mod n) for bigInts x,y,n.
@ -580,7 +576,7 @@ export function multMod(x: number[], y: number[], n: number[]): number[] { @@ -580,7 +576,7 @@ export function multMod(x: number[], y: number[], n: number[]): number[] {
* @param {number} k
* @return {void}
*/
export function randTruePrime_(ans: number[], k: number): void {
/* export function randTruePrime_(ans: number[], k: number): void {
var c, m, pm, dd, j, r, B, divisible, z, zz, recSize
var w
if (primes.length == 0) primes = findPrimes(30000) //check for divisibility by primes <=30000
@ -712,7 +708,7 @@ export function randTruePrime_(ans: number[], k: number): void { @@ -712,7 +708,7 @@ export function randTruePrime_(ans: number[], k: number): void {
}
}
}
}
} */
/**
* Return an n-bit random BigInt (n>=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 { @@ -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[] { @@ -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 { @@ -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 { @@ -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 { @@ -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 { @@ -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:

Loading…
Cancel
Save