From 69c02168412bd973bda47c81cf021a8e97892036 Mon Sep 17 00:00:00 2001 From: Igor Zhukov Date: Thu, 23 Oct 2014 13:34:35 +0400 Subject: [PATCH] Improved overall binary performance --- app/js/lib/bin_utils.js | 39 +++++++++++++++++++++++++---------- app/js/lib/mtproto.js | 12 +++++++---- app/js/lib/mtproto_wrapper.js | 2 +- 3 files changed, 37 insertions(+), 16 deletions(-) diff --git a/app/js/lib/bin_utils.js b/app/js/lib/bin_utils.js index ecbfdfd4..2d7e0b9a 100644 --- a/app/js/lib/bin_utils.js +++ b/app/js/lib/bin_utils.js @@ -112,11 +112,13 @@ function bytesXor (bytes1, bytes2) { } function bytesToWords (bytes) { - var len = bytes.length, - words = []; - - for (var i = 0; i < len; i++) { - words[i >>> 2] |= bytes[i] << (24 - (i % 4) * 8); + var len = bytes.byteLength || bytes.length, + words = [], i; + if (bytes instanceof ArrayBuffer) { + bytes = new Uint8Array(bytes); + } + for (i = 0; i < len; i++) { + words[i >>> 2] |= bytes[i] << (24 - (i % 4) * 8); } return new CryptoJS.lib.WordArray.init(words, len); @@ -128,7 +130,7 @@ function bytesFromWords (wordArray) { bytes = []; for (var i = 0; i < sigBytes; i++) { - bytes.push((words[i >>> 2] >>> (24 - (i % 4) * 8)) & 0xff); + bytes.push((words[i >>> 2] >>> (24 - (i % 4) * 8)) & 0xff); } return bytes; @@ -154,13 +156,23 @@ function bytesToArrayBuffer (b) { return (new Uint8Array(b)).buffer; } +function bufferConcat(buffer1, buffer2) { + var l1 = buffer1.byteLength || buffer1.length, + l2 = buffer2.byteLength || buffer2.length; + var tmp = new Uint8Array(l1 + l2); + tmp.set(buffer1 instanceof ArrayBuffer ? new Uint8Array(buffer1) : buffer1, 0); + tmp.set(buffer2 instanceof ArrayBuffer ? new Uint8Array(buffer2) : buffer2, l1); + + return tmp.buffer; +} + function bytesFromArrayBuffer (buffer) { var len = buffer.byteLength, byteView = new Uint8Array(buffer), bytes = []; for (var i = 0; i < len; ++i) { - bytes[i] = byteView[i]; + bytes[i] = byteView[i]; } return bytes; @@ -228,14 +240,19 @@ function rsaEncrypt (publicKey, bytes) { } function aesEncrypt (bytes, keyBytes, ivBytes) { - // console.log('AES encrypt start', bytes.length/*, bytesToHex(keyBytes), bytesToHex(ivBytes)*/); + var len = bytes.byteLength || bytes.length; + console.log(dT(), 'AES encrypt start', len/*, bytesToHex(keyBytes), bytesToHex(ivBytes)*/); - var needPadding = 16 - (bytes.length % 16); + var needPadding = 16 - (len % 16); if (needPadding > 0 && needPadding < 16) { var padding = new Array(needPadding); (new SecureRandom()).nextBytes(padding); - bytes = bytes.concat(padding); + if (bytes instanceof ArrayBuffer) { + bytes = bufferConcat(bytes, padding); + } else { + bytes = bytes.concat(padding); + } } var encryptedWords = CryptoJS.AES.encrypt(bytesToWords(bytes), bytesToWords(keyBytes), { @@ -246,7 +263,7 @@ function aesEncrypt (bytes, keyBytes, ivBytes) { var encryptedBytes = bytesFromWords(encryptedWords); - // console.log('AES encrypt finish'); + console.log(dT(), 'AES encrypt finish'); return encryptedBytes; } diff --git a/app/js/lib/mtproto.js b/app/js/lib/mtproto.js index 880e32f3..a4e71e49 100644 --- a/app/js/lib/mtproto.js +++ b/app/js/lib/mtproto.js @@ -738,7 +738,7 @@ angular.module('izhukov.mtproto', ['izhukov.utils']) message = { msg_id: messageID, seq_no: seqNo, - body: serializer.getBytes(), + body: serializer.getBytes(true), isAPI: true }; @@ -954,7 +954,7 @@ angular.module('izhukov.mtproto', ['izhukov.utils']) if (!value || value >= currentTime) { if (message = self.sentMessages[messageID]) { messages.push(message); - messagesByteLen += message.body.length + 32; + messagesByteLen += (message.body.byteLength || message.body.length) + 32; if (message.isAPI) { hasApiCall = true; } @@ -1009,7 +1009,7 @@ angular.module('izhukov.mtproto', ['izhukov.utils']) inner: innerMessages } - message = angular.extend({body: container.getBytes()}, containerSentMessage); + message = angular.extend({body: container.getBytes(true)}, containerSentMessage); this.sentMessages[message.msg_id] = containerSentMessage; @@ -1076,10 +1076,14 @@ angular.module('izhukov.mtproto', ['izhukov.utils']) MtpNetworker.prototype.getEncryptedMessage = function (bytes) { var self = this; + console.log(dT(), 'Start encrypt', bytes.byteLength); return CryptoWorker.sha1Hash(bytes).then(function (bytesHash) { + console.log(dT(), 'after hash'); var msgKey = bytesHash.slice(-16); return self.getMsgKeyIv(msgKey, true).then(function (keyIv) { + console.log(dT(), 'after msg key iv'); return CryptoWorker.aesEncrypt(bytes, keyIv[0], keyIv[1]).then(function (encryptedBytes) { + console.log(dT(), 'Finish encrypt'); return { bytes: encryptedBytes, msgKey: msgKey @@ -1111,7 +1115,7 @@ angular.module('izhukov.mtproto', ['izhukov.utils']) data.storeInt(message.body.length, 'message_data_length'); data.storeRawBytes(message.body, 'message_data'); - return this.getEncryptedMessage(data.getBytes()).then(function (encryptedResult) { + return this.getEncryptedMessage(data.getBuffer()).then(function (encryptedResult) { // console.log(dT(), 'Got encrypted out message'/*, encryptedResult*/); var request = new TLSerialization({startMaxLength: encryptedResult.bytes.length + 256}); request.storeIntBytes(self.authKeyID, 64, 'auth_key_id'); diff --git a/app/js/lib/mtproto_wrapper.js b/app/js/lib/mtproto_wrapper.js index 2315b8dd..104e9f1e 100644 --- a/app/js/lib/mtproto_wrapper.js +++ b/app/js/lib/mtproto_wrapper.js @@ -558,7 +558,7 @@ angular.module('izhukov.mtproto.wrapper', ['izhukov.utils', 'izhukov.mtproto']) file_id: fileID, file_part: part, file_total_parts: totalParts, - bytes: bytesFromArrayBuffer(e.target.result) + bytes: e.target.result }, { startMaxLength: partSize + 256, fileUpload: true