Fix file download speed for 1 thread
This commit is contained in:
parent
7ee8e4b832
commit
c7b7427f19
@ -183,7 +183,7 @@ export class AppMessagesManager {
|
||||
|
||||
public loadSavedState() {
|
||||
if(this.loaded) return this.loaded;
|
||||
this.loaded = new Promise((resolve, reject) => {
|
||||
return this.loaded = new Promise((resolve, reject) => {
|
||||
AppStorage.get<{
|
||||
dialogs: Dialog[],
|
||||
allDialogsLoaded: AppMessagesManager['allDialogsLoaded'],
|
||||
|
@ -29,22 +29,22 @@ export class ApiFileManager {
|
||||
resolve: (...args: any[]) => void,
|
||||
reject: (...args: any[]) => void
|
||||
},
|
||||
activeDelta?: number
|
||||
activeDelta: number
|
||||
}>
|
||||
} = {};
|
||||
public downloadActives: {[dcID: string]: number} = {};
|
||||
|
||||
private log: ReturnType<typeof logger> = logger('AFM');
|
||||
|
||||
public downloadRequest(dcID: string | number, cb: () => Promise<unknown>, activeDelta?: number) {
|
||||
public downloadRequest(dcID: string | number, cb: () => Promise<unknown>, activeDelta: number) {
|
||||
if(this.downloadPulls[dcID] === undefined) {
|
||||
this.downloadPulls[dcID] = [];
|
||||
this.downloadActives[dcID] = 0;
|
||||
}
|
||||
|
||||
var downloadPull = this.downloadPulls[dcID];
|
||||
const downloadPull = this.downloadPulls[dcID];
|
||||
|
||||
let promise = new Promise((resolve, reject) => {
|
||||
const promise = new Promise((resolve, reject) => {
|
||||
downloadPull.push({cb: cb, deferred: {resolve, reject}, activeDelta: activeDelta});
|
||||
})/* .catch(() => {}) */;
|
||||
|
||||
@ -56,15 +56,16 @@ export class ApiFileManager {
|
||||
}
|
||||
|
||||
public downloadCheck(dcID: string | number) {
|
||||
var downloadPull = this.downloadPulls[dcID];
|
||||
var downloadLimit = dcID == 'upload' ? 11 : 5;
|
||||
const downloadPull = this.downloadPulls[dcID];
|
||||
//const downloadLimit = dcID == 'upload' ? 11 : 5;
|
||||
const downloadLimit = 24;
|
||||
|
||||
if(this.downloadActives[dcID] >= downloadLimit || !downloadPull || !downloadPull.length) {
|
||||
return false;
|
||||
}
|
||||
|
||||
var data = downloadPull.shift();
|
||||
var activeDelta = data.activeDelta || 1;
|
||||
const data = downloadPull.shift();
|
||||
const activeDelta = data.activeDelta || 1;
|
||||
|
||||
this.downloadActives[dcID] += activeDelta;
|
||||
|
||||
@ -122,8 +123,8 @@ export class ApiFileManager {
|
||||
}
|
||||
|
||||
public getTempFileName(file: any) {
|
||||
var size = file.size || -1;
|
||||
var random = nextRandomInt(0xFFFFFFFF);
|
||||
const size = file.size || -1;
|
||||
const random = nextRandomInt(0xFFFFFFFF);
|
||||
return '_temp' + random + '_' + size;
|
||||
}
|
||||
|
||||
@ -131,12 +132,12 @@ export class ApiFileManager {
|
||||
if(!location) {
|
||||
return false;
|
||||
}
|
||||
var fileName = this.getFileName(location);
|
||||
const fileName = this.getFileName(location);
|
||||
|
||||
return this.cachedDownloads[fileName] || false;
|
||||
}
|
||||
|
||||
public getFileStorage(): typeof cacheStorage {
|
||||
public getFileStorage() {
|
||||
return cacheStorage;
|
||||
}
|
||||
|
||||
@ -419,7 +420,7 @@ export class ApiFileManager {
|
||||
fileDownload: true/* ,
|
||||
singleInRequest: 'safari' in window */
|
||||
});
|
||||
}, dcID).then((result: any) => {
|
||||
}, 2).then((result: any) => {
|
||||
writeFilePromise.then(() => {
|
||||
if(canceled) {
|
||||
return Promise.resolve();
|
||||
|
@ -13,6 +13,7 @@ import passwordManager from './passwordManager';
|
||||
|
||||
/// #if !MTPROTO_WORKER
|
||||
import { $rootScope } from '../utils';
|
||||
import { InvokeApiOptions } from '../../types';
|
||||
/// #endif
|
||||
|
||||
//console.error('apiManager included!');
|
||||
@ -133,10 +134,10 @@ export class ApiManager {
|
||||
}
|
||||
|
||||
// mtpGetNetworker
|
||||
public async getNetworker(dcID: number, options: any = {}): Promise<MTPNetworker> {
|
||||
let upload = (options.fileUpload || options.fileDownload)
|
||||
public async getNetworker(dcID: number, options: InvokeApiOptions): Promise<MTPNetworker> {
|
||||
const upload = (options.fileUpload || options.fileDownload)
|
||||
&& (dcConfigurator.chooseServer(dcID, true) instanceof HTTP || Modes.multipleConnections);
|
||||
let cache = upload ? this.cachedUploadNetworkers : this.cachedNetworkers;
|
||||
const cache = upload ? this.cachedUploadNetworkers : this.cachedNetworkers;
|
||||
|
||||
if(!dcID) {
|
||||
throw new Error('get Networker without dcID');
|
||||
@ -146,72 +147,61 @@ export class ApiManager {
|
||||
return cache[dcID];
|
||||
}
|
||||
|
||||
let getKey = dcID + '-' + +upload;
|
||||
const getKey = dcID + '-' + +upload;
|
||||
if(this.gettingNetworkers[getKey]) {
|
||||
return this.gettingNetworkers[getKey];
|
||||
}
|
||||
|
||||
const ak = 'dc' + dcID + '_auth_key';
|
||||
const akID = 'dc' + dcID + '_auth_keyID';
|
||||
const ss = 'dc' + dcID + '_server_salt';
|
||||
|
||||
return this.gettingNetworkers[getKey] = new Promise(async(resolve, reject) => {
|
||||
var ak = 'dc' + dcID + '_auth_key';
|
||||
var akID = 'dc' + dcID + '_auth_keyID';
|
||||
var ss = 'dc' + dcID + '_server_salt';
|
||||
|
||||
let result = await AppStorage.get<string[]/* |boolean[] */>([ak, akID, ss]);
|
||||
|
||||
let [authKeyHex, authKeyIDHex, serverSaltHex] = result;
|
||||
if(authKeyHex && !authKeyIDHex && serverSaltHex) {
|
||||
return this.gettingNetworkers[getKey] = AppStorage.get<string[]/* |boolean[] */>([ak, akID, ss])
|
||||
.then(async([authKeyHex, authKeyIDHex, serverSaltHex]) => {
|
||||
/* if(authKeyHex && !authKeyIDHex && serverSaltHex) {
|
||||
this.log.warn('Updating to new version (+akID)');
|
||||
await AppStorage.remove(ak, akID, ss);
|
||||
authKeyHex = serverSaltHex = '';
|
||||
}
|
||||
} */
|
||||
|
||||
let networker: MTPNetworker;
|
||||
if(authKeyHex && authKeyHex.length == 512) {
|
||||
if(!serverSaltHex || serverSaltHex.length != 16) {
|
||||
serverSaltHex = 'AAAAAAAAAAAAAAAA';
|
||||
}
|
||||
|
||||
var authKey = bytesFromHex(authKeyHex);
|
||||
var authKeyID = new Uint8Array(bytesFromHex(authKeyIDHex));
|
||||
var serverSalt = bytesFromHex(serverSaltHex);
|
||||
const authKey = bytesFromHex(authKeyHex);
|
||||
const authKeyID = new Uint8Array(bytesFromHex(authKeyIDHex));
|
||||
const serverSalt = bytesFromHex(serverSaltHex);
|
||||
|
||||
resolve(cache[dcID] = networkerFactory.getNetworker(dcID, authKey, authKeyID, serverSalt, options));
|
||||
} else try {
|
||||
let auth = await authorizer.auth(dcID);
|
||||
|
||||
let storeObj = {
|
||||
[ak]: bytesToHex(auth.authKey),
|
||||
[akID]: auth.authKeyID.hex,
|
||||
[ss]: bytesToHex(auth.serverSalt)
|
||||
};
|
||||
|
||||
AppStorage.set(storeObj);
|
||||
|
||||
resolve(cache[dcID] = networkerFactory.getNetworker(dcID, auth.authKey, auth.authKeyID, auth.serverSalt, options));
|
||||
} catch(error) {
|
||||
this.log('Get networker error', error, error.stack);
|
||||
reject(error);
|
||||
networker = networkerFactory.getNetworker(dcID, authKey, authKeyID, serverSalt, options);
|
||||
} else {
|
||||
try { // if no saved state
|
||||
const auth = await authorizer.auth(dcID);
|
||||
|
||||
const storeObj = {
|
||||
[ak]: bytesToHex(auth.authKey),
|
||||
[akID]: auth.authKeyID.hex,
|
||||
[ss]: bytesToHex(auth.serverSalt)
|
||||
};
|
||||
|
||||
AppStorage.set(storeObj);
|
||||
|
||||
networker = networkerFactory.getNetworker(dcID, auth.authKey, auth.authKeyID, auth.serverSalt, options);
|
||||
} catch(error) {
|
||||
this.log('Get networker error', error, error.stack);
|
||||
delete this.gettingNetworkers[getKey];
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
delete this.gettingNetworkers[getKey];
|
||||
return cache[dcID] = networker;
|
||||
});
|
||||
}
|
||||
|
||||
// mtpInvokeApi
|
||||
public invokeApi(method: string, params: any = {}, options: Partial<{
|
||||
dcID: number,
|
||||
timeout: number,
|
||||
noErrorBox: boolean,
|
||||
fileUpload: boolean,
|
||||
ignoreErrors: boolean,
|
||||
fileDownload: boolean,
|
||||
createNetworker: boolean,
|
||||
singleInRequest: boolean,
|
||||
startMaxLength: number,
|
||||
|
||||
waitTime: number,
|
||||
stopTime: number,
|
||||
rawError: any
|
||||
}> = {}) {
|
||||
public invokeApi(method: string, params: any = {}, options: InvokeApiOptions = {}) {
|
||||
///////this.log('Invoke api', method, params, options);
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
@ -343,7 +333,6 @@ export class ApiManager {
|
||||
public checkPassword(value: string): Promise<any> {
|
||||
return passwordManager.getState()
|
||||
.then(state => {
|
||||
console.log(state);
|
||||
return passwordManager.check(state, value);
|
||||
});
|
||||
}
|
||||
|
@ -3,19 +3,11 @@ import MTTransport from './transports/transport';
|
||||
import HTTP from './transports/http';
|
||||
import { Modes } from './mtproto_config';
|
||||
|
||||
type TransportTypes = 'websocket' | 'https' | 'http';
|
||||
type Servers = {
|
||||
[transport: string]: {
|
||||
[dcID: number]: MTTransport
|
||||
[transportType in TransportTypes]: {
|
||||
[dcID: number]: MTTransport[]
|
||||
}
|
||||
/* websocket: {
|
||||
[dcID: number]: Socket
|
||||
},
|
||||
https: {
|
||||
[dcID: number]: HTTPTransport
|
||||
},
|
||||
http: {
|
||||
[dcID: number]: HTTPTransport
|
||||
} */
|
||||
};
|
||||
|
||||
export class DcConfigurator {
|
||||
@ -47,41 +39,50 @@ export class DcConfigurator {
|
||||
http: {}
|
||||
};
|
||||
|
||||
public chooseServer(dcID: number, upload?: boolean, transport = 'websocket') {
|
||||
let servers = upload && (transport != 'websocket' || Modes.multipleConnections)
|
||||
? this.chosenUploadServers[transport]
|
||||
: this.chosenServers[transport];
|
||||
public chooseServer(dcID: number, upload?: boolean, transportType: TransportTypes = 'websocket') {
|
||||
const servers = upload && (transportType != 'websocket' || Modes.multipleConnections)
|
||||
? this.chosenUploadServers[transportType]
|
||||
: this.chosenServers[transportType];
|
||||
|
||||
if(!(dcID in servers)) {
|
||||
let chosenServer = '';
|
||||
servers[dcID] = [];
|
||||
}
|
||||
|
||||
if(transport == 'websocket') {
|
||||
let subdomain = this.sslSubdomains[dcID - 1];
|
||||
let path = Modes.test ? 'apiws_test' : 'apiws';
|
||||
chosenServer = 'wss://' + subdomain + '.web.telegram.org/' + path;
|
||||
return servers[dcID] = new Socket(dcID, chosenServer);
|
||||
}
|
||||
|
||||
if(Modes.ssl || !Modes.http || transport == 'https') {
|
||||
let subdomain = this.sslSubdomains[dcID - 1] + (upload ? '-1' : '');
|
||||
let path = Modes.test ? 'apiw_test1' : 'apiw1';
|
||||
chosenServer = 'https://' + subdomain + '.web.telegram.org/' + path;
|
||||
return servers[dcID] = new HTTP(dcID, chosenServer);
|
||||
}
|
||||
|
||||
for(let dcOption of this.dcOptions) {
|
||||
if(dcOption.id == dcID) {
|
||||
chosenServer = 'http://' + dcOption.host + (dcOption.port != 80 ? ':' + dcOption.port : '') + '/apiw1';
|
||||
return servers[dcID] = new HTTP(dcID, chosenServer);
|
||||
const transports = servers[dcID];
|
||||
|
||||
if(!transports.length || (upload && transports.length < 1)) {
|
||||
let transport: MTTransport;
|
||||
|
||||
if(transportType == 'websocket') {
|
||||
const subdomain = this.sslSubdomains[dcID - 1];
|
||||
const path = Modes.test ? 'apiws_test' : 'apiws';
|
||||
const chosenServer = 'wss://' + subdomain + '.web.telegram.org/' + path;
|
||||
transport = new Socket(dcID, chosenServer);
|
||||
} else if(Modes.ssl || !Modes.http || transportType == 'https') {
|
||||
const subdomain = this.sslSubdomains[dcID - 1] + (upload ? '-1' : '');
|
||||
const path = Modes.test ? 'apiw_test1' : 'apiw1';
|
||||
const chosenServer = 'https://' + subdomain + '.web.telegram.org/' + path;
|
||||
transport = new HTTP(dcID, chosenServer);
|
||||
} else {
|
||||
for(let dcOption of this.dcOptions) {
|
||||
if(dcOption.id == dcID) {
|
||||
const chosenServer = 'http://' + dcOption.host + (dcOption.port != 80 ? ':' + dcOption.port : '') + '/apiw1';
|
||||
transport = new HTTP(dcID, chosenServer);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
console.error('No chosenServer!', dcID);
|
||||
|
||||
return null;
|
||||
|
||||
if(!transport) {
|
||||
console.error('No chosenServer!', dcID);
|
||||
return null;
|
||||
}
|
||||
|
||||
transports.push(transport);
|
||||
return transport;
|
||||
}
|
||||
|
||||
return servers[dcID];
|
||||
return transports[0];
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -14,6 +14,7 @@ import Socket from './transports/websocket';
|
||||
import HTTP from './transports/http';
|
||||
import { logger } from '../polyfill';
|
||||
import { Modes, App } from './mtproto_config';
|
||||
import { InvokeApiOptions } from '../../types';
|
||||
|
||||
//console.error('networker included!', new Error().stack);
|
||||
|
||||
@ -90,14 +91,12 @@ class MTPNetworker {
|
||||
private log: ReturnType<typeof logger>;
|
||||
|
||||
constructor(private dcID: number, private authKey: number[], private authKeyID: Uint8Array,
|
||||
private serverSalt: number[], private options: any = {}) {
|
||||
private serverSalt: number[], private options: InvokeApiOptions = {}) {
|
||||
this.authKeyUint8 = convertToUint8Array(this.authKey);
|
||||
//this.authKeyID = sha1BytesSync(this.authKey).slice(-8);
|
||||
|
||||
this.upload = this.options.fileUpload || this.options.fileDownload || false;
|
||||
|
||||
this.log = logger('NET-' + dcID + (this.upload ? '-U' : ''));
|
||||
|
||||
this.log('constructor'/* , this.authKey, this.authKeyID, this.serverSalt */);
|
||||
|
||||
this.updateSession();
|
||||
@ -111,7 +110,7 @@ class MTPNetworker {
|
||||
this.transport = dcConfigurator.chooseServer(this.dcID, this.upload);
|
||||
|
||||
if(this.transport instanceof HTTP) {
|
||||
/* this.longPollInt = */window.setInterval(this.checkLongPoll.bind(this), 10000);
|
||||
/* this.longPollInt = */setInterval(this.checkLongPoll.bind(this), 10000);
|
||||
this.checkLongPoll();
|
||||
} else {
|
||||
(this.transport as Socket).networker = this;
|
||||
@ -204,24 +203,7 @@ class MTPNetworker {
|
||||
return this.pushMessage(message, options);
|
||||
}
|
||||
|
||||
public wrapApiCall(method: string, params: any = {}, options: {
|
||||
dcID?: number,
|
||||
timeout?: number,
|
||||
noErrorBox?: boolean,
|
||||
fileUpload?: boolean,
|
||||
ignoreErrors?: boolean,
|
||||
fileDownload?: boolean,
|
||||
createNetworker?: boolean,
|
||||
singleInRequest?: boolean,
|
||||
startMaxLength?: number,
|
||||
|
||||
afterMessageID?: string,
|
||||
resultType?: boolean,
|
||||
|
||||
waitTime?: number,
|
||||
stopTime?: number,
|
||||
rawError?: any
|
||||
} = {}) {
|
||||
public wrapApiCall(method: string, params: any = {}, options: InvokeApiOptions = {}) {
|
||||
let serializer = new TLSerialization(options);
|
||||
|
||||
if(!this.connectionInited) { // this will call once for each new session
|
||||
@ -293,7 +275,7 @@ class MTPNetworker {
|
||||
}
|
||||
|
||||
public checkLongPoll() {
|
||||
var isClean = this.cleanupSent();
|
||||
const isClean = this.cleanupSent();
|
||||
//this.log('Check lp', this.longPollPending, tsNow(), this.dcID, isClean, this);
|
||||
if((this.longPollPending && Date.now() < this.longPollPending) ||
|
||||
this.offline) {
|
||||
@ -301,18 +283,17 @@ class MTPNetworker {
|
||||
return false;
|
||||
}
|
||||
|
||||
var self = this;
|
||||
AppStorage.get<number>('dc').then((baseDcID: number) => {
|
||||
if(isClean && (
|
||||
baseDcID != self.dcID ||
|
||||
self.upload ||
|
||||
(self.sleepAfter && Date.now() > self.sleepAfter)
|
||||
baseDcID != this.dcID ||
|
||||
this.upload ||
|
||||
(this.sleepAfter && Date.now() > this.sleepAfter)
|
||||
)) {
|
||||
//console.warn(dT(), 'Send long-poll for DC is delayed', self.dcID, self.sleepAfter);
|
||||
//console.warn(dT(), 'Send long-poll for DC is delayed', this.dcID, this.sleepAfter);
|
||||
return;
|
||||
}
|
||||
|
||||
self.sendLongPoll();
|
||||
this.sendLongPoll();
|
||||
});
|
||||
}
|
||||
|
||||
@ -963,7 +944,7 @@ class MTPNetworker {
|
||||
clearTimeout(this.nextReqTimeout);
|
||||
this.nextReqTimeout = 0;
|
||||
if(delay > 0) {
|
||||
this.nextReqTimeout = window.setTimeout(this.performScheduledRequest.bind(this), delay || 0);
|
||||
this.nextReqTimeout = setTimeout(this.performScheduledRequest.bind(this), delay || 0);
|
||||
} else {
|
||||
setTimeout(this.performScheduledRequest.bind(this), 0);
|
||||
}
|
||||
@ -984,26 +965,25 @@ class MTPNetworker {
|
||||
}
|
||||
|
||||
public cleanupSent() {
|
||||
var self = this;
|
||||
var notEmpty = false;
|
||||
let notEmpty = false;
|
||||
// this.log('clean start', this.dcID/*, this.sentMessages*/)
|
||||
Object.keys(this.sentMessages).forEach((msgID) => {
|
||||
let message = this.sentMessages[msgID];
|
||||
const message = this.sentMessages[msgID];
|
||||
|
||||
// this.log('clean iter', msgID, message)
|
||||
if(message.notContentRelated && self.pendingMessages[msgID] === undefined) {
|
||||
if(message.notContentRelated && this.pendingMessages[msgID] === undefined) {
|
||||
// this.log('clean notContentRelated', msgID)
|
||||
delete self.sentMessages[msgID];
|
||||
delete this.sentMessages[msgID];
|
||||
} else if(message.container) {
|
||||
for(var i = 0; i < message.inner.length; i++) {
|
||||
if(self.sentMessages[message.inner[i]] !== undefined) {
|
||||
// this.log('clean failed, found', msgID, message.inner[i], self.sentMessages[message.inner[i]].seq_no)
|
||||
for(let i = 0; i < message.inner.length; i++) {
|
||||
if(this.sentMessages[message.inner[i]] !== undefined) {
|
||||
// this.log('clean failed, found', msgID, message.inner[i], this.sentMessages[message.inner[i]].seq_no)
|
||||
notEmpty = true;
|
||||
return;
|
||||
}
|
||||
}
|
||||
// this.log('clean container', msgID)
|
||||
delete self.sentMessages[msgID];
|
||||
delete this.sentMessages[msgID];
|
||||
} else {
|
||||
notEmpty = true;
|
||||
}
|
||||
|
@ -1,4 +1,5 @@
|
||||
import { MTPNetworker } from "./networker";
|
||||
import { InvokeApiOptions } from "../../types";
|
||||
|
||||
export class NetworkerFactory {
|
||||
public updatesProcessor: (obj: any, bool: boolean) => void = null;
|
||||
@ -7,8 +8,8 @@ export class NetworkerFactory {
|
||||
this.updatesProcessor = callback;
|
||||
}
|
||||
|
||||
public getNetworker(dcID: number, authKey: number[], authKeyID: Uint8Array, serverSalt: number[], options: any) {
|
||||
//console.log(dT(), 'NetworkerFactory: creating new instance of MTPNetworker:', dcID, options);
|
||||
public getNetworker(dcID: number, authKey: number[], authKeyID: Uint8Array, serverSalt: number[], options: InvokeApiOptions) {
|
||||
//console.log('NetworkerFactory: creating new instance of MTPNetworker:', dcID, options);
|
||||
return new MTPNetworker(dcID, authKey, authKeyID, serverSalt, options);
|
||||
}
|
||||
}
|
||||
|
@ -6,6 +6,8 @@ import {str2bigInt, greater, isZero,
|
||||
bigInt2str, powMod, int2bigInt, mult, mod, sub, bitSize, negative, mult, add} from 'leemon/es/index/';
|
||||
|
||||
export class PasswordManager {
|
||||
private log = (...args: any[]) => {};
|
||||
|
||||
public getState(options: any = {}) {
|
||||
return apiManager.invokeApi('account.getPassword', {}, options).then((result) => {
|
||||
return result
|
||||
@ -89,19 +91,19 @@ export class PasswordManager {
|
||||
let buffer = bufferConcats(client_salt, passwordBuffer, client_salt);
|
||||
|
||||
return CryptoWorker.sha256Hash(buffer).then((buffer: any) => {
|
||||
console.log('encoded 1', bytesToHex(new Uint8Array(buffer)));
|
||||
this.log('encoded 1', bytesToHex(new Uint8Array(buffer)));
|
||||
|
||||
buffer = bufferConcats(server_salt, buffer, server_salt);
|
||||
return CryptoWorker.sha256Hash(buffer).then((buffer: any) => {
|
||||
|
||||
console.log('encoded 2', buffer, bytesToHex(new Uint8Array(buffer)));
|
||||
this.log('encoded 2', buffer, bytesToHex(new Uint8Array(buffer)));
|
||||
|
||||
return CryptoWorker.pbkdf2(new Uint8Array(buffer), client_salt, 100000).then((hash: any) => {
|
||||
console.log('encoded 3', hash, bytesToHex(new Uint8Array(hash)));
|
||||
this.log('encoded 3', hash, bytesToHex(new Uint8Array(hash)));
|
||||
|
||||
hash = bufferConcats(server_salt, hash, server_salt);
|
||||
return CryptoWorker.sha256Hash(hash).then((buffer: any) => {
|
||||
console.log('got password hash:', buffer, bytesToHex(new Uint8Array(buffer)));
|
||||
this.log('got password hash:', buffer, bytesToHex(new Uint8Array(buffer)));
|
||||
|
||||
return buffer;
|
||||
});
|
||||
@ -117,8 +119,8 @@ export class PasswordManager {
|
||||
let B = str2bigInt(bytesToHex(state.srp_B), 16);
|
||||
let g = int2bigInt(algo.g, 32, 256);
|
||||
|
||||
console.log('p', bigInt2str(p, 16));
|
||||
console.log('B', bigInt2str(B, 16));
|
||||
this.log('p', bigInt2str(p, 16));
|
||||
this.log('B', bigInt2str(B, 16));
|
||||
|
||||
/* if(B.compareTo(BigInteger.ZERO) < 0) {
|
||||
console.error('srp_B < 0')
|
||||
@ -144,7 +146,7 @@ export class PasswordManager {
|
||||
new Uint8Array(algo.salt2)) as ArrayBuffer;
|
||||
let x = str2bigInt(bytesToHex(new Uint8Array(pw_hash)), 16);
|
||||
|
||||
console.warn('computed pw_hash:', pw_hash, x, bytesToHex(new Uint8Array(pw_hash)));
|
||||
this.log('computed pw_hash:', pw_hash, x, bytesToHex(new Uint8Array(pw_hash)));
|
||||
|
||||
|
||||
var padArray = function(arr: any[], len: number, fill = 0) {
|
||||
@ -155,25 +157,25 @@ export class PasswordManager {
|
||||
let gForHash = padArray(bytesFromHex(bigInt2str(g, 16)), 256); // like uint8array
|
||||
let b_for_hash = padArray(bytesFromHex(bigInt2str(B, 16)), 256);
|
||||
|
||||
console.log(bytesToHex(pForHash));
|
||||
console.log(bytesToHex(gForHash));
|
||||
console.log(bytesToHex(b_for_hash));
|
||||
this.log(bytesToHex(pForHash));
|
||||
this.log(bytesToHex(gForHash));
|
||||
this.log(bytesToHex(b_for_hash));
|
||||
|
||||
let g_x = powMod(g, x, p);
|
||||
|
||||
console.log('g_x', bigInt2str(g_x, 16));
|
||||
this.log('g_x', bigInt2str(g_x, 16));
|
||||
|
||||
let k: any = await CryptoWorker.sha256Hash(bufferConcat(pForHash, gForHash));
|
||||
k = str2bigInt(bytesToHex(new Uint8Array(k)), 16);
|
||||
|
||||
console.log('k', bigInt2str(k, 16));
|
||||
this.log('k', bigInt2str(k, 16));
|
||||
|
||||
// kg_x = (k * g_x) % p
|
||||
let kg_x = mod(mult(k, g_x), p);
|
||||
|
||||
// good
|
||||
|
||||
console.log('kg_x', bigInt2str(kg_x, 16));
|
||||
this.log('kg_x', bigInt2str(kg_x, 16));
|
||||
|
||||
let is_good_mod_exp_first = (modexp: any, prime: any) => {
|
||||
let diff = sub(prime, modexp);
|
||||
@ -217,12 +219,12 @@ export class PasswordManager {
|
||||
|
||||
let {a, a_for_hash, u} = await generate_and_check_random();
|
||||
|
||||
console.log('a', bigInt2str(a, 16));
|
||||
console.log('a_for_hash', bytesToHex(a_for_hash));
|
||||
console.log('u', bigInt2str(u, 16));
|
||||
this.log('a', bigInt2str(a, 16));
|
||||
this.log('a_for_hash', bytesToHex(a_for_hash));
|
||||
this.log('u', bigInt2str(u, 16));
|
||||
|
||||
// g_b = (B - kg_x) % p
|
||||
console.log('B - kg_x', bigInt2str(sub(B, kg_x), 16));
|
||||
this.log('B - kg_x', bigInt2str(sub(B, kg_x), 16));
|
||||
//let g_b = mod(sub(B, kg_x), p);
|
||||
/* let g_b = sub(B, kg_x);
|
||||
if(negative(g_b)) g_b = add(g_b, p);
|
||||
@ -231,15 +233,15 @@ export class PasswordManager {
|
||||
if(!negative(sub(B, kg_x))) g_b = sub(mod(B, p), kg_x);
|
||||
else g_b = mod(sub(B, kg_x), p); */
|
||||
/* let lol = trim(sub(B, kg_x), 10);
|
||||
console.log('llalala', bigInt2str(lol, 16)); */
|
||||
this.log('llalala', bigInt2str(lol, 16)); */
|
||||
let g_b;
|
||||
if(!greater(B, kg_x)) {
|
||||
console.log('negative');
|
||||
this.log('negative');
|
||||
g_b = add(B, p);
|
||||
} else g_b = B;
|
||||
g_b = mod(sub(g_b, kg_x), p);
|
||||
//g_b = mod(g_b, p);
|
||||
//console.log('g_b', bigInt2str(g_b, 16));
|
||||
//this.log('g_b', bigInt2str(g_b, 16));
|
||||
|
||||
/* if(!is_good_mod_exp_first(g_b, p))
|
||||
throw new Error('bad g_b'); */
|
||||
@ -277,7 +279,7 @@ export class PasswordManager {
|
||||
};
|
||||
|
||||
|
||||
console.log('out', bytesToHex(out.A), bytesToHex(out.M1));
|
||||
this.log('out', bytesToHex(out.A), bytesToHex(out.M1));
|
||||
return out;
|
||||
|
||||
/* console.log(gForHash, pForHash, bForHash); */
|
||||
|
21
src/types.d.ts
vendored
21
src/types.d.ts
vendored
@ -42,4 +42,23 @@ export type MTPhotoSize = {
|
||||
type?: string, // i, m, x, y, w by asc
|
||||
location?: any,
|
||||
bytes?: Uint8Array // if type == 'i'
|
||||
};
|
||||
};
|
||||
|
||||
export type InvokeApiOptions = Partial<{
|
||||
dcID: number,
|
||||
timeout: number,
|
||||
noErrorBox: boolean,
|
||||
fileUpload: boolean,
|
||||
ignoreErrors: boolean,
|
||||
fileDownload: boolean,
|
||||
createNetworker: boolean,
|
||||
singleInRequest: boolean,
|
||||
startMaxLength: number,
|
||||
|
||||
afterMessageID: string,
|
||||
resultType: boolean,
|
||||
|
||||
waitTime: number,
|
||||
stopTime: number,
|
||||
rawError: any
|
||||
}>;
|
Loading…
x
Reference in New Issue
Block a user