372 lines
11 KiB
JavaScript
372 lines
11 KiB
JavaScript
/**
|
|
* md6hash for Javascript
|
|
*
|
|
* Authors: Amrit Panesar [Neo-Desktop]
|
|
* Snack-X
|
|
* cuixiping
|
|
*
|
|
* Note: This package uses the UMD pattern.
|
|
*
|
|
* Usage :
|
|
* var md6 = new md6hash();
|
|
* var data = "md6 FTW";
|
|
* var result = md6.hex(data);
|
|
* console.log(result); // 7bfaa624f661a683be2a3b2007493006a30a7845ee1670e499927861a8e74cce
|
|
*
|
|
* For node.js:
|
|
* var md6hash = require("node-md6");
|
|
*/
|
|
|
|
(function (root, factory) {
|
|
var packageName = 'md6hash';
|
|
|
|
if (typeof define === 'function' && define.amd) {
|
|
// AMD. Register as an anonymous module.
|
|
define([], factory);
|
|
} else if (typeof module === 'object' && module.exports) {
|
|
// Node. Does not work with strict CommonJS, but
|
|
// only CommonJS-like environments that support module.exports,
|
|
// like Node.
|
|
module.exports = factory();
|
|
} else {
|
|
// Browser globals (root is window)
|
|
root[packageName] = factory();
|
|
}
|
|
}(this, function () {
|
|
|
|
var exports = {};
|
|
|
|
exports._hash = function () {
|
|
function to_word(input) {
|
|
var i, length = input.length, output = [];
|
|
|
|
for (i = 0; i < length; i += 8) {
|
|
output.push([
|
|
((input[i] & 0xff) << 24) | ((input[i + 1] & 0xff) << 16) |
|
|
((input[i + 2] & 0xff) << 8) | ((input[i + 3] & 0xff) << 0),
|
|
|
|
((input[i + 4] & 0xff) << 24) | ((input[i + 5] & 0xff) << 16) |
|
|
((input[i + 6] & 0xff) << 8) | ((input[i + 7] & 0xff) << 0)
|
|
]);
|
|
}
|
|
|
|
return output;
|
|
}
|
|
|
|
function from_word(input) {
|
|
var i, length = input.length, output = [];
|
|
|
|
for (i = 0; i < length; i += 1) {
|
|
output.push((input[i][0] >> 24) & 0xff);
|
|
output.push((input[i][0] >> 16) & 0xff);
|
|
output.push((input[i][0] >> 8) & 0xff);
|
|
output.push((input[i][0] >> 0) & 0xff);
|
|
output.push((input[i][1] >> 24) & 0xff);
|
|
output.push((input[i][1] >> 16) & 0xff);
|
|
output.push((input[i][1] >> 8) & 0xff);
|
|
output.push((input[i][1] >> 0) & 0xff);
|
|
}
|
|
|
|
return output;
|
|
}
|
|
|
|
function _xor(x, y) {
|
|
return [
|
|
x[0] ^ y[0],
|
|
x[1] ^ y[1]
|
|
];
|
|
}
|
|
|
|
function _and(x, y) {
|
|
return [
|
|
x[0] & y[0],
|
|
x[1] & y[1]
|
|
];
|
|
}
|
|
|
|
function _shl(x, n) {
|
|
var a = x[0] | 0x0,
|
|
b = x[1] | 0x0;
|
|
|
|
if (n >= 32) {
|
|
return [
|
|
(b << (n - 32)),
|
|
0x0
|
|
];
|
|
}
|
|
else {
|
|
return [
|
|
((a << n) | (b >>> (32 - n))),
|
|
(b << n)
|
|
];
|
|
}
|
|
}
|
|
|
|
function _shr(x, n) {
|
|
var a = x[0] | 0x0,
|
|
b = x[1] | 0x0;
|
|
|
|
if (n >= 32) {
|
|
return [
|
|
0x0,
|
|
(a >>> (n - 32))
|
|
];
|
|
}
|
|
else {
|
|
return [
|
|
(a >>> n),
|
|
((a << (32 - n)) | (b >>> n))
|
|
];
|
|
}
|
|
}
|
|
|
|
function crop(size, hash, right) {
|
|
var length = Math.floor((size + 7) / 8),
|
|
remain = size % 8;
|
|
|
|
if (right) {
|
|
hash = hash.slice(hash.length - length);
|
|
}
|
|
else {
|
|
hash = hash.slice(0, length);
|
|
}
|
|
|
|
if (remain > 0) {
|
|
hash[length - 1] &= (0xff << (8 - remain)) & 0xff;
|
|
}
|
|
|
|
return hash;
|
|
}
|
|
|
|
function _hash(size, data, key, levels) {
|
|
var b, c, n, d, M, K, k, r, L, ell, S0, Sm, Q, t, rs, ls;
|
|
|
|
b = 512;
|
|
c = 128;
|
|
|
|
n = 89;
|
|
|
|
d = size;
|
|
M = data;
|
|
|
|
K = key.slice(0, 64);
|
|
k = K.length;
|
|
|
|
while (K.length < 64) {
|
|
K.push(0x00);
|
|
}
|
|
|
|
K = to_word(K);
|
|
|
|
r = Math.max((k ? 80 : 0), (40 + (d / 4)));
|
|
|
|
L = levels;
|
|
ell = 0;
|
|
|
|
S0 = [0x01234567, 0x89abcdef];
|
|
Sm = [0x7311c281, 0x2425cfa0];
|
|
|
|
Q = [
|
|
[0x7311c281, 0x2425cfa0], [0x64322864, 0x34aac8e7], [0xb60450e9, 0xef68b7c1],
|
|
[0xe8fb2390, 0x8d9f06f1], [0xdd2e76cb, 0xa691e5bf], [0x0cd0d63b, 0x2c30bc41],
|
|
[0x1f8ccf68, 0x23058f8a], [0x54e5ed5b, 0x88e3775d], [0x4ad12aae, 0x0a6d6031],
|
|
[0x3e7f16bb, 0x88222e0d], [0x8af8671d, 0x3fb50c2c], [0x995ad117, 0x8bd25c31],
|
|
[0xc878c1dd, 0x04c4b633], [0x3b72066c, 0x7a1552ac], [0x0d6f3522, 0x631effcb]
|
|
];
|
|
|
|
t = [17, 18, 21, 31, 67, 89];
|
|
rs = [10, 5, 13, 10, 11, 12, 2, 7, 14, 15, 7, 13, 11, 7, 6, 12];
|
|
ls = [11, 24, 9, 16, 15, 9, 27, 15, 6, 2, 29, 8, 15, 5, 31, 9];
|
|
|
|
function f(N) {
|
|
var i, j, s, x, S = [].concat(S0), A = [].concat(N);
|
|
|
|
for (j = 0, i = n; j < r; j += 1, i += 16) {
|
|
for (s = 0; s < 16; s += 1) {
|
|
x = [].concat(S);
|
|
x = _xor(x, A[i + s - t[5]]);
|
|
x = _xor(x, A[i + s - t[0]]);
|
|
x = _xor(x, _and(A[i + s - t[1]], A[i + s - t[2]]));
|
|
x = _xor(x, _and(A[i + s - t[3]], A[i + s - t[4]]));
|
|
x = _xor(x, _shr(x, rs[s]));
|
|
A[i + s] = _xor(x, _shl(x, ls[s]));
|
|
}
|
|
|
|
S = _xor(_xor(_shl(S, 1), _shr(S, (64 - 1))), _and(S, Sm));
|
|
}
|
|
|
|
return A.slice(A.length - 16);
|
|
}
|
|
|
|
function mid(B, C, i, p, z) {
|
|
var U, V;
|
|
|
|
U = [
|
|
((ell & 0xff) << 24) | ((i / Math.pow(2, 32)) & 0xffffff),
|
|
i & 0xffffffff
|
|
];
|
|
|
|
V = [
|
|
((r & 0xfff) << 16) | ((L & 0xff) << 8) | ((z & 0xf) << 4) | ((p & 0xf000) >> 12),
|
|
(((p & 0xfff) << 20) | ((k & 0xff) << 12) | ((d & 0xfff)))
|
|
];
|
|
|
|
return f([].concat(Q, K, [U, V], C, B));
|
|
}
|
|
|
|
function par(M) {
|
|
var i, l, p, z, P = 0, B = [], C = [];
|
|
z = (M.length > b ? 0 : 1);
|
|
|
|
while ((M.length < 1) || ((M.length % b) > 0)) {
|
|
M.push(0x00);
|
|
P += 8;
|
|
}
|
|
|
|
M = to_word(M);
|
|
|
|
while (M.length > 0) {
|
|
B.push(M.slice(0, (b / 8)));
|
|
M = M.slice(b / 8);
|
|
}
|
|
|
|
for (i = 0, p = 0, l = B.length; i < l; i += 1, p = 0) {
|
|
p = (i === (B.length - 1)) ? P : 0;
|
|
C = C.concat(mid(B[i], [], i, p, z));
|
|
}
|
|
|
|
return from_word(C);
|
|
}
|
|
|
|
function seq(M) {
|
|
var i, l, p, z, P = 0, B = [], C = [
|
|
[0x0, 0x0], [0x0, 0x0], [0x0, 0x0], [0x0, 0x0],
|
|
[0x0, 0x0], [0x0, 0x0], [0x0, 0x0], [0x0, 0x0],
|
|
[0x0, 0x0], [0x0, 0x0], [0x0, 0x0], [0x0, 0x0],
|
|
[0x0, 0x0], [0x0, 0x0], [0x0, 0x0], [0x0, 0x0]
|
|
];
|
|
|
|
while ((M.length < 1) || ((M.length % (b - c)) > 0)) {
|
|
M.push(0x00);
|
|
P += 8;
|
|
}
|
|
|
|
M = to_word(M);
|
|
|
|
while (M.length > 0) {
|
|
B.push(M.slice(0, ((b - c) / 8)));
|
|
M = M.slice((b - c) / 8);
|
|
}
|
|
|
|
for (i = 0, p = 0, l = B.length; i < l; i += 1, p = 0) {
|
|
p = (i === (B.length - 1)) ? P : 0;
|
|
z = (i === (B.length - 1)) ? 1 : 0;
|
|
C = mid(B[i], C, i, p, z);
|
|
}
|
|
|
|
return from_word(C);
|
|
}
|
|
|
|
do {
|
|
ell += 1;
|
|
M = ell > L ? seq(M) : par(M);
|
|
}
|
|
while (M.length !== c);
|
|
|
|
return crop(d, M, true);
|
|
}
|
|
|
|
function bytes(input) {
|
|
var output = [], i, ch;
|
|
|
|
for (i = 0; i < input.length; i++) {
|
|
ch = input.charCodeAt(i);
|
|
if (ch <= 0x7f) {
|
|
output.push(ch);
|
|
}
|
|
else if (ch <= 0x7ff) {
|
|
output.push((ch >> 6) | 0xc0);
|
|
output.push((ch & 0x3F) | 0x80);
|
|
}
|
|
else if (ch <= 0xffff) {
|
|
output.push((ch >> 12) | 0xe0);
|
|
output.push(((ch >> 6) & 0x3f) | 0x80);
|
|
output.push((ch & 0x3f) | 0x80);
|
|
}
|
|
else {
|
|
output.push((ch >> 18) | 0xf0);
|
|
output.push(((ch >> 12) & 0x3f) | 0x80);
|
|
output.push(((ch >> 6) & 0x3f) | 0x80);
|
|
output.push((ch & 0x3f) | 0x80);
|
|
}
|
|
}
|
|
|
|
return output;
|
|
}
|
|
|
|
function _prehash(data, size, key, levels) {
|
|
if (typeof data === "undefined") data = "";
|
|
if (typeof size === "undefined") size = 256;
|
|
if (typeof key === "undefined") key = "";
|
|
if (typeof levels === "undefined") levels = 64;
|
|
|
|
data = bytes(data);
|
|
key = bytes(key);
|
|
|
|
if (size <= 0) size = 1;
|
|
else if (size > 512) size = 512;
|
|
|
|
return _hash(size, data, key, levels);
|
|
}
|
|
|
|
function _hex(data, size, key, levels) {
|
|
var hash = _prehash(data, size, key, levels);
|
|
var hex = "";
|
|
var i;
|
|
|
|
for (i = 0; i < hash.length; i++) {
|
|
var v = hash[i];
|
|
var x = v.toString(16);
|
|
if (x.length === 1) x = "0" + x;
|
|
hex += x;
|
|
}
|
|
|
|
return hex;
|
|
}
|
|
|
|
function _raw(data, size, key, levels) {
|
|
var hash = _prehash(data, size, key, levels);
|
|
var raw = "";
|
|
var i;
|
|
|
|
for (i = 0; i < hash.length; i++) {
|
|
var v = hash[i];
|
|
raw += String.fromCharCode(v);
|
|
}
|
|
|
|
return raw;
|
|
}
|
|
|
|
return {
|
|
hex: _hex,
|
|
raw: _raw
|
|
};
|
|
};
|
|
|
|
exports.getHashOfText = function() {
|
|
var out = _hash.apply(this, arguments);
|
|
return out.hex;
|
|
};
|
|
|
|
exports.getRawHashOfText = function() {
|
|
var out = _hash.apply(this, arguments);
|
|
return out.raw;
|
|
};
|
|
|
|
exports.getHashAsObject = function() {
|
|
return _hash.apply(this, arguments);
|
|
};
|
|
|
|
return exports;
|
|
|
|
})); |