From 254b6621c2e03b7edeb99d0a5308ee9fa0520ac4 Mon Sep 17 00:00:00 2001 From: lilia Date: Wed, 24 Aug 2016 01:50:20 -0700 Subject: [PATCH] Update libsignal-protocol v1.1.5 // FREEBIE --- js/libtextsecure.js | 76 +++++++++++++++++++++++++++++ libtextsecure/libsignal-protocol.js | 76 +++++++++++++++++++++++++++++ 2 files changed, 152 insertions(+) diff --git a/js/libtextsecure.js b/js/libtextsecure.js index 03b83bab..3e5a033f 100644 --- a/js/libtextsecure.js +++ b/js/libtextsecure.js @@ -35369,6 +35369,10 @@ var Internal = Internal || {}; }); }, + hash: function(data) { + return crypto.subtle.digest({name: 'SHA-512'}, data); + }, + HKDF: function(input, salt, info) { // Specific implementation of RFC 5869 that only returns the first 3 32-byte chunks // TODO: We dont always need the third chunk, we might skip it @@ -36555,6 +36559,78 @@ Internal.SessionLock.queueJobForNumber = function queueJobForNumber(number, runJ })(); +(function() { + var VERSION = 0; + + function iterateHash(data, key, count) { + data = dcodeIO.ByteBuffer.concat([data, key]).toArrayBuffer(); + return Internal.crypto.hash(data).then(function(result) { + if (--count === 0) { + return result; + } else { + return iterateHash(result, key, count); + } + }); + } + + function shortToArrayBuffer(number) { + return new Uint16Array([number]).buffer; + } + + function getEncodedChunk(hash, offset) { + var chunk = ( hash[offset] * Math.pow(2,32) + + hash[offset+1] * Math.pow(2,24) + + hash[offset+2] * Math.pow(2,16) + + hash[offset+3] * Math.pow(2,8) + + hash[offset+4] ) % 100000; + var s = chunk.toString(); + while (s.length < 5) { + s = '0' + s; + } + return s; + } + + function getDisplayStringFor(identifier, key, iterations) { + var bytes = dcodeIO.ByteBuffer.concat([ + shortToArrayBuffer(VERSION), key, identifier + ]).toArrayBuffer(); + return iterateHash(bytes, key, iterations).then(function(output) { + output = new Uint8Array(output); + return getEncodedChunk(output, 0) + + getEncodedChunk(output, 5) + + getEncodedChunk(output, 10) + + getEncodedChunk(output, 15) + + getEncodedChunk(output, 20) + + getEncodedChunk(output, 25); + }); + } + + libsignal.FingerprintGenerator = function(iterations) { + this.iterations = iterations; + }; + libsignal.FingerprintGenerator.prototype = { + createFor: function(localIdentifier, localIdentityKey, + remoteIdentifier, remoteIdentityKey) { + if (typeof localIdentifier !== 'string' || + typeof remoteIdentifier !== 'string' || + !(localIdentityKey instanceof ArrayBuffer) || + !(remoteIdentityKey instanceof ArrayBuffer)) { + + throw new Error('Invalid arguments'); + } + + return Promise.all([ + getDisplayStringFor(localIdentifier, localIdentityKey, this.iterations), + getDisplayStringFor(remoteIdentifier, remoteIdentityKey, this.iterations) + ]).then(function(fingerprints) { + return fingerprints.sort().join(''); + }); + } + }; + +})(); + + })(); /* * vim: ts=4:sw=4:expandtab diff --git a/libtextsecure/libsignal-protocol.js b/libtextsecure/libsignal-protocol.js index 4671f7ca..2541f176 100644 --- a/libtextsecure/libsignal-protocol.js +++ b/libtextsecure/libsignal-protocol.js @@ -35245,6 +35245,10 @@ var Internal = Internal || {}; }); }, + hash: function(data) { + return crypto.subtle.digest({name: 'SHA-512'}, data); + }, + HKDF: function(input, salt, info) { // Specific implementation of RFC 5869 that only returns the first 3 32-byte chunks // TODO: We dont always need the third chunk, we might skip it @@ -36431,4 +36435,76 @@ Internal.SessionLock.queueJobForNumber = function queueJobForNumber(number, runJ })(); +(function() { + var VERSION = 0; + + function iterateHash(data, key, count) { + data = dcodeIO.ByteBuffer.concat([data, key]).toArrayBuffer(); + return Internal.crypto.hash(data).then(function(result) { + if (--count === 0) { + return result; + } else { + return iterateHash(result, key, count); + } + }); + } + + function shortToArrayBuffer(number) { + return new Uint16Array([number]).buffer; + } + + function getEncodedChunk(hash, offset) { + var chunk = ( hash[offset] * Math.pow(2,32) + + hash[offset+1] * Math.pow(2,24) + + hash[offset+2] * Math.pow(2,16) + + hash[offset+3] * Math.pow(2,8) + + hash[offset+4] ) % 100000; + var s = chunk.toString(); + while (s.length < 5) { + s = '0' + s; + } + return s; + } + + function getDisplayStringFor(identifier, key, iterations) { + var bytes = dcodeIO.ByteBuffer.concat([ + shortToArrayBuffer(VERSION), key, identifier + ]).toArrayBuffer(); + return iterateHash(bytes, key, iterations).then(function(output) { + output = new Uint8Array(output); + return getEncodedChunk(output, 0) + + getEncodedChunk(output, 5) + + getEncodedChunk(output, 10) + + getEncodedChunk(output, 15) + + getEncodedChunk(output, 20) + + getEncodedChunk(output, 25); + }); + } + + libsignal.FingerprintGenerator = function(iterations) { + this.iterations = iterations; + }; + libsignal.FingerprintGenerator.prototype = { + createFor: function(localIdentifier, localIdentityKey, + remoteIdentifier, remoteIdentityKey) { + if (typeof localIdentifier !== 'string' || + typeof remoteIdentifier !== 'string' || + !(localIdentityKey instanceof ArrayBuffer) || + !(remoteIdentityKey instanceof ArrayBuffer)) { + + throw new Error('Invalid arguments'); + } + + return Promise.all([ + getDisplayStringFor(localIdentifier, localIdentityKey, this.iterations), + getDisplayStringFor(remoteIdentifier, remoteIdentityKey, this.iterations) + ]).then(function(fingerprints) { + return fingerprints.sort().join(''); + }); + } + }; + +})(); + + })(); \ No newline at end of file