crypto-browserify
Advanced tools
Comparing version 1.0.1 to 1.0.2
315
md5.js
/* | ||
* A JavaScript implementation of the RSA Data Security, Inc. MD5 Message | ||
* Digest Algorithm, as defined in RFC 1321. | ||
* Version 2.2 Copyright (C) Paul Johnston 1999 - 2009 | ||
* Version 2.1 Copyright (C) Paul Johnston 1999 - 2002. | ||
* Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet | ||
@@ -16,2 +16,3 @@ * Distributed under the BSD License | ||
var b64pad = "="; /* base-64 pad character. "=" for strict RFC compliance */ | ||
var chrsz = 8; /* bits per input character. 8 - ASCII; 16 - Unicode */ | ||
@@ -22,14 +23,8 @@ /* | ||
*/ | ||
function hex_md5(s) { return rstr2hex(rstr_md5(str2rstr_utf8(s))); } | ||
function b64_md5(s) { return rstr2b64(rstr_md5(str2rstr_utf8(s))); } | ||
function bin_md5(s) { return rstr_md5(str2rstr_utf8(s)); } | ||
function any_md5(s, e) { return rstr2any(rstr_md5(str2rstr_utf8(s)), e); } | ||
function hex_hmac_md5(k, d) | ||
{ return rstr2hex(rstr_hmac_md5(str2rstr_utf8(k), str2rstr_utf8(d))); } | ||
function b64_hmac_md5(k, d) | ||
{ return rstr2b64(rstr_hmac_md5(str2rstr_utf8(k), str2rstr_utf8(d))); } | ||
function bin_hmac_md5(k, d) | ||
{ return rstr_hmac_md5(str2rstr_utf8(k), str2rstr_utf8(d)); } | ||
function any_hmac_md5(k, d, e) | ||
{ return rstr2any(rstr_hmac_md5(str2rstr_utf8(k), str2rstr_utf8(d)), e); } | ||
function hex_md5(s){ return binl2hex(core_md5(str2binl(s), s.length * chrsz));} | ||
function b64_md5(s){ return binl2b64(core_md5(str2binl(s), s.length * chrsz));} | ||
function str_md5(s){ return binl2str(core_md5(str2binl(s), s.length * chrsz));} | ||
function hex_hmac_md5(key, data) { return binl2hex(core_hmac_md5(key, data)); } | ||
function b64_hmac_md5(key, data) { return binl2b64(core_hmac_md5(key, data)); } | ||
function str_hmac_md5(key, data) { return binl2str(core_hmac_md5(key, data)); } | ||
@@ -41,212 +36,10 @@ /* | ||
{ | ||
return hex_md5("abc").toLowerCase() == "900150983cd24fb0d6963f7d28e17f72"; | ||
return hex_md5("abc") == "900150983cd24fb0d6963f7d28e17f72"; | ||
} | ||
/* | ||
* Calculate the MD5 of a raw string | ||
* Calculate the MD5 of an array of little-endian words, and a bit length | ||
*/ | ||
function rstr_md5(s) | ||
function core_md5(x, len) | ||
{ | ||
return binl2rstr(binl_md5(rstr2binl(s), s.length * 8)); | ||
} | ||
/* | ||
* Calculate the HMAC-MD5, of a key and some data (raw strings) | ||
*/ | ||
function rstr_hmac_md5(key, data) | ||
{ | ||
var bkey = rstr2binl(key); | ||
if(bkey.length > 16) bkey = binl_md5(bkey, key.length * 8); | ||
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 hash = binl_md5(ipad.concat(rstr2binl(data)), 512 + data.length * 8); | ||
return binl2rstr(binl_md5(opad.concat(hash), 512 + 128)); | ||
} | ||
/* | ||
* Convert a raw string to a hex string | ||
*/ | ||
function rstr2hex(input) | ||
{ | ||
try { hexcase } catch(e) { hexcase=0; } | ||
var hex_tab = hexcase ? "0123456789ABCDEF" : "0123456789abcdef"; | ||
var output = ""; | ||
var x; | ||
for(var i = 0; i < input.length; i++) | ||
{ | ||
x = input.charCodeAt(i); | ||
output += hex_tab.charAt((x >>> 4) & 0x0F) | ||
+ hex_tab.charAt( x & 0x0F); | ||
} | ||
return output; | ||
} | ||
/* | ||
* Convert a raw string to a base-64 string | ||
*/ | ||
function rstr2b64(input) | ||
{ | ||
try { b64pad } catch(e) { b64pad=''; } | ||
var tab = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; | ||
var output = ""; | ||
var len = input.length; | ||
for(var i = 0; i < len; i += 3) | ||
{ | ||
var triplet = (input.charCodeAt(i) << 16) | ||
| (i + 1 < len ? input.charCodeAt(i+1) << 8 : 0) | ||
| (i + 2 < len ? input.charCodeAt(i+2) : 0); | ||
for(var j = 0; j < 4; j++) | ||
{ | ||
if(i * 8 + j * 6 > input.length * 8) output += b64pad; | ||
else output += tab.charAt((triplet >>> 6*(3-j)) & 0x3F); | ||
} | ||
} | ||
return output; | ||
} | ||
/* | ||
* Convert a raw string to an arbitrary string encoding | ||
*/ | ||
function rstr2any(input, encoding) | ||
{ | ||
var divisor = encoding.length; | ||
var i, j, q, x, quotient; | ||
/* Convert to an array of 16-bit big-endian values, forming the dividend */ | ||
var dividend = Array(Math.ceil(input.length / 2)); | ||
for(i = 0; i < dividend.length; i++) | ||
{ | ||
dividend[i] = (input.charCodeAt(i * 2) << 8) | input.charCodeAt(i * 2 + 1); | ||
} | ||
/* | ||
* Repeatedly perform a long division. The binary array forms the dividend, | ||
* the length of the encoding is the divisor. Once computed, the quotient | ||
* forms the dividend for the next step. All remainders are stored for later | ||
* use. | ||
*/ | ||
var full_length = Math.ceil(input.length * 8 / | ||
(Math.log(encoding.length) / Math.log(2))); | ||
var remainders = Array(full_length); | ||
for(j = 0; j < full_length; j++) | ||
{ | ||
quotient = Array(); | ||
x = 0; | ||
for(i = 0; i < dividend.length; i++) | ||
{ | ||
x = (x << 16) + dividend[i]; | ||
q = Math.floor(x / divisor); | ||
x -= q * divisor; | ||
if(quotient.length > 0 || q > 0) | ||
quotient[quotient.length] = q; | ||
} | ||
remainders[j] = x; | ||
dividend = quotient; | ||
} | ||
/* Convert the remainders to the output string */ | ||
var output = ""; | ||
for(i = remainders.length - 1; i >= 0; i--) | ||
output += encoding.charAt(remainders[i]); | ||
return output; | ||
} | ||
/* | ||
* Encode a string as utf-8. | ||
* For efficiency, this assumes the input is valid utf-16. | ||
*/ | ||
function str2rstr_utf8(input) | ||
{ | ||
var output = ""; | ||
var i = -1; | ||
var x, y; | ||
while(++i < input.length) | ||
{ | ||
/* Decode utf-16 surrogate pairs */ | ||
x = input.charCodeAt(i); | ||
y = i + 1 < input.length ? input.charCodeAt(i + 1) : 0; | ||
if(0xD800 <= x && x <= 0xDBFF && 0xDC00 <= y && y <= 0xDFFF) | ||
{ | ||
x = 0x10000 + ((x & 0x03FF) << 10) + (y & 0x03FF); | ||
i++; | ||
} | ||
/* Encode output as utf-8 */ | ||
if(x <= 0x7F) | ||
output += String.fromCharCode(x); | ||
else if(x <= 0x7FF) | ||
output += String.fromCharCode(0xC0 | ((x >>> 6 ) & 0x1F), | ||
0x80 | ( x & 0x3F)); | ||
else if(x <= 0xFFFF) | ||
output += String.fromCharCode(0xE0 | ((x >>> 12) & 0x0F), | ||
0x80 | ((x >>> 6 ) & 0x3F), | ||
0x80 | ( x & 0x3F)); | ||
else if(x <= 0x1FFFFF) | ||
output += String.fromCharCode(0xF0 | ((x >>> 18) & 0x07), | ||
0x80 | ((x >>> 12) & 0x3F), | ||
0x80 | ((x >>> 6 ) & 0x3F), | ||
0x80 | ( x & 0x3F)); | ||
} | ||
return output; | ||
} | ||
/* | ||
* Encode a string as utf-16 | ||
*/ | ||
function str2rstr_utf16le(input) | ||
{ | ||
var output = ""; | ||
for(var i = 0; i < input.length; i++) | ||
output += String.fromCharCode( input.charCodeAt(i) & 0xFF, | ||
(input.charCodeAt(i) >>> 8) & 0xFF); | ||
return output; | ||
} | ||
function str2rstr_utf16be(input) | ||
{ | ||
var output = ""; | ||
for(var i = 0; i < input.length; i++) | ||
output += String.fromCharCode((input.charCodeAt(i) >>> 8) & 0xFF, | ||
input.charCodeAt(i) & 0xFF); | ||
return output; | ||
} | ||
/* | ||
* Convert a raw string to an array of little-endian words | ||
* Characters >255 have their high-byte silently ignored. | ||
*/ | ||
function rstr2binl(input) | ||
{ | ||
var output = Array(input.length >> 2); | ||
for(var i = 0; i < output.length; i++) | ||
output[i] = 0; | ||
for(var i = 0; i < input.length * 8; i += 8) | ||
output[i>>5] |= (input.charCodeAt(i / 8) & 0xFF) << (i%32); | ||
return output; | ||
} | ||
/* | ||
* Convert an array of little-endian words to a string | ||
*/ | ||
function binl2rstr(input) | ||
{ | ||
var output = ""; | ||
for(var i = 0; i < input.length * 32; i += 8) | ||
output += String.fromCharCode((input[i>>5] >>> (i % 32)) & 0xFF); | ||
return output; | ||
} | ||
/* | ||
* Calculate the MD5 of an array of little-endian words, and a bit length. | ||
*/ | ||
function binl_md5(x, len) | ||
{ | ||
/* append padding */ | ||
@@ -342,2 +135,3 @@ x[len >> 5] |= 0x80 << ((len) % 32); | ||
return Array(a, b, c, d); | ||
} | ||
@@ -370,2 +164,21 @@ | ||
/* | ||
* Calculate the HMAC-MD5, of a key and some data | ||
*/ | ||
function core_hmac_md5(key, data) | ||
{ | ||
var bkey = str2binl(key); | ||
if(bkey.length > 16) bkey = core_md5(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 hash = core_md5(ipad.concat(str2binl(data)), 512 + data.length * chrsz); | ||
return core_md5(opad.concat(hash), 512 + 128); | ||
} | ||
/* | ||
* Add integers, wrapping at 2^32. This uses 16-bit operations internally | ||
@@ -389,10 +202,68 @@ * to work around bugs in some JS interpreters. | ||
/* | ||
* Convert a string to an array of little-endian words | ||
* If chrsz is ASCII, characters >255 have their hi-byte silently ignored. | ||
*/ | ||
function str2binl(str) | ||
{ | ||
var bin = Array(); | ||
var mask = (1 << chrsz) - 1; | ||
for(var i = 0; i < str.length * chrsz; i += chrsz) | ||
bin[i>>5] |= (str.charCodeAt(i / chrsz) & mask) << (i%32); | ||
return bin; | ||
} | ||
/* | ||
* Convert an array of little-endian words to a string | ||
*/ | ||
function binl2str(bin) | ||
{ | ||
var str = ""; | ||
var mask = (1 << chrsz) - 1; | ||
for(var i = 0; i < bin.length * 32; i += chrsz) | ||
str += String.fromCharCode((bin[i>>5] >>> (i % 32)) & mask); | ||
return str; | ||
} | ||
/* | ||
* Convert an array of little-endian words to a hex string. | ||
*/ | ||
function binl2hex(binarray) | ||
{ | ||
var hex_tab = hexcase ? "0123456789ABCDEF" : "0123456789abcdef"; | ||
var str = ""; | ||
for(var i = 0; i < binarray.length * 4; i++) | ||
{ | ||
str += hex_tab.charAt((binarray[i>>2] >> ((i%4)*8+4)) & 0xF) + | ||
hex_tab.charAt((binarray[i>>2] >> ((i%4)*8 )) & 0xF); | ||
} | ||
return str; | ||
} | ||
/* | ||
* Convert an array of little-endian words to a base-64 string | ||
*/ | ||
function binl2b64(binarray) | ||
{ | ||
var tab = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; | ||
var str = ""; | ||
for(var i = 0; i < binarray.length * 4; i += 3) | ||
{ | ||
var triplet = (((binarray[i >> 2] >> 8 * ( i %4)) & 0xFF) << 16) | ||
| (((binarray[i+1 >> 2] >> 8 * ((i+1)%4)) & 0xFF) << 8 ) | ||
| ((binarray[i+2 >> 2] >> 8 * ((i+2)%4)) & 0xFF); | ||
for(var j = 0; j < 4; j++) | ||
{ | ||
if(i * 8 + j * 6 > binarray.length * 32) str += b64pad; | ||
else str += tab.charAt((triplet >> 6*(3-j)) & 0x3F); | ||
} | ||
} | ||
return str; | ||
} | ||
exports.hex_md5 = hex_md5; | ||
exports.b64_md5 = b64_md5; | ||
exports.bin_md5 = bin_md5; | ||
exports.any_md5 = any_md5; | ||
exports.bin_md5 = str_md5; | ||
exports.hex_hmac_md5 = hex_hmac_md5; | ||
exports.b64_hmac_md5 = b64_hmac_md5; | ||
exports.bin_hmac_md5 = bin_hmac_md5; | ||
exports.any_hmac_md5 = any_hmac_md5; | ||
exports.bin_hmac_md5 = str_hmac_md5; |
@@ -5,3 +5,3 @@ { | ||
"description": "partial implementation of crypto for the browser", | ||
"version": "1.0.1", | ||
"version": "1.0.2", | ||
"homepage": "https://github.com/dominictarr/crypto-browserify", | ||
@@ -8,0 +8,0 @@ "repository": { |
@@ -1,5 +0,5 @@ | ||
var test = require('tape') | ||
var Buffer = require('buffer').Buffer | ||
var test = require('tape'); | ||
var Buffer = require('buffer').Buffer; | ||
var crypto = require('../') | ||
var crypto = require('../'); | ||
@@ -40,2 +40,11 @@ var algorithms = ['sha1', 'sha256', 'md5']; | ||
EXPECTED['md5-with-binary'] = '27549c8ff29ca52f7957f89c328dbb6d'; | ||
EXPECTED['sha1-with-binary'] = '4fa10dda29053b237b5d9703151c852c61e6d8d7'; | ||
EXPECTED['sha256-with-binary'] = '424ff84246aabc1560a2881b9664108dfe26784c762d930c4ff396c085f4183b'; | ||
EXPECTED['md5-empty-string'] = 'd41d8cd98f00b204e9800998ecf8427e'; | ||
EXPECTED['sha1-empty-string'] = 'da39a3ee5e6b4b0d3255bfef95601890afd80709'; | ||
EXPECTED['sha256-empty-string'] = 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855'; | ||
algorithms.forEach(function (algorithm) { | ||
@@ -59,14 +68,35 @@ encodings.forEach(function (encoding) { | ||
}); | ||
test(algorithm + ' with empty string', function (t) { | ||
t.plan(1); | ||
var actual = crypto.createHash(algorithm).update('', 'utf-8').digest('hex'); | ||
var expected = EXPECTED[algorithm + '-empty-string']; | ||
t.equal(actual, expected); | ||
t.end(); | ||
}); | ||
test(algorithm + ' with raw binary', function (t) { | ||
t.plan(1); | ||
var seed = 'hello'; | ||
for (var i = 0; i < 1000; i++) { | ||
seed = crypto.createHash(algorithm).update(seed).digest('binary'); | ||
} | ||
var actual = crypto.createHash(algorithm).update(seed).digest('hex'); | ||
var expected = EXPECTED[algorithm + '-with-binary']; | ||
t.equal(actual, expected); | ||
t.end(); | ||
}); | ||
}); | ||
test('randomBytes', function (t) { | ||
t.plan(5) | ||
t.equal(crypto.randomBytes(10).length, 10) | ||
t.ok(crypto.randomBytes(10) instanceof Buffer) | ||
crypto.randomBytes(10, function(ex, bytes) { | ||
t.error(ex) | ||
t.equal(bytes.length, 10) | ||
t.ok(bytes instanceof Buffer) | ||
t.end() | ||
}) | ||
}) | ||
t.plan(5); | ||
t.equal(crypto.randomBytes(10).length, 10); | ||
t.ok(crypto.randomBytes(10) instanceof Buffer); | ||
crypto.randomBytes(10, function(ex, bytes) { | ||
t.error(ex); | ||
t.equal(bytes.length, 10); | ||
t.ok(bytes instanceof Buffer); | ||
t.end(); | ||
}); | ||
}); |
@@ -1,16 +0,16 @@ | ||
var test = require("tape") | ||
var test = require('tape'); | ||
var crypto = require('crypto') | ||
var cryptoB = require('../') | ||
var crypto = require('crypto'); | ||
var cryptoB = require('../'); | ||
function assertSame(name, fn) { | ||
test(name, function (t) { | ||
t.plan(1) | ||
fn(crypto, function (err, expected) { | ||
fn(cryptoB, function (err, actual) { | ||
t.equal(actual, expected) | ||
t.end() | ||
}) | ||
}) | ||
}) | ||
test(name, function (t) { | ||
t.plan(1); | ||
fn(crypto, function (err, expected) { | ||
fn(cryptoB, function (err, actual) { | ||
t.equal(actual, expected); | ||
t.end(); | ||
}); | ||
}); | ||
}); | ||
} | ||
@@ -24,3 +24,2 @@ | ||
encodings.forEach(function (encoding) { | ||
assertSame(algorithm + ' hash using ' + encoding, function (crypto, cb) { | ||
@@ -33,16 +32,28 @@ cb(null, crypto.createHash(algorithm).update('hello', 'utf-8').digest(encoding)); | ||
}) | ||
}); | ||
assertSame(algorithm + ' with raw binary', function (crypto, cb) { | ||
var seed = 'hello'; | ||
for (var i = 0; i < 1000; i++) { | ||
seed = crypto.createHash(algorithm).update(seed).digest('binary'); | ||
} | ||
cb(null, crypto.createHash(algorithm).update(seed).digest('hex')); | ||
}); | ||
assertSame(algorithm + ' empty string', function (crypto, cb) { | ||
cb(null, crypto.createHash(algorithm).update('').digest('hex')); | ||
}); | ||
}); | ||
test('randomBytes', function (t) { | ||
t.plan(5) | ||
t.equal(cryptoB.randomBytes(10).length, 10) | ||
t.ok(cryptoB.randomBytes(10) instanceof Buffer) | ||
cryptoB.randomBytes(10, function(ex, bytes) { | ||
t.error(ex) | ||
t.equal(bytes.length, 10) | ||
t.ok(bytes instanceof Buffer) | ||
t.end() | ||
}) | ||
}) | ||
t.plan(5); | ||
t.equal(cryptoB.randomBytes(10).length, 10); | ||
t.ok(cryptoB.randomBytes(10) instanceof Buffer); | ||
cryptoB.randomBytes(10, function(ex, bytes) { | ||
t.error(ex); | ||
t.equal(bytes.length, 10); | ||
t.ok(bytes instanceof Buffer); | ||
t.end(); | ||
}); | ||
}); |
50253
1411