diff --git a/package-lock.json b/package-lock.json
index d08a308d..289d950b 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -6183,6 +6183,53 @@
"resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.7.0.tgz",
"integrity": "sha512-Wpks3yBDm0UcL5qlVhwW9Jr9n9i4FfeWBFOOXP5puDS/SiudJGhw7DPyBqn3487qD4F0lsC0q3zxink37f7zeA=="
},
+ "js-to-mjs": {
+ "version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/js-to-mjs/-/js-to-mjs-0.2.0.tgz",
+ "integrity": "sha512-5OlmInr6FuKAEAqNi0Ag8ErS8LWCp53w/vHSc6Ndm8aTckuOKI/uiil/ltP/xRrl+cSz8Q/oW7q6iglNQHCx+A==",
+ "dev": true,
+ "requires": {
+ "babylon": "^6.18.0",
+ "chalk": "^2.1.0"
+ },
+ "dependencies": {
+ "ansi-styles": {
+ "version": "3.2.1",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
+ "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
+ "dev": true,
+ "requires": {
+ "color-convert": "^1.9.0"
+ }
+ },
+ "chalk": {
+ "version": "2.4.1",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.1.tgz",
+ "integrity": "sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "^3.2.1",
+ "escape-string-regexp": "^1.0.5",
+ "supports-color": "^5.3.0"
+ }
+ },
+ "has-flag": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
+ "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=",
+ "dev": true
+ },
+ "supports-color": {
+ "version": "5.4.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.4.0.tgz",
+ "integrity": "sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w==",
+ "dev": true,
+ "requires": {
+ "has-flag": "^3.0.0"
+ }
+ }
+ }
+ },
"js-tokens": {
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz",
diff --git a/package.json b/package.json
index aab18f83..9234ad85 100644
--- a/package.json
+++ b/package.json
@@ -52,6 +52,7 @@
"html-webpack-plugin": "^3.2.0",
"imports-loader": "^0.8.0",
"ink-docstrap": "^1.3.2",
+ "js-to-mjs": "^0.2.0",
"jsdoc-babel": "^0.4.0",
"less": "^3.0.2",
"less-loader": "^4.1.0",
@@ -122,6 +123,7 @@
"build": "grunt prod",
"test": "grunt test",
"docs": "grunt docs",
- "lint": "grunt lint"
+ "lint": "grunt lint",
+ "postinstall": "npx j2m node_modules/crypto-api/src/crypto-api.js"
}
}
diff --git a/src/core/config/scripts/portOperation.mjs b/src/core/config/scripts/portOperation.mjs
index 4491d493..771993d8 100644
--- a/src/core/config/scripts/portOperation.mjs
+++ b/src/core/config/scripts/portOperation.mjs
@@ -43,7 +43,7 @@ function main() {
const op = OP_CONFIG[opName];
const moduleName = opName.replace(/\w\S*/g, txt => {
return txt.charAt(0).toUpperCase() + txt.substr(1);
- }).replace(/\s/g, "");
+ }).replace(/[\s-/]/g, "");
let legacyFile = "";
diff --git a/src/core/lib/Ciphers.mjs b/src/core/lib/Ciphers.mjs
index b7e98940..3edd6983 100644
--- a/src/core/lib/Ciphers.mjs
+++ b/src/core/lib/Ciphers.mjs
@@ -8,6 +8,7 @@
* @license Apache-2.0
*
*/
+
import OperationError from "../errors/OperationError";
import CryptoJS from "crypto-js";
diff --git a/src/core/lib/Delim.mjs b/src/core/lib/Delim.mjs
index 8e424300..192d3582 100644
--- a/src/core/lib/Delim.mjs
+++ b/src/core/lib/Delim.mjs
@@ -32,10 +32,15 @@ export const WORD_DELIM_OPTIONS = ["Line feed", "CRLF", "Forward slash", "Backsl
export const INPUT_DELIM_OPTIONS = ["Line feed", "CRLF", "Space", "Comma", "Semi-colon", "Colon", "Nothing (separate chars)"];
/**
- * Arithmetic sequence delimiters
+ * Armithmetic sequence delimiters
*/
export const ARITHMETIC_DELIM_OPTIONS = ["Line feed", "Space", "Comma", "Semi-colon", "Colon", "CRLF"];
+/**
+ * Hash delimiters
+ */
+export const HASH_DELIM_OPTIONS = ["Line feed", "CRLF", "Space", "Comma"];
+
/**
* Split delimiters.
*/
diff --git a/src/core/lib/Hash.mjs b/src/core/lib/Hash.mjs
new file mode 100644
index 00000000..4af48d13
--- /dev/null
+++ b/src/core/lib/Hash.mjs
@@ -0,0 +1,28 @@
+/**
+ * Hashing resources.
+ *
+ * @author n1474335 [n1474335@gmail.com]
+ *
+ * @copyright Crown Copyright 2016
+ * @license Apache-2.0
+ */
+
+import Utils from "../Utils";
+import CryptoApi from "crypto-api/src/crypto-api";
+
+
+/**
+ * Generic hash function.
+ *
+ * @param {string} name
+ * @param {ArrayBuffer} input
+ * @param {Object} [options={}]
+ * @returns {string}
+ */
+export function runHash(name, input, options={}) {
+ const msg = Utils.arrayBufferToStr(input, false),
+ hasher = CryptoApi.getHasher(name, options);
+ hasher.update(msg);
+ return CryptoApi.encoder.toHex(hasher.finalize());
+}
+
diff --git a/src/core/operations/Adler32Checksum.mjs b/src/core/operations/Adler32Checksum.mjs
new file mode 100644
index 00000000..3e8013bd
--- /dev/null
+++ b/src/core/operations/Adler32Checksum.mjs
@@ -0,0 +1,52 @@
+/**
+ * @author n1474335 [n1474335@gmail.com]
+ * @copyright Crown Copyright 2016
+ * @license Apache-2.0
+ */
+
+import Operation from "../Operation";
+import Utils from "../Utils";
+
+/**
+ * Adler-32 Checksum operation
+ */
+class Adler32Checksum extends Operation {
+
+ /**
+ * Adler32Checksum constructor
+ */
+ constructor() {
+ super();
+
+ this.name = "Adler-32 Checksum";
+ this.module = "Hashing";
+ this.description = "Adler-32 is a checksum algorithm which was invented by Mark Adler in 1995, and is a modification of the Fletcher checksum. Compared to a cyclic redundancy check of the same length, it trades reliability for speed (preferring the latter).
Adler-32 is more reliable than Fletcher-16, and slightly less reliable than Fletcher-32.";
+ this.inputType = "byteArray";
+ this.outputType = "string";
+ this.args = [];
+ }
+
+ /**
+ * @param {byteArray} input
+ * @param {Object[]} args
+ * @returns {string}
+ */
+ run(input, args) {
+ const MOD_ADLER = 65521;
+ let a = 1,
+ b = 0;
+
+ for (let i = 0; i < input.length; i++) {
+ a += input[i];
+ b += a;
+ }
+
+ a %= MOD_ADLER;
+ b %= MOD_ADLER;
+
+ return Utils.hex(((b << 16) | a) >>> 0, 8);
+ }
+
+}
+
+export default Adler32Checksum;
diff --git a/src/core/operations/AnalyseHash.mjs b/src/core/operations/AnalyseHash.mjs
new file mode 100644
index 00000000..e53b515e
--- /dev/null
+++ b/src/core/operations/AnalyseHash.mjs
@@ -0,0 +1,183 @@
+/**
+ * @author n1474335 [n1474335@gmail.com]
+ * @copyright Crown Copyright 2016
+ * @license Apache-2.0
+ */
+
+import Operation from "../Operation";
+import OperationError from "../errors/OperationError";
+
+/**
+ * Analyse hash operation
+ */
+class AnalyseHash extends Operation {
+
+ /**
+ * AnalyseHash constructor
+ */
+ constructor() {
+ super();
+
+ this.name = "Analyse hash";
+ this.module = "Hashing";
+ this.description = "Tries to determine information about a given hash and suggests which algorithm may have been used to generate it based on its length.";
+ this.inputType = "string";
+ this.outputType = "string";
+ this.args = [];
+ }
+
+ /**
+ * @param {string} input
+ * @param {Object[]} args
+ * @returns {string}
+ */
+ run(input, args) {
+ input = input.replace(/\s/g, "");
+
+ let output = "",
+ possibleHashFunctions = [];
+ const byteLength = input.length / 2,
+ bitLength = byteLength * 8;
+
+ if (!/^[a-f0-9]+$/i.test(input)) {
+ throw new OperationError("Invalid hash");
+ }
+
+ output += "Hash length: " + input.length + "\n" +
+ "Byte length: " + byteLength + "\n" +
+ "Bit length: " + bitLength + "\n\n" +
+ "Based on the length, this hash could have been generated by one of the following hashing functions:\n";
+
+ switch (bitLength) {
+ case 4:
+ possibleHashFunctions = [
+ "Fletcher-4",
+ "Luhn algorithm",
+ "Verhoeff algorithm",
+ ];
+ break;
+ case 8:
+ possibleHashFunctions = [
+ "Fletcher-8",
+ ];
+ break;
+ case 16:
+ possibleHashFunctions = [
+ "BSD checksum",
+ "CRC-16",
+ "SYSV checksum",
+ "Fletcher-16"
+ ];
+ break;
+ case 32:
+ possibleHashFunctions = [
+ "CRC-32",
+ "Fletcher-32",
+ "Adler-32",
+ ];
+ break;
+ case 64:
+ possibleHashFunctions = [
+ "CRC-64",
+ "RIPEMD-64",
+ "SipHash",
+ ];
+ break;
+ case 128:
+ possibleHashFunctions = [
+ "MD5",
+ "MD4",
+ "MD2",
+ "HAVAL-128",
+ "RIPEMD-128",
+ "Snefru",
+ "Tiger-128",
+ ];
+ break;
+ case 160:
+ possibleHashFunctions = [
+ "SHA-1",
+ "SHA-0",
+ "FSB-160",
+ "HAS-160",
+ "HAVAL-160",
+ "RIPEMD-160",
+ "Tiger-160",
+ ];
+ break;
+ case 192:
+ possibleHashFunctions = [
+ "Tiger",
+ "HAVAL-192",
+ ];
+ break;
+ case 224:
+ possibleHashFunctions = [
+ "SHA-224",
+ "SHA3-224",
+ "ECOH-224",
+ "FSB-224",
+ "HAVAL-224",
+ ];
+ break;
+ case 256:
+ possibleHashFunctions = [
+ "SHA-256",
+ "SHA3-256",
+ "BLAKE-256",
+ "ECOH-256",
+ "FSB-256",
+ "GOST",
+ "Grøstl-256",
+ "HAVAL-256",
+ "PANAMA",
+ "RIPEMD-256",
+ "Snefru",
+ ];
+ break;
+ case 320:
+ possibleHashFunctions = [
+ "RIPEMD-320",
+ ];
+ break;
+ case 384:
+ possibleHashFunctions = [
+ "SHA-384",
+ "SHA3-384",
+ "ECOH-384",
+ "FSB-384",
+ ];
+ break;
+ case 512:
+ possibleHashFunctions = [
+ "SHA-512",
+ "SHA3-512",
+ "BLAKE-512",
+ "ECOH-512",
+ "FSB-512",
+ "Grøstl-512",
+ "JH",
+ "MD6",
+ "Spectral Hash",
+ "SWIFFT",
+ "Whirlpool",
+ ];
+ break;
+ case 1024:
+ possibleHashFunctions = [
+ "Fowler-Noll-Vo",
+ ];
+ break;
+ default:
+ possibleHashFunctions = [
+ "Unknown"
+ ];
+ break;
+ }
+
+ return output + possibleHashFunctions.join("\n");
+ }
+
+}
+
+export default AnalyseHash;
diff --git a/src/core/operations/Bcrypt.mjs b/src/core/operations/Bcrypt.mjs
new file mode 100644
index 00000000..cccf4131
--- /dev/null
+++ b/src/core/operations/Bcrypt.mjs
@@ -0,0 +1,54 @@
+/**
+ * @author n1474335 [n1474335@gmail.com]
+ * @copyright Crown Copyright 2016
+ * @license Apache-2.0
+ */
+
+import Operation from "../Operation";
+import bcrypt from "bcryptjs";
+
+/**
+ * Bcrypt operation
+ */
+class Bcrypt extends Operation {
+
+ /**
+ * Bcrypt constructor
+ */
+ constructor() {
+ super();
+
+ this.name = "Bcrypt";
+ this.module = "Hashing";
+ this.description = "bcrypt is a password hashing function designed by Niels Provos and David Mazi\xe8res, based on the Blowfish cipher, and presented at USENIX in 1999. Besides incorporating a salt to protect against rainbow table attacks, bcrypt is an adaptive function: over time, the iteration count (rounds) can be increased to make it slower, so it remains resistant to brute-force search attacks even with increasing computation power.
Enter the password in the input to generate its hash.";
+ this.inputType = "string";
+ this.outputType = "string";
+ this.args = [
+ {
+ "name": "Rounds",
+ "type": "number",
+ "value": 10
+ }
+ ];
+ }
+
+ /**
+ * @param {string} input
+ * @param {Object[]} args
+ * @returns {string}
+ */
+ async run(input, args) {
+ const rounds = args[0];
+ const salt = await bcrypt.genSalt(rounds);
+
+ return await bcrypt.hash(input, salt, null, p => {
+ // Progress callback
+ if (ENVIRONMENT_IS_WORKER())
+ self.sendStatusMessage(`Progress: ${(p * 100).toFixed(0)}%`);
+ });
+
+ }
+
+}
+
+export default Bcrypt;
diff --git a/src/core/operations/BcryptCompare.mjs b/src/core/operations/BcryptCompare.mjs
new file mode 100644
index 00000000..32f275b5
--- /dev/null
+++ b/src/core/operations/BcryptCompare.mjs
@@ -0,0 +1,55 @@
+/**
+ * @author n1474335 [n1474335@gmail.com]
+ * @copyright Crown Copyright 2016
+ * @license Apache-2.0
+ */
+
+import Operation from "../Operation";
+import bcrypt from "bcryptjs";
+
+/**
+ * Bcrypt compare operation
+ */
+class BcryptCompare extends Operation {
+
+ /**
+ * BcryptCompare constructor
+ */
+ constructor() {
+ super();
+
+ this.name = "Bcrypt compare";
+ this.module = "Hashing";
+ this.description = "Tests whether the input matches the given bcrypt hash. To test multiple possible passwords, use the 'Fork' operation.";
+ this.inputType = "string";
+ this.outputType = "string";
+ this.args = [
+ {
+ "name": "Hash",
+ "type": "string",
+ "value": ""
+ }
+ ];
+ }
+
+ /**
+ * @param {string} input
+ * @param {Object[]} args
+ * @returns {string}
+ */
+ async run(input, args) {
+ const hash = args[0];
+
+ const match = await bcrypt.compare(input, hash, null, p => {
+ // Progress callback
+ if (ENVIRONMENT_IS_WORKER())
+ self.sendStatusMessage(`Progress: ${(p * 100).toFixed(0)}%`);
+ });
+
+ return match ? "Match: " + input : "No match";
+
+ }
+
+}
+
+export default BcryptCompare;
diff --git a/src/core/operations/BcryptParse.mjs b/src/core/operations/BcryptParse.mjs
new file mode 100644
index 00000000..e72d18d2
--- /dev/null
+++ b/src/core/operations/BcryptParse.mjs
@@ -0,0 +1,47 @@
+/**
+ * @author n1474335 [n1474335@gmail.com]
+ * @copyright Crown Copyright 2016
+ * @license Apache-2.0
+ */
+
+import Operation from "../Operation";
+import bcrypt from "bcryptjs";
+
+/**
+ * Bcrypt parse operation
+ */
+class BcryptParse extends Operation {
+
+ /**
+ * BcryptParse constructor
+ */
+ constructor() {
+ super();
+
+ this.name = "Bcrypt parse";
+ this.module = "Hashing";
+ this.description = "Parses a bcrypt hash to determine the number of rounds used, the salt, and the password hash.";
+ this.inputType = "string";
+ this.outputType = "string";
+ this.args = [];
+ }
+
+ /**
+ * @param {string} input
+ * @param {Object[]} args
+ * @returns {string}
+ */
+ async run(input, args) {
+ try {
+ return `Rounds: ${bcrypt.getRounds(input)}
+Salt: ${bcrypt.getSalt(input)}
+Password hash: ${input.split(bcrypt.getSalt(input))[1]}
+Full hash: ${input}`;
+ } catch (err) {
+ return "Error: " + err.toString();
+ }
+ }
+
+}
+
+export default BcryptParse;
diff --git a/src/core/operations/CRC16Checksum.mjs b/src/core/operations/CRC16Checksum.mjs
new file mode 100644
index 00000000..c4c5d633
--- /dev/null
+++ b/src/core/operations/CRC16Checksum.mjs
@@ -0,0 +1,40 @@
+/**
+ * @author n1474335 [n1474335@gmail.com]
+ * @copyright Crown Copyright 2016
+ * @license Apache-2.0
+ */
+
+import Operation from "../Operation";
+import JSCRC from "js-crc";
+
+/**
+ * CRC-16 Checksum operation
+ */
+class CRC16Checksum extends Operation {
+
+ /**
+ * CRC16Checksum constructor
+ */
+ constructor() {
+ super();
+
+ this.name = "CRC-16 Checksum";
+ this.module = "Hashing";
+ this.description = "A cyclic redundancy check (CRC) is an error-detecting code commonly used in digital networks and storage devices to detect accidental changes to raw data.
The CRC was invented by W. Wesley Peterson in 1961.";
+ this.inputType = "ArrayBuffer";
+ this.outputType = "string";
+ this.args = [];
+ }
+
+ /**
+ * @param {ArrayBuffer} input
+ * @param {Object[]} args
+ * @returns {string}
+ */
+ run(input, args) {
+ return JSCRC.crc16(input);
+ }
+
+}
+
+export default CRC16Checksum;
diff --git a/src/core/operations/CRC32Checksum.mjs b/src/core/operations/CRC32Checksum.mjs
new file mode 100644
index 00000000..5982273e
--- /dev/null
+++ b/src/core/operations/CRC32Checksum.mjs
@@ -0,0 +1,40 @@
+/**
+ * @author n1474335 [n1474335@gmail.com]
+ * @copyright Crown Copyright 2016
+ * @license Apache-2.0
+ */
+
+import Operation from "../Operation";
+import JSCRC from "js-crc";
+
+/**
+ * CRC-32 Checksum operation
+ */
+class CRC32Checksum extends Operation {
+
+ /**
+ * CRC32Checksum constructor
+ */
+ constructor() {
+ super();
+
+ this.name = "CRC-32 Checksum";
+ this.module = "Hashing";
+ this.description = "A cyclic redundancy check (CRC) is an error-detecting code commonly used in digital networks and storage devices to detect accidental changes to raw data.
The CRC was invented by W. Wesley Peterson in 1961; the 32-bit CRC function of Ethernet and many other standards is the work of several researchers and was published in 1975.";
+ this.inputType = "ArrayBuffer";
+ this.outputType = "string";
+ this.args = [];
+ }
+
+ /**
+ * @param {ArrayBuffer} input
+ * @param {Object[]} args
+ * @returns {string}
+ */
+ run(input, args) {
+ return JSCRC.crc32(input);
+ }
+
+}
+
+export default CRC32Checksum;
diff --git a/src/core/operations/CTPH.mjs b/src/core/operations/CTPH.mjs
new file mode 100644
index 00000000..39f52af4
--- /dev/null
+++ b/src/core/operations/CTPH.mjs
@@ -0,0 +1,40 @@
+/**
+ * @author n1474335 [n1474335@gmail.com]
+ * @copyright Crown Copyright 2016
+ * @license Apache-2.0
+ */
+
+import Operation from "../Operation";
+import ctphjs from "ctph.js";
+
+/**
+ * CTPH operation
+ */
+class CTPH extends Operation {
+
+ /**
+ * CTPH constructor
+ */
+ constructor() {
+ super();
+
+ this.name = "CTPH";
+ this.module = "Hashing";
+ this.description = "Context Triggered Piecewise Hashing, also called Fuzzy Hashing, can match inputs that have homologies. Such inputs have sequences of identical bytes in the same order, although bytes in between these sequences may be different in both content and length.
CTPH was originally based on the work of Dr. Andrew Tridgell and a spam email detector called SpamSum. This method was adapted by Jesse Kornblum and published at the DFRWS conference in 2006 in a paper 'Identifying Almost Identical Files Using Context Triggered Piecewise Hashing'.";
+ this.inputType = "string";
+ this.outputType = "string";
+ this.args = [];
+ }
+
+ /**
+ * @param {string} input
+ * @param {Object[]} args
+ * @returns {string}
+ */
+ run(input, args) {
+ return ctphjs.digest(input);
+ }
+
+}
+
+export default CTPH;
diff --git a/src/core/operations/CompareCTPHHashes.mjs b/src/core/operations/CompareCTPHHashes.mjs
new file mode 100644
index 00000000..7194d89f
--- /dev/null
+++ b/src/core/operations/CompareCTPHHashes.mjs
@@ -0,0 +1,51 @@
+/**
+ * @author n1474335 [n1474335@gmail.com]
+ * @copyright Crown Copyright 2016
+ * @license Apache-2.0
+ */
+
+import Operation from "../Operation";
+import Utils from "../Utils";
+import {HASH_DELIM_OPTIONS} from "../lib/Delim";
+import ctphjs from "ctph.js";
+import OperationError from "../errors/OperationError";
+
+/**
+ * Compare CTPH hashes operation
+ */
+class CompareCTPHHashes extends Operation {
+
+ /**
+ * CompareCTPHHashes constructor
+ */
+ constructor() {
+ super();
+
+ this.name = "Compare CTPH hashes";
+ this.module = "Hashing";
+ this.description = "Compares two Context Triggered Piecewise Hashing (CTPH) fuzzy hashes to determine the similarity between them on a scale of 0 to 100.";
+ this.inputType = "string";
+ this.outputType = "Number";
+ this.args = [
+ {
+ "name": "Delimiter",
+ "type": "option",
+ "value": HASH_DELIM_OPTIONS
+ }
+ ];
+ }
+
+ /**
+ * @param {string} input
+ * @param {Object[]} args
+ * @returns {Number}
+ */
+ run(input, args) {
+ const samples = input.split(Utils.charRep(args[0]));
+ if (samples.length !== 2) throw new OperationError("Incorrect number of samples.");
+ return ctphjs.similarity(samples[0], samples[1]);
+ }
+
+}
+
+export default CompareCTPHHashes;
diff --git a/src/core/operations/CompareSSDEEPHashes.mjs b/src/core/operations/CompareSSDEEPHashes.mjs
new file mode 100644
index 00000000..aa39d5cf
--- /dev/null
+++ b/src/core/operations/CompareSSDEEPHashes.mjs
@@ -0,0 +1,51 @@
+/**
+ * @author n1474335 [n1474335@gmail.com]
+ * @copyright Crown Copyright 2016
+ * @license Apache-2.0
+ */
+
+import Operation from "../Operation";
+import Utils from "../Utils";
+import {HASH_DELIM_OPTIONS} from "../lib/Delim";
+import ssdeepjs from "ssdeep.js";
+import OperationError from "../errors/OperationError";
+
+/**
+ * Compare SSDEEP hashes operation
+ */
+class CompareSSDEEPHashes extends Operation {
+
+ /**
+ * CompareSSDEEPHashes constructor
+ */
+ constructor() {
+ super();
+
+ this.name = "Compare SSDEEP hashes";
+ this.module = "Hashing";
+ this.description = "Compares two SSDEEP fuzzy hashes to determine the similarity between them on a scale of 0 to 100.";
+ this.inputType = "string";
+ this.outputType = "Number";
+ this.args = [
+ {
+ "name": "Delimiter",
+ "type": "option",
+ "value": HASH_DELIM_OPTIONS
+ }
+ ];
+ }
+
+ /**
+ * @param {string} input
+ * @param {Object[]} args
+ * @returns {Number}
+ */
+ run(input, args) {
+ const samples = input.split(Utils.charRep(args[0]));
+ if (samples.length !== 2) throw new OperationError("Incorrect number of samples.");
+ return ssdeepjs.similarity(samples[0], samples[1]);
+ }
+
+}
+
+export default CompareSSDEEPHashes;
diff --git a/src/core/operations/Fletcher16Checksum.mjs b/src/core/operations/Fletcher16Checksum.mjs
new file mode 100644
index 00000000..ea3fe791
--- /dev/null
+++ b/src/core/operations/Fletcher16Checksum.mjs
@@ -0,0 +1,48 @@
+/**
+ * @author n1474335 [n1474335@gmail.com]
+ * @copyright Crown Copyright 2016
+ * @license Apache-2.0
+ */
+
+import Operation from "../Operation";
+import Utils from "../Utils";
+
+/**
+ * Fletcher-16 Checksum operation
+ */
+class Fletcher16Checksum extends Operation {
+
+ /**
+ * Fletcher16Checksum constructor
+ */
+ constructor() {
+ super();
+
+ this.name = "Fletcher-16 Checksum";
+ this.module = "Hashing";
+ this.description = "The Fletcher checksum is an algorithm for computing a position-dependent checksum devised by John Gould Fletcher at Lawrence Livermore Labs in the late 1970s.
The objective of the Fletcher checksum was to provide error-detection properties approaching those of a cyclic redundancy check but with the lower computational effort associated with summation techniques.";
+ this.inputType = "byteArray";
+ this.outputType = "string";
+ this.args = [];
+ }
+
+ /**
+ * @param {byteArray} input
+ * @param {Object[]} args
+ * @returns {string}
+ */
+ run(input, args) {
+ let a = 0,
+ b = 0;
+
+ for (let i = 0; i < input.length; i++) {
+ a = (a + input[i]) % 0xff;
+ b = (b + a) % 0xff;
+ }
+
+ return Utils.hex(((b << 8) | a) >>> 0, 4);
+ }
+
+}
+
+export default Fletcher16Checksum;
diff --git a/src/core/operations/Fletcher32Checksum.mjs b/src/core/operations/Fletcher32Checksum.mjs
new file mode 100644
index 00000000..21c9449e
--- /dev/null
+++ b/src/core/operations/Fletcher32Checksum.mjs
@@ -0,0 +1,48 @@
+/**
+ * @author n1474335 [n1474335@gmail.com]
+ * @copyright Crown Copyright 2016
+ * @license Apache-2.0
+ */
+
+import Operation from "../Operation";
+import Utils from "../Utils";
+
+/**
+ * Fletcher-32 Checksum operation
+ */
+class Fletcher32Checksum extends Operation {
+
+ /**
+ * Fletcher32Checksum constructor
+ */
+ constructor() {
+ super();
+
+ this.name = "Fletcher-32 Checksum";
+ this.module = "Hashing";
+ this.description = "The Fletcher checksum is an algorithm for computing a position-dependent checksum devised by John Gould Fletcher at Lawrence Livermore Labs in the late 1970s.
The objective of the Fletcher checksum was to provide error-detection properties approaching those of a cyclic redundancy check but with the lower computational effort associated with summation techniques.";
+ this.inputType = "byteArray";
+ this.outputType = "string";
+ this.args = [];
+ }
+
+ /**
+ * @param {byteArray} input
+ * @param {Object[]} args
+ * @returns {string}
+ */
+ run(input, args) {
+ let a = 0,
+ b = 0;
+
+ for (let i = 0; i < input.length; i++) {
+ a = (a + input[i]) % 0xffff;
+ b = (b + a) % 0xffff;
+ }
+
+ return Utils.hex(((b << 16) | a) >>> 0, 8);
+ }
+
+}
+
+export default Fletcher32Checksum;
diff --git a/src/core/operations/Fletcher64Checksum.mjs b/src/core/operations/Fletcher64Checksum.mjs
new file mode 100644
index 00000000..ac88a26f
--- /dev/null
+++ b/src/core/operations/Fletcher64Checksum.mjs
@@ -0,0 +1,48 @@
+/**
+ * @author n1474335 [n1474335@gmail.com]
+ * @copyright Crown Copyright 2016
+ * @license Apache-2.0
+ */
+
+import Operation from "../Operation";
+import Utils from "../Utils";
+
+/**
+ * Fletcher-64 Checksum operation
+ */
+class Fletcher64Checksum extends Operation {
+
+ /**
+ * Fletcher64Checksum constructor
+ */
+ constructor() {
+ super();
+
+ this.name = "Fletcher-64 Checksum";
+ this.module = "Hashing";
+ this.description = "The Fletcher checksum is an algorithm for computing a position-dependent checksum devised by John Gould Fletcher at Lawrence Livermore Labs in the late 1970s.
The objective of the Fletcher checksum was to provide error-detection properties approaching those of a cyclic redundancy check but with the lower computational effort associated with summation techniques.";
+ this.inputType = "byteArray";
+ this.outputType = "string";
+ this.args = [];
+ }
+
+ /**
+ * @param {byteArray} input
+ * @param {Object[]} args
+ * @returns {string}
+ */
+ run(input, args) {
+ let a = 0,
+ b = 0;
+
+ for (let i = 0; i < input.length; i++) {
+ a = (a + input[i]) % 0xffffffff;
+ b = (b + a) % 0xffffffff;
+ }
+
+ return Utils.hex(b >>> 0, 8) + Utils.hex(a >>> 0, 8);
+ }
+
+}
+
+export default Fletcher64Checksum;
diff --git a/src/core/operations/Fletcher8Checksum.mjs b/src/core/operations/Fletcher8Checksum.mjs
new file mode 100644
index 00000000..99199449
--- /dev/null
+++ b/src/core/operations/Fletcher8Checksum.mjs
@@ -0,0 +1,48 @@
+/**
+ * @author n1474335 [n1474335@gmail.com]
+ * @copyright Crown Copyright 2016
+ * @license Apache-2.0
+ */
+
+import Operation from "../Operation";
+import Utils from "../Utils";
+
+/**
+ * Fletcher-8 Checksum operation
+ */
+class Fletcher8Checksum extends Operation {
+
+ /**
+ * Fletcher8Checksum constructor
+ */
+ constructor() {
+ super();
+
+ this.name = "Fletcher-8 Checksum";
+ this.module = "Hashing";
+ this.description = "The Fletcher checksum is an algorithm for computing a position-dependent checksum devised by John Gould Fletcher at Lawrence Livermore Labs in the late 1970s.
The objective of the Fletcher checksum was to provide error-detection properties approaching those of a cyclic redundancy check but with the lower computational effort associated with summation techniques.";
+ this.inputType = "byteArray";
+ this.outputType = "string";
+ this.args = [];
+ }
+
+ /**
+ * @param {byteArray} input
+ * @param {Object[]} args
+ * @returns {string}
+ */
+ run(input, args) {
+ let a = 0,
+ b = 0;
+
+ for (let i = 0; i < input.length; i++) {
+ a = (a + input[i]) % 0xf;
+ b = (b + a) % 0xf;
+ }
+
+ return Utils.hex(((b << 4) | a) >>> 0, 2);
+ }
+
+}
+
+export default Fletcher8Checksum;
diff --git a/src/core/operations/GenerateAllHashes.mjs b/src/core/operations/GenerateAllHashes.mjs
new file mode 100644
index 00000000..1280249a
--- /dev/null
+++ b/src/core/operations/GenerateAllHashes.mjs
@@ -0,0 +1,104 @@
+/**
+ * @author n1474335 [n1474335@gmail.com]
+ * @copyright Crown Copyright 2016
+ * @license Apache-2.0
+ */
+
+import Operation from "../Operation";
+import Utils from "../Utils";
+import MD2 from "./MD2";
+import MD4 from "./MD4";
+import MD5 from "./MD5";
+import MD6 from "./MD6";
+import SHA0 from "./SHA0";
+import SHA1 from "./SHA1";
+import SHA2 from "./SHA2";
+import SHA3 from "./SHA3";
+import Keccak from "./Keccak";
+import Shake from "./Shake";
+import RIPEMD from "./RIPEMD";
+import HAS160 from "./HAS160";
+import Whirlpool from "./Whirlpool";
+import SSDEEP from "./SSDEEP";
+import CTPH from "./CTPH";
+import Fletcher8Checksum from "./Fletcher8Checksum";
+import Fletcher16Checksum from "./Fletcher16Checksum";
+import Fletcher32Checksum from "./Fletcher32Checksum";
+import Fletcher64Checksum from "./Fletcher64Checksum";
+import Adler32Checksum from "./Adler32Checksum";
+import CRC16Checksum from "./CRC16Checksum";
+import CRC32Checksum from "./CRC32Checksum";
+
+/**
+ * Generate all hashes operation
+ */
+class GenerateAllHashes extends Operation {
+
+ /**
+ * GenerateAllHashes constructor
+ */
+ constructor() {
+ super();
+
+ this.name = "Generate all hashes";
+ this.module = "Hashing";
+ this.description = "Generates all available hashes and checksums for the input.";
+ this.inputType = "ArrayBuffer";
+ this.outputType = "string";
+ this.args = [];
+ }
+
+ /**
+ * @param {ArrayBuffer} input
+ * @param {Object[]} args
+ * @returns {string}
+ */
+ run(input, args) {
+ const arrayBuffer = input,
+ str = Utils.arrayBufferToStr(arrayBuffer, false),
+ byteArray = new Uint8Array(arrayBuffer),
+ output = "MD2: " + (new MD2()).run(arrayBuffer, []) +
+ "\nMD4: " + (new MD4()).run(arrayBuffer, []) +
+ "\nMD5: " + (new MD5()).run(arrayBuffer, []) +
+ "\nMD6: " + (new MD6()).run(str, []) +
+ "\nSHA0: " + (new SHA0()).run(arrayBuffer, []) +
+ "\nSHA1: " + (new SHA1()).run(arrayBuffer, []) +
+ "\nSHA2 224: " + (new SHA2()).run(arrayBuffer, ["224"]) +
+ "\nSHA2 256: " + (new SHA2()).run(arrayBuffer, ["256"]) +
+ "\nSHA2 384: " + (new SHA2()).run(arrayBuffer, ["384"]) +
+ "\nSHA2 512: " + (new SHA2()).run(arrayBuffer, ["512"]) +
+ "\nSHA3 224: " + (new SHA3()).run(arrayBuffer, ["224"]) +
+ "\nSHA3 256: " + (new SHA3()).run(arrayBuffer, ["256"]) +
+ "\nSHA3 384: " + (new SHA3()).run(arrayBuffer, ["384"]) +
+ "\nSHA3 512: " + (new SHA3()).run(arrayBuffer, ["512"]) +
+ "\nKeccak 224: " + (new Keccak()).run(arrayBuffer, ["224"]) +
+ "\nKeccak 256: " + (new Keccak()).run(arrayBuffer, ["256"]) +
+ "\nKeccak 384: " + (new Keccak()).run(arrayBuffer, ["384"]) +
+ "\nKeccak 512: " + (new Keccak()).run(arrayBuffer, ["512"]) +
+ "\nShake 128: " + (new Shake()).run(arrayBuffer, ["128", 256]) +
+ "\nShake 256: " + (new Shake()).run(arrayBuffer, ["256", 512]) +
+ "\nRIPEMD-128: " + (new RIPEMD()).run(arrayBuffer, ["128"]) +
+ "\nRIPEMD-160: " + (new RIPEMD()).run(arrayBuffer, ["160"]) +
+ "\nRIPEMD-256: " + (new RIPEMD()).run(arrayBuffer, ["256"]) +
+ "\nRIPEMD-320: " + (new RIPEMD()).run(arrayBuffer, ["320"]) +
+ "\nHAS-160: " + (new HAS160()).run(arrayBuffer, []) +
+ "\nWhirlpool-0: " + (new Whirlpool()).run(arrayBuffer, ["Whirlpool-0"]) +
+ "\nWhirlpool-T: " + (new Whirlpool()).run(arrayBuffer, ["Whirlpool-T"]) +
+ "\nWhirlpool: " + (new Whirlpool()).run(arrayBuffer, ["Whirlpool"]) +
+ "\nSSDEEP: " + (new SSDEEP()).run(str) +
+ "\nCTPH: " + (new CTPH()).run(str) +
+ "\n\nChecksums:" +
+ "\nFletcher-8: " + (new Fletcher8Checksum).run(byteArray, []) +
+ "\nFletcher-16: " + (new Fletcher16Checksum).run(byteArray, []) +
+ "\nFletcher-32: " + (new Fletcher32Checksum).run(byteArray, []) +
+ "\nFletcher-64: " + (new Fletcher64Checksum).run(byteArray, []) +
+ "\nAdler-32: " + (new Adler32Checksum).run(byteArray, []) +
+ "\nCRC-16: " + (new CRC16Checksum).run(str, []) +
+ "\nCRC-32: " + (new CRC32Checksum).run(str, []);
+
+ return output;
+ }
+
+}
+
+export default GenerateAllHashes;
diff --git a/src/core/operations/HAS160.mjs b/src/core/operations/HAS160.mjs
new file mode 100644
index 00000000..1cf1ab6e
--- /dev/null
+++ b/src/core/operations/HAS160.mjs
@@ -0,0 +1,40 @@
+/**
+ * @author n1474335 [n1474335@gmail.com]
+ * @copyright Crown Copyright 2016
+ * @license Apache-2.0
+ */
+
+import Operation from "../Operation";
+import {runHash} from "../lib/Hash";
+
+/**
+ * HAS-160 operation
+ */
+class HAS160 extends Operation {
+
+ /**
+ * HAS-160 constructor
+ */
+ constructor() {
+ super();
+
+ this.name = "HAS-160";
+ this.module = "Hashing";
+ this.description = "HAS-160 is a cryptographic hash function designed for use with the Korean KCDSA digital signature algorithm. It is derived from SHA-1, with assorted changes intended to increase its security. It produces a 160-bit output.
HAS-160 is used in the same way as SHA-1. First it divides input in blocks of 512 bits each and pads the final block. A digest function updates the intermediate hash value by processing the input blocks in turn.
The message digest algorithm consists of 80 rounds.";
+ this.inputType = "ArrayBuffer";
+ this.outputType = "string";
+ this.args = [];
+ }
+
+ /**
+ * @param {ArrayBuffer} input
+ * @param {Object[]} args
+ * @returns {string}
+ */
+ run(input, args) {
+ return runHash("has160", input);
+ }
+
+}
+
+export default HAS160;
diff --git a/src/core/operations/HMAC.mjs b/src/core/operations/HMAC.mjs
new file mode 100644
index 00000000..e29656ce
--- /dev/null
+++ b/src/core/operations/HMAC.mjs
@@ -0,0 +1,87 @@
+/**
+ * @author n1474335 [n1474335@gmail.com]
+ * @copyright Crown Copyright 2016
+ * @license Apache-2.0
+ */
+
+import Operation from "../Operation";
+import Utils from "../Utils";
+import CryptoApi from "crypto-api/src/crypto-api";
+
+/**
+ * HMAC operation
+ */
+class HMAC extends Operation {
+
+ /**
+ * HMAC constructor
+ */
+ constructor() {
+ super();
+
+ this.name = "HMAC";
+ this.module = "Hashing";
+ this.description = "Keyed-Hash Message Authentication Codes (HMAC) are a mechanism for message authentication using cryptographic hash functions.";
+ this.inputType = "ArrayBuffer";
+ this.outputType = "string";
+ this.args = [
+ {
+ "name": "Key",
+ "type": "binaryString",
+ "value": ""
+ },
+ {
+ "name": "Hashing function",
+ "type": "option",
+ "value": [
+ "MD2",
+ "MD4",
+ "MD5",
+ "SHA0",
+ "SHA1",
+ "SHA224",
+ "SHA256",
+ "SHA384",
+ "SHA512",
+ "SHA512/224",
+ "SHA512/256",
+ "RIPEMD128",
+ "RIPEMD160",
+ "RIPEMD256",
+ "RIPEMD320",
+ "HAS160",
+ "Whirlpool",
+ "Whirlpool-0",
+ "Whirlpool-T",
+ "Snefru"
+ ]
+ }
+ ];
+ }
+
+ /**
+ * @param {ArrayBuffer} input
+ * @param {Object[]} args
+ * @returns {string}
+ */
+ run(input, args) {
+ const key = args[0],
+ hashFunc = args[1].toLowerCase(),
+ msg = Utils.arrayBufferToStr(input, false),
+ hasher = CryptoApi.getHasher(hashFunc);
+
+ // Horrible shim to fix constructor bug. Reported in nf404/crypto-api#8
+ hasher.reset = () => {
+ hasher.state = {};
+ const tmp = new hasher.constructor();
+ hasher.state = tmp.state;
+ };
+
+ const mac = CryptoApi.getHmac(CryptoApi.encoder.fromUtf(key), hasher);
+ mac.update(msg);
+ return CryptoApi.encoder.toHex(mac.finalize());
+ }
+
+}
+
+export default HMAC;
diff --git a/src/core/operations/Keccak.mjs b/src/core/operations/Keccak.mjs
new file mode 100644
index 00000000..cfe5dd8a
--- /dev/null
+++ b/src/core/operations/Keccak.mjs
@@ -0,0 +1,67 @@
+/**
+ * @author n1474335 [n1474335@gmail.com]
+ * @copyright Crown Copyright 2016
+ * @license Apache-2.0
+ */
+
+import Operation from "../Operation";
+import JSSHA3 from "js-sha3";
+import OperationError from "../errors/OperationError";
+
+/**
+ * Keccak operation
+ */
+class Keccak extends Operation {
+
+ /**
+ * Keccak constructor
+ */
+ constructor() {
+ super();
+
+ this.name = "Keccak";
+ this.module = "Hashing";
+ this.description = "The Keccak hash algorithm was designed by Guido Bertoni, Joan Daemen, Micha\xebl Peeters, and Gilles Van Assche, building upon RadioGat\xfan. It was selected as the winner of the SHA-3 design competition.
This version of the algorithm is Keccak[c=2d] and differs from the SHA-3 specification.";
+ this.inputType = "ArrayBuffer";
+ this.outputType = "string";
+ this.args = [
+ {
+ "name": "Size",
+ "type": "option",
+ "value": ["512", "384", "256", "224"]
+ }
+ ];
+ }
+
+ /**
+ * @param {ArrayBuffer} input
+ * @param {Object[]} args
+ * @returns {string}
+ */
+ run(input, args) {
+ const size = parseInt(args[0], 10);
+ let algo;
+
+ switch (size) {
+ case 224:
+ algo = JSSHA3.keccak224;
+ break;
+ case 384:
+ algo = JSSHA3.keccak384;
+ break;
+ case 256:
+ algo = JSSHA3.keccak256;
+ break;
+ case 512:
+ algo = JSSHA3.keccak512;
+ break;
+ default:
+ throw new OperationError("Invalid size");
+ }
+
+ return algo(input);
+ }
+
+}
+
+export default Keccak;
diff --git a/src/core/operations/MD2.mjs b/src/core/operations/MD2.mjs
new file mode 100644
index 00000000..ab21a397
--- /dev/null
+++ b/src/core/operations/MD2.mjs
@@ -0,0 +1,40 @@
+/**
+ * @author n1474335 [n1474335@gmail.com]
+ * @copyright Crown Copyright 2016
+ * @license Apache-2.0
+ */
+
+import Operation from "../Operation";
+import {runHash} from "../lib/Hash";
+
+/**
+ * MD2 operation
+ */
+class MD2 extends Operation {
+
+ /**
+ * MD2 constructor
+ */
+ constructor() {
+ super();
+
+ this.name = "MD2";
+ this.module = "Hashing";
+ this.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.
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.";
+ this.inputType = "ArrayBuffer";
+ this.outputType = "string";
+ this.args = [];
+ }
+
+ /**
+ * @param {ArrayBuffer} input
+ * @param {Object[]} args
+ * @returns {string}
+ */
+ run(input, args) {
+ return runHash("md2", input);
+ }
+
+}
+
+export default MD2;
diff --git a/src/core/operations/MD4.mjs b/src/core/operations/MD4.mjs
new file mode 100644
index 00000000..52712580
--- /dev/null
+++ b/src/core/operations/MD4.mjs
@@ -0,0 +1,40 @@
+/**
+ * @author n1474335 [n1474335@gmail.com]
+ * @copyright Crown Copyright 2016
+ * @license Apache-2.0
+ */
+
+import Operation from "../Operation";
+import {runHash} from "../lib/Hash";
+
+/**
+ * MD4 operation
+ */
+class MD4 extends Operation {
+
+ /**
+ * MD4 constructor
+ */
+ constructor() {
+ super();
+
+ this.name = "MD4";
+ this.module = "Hashing";
+ this.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.
The security of MD4 has been severely compromised.";
+ this.inputType = "ArrayBuffer";
+ this.outputType = "string";
+ this.args = [];
+ }
+
+ /**
+ * @param {ArrayBuffer} input
+ * @param {Object[]} args
+ * @returns {string}
+ */
+ run(input, args) {
+ return runHash("md4", input);
+ }
+
+}
+
+export default MD4;
diff --git a/src/core/operations/MD5.mjs b/src/core/operations/MD5.mjs
new file mode 100644
index 00000000..692f0f96
--- /dev/null
+++ b/src/core/operations/MD5.mjs
@@ -0,0 +1,40 @@
+/**
+ * @author n1474335 [n1474335@gmail.com]
+ * @copyright Crown Copyright 2016
+ * @license Apache-2.0
+ */
+
+import Operation from "../Operation";
+import {runHash} from "../lib/Hash";
+
+/**
+ * MD5 operation
+ */
+class MD5 extends Operation {
+
+ /**
+ * MD5 constructor
+ */
+ constructor() {
+ super();
+
+ this.name = "MD5";
+ this.module = "Hashing";
+ this.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.
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.";
+ this.inputType = "ArrayBuffer";
+ this.outputType = "string";
+ this.args = [];
+ }
+
+ /**
+ * @param {ArrayBuffer} input
+ * @param {Object[]} args
+ * @returns {string}
+ */
+ run(input, args) {
+ return runHash("md5", input);
+ }
+
+}
+
+export default MD5;
diff --git a/src/core/operations/MD6.mjs b/src/core/operations/MD6.mjs
new file mode 100644
index 00000000..2d12cc27
--- /dev/null
+++ b/src/core/operations/MD6.mjs
@@ -0,0 +1,64 @@
+/**
+ * @author n1474335 [n1474335@gmail.com]
+ * @copyright Crown Copyright 2016
+ * @license Apache-2.0
+ */
+
+import Operation from "../Operation";
+import OperationError from "../errors/OperationError";
+import NodeMD6 from "node-md6";
+
+/**
+ * MD6 operation
+ */
+class MD6 extends Operation {
+
+ /**
+ * MD6 constructor
+ */
+ constructor() {
+ super();
+
+ this.name = "MD6";
+ this.module = "Hashing";
+ this.description = "The MD6 (Message-Digest 6) algorithm is a cryptographic hash function. It uses a Merkle tree-like structure to allow for immense parallel computation of hashes for very long inputs.";
+ this.inputType = "string";
+ this.outputType = "string";
+ this.args = [
+ {
+ "name": "Size",
+ "type": "number",
+ "value": 256
+ },
+ {
+ "name": "Levels",
+ "type": "number",
+ "value": 64
+ },
+ {
+ "name": "Key",
+ "type": "string",
+ "value": ""
+ }
+ ];
+ }
+
+ /**
+ * @param {string} input
+ * @param {Object[]} args
+ * @returns {string}
+ */
+ run(input, args) {
+ const [size, levels, key] = args;
+
+ if (size < 0 || size > 512)
+ throw new OperationError("Size must be between 0 and 512");
+ if (levels < 0)
+ throw new OperationError("Levels must be greater than 0");
+
+ return NodeMD6.getHashOfText(input, size, key, levels);
+ }
+
+}
+
+export default MD6;
diff --git a/src/core/operations/RIPEMD.mjs b/src/core/operations/RIPEMD.mjs
new file mode 100644
index 00000000..07cfe4b4
--- /dev/null
+++ b/src/core/operations/RIPEMD.mjs
@@ -0,0 +1,47 @@
+/**
+ * @author n1474335 [n1474335@gmail.com]
+ * @copyright Crown Copyright 2016
+ * @license Apache-2.0
+ */
+
+import Operation from "../Operation";
+import {runHash} from "../lib/Hash";
+
+/**
+ * RIPEMD operation
+ */
+class RIPEMD extends Operation {
+
+ /**
+ * RIPEMD constructor
+ */
+ constructor() {
+ super();
+
+ this.name = "RIPEMD";
+ this.module = "Hashing";
+ this.description = "RIPEMD (RACE Integrity Primitives Evaluation Message Digest) is a family of cryptographic hash functions developed in Leuven, Belgium, by Hans Dobbertin, Antoon Bosselaers and Bart Preneel at the COSIC research group at the Katholieke Universiteit Leuven, and first published in 1996.
RIPEMD was based upon the design principles used in MD4, and is similar in performance to the more popular SHA-1.
";
+ this.inputType = "ArrayBuffer";
+ this.outputType = "string";
+ this.args = [
+ {
+ "name": "Size",
+ "type": "option",
+ "value": ["320", "256", "160", "128"]
+ }
+ ];
+ }
+
+ /**
+ * @param {ArrayBuffer} input
+ * @param {Object[]} args
+ * @returns {string}
+ */
+ run(input, args) {
+ const size = args[0];
+ return runHash("ripemd" + size, input);
+ }
+
+}
+
+export default RIPEMD;
diff --git a/src/core/operations/SHA0.mjs b/src/core/operations/SHA0.mjs
new file mode 100644
index 00000000..292c63ce
--- /dev/null
+++ b/src/core/operations/SHA0.mjs
@@ -0,0 +1,40 @@
+/**
+ * @author n1474335 [n1474335@gmail.com]
+ * @copyright Crown Copyright 2016
+ * @license Apache-2.0
+ */
+
+import Operation from "../Operation";
+import {runHash} from "../lib/Hash";
+
+/**
+ * SHA0 operation
+ */
+class SHA0 extends Operation {
+
+ /**
+ * SHA0 constructor
+ */
+ constructor() {
+ super();
+
+ this.name = "SHA0";
+ this.module = "Hashing";
+ this.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.";
+ this.inputType = "ArrayBuffer";
+ this.outputType = "string";
+ this.args = [];
+ }
+
+ /**
+ * @param {ArrayBuffer} input
+ * @param {Object[]} args
+ * @returns {string}
+ */
+ run(input, args) {
+ return runHash("sha0", input);
+ }
+
+}
+
+export default SHA0;
diff --git a/src/core/operations/SHA1.mjs b/src/core/operations/SHA1.mjs
new file mode 100644
index 00000000..904c55f0
--- /dev/null
+++ b/src/core/operations/SHA1.mjs
@@ -0,0 +1,40 @@
+/**
+ * @author n1474335 [n1474335@gmail.com]
+ * @copyright Crown Copyright 2016
+ * @license Apache-2.0
+ */
+
+import Operation from "../Operation";
+import {runHash} from "../lib/Hash";
+
+/**
+ * SHA1 operation
+ */
+class SHA1 extends Operation {
+
+ /**
+ * SHA1 constructor
+ */
+ constructor() {
+ super();
+
+ this.name = "SHA1";
+ this.module = "Hashing";
+ this.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.
However, SHA-1's collision resistance has been weakening as new attacks are discovered or improved.";
+ this.inputType = "ArrayBuffer";
+ this.outputType = "string";
+ this.args = [];
+ }
+
+ /**
+ * @param {ArrayBuffer} input
+ * @param {Object[]} args
+ * @returns {string}
+ */
+ run(input, args) {
+ return runHash("sha1", input);
+ }
+
+}
+
+export default SHA1;
diff --git a/src/core/operations/SHA2.mjs b/src/core/operations/SHA2.mjs
new file mode 100644
index 00000000..c5480727
--- /dev/null
+++ b/src/core/operations/SHA2.mjs
@@ -0,0 +1,47 @@
+/**
+ * @author n1474335 [n1474335@gmail.com]
+ * @copyright Crown Copyright 2016
+ * @license Apache-2.0
+ */
+
+import Operation from "../Operation";
+import {runHash} from "../lib/Hash";
+
+/**
+ * SHA2 operation
+ */
+class SHA2 extends Operation {
+
+ /**
+ * SHA2 constructor
+ */
+ constructor() {
+ super();
+
+ this.name = "SHA2";
+ this.module = "Hashing";
+ this.description = "The SHA-2 (Secure Hash Algorithm 2) hash functions were designed by the NSA. SHA-2 includes significant changes from its predecessor, SHA-1. The SHA-2 family consists of hash functions with digests (hash values) that are 224, 256, 384 or 512 bits: SHA224, SHA256, SHA384, SHA512.