Added 'MD2', 'MD4' and 'SHA0' operations. Closes #52.

This commit is contained in:
n1474335 2017-01-16 16:40:43 +00:00
parent 2257754b94
commit ba8524ca79
12 changed files with 1337 additions and 32 deletions

View File

@ -93,6 +93,10 @@ module.exports = function(grunt) {
"src/js/lib/cryptojs/tripledes.js",
"src/js/lib/cryptojs/rc4.js",
"src/js/lib/cryptojs/pbkdf2.js",
"src/js/lib/cryptoapi/crypto-api.js",
"src/js/lib/cryptoapi/hasher.md2.js",
"src/js/lib/cryptoapi/hasher.md4.js",
"src/js/lib/cryptoapi/hasher.sha0.js",
"src/js/lib/jsbn/jsbn.js",
"src/js/lib/jsbn/jsbn2.js",
"src/js/lib/jsbn/base64.js",

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -214,7 +214,10 @@ var Categories = [
ops: [
"Analyse hash",
"Generate all hashes",
"MD2",
"MD4",
"MD5",
"SHA0",
"SHA1",
"SHA224",
"SHA256",

View File

@ -2541,6 +2541,20 @@ var OperationConfig = {
output_type: "string",
args: []
},
"MD2": {
description: "The MD2 (Message-Digest 2) algorithm is a cryptographic hash function developed by Ronald Rivest in 1989. The algorithm is optimized for 8-bit computers.<br><br>Although MD2 is no longer considered secure, even as of 2014, it remains in use in public key infrastructures as part of certificates generated with MD2 and RSA.",
run: Hash.run_md2,
input_type: "string",
output_type: "string",
args: []
},
"MD4": {
description: "The MD4 (Message-Digest 4) algorithm is a cryptographic hash function developed by Ronald Rivest in 1990. The digest length is 128 bits. The algorithm has influenced later designs, such as the MD5, SHA-1 and RIPEMD algorithms.<br><br>The security of MD4 has been severely compromised.",
run: Hash.run_md4,
input_type: "string",
output_type: "string",
args: []
},
"MD5": {
description: "MD5 (Message-Digest 5) is a widely used hash function. It has been used in a variety of security applications and is also commonly used to check the integrity of files.<br><br>However, MD5 is not collision resistant and it isn't suitable for applications like SSL/TLS certificates or digital signatures that rely on this property.",
run: Hash.run_md5,
@ -2548,6 +2562,13 @@ var OperationConfig = {
output_type: "string",
args: []
},
"SHA0": {
description: "SHA-0 is a retronym applied to the original version of the 160-bit hash function published in 1993 under the name 'SHA'. It was withdrawn shortly after publication due to an undisclosed 'significant flaw' and replaced by the slightly revised version SHA-1.",
run: Hash.run_sha0,
input_type: "string",
output_type: "string",
args: []
},
"SHA1": {
description: "The SHA (Secure Hash Algorithm) hash functions were designed by the NSA. SHA-1 is the most established of the existing SHA hash functions and it is used in a variety of security applications and protocols.<br><br>However, SHA-1's collision resistance has been weakening as new attacks are discovered or improved.",
run: Hash.run_sha1,

View File

@ -0,0 +1,768 @@
/** @license
========================================================================
Crypto API for JavaScript - https://github.com/nf404/crypto-api
The MIT License (MIT)
Copyright (c) 2015 nf404
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.
*/
/*global module, require */
(/**
* @param {Object} root
* @returns {CryptoApi}
*/
function (root) {
'use strict';
/**
* @class CryptoApi
* @classdesc Main class
* @public
*/
var CryptoApi = function cryptoApi () {
/**
* @property Hashers
* @type {Hashers}
*/
this.Hashers = new Hashers();
/**
* @property Encodes
* @type {Encodes}
*/
this.Encodes = new Encodes();
/**
* @property Macs
* @type {Macs}
*/
this.Macs = new Macs();
/**
* @property Tools
* @type {Tools}
*/
this.Tools = new Tools();
};
/**
* @interface HasherInterface
* @classdesc All hashers MUST implement this interface
* @public
*/
var HasherInterface = function () {};
/**
* @memberOf HasherInterface
* @constructor
*/
HasherInterface.prototype.constructor = function constructor() {};
/**
* @desc Process ready block
* @memberOf HasherInterface
* @method processBlock
* @param {number[]} block
*/
HasherInterface.prototype.processBlock = function processBlock(block) {};
/**
* Update message
* @memberOf HasherInterface
* @method update
* @param {string} message
*/
HasherInterface.prototype.update = function update(message) {};
/**
* @desc Process last block and return hash
* @memberOf HasherInterface
* @method finalize
* @return {HashArray} hash
*/
HasherInterface.prototype.finalize = function finalize() {};
/**
* @class BaseHasher
* @param {string} name
* @param {Object} options
* @public
*/
var BaseHasher = function(name, options) {};
BaseHasher.prototype.constructor = function (name, options) {
/**
* @desc Hasher name
* @property name
* @type {string}
*/
this.name = name;
/**
* @desc All algorithm variables that changed during process
* @property state
* @type {Object}
*/
this.state = {};
/**
* @desc Unprocessed Message
* @memberof! BaseHasher#
* @alias state.message
* @type {number[]}
*/
this.state.message = [];
/**
* @desc Length of message
* @memberof! BaseHasher#
* @alias state.length
* @type {number}
*/
this.state.length = 0;
/**
* @memberof! BaseHasher#
* @alias state.options
* @type {Object}
*/
this.state.options = options;
this.blockUnits = [];
};
/**
* Size of unit in bytes (4 = 32 bits)
* @memberOf BaseHasher
* @member {number} unitSize
* @static
*/
BaseHasher.prototype.unitSize = 4;
/**
* Bytes order in unit
* 0 - normal
* 1 - reverse
* @memberOf BaseHasher
* @member {number} unitOrder
* @static
*/
BaseHasher.prototype.unitOrder = 0;
/**
* Size of block in units
* @memberOf BaseHasher
* @member {number} blockSize
* @static
*/
BaseHasher.prototype.blockSize = 16;
/**
* Return current state
* @memberOf BaseHasher
* @method getState
* @returns {Object}
*/
BaseHasher.prototype.getState = function getState() {
return JSON.parse(JSON.stringify(this.state));
};
/**
* Set state
* @memberOf BaseHasher
* @method setState
* @param {Object} state
* @return {HasherInterface}
*/
BaseHasher.prototype.setState = function setState(state) {
this.state = state;
return this;
};
/**
* Update message
* @memberOf BaseHasher
* @method update
* @param {string} message
*/
BaseHasher.prototype.update = function update(message) {
var l = 0;
for (var i = 0, msgLen = message.length; i < msgLen; i++) {
var charcode = message.charCodeAt(i);
if (charcode < 0x80) {
this.state.message.push(charcode);
l += 1;
}
else if (charcode < 0x800) {
this.state.message.push(0xc0 | (charcode >> 6),
0x80 | (charcode & 0x3f));
l += 2;
}
else if (charcode < 0xd800 || charcode >= 0xe000) {
this.state.message.push(0xe0 | (charcode >> 12),
0x80 | ((charcode >> 6) & 0x3f),
0x80 | (charcode & 0x3f));
l += 3;
}
// surrogate pair
else {
i++;
// UTF-16 encodes 0x10000-0x10FFFF by
// subtracting 0x10000 and splitting the
// 20 bits of 0x0-0xFFFFF into two halves
charcode = 0x10000 + (((charcode & 0x3ff) << 10)
| (message.charCodeAt(i) & 0x3ff));
this.state.message.push(0xf0 | (charcode >> 18),
0x80 | ((charcode >> 12) & 0x3f),
0x80 | ((charcode >> 6) & 0x3f),
0x80 | (charcode & 0x3f));
l += 4;
}
}
this.state.length += l;
this.process();
};
/**
* Update message from array
* @memberOf BaseHasher
* @method updateFromArray
* @param {number[]} message
* @return {BaseHasher}
*/
BaseHasher.prototype.updateFromArray = function updateFromArray(message) {
this.state.length += message.length;
this.state.message = this.state.message.concat(message);
this.process();
return this;
};
/**
* Process ready blocks
* @memberOf BaseHasher
* @method process
*/
BaseHasher.prototype.process = function process() {
while (this.state.message.length >= this.blockSize * this.unitSize) {
var j = 0, b = 0, block = this.state.message.splice(0, this.blockSize * this.unitSize);
if (this.unitSize > 1) {
this.blockUnits = [];
for (var i = 0, u = 0; i < block.length; i += this.unitSize, u++) {
if (this.unitOrder === 1) {
for (j = this.unitSize - 1, b = 0; j >= 0; j--, b += 8) {
this.blockUnits[u] |= (block[i + j] << b);
}
} else {
for (j = 0, b = 0; j < this.unitSize; j++, b += 8) {
this.blockUnits[u] |= (block[i + j] << b);
}
}
}
this.processBlock(this.blockUnits);
} else {
this.processBlock(block);
}
}
};
/**
* @memberOf CryptoApi
* @member {BaseHasher} BaseHasher
*/
CryptoApi.prototype.BaseHasher = BaseHasher;
/**
* @class Hasher8
* @desc Hasher for 32 bit little endian blocks
* @extends BaseHasher
* @param {string} name
* @param {Object} options
* @public
*/
var Hasher8 = function (name, options) {
this.constructor(name, options);
};
Hasher8.prototype = Object.create(BaseHasher.prototype);
/**
* @desc Normal order of bytes
* @memberOf Hasher8#
* @member {number} unitOrder
*/
Hasher8.prototype.unitOrder = 0;
/**
* @desc Size of unit = 1 byte
* @memberOf Hasher8#
* @member {number} unitSize
*/
Hasher8.prototype.unitSize = 1;
/**
* @memberOf Hasher8
* @constructor
* @param {string} name
* @param {Object} options
*/
Hasher8.prototype.constructor = function (name, options) {
BaseHasher.prototype.constructor.call(this, name, options);
};
/**
* Process ready blocks
* @memberOf Hasher8
* @method process
*/
Hasher8.prototype.process = function process() {
while (this.state.message.length >= this.blockSize * this.unitSize) {
var block = this.state.message.splice(0, this.blockSize * this.unitSize);
this.blockUnits = [];
for (var i = 0; i < this.blockSize; i++) {
this.blockUnits[i] = (block[i]);
}
this.processBlock(this.blockUnits);
}
};
/**
* @memberOf CryptoApi
* @member {Hasher8} Hasher8
*/
CryptoApi.prototype.Hasher8 = Hasher8;
/**
* @class Hasher32le
* @desc Hasher for 32 bit little endian blocks
* @extends BaseHasher
* @param {string} name
* @param {Object} options
* @public
*/
var Hasher32le = function (name, options) {
this.constructor(name, options);
};
Hasher32le.prototype = Object.create(BaseHasher.prototype);
Hasher32le.prototype.unitOrder = 0; // Normal order of bytes
/**
* @memberOf Hasher32le
* @constructor
* @param {string} name
* @param {Object} options
*/
Hasher32le.prototype.constructor = function (name, options) {
BaseHasher.prototype.constructor.call(this, name, options);
};
/**
* Process ready blocks
* @memberOf Hasher32le
* @method process
*/
Hasher32le.prototype.process = function process() {
while (this.state.message.length >= this.blockSize * this.unitSize) {
var block = this.state.message.splice(0, this.blockSize * this.unitSize);
this.blockUnits = [];
for (var i = 0, b = 0; i < this.blockSize; i++, b+=4) {
this.blockUnits[i] = (block[b]);
this.blockUnits[i] |= (block[b + 1] << 8);
this.blockUnits[i] |= (block[b + 2] << 16);
this.blockUnits[i] |= (block[b + 3] << 24);
}
this.processBlock(this.blockUnits);
}
};
/**
* @memberOf CryptoApi
* @member {Hasher32le} Hasher32
*/
CryptoApi.prototype.Hasher32le = Hasher32le;
/**
* @class Hasher32be
* @desc Hasher for 32 bit big endian blocks
* @extends BaseHasher
* @param {string} name
* @param {Object} options
* @public
*/
var Hasher32be = function (name, options) {
this.constructor(name, options);
};
Hasher32be.prototype = Object.create(BaseHasher.prototype);
Hasher32be.prototype.unitOrder = 1; // Reverse order of bytes
/**
* @memberOf Hasher32be
* @constructor
* @param {string} name
* @param {Object} options
*/
Hasher32be.prototype.constructor = function (name, options) {
BaseHasher.prototype.constructor.call(this, name, options);
};
/**
* Process ready blocks
* @memberOf Hasher32be
* @method process
*/
Hasher32be.prototype.process = function process() {
while (this.state.message.length >= this.blockSize * this.unitSize) {
var block = this.state.message.splice(0, this.blockSize * this.unitSize);
this.blockUnits = [];
for (var i = 0, b = 0; i < this.blockSize; i++, b+=4) {
this.blockUnits[i] = (block[b] << 24);
this.blockUnits[i] |= (block[b + 1] << 16);
this.blockUnits[i] |= (block[b + 2] << 8);
this.blockUnits[i] |= (block[b + 3]);
}
this.processBlock(this.blockUnits);
}
};
/**
* @memberOf CryptoApi
* @member {Hasher32be} Hasher32be
*/
CryptoApi.prototype.Hasher32be = Hasher32be;
/**
* @interface MacInterface
* @classdesc All coders MUST implement this interface
* @public
*/
var MacInterface = function () {};
/**
* @memberOf MacInterface
* @param {string|number[]} key
* @param {string} hasher
* @param {Object} options
* @constructor
*/
MacInterface.prototype.constructor = function constructor(key, hasher, options) {};
/**
* @desc Process ready block
* @memberOf MacInterface
* @method processBlock
* @param {number[]} block
*/
MacInterface.prototype.processBlock = function processBlock(block) {};
/**
* Update message
* @memberOf MacInterface
* @method update
* @param {string|number[]} message
* @return {MacInterface}
*/
MacInterface.prototype.update = function update(message) {};
/**
* @desc Process last block and return hash
* @memberOf MacInterface
* @method finalize
* @return {HashArray} hash
*/
MacInterface.prototype.finalize = function finalize() {};
/**
* @class BaseMac
* @extends BaseHasher
* @param {string|number[]} key
* @param {string} hasher
* @param {Object} options
* @public
*/
var BaseMac = function(key, hasher, options) {};
BaseMac.prototype = Object.create(BaseHasher.prototype);
BaseMac.prototype.constructor = function (key, hasher, options) {
BaseHasher.prototype.constructor.call(this, hasher, options);
};
/**
* @memberOf CryptoApi
* @member {BaseMac} BaseMac
*/
CryptoApi.prototype.BaseMac = BaseMac;
/**
* @interface EncodeInterface
* @classdesc All encodes MUST implement this interface
* @public
*/
var EncodeInterface = function () {};
/**
* @memberOf EncodeInterface
* @constructor
* @param {HashArray} hash
*/
EncodeInterface.prototype.constructor = function constructor(hash) {};
/**
* @desc Stringify hash
* @memberOf EncodeInterface
* @method stringify
* @returns {string}
*/
EncodeInterface.prototype.stringify = function encode() {};
/**
* @class BaseEncode
* @desc Encode HashArray
* @param {HashArray} hash
* @public
*/
var BaseEncode = function (hash) {};
/**
* @memberOf BaseEncode
* @constructor
* @param {HashArray} hash
*/
BaseEncode.prototype.constructor = function constructor(hash) {
/**
* @property hash
* @type {HashArray}
*/
this.hash = hash;
};
/**
* @memberOf CryptoApi
* @member {BaseEncode} BaseEncode
*/
CryptoApi.prototype.BaseEncode = BaseEncode;
/**
* @class Hashers
* @classdesc Collection of hashers
*/
var Hashers = function hashers() {
/**
* @property hashers
* @type {Object}
*/
this.hashers = {};
};
/**
* @memberOf Hashers
* @method add
* @param {string} name
* @param {HasherInterface} hasher
*/
Hashers.prototype.add = function add(name, hasher) {
if (hasher === undefined) {
throw Error('Error adding hasher: ' + name);
}
this.hashers[name] = hasher;
};
/**
* @memberOf Hashers
* @method add
* @param {string} name
* @param {Object} options
* @returns {HasherInterface}
*/
Hashers.prototype.get = function get(name, options) {
var Hasher = this.hashers[name];
if ((Hasher === undefined) && (typeof require !== 'undefined')) {
var filename = name;
if (filename === 'sha224') {
filename = 'sha256';
}
require('./hasher.' + filename);
Hasher = this.hashers[name];
}
if (Hasher === undefined) {
throw Error('No hash algorithm: ' + name);
}
return new Hasher(name, options);
};
/**
* @class Encodes
* @classdesc Collection of encodes
*/
var Encodes = function encodes() {
/**
* @property encodes
* @type {Object}
*/
this.encodes = {};
};
/**
* @memberOf Encodes
* @method add
* @param {string} name
* @param {BaseEncode} encode
*/
Encodes.prototype.add = function add(name, encode) {
if (encode === undefined) {
throw Error('Error adding encode: ' + name);
}
this.encodes[name] = encode;
};
/**
* @memberOf Encodes
* @method get
* @param {string} name
* @param {HashArray} hash
* @returns {BaseEncode}
*/
Encodes.prototype.get = function get(name, hash) {
var Encode = this.encodes[name];
if ((Encode === undefined) && (typeof require !== 'undefined')) {
require('./enc.' + name);
Encode = this.encodes[name];
}
if (Encode === undefined) {
throw Error('No encode type: ' + name);
}
return new Encode(hash);
};
/**
* @class Macs
* @classdesc Collection of macs
*/
var Macs = function macs() {
/**
* @property macs
* @type {Object}
*/
this.macs = {};
};
/**
* @memberOf Macs
* @method add
* @param {string} name
* @param {BaseMac} mac
*/
Macs.prototype.add = function add(name, mac) {
if (mac === undefined) {
throw Error('Error adding mac: ' + name);
}
this.macs[name] = mac;
};
/**
* @memberOf Macs
* @method get
* @param {string} name
* @param {string|number[]} key
* @param {string} hasher
* @param {Object} options
* @returns {MacInterface}
*/
Macs.prototype.get = function get(name, key, hasher, options) {
var Mac = this.macs[name];
if ((Mac === undefined) && (typeof require !== 'undefined')) {
require('./mac.' + name);
Mac = this.macs[name];
}
if (Mac === undefined) {
throw Error('No mac type: ' + name);
}
return new Mac(key, hasher, options);
};
/**
* @class Tools
* @classdesc Helper with some methods
*/
var Tools = function tools() {};
/**
* Rotate x to n bits left
* @memberOf Tools
* @method rotateLeft
* @param {number} x
* @param {number} n
* @returns {number}
*/
Tools.prototype.rotateLeft = function rotateLeft(x, n) {
return ((x << n) | (x >>> (32 - n))) | 0;
};
/**
* Rotate x to n bits right
* @memberOf Tools
* @method rotateLeft
* @param {number} x
* @param {number} n
* @returns {number}
*/
Tools.prototype.rotateRight = function rotateLeft(x, n) {
return ((x >>> n) | (x << (32 - n))) | 0;
};
/**
* @class HashArray
* @classdesc Array of hash bytes
* @instanceof {Array}
* @param {number[]} hash
* @param {Encodes} Encodes
* @public
*/
var HashArray = function (hash, Encodes) {
Array.prototype.push.apply(this, hash);
/**
* @property Encodes
* @type {Encodes}
*/
this.Encodes = Encodes;
};
HashArray.prototype = Object.create(Array.prototype);
HashArray.prototype.constructor = HashArray;
/**
* Get hash as string
* @param {string} method
* @returns {string|*}
*/
HashArray.prototype.stringify = function stringify(method) {
return this.Encodes.get(method, this).stringify();
};
/**
* Hash message with algo
*
* @memberof CryptoApi
* @method hash
* @public
* @param {string} algo
* @param {string} message
* @param {Object} options
* @return {HashArray} hash
*/
CryptoApi.prototype.hash = function hash(algo, message, options) {
var hash = this.hasher(algo, options);
hash.update(message);
return hash.finalize();
};
/**
* Get new Hasher object
*
* @memberof CryptoApi
* @method hasher
* @public
* @param {string} algo
* @param {Object} options
* @returns {HasherInterface}
*/
CryptoApi.prototype.hasher = function hasher(algo, options) {
return this.Hashers.get(algo, options);
};
/**
* Get new MAC object
*
* @memberof CryptoApi
* @method mac
* @public
* @param {string} algo
* @param {string|number[]} key
* @param {string} hasher
* @param {Object} options
* @returns {MacInterface}
*/
CryptoApi.prototype.mac = function mac(algo, key, hasher, options) {
return this.Macs.get(algo, key, hasher, options);
};
/**
* Get new HashArray
*
* @memberof CryptoApi
* @method hashArray
* @public
* @param {number[]} hash
* @returns {HashArray}
*/
CryptoApi.prototype.hashArray = function hashArray(hash) {
return new HashArray(hash, this.Encodes);
};
root.CryptoApi = new CryptoApi();
if (typeof module !== 'undefined' && module.exports) {
module.exports = root.CryptoApi;
} else {
return root.CryptoApi;
}
})(this);

View File

@ -0,0 +1,113 @@
/*global require */
(/**
* @param {CryptoApi} CryptoApi
* @returns {Md2}
*/
function (CryptoApi) {
'use strict';
/**
* @class Md2
* @extends Hasher8
* @implements HasherInterface
* @desc Md2 hasher
*/
var Md2 = function (name, options) {
this.constructor(name, options);
};
Md2.prototype = Object.create(CryptoApi.Hasher8.prototype);
/**
* @memberOf Md2
* @constructor
*/
Md2.prototype.constructor = function (name, options) {
CryptoApi.Hasher8.prototype.constructor.call(this, name, options);
/**
* @desc Hash state
* @memberOf! Md2#
* @alias state.hash
* @type {number[]}
*/
this.state.hash = new Array(48);
/**
* @desc Checksum
* @memberOf! Md2#
* @alias state.checksum
* @type {number[]}
*/
this.state.checksum = new Array(16);
};
/**
* @desc Constants from Pi
* @link https://github.com/e-sushi/MD2-S-box-creator
* @memberOf Md2#
* @member {number[]} piSubst
*/
Md2.prototype.piSubst = [
0x29, 0x2E, 0x43, 0xC9, 0xA2, 0xD8, 0x7C, 0x01, 0x3D, 0x36, 0x54, 0xA1, 0xEC, 0xF0, 0x06, 0x13,
0x62, 0xA7, 0x05, 0xF3, 0xC0, 0xC7, 0x73, 0x8C, 0x98, 0x93, 0x2B, 0xD9, 0xBC, 0x4C, 0x82, 0xCA,
0x1E, 0x9B, 0x57, 0x3C, 0xFD, 0xD4, 0xE0, 0x16, 0x67, 0x42, 0x6F, 0x18, 0x8A, 0x17, 0xE5, 0x12,
0xBE, 0x4E, 0xC4, 0xD6, 0xDA, 0x9E, 0xDE, 0x49, 0xA0, 0xFB, 0xF5, 0x8E, 0xBB, 0x2F, 0xEE, 0x7A,
0xA9, 0x68, 0x79, 0x91, 0x15, 0xB2, 0x07, 0x3F, 0x94, 0xC2, 0x10, 0x89, 0x0B, 0x22, 0x5F, 0x21,
0x80, 0x7F, 0x5D, 0x9A, 0x5A, 0x90, 0x32, 0x27, 0x35, 0x3E, 0xCC, 0xE7, 0xBF, 0xF7, 0x97, 0x03,
0xFF, 0x19, 0x30, 0xB3, 0x48, 0xA5, 0xB5, 0xD1, 0xD7, 0x5E, 0x92, 0x2A, 0xAC, 0x56, 0xAA, 0xC6,
0x4F, 0xB8, 0x38, 0xD2, 0x96, 0xA4, 0x7D, 0xB6, 0x76, 0xFC, 0x6B, 0xE2, 0x9C, 0x74, 0x04, 0xF1,
0x45, 0x9D, 0x70, 0x59, 0x64, 0x71, 0x87, 0x20, 0x86, 0x5B, 0xCF, 0x65, 0xE6, 0x2D, 0xA8, 0x02,
0x1B, 0x60, 0x25, 0xAD, 0xAE, 0xB0, 0xB9, 0xF6, 0x1C, 0x46, 0x61, 0x69, 0x34, 0x40, 0x7E, 0x0F,
0x55, 0x47, 0xA3, 0x23, 0xDD, 0x51, 0xAF, 0x3A, 0xC3, 0x5C, 0xF9, 0xCE, 0xBA, 0xC5, 0xEA, 0x26,
0x2C, 0x53, 0x0D, 0x6E, 0x85, 0x28, 0x84, 0x09, 0xD3, 0xDF, 0xCD, 0xF4, 0x41, 0x81, 0x4D, 0x52,
0x6A, 0xDC, 0x37, 0xC8, 0x6C, 0xC1, 0xAB, 0xFA, 0x24, 0xE1, 0x7B, 0x08, 0x0C, 0xBD, 0xB1, 0x4A,
0x78, 0x88, 0x95, 0x8B, 0xE3, 0x63, 0xE8, 0x6D, 0xE9, 0xCB, 0xD5, 0xFE, 0x3B, 0x00, 0x1D, 0x39,
0xF2, 0xEF, 0xB7, 0x0E, 0x66, 0x58, 0xD0, 0xE4, 0xA6, 0x77, 0x72, 0xF8, 0xEB, 0x75, 0x4B, 0x0A,
0x31, 0x44, 0x50, 0xB4, 0x8F, 0xED, 0x1F, 0x1A, 0xDB, 0x99, 0x8D, 0x33, 0x9F, 0x11, 0x83, 0x14];
/**
* @memberOf Md2
* @method processBlock
* @param {number[]} block
*/
Md2.prototype.processBlock = function processBlock(block) {
// Append hash
for (var i = 0; i < 16; i++) {
this.state.hash[16 + i] = block[i];
this.state.hash[32 + i] = this.state.hash[16 + i] ^ this.state.hash[i];
}
// 18 Rounds
var t = 0;
for (i = 0; i < 18; i++) {
for (var j = 0; j < 48; j++) {
t = this.state.hash[j] ^= this.piSubst[t];
}
t = (t + i) & 0xff;
}
// Append checksum
t = this.state.checksum[15];
for (i = 0; i < 16; i++) {
t = this.state.checksum[i] ^= this.piSubst[block[i] ^ t];
}
};
/**
* @memberOf Md2
* @method finalize
* @return {HashArray}
*/
Md2.prototype.finalize = function finalize() {
var padLen = this.state.message.length & 0xf;
this.update(new Array(17 - padLen).join(String.fromCharCode(16 - padLen)));
// Process checksum
this.updateFromArray(this.state.checksum);
// Return hash
return CryptoApi.hashArray(this.state.hash.slice(0, 16));
};
CryptoApi.Hashers.add('md2', Md2);
return Md2;
})(
this.CryptoApi || require('./crypto-api')
);

View File

@ -0,0 +1,204 @@
/*global require */
(/**
* @param {CryptoApi} CryptoApi
* @returns {Md4}
*/
function (CryptoApi) {
'use strict';
/**
* @class Md4
* @desc Md4 hasher
* @implements HasherInterface
* @extends Hasher32le
*/
var Md4 = function md4(name, options) {
this.constructor(name, options);
};
Md4.prototype = Object.create(CryptoApi.Hasher32le.prototype);
/**
* @memberOf Md4
* @constructor
*/
Md4.prototype.constructor = function (name, options) {
CryptoApi.Hasher32le.prototype.constructor.call(this, name, options);
/**
* @desc Hash state
* @memberOf! Md4#
* @alias state.hash
* @type {number[]}
*/
this.state.hash = [0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476];
};
/**
* @desc Transform constants
* @memberOf Md4
* @member {number[]} S
* @const
*/
Md4.prototype.S = [
[3, 7, 11, 19],
[3, 5, 9, 13],
[3, 9, 11, 15]
];
Md4.prototype.F = 0x00000000;
Md4.prototype.G = 0x5a827999;
Md4.prototype.H = 0x6ed9eba1;
// Transform functions
/**
* @param {number} x
* @param {number} y
* @param {number} z
* @returns {number}
*/
Md4.prototype.FF = function FF(x, y, z) {
return (x & y) | ((~x) & z);
};
/**
* @param {number} x
* @param {number} y
* @param {number} z
* @returns {number}
*/
Md4.prototype.GG = function GG(x, y, z) {
return (x & y) | (x & z) | (y & z);
};
/**
* @param {number} x
* @param {number} y
* @param {number} z
* @returns {number}
*/
Md4.prototype.HH = function HH(x, y, z) {
return x ^ y ^ z;
};
/**
*
* @param {function} f
* @param {number} k
* @param {number} a
* @param {number} x
* @param {number} y
* @param {number} z
* @param {number} m
* @param {number} s
* @returns {number}
* @constructor
*/
Md4.prototype.CC = function CC(f, k, a, x, y, z, m, s) {
return CryptoApi.Tools.rotateLeft((a + f(x, y, z) + m + k), s) | 0;
};
/**
* @memberOf Md4
* @method processBlock
* @param {number[]} block
*/
Md4.prototype.processBlock = function processBlock(block) {
// Working variables
var a = this.state.hash[0] | 0;
var b = this.state.hash[1] | 0;
var c = this.state.hash[2] | 0;
var d = this.state.hash[3] | 0;
// Round 1
a = this.CC(this.FF, this.F, a, b, c, d, block[0], this.S[0][0]);
d = this.CC(this.FF, this.F, d, a, b, c, block[1], this.S[0][1]);
c = this.CC(this.FF, this.F, c, d, a, b, block[2], this.S[0][2]);
b = this.CC(this.FF, this.F, b, c, d, a, block[3], this.S[0][3]);
a = this.CC(this.FF, this.F, a, b, c, d, block[4], this.S[0][0]);
d = this.CC(this.FF, this.F, d, a, b, c, block[5], this.S[0][1]);
c = this.CC(this.FF, this.F, c, d, a, b, block[6], this.S[0][2]);
b = this.CC(this.FF, this.F, b, c, d, a, block[7], this.S[0][3]);
a = this.CC(this.FF, this.F, a, b, c, d, block[8], this.S[0][0]);
d = this.CC(this.FF, this.F, d, a, b, c, block[9], this.S[0][1]);
c = this.CC(this.FF, this.F, c, d, a, b, block[10], this.S[0][2]);
b = this.CC(this.FF, this.F, b, c, d, a, block[11], this.S[0][3]);
a = this.CC(this.FF, this.F, a, b, c, d, block[12], this.S[0][0]);
d = this.CC(this.FF, this.F, d, a, b, c, block[13], this.S[0][1]);
c = this.CC(this.FF, this.F, c, d, a, b, block[14], this.S[0][2]);
b = this.CC(this.FF, this.F, b, c, d, a, block[15], this.S[0][3]);
// Round 2
a = this.CC(this.GG, this.G, a, b, c, d, block[0], this.S[1][0]);
d = this.CC(this.GG, this.G, d, a, b, c, block[4], this.S[1][1]);
c = this.CC(this.GG, this.G, c, d, a, b, block[8], this.S[1][2]);
b = this.CC(this.GG, this.G, b, c, d, a, block[12], this.S[1][3]);
a = this.CC(this.GG, this.G, a, b, c, d, block[1], this.S[1][0]);
d = this.CC(this.GG, this.G, d, a, b, c, block[5], this.S[1][1]);
c = this.CC(this.GG, this.G, c, d, a, b, block[9], this.S[1][2]);
b = this.CC(this.GG, this.G, b, c, d, a, block[13], this.S[1][3]);
a = this.CC(this.GG, this.G, a, b, c, d, block[2], this.S[1][0]);
d = this.CC(this.GG, this.G, d, a, b, c, block[6], this.S[1][1]);
c = this.CC(this.GG, this.G, c, d, a, b, block[10], this.S[1][2]);
b = this.CC(this.GG, this.G, b, c, d, a, block[14], this.S[1][3]);
a = this.CC(this.GG, this.G, a, b, c, d, block[3], this.S[1][0]);
d = this.CC(this.GG, this.G, d, a, b, c, block[7], this.S[1][1]);
c = this.CC(this.GG, this.G, c, d, a, b, block[11], this.S[1][2]);
b = this.CC(this.GG, this.G, b, c, d, a, block[15], this.S[1][3]);
// Round 3
a = this.CC(this.HH, this.H, a, b, c, d, block[0], this.S[2][0]);
d = this.CC(this.HH, this.H, d, a, b, c, block[8], this.S[2][1]);
c = this.CC(this.HH, this.H, c, d, a, b, block[4], this.S[2][2]);
b = this.CC(this.HH, this.H, b, c, d, a, block[12], this.S[2][3]);
a = this.CC(this.HH, this.H, a, b, c, d, block[2], this.S[2][0]);
d = this.CC(this.HH, this.H, d, a, b, c, block[10], this.S[2][1]);
c = this.CC(this.HH, this.H, c, d, a, b, block[6], this.S[2][2]);
b = this.CC(this.HH, this.H, b, c, d, a, block[14], this.S[2][3]);
a = this.CC(this.HH, this.H, a, b, c, d, block[1], this.S[2][0]);
d = this.CC(this.HH, this.H, d, a, b, c, block[9], this.S[2][1]);
c = this.CC(this.HH, this.H, c, d, a, b, block[5], this.S[2][2]);
b = this.CC(this.HH, this.H, b, c, d, a, block[13], this.S[2][3]);
a = this.CC(this.HH, this.H, a, b, c, d, block[3], this.S[2][0]);
d = this.CC(this.HH, this.H, d, a, b, c, block[11], this.S[2][1]);
c = this.CC(this.HH, this.H, c, d, a, b, block[7], this.S[2][2]);
b = this.CC(this.HH, this.H, b, c, d, a, block[15], this.S[2][3]);
this.state.hash = [
(this.state.hash[0] + a) | 0,
(this.state.hash[1] + b) | 0,
(this.state.hash[2] + c) | 0,
(this.state.hash[3] + d) | 0
];
};
/**
* @memberOf Md4
* @method finalize
* @return {HashArray} hash
*/
Md4.prototype.finalize = function finalize() {
// Add padding
var padLen = this.state.message.length < 56 ? 56 - this.state.message.length : 120 - this.state.message.length;
var padding = new Array(padLen);
padding[0] = 0x80;
// Add length
var lengthBits = this.state.length * 8;
for (var i = 0; i < 4; i++) {
padding.push((lengthBits >> (8 * i)) & 0xff);
}
// @todo fix length to 64 bit
for (i = 0; i < 4; i++) {
padding.push(0);
}
this.updateFromArray(padding);
var hash = [];
for (i = 0; i < this.state.hash.length; i++) {
for (var j = 0; j < 4; j++) {
hash.push((this.state.hash[i] >> 8 * j) & 0xff);
}
}
// Return hash
return CryptoApi.hashArray(hash);
};
CryptoApi.Hashers.add('md4', Md4);
return Md4;
})(
this.CryptoApi || require('./crypto-api')
);

View File

@ -0,0 +1,125 @@
/*global require */
(/**
*
* @param {CryptoApi} CryptoApi
* @returns {Sha0}
*/
function (CryptoApi) {
'use strict';
// Transform constants
var K = [0x5a827999, 0x6ed9eba1, 0x8f1bbcdc, 0xca62c1d6];
/**
* @class Sha0
* @desc Sha0 hasher
* @implements HasherInterface
* @extends Hasher32be
*/
var Sha0 = function sha0(name, options) {
this.constructor(name, options);
};
Sha0.prototype = Object.create(CryptoApi.Hasher32be.prototype);
/**
* @memberOf Sha0
* @constructor
*/
Sha0.prototype.constructor = function (name, options) {
CryptoApi.Hasher32be.prototype.constructor.call(this, name, options);
/**
* @desc Hash state
* @memberOf! Sha0#
* @alias state.hash
* @type {number[]}
*/
this.state.hash = [
0x67452301,
0xefcdab89,
0x98badcfe,
0x10325476,
0xc3d2e1f0
];
this.W = [];
};
/**
* @memberOf Sha0
* @method processBlock
* @param {number[]} M
*/
Sha0.prototype.processBlock = function processBlock(M) {
// Working variables
var a = this.state.hash[0] | 0;
var b = this.state.hash[1] | 0;
var c = this.state.hash[2] | 0;
var d = this.state.hash[3] | 0;
var e = this.state.hash[4] | 0;
// Calculate hash
for (var i = 0; i < 80; i++) {
if (i < 16) {
this.W[i] = M[i] | 0;
} else {
this.W[i] = (this.W[i - 3] ^ this.W[i - 8] ^ this.W[i - 14] ^ this.W[i - 16]) | 0;
}
var t = (CryptoApi.Tools.rotateLeft(a, 5) + e + this.W[i] + K[(i / 20) >> 0]) | 0;
if (i < 20) {
t = (t + ((b & c) | (~b & d))) | 0;
} else if (i < 40) {
t = (t + (b ^ c ^ d)) | 0;
} else if (i < 60) {
t = (t + ((b & c) | (b & d) | (c & d))) | 0;
} else {
t = (t + (b ^ c ^ d)) | 0;
}
e = d;
d = c;
c = CryptoApi.Tools.rotateLeft(b, 30) | 0;
b = a;
a = t;
}
this.state.hash[0] = (this.state.hash[0] + a) | 0;
this.state.hash[1] = (this.state.hash[1] + b) | 0;
this.state.hash[2] = (this.state.hash[2] + c) | 0;
this.state.hash[3] = (this.state.hash[3] + d) | 0;
this.state.hash[4] = (this.state.hash[4] + e) | 0;
};
/**
* @memberOf Sha0
* @method finalize
* @return {HashArray} hash
*/
Sha0.prototype.finalize = function finalize() {
// Add padding
var padLen = this.state.message.length < 56 ? 56 - this.state.message.length : 120 - this.state.message.length;
padLen += 4; // @todo fix length to 64 bit
var padding = new Array(padLen);
padding[0] = 0x80;
// Add length
var lengthBits = this.state.length * 8;
for (var i = 3; i >= 0; i--) {
padding.push((lengthBits >> (8 * i)) & 0xff);
}
this.updateFromArray(padding);
var hash = [];
for (var k = 0, l = this.state.hash.length; k < l; k++) {
for (var j = 3; j >= 0; j--) {
hash.push((this.state.hash[k] >> 8 * j) & 0xFF);
}
}
// Return hash
return CryptoApi.hashArray(hash);
};
CryptoApi.Hashers.add('sha0', Sha0);
return Sha0;
})(
this.CryptoApi || require('./crypto-api')
);

View File

@ -1,4 +1,4 @@
/* globals CryptoJS, Checksum */
/* globals CryptoApi, CryptoJS, Checksum */
/**
* Hashing operations.
@ -10,6 +10,30 @@
* @namespace
*/
var Hash = {
/**
* MD2 operation.
*
* @param {string} input
* @param {Object[]} args
* @returns {string}
*/
run_md2: function (input, args) {
return Utils.to_hex_fast(CryptoApi.hash("md2", input, {}));
},
/**
* MD4 operation.
*
* @param {string} input
* @param {Object[]} args
* @returns {string}
*/
run_md4: function (input, args) {
return Utils.to_hex_fast(CryptoApi.hash("md4", input, {}));
},
/**
* MD5 operation.
@ -22,6 +46,18 @@ var Hash = {
input = CryptoJS.enc.Latin1.parse(input); // Cast to WordArray
return CryptoJS.MD5(input).toString(CryptoJS.enc.Hex);
},
/**
* SHA0 operation.
*
* @param {string} input
* @param {Object[]} args
* @returns {string}
*/
run_sha0: function (input, args) {
return Utils.to_hex_fast(CryptoApi.hash("sha0", input, {}));
},
/**
@ -164,7 +200,10 @@ var Hash = {
*/
run_all: function (input, args) {
var byte_array = Utils.str_to_byte_array(input),
output = "MD5: " + Hash.run_md5(input, []) +
output = "MD2: " + Hash.run_md2(input, []) +
"\nMD4: " + Hash.run_md4(input, []) +
"\nMD5: " + Hash.run_md5(input, []) +
"\nSHA0: " + Hash.run_sha0(input, []) +
"\nSHA1: " + Hash.run_sha1(input, []) +
"\nSHA2 224: " + Hash.run_sha224(input, []) +
"\nSHA2 256: " + Hash.run_sha256(input, []) +

View File

@ -1,21 +1,21 @@
206 source files
113481 lines
4.2M size
211 source files
114750 lines
4.3M size
137 JavaScript source files
104323 lines
141 JavaScript source files
105592 lines
3.7M size
79 third party JavaScript source files
85052 lines
83 third party JavaScript source files
86258 lines
3.0M size
58 first party JavaScript source files
19271 lines
19334 lines
728K size
3.4M uncompressed JavaScript size
1.8M compressed JavaScript size
15 categories
159 operations
162 operations