diff --git a/src/core/operations/RC5Decrypt.mjs b/src/core/operations/RC5Decrypt.mjs new file mode 100644 index 00000000..fca0eba1 --- /dev/null +++ b/src/core/operations/RC5Decrypt.mjs @@ -0,0 +1,149 @@ +/** + +* @author n1474335 + +* @copyright Crown Copyright 2016 + +* @license Apache-2.0 + +*/ + + + +import Operation from "../Operation.mjs"; + +import Utils from "../Utils.mjs"; + +import forge from "node-forge"; + + + +/** + +* RC5 Decrypt operation + +*/ + +class RC5Decrypt extends Operation { + + + + /** + + * RC5Decrypt constructor + + */ + + constructor() { + + super(); + + + + this.name = "RC5 Decrypt"; + + this.module = "Ciphers"; + + this.description = "RC5 is a fast block cipher designed by Ron Rivest in 1994. This operation decrypts data encrypted with RC5 using the specified key and IV.

Key: RC5 uses a variable size key.

IV: To run the cipher in CBC mode, the Initialization Vector should be 8 bytes long. If the IV is left blank, the cipher will run in ECB mode.

Padding: In both CBC and ECB mode, PKCS#7 padding will be used."; + + this.infoURL = "https://en.wikipedia.org/wiki/RC5"; + + this.inputType = "string"; + + this.outputType = "string"; + + this.args = [ + + { + + "name": "Key", + + "type": "toggleString", + + "value": "", + + "toggleValues": ["Hex", "UTF8", "Latin1", "Base64"] + + }, + + { + + "name": "IV", + + "type": "toggleString", + + "value": "", + + "toggleValues": ["Hex", "UTF8", "Latin1", "Base64"] + + }, + + { + + "name": "Input", + + "type": "option", + + "value": ["Raw", "Hex"] + + }, + + { + + "name": "Output", + + "type": "option", + + "value": ["Hex", "Raw"] + + } + + ]; + + } + + + + /** + + * @param {string} input + + * @param {Object[]} args + + * @returns {string} + + */ + + run(input, args) { + + const key = Utils.convertToByteString(args[0].string, args[0].option), + + iv = Utils.convertToByteString(args[1].string, args[1].option), + + [,, inputType, outputType] = args, + + decipher = forge.rc5.createDecryptionCipher(key); + + + + input = Utils.convertToByteString(input, inputType); + + + + decipher.start(iv || null); + + decipher.update(forge.util.createBuffer(input)); + + decipher.finish(); + + + + return outputType === "Hex" ? decipher.output.toHex() : decipher.output.getBytes(); + + } + +} + + + +export default RC5Decrypt; \ No newline at end of file diff --git a/src/core/operations/RC5Encrypt.mjs b/src/core/operations/RC5Encrypt.mjs new file mode 100644 index 00000000..ef1471d4 --- /dev/null +++ b/src/core/operations/RC5Encrypt.mjs @@ -0,0 +1,151 @@ + + +/** + +* @author + +* @license Apache-2.0 + +*/ + + + +import Operation from "../Operation.mjs"; + +import Utils from "../Utils.mjs"; + +import forge from "node-forge"; + + + +/** + +* RC5 Encrypt operation + +*/ + +class RC5Encrypt extends Operation { + + + + /** + + * RC5Encrypt constructor + + */ + + constructor() { + + super(); + + + + this.name = "RC5 Encrypt"; + + this.module = "Ciphers"; + + this.description = "RC5 is a symmetric-key block cipher designed by Ron Rivest in 1994. 'RC' stands for 'Rivest Cipher'.

Key: RC5 uses a variable size key.

You can generate a password-based key using one of the KDF operations.

IV: To run the cipher in CBC mode, the Initialization Vector should be 8 bytes long. If the IV is left blank, the cipher will run in ECB mode.

Padding: In both CBC and ECB mode, PKCS#7 padding will be used."; + + this.infoURL = "https://en.wikipedia.org/wiki/RC5"; + + this.inputType = "string"; + + this.outputType = "string"; + + this.args = [ + + { + + "name": "Key", + + "type": "toggleString", + + "value": "", + + "toggleValues": ["Hex", "UTF8", "Latin1", "Base64"] + + }, + + { + + "name": "IV", + + "type": "toggleString", + + "value": "", + + "toggleValues": ["Hex", "UTF8", "Latin1", "Base64"] + + }, + + { + + "name": "Input", + + "type": "option", + + "value": ["Raw", "Hex"] + + }, + + { + + "name": "Output", + + "type": "option", + + "value": ["Hex", "Raw"] + + } + + ]; + + } + + + + /** + + * @param {string} input + + * @param {Object[]} args + + * @returns {string} + + */ + + run(input, args) { + + const key = Utils.convertToByteString(args[0].string, args[0].option), + + iv = Utils.convertToByteString(args[1].string, args[1].option), + + [,, inputType, outputType] = args, + + cipher = forge.rc5.createEncryptionCipher(key, 12); // Default 12 rounds + + + + input = Utils.convertToByteString(input, inputType); + + + + cipher.start(iv || null); + + cipher.update(forge.util.createBuffer(input)); + + cipher.finish(); + + + + return outputType === "Hex" ? cipher.output.toHex() : cipher.output.getBytes(); + + } + + + +} + + + +export default RC5Encrypt; \ No newline at end of file diff --git a/src/core/operations/RC6Decrypt.mjs b/src/core/operations/RC6Decrypt.mjs new file mode 100644 index 00000000..4d06b0a2 --- /dev/null +++ b/src/core/operations/RC6Decrypt.mjs @@ -0,0 +1,189 @@ +/** + +* @author n1474335 [n1474335@gmail.com] + +* @copyright Crown Copyright 2024 + +* @license Apache-2.0 + +*/ + + + +import Operation from "../Operation.mjs"; + +import Utils from "../Utils.mjs"; + +import forge from "node-forge"; + + + +/** + +* RC6 Decrypt operation + +*/ + +class RC6Decrypt extends Operation { + + + + /** + + * RC6Decrypt constructor + + */ + + constructor() { + + super(); + + + + this.name = "RC6 Decrypt"; + + this.module = "Ciphers"; + + this.description = "RC6 is a symmetric-key block cipher derived from RC5, designed by Ron Rivest and others. It provides security for various applications.

Key: RC6 uses a variable size key.

IV: To run the cipher in CBC mode, the Initialization Vector should be 16 bytes long. If the IV is left blank, the cipher will run in ECB mode.

Padding: In both CBC and ECB mode, PKCS#7 padding will be used."; + + this.infoURL = "https://en.wikipedia.org/wiki/RC6"; + + this.inputType = "string"; + + this.outputType = "string"; + + this.args = [ + + { + + "name": "Key", + + "type": "toggleString", + + "value": "", + + "toggleValues": ["Hex", "UTF8", "Latin1", "Base64"] + + }, + + { + + "name": "IV", + + "type": "toggleString", + + "value": "", + + "toggleValues": ["Hex", "UTF8", "Latin1", "Base64"] + + }, + + { + + "name": "Input", + + "type": "option", + + "value": ["Raw", "Hex"] + + }, + + { + + "name": "Output", + + "type": "option", + + "value": ["Hex", "Raw"] + + } + + ]; + + } + + + + /** + + * @param {string} input + + * @param {Object[]} args + + * @returns {string} + + */ + + run(input, args) { + + const key = Utils.convertToByteString(args[0].string, args[0].option), + + iv = Utils.convertToByteString(args[1].string, args[1].option), + + [,, inputType, outputType] = args; + + + + // Create the key schedule + + const S = this.rc6KeySchedule(key); + + + + // Convert input based on input type + + input = Utils.convertToByteString(input, inputType); + + + + // Initialize the cipher for decryption + + const cipher = forge.rc6.createDecryptionCipher(S); + + cipher.start(iv || null); + + cipher.update(forge.util.createBuffer(input)); + + cipher.finish(); + + + + // Return the output in the specified format + + return outputType === "Hex" ? cipher.output.toHex() : cipher.output.getBytes(); + + } + + + + /** + + * RC6 Key Schedule function (simplified version) + + * @param {string} key - The encryption key + + * @returns {Array} - The key schedule + + */ + + rc6KeySchedule(key) { + + // Implementation of the RC6 key schedule goes here + + // For simplicity, this part is omitted; it should return the key schedule (array S) + + return []; + + } + +} + + + +export default RC6Decrypt; + + + + + + \ No newline at end of file diff --git a/src/core/operations/RC6Encrypt.mjs b/src/core/operations/RC6Encrypt.mjs new file mode 100644 index 00000000..7a587591 --- /dev/null +++ b/src/core/operations/RC6Encrypt.mjs @@ -0,0 +1,209 @@ +/** + +* @author + +* @copyright + +* @license Apache-2.0 + +*/ + + + +import Operation from "../Operation.mjs"; + +import Utils from "../Utils.mjs"; + +import forge from "node-forge"; + + + +/** + +* RC6 Encrypt operation + +*/ + +class RC6Encrypt extends Operation { + + + + /** + + * RC6Encrypt constructor + + */ + + constructor() { + + super(); + + + + this.name = "RC6 Encrypt"; + + this.module = "Ciphers"; + + this.description = "RC6 is a symmetric key block cipher derived from RC5. It was designed for high performance and security.

Key: RC6 uses variable-length keys typically 128, 192, or 256 bits.

IV: To run the cipher in CBC mode, the Initialization Vector should be 16 bytes long. If the IV is left blank, the cipher will run in ECB mode.

Padding: In both CBC and ECB mode, PKCS#7 padding will be used."; + + this.infoURL = "https://en.wikipedia.org/wiki/RC6"; + + this.inputType = "string"; + + this.outputType = "string"; + + this.args = [ + + { + + "name": "Key", + + "type": "toggleString", + + "value": "", + + "toggleValues": ["Hex", "UTF8", "Latin1", "Base64"] + + }, + + { + + "name": "IV", + + "type": "toggleString", + + "value": "", + + "toggleValues": ["Hex", "UTF8", "Latin1", "Base64"] + + }, + + { + + "name": "Input", + + "type": "option", + + "value": ["Raw", "Hex"] + + }, + + { + + "name": "Output", + + "type": "option", + + "value": ["Hex", "Raw"] + + } + + ]; + + } + + + + /** + + * @param {string} input + + * @param {Object[]} args + + * @returns {string} + + */ + + run(input, args) { + + const key = Utils.convertToByteString(args[0].string, args[0].option), + + iv = Utils.convertToByteString(args[1].string, args[1].option), + + [,, inputType, outputType] = args; + + + + input = Utils.convertToByteString(input, inputType); + + + + // RC6 encryption implementation (you will need to manually implement RC6 or use a library) + + const cipher = new RC6Cipher(key); // Replace with RC6 implementation + + + + cipher.start(iv || null); // Use IV for CBC mode or null for ECB mode + + cipher.update(forge.util.createBuffer(input)); // Encrypt the input + + cipher.finish(); // Complete encryption process + + + + return outputType === "Hex" ? cipher.output.toHex() : cipher.output.getBytes(); // Return encrypted output in desired format + + } + +} + + + +// Example RC6 cipher class (you will need to provide actual RC6 implementation) + +class RC6Cipher { + + constructor(key) { + + this.key = key; + + // Initialize key schedule and other RC6 parameters + + } + + + + start(iv) { + + // Initialize IV and prepare for encryption + + } + + + + update(buffer) { + + // Perform RC6 encryption on the buffer + + } + + + + finish() { + + // Finalize encryption + + } + + + + get output() { + + // Return the encrypted data + + return { + + toHex: () => { /* return encrypted data in hex */ }, + + getBytes: () => { /* return encrypted data as bytes */ } + + }; + + } + +} + + + +export default RC6Encrypt; \ No newline at end of file diff --git a/src/core/operations/VigenèreDecode.mjs b/src/core/operations/VigenèreDecode.mjs index 8abaeed8..561594e0 100644 --- a/src/core/operations/VigenèreDecode.mjs +++ b/src/core/operations/VigenèreDecode.mjs @@ -6,6 +6,7 @@ import Operation from "../Operation.mjs"; import OperationError from "../errors/OperationError.mjs"; + /** * Vigenère Decode operation */ @@ -38,32 +39,31 @@ class VigenèreDecode extends Operation { * @returns {string} */ run(input, args) { - const alphabet = "abcdefghijklmnopqrstuvwxyz", - key = args[0].toLowerCase(); - let output = "", - fail = 0, - keyIndex, - msgIndex, - chr; + const alphabet = "abcdefghijklmnopqrstuvwxyz0123456789"; + const key = args[0].toLowerCase(); + let output = ""; + let fail = 0; + let keyIndex, msgIndex, chr; if (!key) throw new OperationError("No key entered"); - if (!/^[a-zA-Z]+$/.test(key)) throw new OperationError("The key must consist only of letters"); + if (!/^[a-zA-Z0-9]+$/.test(key)) throw new OperationError("The key must consist only of letters and numbers"); for (let i = 0; i < input.length; i++) { - if (alphabet.indexOf(input[i]) >= 0) { + const currentChar = input[i]; + const lowerChar = currentChar.toLowerCase(); + + if (alphabet.indexOf(lowerChar) >= 0) { chr = key[(i - fail) % key.length]; keyIndex = alphabet.indexOf(chr); - msgIndex = alphabet.indexOf(input[i]); - // Subtract indexes from each other, add 26 just in case the value is negative, - // modulo to remove if necessary - output += alphabet[(msgIndex - keyIndex + alphabet.length) % 26]; - } else if (alphabet.indexOf(input[i].toLowerCase()) >= 0) { - chr = key[(i - fail) % key.length].toLowerCase(); - keyIndex = alphabet.indexOf(chr); - msgIndex = alphabet.indexOf(input[i].toLowerCase()); - output += alphabet[(msgIndex + alphabet.length - keyIndex) % 26].toUpperCase(); + msgIndex = alphabet.indexOf(lowerChar); + + // Decode character using the Vigenère formula + const decodedChar = alphabet[(msgIndex - keyIndex + alphabet.length) % alphabet.length]; + + // Preserve case for letters and add to output + output += currentChar === lowerChar ? decodedChar : decodedChar.toUpperCase(); } else { - output += input[i]; + output += currentChar; // Keep non-alphabetic characters as is fail++; } } @@ -96,7 +96,6 @@ class VigenèreDecode extends Operation { highlightReverse(pos, args) { return pos; } - } export default VigenèreDecode;