Merge remote-tracking branch 'upstream/master'

This commit is contained in:
victorlpgazolli 2023-03-23 20:04:04 -03:00
commit 93cbdae32a
138 changed files with 8637 additions and 5017 deletions

View file

@ -27,8 +27,8 @@ class Chef {
*
* @param {string|ArrayBuffer} input - The input data as a string or ArrayBuffer
* @param {Object[]} recipeConfig - The recipe configuration object
* @param {Object} options - The options object storing various user choices
* @param {boolean} options.attempHighlight - Whether or not to attempt highlighting
* @param {Object} [options={}] - The options object storing various user choices
* @param {string} [options.returnType] - What type to return the result as
*
* @returns {Object} response
* @returns {string} response.result - The output of the recipe
@ -37,12 +37,11 @@ class Chef {
* @returns {number} response.duration - The number of ms it took to execute the recipe
* @returns {number} response.error - The error object thrown by a failed operation (false if no error)
*/
async bake(input, recipeConfig, options) {
async bake(input, recipeConfig, options={}) {
log.debug("Chef baking");
const startTime = Date.now(),
recipe = new Recipe(recipeConfig),
containsFc = recipe.containsFlowControl(),
notUTF8 = options && "treatAsUtf8" in options && !options.treatAsUtf8;
containsFc = recipe.containsFlowControl();
let error = false,
progress = 0;
@ -68,20 +67,13 @@ class Chef {
// Present the raw result
await recipe.present(this.dish);
// Depending on the size of the output, we may send it back as a string or an ArrayBuffer.
// This can prevent unnecessary casting as an ArrayBuffer can be easily downloaded as a file.
// The threshold is specified in KiB.
const threshold = (options.ioDisplayThreshold || 1024) * 1024;
const returnType =
this.dish.type === Dish.HTML ?
Dish.HTML :
this.dish.size > threshold ?
Dish.ARRAY_BUFFER :
Dish.STRING;
this.dish.type === Dish.HTML ? Dish.HTML :
options?.returnType ? options.returnType : Dish.ARRAY_BUFFER;
return {
dish: rawDish,
result: await this.dish.get(returnType, notUTF8),
result: await this.dish.get(returnType),
type: Dish.enumLookup(this.dish.type),
progress: progress,
duration: Date.now() - startTime,

View file

@ -9,16 +9,8 @@
import Chef from "./Chef.mjs";
import OperationConfig from "./config/OperationConfig.json" assert {type: "json"};
import OpModules from "./config/modules/OpModules.mjs";
// Add ">" to the start of all log messages in the Chef Worker
import loglevelMessagePrefix from "loglevel-message-prefix";
loglevelMessagePrefix(log, {
prefixes: [],
staticPrefixes: [">"],
prefixFormat: "%p"
});
// Set up Chef instance
self.chef = new Chef();
@ -56,7 +48,7 @@ self.postMessage({
self.addEventListener("message", function(e) {
// Handle message
const r = e.data;
log.debug("ChefWorker receiving command '" + r.action + "'");
log.debug(`Receiving command '${r.action}'`);
switch (r.action) {
case "bake":
@ -86,6 +78,12 @@ self.addEventListener("message", function(e) {
case "setLogLevel":
log.setLevel(r.data, false);
break;
case "setLogPrefix":
loglevelMessagePrefix(log, {
prefixes: [],
staticPrefixes: [r.data]
});
break;
default:
break;
}
@ -101,14 +99,17 @@ async function bake(data) {
// Ensure the relevant modules are loaded
self.loadRequiredModules(data.recipeConfig);
try {
self.inputNum = (data.inputNum !== undefined) ? data.inputNum : -1;
self.inputNum = data.inputNum === undefined ? -1 : data.inputNum;
const response = await self.chef.bake(
data.input, // The user's input
data.recipeConfig, // The configuration of the recipe
data.options // Options set by the user
);
const transferable = (data.input instanceof ArrayBuffer) ? [data.input] : undefined;
const transferable = (response.dish.value instanceof ArrayBuffer) ?
[response.dish.value] :
undefined;
self.postMessage({
action: "bakeComplete",
data: Object.assign(response, {
@ -186,7 +187,7 @@ async function getDishTitle(data) {
*
* @param {Object[]} recipeConfig
* @param {string} direction
* @param {Object} pos - The position object for the highlight.
* @param {Object[]} pos - The position object for the highlight.
* @param {number} pos.start - The start offset.
* @param {number} pos.end - The end offset.
*/

View file

@ -128,10 +128,9 @@ class Dish {
* If running in a browser, get is asynchronous.
*
* @param {number} type - The data type of value, see Dish enums.
* @param {boolean} [notUTF8=false] - Do not treat strings as UTF8.
* @returns {* | Promise} - (Browser) A promise | (Node) value of dish in given type
*/
get(type, notUTF8=false) {
get(type) {
if (typeof type === "string") {
type = Dish.typeEnum(type);
}
@ -140,13 +139,13 @@ class Dish {
// Node environment => _translate is sync
if (isNodeEnvironment()) {
this._translate(type, notUTF8);
this._translate(type);
return this.value;
// Browser environment => _translate is async
} else {
return new Promise((resolve, reject) => {
this._translate(type, notUTF8)
this._translate(type)
.then(() => {
resolve(this.value);
})
@ -190,12 +189,11 @@ class Dish {
* @Node
*
* @param {number} type - The data type of value, see Dish enums.
* @param {boolean} [notUTF8=false] - Do not treat strings as UTF8.
* @returns {Dish | Promise} - (Browser) A promise | (Node) value of dish in given type
*/
presentAs(type, notUTF8=false) {
presentAs(type) {
const clone = this.clone();
return clone.get(type, notUTF8);
return clone.get(type);
}
@ -414,17 +412,16 @@ class Dish {
* If running in the browser, _translate is asynchronous.
*
* @param {number} toType - The data type of value, see Dish enums.
* @param {boolean} [notUTF8=false] - Do not treat strings as UTF8.
* @returns {Promise || undefined}
*/
_translate(toType, notUTF8=false) {
_translate(toType) {
log.debug(`Translating Dish from ${Dish.enumLookup(this.type)} to ${Dish.enumLookup(toType)}`);
// Node environment => translate is sync
if (isNodeEnvironment()) {
this._toArrayBuffer();
this.type = Dish.ARRAY_BUFFER;
this._fromArrayBuffer(toType, notUTF8);
this._fromArrayBuffer(toType);
// Browser environment => translate is async
} else {
@ -486,18 +483,17 @@ class Dish {
* Convert this.value to the given type from ArrayBuffer
*
* @param {number} toType - the Dish enum to convert to
* @param {boolean} [notUTF8=false] - Do not treat strings as UTF8.
*/
_fromArrayBuffer(toType, notUTF8) {
_fromArrayBuffer(toType) {
// Using 'bind' here to allow this.value to be mutated within translation functions
const toTypeFunctions = {
[Dish.STRING]: () => DishString.fromArrayBuffer.bind(this)(notUTF8),
[Dish.NUMBER]: () => DishNumber.fromArrayBuffer.bind(this)(notUTF8),
[Dish.HTML]: () => DishHTML.fromArrayBuffer.bind(this)(notUTF8),
[Dish.STRING]: () => DishString.fromArrayBuffer.bind(this)(),
[Dish.NUMBER]: () => DishNumber.fromArrayBuffer.bind(this)(),
[Dish.HTML]: () => DishHTML.fromArrayBuffer.bind(this)(),
[Dish.ARRAY_BUFFER]: () => {},
[Dish.BIG_NUMBER]: () => DishBigNumber.fromArrayBuffer.bind(this)(notUTF8),
[Dish.JSON]: () => DishJSON.fromArrayBuffer.bind(this)(notUTF8),
[Dish.BIG_NUMBER]: () => DishBigNumber.fromArrayBuffer.bind(this)(),
[Dish.JSON]: () => DishJSON.fromArrayBuffer.bind(this)(),
[Dish.FILE]: () => DishFile.fromArrayBuffer.bind(this)(),
[Dish.LIST_FILE]: () => DishListFile.fromArrayBuffer.bind(this)(),
[Dish.BYTE_ARRAY]: () => DishByteArray.fromArrayBuffer.bind(this)(),

View file

@ -230,14 +230,12 @@ class Recipe {
this.lastRunOp = op;
} catch (err) {
// Return expected errors as output
if (err instanceof OperationError ||
(err.type && err.type === "OperationError")) {
if (err instanceof OperationError || err?.type === "OperationError") {
// Cannot rely on `err instanceof OperationError` here as extending
// native types is not fully supported yet.
dish.set(err.message, "string");
return i;
} else if (err instanceof DishError ||
(err.type && err.type === "DishError")) {
} else if (err instanceof DishError || err?.type === "DishError") {
dish.set(err.message, "string");
return i;
} else {

View file

@ -4,6 +4,8 @@
* @license Apache-2.0
*/
// loglevel import required for Node API
import log from "loglevel";
import utf8 from "utf8";
import {fromBase64, toBase64} from "./lib/Base64.mjs";
import {fromHex} from "./lib/Hex.mjs";
@ -174,17 +176,13 @@ class Utils {
* @returns {string}
*/
static printable(str, preserveWs=false, onlyAscii=false) {
if (isWebEnvironment() && window.app && !window.app.options.treatAsUtf8) {
str = Utils.byteArrayToChars(Utils.strToByteArray(str));
}
if (onlyAscii) {
return str.replace(/[^\x20-\x7f]/g, ".");
}
// eslint-disable-next-line no-misleading-character-class
const re = /[\0-\x08\x0B-\x0C\x0E-\x1F\x7F-\x9F\xAD\u0378\u0379\u037F-\u0383\u038B\u038D\u03A2\u0528-\u0530\u0557\u0558\u0560\u0588\u058B-\u058E\u0590\u05C8-\u05CF\u05EB-\u05EF\u05F5-\u0605\u061C\u061D\u06DD\u070E\u070F\u074B\u074C\u07B2-\u07BF\u07FB-\u07FF\u082E\u082F\u083F\u085C\u085D\u085F-\u089F\u08A1\u08AD-\u08E3\u08FF\u0978\u0980\u0984\u098D\u098E\u0991\u0992\u09A9\u09B1\u09B3-\u09B5\u09BA\u09BB\u09C5\u09C6\u09C9\u09CA\u09CF-\u09D6\u09D8-\u09DB\u09DE\u09E4\u09E5\u09FC-\u0A00\u0A04\u0A0B-\u0A0E\u0A11\u0A12\u0A29\u0A31\u0A34\u0A37\u0A3A\u0A3B\u0A3D\u0A43-\u0A46\u0A49\u0A4A\u0A4E-\u0A50\u0A52-\u0A58\u0A5D\u0A5F-\u0A65\u0A76-\u0A80\u0A84\u0A8E\u0A92\u0AA9\u0AB1\u0AB4\u0ABA\u0ABB\u0AC6\u0ACA\u0ACE\u0ACF\u0AD1-\u0ADF\u0AE4\u0AE5\u0AF2-\u0B00\u0B04\u0B0D\u0B0E\u0B11\u0B12\u0B29\u0B31\u0B34\u0B3A\u0B3B\u0B45\u0B46\u0B49\u0B4A\u0B4E-\u0B55\u0B58-\u0B5B\u0B5E\u0B64\u0B65\u0B78-\u0B81\u0B84\u0B8B-\u0B8D\u0B91\u0B96-\u0B98\u0B9B\u0B9D\u0BA0-\u0BA2\u0BA5-\u0BA7\u0BAB-\u0BAD\u0BBA-\u0BBD\u0BC3-\u0BC5\u0BC9\u0BCE\u0BCF\u0BD1-\u0BD6\u0BD8-\u0BE5\u0BFB-\u0C00\u0C04\u0C0D\u0C11\u0C29\u0C34\u0C3A-\u0C3C\u0C45\u0C49\u0C4E-\u0C54\u0C57\u0C5A-\u0C5F\u0C64\u0C65\u0C70-\u0C77\u0C80\u0C81\u0C84\u0C8D\u0C91\u0CA9\u0CB4\u0CBA\u0CBB\u0CC5\u0CC9\u0CCE-\u0CD4\u0CD7-\u0CDD\u0CDF\u0CE4\u0CE5\u0CF0\u0CF3-\u0D01\u0D04\u0D0D\u0D11\u0D3B\u0D3C\u0D45\u0D49\u0D4F-\u0D56\u0D58-\u0D5F\u0D64\u0D65\u0D76-\u0D78\u0D80\u0D81\u0D84\u0D97-\u0D99\u0DB2\u0DBC\u0DBE\u0DBF\u0DC7-\u0DC9\u0DCB-\u0DCE\u0DD5\u0DD7\u0DE0-\u0DF1\u0DF5-\u0E00\u0E3B-\u0E3E\u0E5C-\u0E80\u0E83\u0E85\u0E86\u0E89\u0E8B\u0E8C\u0E8E-\u0E93\u0E98\u0EA0\u0EA4\u0EA6\u0EA8\u0EA9\u0EAC\u0EBA\u0EBE\u0EBF\u0EC5\u0EC7\u0ECE\u0ECF\u0EDA\u0EDB\u0EE0-\u0EFF\u0F48\u0F6D-\u0F70\u0F98\u0FBD\u0FCD\u0FDB-\u0FFF\u10C6\u10C8-\u10CC\u10CE\u10CF\u1249\u124E\u124F\u1257\u1259\u125E\u125F\u1289\u128E\u128F\u12B1\u12B6\u12B7\u12BF\u12C1\u12C6\u12C7\u12D7\u1311\u1316\u1317\u135B\u135C\u137D-\u137F\u139A-\u139F\u13F5-\u13FF\u169D-\u169F\u16F1-\u16FF\u170D\u1715-\u171F\u1737-\u173F\u1754-\u175F\u176D\u1771\u1774-\u177F\u17DE\u17DF\u17EA-\u17EF\u17FA-\u17FF\u180F\u181A-\u181F\u1878-\u187F\u18AB-\u18AF\u18F6-\u18FF\u191D-\u191F\u192C-\u192F\u193C-\u193F\u1941-\u1943\u196E\u196F\u1975-\u197F\u19AC-\u19AF\u19CA-\u19CF\u19DB-\u19DD\u1A1C\u1A1D\u1A5F\u1A7D\u1A7E\u1A8A-\u1A8F\u1A9A-\u1A9F\u1AAE-\u1AFF\u1B4C-\u1B4F\u1B7D-\u1B7F\u1BF4-\u1BFB\u1C38-\u1C3A\u1C4A-\u1C4C\u1C80-\u1CBF\u1CC8-\u1CCF\u1CF7-\u1CFF\u1DE7-\u1DFB\u1F16\u1F17\u1F1E\u1F1F\u1F46\u1F47\u1F4E\u1F4F\u1F58\u1F5A\u1F5C\u1F5E\u1F7E\u1F7F\u1FB5\u1FC5\u1FD4\u1FD5\u1FDC\u1FF0\u1FF1\u1FF5\u1FFF\u200B-\u200F\u202A-\u202E\u2060-\u206F\u2072\u2073\u208F\u209D-\u209F\u20BB-\u20CF\u20F1-\u20FF\u218A-\u218F\u23F4-\u23FF\u2427-\u243F\u244B-\u245F\u2700\u2B4D-\u2B4F\u2B5A-\u2BFF\u2C2F\u2C5F\u2CF4-\u2CF8\u2D26\u2D28-\u2D2C\u2D2E\u2D2F\u2D68-\u2D6E\u2D71-\u2D7E\u2D97-\u2D9F\u2DA7\u2DAF\u2DB7\u2DBF\u2DC7\u2DCF\u2DD7\u2DDF\u2E3C-\u2E7F\u2E9A\u2EF4-\u2EFF\u2FD6-\u2FEF\u2FFC-\u2FFF\u3040\u3097\u3098\u3100-\u3104\u312E-\u3130\u318F\u31BB-\u31BF\u31E4-\u31EF\u321F\u32FF\u4DB6-\u4DBF\u9FCD-\u9FFF\uA48D-\uA48F\uA4C7-\uA4CF\uA62C-\uA63F\uA698-\uA69E\uA6F8-\uA6FF\uA78F\uA794-\uA79F\uA7AB-\uA7F7\uA82C-\uA82F\uA83A-\uA83F\uA878-\uA87F\uA8C5-\uA8CD\uA8DA-\uA8DF\uA8FC-\uA8FF\uA954-\uA95E\uA97D-\uA97F\uA9CE\uA9DA-\uA9DD\uA9E0-\uA9FF\uAA37-\uAA3F\uAA4E\uAA4F\uAA5A\uAA5B\uAA7C-\uAA7F\uAAC3-\uAADA\uAAF7-\uAB00\uAB07\uAB08\uAB0F\uAB10\uAB17-\uAB1F\uAB27\uAB2F-\uABBF\uABEE\uABEF\uABFA-\uABFF\uD7A4-\uD7AF\uD7C7-\uD7CA\uD7FC-\uD7FF\uE000-\uF8FF\uFA6E\uFA6F\uFADA-\uFAFF\uFB07-\uFB12\uFB18-\uFB1C\uFB37\uFB3D\uFB3F\uFB42\uFB45\uFBC2-\uFBD2\uFD40-\uFD4F\uFD90\uFD91\uFDC8-\uFDEF\uFDFE\uFDFF\uFE1A-\uFE1F\uFE27-\uFE2F\uFE53\uFE67\uFE6C-\uFE6F\uFE75\uFEFD-\uFF00\uFFBF-\uFFC1\uFFC8\uFFC9\uFFD0\uFFD1\uFFD8\uFFD9\uFFDD-\uFFDF\uFFE7\uFFEF-\uFFFB\uFFFE\uFFFF]/g;
const wsRe = /[\x09-\x10\x0D\u2028\u2029]/g;
const wsRe = /[\x09-\x10\u2028\u2029]/g;
str = str.replace(re, ".");
if (!preserveWs) str = str.replace(wsRe, ".");
@ -192,6 +190,21 @@ class Utils {
}
/**
* Returns a string with whitespace represented as special characters from the
* Unicode Private Use Area, which CyberChef will display as control characters.
* Private Use Area characters are in the range U+E000..U+F8FF.
* https://en.wikipedia.org/wiki/Private_Use_Areas
* @param {string} str
* @returns {string}
*/
static escapeWhitespace(str) {
return str.replace(/[\x09-\x10]/g, function(c) {
return String.fromCharCode(0xe000 + c.charCodeAt(0));
});
}
/**
* Parse a string entered by a user and replace escaped chars with the bytes they represent.
*
@ -461,6 +474,9 @@ class Utils {
* Utils.strToArrayBuffer("你好");
*/
static strToArrayBuffer(str) {
log.debug(`Converting string[${str?.length}] to array buffer`);
if (!str) return new ArrayBuffer;
const arr = new Uint8Array(str.length);
let i = str.length, b;
while (i--) {
@ -487,17 +503,20 @@ class Utils {
* Utils.strToUtf8ArrayBuffer("你好");
*/
static strToUtf8ArrayBuffer(str) {
const utf8Str = utf8.encode(str);
log.debug(`Converting string[${str?.length}] to UTF8 array buffer`);
if (!str) return new ArrayBuffer;
if (str.length !== utf8Str.length) {
if (isWorkerEnvironment()) {
const buffer = new TextEncoder("utf-8").encode(str);
if (str.length !== buffer.length) {
if (isWorkerEnvironment() && self && typeof self.setOption === "function") {
self.setOption("attemptHighlight", false);
} else if (isWebEnvironment()) {
window.app.options.attemptHighlight = false;
}
}
return Utils.strToArrayBuffer(utf8Str);
return buffer.buffer;
}
@ -516,6 +535,8 @@ class Utils {
* Utils.strToByteArray("你好");
*/
static strToByteArray(str) {
log.debug(`Converting string[${str?.length}] to byte array`);
if (!str) return [];
const byteArray = new Array(str.length);
let i = str.length, b;
while (i--) {
@ -542,6 +563,8 @@ class Utils {
* Utils.strToUtf8ByteArray("你好");
*/
static strToUtf8ByteArray(str) {
log.debug(`Converting string[${str?.length}] to UTF8 byte array`);
if (!str) return [];
const utf8Str = utf8.encode(str);
if (str.length !== utf8Str.length) {
@ -570,6 +593,8 @@ class Utils {
* Utils.strToCharcode("你好");
*/
static strToCharcode(str) {
log.debug(`Converting string[${str?.length}] to charcode`);
if (!str) return [];
const charcode = [];
for (let i = 0; i < str.length; i++) {
@ -604,20 +629,26 @@ class Utils {
* Utils.byteArrayToUtf8([228,189,160,229,165,189]);
*/
static byteArrayToUtf8(byteArray) {
const str = Utils.byteArrayToChars(byteArray);
log.debug(`Converting byte array[${byteArray?.length}] to UTF8`);
if (!byteArray || !byteArray.length) return "";
if (!(byteArray instanceof Uint8Array))
byteArray = new Uint8Array(byteArray);
try {
const utf8Str = utf8.decode(str);
if (str.length !== utf8Str.length) {
const str = new TextDecoder("utf-8", {fatal: true}).decode(byteArray);
if (str.length !== byteArray.length) {
if (isWorkerEnvironment()) {
self.setOption("attemptHighlight", false);
} else if (isWebEnvironment()) {
window.app.options.attemptHighlight = false;
}
}
return utf8Str;
return str;
} catch (err) {
// If it fails, treat it as ANSI
return str;
return Utils.byteArrayToChars(byteArray);
}
}
@ -636,11 +667,13 @@ class Utils {
* Utils.byteArrayToChars([20320,22909]);
*/
static byteArrayToChars(byteArray) {
if (!byteArray) return "";
log.debug(`Converting byte array[${byteArray?.length}] to chars`);
if (!byteArray || !byteArray.length) return "";
let str = "";
// String concatenation appears to be faster than an array join
for (let i = 0; i < byteArray.length;) {
str += String.fromCharCode(byteArray[i++]);
// Maxiumum arg length for fromCharCode is 65535, but the stack may already be fairly deep,
// so don't get too near it.
for (let i = 0; i < byteArray.length; i += 20000) {
str += String.fromCharCode(...(byteArray.slice(i, i+20000)));
}
return str;
}
@ -658,6 +691,8 @@ class Utils {
* Utils.arrayBufferToStr(Uint8Array.from([104,101,108,108,111]).buffer);
*/
static arrayBufferToStr(arrayBuffer, utf8=true) {
log.debug(`Converting array buffer[${arrayBuffer?.byteLength}] to str`);
if (!arrayBuffer || !arrayBuffer.byteLength) return "";
const arr = new Uint8Array(arrayBuffer);
return utf8 ? Utils.byteArrayToUtf8(arr) : Utils.byteArrayToChars(arr);
}
@ -789,10 +824,10 @@ class Utils {
}
if (removeScriptAndStyle) {
htmlStr = recursiveRemove(/<script[^>]*>.*?<\/script[^>]*>/gi, htmlStr);
htmlStr = recursiveRemove(/<style[^>]*>.*?<\/style[^>]*>/gi, htmlStr);
htmlStr = recursiveRemove(/<script[^>]*>(\s|\S)*?<\/script[^>]*>/gi, htmlStr);
htmlStr = recursiveRemove(/<style[^>]*>(\s|\S)*?<\/style[^>]*>/gi, htmlStr);
}
return htmlStr.replace(/<[^>]+>/g, "");
return recursiveRemove(/<[^>]+>/g, htmlStr);
}
@ -800,6 +835,11 @@ class Utils {
* Escapes HTML tags in a string to stop them being rendered.
* https://www.owasp.org/index.php/XSS_(Cross_Site_Scripting)_Prevention_Cheat_Sheet
*
* Null bytes are a special case and are converted to a character from the Unicode
* Private Use Area, which CyberChef will display as a control character picture.
* This is done due to null bytes not being rendered or stored correctly in HTML
* DOM building.
*
* @param {string} str
* @returns string
*
@ -814,12 +854,13 @@ class Utils {
">": "&gt;",
'"': "&quot;",
"'": "&#x27;", // &apos; not recommended because it's not in the HTML spec
"`": "&#x60;"
"`": "&#x60;",
"\u0000": "\ue000"
};
return str.replace(/[&<>"'`]/g, function (match) {
return str ? str.replace(/[&<>"'`\u0000]/g, function (match) {
return HTML_CHARS[match];
});
}) : str;
}
@ -841,10 +882,11 @@ class Utils {
"&quot;": '"',
"&#x27;": "'",
"&#x2F;": "/",
"&#x60;": "`"
"&#x60;": "`",
"\ue000": "\u0000"
};
return str.replace(/&#?x?[a-z0-9]{2,4};/ig, function (match) {
return str.replace(/(&#?x?[a-z0-9]{2,4};|\ue000)/ig, function (match) {
return HTML_CHARS[match] || match;
});
}

View file

@ -121,6 +121,7 @@
"Substitute",
"Derive PBKDF2 key",
"Derive EVP key",
"Derive HKDF key",
"Bcrypt",
"Scrypt",
"JWT Sign",
@ -247,6 +248,7 @@
"Remove null bytes",
"To Upper case",
"To Lower case",
"Swap case",
"To Case Insensitive Regex",
"From Case Insensitive Regex",
"Add line numbers",
@ -271,6 +273,7 @@
"Fuzzy Match",
"Offset checker",
"Hamming Distance",
"Levenshtein Distance",
"Convert distance",
"Convert area",
"Convert mass",

View file

@ -24,12 +24,11 @@ class DishBigNumber extends DishType {
/**
* convert the given value from a ArrayBuffer
* @param {boolean} notUTF8
*/
static fromArrayBuffer(notUTF8) {
static fromArrayBuffer() {
DishBigNumber.checkForValue(this.value);
try {
this.value = new BigNumber(Utils.arrayBufferToStr(this.value, !notUTF8));
this.value = new BigNumber(Utils.arrayBufferToStr(this.value));
} catch (err) {
this.value = new BigNumber(NaN);
}

View file

@ -22,11 +22,10 @@ class DishJSON extends DishType {
/**
* convert the given value from a ArrayBuffer
* @param {boolean} notUTF8
*/
static fromArrayBuffer(notUTF8) {
static fromArrayBuffer() {
DishJSON.checkForValue(this.value);
this.value = JSON.parse(Utils.arrayBufferToStr(this.value, !notUTF8));
this.value = JSON.parse(Utils.arrayBufferToStr(this.value));
}
}

View file

@ -23,11 +23,10 @@ class DishNumber extends DishType {
/**
* convert the given value from a ArrayBuffer
* @param {boolean} notUTF8
*/
static fromArrayBuffer(notUTF8) {
static fromArrayBuffer() {
DishNumber.checkForValue(this.value);
this.value = this.value ? parseFloat(Utils.arrayBufferToStr(this.value, !notUTF8)) : 0;
this.value = this.value ? parseFloat(Utils.arrayBufferToStr(this.value)) : 0;
}
}

View file

@ -23,11 +23,10 @@ class DishString extends DishType {
/**
* convert the given value from a ArrayBuffer
* @param {boolean} notUTF8
*/
static fromArrayBuffer(notUTF8) {
static fromArrayBuffer() {
DishString.checkForValue(this.value);
this.value = this.value ? Utils.arrayBufferToStr(this.value, !notUTF8) : "";
this.value = this.value ? Utils.arrayBufferToStr(this.value) : "";
}
}

View file

@ -29,9 +29,8 @@ class DishType {
/**
* convert the given value from a ArrayBuffer
* @param {boolean} notUTF8
*/
static fromArrayBuffer(notUTF8=undefined) {
static fromArrayBuffer() {
throw new Error("fromArrayBuffer has not been implemented");
}
}

View file

@ -25,12 +25,12 @@ import OperationError from "../errors/OperationError.mjs";
*/
export function toBase64(data, alphabet="A-Za-z0-9+/=") {
if (!data) return "";
if (typeof data == "string") {
data = Utils.strToArrayBuffer(data);
}
if (data instanceof ArrayBuffer) {
data = new Uint8Array(data);
}
if (typeof data == "string") {
data = Utils.strToByteArray(data);
}
alphabet = Utils.expandAlphRange(alphabet).join("");
if (alphabet.length !== 64 && alphabet.length !== 65) { // Allow for padding

View file

@ -6,10 +6,12 @@
* @license Apache-2.0
*/
import cptable from "codepage";
/**
* Character encoding format mappings.
*/
export const IO_FORMAT = {
export const CHR_ENC_CODE_PAGES = {
"UTF-8 (65001)": 65001,
"UTF-7 (65000)": 65000,
"UTF-16LE (1200)": 1200,
@ -164,6 +166,57 @@ export const IO_FORMAT = {
"Simplified Chinese GB18030 (54936)": 54936,
};
export const CHR_ENC_SIMPLE_LOOKUP = {};
export const CHR_ENC_SIMPLE_REVERSE_LOOKUP = {};
for (const name in CHR_ENC_CODE_PAGES) {
const simpleName = name.match(/(^.+)\([\d/]+\)$/)[1];
CHR_ENC_SIMPLE_LOOKUP[simpleName] = CHR_ENC_CODE_PAGES[name];
CHR_ENC_SIMPLE_REVERSE_LOOKUP[CHR_ENC_CODE_PAGES[name]] = simpleName;
}
/**
* Returns the width of the character set for the given codepage.
* For example, UTF-8 is a Single Byte Character Set, whereas
* UTF-16 is a Double Byte Character Set.
*
* @param {number} page - The codepage number
* @returns {number}
*/
export function chrEncWidth(page) {
if (typeof page !== "number") return 0;
// Raw Bytes have a width of 1
if (page === 0) return 1;
const pageStr = page.toString();
// Confirm this page is legitimate
if (!Object.prototype.hasOwnProperty.call(CHR_ENC_SIMPLE_REVERSE_LOOKUP, pageStr))
return 0;
// Statically defined code pages
if (Object.prototype.hasOwnProperty.call(cptable, pageStr))
return cptable[pageStr].dec.length > 256 ? 2 : 1;
// Cached code pages
if (cptable.utils.cache.sbcs.includes(pageStr))
return 1;
if (cptable.utils.cache.dbcs.includes(pageStr))
return 2;
// Dynamically generated code pages
if (Object.prototype.hasOwnProperty.call(cptable.utils.magic, pageStr)) {
// Generate a single character and measure it
const a = cptable.utils.encode(page, "a");
return a.length;
}
return 0;
}
/**
* Unicode Normalisation Forms
*

View file

@ -10,8 +10,7 @@ import OperationError from "../errors/OperationError.mjs";
import jsQR from "jsqr";
import qr from "qr-image";
import Utils from "../Utils.mjs";
import jimplib from "jimp/es/index.js";
const jimp = jimplib.default ? jimplib.default : jimplib;
import jimp from "jimp";
/**
* Parses a QR code image from an image

View file

@ -9,8 +9,7 @@ import OperationError from "../errors/OperationError.mjs";
import { isImage } from "../lib/FileType.mjs";
import { toBase64 } from "../lib/Base64.mjs";
import { isWorkerEnvironment } from "../Utils.mjs";
import jimplib from "jimp/es/index.js";
const jimp = jimplib.default ? jimplib.default : jimplib;
import jimp from "jimp";
/**
* Add Text To Image operation

View file

@ -10,8 +10,7 @@ import { isWorkerEnvironment } from "../Utils.mjs";
import { isImage } from "../lib/FileType.mjs";
import { toBase64 } from "../lib/Base64.mjs";
import { gaussianBlur } from "../lib/ImageManipulation.mjs";
import jimplib from "jimp/es/index.js";
const jimp = jimplib.default ? jimplib.default : jimplib;
import jimp from "jimp";
/**
* Blur Image operation

View file

@ -9,8 +9,7 @@ import OperationError from "../errors/OperationError.mjs";
import { isImage } from "../lib/FileType.mjs";
import { toBase64 } from "../lib/Base64.mjs";
import { isWorkerEnvironment } from "../Utils.mjs";
import jimplib from "jimp/es/index.js";
const jimp = jimplib.default ? jimplib.default : jimplib;
import jimp from "jimp";
/**
* Contain Image operation

View file

@ -8,8 +8,7 @@ import Operation from "../Operation.mjs";
import OperationError from "../errors/OperationError.mjs";
import { isImage } from "../lib/FileType.mjs";
import { toBase64 } from "../lib/Base64.mjs";
import jimplib from "jimp/es/index.js";
const jimp = jimplib.default ? jimplib.default : jimplib;
import jimp from "jimp";
/**
* Convert Image Format operation

View file

@ -9,8 +9,7 @@ import OperationError from "../errors/OperationError.mjs";
import { isImage } from "../lib/FileType.mjs";
import { toBase64 } from "../lib/Base64.mjs";
import { isWorkerEnvironment } from "../Utils.mjs";
import jimplib from "jimp/es/index.js";
const jimp = jimplib.default ? jimplib.default : jimplib;
import jimp from "jimp";
/**
* Cover Image operation

View file

@ -9,8 +9,7 @@ import OperationError from "../errors/OperationError.mjs";
import { isImage } from "../lib/FileType.mjs";
import { toBase64 } from "../lib/Base64.mjs";
import { isWorkerEnvironment } from "../Utils.mjs";
import jimplib from "jimp/es/index.js";
const jimp = jimplib.default ? jimplib.default : jimplib;
import jimp from "jimp";
/**
* Crop Image operation

View file

@ -6,7 +6,7 @@
import Operation from "../Operation.mjs";
import cptable from "codepage";
import {IO_FORMAT} from "../lib/ChrEnc.mjs";
import {CHR_ENC_CODE_PAGES} from "../lib/ChrEnc.mjs";
/**
* Decode text operation
@ -26,7 +26,7 @@ class DecodeText extends Operation {
"<br><br>",
"Supported charsets are:",
"<ul>",
Object.keys(IO_FORMAT).map(e => `<li>${e}</li>`).join("\n"),
Object.keys(CHR_ENC_CODE_PAGES).map(e => `<li>${e}</li>`).join("\n"),
"</ul>",
].join("\n");
this.infoURL = "https://wikipedia.org/wiki/Character_encoding";
@ -36,7 +36,7 @@ class DecodeText extends Operation {
{
"name": "Encoding",
"type": "option",
"value": Object.keys(IO_FORMAT)
"value": Object.keys(CHR_ENC_CODE_PAGES)
}
];
}
@ -47,7 +47,7 @@ class DecodeText extends Operation {
* @returns {string}
*/
run(input, args) {
const format = IO_FORMAT[args[0]];
const format = CHR_ENC_CODE_PAGES[args[0]];
return cptable.utils.decode(format, new Uint8Array(input));
}

View file

@ -0,0 +1,138 @@
/**
* @author mikecat
* @copyright Crown Copyright 2023
* @license Apache-2.0
*/
import Operation from "../Operation.mjs";
import Utils from "../Utils.mjs";
import OperationError from "../errors/OperationError.mjs";
import CryptoApi from "crypto-api/src/crypto-api.mjs";
/**
* Derive HKDF Key operation
*/
class DeriveHKDFKey extends Operation {
/**
* DeriveHKDFKey constructor
*/
constructor() {
super();
this.name = "Derive HKDF key";
this.module = "Crypto";
this.description = "A simple Hashed Message Authenticaton Code (HMAC)-based key derivation function (HKDF), defined in RFC5869.";
this.infoURL = "https://wikipedia.org/wiki/HKDF";
this.inputType = "ArrayBuffer";
this.outputType = "string";
this.args = [
{
"name": "Salt",
"type": "toggleString",
"value": "",
"toggleValues": ["Hex", "Decimal", "Base64", "UTF8", "Latin1"]
},
{
"name": "Info",
"type": "toggleString",
"value": "",
"toggleValues": ["Hex", "Decimal", "Base64", "UTF8", "Latin1"]
},
{
"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"
],
"defaultIndex": 6
},
{
"name": "Extract mode",
"type": "argSelector",
"value": [
{
"name": "with salt",
"on": [0]
},
{
"name": "no salt",
"off": [0]
},
{
"name": "skip",
"off": [0]
}
]
},
{
"name": "L (number of output octets)",
"type": "number",
"value": 16,
"min": 0
},
];
}
/**
* @param {ArrayBuffer} input
* @param {Object[]} args
* @returns {ArrayBuffer}
*/
run(input, args) {
const argSalt = Utils.convertToByteString(args[0].string || "", args[0].option),
info = Utils.convertToByteString(args[1].string || "", args[1].option),
hashFunc = args[2].toLowerCase(),
extractMode = args[3],
L = args[4],
IKM = Utils.arrayBufferToStr(input, false),
hasher = CryptoApi.getHasher(hashFunc),
HashLen = hasher.finalize().length;
if (L < 0) {
throw new OperationError("L must be non-negative");
}
if (L > 255 * HashLen) {
throw new OperationError("L too large (maximum length for " + args[2] + " is " + (255 * HashLen) + ")");
}
const hmacHash = function(key, data) {
hasher.reset();
const mac = CryptoApi.getHmac(key, hasher);
mac.update(data);
return mac.finalize();
};
const salt = extractMode === "with salt" ? argSalt : "\0".repeat(HashLen);
const PRK = extractMode === "skip" ? IKM : hmacHash(salt, IKM);
let T = "";
let result = "";
for (let i = 1; i <= 255 && result.length < L; i++) {
const TNext = hmacHash(PRK, T + info + String.fromCharCode(i));
result += TNext;
T = TNext;
}
return CryptoApi.encoder.toHex(result.substring(0, L));
}
}
export default DeriveHKDFKey;

View file

@ -65,7 +65,7 @@ class DetectFileType extends Operation {
Extension: ${type.extension}
MIME type: ${type.mime}\n`;
if (type.description && type.description.length) {
if (type?.description?.length) {
output += `Description: ${type.description}\n`;
}

View file

@ -9,8 +9,7 @@ import OperationError from "../errors/OperationError.mjs";
import { isImage } from "../lib/FileType.mjs";
import { toBase64 } from "../lib/Base64.mjs";
import { isWorkerEnvironment } from "../Utils.mjs";
import jimplib from "jimp/es/index.js";
const jimp = jimplib.default ? jimplib.default : jimplib;
import jimp from "jimp";
/**
* Image Dither operation

View file

@ -6,7 +6,7 @@
import Operation from "../Operation.mjs";
import cptable from "codepage";
import {IO_FORMAT} from "../lib/ChrEnc.mjs";
import {CHR_ENC_CODE_PAGES} from "../lib/ChrEnc.mjs";
/**
* Encode text operation
@ -26,7 +26,7 @@ class EncodeText extends Operation {
"<br><br>",
"Supported charsets are:",
"<ul>",
Object.keys(IO_FORMAT).map(e => `<li>${e}</li>`).join("\n"),
Object.keys(CHR_ENC_CODE_PAGES).map(e => `<li>${e}</li>`).join("\n"),
"</ul>",
].join("\n");
this.infoURL = "https://wikipedia.org/wiki/Character_encoding";
@ -36,7 +36,7 @@ class EncodeText extends Operation {
{
"name": "Encoding",
"type": "option",
"value": Object.keys(IO_FORMAT)
"value": Object.keys(CHR_ENC_CODE_PAGES)
}
];
}
@ -47,7 +47,7 @@ class EncodeText extends Operation {
* @returns {ArrayBuffer}
*/
run(input, args) {
const format = IO_FORMAT[args[0]];
const format = CHR_ENC_CODE_PAGES[args[0]];
const encoded = cptable.utils.encode(format, input);
return new Uint8Array(encoded).buffer;
}

View file

@ -358,7 +358,7 @@ class Entropy extends Operation {
<br><script>
var canvas = document.getElementById("chart-area"),
parentRect = canvas.parentNode.getBoundingClientRect(),
parentRect = canvas.closest(".cm-scroller").getBoundingClientRect(),
entropy = ${entropy},
height = parentRect.height * 0.25;

View file

@ -9,8 +9,7 @@ import OperationError from "../errors/OperationError.mjs";
import Utils from "../Utils.mjs";
import { fromBinary } from "../lib/Binary.mjs";
import { isImage } from "../lib/FileType.mjs";
import jimplib from "jimp/es/index.js";
const jimp = jimplib.default ? jimplib.default : jimplib;
import jimp from "jimp";
/**
* Extract LSB operation

View file

@ -7,8 +7,7 @@
import Operation from "../Operation.mjs";
import OperationError from "../errors/OperationError.mjs";
import { isImage } from "../lib/FileType.mjs";
import jimplib from "jimp/es/index.js";
const jimp = jimplib.default ? jimplib.default : jimplib;
import jimp from "jimp";
import {RGBA_DELIM_OPTIONS} from "../lib/Delim.mjs";

View file

@ -9,8 +9,7 @@ import OperationError from "../errors/OperationError.mjs";
import { isImage } from "../lib/FileType.mjs";
import { toBase64 } from "../lib/Base64.mjs";
import { isWorkerEnvironment } from "../Utils.mjs";
import jimplib from "jimp/es/index.js";
const jimp = jimplib.default ? jimplib.default : jimplib;
import jimp from "jimp";
/**
* Flip Image operation

View file

@ -91,7 +91,7 @@ Number of bytes not represented: ${256 - freq.bytesRepresented}
<script>
var canvas = document.getElementById("chart-area"),
parentRect = canvas.parentNode.getBoundingClientRect(),
parentRect = canvas.closest(".cm-scroller").getBoundingClientRect(),
scores = ${JSON.stringify(freq.percentages)};
canvas.width = parentRect.width * 0.95;

View file

@ -84,7 +84,7 @@ class FromBCD extends Operation {
break;
case "Raw":
default:
byteArray = Utils.strToByteArray(input);
byteArray = new Uint8Array(Utils.strToArrayBuffer(input));
byteArray.forEach(b => {
nibbles.push(b >>> 4);
nibbles.push(b & 15);

View file

@ -26,7 +26,7 @@ class FromCharcode extends Operation {
this.description = "Converts unicode character codes back into text.<br><br>e.g. <code>0393 03b5 03b9 03ac 20 03c3 03bf 03c5</code> becomes <code>Γειά σου</code>";
this.infoURL = "https://wikipedia.org/wiki/Plane_(Unicode)";
this.inputType = "string";
this.outputType = "byteArray";
this.outputType = "ArrayBuffer";
this.args = [
{
"name": "Delimiter",
@ -44,7 +44,7 @@ class FromCharcode extends Operation {
/**
* @param {string} input
* @param {Object[]} args
* @returns {byteArray}
* @returns {ArrayBuffer}
*
* @throws {OperationError} if base out of range
*/
@ -59,7 +59,7 @@ class FromCharcode extends Operation {
}
if (input.length === 0) {
return [];
return new ArrayBuffer;
}
if (base !== 16 && isWorkerEnvironment()) self.setOption("attemptHighlight", false);
@ -77,7 +77,7 @@ class FromCharcode extends Operation {
for (i = 0; i < bites.length; i++) {
latin1 += Utils.chr(parseInt(bites[i], base));
}
return Utils.strToByteArray(latin1);
return Utils.strToArrayBuffer(latin1);
}
}

View file

@ -10,8 +10,7 @@ import Utils from "../Utils.mjs";
import {isImage} from "../lib/FileType.mjs";
import {toBase64} from "../lib/Base64.mjs";
import {isWorkerEnvironment} from "../Utils.mjs";
import jimplib from "jimp/es/index.js";
const jimp = jimplib.default ? jimplib.default : jimplib;
import jimp from "jimp";
/**
* Generate Image operation

View file

@ -68,8 +68,8 @@ class HammingDistance extends Operation {
samples[0] = fromHex(samples[0]);
samples[1] = fromHex(samples[1]);
} else {
samples[0] = Utils.strToByteArray(samples[0]);
samples[1] = Utils.strToByteArray(samples[1]);
samples[0] = new Uint8Array(Utils.strToArrayBuffer(samples[0]));
samples[1] = new Uint8Array(Utils.strToArrayBuffer(samples[1]));
}
let dist = 0;

View file

@ -9,8 +9,7 @@ import OperationError from "../errors/OperationError.mjs";
import { isImage } from "../lib/FileType.mjs";
import { toBase64 } from "../lib/Base64.mjs";
import { isWorkerEnvironment } from "../Utils.mjs";
import jimplib from "jimp/es/index.js";
const jimp = jimplib.default ? jimplib.default : jimplib;
import jimp from "jimp";
/**
* Image Brightness / Contrast operation

View file

@ -9,8 +9,7 @@ import OperationError from "../errors/OperationError.mjs";
import { isImage } from "../lib/FileType.mjs";
import { toBase64 } from "../lib/Base64.mjs";
import { isWorkerEnvironment } from "../Utils.mjs";
import jimplib from "jimp/es/index.js";
const jimp = jimplib.default ? jimplib.default : jimplib;
import jimp from "jimp";
/**
* Image Filter operation

View file

@ -9,8 +9,7 @@ import OperationError from "../errors/OperationError.mjs";
import { isImage } from "../lib/FileType.mjs";
import { toBase64 } from "../lib/Base64.mjs";
import { isWorkerEnvironment } from "../Utils.mjs";
import jimplib from "jimp/es/index.js";
const jimp = jimplib.default ? jimplib.default : jimplib;
import jimp from "jimp";
/**
* Image Hue/Saturation/Lightness operation

View file

@ -9,8 +9,7 @@ import OperationError from "../errors/OperationError.mjs";
import { isImage } from "../lib/FileType.mjs";
import { toBase64 } from "../lib/Base64.mjs";
import { isWorkerEnvironment } from "../Utils.mjs";
import jimplib from "jimp/es/index.js";
const jimp = jimplib.default ? jimplib.default : jimplib;
import jimp from "jimp";
/**
* Image Opacity operation

View file

@ -78,7 +78,7 @@ The graph shows the IC of the input data. A low IC generally means that the text
<script type='application/javascript'>
var canvas = document.getElementById("chart-area"),
parentRect = canvas.parentNode.getBoundingClientRect(),
parentRect = canvas.closest(".cm-scroller").getBoundingClientRect(),
ic = ${ic};
canvas.width = parentRect.width * 0.95;

View file

@ -9,8 +9,7 @@ import OperationError from "../errors/OperationError.mjs";
import { isImage } from "../lib/FileType.mjs";
import { toBase64 } from "../lib/Base64.mjs";
import { isWorkerEnvironment } from "../Utils.mjs";
import jimplib from "jimp/es/index.js";
const jimp = jimplib.default ? jimplib.default : jimplib;
import jimp from "jimp";
/**
* Invert Image operation

View file

@ -0,0 +1,98 @@
/**
* @author mikecat
* @copyright Crown Copyright 2023
* @license Apache-2.0
*/
import Operation from "../Operation.mjs";
import OperationError from "../errors/OperationError.mjs";
/**
* Levenshtein Distance operation
*/
class LevenshteinDistance extends Operation {
/**
* LevenshteinDistance constructor
*/
constructor() {
super();
this.name = "Levenshtein Distance";
this.module = "Default";
this.description = "Levenshtein Distance (also known as Edit Distance) is a string metric to measure a difference between two strings that counts operations (insertions, deletions, and substitutions) on single character that are required to change one string to another.";
this.infoURL = "https://wikipedia.org/wiki/Levenshtein_distance";
this.inputType = "string";
this.outputType = "number";
this.args = [
{
name: "Sample delimiter",
type: "binaryString",
value: "\\n"
},
{
name: "Insertion cost",
type: "number",
value: 1
},
{
name: "Deletion cost",
type: "number",
value: 1
},
{
name: "Substitution cost",
type: "number",
value: 1
},
];
}
/**
* @param {string} input
* @param {Object[]} args
* @returns {number}
*/
run(input, args) {
const [delim, insCost, delCost, subCost] = args;
const samples = input.split(delim);
if (samples.length !== 2) {
throw new OperationError("Incorrect number of samples. Check your input and/or delimiter.");
}
if (insCost < 0 || delCost < 0 || subCost < 0) {
throw new OperationError("Negative costs are not allowed.");
}
const src = samples[0], dest = samples[1];
let currentCost = new Array(src.length + 1);
let nextCost = new Array(src.length + 1);
for (let i = 0; i < currentCost.length; i++) {
currentCost[i] = delCost * i;
}
for (let i = 0; i < dest.length; i++) {
const destc = dest.charAt(i);
nextCost[0] = currentCost[0] + insCost;
for (let j = 0; j < src.length; j++) {
let candidate;
// insertion
let optCost = currentCost[j + 1] + insCost;
// deletion
candidate = nextCost[j] + delCost;
if (candidate < optCost) optCost = candidate;
// substitution or matched character
candidate = currentCost[j];
if (src.charAt(j) !== destc) candidate += subCost;
if (candidate < optCost) optCost = candidate;
// store calculated cost
nextCost[j + 1] = optCost;
}
const tempCost = nextCost;
nextCost = currentCost;
currentCost = tempCost;
}
return currentCost[currentCost.length - 1];
}
}
export default LevenshteinDistance;

View file

@ -149,7 +149,7 @@ class Magic extends Operation {
output += `<tr>
<td><a href="#${recipeURL}">${Utils.generatePrettyRecipe(option.recipe, true)}</a></td>
<td>${Utils.escapeHtml(Utils.printable(Utils.truncate(option.data, 99)))}</td>
<td>${Utils.escapeHtml(Utils.escapeWhitespace(Utils.truncate(option.data, 99)))}</td>
<td>${language}${fileType}${matchingOps}${useful}${validUTF8}${entropy}</td>
</tr>`;
});

View file

@ -5,8 +5,6 @@
*/
import Operation from "../Operation.mjs";
import cptable from "codepage";
import {runHash} from "../lib/Hash.mjs";
/**
@ -35,10 +33,14 @@ class NTHash extends Operation {
* @returns {string}
*/
run(input, args) {
const format = 1200; // UTF-16LE
const encoded = cptable.utils.encode(format, input);
const hashed = runHash("md4", encoded);
// Convert to UTF-16LE
const buf = new ArrayBuffer(input.length * 2);
const bufView = new Uint16Array(buf);
for (let i = 0; i < input.length; i++) {
bufView[i] = input.charCodeAt(i);
}
const hashed = runHash("md4", buf);
return hashed.toUpperCase();
}
}

View file

@ -8,8 +8,7 @@ import Operation from "../Operation.mjs";
import OperationError from "../errors/OperationError.mjs";
import { isImage } from "../lib/FileType.mjs";
import { toBase64 } from "../lib/Base64.mjs";
import jimplib from "jimp/es/index.js";
const jimp = jimplib.default ? jimplib.default : jimplib;
import jimp from "jimp";
/**
* Normalise Image operation

View file

@ -48,7 +48,7 @@ class PlistViewer extends Operation {
.replace(/<true\/>/g, m => "true")
.replace(/<\/plist>/g, "/plist")
.replace(/<date>.+<\/date>/g, m => `${m.slice(6, m.indexOf(/<\/integer>/g)-6)}`)
.replace(/<data>(\s|.)+?<\/data>/g, m => `${m.slice(6, m.indexOf(/<\/data>/g)-6)}`)
.replace(/<data>[\s\S]+?<\/data>/g, m => `${m.slice(6, m.indexOf(/<\/data>/g)-6)}`)
.replace(/[ \t\r\f\v]/g, "");
/**

View file

@ -112,8 +112,8 @@ CMYK: ${cmyk}
useAlpha: true
}).on('colorpickerChange', function(e) {
var color = e.color.string('rgba');
document.getElementById('input-text').value = color;
window.app.manager.input.debounceInputChange(new Event("keyup"));
window.app.manager.input.setInput(color);
window.app.manager.input.inputChange(new Event("keyup"));
});
</script>`;
}

View file

@ -49,7 +49,7 @@ class ParseIPv4Header extends Operation {
if (format === "Hex") {
input = fromHex(input);
} else if (format === "Raw") {
input = Utils.strToByteArray(input);
input = new Uint8Array(Utils.strToArrayBuffer(input));
} else {
throw new OperationError("Unrecognised input format.");
}

View file

@ -71,7 +71,7 @@ class ParseX509Certificate extends Operation {
cert.readCertHex(toHex(fromBase64(input, null, "byteArray"), ""));
break;
case "Raw":
cert.readCertHex(toHex(Utils.strToByteArray(input), ""));
cert.readCertHex(toHex(Utils.strToArrayBuffer(input), ""));
break;
default:
undefinedInputFormat = true;

View file

@ -77,7 +77,7 @@ class PlayMedia extends Operation {
* Displays an audio or video element that may be able to play the media
* file.
*
* @param data {byteArray} Data containing an audio or video file.
* @param {byteArray} data Data containing an audio or video file.
* @returns {string} Markup to display a media player.
*/
async present(data) {

View file

@ -86,12 +86,12 @@ class ROT13BruteForce extends Operation {
}
const rotatedString = Utils.byteArrayToUtf8(rotated);
if (rotatedString.toLowerCase().indexOf(cribLower) >= 0) {
const rotatedStringPrintable = Utils.printable(rotatedString, false);
const rotatedStringEscaped = Utils.escapeWhitespace(rotatedString);
if (printAmount) {
const amountStr = "Amount = " + (" " + amount).slice(-2) + ": ";
result.push(amountStr + rotatedStringPrintable);
result.push(amountStr + rotatedStringEscaped);
} else {
result.push(rotatedStringPrintable);
result.push(rotatedStringEscaped);
}
}
}

View file

@ -66,12 +66,12 @@ class ROT47BruteForce extends Operation {
}
const rotatedString = Utils.byteArrayToUtf8(rotated);
if (rotatedString.toLowerCase().indexOf(cribLower) >= 0) {
const rotatedStringPrintable = Utils.printable(rotatedString, false);
const rotatedStringEscaped = Utils.escapeWhitespace(rotatedString);
if (printAmount) {
const amountStr = "Amount = " + (" " + amount).slice(-2) + ": ";
result.push(amountStr + rotatedStringPrintable);
result.push(amountStr + rotatedStringEscaped);
} else {
result.push(rotatedStringPrintable);
result.push(rotatedStringEscaped);
}
}
}

View file

@ -10,8 +10,7 @@ import Utils from "../Utils.mjs";
import { isImage } from "../lib/FileType.mjs";
import { runHash } from "../lib/Hash.mjs";
import { toBase64 } from "../lib/Base64.mjs";
import jimplib from "jimp/es/index.js";
const jimp = jimplib.default ? jimplib.default : jimplib;
import jimp from "jimp";
/**
* Randomize Colour Palette operation

View file

@ -9,8 +9,7 @@ import OperationError from "../errors/OperationError.mjs";
import { isImage } from "../lib/FileType.mjs";
import { toBase64 } from "../lib/Base64.mjs";
import { isWorkerEnvironment } from "../Utils.mjs";
import jimplib from "jimp/es/index.js";
const jimp = jimplib.default ? jimplib.default : jimplib;
import jimp from "jimp";
/**
* Resize Image operation

View file

@ -9,8 +9,7 @@ import OperationError from "../errors/OperationError.mjs";
import { isImage } from "../lib/FileType.mjs";
import { toBase64 } from "../lib/Base64.mjs";
import { isWorkerEnvironment } from "../Utils.mjs";
import jimplib from "jimp/es/index.js";
const jimp = jimplib.default ? jimplib.default : jimplib;
import jimp from "jimp";
/**
* Rotate Image operation

View file

@ -60,7 +60,7 @@ class ScanForEmbeddedFiles extends Operation {
Extension: ${type.fileDetails.extension}
MIME type: ${type.fileDetails.mime}\n`;
if (type.fileDetails.description && type.fileDetails.description.length) {
if (type?.fileDetails?.description?.length) {
output += ` Description: ${type.fileDetails.description}\n`;
}
});

View file

@ -10,8 +10,7 @@ import { isImage } from "../lib/FileType.mjs";
import { toBase64 } from "../lib/Base64.mjs";
import { gaussianBlur } from "../lib/ImageManipulation.mjs";
import { isWorkerEnvironment } from "../Utils.mjs";
import jimplib from "jimp/es/index.js";
const jimp = jimplib.default ? jimplib.default : jimplib;
import jimp from "jimp";
/**
* Sharpen Image operation

View file

@ -90,7 +90,14 @@ class ShowOnMap extends Operation {
leafletUrl = "https://unpkg.com/leaflet@1.5.0/dist/leaflet.js",
leafletCssUrl = "https://unpkg.com/leaflet@1.5.0/dist/leaflet.css";
return `<link rel="stylesheet" href="${leafletCssUrl}" crossorigin=""/>
<style>#output-html { white-space: normal; padding: 0; }</style>
<style>
#output-text .cm-content,
#output-text .cm-line,
#output-html {
padding: 0;
white-space: normal;
}
</style>
<div id="presentedMap" style="width: 100%; height: 100%;"></div>
<script type="text/javascript">
var mapscript = document.createElement('script');

View file

@ -8,8 +8,7 @@ import Operation from "../Operation.mjs";
import OperationError from "../errors/OperationError.mjs";
import Utils from "../Utils.mjs";
import {isImage} from "../lib/FileType.mjs";
import jimplib from "jimp/es/index.js";
const jimp = jimplib.default ? jimplib.default : jimplib;
import jimp from "jimp";
/**
* Split Colour Channels operation

View file

@ -0,0 +1,76 @@
/**
* @author mikecat
* @copyright Crown Copyright 2023
* @license Apache-2.0
*/
import Operation from "../Operation.mjs";
/**
* Swap case operation
*/
class SwapCase extends Operation {
/**
* SwapCase constructor
*/
constructor() {
super();
this.name = "Swap case";
this.module = "Default";
this.description = "Converts uppercase letters to lowercase ones, and lowercase ones to uppercase ones.";
this.infoURL = "";
this.inputType = "string";
this.outputType = "string";
this.args = [];
}
/**
* @param {string} input
* @param {Object[]} args
* @returns {string}
*/
run(input, args) {
let result = "";
for (let i = 0; i < input.length; i++) {
const c = input.charAt(i);
const upper = c.toUpperCase();
if (c === upper) {
result += c.toLowerCase();
} else {
result += upper;
}
}
return result;
}
/**
* Highlight Swap case
*
* @param {Object[]} pos
* @param {number} pos[].start
* @param {number} pos[].end
* @param {Object[]} args
* @returns {Object[]} pos
*/
highlight(pos, args) {
return pos;
}
/**
* Highlight Swap case in reverse
*
* @param {Object[]} pos
* @param {number} pos[].start
* @param {number} pos[].end
* @param {Object[]} args
* @returns {Object[]} pos
*/
highlightReverse(pos, args) {
return pos;
}
}
export default SwapCase;

View file

@ -8,7 +8,7 @@
import Operation from "../Operation.mjs";
import Utils from "../Utils.mjs";
import cptable from "codepage";
import {IO_FORMAT} from "../lib/ChrEnc.mjs";
import {CHR_ENC_CODE_PAGES} from "../lib/ChrEnc.mjs";
/**
* Text Encoding Brute Force operation
@ -28,7 +28,7 @@ class TextEncodingBruteForce extends Operation {
"<br><br>",
"Supported charsets are:",
"<ul>",
Object.keys(IO_FORMAT).map(e => `<li>${e}</li>`).join("\n"),
Object.keys(CHR_ENC_CODE_PAGES).map(e => `<li>${e}</li>`).join("\n"),
"</ul>"
].join("\n");
this.infoURL = "https://wikipedia.org/wiki/Character_encoding";
@ -51,15 +51,15 @@ class TextEncodingBruteForce extends Operation {
*/
run(input, args) {
const output = {},
charsets = Object.keys(IO_FORMAT),
charsets = Object.keys(CHR_ENC_CODE_PAGES),
mode = args[0];
charsets.forEach(charset => {
try {
if (mode === "Decode") {
output[charset] = cptable.utils.decode(IO_FORMAT[charset], input);
output[charset] = cptable.utils.decode(CHR_ENC_CODE_PAGES[charset], input);
} else {
output[charset] = Utils.arrayBufferToStr(cptable.utils.encode(IO_FORMAT[charset], input));
output[charset] = Utils.arrayBufferToStr(cptable.utils.encode(CHR_ENC_CODE_PAGES[charset], input));
}
} catch (err) {
output[charset] = "Could not decode.";
@ -79,7 +79,7 @@ class TextEncodingBruteForce extends Operation {
let table = "<table class='table table-hover table-sm table-bordered table-nonfluid'><tr><th>Encoding</th><th>Value</th></tr>";
for (const enc in encodings) {
const value = Utils.escapeHtml(Utils.printable(encodings[enc], true));
const value = Utils.escapeHtml(Utils.escapeWhitespace(encodings[enc]));
table += `<tr><td>${enc}</td><td>${value}</td></tr>`;
}

View file

@ -76,7 +76,7 @@ class ToHex extends Operation {
}
const lineSize = args[1],
len = (delim === "\r\n" ? 1 : delim.length) + commaLen;
len = delim.length + commaLen;
const countLF = function(p) {
// Count the number of LFs from 0 upto p
@ -105,7 +105,7 @@ class ToHex extends Operation {
* @returns {Object[]} pos
*/
highlightReverse(pos, args) {
let delim, commaLen;
let delim, commaLen = 0;
if (args[0] === "0x with comma") {
delim = "0x";
commaLen = 1;
@ -114,7 +114,7 @@ class ToHex extends Operation {
}
const lineSize = args[1],
len = (delim === "\r\n" ? 1 : delim.length) + commaLen,
len = delim.length + commaLen,
width = len + 2;
const countLF = function(p) {

View file

@ -63,33 +63,32 @@ class ToHexdump extends Operation {
if (length < 1 || Math.round(length) !== length)
throw new OperationError("Width must be a positive integer");
let output = "";
const lines = [];
for (let i = 0; i < data.length; i += length) {
const buff = data.slice(i, i+length);
let hexa = "";
for (let j = 0; j < buff.length; j++) {
hexa += Utils.hex(buff[j], padding) + " ";
}
let lineNo = Utils.hex(i, 8);
const buff = data.slice(i, i+length);
const hex = [];
buff.forEach(b => hex.push(Utils.hex(b, padding)));
let hexStr = hex.join(" ").padEnd(length*(padding+1), " ");
const ascii = Utils.printable(Utils.byteArrayToChars(buff), false, unixFormat);
const asciiStr = ascii.padEnd(buff.length, " ");
if (upperCase) {
hexa = hexa.toUpperCase();
hexStr = hexStr.toUpperCase();
lineNo = lineNo.toUpperCase();
}
output += lineNo + " " +
hexa.padEnd(length*(padding+1), " ") +
" |" +
Utils.printable(Utils.byteArrayToChars(buff), false, unixFormat).padEnd(buff.length, " ") +
"|\n";
lines.push(`${lineNo} ${hexStr} |${asciiStr}|`);
if (includeFinalLength && i+buff.length === data.length) {
output += Utils.hex(i+buff.length, 8) + "\n";
lines.push(Utils.hex(i+buff.length, 8));
}
}
return output.slice(0, -1);
return lines.join("\n");
}
/**

View file

@ -214,7 +214,7 @@ class ToTable extends Operation {
output += outputRow(row, longestCells);
let rowOutput = verticalBorder;
row.forEach(function(cell, index) {
rowOutput += " " + headerDivider + " " + verticalBorder;
rowOutput += " " + headerDivider.repeat(longestCells[index]) + " " + verticalBorder;
});
output += rowOutput += "\n";

View file

@ -5,6 +5,7 @@
*/
import Operation from "../Operation.mjs";
import Utils from "../Utils.mjs";
import moment from "moment-timezone";
import {DATETIME_FORMATS, FORMAT_EXAMPLES} from "../lib/DateTime.mjs";
@ -24,7 +25,8 @@ class TranslateDateTimeFormat extends Operation {
this.description = "Parses a datetime string in one format and re-writes it in another.<br><br>Run with no input to see the relevant format string examples.";
this.infoURL = "https://momentjs.com/docs/#/parsing/string-format/";
this.inputType = "string";
this.outputType = "html";
this.outputType = "string";
this.presentType = "html";
this.args = [
{
"name": "Built in formats",
@ -53,12 +55,14 @@ class TranslateDateTimeFormat extends Operation {
"value": ["UTC"].concat(moment.tz.names())
}
];
this.invalidFormatMessage = "Invalid format.";
}
/**
* @param {string} input
* @param {Object[]} args
* @returns {html}
* @returns {string}
*/
run(input, args) {
const [inputFormat, inputTimezone, outputFormat, outputTimezone] = args.slice(1);
@ -68,12 +72,22 @@ class TranslateDateTimeFormat extends Operation {
date = moment.tz(input, inputFormat, inputTimezone);
if (!date || date.format() === "Invalid date") throw Error;
} catch (err) {
return `Invalid format.\n\n${FORMAT_EXAMPLES}`;
return this.invalidFormatMessage;
}
return date.tz(outputTimezone).format(outputFormat);
return date.tz(outputTimezone).format(outputFormat.replace(/[<>]/g, ""));
}
/**
* @param {string} data
* @returns {html}
*/
present(data) {
if (data === this.invalidFormatMessage) {
return `${data}\n\n${FORMAT_EXAMPLES}`;
}
return Utils.escapeHtml(data);
}
}
export default TranslateDateTimeFormat;

View file

@ -9,8 +9,7 @@ import OperationError from "../errors/OperationError.mjs";
import Utils from "../Utils.mjs";
import { isImage } from "../lib/FileType.mjs";
import { toBase64 } from "../lib/Base64.mjs";
import jimplib from "jimp/es/index.js";
const jimp = jimplib.default ? jimplib.default : jimplib;
import jimp from "jimp";
/**
* View Bit Plane operation

View file

@ -126,11 +126,7 @@ class XORBruteForce extends Operation {
if (crib && resultUtf8.toLowerCase().indexOf(crib) < 0) continue;
if (printKey) record += "Key = " + Utils.hex(key, (2*keyLength)) + ": ";
if (outputHex) {
record += toHex(result);
} else {
record += Utils.printable(resultUtf8, false);
}
record += outputHex ? toHex(result) : Utils.escapeWhitespace(resultUtf8);
output.push(record);
}

View file

@ -2,7 +2,7 @@
* GOST 28147-89/GOST R 34.12-2015/GOST R 32.13-2015 Encryption Algorithm
* 1.76
* 2014-2016, Rudolf Nickolaev. All rights reserved.
*
*
* Exported for CyberChef by mshwed [m@ttshwed.com]
*/
@ -18,7 +18,7 @@
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
@ -29,7 +29,7 @@
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*
*/
import GostRandom from './gostRandom.mjs';
@ -37,10 +37,10 @@ import GostRandom from './gostRandom.mjs';
import crypto from 'crypto'
/*
* Initial parameters and common algortithms of GOST 28147-89
*
* Initial parameters and common algortithms of GOST 28147-89
*
* http://tools.ietf.org/html/rfc5830
*
*
*/ // <editor-fold defaultstate="collapsed">
var root = {};
@ -198,7 +198,7 @@ function randomSeed(e) {
function buffer(d) {
if (d instanceof CryptoOperationData)
return d;
else if (d && d.buffer && d.buffer instanceof CryptoOperationData)
else if (d && d?.buffer instanceof CryptoOperationData)
return d.byteOffset === 0 && d.byteLength === d.buffer.byteLength ?
d.buffer : new Uint8Array(new Uint8Array(d, d.byteOffset, d.byteLength)).buffer;
else
@ -232,9 +232,9 @@ function swap32(b) {
// </editor-fold>
/*
* Initial parameters and common algortithms of GOST R 34.12-15
* Initial parameters and common algortithms of GOST R 34.12-15
* Algorithm "Kuznechik" 128bit
*
*
*/ // <editor-fold defaultstate="collapsed">
// Default initial vector
@ -243,17 +243,17 @@ var defaultIV128 = new Uint8Array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
// Mult table for R function
var multTable = (function () {
// Multiply two numbers in the GF(2^8) finite field defined
// Multiply two numbers in the GF(2^8) finite field defined
// by the polynomial x^8 + x^7 + x^6 + x + 1 = 0 */
function gmul(a, b) {
var p = 0, counter, carry;
for (counter = 0; counter < 8; counter++) {
if (b & 1)
p ^= a;
carry = a & 0x80; // detect if x^8 term is about to be generated
carry = a & 0x80; // detect if x^8 term is about to be generated
a = (a << 1) & 0xff;
if (carry)
a ^= 0xc3; // replace x^8 with x^7 + x^6 + x + 1
a ^= 0xc3; // replace x^8 with x^7 + x^6 + x + 1
b >>= 1;
}
return p & 0xff;
@ -379,7 +379,7 @@ function funcC(number, d) {
/**
* Key schedule for GOST R 34.12-15 128bits
*
*
* @memberOf GostCipher
* @private
* @instance
@ -404,8 +404,8 @@ function keySchedule128(k) // <editor-fold defaultstate="collapsed">
} // </editor-fold>
/**
* GOST R 34.12-15 128 bits encrypt/decrypt process
*
* GOST R 34.12-15 128 bits encrypt/decrypt process
*
* @memberOf GostCipher
* @private
* @instance
@ -434,14 +434,14 @@ function process128(k, d, ofs, e) // <editor-fold defaultstate="collapsed">
/**
* One GOST encryption round
*
*
* @memberOf GostCipher
* @private
* @instance
* @method round
* @param {Int8Array} S sBox
* @param {Int32Array} m 2x32 bits cipher block
* @param {Int32Array} k 32 bits key[i]
* @param {Int32Array} m 2x32 bits cipher block
* @param {Int32Array} k 32 bits key[i]
*/
function round(S, m, k) // <editor-fold defaultstate="collapsed">
{
@ -465,13 +465,13 @@ function round(S, m, k) // <editor-fold defaultstate="collapsed">
/**
* Process encrypt/decrypt block with key K using GOST 28147-89
*
*
* @memberOf GostCipher
* @private
* @instance
* @method process
* @param k {Int32Array} 8x32 bits key
* @param d {Int32Array} 8x8 bits cipher block
* @param k {Int32Array} 8x32 bits key
* @param d {Int32Array} 8x8 bits cipher block
* @param ofs {number} offset
*/
function process89(k, d, ofs) // <editor-fold defaultstate="collapsed">
@ -490,13 +490,13 @@ function process89(k, d, ofs) // <editor-fold defaultstate="collapsed">
/**
* Process encrypt/decrypt block with key K using GOST R 34.12-15 64bit block
*
*
* @memberOf GostCipher
* @private
* @instance
* @method process
* @param k {Int32Array} 8x32 bits key
* @param d {Int32Array} 8x8 bits cipher block
* @param k {Int32Array} 8x32 bits key
* @param d {Int32Array} 8x8 bits cipher block
* @param ofs {number} offset
*/
function process15(k, d, ofs) // <editor-fold defaultstate="collapsed">
@ -517,7 +517,7 @@ function process15(k, d, ofs) // <editor-fold defaultstate="collapsed">
/**
* Key keySchedule algorithm for GOST 28147-89 64bit cipher
*
*
* @memberOf GostCipher
* @private
* @instance
@ -556,7 +556,7 @@ function keySchedule89(k, e) // <editor-fold defaultstate="collapsed">
/**
* Key keySchedule algorithm for GOST R 34.12-15 64bit cipher
*
*
* @memberOf GostCipher
* @private
* @instance
@ -595,9 +595,9 @@ function keySchedule15(k, e) // <editor-fold defaultstate="collapsed">
/**
* Key schedule for RC2
*
*
* https://tools.ietf.org/html/rfc2268
*
*
* @memberOf GostCipher
* @private
* @instance
@ -649,10 +649,10 @@ var keyScheduleRC2 = (function () // <editor-fold defaultstate="collapsed">
)();
/**
* RC2 encrypt/decrypt process
*
* RC2 encrypt/decrypt process
*
* https://tools.ietf.org/html/rfc2268
*
*
* @memberOf GostCipher
* @private
* @instance
@ -734,13 +734,13 @@ var processRC2 = (function () // <editor-fold defaultstate="collapsed">
/**
* Algorithm name GOST 28147-ECB<br><br>
*
* encryptECB (K, D) is D, encrypted with key k using GOST 28147/GOST R 34.13 in
* "prostaya zamena" (Electronic Codebook, ECB) mode.
*
* encryptECB (K, D) is D, encrypted with key k using GOST 28147/GOST R 34.13 in
* "prostaya zamena" (Electronic Codebook, ECB) mode.
* @memberOf GostCipher
* @method encrypt
* @instance
* @param k {CryptoOperationData} 8x32 bit key
* @param k {CryptoOperationData} 8x32 bit key
* @param d {CryptoOperationData} 8 bits message
* @return {CryptoOperationData} result
*/
@ -759,14 +759,14 @@ function encryptECB(k, d) // <editor-fold defaultstate="collapsed">
/**
* Algorithm name GOST 28147-ECB<br><br>
*
* decryptECB (K, D) is D, decrypted with key K using GOST 28147/GOST R 34.13 in
*
* decryptECB (K, D) is D, decrypted with key K using GOST 28147/GOST R 34.13 in
* "prostaya zamena" (Electronic Codebook, ECB) mode.
*
*
* @memberOf GostCipher
* @method decrypt
* @instance
* @param k {CryptoOperationData} 8x32 bits key
* @param k {CryptoOperationData} 8x32 bits key
* @param d {CryptoOperationData} 8 bits message
* @return {CryptoOperationData} result
*/
@ -785,16 +785,16 @@ function decryptECB(k, d) // <editor-fold defaultstate="collapsed">
/**
* Algorithm name GOST 28147-CFB<br><br>
*
* encryptCFB (IV, K, D) is D, encrypted with key K using GOST 28147/GOST R 34.13
* in "gammirovanie s obratnoj svyaziyu" (Cipher Feedback, CFB) mode, and IV is
*
* encryptCFB (IV, K, D) is D, encrypted with key K using GOST 28147/GOST R 34.13
* in "gammirovanie s obratnoj svyaziyu" (Cipher Feedback, CFB) mode, and IV is
* used as the initialization vector.
*
*
* @memberOf GostCipher
* @method encrypt
* @instance
* @param {CryptoOperationData} k 8x32 bits key
* @param {CryptoOperationData} d 8 bits array with data
* @param {CryptoOperationData} k 8x32 bits key
* @param {CryptoOperationData} d 8 bits array with data
* @param {CryptoOperationData} iv initial vector
* @return {CryptoOperationData} result
*/
@ -838,16 +838,16 @@ function encryptCFB(k, d, iv) // <editor-fold defaultstate="collapsed">
/**
* Algorithm name GOST 28147-CFB<br><br>
*
* decryptCFB (IV, K, D) is D, decrypted with key K using GOST 28147/GOST R 34.13
* in "gammirovanie s obratnoj svyaziyu po shifrotekstu" (Cipher Feedback, CFB) mode, and IV is
*
* decryptCFB (IV, K, D) is D, decrypted with key K using GOST 28147/GOST R 34.13
* in "gammirovanie s obratnoj svyaziyu po shifrotekstu" (Cipher Feedback, CFB) mode, and IV is
* used as the initialization vector.
*
*
* @memberOf GostCipher
* @method decrypt
* @instance
* @param {CryptoOperationData} k 8x32 bits key
* @param {CryptoOperationData} d 8 bits array with data
* @param {CryptoOperationData} k 8x32 bits key
* @param {CryptoOperationData} d 8 bits array with data
* @param {CryptoOperationData} iv initial vector
* @return {CryptoOperationData} result
*/
@ -893,31 +893,31 @@ function decryptCFB(k, d, iv) // <editor-fold defaultstate="collapsed">
/**
* Algorithm name GOST 28147-OFB<br><br>
*
* encryptOFB/decryptOFB (IV, K, D) is D, encrypted with key K using GOST 28147/GOST R 34.13
* in "gammirovanie s obratnoj svyaziyu po vyhodu" (Output Feedback, OFB) mode, and IV is
*
* encryptOFB/decryptOFB (IV, K, D) is D, encrypted with key K using GOST 28147/GOST R 34.13
* in "gammirovanie s obratnoj svyaziyu po vyhodu" (Output Feedback, OFB) mode, and IV is
* used as the initialization vector.
*
*
* @memberOf GostCipher
* @method encrypt
* @instance
* @param {CryptoOperationData} k 8x32 bits key
* @param {CryptoOperationData} d 8 bits array with data
* @param {CryptoOperationData} k 8x32 bits key
* @param {CryptoOperationData} d 8 bits array with data
* @param {CryptoOperationData} iv 8x8 optional bits initial vector
* @return {CryptoOperationData} result
*/
/**
* Algorithm name GOST 28147-OFB<br><br>
*
* encryptOFB/decryptOFB (IV, K, D) is D, encrypted with key K using GOST 28147/GOST R 34.13
* in "gammirovanie s obratnoj svyaziyu po vyhodu" (Output Feedback, OFB) mode, and IV is
*
* encryptOFB/decryptOFB (IV, K, D) is D, encrypted with key K using GOST 28147/GOST R 34.13
* in "gammirovanie s obratnoj svyaziyu po vyhodu" (Output Feedback, OFB) mode, and IV is
* used as the initialization vector.
*
*
* @memberOf GostCipher
* @method decrypt
* @instance
* @param {CryptoOperationData} k 8x32 bits key
* @param {CryptoOperationData} d 8 bits array with data
* @param {CryptoOperationData} k 8x32 bits key
* @param {CryptoOperationData} d 8 bits array with data
* @param {CryptoOperationData} iv initial vector
* @return {CryptoOperationData} result
*/
@ -965,29 +965,29 @@ function processOFB(k, d, iv) // <editor-fold defaultstate="collapsed">
/**
* Algorithm name GOST 28147-CTR<br><br>
*
* encryptCTR/decryptCTR (IV, K, D) is D, encrypted with key K using GOST 28147/GOST R 34.13
* in "gammirovanie" (Counter Mode-CTR) mode, and IV is used as the
*
* encryptCTR/decryptCTR (IV, K, D) is D, encrypted with key K using GOST 28147/GOST R 34.13
* in "gammirovanie" (Counter Mode-CTR) mode, and IV is used as the
* initialization vector.
* @memberOf GostCipher
* @method encrypt
* @instance
* @param {CryptoOperationData} k 8x32 bits key
* @param {CryptoOperationData} d 8 bits array with data
* @param {CryptoOperationData} k 8x32 bits key
* @param {CryptoOperationData} d 8 bits array with data
* @param {CryptoOperationData} iv 8x8 optional bits initial vector
* @return {CryptoOperationData} result
*/
/**
* Algorithm name GOST 28147-CTR<br><br>
*
* encryptCTR/decryptCTR (IV, K, D) is D, encrypted with key K using GOST 28147/GOST R 34.13
* in "gammirovanie" (Counter Mode-CTR) mode, and IV is used as the
*
* encryptCTR/decryptCTR (IV, K, D) is D, encrypted with key K using GOST 28147/GOST R 34.13
* in "gammirovanie" (Counter Mode-CTR) mode, and IV is used as the
* initialization vector.
* @memberOf GostCipher
* @method decrypt
* @instance
* @param {CryptoOperationData} k 8x32 bits key
* @param {CryptoOperationData} d 8 bits array with data
* @param {CryptoOperationData} k 8x32 bits key
* @param {CryptoOperationData} d 8 bits array with data
* @param {CryptoOperationData} iv initial vector
* @return {CryptoOperationData} result
*/
@ -1081,16 +1081,16 @@ function processCTR15(k, d, iv) // <editor-fold defaultstate="collapsed">
/**
* Algorithm name GOST 28147-CBC<br><br>
*
* encryptCBC (IV, K, D) is D, encrypted with key K using GOST 28147/GOST R 34.13
* in "Prostaya zamena s zatsepleniem" (Cipher-Block-Chaining, CBC) mode and IV is used as the initialization
*
* encryptCBC (IV, K, D) is D, encrypted with key K using GOST 28147/GOST R 34.13
* in "Prostaya zamena s zatsepleniem" (Cipher-Block-Chaining, CBC) mode and IV is used as the initialization
* vector.
*
*
* @memberOf GostCipher
* @method encrypt
* @instance
* @param {CryptoOperationData} k 8x32 bits key
* @param {CryptoOperationData} d 8 bits array with data
* @param {CryptoOperationData} k 8x32 bits key
* @param {CryptoOperationData} d 8 bits array with data
* @param {CryptoOperationData} iv initial vector
* @return {CryptoOperationData} result
*/
@ -1128,16 +1128,16 @@ function encryptCBC(k, d, iv) // <editor-fold defaultstate="collapsed">
/**
* Algorithm name GOST 28147-CBC<br><br>
*
* decryptCBC (IV, K, D) is D, decrypted with key K using GOST 28147/GOST R 34.13
* in "Prostaya zamena s zatsepleniem" (Cipher-Block-Chaining, CBC) mode and IV is used as the initialization
*
* decryptCBC (IV, K, D) is D, decrypted with key K using GOST 28147/GOST R 34.13
* in "Prostaya zamena s zatsepleniem" (Cipher-Block-Chaining, CBC) mode and IV is used as the initialization
* vector.
*
*
* @memberOf GostCipher
* @method decrypt
* @instance
* @param {CryptoOperationData} k 8x32 bits key
* @param {CryptoOperationData} d 8 bits array with data
* @param {CryptoOperationData} k 8x32 bits key
* @param {CryptoOperationData} d 8 bits array with data
* @param {CryptoOperationData} iv initial vector
* @return {CryptoOperationData} result
*/
@ -1176,7 +1176,7 @@ function decryptCBC(k, d, iv) // <editor-fold defaultstate="collapsed">
/**
* The generateKey method returns a new generated key.
*
*
* @memberOf GostCipher
* @method generateKey
* @instance
@ -1193,18 +1193,18 @@ function generateKey() // <editor-fold defaultstate="collapsed">
/**
* makeIMIT (K, D) is the 32-bit result of the GOST 28147/GOST R 34.13 in
* "imitovstavka" (MAC) mode, used with D as plaintext, K as key and IV
* as initialization vector. Note that the standard specifies its use
* makeIMIT (K, D) is the 32-bit result of the GOST 28147/GOST R 34.13 in
* "imitovstavka" (MAC) mode, used with D as plaintext, K as key and IV
* as initialization vector. Note that the standard specifies its use
* in this mode only with an initialization vector of zero.
*
*
* @memberOf GostCipher
* @method processMAC
* @private
* @instance
* @param {Int32Array} key 8x32 bits key
* @param {Int32Array} key 8x32 bits key
* @param {Int32Array} s 8x8 sum array
* @param {Uint8Array} d 8 bits array with data
* @param {Uint8Array} d 8 bits array with data
* @return {Uint8Array} result
*/
function processMAC89(key, s, d) // <editor-fold defaultstate="collapsed">
@ -1271,16 +1271,16 @@ function processMAC15(key, s, d) // <editor-fold defaultstate="collapsed">
} // </editor-fold>
/**
* signMAC (K, D, IV) is the 32-bit result of the GOST 28147/GOST R 34.13 in
* "imitovstavka" (MAC) mode, used with D as plaintext, K as key and IV
* as initialization vector. Note that the standard specifies its use
* signMAC (K, D, IV) is the 32-bit result of the GOST 28147/GOST R 34.13 in
* "imitovstavka" (MAC) mode, used with D as plaintext, K as key and IV
* as initialization vector. Note that the standard specifies its use
* in this mode only with an initialization vector of zero.
*
*
* @memberOf GostCipher
* @method sign
* @instance
* @param {CryptoOperationData} k 8x32 bits key
* @param {CryptoOperationData} d 8 bits array with data
* @param {CryptoOperationData} k 8x32 bits key
* @param {CryptoOperationData} d 8 bits array with data
* @param {CryptoOperationData} iv initial vector
* @return {CryptoOperationData} result
*/
@ -1298,17 +1298,17 @@ function signMAC(k, d, iv) // <editor-fold defaultstate="collapsed">
} // </editor-fold>
/**
* verifyMAC (K, M, D, IV) the 32-bit result verification of the GOST 28147/GOST R 34.13 in
* "imitovstavka" (MAC) mode, used with D as plaintext, K as key and IV
* as initialization vector. Note that the standard specifies its use
* verifyMAC (K, M, D, IV) the 32-bit result verification of the GOST 28147/GOST R 34.13 in
* "imitovstavka" (MAC) mode, used with D as plaintext, K as key and IV
* as initialization vector. Note that the standard specifies its use
* in this mode only with an initialization vector of zero.
*
*
* @memberOf GostCipher
* @method verify
* @instance
* @param {CryptoOperationData} k 8x32 bits key
* @param {CryptoOperationData} k 8x32 bits key
* @param {CryptoOperationData} m 8 bits array with signature
* @param {CryptoOperationData} d 8 bits array with data
* @param {CryptoOperationData} d 8 bits array with data
* @param {CryptoOperationData} iv 8x8 optional bits initial vector
* @return {boolen} MAC verified = true
*/
@ -1326,14 +1326,14 @@ function verifyMAC(k, m, d, iv) // <editor-fold defaultstate="collapsed">
/**
* Algorithm name GOST 28147-KW<br><br>
*
*
* This algorithm encrypts GOST 28147-89 CEK with a GOST 28147/GOST R 34.13 KEK.
* Ref. rfc4357 6.1 GOST 28147-89 Key Wrap
* Note: This algorithm MUST NOT be used with a KEK produced by VKO GOST
* R 34.10-94, because such a KEK is constant for every sender-recipient
* pair. Encrypting many different content encryption keys on the same
* Note: This algorithm MUST NOT be used with a KEK produced by VKO GOST
* R 34.10-94, because such a KEK is constant for every sender-recipient
* pair. Encrypting many different content encryption keys on the same
* constant KEK may reveal that KEK.
*
*
* @memberOf GostCipher
* @method wrapKey
* @instance
@ -1344,14 +1344,14 @@ function verifyMAC(k, m, d, iv) // <editor-fold defaultstate="collapsed">
function wrapKeyGOST(kek, cek) // <editor-fold defaultstate="collapsed">
{
var n = this.blockSize, k = this.keySize, len = k + (n >> 1);
// 1) For a unique symmetric KEK, generate 8 octets at random and call
// the result UKM. For a KEK, produced by VKO GOST R 34.10-2001, use
// the UKM that was used for key derivation.
if (!this.ukm)
// 1) For a unique symmetric KEK, generate 8 octets at random and call
// the result UKM. For a KEK, produced by VKO GOST R 34.10-2001, use
// the UKM that was used for key derivation.
if (!this.ukm)
throw new DataError('UKM must be defined');
var ukm = new Uint8Array(this.ukm);
// 2) Compute a 4-byte checksum value, GOST 28147IMIT (UKM, KEK, CEK).
// Call the result CEK_MAC.
// 2) Compute a 4-byte checksum value, GOST 28147IMIT (UKM, KEK, CEK).
// Call the result CEK_MAC.
var mac = signMAC.call(this, kek, cek, ukm);
// 3) Encrypt the CEK in ECB mode using the KEK. Call the ciphertext CEK_ENC.
var enc = encryptECB.call(this, kek, cek);
@ -1364,10 +1364,10 @@ function wrapKeyGOST(kek, cek) // <editor-fold defaultstate="collapsed">
/**
* Algorithm name GOST 28147-KW<br><br>
*
*
* This algorithm decrypts GOST 28147-89 CEK with a GOST 28147 KEK.
* Ref. rfc4357 6.2 GOST 28147-89 Key Unwrap
*
*
* @memberOf GostCipher
* @method unwrapKey
* @instance
@ -1382,9 +1382,9 @@ function unwrapKeyGOST(kek, data) // <editor-fold defaultstate="collapsed">
var d = buffer(data);
if (d.byteLength !== len)
throw new DataError('Wrapping key size must be ' + len + ' bytes');
// 2) Decompose the wrapped content-encryption key into UKM, CEK_ENC, and CEK_MAC.
// UKM is the most significant (first) 8 octets. CEK_ENC is next 32 octets,
// and CEK_MAC is the least significant (last) 4 octets.
// 2) Decompose the wrapped content-encryption key into UKM, CEK_ENC, and CEK_MAC.
// UKM is the most significant (first) 8 octets. CEK_ENC is next 32 octets,
// and CEK_MAC is the least significant (last) 4 octets.
if (!this.ukm)
throw new DataError('UKM must be defined');
var ukm = new Uint8Array(this.ukm),
@ -1392,7 +1392,7 @@ function unwrapKeyGOST(kek, data) // <editor-fold defaultstate="collapsed">
mac = new Uint8Array(d, k, n >> 1);
// 3) Decrypt CEK_ENC in ECB mode using the KEK. Call the output CEK.
var cek = decryptECB.call(this, kek, enc);
// 4) Compute a 4-byte checksum value, GOST 28147IMIT (UKM, KEK, CEK),
// 4) Compute a 4-byte checksum value, GOST 28147IMIT (UKM, KEK, CEK),
// compare the result with CEK_MAC. If they are not equal, then error.
var check = verifyMAC.call(this, kek, mac, cek, ukm);
if (!check)
@ -1402,11 +1402,11 @@ function unwrapKeyGOST(kek, data) // <editor-fold defaultstate="collapsed">
/**
* Algorithm name GOST 28147-CPKW<br><br>
*
* Given a random 64-bit UKM and a GOST 28147 key K, this algorithm
*
* Given a random 64-bit UKM and a GOST 28147 key K, this algorithm
* creates a new GOST 28147-89 key K(UKM).
* Ref. rfc4357 6.3 CryptoPro KEK Diversification Algorithm
*
*
* @memberOf GostCipher
* @method diversify
* @instance
@ -1419,10 +1419,10 @@ function diversifyKEK(kek, ukm) // <editor-fold defaultstate="collapsed">
{
var n = this.blockSize;
// 1) Let K[0] = K;
// 1) Let K[0] = K;
var k = intArray(kek);
// 2) UKM is split into components a[i,j]:
// UKM = a[0]|..|a[7] (a[i] - byte, a[i,0]..a[i,7] - its bits)
// 2) UKM is split into components a[i,j]:
// UKM = a[0]|..|a[7] (a[i] - byte, a[i,0]..a[i,7] - its bits)
var a = [];
for (var i = 0; i < n; i++) {
a[i] = [];
@ -1430,15 +1430,15 @@ function diversifyKEK(kek, ukm) // <editor-fold defaultstate="collapsed">
a[i][j] = (ukm[i] >>> j) & 0x1;
}
}
// 3) Let i be 0.
// 4) K[1]..K[8] are calculated by repeating the following algorithm
// eight times:
// 3) Let i be 0.
// 4) K[1]..K[8] are calculated by repeating the following algorithm
// eight times:
for (var i = 0; i < n; i++) {
// A) K[i] is split into components k[i,j]:
// K[i] = k[i,0]|k[i,1]|..|k[i,7] (k[i,j] - 32-bit integer)
// B) Vector S[i] is calculated:
// S[i] = ((a[i,0]*k[i,0] + ... + a[i,7]*k[i,7]) mod 2^32) |
// (((~a[i,0])*k[i,0] + ... + (~a[i,7])*k[i,7]) mod 2^32);
// B) Vector S[i] is calculated:
// S[i] = ((a[i,0]*k[i,0] + ... + a[i,7]*k[i,7]) mod 2^32) |
// (((~a[i,0])*k[i,0] + ... + (~a[i,7])*k[i,7]) mod 2^32);
var s = new Int32Array(2);
for (var j = 0; j < 8; j++) {
if (a[i][j])
@ -1457,12 +1457,12 @@ function diversifyKEK(kek, ukm) // <editor-fold defaultstate="collapsed">
/**
* Algorithm name GOST 28147-CPKW<br><br>
*
* This algorithm encrypts GOST 28147-89 CEK with a GOST 28147 KEK.
* It can be used with any KEK (e.g., produced by VKO GOST R 34.10-94 or
*
* This algorithm encrypts GOST 28147-89 CEK with a GOST 28147 KEK.
* It can be used with any KEK (e.g., produced by VKO GOST R 34.10-94 or
* VKO GOST R 34.10-2001) because a unique UKM is used to diversify the KEK.
* Ref. rfc4357 6.3 CryptoPro Key Wrap
*
*
* @memberOf GostCipher
* @method wrapKey
* @instance
@ -1473,21 +1473,21 @@ function diversifyKEK(kek, ukm) // <editor-fold defaultstate="collapsed">
function wrapKeyCP(kek, cek) // <editor-fold defaultstate="collapsed">
{
var n = this.blockSize, k = this.keySize, len = k + (n >> 1);
// 1) For a unique symmetric KEK or a KEK produced by VKO GOST R
// 34.10-94, generate 8 octets at random. Call the result UKM. For
// a KEK, produced by VKO GOST R 34.10-2001, use the UKM that was
// 1) For a unique symmetric KEK or a KEK produced by VKO GOST R
// 34.10-94, generate 8 octets at random. Call the result UKM. For
// a KEK, produced by VKO GOST R 34.10-2001, use the UKM that was
// used for key derivation.
if (!this.ukm)
if (!this.ukm)
throw new DataError('UKM must be defined');
var ukm = new Uint8Array(this.ukm);
// 2) Diversify KEK, using the CryptoPro KEK Diversification Algorithm,
// 2) Diversify KEK, using the CryptoPro KEK Diversification Algorithm,
// described in Section 6.5. Call the result KEK(UKM).
var dek = diversifyKEK.call(this, kek, ukm);
// 3) Compute a 4-byte checksum value, GOST 28147IMIT (UKM, KEK(UKM),
// CEK). Call the result CEK_MAC.
// 3) Compute a 4-byte checksum value, GOST 28147IMIT (UKM, KEK(UKM),
// CEK). Call the result CEK_MAC.
var mac = signMAC.call(this, dek, cek, ukm);
// 4) Encrypt CEK in ECB mode using KEK(UKM). Call the ciphertext
// CEK_ENC.
// 4) Encrypt CEK in ECB mode using KEK(UKM). Call the ciphertext
// CEK_ENC.
var enc = encryptECB.call(this, dek, cek);
// 5) The wrapped content-encryption key is (UKM | CEK_ENC | CEK_MAC).
var r = new Uint8Array(len);
@ -1498,8 +1498,8 @@ function wrapKeyCP(kek, cek) // <editor-fold defaultstate="collapsed">
/**
* Algorithm name GOST 28147-CPKW<br><br>
*
* This algorithm encrypts GOST 28147-89 CEK with a GOST 28147 KEK.
*
* This algorithm encrypts GOST 28147-89 CEK with a GOST 28147 KEK.
* Ref. rfc4357 6.4 CryptoPro Key Unwrap
*
* @memberOf GostCipher
@ -1512,26 +1512,26 @@ function wrapKeyCP(kek, cek) // <editor-fold defaultstate="collapsed">
function unwrapKeyCP(kek, data) // <editor-fold defaultstate="collapsed">
{
var n = this.blockSize, k = this.keySize, len = k + (n >> 1);
// 1) If the wrapped content-encryption key is not 44 octets, then error.
// 1) If the wrapped content-encryption key is not 44 octets, then error.
var d = buffer(data);
if (d.byteLength !== len)
throw new DataError('Wrapping key size must be ' + len + ' bytes');
// 2) Decompose the wrapped content-encryption key into UKM, CEK_ENC,
// and CEK_MAC. UKM is the most significant (first) 8 octets.
// CEK_ENC is next 32 octets, and CEK_MAC is the least significant
// (last) 4 octets.
// 2) Decompose the wrapped content-encryption key into UKM, CEK_ENC,
// and CEK_MAC. UKM is the most significant (first) 8 octets.
// CEK_ENC is next 32 octets, and CEK_MAC is the least significant
// (last) 4 octets.
if (!this.ukm)
throw new DataError('UKM must be defined');
var ukm = new Uint8Array(this.ukm),
enc = new Uint8Array(d, 0, k),
mac = new Uint8Array(d, k, n >> 1);
// 3) Diversify KEK using the CryptoPro KEK Diversification Algorithm,
// described in section 6.5. Call the result KEK(UKM).
// 3) Diversify KEK using the CryptoPro KEK Diversification Algorithm,
// described in section 6.5. Call the result KEK(UKM).
var dek = diversifyKEK.call(this, kek, ukm);
// 4) Decrypt CEK_ENC in ECB mode using KEK(UKM). Call the output CEK.
// 4) Decrypt CEK_ENC in ECB mode using KEK(UKM). Call the output CEK.
var cek = decryptECB.call(this, dek, enc);
// 5) Compute a 4-byte checksum value, GOST 28147IMIT (UKM, KEK(UKM),
// CEK), compare the result with CEK_MAC. If they are not equal,
// 5) Compute a 4-byte checksum value, GOST 28147IMIT (UKM, KEK(UKM),
// CEK), compare the result with CEK_MAC. If they are not equal,
// then it is an error.
var check = verifyMAC.call(this, dek, mac, cek, ukm);
if (!check)
@ -1541,23 +1541,23 @@ function unwrapKeyCP(kek, data) // <editor-fold defaultstate="collapsed">
/**
* SignalCom master key packing algorithm
*
*
* kek stored in 3 files - kek.opq, mk.db3, masks.db3
* kek.opq - always 36 bytes length = 32 bytes encrypted kek + 4 bytes mac of decrypted kek
* mk.db3 - 6 bytes header (1 byte magic code 0x22 + 1 byte count of masks + 4 bytes mac of
* xor summarizing masks value) + attached masks
* masks.db3 - detached masks.
* mk.db3 - 6 bytes header (1 byte magic code 0x22 + 1 byte count of masks + 4 bytes mac of
* xor summarizing masks value) + attached masks
* masks.db3 - detached masks.
* Total length of attached + detached masks = 32 bits * count of masks
* Default value of count 8 = (7 attached + 1 detached). But really no reason for such
* Default value of count 8 = (7 attached + 1 detached). But really no reason for such
* separation - all masks xor summarizing - order is not matter.
* Content of file rand.opq can used as ukm. Don't forget change file content after using.
*
* For usb-token files has names:
* Content of file rand.opq can used as ukm. Don't forget change file content after using.
*
* For usb-token files has names:
* a001 - mk.db3, b001 - masks.db3, c001 - kek.opq, d001 - rand.opq
* For windows registry
* 00000001 - mk.db3, 00000002 - masks.db3, 00000003 - key.opq, 00000004 - rand.opq,
* 00000001 - mk.db3, 00000002 - masks.db3, 00000003 - key.opq, 00000004 - rand.opq,
* 00000006 - keys\00000001.key, 0000000A - certificate
*
*
* @memberOf GostCipher
* @method packKey
* @instance
@ -1603,9 +1603,9 @@ function packKeySC(unpacked, ukm) // <editor-fold defaultstate="collapsed">
/**
* Algorithm name GOST 28147-SCKW<br><br>
*
*
* SignalCom master key unpacking algorithm
*
*
* @memberOf GostCipher
* @method unpackKey
* @instance
@ -1650,14 +1650,14 @@ function unpackKeySC(packed) // <editor-fold defaultstate="collapsed">
/**
* Algorithm name GOST 28147-SCKW<br><br>
*
*
* SignalCom Key Wrapping algorithm
*
*
* @memberOf GostCipher
* @method wrapKey
* @instance
* @param {CryptoOperationData} kek - clear kek or concatination of mk.db3 + masks.db3
* @param {CryptoOperationData} cek - key for wrapping
* @param {CryptoOperationData} cek - key for wrapping
* @returns {CryptoOperationData} wrapped key - file kek.opq
*/
function wrapKeySC(kek, cek) // <editor-fold defaultstate="collapsed">
@ -1677,13 +1677,13 @@ function wrapKeySC(kek, cek) // <editor-fold defaultstate="collapsed">
/**
* Algorithm name GOST 28147-SCKW<br><br>
*
*
* SignalCom Key UnWrapping algorithm
*
*
* @memberOf GostCipher
* @method unwrapKey
* @instance
* @param {CryptoOperationData} kek - concatination of files mk.db3 + masks.db3 or clear kek
* @param {CryptoOperationData} kek - concatination of files mk.db3 + masks.db3 or clear kek
* @param {CryptoOperationData} cek - wrapping key - file kek.opq
* @return {CryptoOperationData} result
*/
@ -1704,9 +1704,9 @@ function unwrapKeySC(kek, cek) // <editor-fold defaultstate="collapsed">
/**
* Algorithm name GOST 28147-SCKW<br><br>
*
*
* SignalCom master key generation for wrapping
*
*
* @memberOf GostCipher
* @method generateKey
* @instance
@ -1719,24 +1719,24 @@ function generateWrappingKeySC() // <editor-fold defaultstate="collapsed">
function maskKey(mask, key, inverse, keySize) // <editor-fold defaultstate="collapsed">
{
var k = keySize / 4,
var k = keySize / 4,
m32 = new Int32Array(buffer(mask)),
k32 = new Int32Array(buffer(key)),
k32 = new Int32Array(buffer(key)),
r32 = new Int32Array(k);
if (inverse)
for (var i = 0; i < k; i++)
for (var i = 0; i < k; i++)
r32[i] = (k32[i] + m32[i]) & 0xffffffff;
else
for (var i = 0; i < k; i++)
for (var i = 0; i < k; i++)
r32[i] = (k32[i] - m32[i]) & 0xffffffff;
return r32.buffer;
} // </editor-fold>
/**
* Algorithm name GOST 28147-MASK<br><br>
*
*
* This algorithm wrap key mask
*
*
* @memberOf GostCipher
* @method wrapKey
* @instance
@ -1751,7 +1751,7 @@ function wrapKeyMask(mask, key) // <editor-fold defaultstate="collapsed">
/**
* Algorithm name GOST 28147-CPKW<br><br>
*
*
* This algorithm unwrap key mask
*
* @memberOf GostCipher
@ -1768,17 +1768,17 @@ function unwrapKeyMask(mask, key) // <editor-fold defaultstate="collapsed">
/**
* Algorithm name GOST 28147-CPKM<br><br>
*
*
* Key meshing in according to rfc4357 2.3.2. CryptoPro Key Meshing
*
*
* @memberOf GostCipher
* @method keyMeshing
* @instance
* @private
* @param {(Uint8Array|CryptoOperationData)} k 8x8 bit key
* @param {(Uint8Array|CryptoOperationData)} k 8x8 bit key
* @param {Uint8Array} s 8x8 bit sync (iv)
* @param {Integer} i block index
* @param {Int32Array} key 8x32 bit key schedule
* @param {Int32Array} key 8x32 bit key schedule
* @param {boolean} e true - decrypt
* @returns CryptoOperationData next 8x8 bit key
*/
@ -1797,12 +1797,12 @@ function keyMeshingCP(k, s, i, key, e) // <editor-fold defaultstate="collapsed">
/**
* Null Key Meshing in according to rfc4357 2.3.1
*
*
* @memberOf GostCipher
* @method keyMeshing
* @instance
* @private
* @param {(Uint8Array|CryptoOperationData)} k 8x8 bit key
* @param {(Uint8Array|CryptoOperationData)} k 8x8 bit key
*/
function noKeyMeshing(k) // <editor-fold defaultstate="collapsed">
{
@ -1811,9 +1811,9 @@ function noKeyMeshing(k) // <editor-fold defaultstate="collapsed">
/**
* Algorithm name GOST 28147-NoPadding<br><br>
*
*
* No padding.
*
*
* @memberOf GostCipher
* @method padding
* @instance
@ -1828,11 +1828,11 @@ function noPad(d) // <editor-fold defaultstate="collapsed">
/**
* Algorithm name GOST 28147-PKCS5Padding<br><br>
*
* PKCS#5 padding: 8-x remaining bytes are filled with the value of
* 8-x. If theres no incomplete block, one extra block filled with
*
* PKCS#5 padding: 8-x remaining bytes are filled with the value of
* 8-x. If theres no incomplete block, one extra block filled with
* value 8 is added
*
*
* @memberOf GostCipher
* @method padding
* @instance
@ -1870,9 +1870,9 @@ function pkcs5Unpad(d) // <editor-fold defaultstate="collapsed">
/**
* Algorithm name GOST 28147-ZeroPadding<br><br>
*
*
* Zero padding: 8-x remaining bytes are filled with zero
*
*
* @memberOf GostCipher
* @method padding
* @instance
@ -1895,10 +1895,10 @@ function zeroPad(d) // <editor-fold defaultstate="collapsed">
/**
* Algorithm name GOST 28147-BitPadding<br><br>
*
* Bit padding: P* = P || 1 || 000...0 If theres no incomplete block,
*
* Bit padding: P* = P || 1 || 000...0 If theres no incomplete block,
* one extra block filled with 1 || 000...0
*
*
* @memberOf GostCipher
* @method padding
* @instance
@ -1906,7 +1906,7 @@ function zeroPad(d) // <editor-fold defaultstate="collapsed">
* @param {Uint8Array} d array with source data
* @returns {Uint8Array} result
*/
function bitPad(d) // <editor-fold defaultstate="collapsed">
function bitPad(d) // <editor-fold defaultstate="collapsed">
{
var n = d.byteLength,
nb = this.blockSize,
@ -1919,7 +1919,7 @@ function bitPad(d) // <editor-fold defaultstate="collapsed">
return r;
} // </editor-fold>
function bitUnpad(d) // <editor-fold defaultstate="collapsed">
function bitUnpad(d) // <editor-fold defaultstate="collapsed">
{
var m = d.byteLength,
n = m;
@ -1936,10 +1936,10 @@ function bitUnpad(d) // <editor-fold defaultstate="collapsed">
/**
* Algorithm name GOST 28147-RandomPadding<br><br>
*
* Random padding: 8-x remaining bytes of the last block are set to
*
* Random padding: 8-x remaining bytes of the last block are set to
* random.
*
*
* @memberOf GostCipher
* @method padding
* @instance
@ -1960,15 +1960,15 @@ function randomPad(d) // <editor-fold defaultstate="collapsed">
} // </editor-fold>
/**
* GOST 28147-89 Encryption Algorithm<br><br>
*
* GOST 28147-89 Encryption Algorithm<br><br>
*
* References {@link http://tools.ietf.org/html/rfc5830}<br><br>
*
* When keys and initialization vectors are converted to/from byte arrays,
*
* When keys and initialization vectors are converted to/from byte arrays,
* little-endian byte order is assumed.<br><br>
*
*
* Normalized algorithm identifier common parameters:
*
*
* <ul>
* <li><b>name</b> Algorithm name 'GOST 28147' or 'GOST R 34.12'</li>
* <li><b>version</b> Algorithm version, number
@ -1992,9 +1992,9 @@ function randomPad(d) // <editor-fold defaultstate="collapsed">
* </li>
* <li><b>sBox</b> Paramset sBox for GOST 28147-89, string. Used only if version = 1989</li>
* </ul>
*
*
* Supported algorithms, modes and parameters:
*
*
* <ul>
* <li>Encript/Decrypt mode (ES)
* <ul>
@ -2017,9 +2017,9 @@ function randomPad(d) // <editor-fold defaultstate="collapsed">
* </ul>
* </li>
* </ul>
*
*
* Supported paramters values:
*
*
* <ul>
* <li>Block modes (parameter 'block')
* <ul>
@ -2053,7 +2053,7 @@ function randomPad(d) // <editor-fold defaultstate="collapsed">
* </ul>
* </li>
* </ul>
*
*
* @class GostCipher
* @param {AlgorithmIndentifier} algorithm WebCryptoAPI algorithm identifier
*/
@ -2076,7 +2076,7 @@ function GostCipher(algorithm) // <editor-fold defaultstate="collapsed">
((algorithm.keyWrapping || 'NO') !== 'NO' ? algorithm.keyWrapping : '') + 'KW' :
(algorithm.block || 'ECB') + ((algorithm.block === 'CFB' || algorithm.block === 'OFB' ||
(algorithm.block === 'CTR' && algorithm.version === 2015)) &&
algorithm.shiftBits && algorithm.shiftBits !== this.blockLength ? '-' + algorithm.shiftBits : '') +
algorithm?.shiftBits !== this.blockLength ? '-' + algorithm.shiftBits : '') +
(algorithm.padding ? '-' + (algorithm.padding || (algorithm.block === 'CTR' ||
algorithm.block === 'CFB' || algorithm.block === 'OFB' ? 'NO' : 'ZERO')) + 'PADDING' : '') +
((algorithm.keyMeshing || 'NO') !== 'NO' ? '-CPKEYMESHING' : '')) +
@ -2085,7 +2085,7 @@ function GostCipher(algorithm) // <editor-fold defaultstate="collapsed">
// Algorithm procreator
this.procreator = algorithm.procreator;
switch (algorithm.version || 1989) {
case 1:
this.process = processRC2;

View file

@ -2,7 +2,7 @@
* Coding algorithms: Base64, Hex, Int16, Chars, BER and PEM
* version 1.76
* 2014-2016, Rudolf Nickolaev. All rights reserved.
*
*
* Exported for CyberChef by mshwed [m@ttshwed.com]
*/
@ -18,7 +18,7 @@
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*
* THIS SOfTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES Of MERCHANTABILITY AND fITNESS fOR A PARTICULAR PURPOSE ARE
@ -29,16 +29,16 @@
* CAUSED AND ON ANY THEORY Of LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT Of THE USE
* Of THIS SOfTWARE, EVEN If ADVISED Of THE POSSIBILITY OF SUCH DAMAGE.
*
*
*/
import gostCrypto from './gostCrypto.mjs';
/**
* The Coding interface provides string converting methods: Base64, Hex,
* The Coding interface provides string converting methods: Base64, Hex,
* Int16, Chars, BER and PEM
* @class GostCoding
*
*
*/ // <editor-fold defaultstate="collapsed">
var root = {};
var DataError = Error;
@ -48,7 +48,7 @@ var Date = Date;
function buffer(d) {
if (d instanceof CryptoOperationData)
return d;
else if (d && d.buffer && d.buffer instanceof CryptoOperationData)
else if (d && d?.buffer instanceof CryptoOperationData)
return d.byteOffset === 0 && d.byteLength === d.buffer.byteLength ?
d.buffer : new Uint8Array(new Uint8Array(d, d.byteOffset, d.byteLength)).buffer;
else
@ -60,13 +60,13 @@ function GostCoding() {
/**
* BASE64 conversion
*
*
* @class GostCoding.Base64
*/
var Base64 = {// <editor-fold defaultstate="collapsed">
/**
* Base64.decode convert BASE64 string s to CryptoOperationData
*
*
* @memberOf GostCoding.Base64
* @param {String} s BASE64 encoded string value
* @returns {CryptoOperationData} Binary decoded data
@ -100,7 +100,7 @@ var Base64 = {// <editor-fold defaultstate="collapsed">
},
/**
* Base64.encode(data) convert CryptoOperationData data to BASE64 string
*
*
* @memberOf GostCoding.Base64
* @param {CryptoOperationData} data Bynary data for encoding
* @returns {String} BASE64 encoded data
@ -129,7 +129,7 @@ var Base64 = {// <editor-fold defaultstate="collapsed">
/**
* BASE64 conversion
*
*
* @memberOf GostCoding
* @insnance
* @type GostCoding.Base64
@ -139,7 +139,7 @@ GostCoding.prototype.Base64 = Base64;
/**
* Text string conversion <br>
* Methods support charsets: ascii, win1251, utf8, utf16 (ucs2, unicode), utf32 (ucs4)
*
*
* @class GostCoding.Chars
*/
var Chars = (function () { // <editor-fold defaultstate="collapsed">
@ -162,8 +162,8 @@ var Chars = (function () { // <editor-fold defaultstate="collapsed">
return {
/**
* Chars.decode(s, charset) convert string s with defined charset to CryptoOperationData
*
* Chars.decode(s, charset) convert string s with defined charset to CryptoOperationData
*
* @memberOf GostCoding.Chars
* @param {string} s Javascript string
* @param {string} charset Charset, default 'win1251'
@ -236,7 +236,7 @@ var Chars = (function () { // <editor-fold defaultstate="collapsed">
},
/**
* Chars.encode(data, charset) convert CryptoOperationData data to string with defined charset
*
*
* @memberOf GostCoding.Chars
* @param {CryptoOperationData} data Binary data
* @param {string} charset Charset, default win1251
@ -250,15 +250,15 @@ var Chars = (function () { // <editor-fold defaultstate="collapsed">
if (charset === 'utf8') {
c = c >= 0xfc && c < 0xfe && i + 5 < n ? // six bytes
(c - 0xfc) * 1073741824 + (d[++i] - 0x80 << 24) + (d[++i] - 0x80 << 18) + (d[++i] - 0x80 << 12) + (d[++i] - 0x80 << 6) + d[++i] - 0x80
: c >> 0xf8 && c < 0xfc && i + 4 < n ? // five bytes
: c >> 0xf8 && c < 0xfc && i + 4 < n ? // five bytes
(c - 0xf8 << 24) + (d[++i] - 0x80 << 18) + (d[++i] - 0x80 << 12) + (d[++i] - 0x80 << 6) + d[++i] - 0x80
: c >> 0xf0 && c < 0xf8 && i + 3 < n ? // four bytes
: c >> 0xf0 && c < 0xf8 && i + 3 < n ? // four bytes
(c - 0xf0 << 18) + (d[++i] - 0x80 << 12) + (d[++i] - 0x80 << 6) + d[++i] - 0x80
: c >= 0xe0 && c < 0xf0 && i + 2 < n ? // three bytes
: c >= 0xe0 && c < 0xf0 && i + 2 < n ? // three bytes
(c - 0xe0 << 12) + (d[++i] - 0x80 << 6) + d[++i] - 0x80
: c >= 0xc0 && c < 0xe0 && i + 1 < n ? // two bytes
: c >= 0xc0 && c < 0xe0 && i + 1 < n ? // two bytes
(c - 0xc0 << 6) + d[++i] - 0x80
: c; // one byte
: c; // one byte
} else if (charset === 'unicode' || charset === 'ucs2' || charset === 'utf16') {
c = (c << 8) + d[++i];
if (c >= 0xD800 && c < 0xE000) {
@ -289,7 +289,7 @@ var Chars = (function () { // <editor-fold defaultstate="collapsed">
/**
* Text string conversion
*
*
* @memberOf GostCoding
* @insnance
* @type GostCoding.Chars
@ -298,20 +298,20 @@ GostCoding.prototype.Chars = Chars;
/**
* HEX conversion
*
*
* @class GostCoding.Hex
*/
var Hex = {// <editor-fold defaultstate="collapsed">
/**
* Hex.decode(s, endean) convert HEX string s to CryptoOperationData in endean mode
*
*
* @memberOf GostCoding.Hex
* @param {string} s Hex encoded string
* @param {boolean} endean Little or Big Endean, default Little
* @returns {CryptoOperationData} Decoded binary data
*/
decode: function (s, endean) {
s = s.replace(/[^A-fa-f0-9]/g, '');
s = s.replace(/[^A-Fa-f0-9]/g, '');
var n = Math.ceil(s.length / 2), r = new Uint8Array(n);
s = (s.length % 2 > 0 ? '0' : '') + s;
if (endean && ((typeof endean !== 'string') ||
@ -325,8 +325,8 @@ var Hex = {// <editor-fold defaultstate="collapsed">
},
/**
* Hex.encode(data, endean) convert CryptoOperationData data to HEX string in endean mode
*
* @memberOf GostCoding.Hex
*
* @memberOf GostCoding.Hex
* @param {CryptoOperationData} data Binary data
* @param {boolean} endean Little/Big Endean, default Little
* @returns {string} Hex decoded string
@ -358,19 +358,19 @@ GostCoding.prototype.Hex = Hex;
/**
* String hex-encoded integer conversion
*
*
* @class GostCoding.Int16
*/
var Int16 = {// <editor-fold defaultstate="collapsed">
/**
* Int16.decode(s) convert hex big insteger s to CryptoOperationData
*
* @memberOf GostCoding.Int16
* @param {string} s Int16 string
*
* @memberOf GostCoding.Int16
* @param {string} s Int16 string
* @returns {CryptoOperationData} Decoded binary data
*/
decode: function (s) {
s = (s || '').replace(/[^\-A-fa-f0-9]/g, '');
s = (s || '').replace(/[^\-A-Fa-f0-9]/g, '');
if (s.length === 0)
s = '0';
// Signature
@ -403,7 +403,7 @@ var Int16 = {// <editor-fold defaultstate="collapsed">
},
/**
* Int16.encode(data) convert CryptoOperationData data to big integer hex string
*
*
* @memberOf GostCoding.Int16
* @param {CryptoOperationData} data Binary data
* @returns {string} Int16 encoded string
@ -438,7 +438,7 @@ GostCoding.prototype.Int16 = Int16;
/**
* BER, DER, CER conversion
*
*
* @class GostCoding.BER
*/
var BER = (function () { // <editor-fold defaultstate="collapsed">
@ -659,7 +659,7 @@ var BER = (function () { // <editor-fold defaultstate="collapsed">
case 0x1C: // UniversalString
case 0x1E: // BMPString
k = k || 0;
// Split content on 1000 octet len parts
// Split content on 1000 octet len parts
var size = 1000;
var bytelen = 0, ba = [], offset = 0;
for (var i = k, n = content.length; i < n; i += size - k) {
@ -777,7 +777,7 @@ var BER = (function () { // <editor-fold defaultstate="collapsed">
} while (buf & 0x80);
}
// Read len
// Read len
buf = d[pos++];
len = buf & 0x7f;
if (len !== buf) {
@ -979,7 +979,7 @@ var BER = (function () { // <editor-fold defaultstate="collapsed">
throw new DataError('Unrecognized time format "' + s + '" at offset ' + start);
if (shortYear) {
// Where YY is greater than or equal to 50, the year SHALL be interpreted as 19YY; and
// Where YY is less than 50, the year SHALL be interpreted as 20YY
// Where YY is less than 50, the year SHALL be interpreted as 20YY
m[1] = +m[1];
m[1] += (m[1] < 50) ? 2000 : 1900;
}
@ -1031,12 +1031,12 @@ var BER = (function () { // <editor-fold defaultstate="collapsed">
* <li>CryptoOperationData - OCTET STRING</li>
* </ul>
* SEQUENCE or SET arrays recursively encoded for each item.<br>
* OCTET STRING and BIT STRING can presents as array with one item.
* OCTET STRING and BIT STRING can presents as array with one item.
* It means encapsulates encoding for child element.<br>
*
* If CONTEXT or APPLICATION classes item presents as array with one
*
* If CONTEXT or APPLICATION classes item presents as array with one
* item we use EXPLICIT encoding for element, else IMPLICIT encoding.<br>
*
*
* @memberOf GostCoding.BER
* @param {Object} object Object to encoding
* @param {string} format Encoding rule: 'DER' or 'CER', default 'DER'
@ -1048,7 +1048,7 @@ var BER = (function () { // <editor-fold defaultstate="collapsed">
},
/**
* BER.encode(data) convert ASN.1 format CryptoOperationData data to javascript object<br><br>
*
*
* Conversion rules to javascript object:
* <ul>
* <li>BOOLEAN - Boolean object</li>
@ -1057,7 +1057,7 @@ var BER = (function () { // <editor-fold defaultstate="collapsed">
* <li>OCTET STRING - Hex encoded string or Array with one item in case of incapsulates encoding</li>
* <li>OBJECT IDENTIFIER - String with object identifier</li>
* <li>SEQUENCE, SET - Array of encoded items</li>
* <li>UTF8String, NumericString, PrintableString, TeletexString, VideotexString,
* <li>UTF8String, NumericString, PrintableString, TeletexString, VideotexString,
* IA5String, GraphicString, VisibleString, GeneralString, UniversalString,
* BMPString - encoded String</li>
* <li>UTCTime, GeneralizedTime - Date</li>
@ -1087,7 +1087,7 @@ GostCoding.prototype.BER = BER;
var PEM = {// <editor-fold defaultstate="collapsed">
/**
* PEM.encode(data, name) encode CryptoOperationData to PEM format with name label
*
*
* @memberOf GostCoding.PEM
* @param {(Object|CryptoOperationData)} data Java script object or BER-encoded binary data
* @param {string} name Name of PEM object: 'certificate', 'private key' etc.
@ -1100,7 +1100,7 @@ var PEM = {// <editor-fold defaultstate="collapsed">
},
/**
* PEM.decode(s, name, deep) decode PEM format s labeled name to CryptoOperationData or javascript object in according to deep parameter
*
*
* @memberOf GostCoding.PEM
* @param {string} s PEM encoded string
* @param {string} name Name of PEM object: 'certificate', 'private key' etc.
@ -1151,10 +1151,10 @@ GostCoding.prototype.PEM = PEM;
if (gostCrypto)
/**
* Coding algorithms: Base64, Hex, Int16, Chars, BER and PEM
*
*
* @memberOf gostCrypto
* @type GostCoding
*/
gostCrypto.coding = new GostCoding();
export default GostCoding;
export default GostCoding;

View file

@ -2,11 +2,11 @@
* Implementation Web Crypto interfaces for GOST algorithms
* 1.76
* 2014-2016, Rudolf Nickolaev. All rights reserved.
*
*
* Exported for CyberChef by mshwed [m@ttshwed.com]
*/
/*
/*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
@ -18,7 +18,7 @@
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
@ -29,7 +29,7 @@
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*
*/
import GostRandom from './gostRandom.mjs';
@ -39,7 +39,7 @@ import crypto from 'crypto'
/*
* Algorithm normalization
*
*
*/ // <editor-fold defaultstate="collapsed">
var root = {};
@ -233,7 +233,7 @@ function normalize(algorithm, method) {
break;
}
// Encrypt additional modes
// Encrypt additional modes
if (na.mode === 'ES') {
if (algorithm.block)
na.block = algorithm.block; // ECB, CFB, OFB, CTR, CBC
@ -383,7 +383,7 @@ function checkNative(algorithm) {
/*
* Key conversion methods
*
*
*/ // <editor-fold defaultstate="collapsed">
// Check key parameter
@ -522,7 +522,7 @@ function swapBytes(src) {
/**
* Promise stub object (not fulfill specification, only for internal use)
* Class not defined if Promise class already defined in root context<br><br>
*
*
* The Promise object is used for deferred and asynchronous computations. A Promise is in one of the three states:
* <ul>
* <li>pending: initial state, not fulfilled or rejected.</li>
@ -532,8 +532,8 @@ function swapBytes(src) {
* Another term describing the state is settled: the Promise is either fulfilled or rejected, but not pending.<br><br>
* @class Promise
* @global
* @param {function} executor Function object with two arguments resolve and reject.
* The first argument fulfills the promise, the second argument rejects it.
* @param {function} executor Function object with two arguments resolve and reject.
* The first argument fulfills the promise, the second argument rejects it.
* We can call these functions, once our operation is completed.
*/ // <editor-fold defaultstate="collapsed">
if (!Promise) {
@ -588,15 +588,15 @@ if (!Promise) {
}
}
/**
* The then() method returns a Promise. It takes two arguments, both are
* The then() method returns a Promise. It takes two arguments, both are
* callback functions for the success and failure cases of the Promise.
*
*
* @method then
* @memberOf Promise
* @instance
* @param {function} onFulfilled A Function called when the Promise is fulfilled. This function has one argument, the fulfillment value.
* @param {function} onRejected A Function called when the Promise is rejected. This function has one argument, the rejection reason.
* @returns {Promise}
* @returns {Promise}
*/
this.then = function (onFulfilled, onRejected) {
@ -611,7 +611,7 @@ if (!Promise) {
return;
}
value = mswrap(value);
if (value && value.then && value.then.call) {
if (value && value?.then?.call) {
value.then(resolve, reject);
} else {
resolve(value);
@ -627,7 +627,7 @@ if (!Promise) {
return;
}
reason = mswrap(reason);
if (reason && reason.then && reason.then.call) {
if (reason && reason?.then?.call) {
reason.then(resolve, reject);
} else {
reject(reason);
@ -647,14 +647,14 @@ if (!Promise) {
};
/**
* The catch() method returns a Promise and deals with rejected cases only.
* The catch() method returns a Promise and deals with rejected cases only.
* It behaves the same as calling Promise.prototype.then(undefined, onRejected).
*
*
* @method catch
* @memberOf Promise
* @instance
* @param {function} onRejected A Function called when the Promise is rejected. This function has one argument, the rejection reason.
* @returns {Promise}
* @returns {Promise}
*/
this['catch'] = function (onRejected) {
return this.then(undefined, onRejected);
@ -662,15 +662,15 @@ if (!Promise) {
}
/**
* The Promise.all(iterable) method returns a promise that resolves when all
* The Promise.all(iterable) method returns a promise that resolves when all
* of the promises in the iterable argument have resolved.<br><br>
*
* The result is passed as an array of values from all the promises.
* If something passed in the iterable array is not a promise, it's converted to
* one by Promise.resolve. If any of the passed in promises rejects, the
* all Promise immediately rejects with the value of the promise that rejected,
*
* The result is passed as an array of values from all the promises.
* If something passed in the iterable array is not a promise, it's converted to
* one by Promise.resolve. If any of the passed in promises rejects, the
* all Promise immediately rejects with the value of the promise that rejected,
* discarding all the other promises whether or not they have resolved.
*
*
* @method all
* @memberOf Promise
* @static
@ -698,7 +698,7 @@ if (!Promise) {
for (var i = 0, n = promises.length; i < n; i++) {
var data = promises[i];
if (data.then && data.then.call)
if (data?.then?.call)
data.then(asyncResolve(i), asyncReject);
else
result[i] = data;
@ -715,7 +715,7 @@ if (!Promise) {
/*
* Worker executor
*
*
*/ // <editor-fold defaultstate="collapsed">
var baseUrl = '', nameSuffix = '';
@ -797,7 +797,7 @@ if (!root.importScripts) {
if (!worker) {
// Import main module
// Reason: we are already in worker process or Worker interface is not
// Reason: we are already in worker process or Worker interface is not
// yet supported
root.gostEngine || require('./gostEngine');
}
@ -841,11 +841,11 @@ function call(callback) {
/*
* WebCrypto common class references
*
*
*/ // <editor-fold defaultstate="collapsed">
/**
* The Algorithm object is a dictionary object [WebIDL] which is used to
* specify an algorithm and any additional parameters required to fully
* The Algorithm object is a dictionary object [WebIDL] which is used to
* specify an algorithm and any additional parameters required to fully
* specify the desired operation.<br>
* <pre>
* dictionary Algorithm {
@ -867,7 +867,7 @@ function call(callback) {
*/
/**
* The KeyAlgorithm interface represents information about the contents of a
* The KeyAlgorithm interface represents information about the contents of a
* given Key object.
* <pre>
* interface KeyAlgorithm {
@ -875,14 +875,14 @@ function call(callback) {
* };
* </pre>
* WebCrypto API reference {@link http://www.w3.org/TR/WebCryptoAPI/#key-algorithm-interface}
* @class KeyAlgorithm
* @class KeyAlgorithm
* @param {DOMString} name The name of the algorithm used to generate the Key
*/
/**
* The type of a key. The recognized key type values are "public", "private"
* and "secret". Opaque keying material, including that used for symmetric
* algorithms, is represented by "secret", while keys used as part of asymmetric
* The type of a key. The recognized key type values are "public", "private"
* and "secret". Opaque keying material, including that used for symmetric
* algorithms, is represented by "secret", while keys used as part of asymmetric
* algorithms composed of public/private keypairs will be either "public" or "private".
* <pre>
* typedef DOMString KeyType;
@ -892,8 +892,8 @@ function call(callback) {
*/
/**
* Sequence of operation type that may be performed using a key. The recognized
* key usage values are "encrypt", "decrypt", "sign", "verify", "deriveKey",
* Sequence of operation type that may be performed using a key. The recognized
* key usage values are "encrypt", "decrypt", "sign", "verify", "deriveKey",
* "deriveBits", "wrapKey" and "unwrapKey".
* <pre>
* typedef DOMString[] KeyUsages;
@ -903,19 +903,19 @@ function call(callback) {
*/
/**
* The Key object represents an opaque reference to keying material that is
* The Key object represents an opaque reference to keying material that is
* managed by the user agent.<br>
* This specification provides a uniform interface for many different kinds of
* keying material managed by the user agent. This may include keys that have
* been generated by the user agent, derived from other keys by the user agent,
* imported to the user agent through user actions or using this API,
* pre-provisioned within software or hardware to which the user agent has
* access or made available to the user agent in other ways. The term key refers
* broadly to any keying material including actual keys for cryptographic
* This specification provides a uniform interface for many different kinds of
* keying material managed by the user agent. This may include keys that have
* been generated by the user agent, derived from other keys by the user agent,
* imported to the user agent through user actions or using this API,
* pre-provisioned within software or hardware to which the user agent has
* access or made available to the user agent in other ways. The term key refers
* broadly to any keying material including actual keys for cryptographic
* operations and secret values obtained within key derivation or exchange operations.<br>
* The Key object is not required to directly interface with the underlying key
* storage mechanism, and may instead simply be a reference for the user agent
* to understand how to obtain the keying material when needed, eg. when performing
* The Key object is not required to directly interface with the underlying key
* storage mechanism, and may instead simply be a reference for the user agent
* to understand how to obtain the keying material when needed, eg. when performing
* a cryptographic operation.
* <pre>
* interface Key {
@ -923,14 +923,14 @@ function call(callback) {
* readonly attribute boolean extractable;
* readonly attribute KeyAlgorithm algorithm;
* readonly attribute KeyUsages usages;
* };
* };
* </pre>
* WebCrypto API reference {@link http://www.w3.org/TR/WebCryptoAPI/#key-interface}
* @class Key
* @param {KeyType} type The type of a key. The recognized key type values are "public", "private" and "secret".
* @param {boolean} extractable Whether or not the raw keying material may be exported by the application.
* @param {KeyAlgorithm} algorithm The Algorithm used to generate the key.
* @param {KeyUsages} usages Key usage array: type of operation that may be performed using a key.
* @param {KeyUsages} usages Key usage array: type of operation that may be performed using a key.
*/
/**
@ -939,7 +939,7 @@ function call(callback) {
* interface KeyPair {
* readonly attribute Key publicKey;
* readonly attribute Key privateKey;
* };
* };
* </pre>
* WebCrypto API reference {@link http://www.w3.org/TR/WebCryptoAPI/#keypair}
* @class KeyPair
@ -963,7 +963,7 @@ function call(callback) {
*/
/**
* Binary data
* Binary data
* <pre>
* typedef (ArrayBuffer or ArrayBufferView) CryptoOperationData;
* </pre>
@ -982,9 +982,9 @@ var CryptoOperationData = ArrayBuffer;
/**
* The gostCrypto provide general purpose cryptographic functionality for
* GOST standards including a cryptographically strong pseudo-random number
* GOST standards including a cryptographically strong pseudo-random number
* generator seeded with truly random values.
*
*
* @namespace gostCrypto
*/
var gostCrypto = {};
@ -992,17 +992,17 @@ var gostCrypto = {};
/**
* The SubtleCrypto class provides low-level cryptographic primitives and algorithms.
* WebCrypto API reference {@link http://www.w3.org/TR/WebCryptoAPI/#subtlecrypto-interface}
*
*
* @class SubtleCrypto
*/ // <editor-fold>
function SubtleCrypto() {
}
/**
* The encrypt method returns a new Promise object that will encrypt data
* The encrypt method returns a new Promise object that will encrypt data
* using the specified algorithm identifier with the supplied Key.
* WebCrypto API reference {@link http://www.w3.org/TR/WebCryptoAPI/#SubtleCrypto-method-encrypt}<br><br>
*
*
* Supported algorithm names:
* <ul>
* <li><b>GOST 28147-ECB</b> "prostaya zamena" (ECB) mode (default)</li>
@ -1016,8 +1016,8 @@ function SubtleCrypto() {
* <li><b>GOST R 34.12-CTR</b> "gammirovanie" (counter) mode</li>
* <li><b>GOST R 34.12-CBC</b> Cipher-Block-Chaining (CBC) mode</li>
* </ul>
* For more information see {@link GostCipher}
*
* For more information see {@link GostCipher}
*
* @memberOf SubtleCrypto
* @method encrypt
* @instance
@ -1039,10 +1039,10 @@ SubtleCrypto.prototype.encrypt = function (algorithm, key, data) // <editor-fold
}; // </editor-fold>
/**
* The decrypt method returns a new Promise object that will decrypt data
* using the specified algorithm identifier with the supplied Key.
* The decrypt method returns a new Promise object that will decrypt data
* using the specified algorithm identifier with the supplied Key.
* WebCrypto API reference {@link http://www.w3.org/TR/WebCryptoAPI/#SubtleCrypto-method-decrypt}<br><br>
*
*
* Supported algorithm names:
* <ul>
* <li><b>GOST 28147-ECB</b> "prostaya zamena" (ECB) mode (default)</li>
@ -1056,8 +1056,8 @@ SubtleCrypto.prototype.encrypt = function (algorithm, key, data) // <editor-fold
* <li><b>GOST R 34.12-CTR</b> "gammirovanie" (counter) mode</li>
* <li><b>GOST R 34.12-CBC</b> Cipher-Block-Chaining (CBC) mode</li>
* </ul>
* For additional modes see {@link GostCipher}
*
* For additional modes see {@link GostCipher}
*
* @memberOf SubtleCrypto
* @method decrypt
* @instance
@ -1079,10 +1079,10 @@ SubtleCrypto.prototype.decrypt = function (algorithm, key, data) // <editor-fold
}; // </editor-fold>
/**
* The sign method returns a new Promise object that will sign data using
* The sign method returns a new Promise object that will sign data using
* the specified algorithm identifier with the supplied Key.
* WebCrypto API reference {@link http://www.w3.org/TR/WebCryptoAPI/#SubtleCrypto-method-sign}<br><br>
*
*
* Supported algorithm names:
* <ul>
* <li><b>GOST R 34.10-94</b> GOST Signature</li>
@ -1096,12 +1096,12 @@ SubtleCrypto.prototype.decrypt = function (algorithm, key, data) // <editor-fold
* <li><b>SHA-HMAC</b> HMAC base on SHA</li>
* </ul>
* For additional modes see {@link GostSign}, {@link GostDigest} and {@link GostCipher}
*
*
* @memberOf SubtleCrypto
* @method sign
* @instance
* @param {AlgorithmIdentifier} algorithm Algorithm identifier
* @param {Key} key Key object
* @param {Key} key Key object
* @param {CryptoOperationData} data Operation data
* @returns {Promise} Promise that resolves with {@link CryptoOperationData}
*/
@ -1124,10 +1124,10 @@ SubtleCrypto.prototype.sign = function (algorithm, key, data) // <editor-fold de
}; // </editor-fold>
/**
* The verify method returns a new Promise object that will verify data
* The verify method returns a new Promise object that will verify data
* using the specified algorithm identifier with the supplied Key.
* WebCrypto API reference {@link http://www.w3.org/TR/WebCryptoAPI/#SubtleCrypto-method-verify}<br><br>
*
*
* Supported algorithm names:
* <ul>
* <li><b>GOST R 34.10-94</b> GOST Signature</li>
@ -1141,7 +1141,7 @@ SubtleCrypto.prototype.sign = function (algorithm, key, data) // <editor-fold de
* <li><b>SHA-HMAC</b> HMAC base on SHA</li>
* </ul>
* For additional modes see {@link GostSign}, {@link GostDigest} and {@link GostCipher}
*
*
* @memberOf SubtleCrypto
* @method verify
* @instance
@ -1168,10 +1168,10 @@ SubtleCrypto.prototype.verify = function (algorithm, key, signature, data) // <e
}; // </editor-fold>
/**
* The digest method returns a new Promise object that will digest data
* using the specified algorithm identifier.
* The digest method returns a new Promise object that will digest data
* using the specified algorithm identifier.
* WebCrypto API reference {@link http://www.w3.org/TR/WebCryptoAPI/#SubtleCrypto-method-digest}<br><br>
*
*
* Supported algorithm names:
* <ul>
* <li><b>GOST R 34.11-94</b> Old-Style GOST Hash</li>
@ -1179,7 +1179,7 @@ SubtleCrypto.prototype.verify = function (algorithm, key, signature, data) // <e
* <li><b>SHA</b> SHA Hash</li>
* </ul>
* For additional modes see {@link GostDigest}
*
*
* @memberOf SubtleCrypto
* @method digest
* @instance
@ -1201,10 +1201,10 @@ SubtleCrypto.prototype.digest = function (algorithm, data) // <editor-fold defau
/**
* The generateKey method returns a new Promise object that will key(s) using
* the specified algorithm identifier. Key can be used in according with
* KeyUsages sequence. The recognized key usage values are "encrypt", "decrypt",
* KeyUsages sequence. The recognized key usage values are "encrypt", "decrypt",
* "sign", "verify", "deriveKey", "deriveBits", "wrapKey" and "unwrapKey".
* WebCrypto API reference {@link http://www.w3.org/TR/WebCryptoAPI/#SubtleCrypto-method-generateKey}<br><br>
*
*
* Supported algorithm names:
* <ul>
* <li><b>GOST R 34.10</b> ECGOST Key Pairs</li>
@ -1216,7 +1216,7 @@ SubtleCrypto.prototype.digest = function (algorithm, data) // <editor-fold defau
* </ul>
* For additional modes see {@link GostSign}, {@link GostDigest} and {@link GostCipher}<br>
* Note: Generation key for GOST R 34.10-94 not supported.
*
*
* @memberOf SubtleCrypto
* @method generateKey
* @instance
@ -1254,10 +1254,10 @@ SubtleCrypto.prototype.generateKey = function (algorithm, extractable, keyUsages
/**
* The deriveKey method returns a new Promise object that will key(s) using
* the specified algorithm identifier. Key can be used in according with
* KeyUsage sequence. The recognized key usage values are "encrypt", "decrypt",
* KeyUsage sequence. The recognized key usage values are "encrypt", "decrypt",
* "sign", "verify", "deriveKey", "deriveBits", "wrapKey" and "unwrapKey".
* WebCrypto API reference {@link http://www.w3.org/TR/WebCryptoAPI/#SubtleCrypto-method-deriveKey}<br><br>
*
*
* Supported algorithm names:
* <ul>
* <li><b>GOST R 34.10-DH</b> ECDH Key Agreement mode</li>
@ -1269,7 +1269,7 @@ SubtleCrypto.prototype.generateKey = function (algorithm, extractable, keyUsages
* <li><b>SHA-PFXKDF</b> PFX Key for Derivation Algorithm</li>
* </ul>
* For additional modes see {@link GostSign} and {@link GostDigest}
*
*
* @memberOf SubtleCrypto
* @method deriveKey
* @instance
@ -1277,7 +1277,7 @@ SubtleCrypto.prototype.generateKey = function (algorithm, extractable, keyUsages
* @param {Key} baseKey Derivation key object
* @param {AlgorithmIdentifier} derivedKeyType Derived key algorithm identifier
* @param {boolean} extractable Whether or not the raw keying material may be exported by the application
* @param {KeyUsages} keyUsages Key usage array: type of operation that may be performed using a key
* @param {KeyUsages} keyUsages Key usage array: type of operation that may be performed using a key
* @returns {Promise} Promise that resolves with {@link Key}
*/
SubtleCrypto.prototype.deriveKey = function (algorithm, baseKey,
@ -1302,10 +1302,10 @@ SubtleCrypto.prototype.deriveKey = function (algorithm, baseKey,
}; // </editor-fold>
/**
* The deriveBits method returns length bits on baseKey using the
* specified algorithm identifier.
* The deriveBits method returns length bits on baseKey using the
* specified algorithm identifier.
* WebCrypto API reference {@link http://www.w3.org/TR/WebCryptoAPI/#SubtleCrypto-method-deriveBits}<br><br>
*
*
* Supported algorithm names:
* <ul>
* <li><b>GOST R 34.10-DH</b> ECDH Key Agreement mode</li>
@ -1317,7 +1317,7 @@ SubtleCrypto.prototype.deriveKey = function (algorithm, baseKey,
* <li><b>SHA-PFXKDF</b> PFX Key for Derivation Algorithm</li>
* </ul>
* For additional modes see {@link GostSign} and {@link GostDigest}
*
*
* @memberOf SubtleCrypto
* @method deriveBits
* @instance
@ -1342,7 +1342,7 @@ SubtleCrypto.prototype.deriveBits = function (algorithm, baseKey, length) // <ed
/**
* The importKey method returns a new Promise object that will key(s) using
* the specified algorithm identifier. Key can be used in according with
* KeyUsage sequence. The recognized key usage values are "encrypt", "decrypt",
* KeyUsage sequence. The recognized key usage values are "encrypt", "decrypt",
* "sign", "verify", "deriveKey", "deriveBits", "wrapKey" and "unwrapKey".<br><br>
* Parameter keyData contains data in defined format.
* The suppored key format values are:
@ -1352,7 +1352,7 @@ SubtleCrypto.prototype.deriveBits = function (algorithm, baseKey, length) // <ed
* <li>'spki' - The DER encoding of the SubjectPublicKeyInfo structure from RFC 5280.</li>
* </ul>
* WebCrypto API reference {@link http://www.w3.org/TR/WebCryptoAPI/#SubtleCrypto-method-importKey}<br><br>
*
*
* Supported algorithm names:
* <ul>
* <li><b>GOST R 34.10-94</b> GOST Private and Public keys</li>
@ -1364,7 +1364,7 @@ SubtleCrypto.prototype.deriveBits = function (algorithm, baseKey, length) // <ed
* <li><b>GOST R 34.11-KDF</b> Key for Derivation Algorithm</li>
* </ul>
* For additional modes see {@link GostSign}, {@link GostDigest} and {@link GostCipher}<br>
*
*
* @memberOf SubtleCrypto
* @method importKey
* @instance
@ -1455,7 +1455,7 @@ SubtleCrypto.prototype.importKey = function (format, keyData, algorithm, extract
* <li>'spki' - The DER encoding of the SubjectPublicKeyInfo structure from RFC 5280.</li>
* </ul>
* WebCrypto API reference {@link http://www.w3.org/TR/WebCryptoAPI/#SubtleCrypto-method-exportKey}<br><br>
*
*
* Supported algorithm names:
* <ul>
* <li><b>GOST R 34.10-94</b> GOST Private and Public keys</li>
@ -1472,7 +1472,7 @@ SubtleCrypto.prototype.importKey = function (format, keyData, algorithm, extract
* <li><b>SHA-PFXKDF</b> Import PFX Key for Derivation Algorithm</li>
* </ul>
* For additional modes see {@link GostSign}, {@link GostDigest} and {@link GostCipher}<br>
*
*
* @memberOf SubtleCrypto
* @method exportKey
* @instance
@ -1492,7 +1492,7 @@ SubtleCrypto.prototype.exportKey = function (format, key) // <editor-fold defaul
var raw = extractKey(null, null, key);
if (format === 'raw')
return raw;
else if (format === 'pkcs8' && key.algorithm && key.algorithm.id) {
else if (format === 'pkcs8' && key?.algorithm?.id) {
if (key.algorithm.procreator === 'VN') {
// Add masks for ViPNet
var algorithm = key.algorithm, mask;
@ -1514,7 +1514,7 @@ SubtleCrypto.prototype.exportKey = function (format, key) // <editor-fold defaul
});
} else
return gostCrypto.asn1.GostPrivateKeyInfo.encode(key);
} else if (format === 'spki' && key.algorithm && key.algorithm.id)
} else if (format === 'spki' && key?.algorithm?.id)
return gostCrypto.asn1.GostSubjectPublicKeyInfo.encode(key);
else
throw new NotSupportedError('Key format not supported');
@ -1524,7 +1524,7 @@ SubtleCrypto.prototype.exportKey = function (format, key) // <editor-fold defaul
/**
* The wrapKey method returns a new Promise object that will wrapped key(s).
* WebCrypto API reference {@link http://www.w3.org/TR/WebCryptoAPI/#SubtleCrypto-method-wrapKey}<br><br>
*
*
* Supported algorithm names:
* <ul>
* <li><b>GOST 28147-KW</b> Key Wrapping GOST 28147 modes</li>
@ -1534,7 +1534,7 @@ SubtleCrypto.prototype.exportKey = function (format, key) // <editor-fold defaul
* <li><b>GOST R 34.10-MASK</b> Key Mask GOST R 34.10 modes</li>
* </ul>
* For additional modes see {@link GostCipher}<br>
*
*
* @memberOf SubtleCrypto
* @method wrapKey
* @instance
@ -1567,7 +1567,7 @@ SubtleCrypto.prototype.wrapKey = function (format, key, wrappingKey, wrapAlgorit
/**
* The unwrapKey method returns a new Promise object that will unwrapped key(s).
* WebCrypto API reference {@link http://www.w3.org/TR/WebCryptoAPI/#SubtleCrypto-method-unwrapKey}<br><br>
*
*
* Supported algorithm names:
* <ul>
* <li><b>GOST 28147-KW</b> Key Wrapping GOST 28147 modes</li>
@ -1577,7 +1577,7 @@ SubtleCrypto.prototype.wrapKey = function (format, key, wrappingKey, wrapAlgorit
* <li><b>GOST R 34.10-MASK</b> Key Mask GOST R 34.10 modes</li>
* </ul>
* For additional modes see {@link GostCipher}<br>
*
*
* @memberOf SubtleCrypto
* @method unwrapKey
* @instance
@ -1620,21 +1620,21 @@ SubtleCrypto.prototype.unwrapKey = function (format, wrappedKey, unwrappingKey,
}; // </editor-fold>
/**
* The subtle attribute provides an instance of the SubtleCrypto
* interface which provides low-level cryptographic primitives and
* The subtle attribute provides an instance of the SubtleCrypto
* interface which provides low-level cryptographic primitives and
* algorithms.
*
*
* @memberOf gostCrypto
* @type SubtleCrypto
*/
gostCrypto.subtle = new SubtleCrypto();
/**
* The getRandomValues method generates cryptographically random values.
*
* The getRandomValues method generates cryptographically random values.
*
* First try to use Web Crypto random genereator. Next make random
* bytes based on standart Math.random mixed with time and mouse pointer
*
*
* @memberOf gostCrypto
* @param {(CryptoOperationData)} array Destination buffer for random data
*/

View file

@ -2,7 +2,7 @@
* GOST R 34.11-94 / GOST R 34.11-12 implementation
* 1.76
* 2014-2016, Rudolf Nickolaev. All rights reserved.
*
*
* Exported for CyberChef by mshwed [m@ttshwed.com]
*/
@ -18,11 +18,11 @@
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*
* Converted to JavaScript from source https://www.streebog.net/
* Copyright (c) 2013, Alexey Degtyarev.
* All rights reserved.
*
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
@ -33,7 +33,7 @@
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*
*/
import GostRandom from './gostRandom.mjs';
@ -42,12 +42,12 @@
/*
* GOST R 34.11
* Common methods
*
* Common methods
*
*/ // <editor-fold defaultstate="collapsed">
var root = {};
var rootCrypto = crypto
var rootCrypto = crypto
var DataError = Error,
NotSupportedError = Error;
@ -113,7 +113,7 @@ function getSeed(length) {
function buffer(d) {
if (d instanceof ArrayBuffer)
return d;
else if (d && d.buffer && d.buffer instanceof ArrayBuffer)
else if (d && d?.buffer instanceof ArrayBuffer)
return d.byteOffset === 0 && d.byteLength === d.buffer.byteLength ?
d.buffer : new Uint8Array(new Uint8Array(d, d.byteOffset, d.byteLength)).buffer;
else
@ -122,16 +122,16 @@ function buffer(d) {
/**
* Algorithm name GOST R 34.11 or GOST R 34.11-12<br><br>
*
*
* http://tools.ietf.org/html/rfc6986
*
*
* The digest method returns digest data in according to GOST R 4311-2012.<br>
* Size of digest also defines in algorithm name.
* Size of digest also defines in algorithm name.
* <ul>
* <li>GOST R 34.11-256-12 - 256 bits digest</li>
* <li>GOST R 34.11-512-12 - 512 bits digest</li>
* </ul>
*
*
* @memberOf GostDigest
* @method digest
* @instance
@ -140,13 +140,13 @@ function buffer(d) {
*/
var digest2012 = (function () // <editor-fold defaultstate="collapsed">
{
// Constants
var buffer0 = new Int32Array(16); // [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
// Constants
var buffer0 = new Int32Array(16); // [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
var buffer512 = new Int32Array(16); // [512, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
var buffer512 = new Int32Array(16); // [512, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
buffer512[0] = 512;
// Constant C
// Constant C
var C = (function (s) {
var h = new Int32Array(b64decode(s)),
r = new Array(12);
@ -157,7 +157,7 @@ var digest2012 = (function () // <editor-fold defaultstate="collapsed">
'B0Wm8lllgN0jTXTMNnR2BRXTYKQIKkKiAWlnkpHgfEv8xIV1jbhOcRbQRS5DdmovH3xlwIEvy+vp2soe2lsIsbebsSFwBHnmVs3L1xui3VXKpwrbwmG1XFiZ1hJrF7WaMQG1Fg9e1WGYKyMKcur+89e1cA9GneNPGi+dqYq1o2+yCroK9ZYemTHbeoZD9LbCCdtiYDc6ycGxnjWQ5A/i03t7KbEUderyix+cUl9e8QY1hD1qKPw5Cscvzius3HT1LtHjhLy+DCLxN+iToepTNL4DUpMzE7fYddYD7YIs16k/NV5orRxynX08XDN+hY5I3eRxXaDhSPnSZhXos98f71f+bHz9WBdg9WPqqX6iVnoWGicjtwD/36P1OiVHF82/vf8PgNc1njVKEIYWHxwVf2MjqWwMQT+amUdHraxr6ktufWRGekBo+jVPkDZyxXG/tsa+wmYf8gq0t5oct6b6z8aO8Jq0mn8YbKRCUfnEZi3AOTB6O8Okb9nTOh2urk+uk9QUOk1WhojzSjyiTEUXNQQFSiiDaUcGNyyCLcWrkgnJk3oZMz5H08mHv+bHxp45VAkkv/6GrFHsxaruFg7H9B7nAr/UDX+k' +
'2ahRWTXCrDYvxKXRK43RaZAGm5LLK4n0msTbTTtEtIke3jaccfi3TkFBbgwCqucDp8mTTUJbH5vbWiODUURhcmAqH8uS3DgOVJwHppqKK3uxzrLbC0QKgIQJDeC3Vdk8JEKJJRs6fTreXxbs2JpMlJsiMRZUWo837ZxFmPvHtHTDtjsV0fqYNvRSdjswbB56SzNprwJn558DYTMbiuH/H9t4iv8c50GJ8/PkskjlKjhSbwWApt6+qxst84HNpMprXdhvwEpZot6Ybkd9Hc2678q5SOrvcR2KeWaEFCGAASBhB6vru2v62JT+WmPNxgIw+4nI79CezXsg1xvxSpK8SJkbstnVF/T6UijhiKqkHeeGzJEYne+AXZufITDUEiD4dx3fvDI8pM16sUkEsIAT0roxFvFn5443');
// Precalc Ax
// Precalc Ax
var Ax = (function (s) {
return new Int32Array(b64decode(s));
})(
@ -201,12 +201,12 @@ var digest2012 = (function () // <editor-fold defaultstate="collapsed">
// Variables
var sigma, N, h;
// 64bit tools
// 64bit tools
function get8(x, i) {
return (x[i >> 2] >> ((i & 3) << 3)) & 0xff;
}
// 512bit tools
// 512bit tools
function add512(x, y) {
var CF = 0, w0, w1;
for (var i = 0; i < 16; i++) {
@ -315,7 +315,7 @@ var digest2012 = (function () // <editor-fold defaultstate="collapsed">
return function (data) {
// Cleanup
// Cleanup
sigma = new512();
N = new512();
@ -357,9 +357,9 @@ var digest2012 = (function () // <editor-fold defaultstate="collapsed">
/**
* Algorithm name GOST R 34.11-94<br><br>
*
*
* http://tools.ietf.org/html/rfc5831
*
*
* The digest method returns digest data in according to GOST R 34.11-94.
* @memberOf GostDigest
* @method digest
@ -512,7 +512,7 @@ var digest94 = (function () // <editor-fold defaultstate="collapsed">
var n = d.length;
var r = n % 32, q = (n - r) / 32;
// Proccess full blocks
// Proccess full blocks
for (var i = 0; i < q; i++) {
var b = new Uint8Array(d.buffer, i * 32, 32);
@ -553,11 +553,11 @@ var digest94 = (function () // <editor-fold defaultstate="collapsed">
/**
* Algorithm name SHA-1<br><br>
*
*
* https://tools.ietf.org/html/rfc3174
*
*
* The digest method returns digest data in according to SHA-1.<br>
*
*
* @memberOf GostDigest
* @method digest
* @instance
@ -700,9 +700,9 @@ var digestSHA1 = (function () // <editor-fold defaultstate="collapsed">
} // </editor-fold>
)();
/**
/**
* Algorithm name GOST R 34.11-HMAC<br><br>
*
*
* HMAC with the specified hash function.
* @memberOf GostDigest
* @method sign
@ -742,9 +742,9 @@ function signHMAC(key, data) // <editor-fold defaultstate="collapsed">
/**
* Algorithm name GOST R 34.11-HMAC<br><br>
*
*
* Verify HMAC based on GOST R 34.11 hash
*
*
* @memberOf GostDigest
* @method verify
* @instance
@ -768,9 +768,9 @@ function verifyHMAC(key, signature, data) // <editor-fold defaultstate="collapse
/**
* Algorithm name GOST R 34.11-KDF<br><br>
*
*
* Simple generate key 256/512 bit random seed for derivation algorithms
*
*
* @memberOf GostDigest
* @method generateKey
* @instance
@ -783,7 +783,7 @@ function generateKey() // <editor-fold defaultstate="collapsed">
/**
* Algorithm name GOST R 34.11-PFXKDF<br><br>
*
*
* Derive bits from password (PKCS12 mode)
* <ul>
* <li>algorithm.salt - random value, salt</li>
@ -868,16 +868,16 @@ function deriveBitsPFXKDF(baseKey, length) // <editor-fold defaultstate="collaps
/**
* Algorithm name GOST R 34.11-KDF<br><br>
*
*
* Derive bits for KEK deversification in 34.10-2012 algorithm
* KDF(KEK, UKM, label) = HMAC256 (KEK, 0x01|label|0x00|UKM|0x01|0x00)
* Default label = 0x26|0xBD|0xB8|0x78
*
* KDF(KEK, UKM, label) = HMAC256 (KEK, 0x01|label|0x00|UKM|0x01|0x00)
* Default label = 0x26|0xBD|0xB8|0x78
*
* @memberOf GostDigest
* @method deriveBits
* @instance
* @param {(ArrayBuffer|TypedArray)} baseKey base key for deriviation
* @param {number} length output bit-length
* @param {number} length output bit-length
* @returns {ArrayBuffer} result
*/
function deriveBitsKDF(baseKey, length) // <editor-fold defaultstate="collapsed">
@ -907,7 +907,7 @@ function deriveBitsKDF(baseKey, length) // <editor-fold defaultstate="collapsed"
/**
* Algorithm name GOST R 34.11-PBKDF1<br><br>
*
*
* Derive bits from password
* <ul>
* <li>algorithm.salt - random value, salt</li>
@ -943,7 +943,7 @@ function deriveBitsPBKDF1(baseKey, length) // <editor-fold defaultstate="collaps
/**
* Algorithm name GOST R 34.11-PBKDF2<br><br>
*
*
* Derive bits from password
* <ul>
* <li>algorithm.salt - random value, salt</li>
@ -999,7 +999,7 @@ function deriveBitsPBKDF2(baseKey, length) // <editor-fold defaultstate="collaps
/**
* Algorithm name GOST R 34.11-CPKDF<br><br>
*
*
* Derive bits from password. CryptoPro algorithm
* <ul>
* <li>algorithm.salt - random value, salt</li>
@ -1074,9 +1074,9 @@ function deriveBitsCP(baseKey, length) {
/**
* Algorithm name GOST R 34.11-KDF or GOST R 34.11-PBKDF2 or other<br><br>
*
*
* Derive key from derive bits subset
*
*
* @memberOf GostDigest
* @method deriveKey
* @instance
@ -1090,11 +1090,11 @@ function deriveKey(baseKey) // <editor-fold defaultstate="collapsed">
/**
* GOST R 34.11 Algorithm<br><br>
*
*
* References: {@link http://tools.ietf.org/html/rfc6986} and {@link http://tools.ietf.org/html/rfc5831}<br><br>
*
*
* Normalized algorithm identifier common parameters:
*
*
* <ul>
* <li><b>name</b> Algorithm name 'GOST R 34.11'</li>
* <li><b>version</b> Algorithm version
@ -1121,9 +1121,9 @@ function deriveKey(baseKey) // <editor-fold defaultstate="collapsed">
* </li>
* <li><b>sBox</b> Paramset sBox for GOST 28147-89. Used only if version = 1994</li>
* </ul>
*
*
* Supported algorithms, modes and parameters:
*
*
* <ul>
* <li>Digest HASH mode (default)</li>
* <li>Sign/Verify HMAC modes parameters depends on version and length
@ -1150,7 +1150,7 @@ function deriveKey(baseKey) // <editor-fold defaultstate="collapsed">
* <ul>
* <li><b>salt</b> {@link CryptoOperationData} Random salt as input for HMAC algorithm</li>
* <li><b>iterations</b> Iteration count. GOST recomended value 1000 (default) or 2000</li>
* <li><b>diversifier</b> Deversifier, ID=1 - key material for performing encryption or decryption,
* <li><b>diversifier</b> Deversifier, ID=1 - key material for performing encryption or decryption,
* ID=2 - IV (Initial Value) for encryption or decryption, ID=3 - integrity key for MACing</li>
* </ul>
* </li>
@ -1161,7 +1161,7 @@ function deriveKey(baseKey) // <editor-fold defaultstate="collapsed">
* </ul>
* </li>
* </ul>
*
*
* @class GostDigest
* @param {AlgorithmIdentifier} algorithm WebCryptoAPI algorithm identifier
*/
@ -1257,4 +1257,4 @@ function GostDigest(algorithm) // <editor-fold defaultstate="collapsed">
}
} // </editor-fold>
export default GostDigest;
export default GostDigest;

View file

@ -16,10 +16,10 @@
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*
* Used library JSBN http://www-cs-students.stanford.edu/~tjw/jsbn/
* Copyright (c) 2003-2005 Tom Wu (tjw@cs.Stanford.EDU)
*
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
@ -30,7 +30,7 @@
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*
*/
import GostRandom from './gostRandom.mjs';
@ -40,11 +40,11 @@
/*
* Predefined curves and params collection
*
*
* http://tools.ietf.org/html/rfc5832
* http://tools.ietf.org/html/rfc7091
* http://tools.ietf.org/html/rfc4357
*
*
*/ // <editor-fold defaultstate="collapsed">
var root = {};
@ -181,10 +181,10 @@ var GostParams = {
}
}; // </editor-fold>
/*
* BigInteger arithmetic tools
* optimized release of http://www-cs-students.stanford.edu/~tjw/jsbn/jsbn.js
*
/*
* BigInteger arithmetic tools
* optimized release of http://www-cs-students.stanford.edu/~tjw/jsbn/jsbn.js
*
*/ // <editor-fold defaultstate="collapsed">
// Bits per one element
@ -688,8 +688,8 @@ function extend(c, o) {
/*
* Classic, Barret, Mongomery reductions, optimized ExpMod algorithms
* optimized release of http://www-cs-students.stanford.edu/~tjw/jsbn/jsbn2.js
*
*/ // <editor-fold defaultstate="collapsed">
*
*/ // <editor-fold defaultstate="collapsed">
// Classic reduction
var Classic = function (m) {
@ -974,8 +974,8 @@ function expMod(x, e, m) {
/*
* EC Field Elements, Points, Curves
* optimized release of http://www-cs-students.stanford.edu/~tjw/jsbn/ec.js
*
*/ // <editor-fold defaultstate="collapsed">
*
*/ // <editor-fold defaultstate="collapsed">
// EC Field Elemets
function newFE(a, x) {
@ -1233,8 +1233,8 @@ function newCurve(q, a, b) {
/*
* Converion tools (hex, binary)
*
*/ // <editor-fold defaultstate="collapsed">
*
*/ // <editor-fold defaultstate="collapsed">
function atobi(d) {
var k = 8;
@ -1445,7 +1445,7 @@ function hash(d) {
function buffer(d) {
if (d instanceof CryptoOperationData)
return d;
else if (d && d.buffer && d.buffer instanceof CryptoOperationData)
else if (d && d?.buffer instanceof CryptoOperationData)
return d.byteOffset === 0 && d.byteLength === d.buffer.byteLength ?
d.buffer : new Uint8Array(new Uint8Array(d, d.byteOffset, d.byteLength)).buffer;
else
@ -1483,9 +1483,9 @@ function getSeed(length) {
/**
* Algorithm name GOST R 34.10<br><br>
*
*
* The sign method returns sign data generated with the supplied privateKey.<br>
*
*
* @memberOf GostSign
* @method sign
* @instance
@ -1518,7 +1518,7 @@ function sign(privateKey, data) // <editor-fold defaultstate="collapsed">
getSeed(this.bitLength)), q); // pseudo random 0 < k < q
// Stage 4
if (this.curve) {
// Gost R 34.10-2001 || Gost R 34.10-2012
// Gost R 34.10-2001 || Gost R 34.10-2012
var P = this.P;
var C = mulEC(P, k);
r = mod(getX(C), q);
@ -1552,9 +1552,9 @@ function sign(privateKey, data) // <editor-fold defaultstate="collapsed">
/**
* Algorithm name GOST R 34.10<br><br>
*
*
* The verify method returns signature verification for the supplied publicKey.<br>
*
*
* @memberOf GostSign
* @method sign
* @instance
@ -1578,7 +1578,7 @@ function verify(publicKey, signature, data) // <editor-fold defaultstate="collap
signature = swap(signature);
var zetta = to2(signature);
// Swap bytes for CryptoPro algorithm
s = zetta[1]; // first 32 octets contain the big-endian representation of s
s = zetta[1]; // first 32 octets contain the big-endian representation of s
r = zetta[0]; // and second 32 octets contain the big-endian representation of r
}
if (compare(r, q) >= 0 || compare(s, q) >= 0)
@ -1597,13 +1597,13 @@ function verify(publicKey, signature, data) // <editor-fold defaultstate="collap
var z2 = sub(q, mod(mul(r, v), q));
// Stage 6
if (this.curve) {
// Gost R 34.10-2001 || Gost R 34.10-2012
// Gost R 34.10-2001 || Gost R 34.10-2012
var k2 = to2(publicKey),
curve = this.curve,
P = this.P,
x = newFE(curve, k2[0]), // first 32 octets contain the little-endian representation of x
y = newFE(curve, k2[1]), // and second 32 octets contain the little-endian representation of y.
Q = new newEC(curve, x, y); // This corresponds to the binary representation of (<y>256||<x>256)
Q = new newEC(curve, x, y); // This corresponds to the binary representation of (<y>256||<x>256)
var C = mulTwoEC(P, z1, Q, z2);
var R = mod(getX(C), q);
} else {
@ -1618,10 +1618,10 @@ function verify(publicKey, signature, data) // <editor-fold defaultstate="collap
/**
* Algorithm name GOST R 34.10<br><br>
*
* The generateKey method returns a new generated key pair using the specified
*
* The generateKey method returns a new generated key pair using the specified
* AlgorithmIdentifier.
*
*
* @memberOf GostSign
* @method generateKey
* @instance
@ -1664,9 +1664,9 @@ function generateKey() // <editor-fold defaultstate="collapsed">
/**
* Algorithm name GOST R 34.10 mode MASK<br><br>
*
*
* The generateMaskKey method returns a new generated key mask using for wrapping.
*
*
* @memberOf GostSign
* @method generateMaskKey
* @instance
@ -1689,9 +1689,9 @@ function generateMaskKey() // <editor-fold defaultstate="collapsed">
/**
* Algorithm name GOST R 34.10<br><br>
*
*
* Unwrap private key from private key and ukm (mask)
*
*
* @memberOf GostSign
* @method unwrap
* @instance
@ -1714,9 +1714,9 @@ function unwrapKey(baseKey, data) // <editor-fold defaultstate="collapsed">
/**
* Algorithm name GOST R 34.10<br><br>
*
*
* Wrap private key with private key and ukm (mask)
*
*
* @memberOf GostSign
* @method unwrap
* @instance
@ -1739,7 +1739,7 @@ function wrapKey(baseKey, data) // <editor-fold defaultstate="collapsed">
/**
* Algorithm name GOST R 34.10<br><br>
*
*
* @memberOf GostSign
* @method derive
* @instance
@ -1755,36 +1755,36 @@ function derive(baseKey) // <editor-fold defaultstate="collapsed">
var x = mod(atobi(buffer(baseKey)), q);
if (this.curve) {
// 1) Let K(x,y,UKM) = ((UKM*x)(mod q)) . (y.P) (512 bit), where
// x - senders private key (256 bit)
// x.P - senders public key (512 bit)
// y - recipients private key (256 bit)
// y.P - recipients public key (512 bit)
// UKM - non-zero integer, produced as in step 2 p. 6.1 [GOSTR341001]
// P - base point on the elliptic curve (two 256-bit coordinates)
// UKM*x - x multiplied by UKM as integers
// x.P - a multiple point
// 1) Let K(x,y,UKM) = ((UKM*x)(mod q)) . (y.P) (512 bit), where
// x - senders private key (256 bit)
// x.P - senders public key (512 bit)
// y - recipients private key (256 bit)
// y.P - recipients public key (512 bit)
// UKM - non-zero integer, produced as in step 2 p. 6.1 [GOSTR341001]
// P - base point on the elliptic curve (two 256-bit coordinates)
// UKM*x - x multiplied by UKM as integers
// x.P - a multiple point
var K = mulEC(this.peer_Q, mod(mul(ukm, x), q));
k = from2(getX(K), getY(K), // This corresponds to the binary representation of (<y>256||<x>256)
this.bitLength);
} else {
// 1) Let K(x,y) = a^(x*y) (mod p), where
// x - senders private key, a^x - senders public key
// y - recipients private key, a^y - recipients public key
// 1) Let K(x,y) = a^(x*y) (mod p), where
// x - senders private key, a^x - senders public key
// y - recipients private key, a^y - recipients public key
// a, p - parameters
var p = this.p, a = this.a;
k = bitoa(expMod(this.peer_y, x, p));
}
// 2) Calculate a 256-bit hash of K(x,y,UKM):
// 2) Calculate a 256-bit hash of K(x,y,UKM):
// KEK(x,y,UKM) = gostSign (K(x,y,UKM)
return hash.call(this, k);
} // </editor-fold>
/**
* Algorithm name GOST R 34.10<br><br>
*
*
* The deriveBits method returns length bits on baseKey.
*
*
* @memberOf GostSign
* @method deriveBits
* @instance
@ -1806,13 +1806,13 @@ function deriveBits(baseKey, length) // <editor-fold defaultstate="collapsed">
/**
* Algorithm name GOST R 34.10<br><br>
*
*
* The deriveKey method returns 256 bit Key encryption key on baseKey.
*
* This algorithm creates a key encryption key (KEK) using 64 bit UKM,
* the senders private key, and the recipients public key (or the
*
* This algorithm creates a key encryption key (KEK) using 64 bit UKM,
* the senders private key, and the recipients public key (or the
* reverse of the latter pair
*
*
* @memberOf GostSign
* @method deriveKey
* @instance
@ -1831,11 +1831,11 @@ function deriveKey(baseKey) // <editor-fold defaultstate="collapsed">
/**
* Gost R 34.10 universal object<br><br>
*
*
* References: {@link http://tools.ietf.org/html/rfc6986} and {@link http://tools.ietf.org/html/rfc5831}<br><br>
*
*
* Normalized algorithm identifier common parameters:
*
*
* <ul>
* <li><b>name</b> Algorithm name 'GOST R 34.10'</li>
* <li><b>version</b> Algorithm version
@ -1859,9 +1859,9 @@ function deriveKey(baseKey) // <editor-fold defaultstate="collapsed">
* </li>
* <li><b>sBox</b> Paramset sBox for GOST 34.11-94. Used only if version = 1994 or 2001</li>
* </ul>
*
*
* Supported algorithms, modes and parameters:
*
*
* <ul>
* <li>Sign/Verify mode (SIGN)</li>
* <li>DeriveKey/DeriveBits mode (DH)
@ -1897,7 +1897,7 @@ function deriveKey(baseKey) // <editor-fold defaultstate="collapsed">
* </ul>
* </li>
* </ul>
*
*
* @class GostSign
* @param {AlgorithmIndentifier} algorithm
*/
@ -2015,7 +2015,7 @@ function GostSign(algorithm) // <editor-fold defaultstate="collapsed">
}
// Pregenerated seed for key exchange algorithms
if (algorithm.ukm) // Now don't check size
if (algorithm.ukm) // Now don't check size
this.ukm = algorithm.ukm;
} // </editor-fold>