Skip to content

Instantly share code, notes, and snippets.

@jasondavies
Created March 7, 2009 12:52
Show Gist options
  • Save jasondavies/75321 to your computer and use it in GitHub Desktop.
Save jasondavies/75321 to your computer and use it in GitHub Desktop.
/**
* Support for generating SHA-1 of a stream.
*
* Based on http://pajhome.org.uk/crypt/md5/sha1.js.
*/
function naked_sha1_head() {
var w = Array(80);
var a = 1732584193;
var b = -271733879;
var c = -1732584194;
var d = 271733878;
var e = -1009589776;
return [w, a, b, c, d, e, [], 0, 0];
}
function naked_sha1(x, len, h) {
var w = h[0], a = h[1], b = h[2], c = h[3], d = h[4], e = h[5];
/* prepend data from last time */
var old_len = h[8];
var blen = x.length;
if (x.length > 0) {
var shift = old_len % 32;
if (shift > 0) {
h[6][old_len >> 5] |= x[0] >> shift;
for (var i=0; i<x.length-1; i++) {
x[i] = x[i] << (32 - shift) | x[i+1] >> shift;
}
x[x.length-1] <<= 32 - shift;
}
}
x = h[6].concat(x)
var max = (old_len + len) >> 5;
max -= max % 16;
for(var i = 0; i < max; i += 16)
{
var olda = a;
var oldb = b;
var oldc = c;
var oldd = d;
var olde = e;
for(var j = 0; j < 80; j++)
{
if(j < 16) w[j] = x[i + j];
else w[j] = rol(w[j-3] ^ w[j-8] ^ w[j-14] ^ w[j-16], 1);
var t = safe_add(safe_add(rol(a, 5), sha1_ft(j, b, c, d)),
safe_add(safe_add(e, w[j]), sha1_kt(j)));
e = d;
d = c;
c = rol(b, 30);
b = a;
a = t;
}
a = safe_add(a, olda);
b = safe_add(b, oldb);
c = safe_add(c, oldc);
d = safe_add(d, oldd);
e = safe_add(e, olde);
}
h[0] = w;
h[1] = a;
h[2] = b;
h[3] = c;
h[4] = d;
h[5] = e;
/* store extra for next time */
h[6] = x.slice(max, (old_len + len + 24) >> 5);
h[7] += len;
h[8] += len - 32 * max;
}
function naked_sha1_tail(h) {
/* append padding */
var x = h[6];
var total_len = h[7];
var len = h[8];
x[len >> 5] |= 0x80 << (24 - len % 32);
x[((len + 64 >> 9) << 4) + 15] = total_len;
h[8] += 512 - len % 512;
naked_sha1([], 0, h);
return h.slice(1, 6);
}
function hmac_sha1_stream_head(key, data) {
var bkey = str2binb(key);
if(bkey.length > 16) bkey = core_sha1(bkey, key.length * chrsz);
var ipad = Array(16), opad = Array(16);
for(var i = 0; i < 16; i++)
{
ipad[i] = bkey[i] ^ 0x36363636;
opad[i] = bkey[i] ^ 0x5C5C5C5C;
}
var naked_hash = naked_sha1_head();
naked_sha1(ipad.concat(str2binb(data)), 512 + data.length * chrsz, naked_hash);
return {
opad: opad,
naked_hash: naked_hash
};
}
function hmac_sha1_stream(data, naked_hash) {
naked_sha1(str2binb(data), data.length * chrsz, naked_hash);
}
function hmac_sha1_stream_tail(opad, naked_hash) {
var hash = naked_sha1_tail(naked_hash);
return binb2b64(core_sha1(opad.concat(hash), 512 + 160));
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment