Comparing version 0.7.6 to 0.7.7
{ | ||
"name": "rusha", | ||
"version": "0.7.6", | ||
"version": "0.7.7", | ||
"description": "A high-performance pure-javascript SHA1 implementation suitable for large binary data.", | ||
@@ -21,3 +21,4 @@ "main": "rusha.js", | ||
"mocha": "~1.15.0", | ||
"jsmin": "~1.0" | ||
"jsmin": "~1.0", | ||
"sweet.js": "~0.7.1" | ||
}, | ||
@@ -24,0 +25,0 @@ "author": "Sam Rijs", |
629
rusha.js
@@ -1,295 +0,340 @@ | ||
/* | ||
* Rusha, a JavaScript implementation of the Secure Hash Algorithm, SHA-1, | ||
* as defined in FIPS PUB 180-1, tuned for high performance with large inputs. | ||
* (http://github.com/srijs/rusha) | ||
* | ||
* Inspired by Paul Johnstons implementation (http://pajhome.org.uk/crypt/md5). | ||
* | ||
* Copyright (c) 2013 Sam Rijs (http://awesam.de). | ||
* Released under the terms of the MIT license as follows: | ||
* | ||
* Permission is hereby granted, free of charge, to any person obtaining a | ||
* copy of this software and associated documentation files (the "Software"), | ||
* to deal in the Software without restriction, including without limitation | ||
* the rights to use, copy, modify, merge, publish, distribute, sublicense, | ||
* and/or sell copies of the Software, and to permit persons to whom the | ||
* Software is furnished to do so, subject to the following conditions: | ||
* | ||
* The above copyright notice and this permission notice shall be included in | ||
* all copies or substantial portions of the Software. | ||
* | ||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | ||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS | ||
* IN THE SOFTWARE. | ||
*/ | ||
(function () { | ||
// If we'e running in Node.JS, export a module. | ||
if (typeof module !== 'undefined') { | ||
module.exports = Rusha; | ||
} | ||
// If we're running in a DOM context, export | ||
// the Rusha object to toplevel. | ||
if (typeof window !== 'undefined') { | ||
window.Rusha = Rusha; | ||
} | ||
// If we're running in a webworker, accept | ||
// messages containing a jobid and a buffer | ||
// or blob object, and return the hash result. | ||
if (typeof FileReaderSync !== 'undefined') { | ||
var reader = new FileReaderSync(), | ||
hasher = new Rusha(4 * 1024 * 1024); | ||
self.onmessage = function onMessage (event) { | ||
var hash, data = event.data.data; | ||
if (data instanceof Blob) { | ||
try { | ||
data = reader.readAsBinaryString(data); | ||
} catch (e) { | ||
self.postMessage({id: event.data.id, error: e.name}); | ||
return; | ||
// If we'e running in Node.JS, export a module. | ||
if (typeof module !== 'undefined') { | ||
module.exports = Rusha; | ||
} | ||
// If we're running in a DOM context, export | ||
// the Rusha object to toplevel. | ||
if (typeof window !== 'undefined') { | ||
window.Rusha = Rusha; | ||
} | ||
// If we're running in a webworker, accept | ||
// messages containing a jobid and a buffer | ||
// or blob object, and return the hash result. | ||
if (typeof FileReaderSync !== 'undefined') { | ||
var reader = new FileReaderSync(), hasher = new Rusha(4 * 1024 * 1024); | ||
self.onmessage = function onMessage(event) { | ||
var hash, data = event.data.data; | ||
if (data instanceof Blob) { | ||
try { | ||
data = reader.readAsBinaryString(data); | ||
} catch (e) { | ||
self.postMessage({ | ||
id: event.data.id, | ||
error: e.name | ||
}); | ||
return; | ||
} | ||
} | ||
hash = hasher.digest(data); | ||
self.postMessage({ | ||
id: event.data.id, | ||
hash: hash | ||
}); | ||
}; | ||
} | ||
// The Rusha object is a wrapper around the low-level RushaCore. | ||
// It provides means of converting different inputs to the | ||
// format accepted by RushaCore as well as other utility methods. | ||
function Rusha(chunkSize) { | ||
'use strict'; | ||
// Private object structure. | ||
var self$2 = { fill: 0 }; | ||
// Calculate the length of buffer that the sha1 routine uses | ||
// including the padding. | ||
var padlen = function (len) { | ||
for (len += 9; len % 64 > 0; len += 1); | ||
return len; | ||
}; | ||
var padZeroes = function (bin, len) { | ||
for (var i = len >> 2; i < bin.length; i++) | ||
bin[i] = 0; | ||
}; | ||
var padData = function (bin, chunkLen, msgLen) { | ||
bin[chunkLen >> 2] |= 128 << 24 - (chunkLen % 4 << 3); | ||
bin[((chunkLen >> 2) + 2 & ~15) + 15] = msgLen << 3; | ||
}; | ||
// Convert a binary string to a big-endian Int32Array using | ||
// four characters per slot and pad it per the sha1 spec. | ||
// A binary string is expected to only contain char codes < 256. | ||
var convStr = function (str, bin, start, len) { | ||
var i, m = len % 4, j = len - m; | ||
for (i = 0; i < j; i = i + 4 | 0) { | ||
bin[i >> 2] = str.charCodeAt(start + i) << 24 | str.charCodeAt(start + i + 1) << 16 | str.charCodeAt(start + i + 2) << 8 | str.charCodeAt(start + i + 3); | ||
} | ||
switch (m) { | ||
case 0: | ||
bin[j >> 2] |= str.charCodeAt(start + j + 3); | ||
case 3: | ||
bin[j >> 2] |= str.charCodeAt(start + j + 2) << 8; | ||
case 2: | ||
bin[j >> 2] |= str.charCodeAt(start + j + 1) << 16; | ||
case 1: | ||
bin[j >> 2] |= str.charCodeAt(start + j) << 24; | ||
} | ||
}; | ||
// Convert a buffer or array to a big-endian Int32Array using | ||
// four elements per slot and pad it per the sha1 spec. | ||
// The buffer or array is expected to only contain elements < 256. | ||
var convBuf = function (buf, bin, start, len) { | ||
var i, m = len % 4, j = len - m; | ||
for (i = 0; i < j; i = i + 4 | 0) { | ||
bin[i >> 2] = buf[start + i] << 24 | buf[start + i + 1] << 16 | buf[start + i + 2] << 8 | buf[start + i + 3]; | ||
} | ||
switch (m) { | ||
case 0: | ||
bin[j >> 2] |= buf[start + j + 3]; | ||
case 3: | ||
bin[j >> 2] |= buf[start + j + 2] << 8; | ||
case 2: | ||
bin[j >> 2] |= buf[start + j + 1] << 16; | ||
case 1: | ||
bin[j >> 2] |= buf[start + j] << 24; | ||
} | ||
}; | ||
// Convert general data to a big-endian Int32Array written on the | ||
// heap. | ||
var conv = function (data, bin, start, len) { | ||
if (typeof data === 'string') { | ||
return convStr(data, bin, start, len); | ||
} else if (data instanceof Array || typeof global !== 'undefined' && typeof global.Buffer !== 'undefined' && global.Buffer.isBuffer(data)) { | ||
return convBuf(data, bin, start, len); | ||
} else if (data instanceof ArrayBuffer) { | ||
return convBuf(new Uint8Array(data), bin, start, len); | ||
} else if (data.buffer instanceof ArrayBuffer) { | ||
return convBuf(new Uint8Array(data.buffer), bin, start, len); | ||
} else { | ||
throw new Error('Unsupported data type.'); | ||
} | ||
}; | ||
// Convert an ArrayBuffer into its hexadecimal string representation. | ||
var hex = function (arrayBuffer) { | ||
var i, x, hex_tab = '0123456789abcdef', res = [], binarray = new Uint8Array(arrayBuffer); | ||
for (i = 0; i < binarray.length; i++) { | ||
x = binarray[i]; | ||
res[i] = hex_tab.charAt(x >> 4 & 15) + hex_tab.charAt(x >> 0 & 15); | ||
} | ||
return res.join(''); | ||
}; | ||
var ceilHeapSize = function (v) { | ||
// The asm.js spec says: | ||
// The heap object's byteLength must be either | ||
// 2^n for n in [12, 24) or 2^24 * n for n ≥ 1. | ||
// Also, byteLengths smaller than 2^16 are deprecated. | ||
var p; | ||
// If v is smaller than 2^16, the smallest possible solution | ||
// is 2^16. | ||
if (v <= 65536) | ||
return 65536; | ||
// If v < 2^24, we round up to 2^n, | ||
// otherwise we round up to 2^24 * n. | ||
if (v < 16777216) { | ||
for (p = 1; p < v; p = p << 1); | ||
} else { | ||
for (p = 16777216; p < v; p += 16777216); | ||
} | ||
return p; | ||
}; | ||
// Resize the internal data structures to a new capacity. | ||
var resize = function (size) { | ||
if (size % 64 > 0) { | ||
throw new Error('Chunk size must be a multiple of 128 bit'); | ||
} | ||
self$2.maxChunkLen = size; | ||
self$2.padMaxChunkLen = padlen(size); | ||
// The size of the heap is the sum of: | ||
// 1. The padded input message size | ||
// 2. The extended space the algorithm needs (320 byte) | ||
// 3. The 160 bit state the algoritm uses | ||
self$2.heap = new ArrayBuffer(ceilHeapSize(self$2.padMaxChunkLen + 320 + 20)); | ||
self$2.core = RushaCore({ | ||
Int32Array: Int32Array, | ||
DataView: DataView | ||
}, {}, self$2.heap); | ||
self$2.buffer = null; | ||
}; | ||
// On initialize, resize the datastructures according | ||
// to an optional size hint. | ||
resize(chunkSize || 4 * 1024 * 1024); | ||
var initState = function (heap, padMsgLen) { | ||
var io = new Int32Array(heap, padMsgLen + 320, 5); | ||
io[0] = 1732584193; | ||
io[1] = -271733879; | ||
io[2] = -1732584194; | ||
io[3] = 271733878; | ||
io[4] = -1009589776; | ||
}; | ||
var initChunk = function (chunkLen, msgLen, finalize) { | ||
var padChunkLen = chunkLen; | ||
if (finalize) { | ||
padChunkLen = padlen(chunkLen); | ||
} | ||
var view = new Int32Array(self$2.heap, 0, padChunkLen >> 2); | ||
if (finalize) { | ||
padZeroes(view, chunkLen); | ||
} | ||
if (finalize) { | ||
padData(view, chunkLen, msgLen); | ||
} | ||
return padChunkLen; | ||
}; | ||
// Initialize and call the RushaCore, | ||
// assuming an input buffer of length len * 4. | ||
var coreCall = function (data, chunkStart, chunkLen, msgLen, finalize) { | ||
var padChunkLen = initChunk(chunkLen, msgLen, finalize); | ||
var view = new Int32Array(self$2.heap, 0, padChunkLen >> 2); | ||
conv(data, view, chunkStart, chunkLen); | ||
self$2.core.hash(padChunkLen, self$2.padMaxChunkLen); | ||
}; | ||
var getRawDigest = function (heap, padMaxChunkLen) { | ||
var io = new Int32Array(heap, padMaxChunkLen + 320, 5); | ||
var out = new Int32Array(5); | ||
var arr = new DataView(out.buffer); | ||
arr.setInt32(0, io[0], false); | ||
arr.setInt32(4, io[1], false); | ||
arr.setInt32(8, io[2], false); | ||
arr.setInt32(12, io[3], false); | ||
arr.setInt32(16, io[4], false); | ||
return out; | ||
}; | ||
// Calculate the hash digest as an array of 5 32bit integers. | ||
var rawDigest = this.rawDigest = function (str) { | ||
var msgLen = str.byteLength || str.length; | ||
initState(self$2.heap, self$2.padMaxChunkLen); | ||
var chunkOffset = 0, chunkLen = self$2.maxChunkLen, last; | ||
for (chunkOffset = 0; msgLen > chunkOffset + chunkLen; chunkOffset += chunkLen) { | ||
coreCall(str, chunkOffset, chunkLen, msgLen, false); | ||
} | ||
coreCall(str, chunkOffset, msgLen - chunkOffset, msgLen, true); | ||
return getRawDigest(self$2.heap, self$2.padMaxChunkLen); | ||
}; | ||
// The digest and digestFrom* interface returns the hash digest | ||
// as a hex string. | ||
this.digest = this.digestFromString = this.digestFromBuffer = this.digestFromArrayBuffer = function (str, start) { | ||
return hex(rawDigest(str, start).buffer); | ||
}; | ||
} | ||
; | ||
// The low-level RushCore module provides the heart of Rusha, | ||
// a high-speed sha1 implementation working on an Int32Array heap. | ||
// At first glance, the implementation seems complicated, however | ||
// with the SHA1 spec at hand, it is obvious this almost a textbook | ||
// implementation that has a few functions hand-inlined and a few loops | ||
// hand-unrolled. | ||
function RushaCore(stdlib, foreign, heap) { | ||
'use asm'; | ||
var H = new stdlib.Int32Array(heap); | ||
function hash(k, x) { | ||
// k in bytes | ||
k = k | 0; | ||
x = x | 0; | ||
var i = 0, j = 0, y0 = 0, z0 = 0, y1 = 0, z1 = 0, y2 = 0, z2 = 0, y3 = 0, z3 = 0, y4 = 0, z4 = 0, t0 = 0, t1 = 0; | ||
y0 = H[x + 320 >> 2] | 0; | ||
y1 = H[x + 324 >> 2] | 0; | ||
y2 = H[x + 328 >> 2] | 0; | ||
y3 = H[x + 332 >> 2] | 0; | ||
y4 = H[x + 336 >> 2] | 0; | ||
for (i = 0; (i | 0) < (k | 0); i = i + 64 | 0) { | ||
z0 = y0; | ||
z1 = y1; | ||
z2 = y2; | ||
z3 = y3; | ||
z4 = y4; | ||
for (j = 0; (j | 0) < 64; j = j + 4 | 0) { | ||
t1 = H[i + j >> 2] | 0; | ||
t0 = ((y0 << 5 | y0 >>> 27) + (y1 & y2 | ~y1 & y3) | 0) + ((t1 + y4 | 0) + 1518500249 | 0) | 0; | ||
y4 = y3; | ||
y3 = y2; | ||
y2 = y1 << 30 | y1 >>> 2; | ||
y1 = y0; | ||
y0 = t0; | ||
; | ||
H[k + j >> 2] = t1; | ||
} | ||
for (j = k + 64 | 0; (j | 0) < (k + 80 | 0); j = j + 4 | 0) { | ||
t1 = (H[j - 12 >> 2] ^ H[j - 32 >> 2] ^ H[j - 56 >> 2] ^ H[j - 64 >> 2]) << 1 | (H[j - 12 >> 2] ^ H[j - 32 >> 2] ^ H[j - 56 >> 2] ^ H[j - 64 >> 2]) >>> 31; | ||
t0 = ((y0 << 5 | y0 >>> 27) + (y1 & y2 | ~y1 & y3) | 0) + ((t1 + y4 | 0) + 1518500249 | 0) | 0; | ||
y4 = y3; | ||
y3 = y2; | ||
y2 = y1 << 30 | y1 >>> 2; | ||
y1 = y0; | ||
y0 = t0; | ||
; | ||
H[j >> 2] = t1; | ||
} | ||
for (j = k + 80 | 0; (j | 0) < (k + 160 | 0); j = j + 4 | 0) { | ||
t1 = (H[j - 12 >> 2] ^ H[j - 32 >> 2] ^ H[j - 56 >> 2] ^ H[j - 64 >> 2]) << 1 | (H[j - 12 >> 2] ^ H[j - 32 >> 2] ^ H[j - 56 >> 2] ^ H[j - 64 >> 2]) >>> 31; | ||
t0 = ((y0 << 5 | y0 >>> 27) + (y1 ^ y2 ^ y3) | 0) + ((t1 + y4 | 0) + 1859775393 | 0) | 0; | ||
y4 = y3; | ||
y3 = y2; | ||
y2 = y1 << 30 | y1 >>> 2; | ||
y1 = y0; | ||
y0 = t0; | ||
; | ||
H[j >> 2] = t1; | ||
} | ||
for (j = k + 160 | 0; (j | 0) < (k + 240 | 0); j = j + 4 | 0) { | ||
t1 = (H[j - 12 >> 2] ^ H[j - 32 >> 2] ^ H[j - 56 >> 2] ^ H[j - 64 >> 2]) << 1 | (H[j - 12 >> 2] ^ H[j - 32 >> 2] ^ H[j - 56 >> 2] ^ H[j - 64 >> 2]) >>> 31; | ||
t0 = ((y0 << 5 | y0 >>> 27) + (y1 & y2 | y1 & y3 | y2 & y3) | 0) + ((t1 + y4 | 0) - 1894007588 | 0) | 0; | ||
y4 = y3; | ||
y3 = y2; | ||
y2 = y1 << 30 | y1 >>> 2; | ||
y1 = y0; | ||
y0 = t0; | ||
; | ||
H[j >> 2] = t1; | ||
} | ||
for (j = k + 240 | 0; (j | 0) < (k + 320 | 0); j = j + 4 | 0) { | ||
t1 = (H[j - 12 >> 2] ^ H[j - 32 >> 2] ^ H[j - 56 >> 2] ^ H[j - 64 >> 2]) << 1 | (H[j - 12 >> 2] ^ H[j - 32 >> 2] ^ H[j - 56 >> 2] ^ H[j - 64 >> 2]) >>> 31; | ||
t0 = ((y0 << 5 | y0 >>> 27) + (y1 ^ y2 ^ y3) | 0) + ((t1 + y4 | 0) - 899497514 | 0) | 0; | ||
y4 = y3; | ||
y3 = y2; | ||
y2 = y1 << 30 | y1 >>> 2; | ||
y1 = y0; | ||
y0 = t0; | ||
; | ||
H[j >> 2] = t1; | ||
} | ||
y0 = y0 + z0 | 0; | ||
y1 = y1 + z1 | 0; | ||
y2 = y2 + z2 | 0; | ||
y3 = y3 + z3 | 0; | ||
y4 = y4 + z4 | 0; | ||
} | ||
H[x + 320 >> 2] = y0; | ||
H[x + 324 >> 2] = y1; | ||
H[x + 328 >> 2] = y2; | ||
H[x + 332 >> 2] = y3; | ||
H[x + 336 >> 2] = y4; | ||
} | ||
} | ||
hash = hasher.digest(data); | ||
self.postMessage({id: event.data.id, hash: hash}); | ||
}; | ||
} | ||
// The Rusha object is a wrapper around the low-level RushaCore. | ||
// It provides means of converting different inputs to the | ||
// format accepted by RushaCore as well as other utility methods. | ||
function Rusha (sizeHint) { | ||
"use strict"; | ||
// Private object structure. | ||
var self = {fill: 0}; | ||
// Calculate the length of buffer that the sha1 routine uses | ||
// including the padding. | ||
var padlen = function (len) { | ||
return len + 1 + ((len ) % 64 < 56 ? 56 : 56 + 64) - (len ) % 64 + 8; | ||
}; | ||
var padZeroes = function (bin, len) { | ||
for (var i = len >> 2; i < bin.length; i++) bin[i] = 0; | ||
}; | ||
var padData = function (bin, len) { | ||
bin[len>>2] |= 0x80 << (24 - (len % 4 << 3)); | ||
bin[(((len >> 2) + 2) & ~0x0f) + 15] = len << 3; | ||
}; | ||
// Convert a binary string to a big-endian Int32Array using | ||
// four characters per slot and pad it per the sha1 spec. | ||
// A binary string is expected to only contain char codes < 256. | ||
var convStr = function (str, bin, len) { | ||
var i; | ||
for (i = 0; i < len; i = i + 4 |0) { | ||
bin[i>>2] = str.charCodeAt(i) << 24 | | ||
str.charCodeAt(i+1) << 16 | | ||
str.charCodeAt(i+2) << 8 | | ||
str.charCodeAt(i+3); | ||
} | ||
}; | ||
// Convert a buffer or array to a big-endian Int32Array using | ||
// four elements per slot and pad it per the sha1 spec. | ||
// The buffer or array is expected to only contain elements < 256. | ||
var convBuf = function (buf, bin, len) { | ||
var i, m = len % 4, j = len - m; | ||
for (i = 0; i < j; i = i + 4 |0) { | ||
bin[i>>2] = buf[i] << 24 | | ||
buf[i+1] << 16 | | ||
buf[i+2] << 8 | | ||
buf[i+3]; | ||
} | ||
switch (m) { | ||
case 0: bin[j>>2] |= buf[j+3]; | ||
case 3: bin[j>>2] |= buf[j+2] << 8; | ||
case 2: bin[j>>2] |= buf[j+1] << 16; | ||
case 1: bin[j>>2] |= buf[j] << 24; | ||
} | ||
}; | ||
// Convert general data to a big-endian Int32Array written on the | ||
// heap and return it's length; | ||
var conv = function (data, bin, len) { | ||
if (typeof data === 'string') { | ||
return convStr(data, bin, len); | ||
} else if (data instanceof Array || (typeof global !== 'undefined' && | ||
typeof global.Buffer !== 'undefined' && | ||
global.Buffer.isBuffer(data))) { | ||
return convBuf(data, bin, len); | ||
} else if (data instanceof ArrayBuffer) { | ||
return convBuf(new Uint8Array(data), bin, len); | ||
} else if (data.buffer instanceof ArrayBuffer) { | ||
return convBuf(new Uint8Array(data.buffer), bin, len); | ||
} else { | ||
throw new Error('Unsupported data type.'); | ||
} | ||
}; | ||
// Convert an ArrayBuffer into its hexadecimal string representation. | ||
var hex = function (arrayBuffer) { | ||
var i, x, hex_tab = "0123456789abcdef", res = [], binarray = new Uint8Array(arrayBuffer); | ||
for (i = 0; i < binarray.length; i++) { | ||
x = binarray[i]; | ||
res[i] = hex_tab.charAt((x >> 4) & 0xF) + | ||
hex_tab.charAt((x >> 0) & 0xF); | ||
} | ||
return res.join(''); | ||
}; | ||
var ceilHeapSize = function (v) { | ||
// The asm.js spec says: | ||
// The heap object's byteLength must be either | ||
// 2^n for n in [12, 24) or 2^24 * n for n ≥ 1. | ||
var p; | ||
// If v is smaller than 2^12, the smallest possible solution | ||
// is 2^12. | ||
if (v <= 4096) return 4096; | ||
// If v < 2^24, we round up to 2^n, | ||
// otherwise we round up to 2^24 * n. | ||
if (v < 16777216) { | ||
for (p = 1; p < v; p = p << 1); | ||
} else { | ||
for (p = 16777216; p < v; p += 16777216); | ||
} | ||
return p; | ||
}; | ||
// Resize the internal data structures to a new capacity. | ||
var resize = function (size) { | ||
self.sizeHint = size; | ||
self.heap = new ArrayBuffer(ceilHeapSize(padlen(size) + 320)); | ||
self.core = RushaCore({Int32Array: Int32Array, DataView: DataView}, {}, self.heap); | ||
}; | ||
// On initialize, resize the datastructures according | ||
// to an optional size hint. | ||
resize(sizeHint || 0); | ||
// Initialize and call the RushaCore, | ||
// assuming an input buffer of length len * 4. | ||
var coreCall = function (len) { | ||
var h = new Int32Array(self.heap, len << 2, 5); | ||
h[0] = 1732584193; | ||
h[1] = -271733879; | ||
h[2] = -1732584194; | ||
h[3] = 271733878; | ||
h[4] = -1009589776; | ||
self.core.hash(len); | ||
}; | ||
// Calculate the hash digest as an array of 5 32bit integers. | ||
var rawDigest = this.rawDigest = function (str) { | ||
var len = str.byteLength || str.length; | ||
if (len > self.sizeHint) { | ||
resize(len); | ||
} | ||
var view = new Int32Array(self.heap, 0, padlen(len) >> 2); | ||
padZeroes(view, len); | ||
conv(str, view, len); | ||
padData(view, len); | ||
coreCall(view.length); | ||
var out = new Int32Array(5); | ||
var arr = new DataView(out.buffer); | ||
arr.setInt32(0, view[0], false); | ||
arr.setInt32(4, view[1], false); | ||
arr.setInt32(8, view[2], false); | ||
arr.setInt32(12, view[3], false); | ||
arr.setInt32(16, view[4], false); | ||
return out; | ||
}; | ||
// The digest and digestFrom* interface returns the hash digest | ||
// as a hex string. | ||
this.digest = this.digestFromString = | ||
this.digestFromBuffer = this.digestFromArrayBuffer = | ||
function (str) { | ||
return hex(rawDigest(str).buffer); | ||
}; | ||
}; | ||
// The low-level RushCore module provides the heart of Rusha, | ||
// a high-speed sha1 implementation working on an Int32Array heap. | ||
// At first glance, the implementation seems complicated, however | ||
// with the SHA1 spec at hand, it is obvious this almost a textbook | ||
// implementation that has a few functions hand-inlined and a few loops | ||
// hand-unrolled. | ||
function RushaCore (stdlib, foreign, heap) { | ||
"use asm"; | ||
var H = new stdlib.Int32Array(heap); | ||
function hash (k) { | ||
k = k|0; | ||
var i = 0, j = 0, | ||
y0 = 0, z0 = 0, y1 = 0, z1 = 0, | ||
y2 = 0, z2 = 0, y3 = 0, z3 = 0, | ||
y4 = 0, z4 = 0, t0 = 0, t1 = 0; | ||
y0 = H[k+0<<2>>2]|0; | ||
y1 = H[k+1<<2>>2]|0; | ||
y2 = H[k+2<<2>>2]|0; | ||
y3 = H[k+3<<2>>2]|0; | ||
y4 = H[k+4<<2>>2]|0; | ||
for (i = 0; (i|0) < (k|0); i = i + 16 |0) { | ||
z0 = y0; | ||
z1 = y1; | ||
z2 = y2; | ||
z3 = y3; | ||
z4 = y4; | ||
for (j = 0; (j|0) < 16; j = j + 1 |0) { | ||
t1 = H[i+j<<2>>2]|0; | ||
t0 = ((((y0) << 5 | (y0) >>> 27) + (y1 & y2 | ~y1 & y3) |0) + ((t1 + y4 | 0) +1518500249 |0) |0); | ||
y4 = y3; y3 = y2; y2 = ((y1) << 30 | (y1) >>> 2); y1 = y0; y0 = t0; | ||
H[k+j<<2>>2] = t1; | ||
} | ||
for (j = k + 16 |0; (j|0) < (k + 20 |0); j = j + 1 |0) { | ||
t1 = (((H[j-3<<2>>2] ^ H[j-8<<2>>2] ^ H[j-14<<2>>2] ^ H[j-16<<2>>2]) << 1 | (H[j-3<<2>>2] ^ H[j-8<<2>>2] ^ H[j-14<<2>>2] ^ H[j-16<<2>>2]) >>> 31)); | ||
t0 = ((((y0) << 5 | (y0) >>> 27) + (y1 & y2 | ~y1 & y3) |0) + ((t1 + y4 | 0) +1518500249 |0) |0); | ||
y4 = y3; y3 = y2; y2 = ((y1) << 30 | (y1) >>> 2); y1 = y0; y0 = t0; | ||
H[j<<2>>2] = t1; | ||
} | ||
for (j = k + 20 |0; (j|0) < (k + 40 |0); j = j + 1 |0) { | ||
t1 = (((H[j-3<<2>>2] ^ H[j-8<<2>>2] ^ H[j-14<<2>>2] ^ H[j-16<<2>>2]) << 1 | (H[j-3<<2>>2] ^ H[j-8<<2>>2] ^ H[j-14<<2>>2] ^ H[j-16<<2>>2]) >>> 31)); | ||
t0 = ((((y0) << 5 | (y0) >>> 27) + (y1 ^ y2 ^ y3) |0) + ((t1 + y4 | 0) +1859775393 |0) |0); | ||
y4 = y3; y3 = y2; y2 = ((y1) << 30 | (y1) >>> 2); y1 = y0; y0 = t0; | ||
H[j<<2>>2] = t1; | ||
} | ||
for (j = k + 40 |0; (j|0) < (k + 60 |0); j = j + 1 |0) { | ||
t1 = (((H[j-3<<2>>2] ^ H[j-8<<2>>2] ^ H[j-14<<2>>2] ^ H[j-16<<2>>2]) << 1 | (H[j-3<<2>>2] ^ H[j-8<<2>>2] ^ H[j-14<<2>>2] ^ H[j-16<<2>>2]) >>> 31)); | ||
t0 = ((((y0) << 5 | (y0) >>> 27) + (y1 & y2 | y1 & y3 | y2 & y3) |0) + ((t1 + y4 | 0) -1894007588 |0) |0); | ||
y4 = y3; y3 = y2; y2 = ((y1) << 30 | (y1) >>> 2); y1 = y0; y0 = t0; | ||
H[j<<2>>2] = t1; | ||
} | ||
for (j = k + 60 |0; (j|0) < (k + 80 |0); j = j + 1 |0) { | ||
t1 = (((H[j-3<<2>>2] ^ H[j-8<<2>>2] ^ H[j-14<<2>>2] ^ H[j-16<<2>>2]) << 1 | (H[j-3<<2>>2] ^ H[j-8<<2>>2] ^ H[j-14<<2>>2] ^ H[j-16<<2>>2]) >>> 31)); | ||
t0 = ((((y0) << 5 | (y0) >>> 27) + (y1 ^ y2 ^ y3) |0) + ((t1 + y4 | 0) -899497514 |0) |0); | ||
y4 = y3; y3 = y2; y2 = ((y1) << 30 | (y1) >>> 2); y1 = y0; y0 = t0; | ||
H[j<<2>>2] = t1; | ||
} | ||
y0 = y0 + z0 |0; | ||
y1 = y1 + z1 |0; | ||
y2 = y2 + z2 |0; | ||
y3 = y3 + z3 |0; | ||
y4 = y4 + z4 |0; | ||
} | ||
H[0] = y0; | ||
H[1] = y1; | ||
H[2] = y2; | ||
H[3] = y3; | ||
H[4] = y4; | ||
return { hash: hash }; | ||
} | ||
return {hash: hash}; | ||
} | ||
})(); | ||
}()); |
@@ -6,14 +6,20 @@ | ||
hash=hasher.digest(data);self.postMessage({id:event.data.id,hash:hash});};} | ||
function Rusha(sizeHint){"use strict";var self={fill:0};var padlen=function(len){return len+1+((len)%64<56?56:56+64)-(len)%64+8;};var padZeroes=function(bin,len){for(var i=len>>2;i<bin.length;i++)bin[i]=0;};var padData=function(bin,len){bin[len>>2]|=0x80<<(24-(len%4<<3));bin[(((len>>2)+2)&~0x0f)+15]=len<<3;};var convStr=function(str,bin,len){var i;for(i=0;i<len;i=i+4|0){bin[i>>2]=str.charCodeAt(i)<<24|str.charCodeAt(i+1)<<16|str.charCodeAt(i+2)<<8|str.charCodeAt(i+3);}};var convBuf=function(buf,bin,len){var i,m=len%4,j=len-m;for(i=0;i<j;i=i+4|0){bin[i>>2]=buf[i]<<24|buf[i+1]<<16|buf[i+2]<<8|buf[i+3];} | ||
switch(m){case 0:bin[j>>2]|=buf[j+3];case 3:bin[j>>2]|=buf[j+2]<<8;case 2:bin[j>>2]|=buf[j+1]<<16;case 1:bin[j>>2]|=buf[j]<<24;}};var conv=function(data,bin,len){if(typeof data==='string'){return convStr(data,bin,len);}else if(data instanceof Array||(typeof global!=='undefined'&&typeof global.Buffer!=='undefined'&&global.Buffer.isBuffer(data))){return convBuf(data,bin,len);}else if(data instanceof ArrayBuffer){return convBuf(new Uint8Array(data),bin,len);}else if(data.buffer instanceof ArrayBuffer){return convBuf(new Uint8Array(data.buffer),bin,len);}else{throw new Error('Unsupported data type.');}};var hex=function(arrayBuffer){var i,x,hex_tab="0123456789abcdef",res=[],binarray=new Uint8Array(arrayBuffer);for(i=0;i<binarray.length;i++){x=binarray[i];res[i]=hex_tab.charAt((x>>4)&0xF)+ | ||
hex_tab.charAt((x>>0)&0xF);} | ||
return res.join('');};var ceilHeapSize=function(v){var p;if(v<=4096)return 4096;if(v<16777216){for(p=1;p<v;p=p<<1);}else{for(p=16777216;p<v;p+=16777216);} | ||
return p;};var resize=function(size){self.sizeHint=size;self.heap=new ArrayBuffer(ceilHeapSize(padlen(size)+320));self.core=RushaCore({Int32Array:Int32Array,DataView:DataView},{},self.heap);};resize(sizeHint||0);var coreCall=function(len){var h=new Int32Array(self.heap,len<<2,5);h[0]=1732584193;h[1]=-271733879;h[2]=-1732584194;h[3]=271733878;h[4]=-1009589776;self.core.hash(len);};var rawDigest=this.rawDigest=function(str){var len=str.byteLength||str.length;if(len>self.sizeHint){resize(len);} | ||
var view=new Int32Array(self.heap,0,padlen(len)>>2);padZeroes(view,len);conv(str,view,len);padData(view,len);coreCall(view.length);var out=new Int32Array(5);var arr=new DataView(out.buffer);arr.setInt32(0,view[0],false);arr.setInt32(4,view[1],false);arr.setInt32(8,view[2],false);arr.setInt32(12,view[3],false);arr.setInt32(16,view[4],false);return out;};this.digest=this.digestFromString=this.digestFromBuffer=this.digestFromArrayBuffer=function(str){return hex(rawDigest(str).buffer);};};function RushaCore(stdlib,foreign,heap){"use asm";var H=new stdlib.Int32Array(heap);function hash(k){k=k|0;var i=0,j=0,y0=0,z0=0,y1=0,z1=0,y2=0,z2=0,y3=0,z3=0,y4=0,z4=0,t0=0,t1=0;y0=H[k+0<<2>>2]|0;y1=H[k+1<<2>>2]|0;y2=H[k+2<<2>>2]|0;y3=H[k+3<<2>>2]|0;y4=H[k+4<<2>>2]|0;for(i=0;(i|0)<(k|0);i=i+16|0){z0=y0;z1=y1;z2=y2;z3=y3;z4=y4;for(j=0;(j|0)<16;j=j+1|0){t1=H[i+j<<2>>2]|0;t0=((((y0)<<5|(y0)>>>27)+(y1&y2|~y1&y3)|0)+((t1+y4|0)+1518500249|0)|0);y4=y3;y3=y2;y2=((y1)<<30|(y1)>>>2);y1=y0;y0=t0;H[k+j<<2>>2]=t1;} | ||
for(j=k+16|0;(j|0)<(k+20|0);j=j+1|0){t1=(((H[j-3<<2>>2]^H[j-8<<2>>2]^H[j-14<<2>>2]^H[j-16<<2>>2])<<1|(H[j-3<<2>>2]^H[j-8<<2>>2]^H[j-14<<2>>2]^H[j-16<<2>>2])>>>31));t0=((((y0)<<5|(y0)>>>27)+(y1&y2|~y1&y3)|0)+((t1+y4|0)+1518500249|0)|0);y4=y3;y3=y2;y2=((y1)<<30|(y1)>>>2);y1=y0;y0=t0;H[j<<2>>2]=t1;} | ||
for(j=k+20|0;(j|0)<(k+40|0);j=j+1|0){t1=(((H[j-3<<2>>2]^H[j-8<<2>>2]^H[j-14<<2>>2]^H[j-16<<2>>2])<<1|(H[j-3<<2>>2]^H[j-8<<2>>2]^H[j-14<<2>>2]^H[j-16<<2>>2])>>>31));t0=((((y0)<<5|(y0)>>>27)+(y1^y2^y3)|0)+((t1+y4|0)+1859775393|0)|0);y4=y3;y3=y2;y2=((y1)<<30|(y1)>>>2);y1=y0;y0=t0;H[j<<2>>2]=t1;} | ||
for(j=k+40|0;(j|0)<(k+60|0);j=j+1|0){t1=(((H[j-3<<2>>2]^H[j-8<<2>>2]^H[j-14<<2>>2]^H[j-16<<2>>2])<<1|(H[j-3<<2>>2]^H[j-8<<2>>2]^H[j-14<<2>>2]^H[j-16<<2>>2])>>>31));t0=((((y0)<<5|(y0)>>>27)+(y1&y2|y1&y3|y2&y3)|0)+((t1+y4|0)-1894007588|0)|0);y4=y3;y3=y2;y2=((y1)<<30|(y1)>>>2);y1=y0;y0=t0;H[j<<2>>2]=t1;} | ||
for(j=k+60|0;(j|0)<(k+80|0);j=j+1|0){t1=(((H[j-3<<2>>2]^H[j-8<<2>>2]^H[j-14<<2>>2]^H[j-16<<2>>2])<<1|(H[j-3<<2>>2]^H[j-8<<2>>2]^H[j-14<<2>>2]^H[j-16<<2>>2])>>>31));t0=((((y0)<<5|(y0)>>>27)+(y1^y2^y3)|0)+((t1+y4|0)-899497514|0)|0);y4=y3;y3=y2;y2=((y1)<<30|(y1)>>>2);y1=y0;y0=t0;H[j<<2>>2]=t1;} | ||
function Rusha(chunkSize){'use strict';var self$2={fill:0};var padlen=function(len){for(len+=9;len%64>0;len+=1);return len;};var padZeroes=function(bin,len){for(var i=len>>2;i<bin.length;i++) | ||
bin[i]=0;};var padData=function(bin,chunkLen,msgLen){bin[chunkLen>>2]|=128<<24-(chunkLen%4<<3);bin[((chunkLen>>2)+2&~15)+15]=msgLen<<3;};var convStr=function(str,bin,start,len){var i,m=len%4,j=len-m;for(i=0;i<j;i=i+4|0){bin[i>>2]=str.charCodeAt(start+i)<<24|str.charCodeAt(start+i+1)<<16|str.charCodeAt(start+i+2)<<8|str.charCodeAt(start+i+3);} | ||
switch(m){case 0:bin[j>>2]|=str.charCodeAt(start+j+3);case 3:bin[j>>2]|=str.charCodeAt(start+j+2)<<8;case 2:bin[j>>2]|=str.charCodeAt(start+j+1)<<16;case 1:bin[j>>2]|=str.charCodeAt(start+j)<<24;}};var convBuf=function(buf,bin,start,len){var i,m=len%4,j=len-m;for(i=0;i<j;i=i+4|0){bin[i>>2]=buf[start+i]<<24|buf[start+i+1]<<16|buf[start+i+2]<<8|buf[start+i+3];} | ||
switch(m){case 0:bin[j>>2]|=buf[start+j+3];case 3:bin[j>>2]|=buf[start+j+2]<<8;case 2:bin[j>>2]|=buf[start+j+1]<<16;case 1:bin[j>>2]|=buf[start+j]<<24;}};var conv=function(data,bin,start,len){if(typeof data==='string'){return convStr(data,bin,start,len);}else if(data instanceof Array||typeof global!=='undefined'&&typeof global.Buffer!=='undefined'&&global.Buffer.isBuffer(data)){return convBuf(data,bin,start,len);}else if(data instanceof ArrayBuffer){return convBuf(new Uint8Array(data),bin,start,len);}else if(data.buffer instanceof ArrayBuffer){return convBuf(new Uint8Array(data.buffer),bin,start,len);}else{throw new Error('Unsupported data type.');}};var hex=function(arrayBuffer){var i,x,hex_tab='0123456789abcdef',res=[],binarray=new Uint8Array(arrayBuffer);for(i=0;i<binarray.length;i++){x=binarray[i];res[i]=hex_tab.charAt(x>>4&15)+hex_tab.charAt(x>>0&15);} | ||
return res.join('');};var ceilHeapSize=function(v){var p;if(v<=65536) | ||
return 65536;if(v<16777216){for(p=1;p<v;p=p<<1);}else{for(p=16777216;p<v;p+=16777216);} | ||
return p;};var resize=function(size){if(size%64>0){throw new Error('Chunk size must be a multiple of 128 bit');} | ||
self$2.maxChunkLen=size;self$2.padMaxChunkLen=padlen(size);self$2.heap=new ArrayBuffer(ceilHeapSize(self$2.padMaxChunkLen+320+20));self$2.core=RushaCore({Int32Array:Int32Array,DataView:DataView},{},self$2.heap);self$2.buffer=null;};resize(chunkSize||4*1024*1024);var initState=function(heap,padMsgLen){var io=new Int32Array(heap,padMsgLen+320,5);io[0]=1732584193;io[1]=-271733879;io[2]=-1732584194;io[3]=271733878;io[4]=-1009589776;};var initChunk=function(chunkLen,msgLen,finalize){var padChunkLen=chunkLen;if(finalize){padChunkLen=padlen(chunkLen);} | ||
var view=new Int32Array(self$2.heap,0,padChunkLen>>2);if(finalize){padZeroes(view,chunkLen);} | ||
if(finalize){padData(view,chunkLen,msgLen);} | ||
return padChunkLen;};var coreCall=function(data,chunkStart,chunkLen,msgLen,finalize){var padChunkLen=initChunk(chunkLen,msgLen,finalize);var view=new Int32Array(self$2.heap,0,padChunkLen>>2);conv(data,view,chunkStart,chunkLen);self$2.core.hash(padChunkLen,self$2.padMaxChunkLen);};var getRawDigest=function(heap,padMaxChunkLen){var io=new Int32Array(heap,padMaxChunkLen+320,5);var out=new Int32Array(5);var arr=new DataView(out.buffer);arr.setInt32(0,io[0],false);arr.setInt32(4,io[1],false);arr.setInt32(8,io[2],false);arr.setInt32(12,io[3],false);arr.setInt32(16,io[4],false);return out;};var rawDigest=this.rawDigest=function(str){var msgLen=str.byteLength||str.length;initState(self$2.heap,self$2.padMaxChunkLen);var chunkOffset=0,chunkLen=self$2.maxChunkLen,last;for(chunkOffset=0;msgLen>chunkOffset+chunkLen;chunkOffset+=chunkLen){coreCall(str,chunkOffset,chunkLen,msgLen,false);} | ||
coreCall(str,chunkOffset,msgLen-chunkOffset,msgLen,true);return getRawDigest(self$2.heap,self$2.padMaxChunkLen);};this.digest=this.digestFromString=this.digestFromBuffer=this.digestFromArrayBuffer=function(str,start){return hex(rawDigest(str,start).buffer);};};function RushaCore(stdlib,foreign,heap){'use asm';var H=new stdlib.Int32Array(heap);function hash(k,x){k=k|0;x=x|0;var i=0,j=0,y0=0,z0=0,y1=0,z1=0,y2=0,z2=0,y3=0,z3=0,y4=0,z4=0,t0=0,t1=0;y0=H[x+320>>2]|0;y1=H[x+324>>2]|0;y2=H[x+328>>2]|0;y3=H[x+332>>2]|0;y4=H[x+336>>2]|0;for(i=0;(i|0)<(k|0);i=i+64|0){z0=y0;z1=y1;z2=y2;z3=y3;z4=y4;for(j=0;(j|0)<64;j=j+4|0){t1=H[i+j>>2]|0;t0=((y0<<5|y0>>>27)+(y1&y2|~y1&y3)|0)+((t1+y4|0)+1518500249|0)|0;y4=y3;y3=y2;y2=y1<<30|y1>>>2;y1=y0;y0=t0;;H[k+j>>2]=t1;} | ||
for(j=k+64|0;(j|0)<(k+80|0);j=j+4|0){t1=(H[j-12>>2]^H[j-32>>2]^H[j-56>>2]^H[j-64>>2])<<1|(H[j-12>>2]^H[j-32>>2]^H[j-56>>2]^H[j-64>>2])>>>31;t0=((y0<<5|y0>>>27)+(y1&y2|~y1&y3)|0)+((t1+y4|0)+1518500249|0)|0;y4=y3;y3=y2;y2=y1<<30|y1>>>2;y1=y0;y0=t0;;H[j>>2]=t1;} | ||
for(j=k+80|0;(j|0)<(k+160|0);j=j+4|0){t1=(H[j-12>>2]^H[j-32>>2]^H[j-56>>2]^H[j-64>>2])<<1|(H[j-12>>2]^H[j-32>>2]^H[j-56>>2]^H[j-64>>2])>>>31;t0=((y0<<5|y0>>>27)+(y1^y2^y3)|0)+((t1+y4|0)+1859775393|0)|0;y4=y3;y3=y2;y2=y1<<30|y1>>>2;y1=y0;y0=t0;;H[j>>2]=t1;} | ||
for(j=k+160|0;(j|0)<(k+240|0);j=j+4|0){t1=(H[j-12>>2]^H[j-32>>2]^H[j-56>>2]^H[j-64>>2])<<1|(H[j-12>>2]^H[j-32>>2]^H[j-56>>2]^H[j-64>>2])>>>31;t0=((y0<<5|y0>>>27)+(y1&y2|y1&y3|y2&y3)|0)+((t1+y4|0)-1894007588|0)|0;y4=y3;y3=y2;y2=y1<<30|y1>>>2;y1=y0;y0=t0;;H[j>>2]=t1;} | ||
for(j=k+240|0;(j|0)<(k+320|0);j=j+4|0){t1=(H[j-12>>2]^H[j-32>>2]^H[j-56>>2]^H[j-64>>2])<<1|(H[j-12>>2]^H[j-32>>2]^H[j-56>>2]^H[j-64>>2])>>>31;t0=((y0<<5|y0>>>27)+(y1^y2^y3)|0)+((t1+y4|0)-899497514|0)|0;y4=y3;y3=y2;y2=y1<<30|y1>>>2;y1=y0;y0=t0;;H[j>>2]=t1;} | ||
y0=y0+z0|0;y1=y1+z1|0;y2=y2+z2|0;y3=y3+z3|0;y4=y4+z4|0;} | ||
H[0]=y0;H[1]=y1;H[2]=y2;H[3]=y3;H[4]=y4;} | ||
return{hash:hash};}})(); | ||
H[x+320>>2]=y0;H[x+324>>2]=y1;H[x+328>>2]=y2;H[x+332>>2]=y3;H[x+336>>2]=y4;} | ||
return{hash:hash};}}()); |
@@ -43,3 +43,3 @@ (function () { | ||
it('returns hex string from string', function() { | ||
assert.equal('a9993e364706816aba3e25717850c26c9cd0d89d', (new Rusha()).digestFromString(abcString)); | ||
assert.equal('a9993e364706816aba3e25717850c26c9cd0d89d', r.digestFromString(abcString)); | ||
}); | ||
@@ -46,0 +46,0 @@ }); |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
46483
10
777
3
1