From 23763363bab5c24338c89f7131ebed7921dc5951 Mon Sep 17 00:00:00 2001 From: Philipp Arnold Date: Fri, 10 Dec 2021 23:22:57 +0100 Subject: [PATCH 01/34] Added a JSON to YAML and a YALM to JSON operation --- src/core/config/Categories.json | 4 ++- src/core/operations/JSONToYAML.mjs | 46 ++++++++++++++++++++++++++++++ src/core/operations/YAMLToJSON.mjs | 45 +++++++++++++++++++++++++++++ tests/operations/index.mjs | 1 + tests/operations/tests/YAML.mjs | 42 +++++++++++++++++++++++++++ 5 files changed, 137 insertions(+), 1 deletion(-) create mode 100644 src/core/operations/JSONToYAML.mjs create mode 100644 src/core/operations/YAMLToJSON.mjs create mode 100644 tests/operations/tests/YAML.mjs diff --git a/src/core/config/Categories.json b/src/core/config/Categories.json index 09ee8d15..e35bc851 100644 --- a/src/core/config/Categories.json +++ b/src/core/config/Categories.json @@ -63,7 +63,9 @@ "JSON to CSV", "Avro to JSON", "CBOR Encode", - "CBOR Decode" + "CBOR Decode", + "YAML to JSON", + "JSON to YAML" ] }, { diff --git a/src/core/operations/JSONToYAML.mjs b/src/core/operations/JSONToYAML.mjs new file mode 100644 index 00000000..2c8102e0 --- /dev/null +++ b/src/core/operations/JSONToYAML.mjs @@ -0,0 +1,46 @@ +/** + * @author ccarpo [ccarpo@gmx.net] + * @copyright Crown Copyright 2021 + * @license Apache-2.0 + */ + +import Operation from "../Operation.mjs"; +import OperationError from "../errors/OperationError.mjs"; +import YAML from "yaml"; + +/** + * JSON to YAML operation + */ +class JSONToYAML extends Operation { + + /** + * JSONToYAML constructor + */ + constructor() { + super(); + + this.name = "JSON to YAML"; + this.module = "Default"; + this.description = "Converts a JSON into a YAML"; + this.infoURL = "https://en.wikipedia.org/wiki/YAML"; + this.inputType = "JSON"; + this.outputType = "string"; + this.args = []; + } + + /** + * @param {JSON} input + * @param {Object[]} args + * @returns {string} + */ + run(input, args) { + try { + return YAML.stringify(input); + } catch (err) { + throw new OperationError("Test"); + } + } + +} + +export default JSONToYAML; diff --git a/src/core/operations/YAMLToJSON.mjs b/src/core/operations/YAMLToJSON.mjs new file mode 100644 index 00000000..4f77f4fd --- /dev/null +++ b/src/core/operations/YAMLToJSON.mjs @@ -0,0 +1,45 @@ +/** + * @author ccarpo [ccarpo@gmx.net] + * @copyright Crown Copyright 2021 + * @license Apache-2.0 + */ + +import Operation from "../Operation.mjs"; +import OperationError from "../errors/OperationError.mjs"; +import jsYaml from "js-yaml"; +/** + * YAML to JSON operation + */ +class YAMLToJSON extends Operation { + + /** + * YAMLToJSON constructor + */ + constructor() { + super(); + + this.name = "YAML to JSON"; + this.module = "Default"; + this.description = "Converts a YAML to JSON"; + this.infoURL = "https://en.wikipedia.org/wiki/YAML"; + this.inputType = "string"; + this.outputType = "JSON"; + this.args = []; + } + + /** + * @param {string} input + * @param {Object[]} args + * @returns {JSON} + */ + run(input, args) { + try { + return jsYaml.load(input); + } catch (err) { + throw new OperationError("Unable to parse YAML: " + err); + } + } + +} + +export default YAMLToJSON; diff --git a/tests/operations/index.mjs b/tests/operations/index.mjs index 9add20b9..3f7a7457 100644 --- a/tests/operations/index.mjs +++ b/tests/operations/index.mjs @@ -107,6 +107,7 @@ import "./tests/CBORDecode.mjs"; import "./tests/JA3Fingerprint.mjs"; import "./tests/JA3SFingerprint.mjs"; import "./tests/HASSH.mjs"; +import "./tests/YAML.mjs"; // Cannot test operations that use the File type yet diff --git a/tests/operations/tests/YAML.mjs b/tests/operations/tests/YAML.mjs new file mode 100644 index 00000000..ba72ed43 --- /dev/null +++ b/tests/operations/tests/YAML.mjs @@ -0,0 +1,42 @@ + +/** + * YAML tests. + * + * @author ccarpo [ccarpo@gmx.net] + * + * @copyright Crown Copyright 2018 + * @license Apache-2.0 + */ +import TestRegister from "../../lib/TestRegister.mjs"; + +const EXAMPLE_YAML = `number: 3\nplain: string\nblock: |\n two\n lines`; +const EXAMPLE_JSON = `{ "number": 3, "plain": "string" }`; + +TestRegister.addTests([ + { + name: "YAML to JSON", + input: EXAMPLE_YAML, + expectedOutput: JSON.stringify({ + "number": 3, + "plain": "string", + "block": "two\nlines\n" + }, null, 4), + recipeConfig: [ + { + op: "YAML to JSON", + args: [], + } + ], + }, + { + name: "JSON to YAML", + input: EXAMPLE_JSON, + expectedOutput: `number: 3\nplain: string\n`, + recipeConfig: [ + { + op: "JSON to YAML", + args: [], + } + ], + }, +]); From d2da11c79a59412b3ae480a5c2e05ff4421bd113 Mon Sep 17 00:00:00 2001 From: zhzy0077 Date: Tue, 25 Jul 2023 14:42:43 +0800 Subject: [PATCH 02/34] Support jq. --- package-lock.json | 11 +++++++ package.json | 1 + src/core/config/Categories.json | 1 + src/core/operations/Jq.mjs | 57 +++++++++++++++++++++++++++++++++ 4 files changed, 70 insertions(+) create mode 100644 src/core/operations/Jq.mjs diff --git a/package-lock.json b/package-lock.json index 3cccfa6c..a53ba37e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -45,6 +45,7 @@ "geodesy": "1.1.3", "highlight.js": "^11.7.0", "jimp": "^0.16.13", + "jq-web": "^0.5.1", "jquery": "3.6.4", "js-crc": "^0.2.0", "js-sha3": "^0.8.0", @@ -8662,6 +8663,11 @@ "resolved": "https://registry.npmjs.org/jpeg-js/-/jpeg-js-0.4.4.tgz", "integrity": "sha512-WZzeDOEtTOBK4Mdsar0IqEU5sMr3vSV2RqkAIzUEV2BHnUfKGyswWFPFwK5EeDo93K3FohSHbLAjj0s1Wzd+dg==" }, + "node_modules/jq-web": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/jq-web/-/jq-web-0.5.1.tgz", + "integrity": "sha512-3Fa3E6g3U1O1j46ljy0EM10yRr4txzILga8J7bqOG8F89gZ6Lilz82WG9z6TItWpYEO0YGa4W8yFGj+NMM1xqQ==" + }, "node_modules/jquery": { "version": "3.6.4", "resolved": "https://registry.npmjs.org/jquery/-/jquery-3.6.4.tgz", @@ -19681,6 +19687,11 @@ "resolved": "https://registry.npmjs.org/jpeg-js/-/jpeg-js-0.4.4.tgz", "integrity": "sha512-WZzeDOEtTOBK4Mdsar0IqEU5sMr3vSV2RqkAIzUEV2BHnUfKGyswWFPFwK5EeDo93K3FohSHbLAjj0s1Wzd+dg==" }, + "jq-web": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/jq-web/-/jq-web-0.5.1.tgz", + "integrity": "sha512-3Fa3E6g3U1O1j46ljy0EM10yRr4txzILga8J7bqOG8F89gZ6Lilz82WG9z6TItWpYEO0YGa4W8yFGj+NMM1xqQ==" + }, "jquery": { "version": "3.6.4", "resolved": "https://registry.npmjs.org/jquery/-/jquery-3.6.4.tgz", diff --git a/package.json b/package.json index 45328dd1..7bb14e9b 100644 --- a/package.json +++ b/package.json @@ -127,6 +127,7 @@ "geodesy": "1.1.3", "highlight.js": "^11.7.0", "jimp": "^0.16.13", + "jq-web": "^0.5.1", "jquery": "3.6.4", "js-crc": "^0.2.0", "js-sha3": "^0.8.0", diff --git a/src/core/config/Categories.json b/src/core/config/Categories.json index cf4d91be..3cf600fd 100644 --- a/src/core/config/Categories.json +++ b/src/core/config/Categories.json @@ -422,6 +422,7 @@ "CSS Minify", "XPath expression", "JPath expression", + "Jq", "CSS selector", "PHP Deserialize", "Microsoft Script Decoder", diff --git a/src/core/operations/Jq.mjs b/src/core/operations/Jq.mjs new file mode 100644 index 00000000..38aa5abb --- /dev/null +++ b/src/core/operations/Jq.mjs @@ -0,0 +1,57 @@ +/** + * @author zhzy0077 [zhzy0077@hotmail.com] + * @copyright Crown Copyright 2023 + * @license Apache-2.0 + */ + +import Operation from "../Operation.mjs"; +import OperationError from "../errors/OperationError.mjs"; +import jq from "jq-web"; + +/** + * jq operation + */ +class Jq extends Operation { + + /** + * Jq constructor + */ + constructor() { + super(); + + this.name = "jq"; + this.module = "Code"; + this.description = "jq is a lightweight and flexible command-line JSON processor."; + this.infoURL = "https://github.com/jqlang/jq"; + this.inputType = "JSON"; + this.outputType = "string"; + this.args = [ + { + name: "Query", + type: "string", + value: "" + } + ]; + } + + /** + * @param {JSON} input + * @param {Object[]} args + * @returns {string} + */ + run(input, args) { + const [query] = args; + let result; + + try { + result = jq.json(input, query); + } catch (err) { + throw new OperationError(`Invalid jq expression: ${err.message}`); + } + + return JSON.stringify(result); + } + +} + +export default Jq; From 721061d0548a4b9cc9e1d48aa9043ce5c38e8ef2 Mon Sep 17 00:00:00 2001 From: zhzy0077 Date: Tue, 25 Jul 2023 14:48:03 +0800 Subject: [PATCH 03/34] fix typo. --- src/core/config/Categories.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/config/Categories.json b/src/core/config/Categories.json index 3cf600fd..9283fe65 100644 --- a/src/core/config/Categories.json +++ b/src/core/config/Categories.json @@ -422,7 +422,7 @@ "CSS Minify", "XPath expression", "JPath expression", - "Jq", + "jq", "CSS selector", "PHP Deserialize", "Microsoft Script Decoder", From 7353315baaedb2113cda178d03a88cafc7f02a4e Mon Sep 17 00:00:00 2001 From: ccarpo Date: Tue, 21 Nov 2023 08:56:20 +0100 Subject: [PATCH 04/34] Renamed JSON to Yaml to Beautify JSON --- src/core/config/Categories.json | 2 +- .../operations/{JSONToYAML.mjs => BeautifyYAML.mjs} | 12 ++++++------ src/core/operations/YAMLToJSON.mjs | 2 +- tests/operations/index.mjs | 2 +- .../operations/tests/{YAML.mjs => BeautifyYAML.mjs} | 6 +++--- 5 files changed, 12 insertions(+), 12 deletions(-) rename src/core/operations/{JSONToYAML.mjs => BeautifyYAML.mjs} (76%) rename tests/operations/tests/{YAML.mjs => BeautifyYAML.mjs} (89%) diff --git a/src/core/config/Categories.json b/src/core/config/Categories.json index e35bc851..ce1a639b 100644 --- a/src/core/config/Categories.json +++ b/src/core/config/Categories.json @@ -65,7 +65,7 @@ "CBOR Encode", "CBOR Decode", "YAML to JSON", - "JSON to YAML" + "Beatufiy YAML" ] }, { diff --git a/src/core/operations/JSONToYAML.mjs b/src/core/operations/BeautifyYAML.mjs similarity index 76% rename from src/core/operations/JSONToYAML.mjs rename to src/core/operations/BeautifyYAML.mjs index 2c8102e0..b87573d8 100644 --- a/src/core/operations/JSONToYAML.mjs +++ b/src/core/operations/BeautifyYAML.mjs @@ -9,19 +9,19 @@ import OperationError from "../errors/OperationError.mjs"; import YAML from "yaml"; /** - * JSON to YAML operation + * Beautify YAML operation */ -class JSONToYAML extends Operation { +class BeautifyYAML extends Operation { /** - * JSONToYAML constructor + * BeautifyYAML constructor */ constructor() { super(); - this.name = "JSON to YAML"; + this.name = "Beautify YAML"; this.module = "Default"; - this.description = "Converts a JSON into a YAML"; + this.description = "Format a JSON object into YAML"; this.infoURL = "https://en.wikipedia.org/wiki/YAML"; this.inputType = "JSON"; this.outputType = "string"; @@ -43,4 +43,4 @@ class JSONToYAML extends Operation { } -export default JSONToYAML; +export default BeautifyYAML; diff --git a/src/core/operations/YAMLToJSON.mjs b/src/core/operations/YAMLToJSON.mjs index 4f77f4fd..5b986575 100644 --- a/src/core/operations/YAMLToJSON.mjs +++ b/src/core/operations/YAMLToJSON.mjs @@ -20,7 +20,7 @@ class YAMLToJSON extends Operation { this.name = "YAML to JSON"; this.module = "Default"; - this.description = "Converts a YAML to JSON"; + this.description = "Convert YAML to JSON"; this.infoURL = "https://en.wikipedia.org/wiki/YAML"; this.inputType = "string"; this.outputType = "JSON"; diff --git a/tests/operations/index.mjs b/tests/operations/index.mjs index 3f7a7457..475d6d31 100644 --- a/tests/operations/index.mjs +++ b/tests/operations/index.mjs @@ -107,7 +107,7 @@ import "./tests/CBORDecode.mjs"; import "./tests/JA3Fingerprint.mjs"; import "./tests/JA3SFingerprint.mjs"; import "./tests/HASSH.mjs"; -import "./tests/YAML.mjs"; +import "./tests/BeautifyYAML.mjs"; // Cannot test operations that use the File type yet diff --git a/tests/operations/tests/YAML.mjs b/tests/operations/tests/BeautifyYAML.mjs similarity index 89% rename from tests/operations/tests/YAML.mjs rename to tests/operations/tests/BeautifyYAML.mjs index ba72ed43..f2cc58fb 100644 --- a/tests/operations/tests/YAML.mjs +++ b/tests/operations/tests/BeautifyYAML.mjs @@ -4,7 +4,7 @@ * * @author ccarpo [ccarpo@gmx.net] * - * @copyright Crown Copyright 2018 + * @copyright Crown Copyright 2021 * @license Apache-2.0 */ import TestRegister from "../../lib/TestRegister.mjs"; @@ -29,12 +29,12 @@ TestRegister.addTests([ ], }, { - name: "JSON to YAML", + name: "Beautify YAML", input: EXAMPLE_JSON, expectedOutput: `number: 3\nplain: string\n`, recipeConfig: [ { - op: "JSON to YAML", + op: "Beautify YAML", args: [], } ], From 4255d8d543226969381adc1c6a06f421e76ac6d8 Mon Sep 17 00:00:00 2001 From: ccarpo Date: Tue, 21 Nov 2023 09:19:58 +0100 Subject: [PATCH 05/34] Renamed JSON to Yaml to Beautify JSON --- src/core/config/Categories.json | 2 +- .../operations/{JSONToYAML.mjs => BeautifyYAML.mjs} | 12 ++++++------ src/core/operations/YAMLToJSON.mjs | 2 +- tests/operations/index.mjs | 2 +- .../operations/tests/{YAML.mjs => BeautifyYAML.mjs} | 6 +++--- 5 files changed, 12 insertions(+), 12 deletions(-) rename src/core/operations/{JSONToYAML.mjs => BeautifyYAML.mjs} (76%) rename tests/operations/tests/{YAML.mjs => BeautifyYAML.mjs} (89%) diff --git a/src/core/config/Categories.json b/src/core/config/Categories.json index e35bc851..6e5e7f04 100644 --- a/src/core/config/Categories.json +++ b/src/core/config/Categories.json @@ -65,7 +65,7 @@ "CBOR Encode", "CBOR Decode", "YAML to JSON", - "JSON to YAML" + "Beautify YAML" ] }, { diff --git a/src/core/operations/JSONToYAML.mjs b/src/core/operations/BeautifyYAML.mjs similarity index 76% rename from src/core/operations/JSONToYAML.mjs rename to src/core/operations/BeautifyYAML.mjs index 2c8102e0..b87573d8 100644 --- a/src/core/operations/JSONToYAML.mjs +++ b/src/core/operations/BeautifyYAML.mjs @@ -9,19 +9,19 @@ import OperationError from "../errors/OperationError.mjs"; import YAML from "yaml"; /** - * JSON to YAML operation + * Beautify YAML operation */ -class JSONToYAML extends Operation { +class BeautifyYAML extends Operation { /** - * JSONToYAML constructor + * BeautifyYAML constructor */ constructor() { super(); - this.name = "JSON to YAML"; + this.name = "Beautify YAML"; this.module = "Default"; - this.description = "Converts a JSON into a YAML"; + this.description = "Format a JSON object into YAML"; this.infoURL = "https://en.wikipedia.org/wiki/YAML"; this.inputType = "JSON"; this.outputType = "string"; @@ -43,4 +43,4 @@ class JSONToYAML extends Operation { } -export default JSONToYAML; +export default BeautifyYAML; diff --git a/src/core/operations/YAMLToJSON.mjs b/src/core/operations/YAMLToJSON.mjs index 4f77f4fd..5b986575 100644 --- a/src/core/operations/YAMLToJSON.mjs +++ b/src/core/operations/YAMLToJSON.mjs @@ -20,7 +20,7 @@ class YAMLToJSON extends Operation { this.name = "YAML to JSON"; this.module = "Default"; - this.description = "Converts a YAML to JSON"; + this.description = "Convert YAML to JSON"; this.infoURL = "https://en.wikipedia.org/wiki/YAML"; this.inputType = "string"; this.outputType = "JSON"; diff --git a/tests/operations/index.mjs b/tests/operations/index.mjs index 3f7a7457..475d6d31 100644 --- a/tests/operations/index.mjs +++ b/tests/operations/index.mjs @@ -107,7 +107,7 @@ import "./tests/CBORDecode.mjs"; import "./tests/JA3Fingerprint.mjs"; import "./tests/JA3SFingerprint.mjs"; import "./tests/HASSH.mjs"; -import "./tests/YAML.mjs"; +import "./tests/BeautifyYAML.mjs"; // Cannot test operations that use the File type yet diff --git a/tests/operations/tests/YAML.mjs b/tests/operations/tests/BeautifyYAML.mjs similarity index 89% rename from tests/operations/tests/YAML.mjs rename to tests/operations/tests/BeautifyYAML.mjs index ba72ed43..f2cc58fb 100644 --- a/tests/operations/tests/YAML.mjs +++ b/tests/operations/tests/BeautifyYAML.mjs @@ -4,7 +4,7 @@ * * @author ccarpo [ccarpo@gmx.net] * - * @copyright Crown Copyright 2018 + * @copyright Crown Copyright 2021 * @license Apache-2.0 */ import TestRegister from "../../lib/TestRegister.mjs"; @@ -29,12 +29,12 @@ TestRegister.addTests([ ], }, { - name: "JSON to YAML", + name: "Beautify YAML", input: EXAMPLE_JSON, expectedOutput: `number: 3\nplain: string\n`, recipeConfig: [ { - op: "JSON to YAML", + op: "Beautify YAML", args: [], } ], From cc21fe18ca450e05a8e71c1d1c0b58c460127d94 Mon Sep 17 00:00:00 2001 From: ccarpo Date: Tue, 21 Nov 2023 09:24:54 +0100 Subject: [PATCH 06/34] fixed typo. --- src/core/config/Categories.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/config/Categories.json b/src/core/config/Categories.json index ce1a639b..6e5e7f04 100644 --- a/src/core/config/Categories.json +++ b/src/core/config/Categories.json @@ -65,7 +65,7 @@ "CBOR Encode", "CBOR Decode", "YAML to JSON", - "Beatufiy YAML" + "Beautify YAML" ] }, { From fb3c36af85a528ee2728a051b931c3bcba6d1ecb Mon Sep 17 00:00:00 2001 From: JSCU-CNI <121175071+JSCU-CNI@users.noreply.github.com> Date: Wed, 24 Jul 2024 14:23:40 +0200 Subject: [PATCH 07/34] Add fingerprints to 'Parse X.509 certificate' operation --- src/core/operations/ParseX509Certificate.mjs | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/core/operations/ParseX509Certificate.mjs b/src/core/operations/ParseX509Certificate.mjs index 11e63424..cdd1e9c7 100644 --- a/src/core/operations/ParseX509Certificate.mjs +++ b/src/core/operations/ParseX509Certificate.mjs @@ -6,7 +6,8 @@ import r from "jsrsasign"; import { fromBase64 } from "../lib/Base64.mjs"; -import { toHex } from "../lib/Hex.mjs"; +import { runHash } from "../lib/Hash.mjs"; +import { fromHex, toHex } from "../lib/Hex.mjs"; import { formatByteStr, formatDnObj } from "../lib/PublicKey.mjs"; import Operation from "../Operation.mjs"; import Utils from "../Utils.mjs"; @@ -81,7 +82,8 @@ class ParseX509Certificate extends Operation { } if (undefinedInputFormat) throw "Undefined input format"; - const sn = cert.getSerialNumberHex(), + const hex = Utils.strToArrayBuffer(Utils.byteArrayToChars(fromHex(cert.hex))), + sn = cert.getSerialNumberHex(), issuer = cert.getIssuer(), subject = cert.getSubject(), pk = cert.getPublicKey(), @@ -191,6 +193,10 @@ Issuer ${issuerStr} Subject ${subjectStr} +Fingerprints + MD5: ${runHash("md5", hex)} + SHA1: ${runHash("sha1", hex)} + SHA256: ${runHash("sha256", hex)} Public Key ${pkStr.slice(0, -1)} Certificate Signature From a1647b02cb2c59e4da3706c71ac4f3e685d2aa25 Mon Sep 17 00:00:00 2001 From: flakjacket Date: Fri, 20 Sep 2024 15:46:04 +0200 Subject: [PATCH 08/34] Initial SM2 changes --- src/core/config/Categories.json | 3 +- src/core/operations/SM2Encrypt.mjs | 210 +++++++++++++++++++++++++++++ 2 files changed, 212 insertions(+), 1 deletion(-) create mode 100644 src/core/operations/SM2Encrypt.mjs diff --git a/src/core/config/Categories.json b/src/core/config/Categories.json index bebdd6a5..31618ab3 100644 --- a/src/core/config/Categories.json +++ b/src/core/config/Categories.json @@ -189,7 +189,8 @@ "Parse SSH Host Key", "Parse CSR", "Public Key from Certificate", - "Public Key from Private Key" + "Public Key from Private Key", + "SM2 Encrypt" ] }, { diff --git a/src/core/operations/SM2Encrypt.mjs b/src/core/operations/SM2Encrypt.mjs new file mode 100644 index 00000000..29a6bbc6 --- /dev/null +++ b/src/core/operations/SM2Encrypt.mjs @@ -0,0 +1,210 @@ +/** + * @author flakjacket95 [dflack95@gmail.com] + * @copyright Crown Copyright 2024 + * @license Apache-2.0 + */ + +import Operation from "../Operation.mjs"; +import OperationError from "../errors/OperationError.mjs"; +import { fromHex } from "../lib/Hex.mjs"; +import { toBase64 } from "../lib/Base64.mjs"; +import Utils from "../Utils.mjs"; +import Sm3 from "crypto-api/src/hasher/sm3.mjs"; +import {toHex} from "crypto-api/src/encoder/hex.mjs"; +//import { ECCurveFp } from "jsrsasign"; +import r from "jsrsasign"; + +/** + * SM2 Encrypt operation + */ +class SM2Encrypt extends Operation { + + /** + * SM2Encrypt constructor + */ + constructor() { + super(); + + this.name = "SM2 Encrypt"; + this.module = "Ciphers"; + this.description = "Encrypts a message utilizing the SM2 standard"; + this.infoURL = ""; // Usually a Wikipedia link. Remember to remove localisation (i.e. https://wikipedia.org/etc rather than https://en.wikipedia.org/etc) + this.inputType = "ArrayBuffer"; + this.outputType = "string"; + + this.args = [ + { + name: "Public Key X", + type: "string", + value: "DEADBEEF" + }, + { + name: "Public Key Y", + type: "string", + value: "DEADBEEF" + }, + { + "name": "Output Format", + "type": "option", + "value": ["C1C3C2", "C1C2C3"] + }, + { + name: "Curve", + type: "option", + "value": ["sm2p256v1"] + } + ]; + this.ecParams = null; + this.rng = new r.SecureRandom(); + /* + For any additional curve definitions utilized by SM2, add another block like the below for that curve, then add the curve name to the Curve selection dropdown + */ + r.crypto.ECParameterDB.regist( + 'sm2p256v1', // name / p = 2**256 - 2**224 - 2**96 + 2**64 - 1 + 256, + 'FFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000FFFFFFFFFFFFFFFF', // p + 'FFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000FFFFFFFFFFFFFFFC', // a + '28E9FA9E9D9F5E344D5A9E4BCF6509A7F39789F515AB8F92DDBCBD414D940E93', // b + 'FFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFF7203DF6B21C6052B53BBF40939D54123', // n + '1', // h + '32C4AE2C1F1981195F9904466A39C9948FE30BBFF2660BE1715A4589334C74C7', // gx + 'BC3736A2F4F6779C59BDCEE36B692153D0A9877CC62A474002DF32E52139F0A0', // gy + [] + ) // alias + } + + /** + * @param {ArrayBuffer} input + * @param {Object[]} args + * @returns {byteArray} + */ + run(input, args) { + const [privateKeyX, privateKeyY, outputFormat, curveName] = args; + + this.outputFormat = outputFormat; + + this.ecParams = r.crypto.ECParameterDB.getByName(curveName); + + this.publicKey = this.ecParams.curve.decodePointHex("04" + privateKeyX + privateKeyY); + + if (this.publicKey.isInfinity()) { + throw new OperationError("Invalid Public Key"); + } + + var result = this.encrypt(new Uint8Array(input)) + + return result + } + + /** + * Highlight SM2 Encrypt + * + * @param {Object[]} pos + * @param {number} pos[].start + * @param {number} pos[].end + * @param {Object[]} args + * @returns {Object[]} pos + */ + highlight(pos, args) { + const [privateKeyX, privateKeyY, outputFormat, curveName] = args; + var num = pos[0].end - pos[0].start + var adjust = 128 + if (outputFormat == "C1C3C2") { + adjust = 192 + } + pos[0].start = Math.ceil(pos[0].start + adjust); + pos[0].end = Math.floor(pos[0].end + adjust + num); + return pos; + } + + encrypt(input) { + const n = this.ecParams.n + const G = this.ecParams.G + + var k = this.generatePublicKey(); + var c1 = G.multiply(k); + + var bic1X = c1.getX().toBigInteger(); + var bic1Y = c1.getY().toBigInteger(); + + var charlen = this.ecParams.keycharlen; + var hexC1X = ("0000000000" + bic1X.toString(16)).slice(- charlen); + var hexC1Y = ("0000000000" + bic1Y.toString(16)).slice(- charlen); + + const p2 = this.publicKey.multiply(k); + + var c3 = this.c3(p2, input); + + var key = this.kdf(p2, input.byteLength); + + for (let i = 0; i < input.byteLength; i++) { + input[i] ^= Utils.ord(key[i]); + } + var c2 = Buffer.from(input).toString('hex'); + + if (this.outputFormat == "C1C3C2") { + return hexC1X + hexC1Y + c3 + c2; + } else { + return hexC1X + hexC1Y + c2 + c3; + } + } + + getBigRandom(limit) { + return new r.BigInteger(limit.bitLength(), this.rng) + .mod(limit.subtract(r.BigInteger.ONE)) + .add(r.BigInteger.ONE); + } + + generatePublicKey() { + const n = this.ecParams.n; + var k = this.getBigRandom(n); + return k; + } + + kdf(p2, len) { + var biX = p2.getX().toBigInteger(); + var biY = p2.getY().toBigInteger(); + + var charlen = this.ecParams.keycharlen; + var hX = ("0000000000" + biX.toString(16)).slice(- charlen); + var hY = ("0000000000" + biY.toString(16)).slice(- charlen); + + var total = Math.ceil(len / 32) + 1; + var cnt = 1; + + var keyMaterial = "" + + while (cnt < total) { + var num = Utils.intToByteArray(cnt, 4, "big"); + var overall = fromHex(hX).concat(fromHex(hY)).concat(num) + keyMaterial += this.sm3(overall); + cnt++; + } + + return keyMaterial + } + + c3(p2, input) { + var biX = p2.getX().toBigInteger(); + var biY = p2.getY().toBigInteger(); + + var charlen = this.ecParams.keycharlen; + var hX = ("0000000000" + biX.toString(16)).slice(- charlen); + var hY = ("0000000000" + biY.toString(16)).slice(- charlen); + + var overall = fromHex(hX).concat(Array.from(input)).concat(fromHex(hY)); + + return toHex(this.sm3(overall)); + + } + + sm3(data) { + var hashData = Utils.arrayBufferToStr(Uint8Array.from(data).buffer, false); + const hasher = new Sm3(); + hasher.update(hashData); + return hasher.finalize(); + } + +} + +export default SM2Encrypt; From 99ba6b487cbbed094b79ea3252d70f201b64cb91 Mon Sep 17 00:00:00 2001 From: Dan Flack Date: Fri, 20 Sep 2024 16:20:15 +0200 Subject: [PATCH 09/34] Add comments, docs, and some additional restructuring --- src/core/operations/SM2Encrypt.mjs | 103 +++++++++++++++++++++-------- 1 file changed, 76 insertions(+), 27 deletions(-) diff --git a/src/core/operations/SM2Encrypt.mjs b/src/core/operations/SM2Encrypt.mjs index 29a6bbc6..e34288bd 100644 --- a/src/core/operations/SM2Encrypt.mjs +++ b/src/core/operations/SM2Encrypt.mjs @@ -80,11 +80,12 @@ class SM2Encrypt extends Operation { */ run(input, args) { const [privateKeyX, privateKeyY, outputFormat, curveName] = args; - this.outputFormat = outputFormat; - this.ecParams = r.crypto.ECParameterDB.getByName(curveName); - + /* + * TODO: This needs some additional length validation; and checking for errors in the decoding process + * TODO: Can probably support other public key encoding methods here as well in the future + */ this.publicKey = this.ecParams.curve.decodePointHex("04" + privateKeyX + privateKeyY); if (this.publicKey.isInfinity()) { @@ -92,7 +93,6 @@ class SM2Encrypt extends Operation { } var result = this.encrypt(new Uint8Array(input)) - return result } @@ -117,31 +117,43 @@ class SM2Encrypt extends Operation { return pos; } + /** + * Main encryption function; takes user input, processes encryption and returns the result in hex (with the components arranged as configured by the user args) + * + * @param {*} input + * @returns {string} + */ encrypt(input) { - const n = this.ecParams.n const G = this.ecParams.G - + + /* + * Compute a new, random public key along the same elliptic curve to form the starting point for our encryption process (record the resulting X and Y as hex to provide as part of the operation output) + * k: Randomly generated BigInteger + * c1: Result of dotting our curve generator point `G` with the value of `k` + */ var k = this.generatePublicKey(); var c1 = G.multiply(k); - - var bic1X = c1.getX().toBigInteger(); - var bic1Y = c1.getY().toBigInteger(); - - var charlen = this.ecParams.keycharlen; - var hexC1X = ("0000000000" + bic1X.toString(16)).slice(- charlen); - var hexC1Y = ("0000000000" + bic1Y.toString(16)).slice(- charlen); + const [hexC1X, hexC1Y] = this.getPointAsHex(c1); const p2 = this.publicKey.multiply(k); + /* + * Compute the C3 SM3 hash before we transform the array + */ var c3 = this.c3(p2, input); + /* + * Genreate a proper length encryption key, XOR iteratively, and convert newly encrypted data to hex + */ var key = this.kdf(p2, input.byteLength); - for (let i = 0; i < input.byteLength; i++) { input[i] ^= Utils.ord(key[i]); } var c2 = Buffer.from(input).toString('hex'); + /* + * Check user input specs; order the output components as selected + */ if (this.outputFormat == "C1C3C2") { return hexC1X + hexC1Y + c3 + c2; } else { @@ -149,25 +161,39 @@ class SM2Encrypt extends Operation { } } + /** + * Generates a large random number + * + * @param {*} limit + * @returns + */ getBigRandom(limit) { return new r.BigInteger(limit.bitLength(), this.rng) .mod(limit.subtract(r.BigInteger.ONE)) .add(r.BigInteger.ONE); } + /** + * Helper function for generating a large random K number; utilized for generating our initial C1 point + * TODO: Do we need to do any sort of validation on the resulting k values? + * + * @returns {BigInteger} + */ generatePublicKey() { const n = this.ecParams.n; var k = this.getBigRandom(n); return k; } + /** + * SM2 Key Derivation Function (KDF); Takes P2 point, and generates a key material stream large enough to encrypt all of the input data + * + * @param {*} p2 + * @param {*} len + * @returns {string} + */ kdf(p2, len) { - var biX = p2.getX().toBigInteger(); - var biY = p2.getY().toBigInteger(); - - var charlen = this.ecParams.keycharlen; - var hX = ("0000000000" + biX.toString(16)).slice(- charlen); - var hY = ("0000000000" + biY.toString(16)).slice(- charlen); + const [hX, hY] = this.getPointAsHex(p2); var total = Math.ceil(len / 32) + 1; var cnt = 1; @@ -180,17 +206,18 @@ class SM2Encrypt extends Operation { keyMaterial += this.sm3(overall); cnt++; } - return keyMaterial } + /** + * Calculates the C3 component of our final encrypted payload; which is the SM3 hash of the P2 point and the original, unencrypted input data + * + * @param {*} p2 + * @param {*} input + * @returns {string} + */ c3(p2, input) { - var biX = p2.getX().toBigInteger(); - var biY = p2.getY().toBigInteger(); - - var charlen = this.ecParams.keycharlen; - var hX = ("0000000000" + biX.toString(16)).slice(- charlen); - var hY = ("0000000000" + biY.toString(16)).slice(- charlen); + const [hX, hY] = this.getPointAsHex(p2); var overall = fromHex(hX).concat(Array.from(input)).concat(fromHex(hY)); @@ -198,6 +225,12 @@ class SM2Encrypt extends Operation { } + /** + * SM3 setup helper function; takes input data as an array, processes the hash and returns the result + * + * @param {*} data + * @returns {string} + */ sm3(data) { var hashData = Utils.arrayBufferToStr(Uint8Array.from(data).buffer, false); const hasher = new Sm3(); @@ -205,6 +238,22 @@ class SM2Encrypt extends Operation { return hasher.finalize(); } + /** + * Utility function, returns an elliptic curve points X and Y values as hex; + * + * @param {EcPointFp} point + * @returns {[]} + */ + getPointAsHex(point) { + var biX = point.getX().toBigInteger(); + var biY = point.getY().toBigInteger(); + + var charlen = this.ecParams.keycharlen; + var hX = ("0000000000" + biX.toString(16)).slice(- charlen); + var hY = ("0000000000" + biY.toString(16)).slice(- charlen); + return [hX, hY] + } + } export default SM2Encrypt; From 54cfb1714555c395138aa52a66351c3337512c05 Mon Sep 17 00:00:00 2001 From: Dan Flack Date: Fri, 20 Sep 2024 19:17:00 +0200 Subject: [PATCH 10/34] Initial migration to library; add decryption operation --- src/core/config/Categories.json | 3 +- src/core/lib/SM2.mjs | 232 +++++++++++++++++++++++++++++ src/core/operations/SM2Decrypt.mjs | 65 ++++++++ src/core/operations/SM2Encrypt.mjs | 175 +--------------------- 4 files changed, 306 insertions(+), 169 deletions(-) create mode 100644 src/core/lib/SM2.mjs create mode 100644 src/core/operations/SM2Decrypt.mjs diff --git a/src/core/config/Categories.json b/src/core/config/Categories.json index 31618ab3..e8b7d202 100644 --- a/src/core/config/Categories.json +++ b/src/core/config/Categories.json @@ -190,7 +190,8 @@ "Parse CSR", "Public Key from Certificate", "Public Key from Private Key", - "SM2 Encrypt" + "SM2 Encrypt", + "SM2 Decrypt" ] }, { diff --git a/src/core/lib/SM2.mjs b/src/core/lib/SM2.mjs new file mode 100644 index 00000000..69bcaca1 --- /dev/null +++ b/src/core/lib/SM2.mjs @@ -0,0 +1,232 @@ +/** + * Utilities and operations utilized for SM2 encryption and decryption + * @author flakjacket95 [dflack95@gmail.com] + * @copyright Crown Copyright 2024 + * @license Apache-2.0 + */ + +import { fromHex } from "../lib/Hex.mjs"; +import Utils from "../Utils.mjs"; +import Sm3 from "crypto-api/src/hasher/sm3.mjs"; +import {toHex} from "crypto-api/src/encoder/hex.mjs"; +import r from "jsrsasign"; + +export class SM2 { + constructor(curve, format) { + this.ecParams = null; + this.rng = new r.SecureRandom(); + /* + For any additional curve definitions utilized by SM2, add another block like the below for that curve, then add the curve name to the Curve selection dropdown + */ + r.crypto.ECParameterDB.regist( + 'sm2p256v1', // name / p = 2**256 - 2**224 - 2**96 + 2**64 - 1 + 256, + 'FFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000FFFFFFFFFFFFFFFF', // p + 'FFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000FFFFFFFFFFFFFFFC', // a + '28E9FA9E9D9F5E344D5A9E4BCF6509A7F39789F515AB8F92DDBCBD414D940E93', // b + 'FFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFF7203DF6B21C6052B53BBF40939D54123', // n + '1', // h + '32C4AE2C1F1981195F9904466A39C9948FE30BBFF2660BE1715A4589334C74C7', // gx + 'BC3736A2F4F6779C59BDCEE36B692153D0A9877CC62A474002DF32E52139F0A0', // gy + [] + ) // alias + this.ecParams = r.crypto.ECParameterDB.getByName(curve); + + this.format = format; + } + + /** + * Set the public key coordinates for the SM2 class + * + * @param {string} publicKeyX + * @param {string} publicKeyY + */ + setPublicKey(publicKeyX, publicKeyY) { + console.log('Set public key') + /* + * TODO: This needs some additional length validation; and checking for errors in the decoding process + * TODO: Can probably support other public key encoding methods here as well in the future + */ + this.publicKey = this.ecParams.curve.decodePointHex("04" + publicKeyX + publicKeyY); + + if (this.publicKey.isInfinity()) { + throw new OperationError("Invalid Public Key"); + } + } + + /** + * Set the private key value for the SM2 class + * + * @param {string} privateKey + */ + setPrivateKey(privateKey) { + this.privateKey = null; //Somehow take hex input and translate back to a BigInteger??? + } + + /** + * Main encryption function; takes user input, processes encryption and returns the result in hex (with the components arranged as configured by the user args) + * + * @param {*} input + * @returns {string} + */ + encrypt(input) { + const G = this.ecParams.G + + /* + * Compute a new, random public key along the same elliptic curve to form the starting point for our encryption process (record the resulting X and Y as hex to provide as part of the operation output) + * k: Randomly generated BigInteger + * c1: Result of dotting our curve generator point `G` with the value of `k` + */ + var k = this.generatePublicKey(); + var c1 = G.multiply(k); + const [hexC1X, hexC1Y] = this.getPointAsHex(c1); + + /* + * Compute p2 (secret) using the public key, and the chosen k value above + */ + const p2 = this.publicKey.multiply(k); + + /* + * Compute the C3 SM3 hash before we transform the array + */ + var c3 = this.c3(p2, input); + + /* + * Genreate a proper length encryption key, XOR iteratively, and convert newly encrypted data to hex + */ + var key = this.kdf(p2, input.byteLength); + for (let i = 0; i < input.byteLength; i++) { + input[i] ^= Utils.ord(key[i]); + } + var c2 = Buffer.from(input).toString('hex'); + + /* + * Check user input specs; order the output components as selected + */ + if (this.format == "C1C3C2") { + return hexC1X + hexC1Y + c3 + c2; + } else { + return hexC1X + hexC1Y + c2 + c3; + } + } + /** + * Function to decrypt an SM2 encrypted message + * + * @param {*} input + */ + decrypt(input) { + /* + * + */ + var c1 = this.ecParams.curve.decodePointHex("04" + publicKeyX + publicKeyY); + + /* + * Compute the p2 (secret) value by taking the C1 point provided in the encrypted package, and multiplying by the private k value + */ + var p2 = c1.multiply(this.privateKey); + + /* + * Similar to encryption; compute sufficient length key material and XOR the input data to recover the original message + */ + var key = this.kdf(p2, input.byteLength); + for (let i = 0; i < input.byteLength; i++) { + input[i] ^= Utils.ord(key[i]); + } + console.log(input) + //var dec = Buffer.from(input).toString('hex'); + } + + + /** + * Generates a large random number + * + * @param {*} limit + * @returns + */ + getBigRandom(limit) { + return new r.BigInteger(limit.bitLength(), this.rng) + .mod(limit.subtract(r.BigInteger.ONE)) + .add(r.BigInteger.ONE); + } + + /** + * Helper function for generating a large random K number; utilized for generating our initial C1 point + * TODO: Do we need to do any sort of validation on the resulting k values? + * + * @returns {BigInteger} + */ + generatePublicKey() { + const n = this.ecParams.n; + var k = this.getBigRandom(n); + return k; + } + + /** + * SM2 Key Derivation Function (KDF); Takes P2 point, and generates a key material stream large enough to encrypt all of the input data + * + * @param {*} p2 + * @param {*} len + * @returns {string} + */ + kdf(p2, len) { + const [hX, hY] = this.getPointAsHex(p2); + + var total = Math.ceil(len / 32) + 1; + var cnt = 1; + + var keyMaterial = "" + + while (cnt < total) { + var num = Utils.intToByteArray(cnt, 4, "big"); + var overall = fromHex(hX).concat(fromHex(hY)).concat(num) + keyMaterial += this.sm3(overall); + cnt++; + } + return keyMaterial + } + + /** + * Calculates the C3 component of our final encrypted payload; which is the SM3 hash of the P2 point and the original, unencrypted input data + * + * @param {*} p2 + * @param {*} input + * @returns {string} + */ + c3(p2, input) { + const [hX, hY] = this.getPointAsHex(p2); + + var overall = fromHex(hX).concat(Array.from(input)).concat(fromHex(hY)); + + return toHex(this.sm3(overall)); + + } + + /** + * SM3 setup helper function; takes input data as an array, processes the hash and returns the result + * + * @param {*} data + * @returns {string} + */ + sm3(data) { + var hashData = Utils.arrayBufferToStr(Uint8Array.from(data).buffer, false); + const hasher = new Sm3(); + hasher.update(hashData); + return hasher.finalize(); + } + + /** + * Utility function, returns an elliptic curve points X and Y values as hex; + * + * @param {EcPointFp} point + * @returns {[]} + */ + getPointAsHex(point) { + var biX = point.getX().toBigInteger(); + var biY = point.getY().toBigInteger(); + + var charlen = this.ecParams.keycharlen; + var hX = ("0000000000" + biX.toString(16)).slice(- charlen); + var hY = ("0000000000" + biY.toString(16)).slice(- charlen); + return [hX, hY] + } +} \ No newline at end of file diff --git a/src/core/operations/SM2Decrypt.mjs b/src/core/operations/SM2Decrypt.mjs new file mode 100644 index 00000000..cf77892d --- /dev/null +++ b/src/core/operations/SM2Decrypt.mjs @@ -0,0 +1,65 @@ +/** + * @author flakjacket95 [dflack95@gmail.com] + * @copyright Crown Copyright 2024 + * @license Apache-2.0 + */ + +import Operation from "../Operation.mjs"; +import OperationError from "../errors/OperationError.mjs"; + +import { SM2 } from "../lib/SM2.mjs"; + +/** + * SM2Decrypt operation + */ +class SM2Decrypt extends Operation { + + /** + * SM2Decrypt constructor + */ + constructor() { + super(); + + this.name = "SM2 Decrypt"; + this.module = "Crypto"; + this.description = "Decrypts a message utilizing the SM2 standard"; + this.infoURL = ""; // Usually a Wikipedia link. Remember to remove localisation (i.e. https://wikipedia.org/etc rather than https://en.wikipedia.org/etc) + this.inputType = "string"; + this.outputType = "ArrayBuffer"; + this.args = [ + { + name: "Private Key", + type: "string", + value: "DEADBEEF" + }, + { + "name": "Input Format", + "type": "option", + "value": ["C1C3C2", "C1C2C3"] + }, + { + name: "Curve", + type: "option", + "value": ["sm2p256v1"] + } + ]; + } + + /** + * @param {string} input + * @param {Object[]} args + * @returns {ArrayBuffer} + */ + run(input, args) { + const [privateKey, inputFormat, curveName] = args; + + var sm2 = new SM2(curveName, inputFormat); + sm2.setPrivateKey(privateKey); + + var result = sm2.decrypt(new Uint8Array(input)) + return result + } + +} + +export default SM2Decrypt; diff --git a/src/core/operations/SM2Encrypt.mjs b/src/core/operations/SM2Encrypt.mjs index e34288bd..61dbe281 100644 --- a/src/core/operations/SM2Encrypt.mjs +++ b/src/core/operations/SM2Encrypt.mjs @@ -6,12 +6,13 @@ import Operation from "../Operation.mjs"; import OperationError from "../errors/OperationError.mjs"; + +import { SM2 } from "../lib/SM2.mjs"; + import { fromHex } from "../lib/Hex.mjs"; -import { toBase64 } from "../lib/Base64.mjs"; import Utils from "../Utils.mjs"; import Sm3 from "crypto-api/src/hasher/sm3.mjs"; import {toHex} from "crypto-api/src/encoder/hex.mjs"; -//import { ECCurveFp } from "jsrsasign"; import r from "jsrsasign"; /** @@ -54,23 +55,6 @@ class SM2Encrypt extends Operation { "value": ["sm2p256v1"] } ]; - this.ecParams = null; - this.rng = new r.SecureRandom(); - /* - For any additional curve definitions utilized by SM2, add another block like the below for that curve, then add the curve name to the Curve selection dropdown - */ - r.crypto.ECParameterDB.regist( - 'sm2p256v1', // name / p = 2**256 - 2**224 - 2**96 + 2**64 - 1 - 256, - 'FFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000FFFFFFFFFFFFFFFF', // p - 'FFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000FFFFFFFFFFFFFFFC', // a - '28E9FA9E9D9F5E344D5A9E4BCF6509A7F39789F515AB8F92DDBCBD414D940E93', // b - 'FFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFF7203DF6B21C6052B53BBF40939D54123', // n - '1', // h - '32C4AE2C1F1981195F9904466A39C9948FE30BBFF2660BE1715A4589334C74C7', // gx - 'BC3736A2F4F6779C59BDCEE36B692153D0A9877CC62A474002DF32E52139F0A0', // gy - [] - ) // alias } /** @@ -79,20 +63,13 @@ class SM2Encrypt extends Operation { * @returns {byteArray} */ run(input, args) { - const [privateKeyX, privateKeyY, outputFormat, curveName] = args; + const [publicKeyX, publicKeyY, outputFormat, curveName] = args; this.outputFormat = outputFormat; - this.ecParams = r.crypto.ECParameterDB.getByName(curveName); - /* - * TODO: This needs some additional length validation; and checking for errors in the decoding process - * TODO: Can probably support other public key encoding methods here as well in the future - */ - this.publicKey = this.ecParams.curve.decodePointHex("04" + privateKeyX + privateKeyY); - if (this.publicKey.isInfinity()) { - throw new OperationError("Invalid Public Key"); - } + var sm2 = new SM2(curveName, outputFormat); + sm2.setPublicKey(publicKeyX, publicKeyY); - var result = this.encrypt(new Uint8Array(input)) + var result = sm2.encrypt(new Uint8Array(input)) return result } @@ -116,144 +93,6 @@ class SM2Encrypt extends Operation { pos[0].end = Math.floor(pos[0].end + adjust + num); return pos; } - - /** - * Main encryption function; takes user input, processes encryption and returns the result in hex (with the components arranged as configured by the user args) - * - * @param {*} input - * @returns {string} - */ - encrypt(input) { - const G = this.ecParams.G - - /* - * Compute a new, random public key along the same elliptic curve to form the starting point for our encryption process (record the resulting X and Y as hex to provide as part of the operation output) - * k: Randomly generated BigInteger - * c1: Result of dotting our curve generator point `G` with the value of `k` - */ - var k = this.generatePublicKey(); - var c1 = G.multiply(k); - const [hexC1X, hexC1Y] = this.getPointAsHex(c1); - - const p2 = this.publicKey.multiply(k); - - /* - * Compute the C3 SM3 hash before we transform the array - */ - var c3 = this.c3(p2, input); - - /* - * Genreate a proper length encryption key, XOR iteratively, and convert newly encrypted data to hex - */ - var key = this.kdf(p2, input.byteLength); - for (let i = 0; i < input.byteLength; i++) { - input[i] ^= Utils.ord(key[i]); - } - var c2 = Buffer.from(input).toString('hex'); - - /* - * Check user input specs; order the output components as selected - */ - if (this.outputFormat == "C1C3C2") { - return hexC1X + hexC1Y + c3 + c2; - } else { - return hexC1X + hexC1Y + c2 + c3; - } - } - - /** - * Generates a large random number - * - * @param {*} limit - * @returns - */ - getBigRandom(limit) { - return new r.BigInteger(limit.bitLength(), this.rng) - .mod(limit.subtract(r.BigInteger.ONE)) - .add(r.BigInteger.ONE); - } - - /** - * Helper function for generating a large random K number; utilized for generating our initial C1 point - * TODO: Do we need to do any sort of validation on the resulting k values? - * - * @returns {BigInteger} - */ - generatePublicKey() { - const n = this.ecParams.n; - var k = this.getBigRandom(n); - return k; - } - - /** - * SM2 Key Derivation Function (KDF); Takes P2 point, and generates a key material stream large enough to encrypt all of the input data - * - * @param {*} p2 - * @param {*} len - * @returns {string} - */ - kdf(p2, len) { - const [hX, hY] = this.getPointAsHex(p2); - - var total = Math.ceil(len / 32) + 1; - var cnt = 1; - - var keyMaterial = "" - - while (cnt < total) { - var num = Utils.intToByteArray(cnt, 4, "big"); - var overall = fromHex(hX).concat(fromHex(hY)).concat(num) - keyMaterial += this.sm3(overall); - cnt++; - } - return keyMaterial - } - - /** - * Calculates the C3 component of our final encrypted payload; which is the SM3 hash of the P2 point and the original, unencrypted input data - * - * @param {*} p2 - * @param {*} input - * @returns {string} - */ - c3(p2, input) { - const [hX, hY] = this.getPointAsHex(p2); - - var overall = fromHex(hX).concat(Array.from(input)).concat(fromHex(hY)); - - return toHex(this.sm3(overall)); - - } - - /** - * SM3 setup helper function; takes input data as an array, processes the hash and returns the result - * - * @param {*} data - * @returns {string} - */ - sm3(data) { - var hashData = Utils.arrayBufferToStr(Uint8Array.from(data).buffer, false); - const hasher = new Sm3(); - hasher.update(hashData); - return hasher.finalize(); - } - - /** - * Utility function, returns an elliptic curve points X and Y values as hex; - * - * @param {EcPointFp} point - * @returns {[]} - */ - getPointAsHex(point) { - var biX = point.getX().toBigInteger(); - var biY = point.getY().toBigInteger(); - - var charlen = this.ecParams.keycharlen; - var hX = ("0000000000" + biX.toString(16)).slice(- charlen); - var hY = ("0000000000" + biY.toString(16)).slice(- charlen); - return [hX, hY] - } - } export default SM2Encrypt; From 857d3b6d17bcfcd0da1eb68f959abe23948849c1 Mon Sep 17 00:00:00 2001 From: Dan Flack Date: Fri, 20 Sep 2024 21:00:05 +0200 Subject: [PATCH 11/34] Fully functional encrypt/decrypt --- src/core/lib/SM2.mjs | 41 +++++++++++++++++++++--------- src/core/operations/SM2Decrypt.mjs | 3 ++- 2 files changed, 31 insertions(+), 13 deletions(-) diff --git a/src/core/lib/SM2.mjs b/src/core/lib/SM2.mjs index 69bcaca1..74b8639d 100644 --- a/src/core/lib/SM2.mjs +++ b/src/core/lib/SM2.mjs @@ -5,6 +5,7 @@ * @license Apache-2.0 */ +import OperationError from "../errors/OperationError.mjs"; import { fromHex } from "../lib/Hex.mjs"; import Utils from "../Utils.mjs"; import Sm3 from "crypto-api/src/hasher/sm3.mjs"; @@ -42,7 +43,6 @@ export class SM2 { * @param {string} publicKeyY */ setPublicKey(publicKeyX, publicKeyY) { - console.log('Set public key') /* * TODO: This needs some additional length validation; and checking for errors in the decoding process * TODO: Can probably support other public key encoding methods here as well in the future @@ -59,8 +59,8 @@ export class SM2 { * * @param {string} privateKey */ - setPrivateKey(privateKey) { - this.privateKey = null; //Somehow take hex input and translate back to a BigInteger??? + setPrivateKey(privateKeyHex) { + this.privateKey = new r.BigInteger(privateKeyHex, 16); } /** @@ -115,10 +115,21 @@ export class SM2 { * @param {*} input */ decrypt(input) { - /* - * - */ - var c1 = this.ecParams.curve.decodePointHex("04" + publicKeyX + publicKeyY); + var c1X = input.slice(0, 64); + var c1Y = input.slice(64, 128); + + var c3 = "" + var c2 = "" + + if (this.format == "C1C3C2") { + c3 = input.slice(128,192); + c2 = input.slice(192); + } else { + c2 = input.slice(128, -64); + c3 = input.slice(-64); + } + c2 = Uint8Array.from(fromHex(c2)) + var c1 = this.ecParams.curve.decodePointHex("04" + c1X + c1Y); /* * Compute the p2 (secret) value by taking the C1 point provided in the encrypted package, and multiplying by the private k value @@ -128,12 +139,18 @@ export class SM2 { /* * Similar to encryption; compute sufficient length key material and XOR the input data to recover the original message */ - var key = this.kdf(p2, input.byteLength); - for (let i = 0; i < input.byteLength; i++) { - input[i] ^= Utils.ord(key[i]); + var key = this.kdf(p2, c2.byteLength); + + for (let i = 0; i < c2.byteLength; i++) { + c2[i] ^= Utils.ord(key[i]); + } + + var check = this.c3(p2, c2); + if (check === c3) { + return c2.buffer; + } else { + throw new OperationError("Decryption Error -- Computed Hashes Do Not Match"); } - console.log(input) - //var dec = Buffer.from(input).toString('hex'); } diff --git a/src/core/operations/SM2Decrypt.mjs b/src/core/operations/SM2Decrypt.mjs index cf77892d..57e263d1 100644 --- a/src/core/operations/SM2Decrypt.mjs +++ b/src/core/operations/SM2Decrypt.mjs @@ -56,7 +56,8 @@ class SM2Decrypt extends Operation { var sm2 = new SM2(curveName, inputFormat); sm2.setPrivateKey(privateKey); - var result = sm2.decrypt(new Uint8Array(input)) + + var result = sm2.decrypt(input); return result } From 9eff9e501872e8a41c9e18e38905dd4874ad3a9a Mon Sep 17 00:00:00 2001 From: Dan Flack Date: Fri, 20 Sep 2024 21:07:24 +0200 Subject: [PATCH 12/34] Set default paramater indices --- src/core/operations/SM2Decrypt.mjs | 6 ++++-- src/core/operations/SM2Encrypt.mjs | 6 ++++-- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/src/core/operations/SM2Decrypt.mjs b/src/core/operations/SM2Decrypt.mjs index 57e263d1..dcacdc3f 100644 --- a/src/core/operations/SM2Decrypt.mjs +++ b/src/core/operations/SM2Decrypt.mjs @@ -35,12 +35,14 @@ class SM2Decrypt extends Operation { { "name": "Input Format", "type": "option", - "value": ["C1C3C2", "C1C2C3"] + "value": ["C1C3C2", "C1C2C3"], + "defaultIndex": 0 }, { name: "Curve", type: "option", - "value": ["sm2p256v1"] + "value": ["sm2p256v1"], + "defaultIndex": 0 } ]; } diff --git a/src/core/operations/SM2Encrypt.mjs b/src/core/operations/SM2Encrypt.mjs index 61dbe281..fe20e957 100644 --- a/src/core/operations/SM2Encrypt.mjs +++ b/src/core/operations/SM2Encrypt.mjs @@ -47,12 +47,14 @@ class SM2Encrypt extends Operation { { "name": "Output Format", "type": "option", - "value": ["C1C3C2", "C1C2C3"] + "value": ["C1C3C2", "C1C2C3"], + "defaultIndex": 0 }, { name: "Curve", type: "option", - "value": ["sm2p256v1"] + "value": ["sm2p256v1"], + "defaultIndex": 0 } ]; } From 84ce8e6f307c826a5bda17083822a5050d442931 Mon Sep 17 00:00:00 2001 From: flackjacket95 Date: Sat, 21 Sep 2024 11:33:41 +0200 Subject: [PATCH 13/34] Add tests --- tests/operations/index.mjs | 1 + tests/operations/tests/SM2.mjs | 135 +++++++++++++++++++++++++++++++++ 2 files changed, 136 insertions(+) create mode 100644 tests/operations/tests/SM2.mjs diff --git a/tests/operations/index.mjs b/tests/operations/index.mjs index 40ce7a2e..289fadc9 100644 --- a/tests/operations/index.mjs +++ b/tests/operations/index.mjs @@ -139,6 +139,7 @@ import "./tests/SetIntersection.mjs"; import "./tests/SetUnion.mjs"; import "./tests/Shuffle.mjs"; import "./tests/SIGABA.mjs"; +import "./tests/SM2.mjs"; import "./tests/SM4.mjs"; // import "./tests/SplitColourChannels.mjs"; // Cannot test operations that use the File type yet import "./tests/StrUtils.mjs"; diff --git a/tests/operations/tests/SM2.mjs b/tests/operations/tests/SM2.mjs new file mode 100644 index 00000000..278d46a7 --- /dev/null +++ b/tests/operations/tests/SM2.mjs @@ -0,0 +1,135 @@ +/** + * SM2 Tests + * + * @author flakjacket95 [dflack95@gmail.com] + * @copyright Crown Copyright 2024 + * @license Apache-2.0 + */ +import TestRegister from "../../lib/TestRegister.mjs"; + +/* Plaintexts */ + +const SMALL_PLAIN = "I am a small plaintext" +const LARGE_PLAIN = "I am a larger plaintext, that will require the encryption KDF to generate a much larger key to properly encrypt me" + +/* Test Key Parameters */ +const PUBLIC_X = "f7d903cab7925066c31150a92b31e548e63f954f92d01eaa0271fb2a336baef8" +const PUBLIC_Y = "fb0c45e410ef7a6cdae724e6a78dbff52562e97ede009e762b667d9b14adea6c" +const PRIVATE_K = "e74a72505084c3269aa9b696d603e3e08c74c6740212c11a31e26cdfe08bdf6a" + +const CURVE = "sm2p256v1" + +/* Decryption Test Ciphertext*/ + +const CIPHERTEXT_1 = "9a31bc0adb4677cdc4141479e3949572a55c3e6fb52094721f741c2bd2e179aaa87be6263bc1be602e473be3d5de5dce97f8248948b3a7e15f9f67f64aef21575e0c05e6171870a10ff9ab778dbef24267ad90e1a9d47d68f757d57c4816612e9829f804025dea05a511cda39371c22a2828f976f72e" +const CIPHERTEXT_2 = "d3647d68568a2e7a4f8e843286be7bf2b4d80256697d19a73df306ae1a7e6d0364d942e23d2340606e7a2502a838b132f9242587b2ea7e4c207e87242eea8cae68f5ff4da2a95a7f6d350608ae5b6777e1d925bf9c560087af84aba7befba713130106ddb4082d803811bca3864594722f3198d58257fe4ba37f4aa540adf4cb0568bddd2d8140ad3030deea0a87e3198655cc4d22bfc3d73b1c4afec2ff15d68c8d1298d97132cace922ee8a4e41ca288a7e748b77ca94aa81dc283439923ae7939e00898e16fe5111fbe1d928d152b216a" +const CIPHERTEXT_3 = "5f340eeb4398fa8950ee3408d0e3fe34bf7728c9fdb060c94b916891b5c693610274160b52a7132a2bf16ad5cdb57d1e00da2f3ddbd55350729aa9c268b53e40c05ccce9912daa14406e8c132e389484e69757350be25351755dcc6c25c94b3c1a448b2cf8c2017582125eb6cf782055b199a875e966" +const CIPHERTEXT_4 = "0649bac46c3f9fd7fb3b2be4bff27414d634651efd02ca67d8c802bbc5468e77d035c39b581d6b56227f5d87c0b4efbea5032c0761139295ae194b9f1fce698f2f4b51d89fa5554171a1aad2e61fe9de89831aec472ecc5ab178ebf4d2230c1fb94fca03e536b87b9eba6db71ba9939260a08ffd230ca86cb45cf754854222364231bdb8b873791d63ad57a4b3fa5b6375388dc879373f5f1be9051bc5072a8afbec5b7b034e4907aa5bb4b6b1f50e725d09cb6a02e07ce20263005f6c9157ce05d3ea739d231d4f09396fb72aa680884d78" + + +TestRegister.addTests([ + { + name: "SM2 Decrypt: Small Input; Format One", + input: CIPHERTEXT_1, + expectedOutput: SMALL_PLAIN, + recipeConfig: [ + { + "op": "SM2 Decrypt", + "args": [PRIVATE_K, "C1C3C2", CURVE] + } + ] + }, + { + name: "SM2 Decrypt: Large Input; Format One", + input: CIPHERTEXT_2, + expectedOutput: LARGE_PLAIN, + recipeConfig: [ + { + "op": "SM2 Decrypt", + "args": [PRIVATE_K, "C1C3C2", CURVE] + } + ] + }, + { + name: "SM2 Decrypt: Small Input; Format Two", + input: CIPHERTEXT_3, + expectedOutput: SMALL_PLAIN, + recipeConfig: [ + { + "op": "SM2 Decrypt", + "args": [PRIVATE_K, "C1C2C3", CURVE] + } + ] + }, + { + name: "SM2 Decrypt: Large Input; Format Two", + input: CIPHERTEXT_4, + expectedOutput: LARGE_PLAIN, + recipeConfig: [ + { + "op": "SM2 Decrypt", + "args": [PRIVATE_K, "C1C2C3", CURVE] + } + ] + }, + { + name: "SM2 Encrypt And Decrypt: Small Input; Format One", + input: SMALL_PLAIN, + expectedOutput: SMALL_PLAIN, + recipeConfig: [ + { + "op": "SM2 Encrypt", + "args": [PUBLIC_X, PUBLIC_Y, "C1C3C2", CURVE], + }, + { + "op": "SM2 Decrypt", + "args": [PRIVATE_K, "C1C3C2", CURVE] + } + ] + }, + { + name: "SM2 Encrypt And Decrypt: Large Input; Format One", + input: LARGE_PLAIN, + expectedOutput: LARGE_PLAIN, + recipeConfig: [ + { + "op": "SM2 Encrypt", + "args": [PUBLIC_X, PUBLIC_Y, "C1C3C2", CURVE], + }, + { + "op": "SM2 Decrypt", + "args": [PRIVATE_K, "C1C3C2", CURVE] + } + ] + }, + { + name: "SM2 Encrypt And Decrypt: Small Input; Format Two", + input: SMALL_PLAIN, + expectedOutput: SMALL_PLAIN, + recipeConfig: [ + { + "op": "SM2 Encrypt", + "args": [PUBLIC_X, PUBLIC_Y, "C1C2C3", CURVE], + }, + { + "op": "SM2 Decrypt", + "args": [PRIVATE_K, "C1C2C2", CURVE] + } + ] + }, + { + name: "SM2 Encrypt And Decrypt: Large Input; Format Two", + input: LARGE_PLAIN, + expectedOutput: LARGE_PLAIN, + recipeConfig: [ + { + "op": "SM2 Encrypt", + "args": [PUBLIC_X, PUBLIC_Y, "C1C2C3", CURVE], + }, + { + "op": "SM2 Decrypt", + "args": [PRIVATE_K, "C1C2C3", CURVE] + } + ] + }, +]); From 0f16fa0ce167f67b1b839477efd2055ed43a3c97 Mon Sep 17 00:00:00 2001 From: Dan Flack Date: Sat, 21 Sep 2024 11:47:01 +0200 Subject: [PATCH 14/34] Updates for linter --- src/core/lib/SM2.mjs | 45 ++++++++++++++++++++++++++------------------ 1 file changed, 27 insertions(+), 18 deletions(-) diff --git a/src/core/lib/SM2.mjs b/src/core/lib/SM2.mjs index 74b8639d..575f93ea 100644 --- a/src/core/lib/SM2.mjs +++ b/src/core/lib/SM2.mjs @@ -12,7 +12,16 @@ import Sm3 from "crypto-api/src/hasher/sm3.mjs"; import {toHex} from "crypto-api/src/encoder/hex.mjs"; import r from "jsrsasign"; +/** + * SM2 Class for encryption and decryption operations + */ export class SM2 { + /** + * Constructor for SM2 class; sets up with the curve and the output format as specified in user args + * + * @param {*} curve + * @param {*} format + */ constructor(curve, format) { this.ecParams = null; this.rng = new r.SecureRandom(); @@ -20,15 +29,15 @@ export class SM2 { For any additional curve definitions utilized by SM2, add another block like the below for that curve, then add the curve name to the Curve selection dropdown */ r.crypto.ECParameterDB.regist( - 'sm2p256v1', // name / p = 2**256 - 2**224 - 2**96 + 2**64 - 1 + "sm2p256v1", // name / p = 2**256 - 2**224 - 2**96 + 2**64 - 1 256, - 'FFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000FFFFFFFFFFFFFFFF', // p - 'FFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000FFFFFFFFFFFFFFFC', // a - '28E9FA9E9D9F5E344D5A9E4BCF6509A7F39789F515AB8F92DDBCBD414D940E93', // b - 'FFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFF7203DF6B21C6052B53BBF40939D54123', // n - '1', // h - '32C4AE2C1F1981195F9904466A39C9948FE30BBFF2660BE1715A4589334C74C7', // gx - 'BC3736A2F4F6779C59BDCEE36B692153D0A9877CC62A474002DF32E52139F0A0', // gy + "FFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000FFFFFFFFFFFFFFFF", // p + "FFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000FFFFFFFFFFFFFFFC", // a + "28E9FA9E9D9F5E344D5A9E4BCF6509A7F39789F515AB8F92DDBCBD414D940E93", // b + "FFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFF7203DF6B21C6052B53BBF40939D54123", // n + "1", // h + "32C4AE2C1F1981195F9904466A39C9948FE30BBFF2660BE1715A4589334C74C7", // gx + "BC3736A2F4F6779C59BDCEE36B692153D0A9877CC62A474002DF32E52139F0A0", // gy [] ) // alias this.ecParams = r.crypto.ECParameterDB.getByName(curve); @@ -38,9 +47,9 @@ export class SM2 { /** * Set the public key coordinates for the SM2 class - * - * @param {string} publicKeyX - * @param {string} publicKeyY + * + * @param {string} publicKeyX + * @param {string} publicKeyY */ setPublicKey(publicKeyX, publicKeyY) { /* @@ -56,17 +65,17 @@ export class SM2 { /** * Set the private key value for the SM2 class - * - * @param {string} privateKey + * + * @param {string} privateKey */ setPrivateKey(privateKeyHex) { this.privateKey = new r.BigInteger(privateKeyHex, 16); } - + /** * Main encryption function; takes user input, processes encryption and returns the result in hex (with the components arranged as configured by the user args) - * - * @param {*} input + * + * @param {*} input * @returns {string} */ encrypt(input) { @@ -111,8 +120,8 @@ export class SM2 { } /** * Function to decrypt an SM2 encrypted message - * - * @param {*} input + * + * @param {*} input */ decrypt(input) { var c1X = input.slice(0, 64); From f61bdf06c69f34dbaa19b3abd10e69187ca89371 Mon Sep 17 00:00:00 2001 From: Dan Flack Date: Sat, 21 Sep 2024 12:00:37 +0200 Subject: [PATCH 15/34] Additional linter corrections --- src/core/lib/SM2.mjs | 104 ++++++++++++++--------------- src/core/operations/SM2Decrypt.mjs | 8 +-- src/core/operations/SM2Encrypt.mjs | 23 +++---- tests/operations/tests/SM2.mjs | 22 +++--- 4 files changed, 74 insertions(+), 83 deletions(-) diff --git a/src/core/lib/SM2.mjs b/src/core/lib/SM2.mjs index 575f93ea..e8156410 100644 --- a/src/core/lib/SM2.mjs +++ b/src/core/lib/SM2.mjs @@ -19,8 +19,8 @@ export class SM2 { /** * Constructor for SM2 class; sets up with the curve and the output format as specified in user args * - * @param {*} curve - * @param {*} format + * @param {*} curve + * @param {*} format */ constructor(curve, format) { this.ecParams = null; @@ -39,7 +39,7 @@ export class SM2 { "32C4AE2C1F1981195F9904466A39C9948FE30BBFF2660BE1715A4589334C74C7", // gx "BC3736A2F4F6779C59BDCEE36B692153D0A9877CC62A474002DF32E52139F0A0", // gy [] - ) // alias + ); // alias this.ecParams = r.crypto.ECParameterDB.getByName(curve); this.format = format; @@ -79,15 +79,15 @@ export class SM2 { * @returns {string} */ encrypt(input) { - const G = this.ecParams.G + const G = this.ecParams.G; /* * Compute a new, random public key along the same elliptic curve to form the starting point for our encryption process (record the resulting X and Y as hex to provide as part of the operation output) * k: Randomly generated BigInteger * c1: Result of dotting our curve generator point `G` with the value of `k` */ - var k = this.generatePublicKey(); - var c1 = G.multiply(k); + const k = this.generatePublicKey(); + const c1 = G.multiply(k); const [hexC1X, hexC1Y] = this.getPointAsHex(c1); /* @@ -98,21 +98,21 @@ export class SM2 { /* * Compute the C3 SM3 hash before we transform the array */ - var c3 = this.c3(p2, input); + const c3 = this.c3(p2, input); /* * Genreate a proper length encryption key, XOR iteratively, and convert newly encrypted data to hex */ - var key = this.kdf(p2, input.byteLength); + const key = this.kdf(p2, input.byteLength); for (let i = 0; i < input.byteLength; i++) { input[i] ^= Utils.ord(key[i]); } - var c2 = Buffer.from(input).toString('hex'); + const c2 = Buffer.from(input).toString("hex"); /* * Check user input specs; order the output components as selected */ - if (this.format == "C1C3C2") { + if (this.format === "C1C3C2") { return hexC1X + hexC1Y + c3 + c2; } else { return hexC1X + hexC1Y + c2 + c3; @@ -124,37 +124,37 @@ export class SM2 { * @param {*} input */ decrypt(input) { - var c1X = input.slice(0, 64); - var c1Y = input.slice(64, 128); + const c1X = input.slice(0, 64); + const c1Y = input.slice(64, 128); - var c3 = "" - var c2 = "" + let c3 = ""; + let c2 = ""; - if (this.format == "C1C3C2") { - c3 = input.slice(128,192); + if (this.format === "C1C3C2") { + c3 = input.slice(128, 192); c2 = input.slice(192); } else { c2 = input.slice(128, -64); c3 = input.slice(-64); } - c2 = Uint8Array.from(fromHex(c2)) - var c1 = this.ecParams.curve.decodePointHex("04" + c1X + c1Y); + c2 = Uint8Array.from(fromHex(c2)); + const c1 = this.ecParams.curve.decodePointHex("04" + c1X + c1Y); /* * Compute the p2 (secret) value by taking the C1 point provided in the encrypted package, and multiplying by the private k value */ - var p2 = c1.multiply(this.privateKey); + const p2 = c1.multiply(this.privateKey); /* * Similar to encryption; compute sufficient length key material and XOR the input data to recover the original message */ - var key = this.kdf(p2, c2.byteLength); + const key = this.kdf(p2, c2.byteLength); for (let i = 0; i < c2.byteLength; i++) { c2[i] ^= Utils.ord(key[i]); } - var check = this.c3(p2, c2); + const check = this.c3(p2, c2); if (check === c3) { return c2.buffer; } else { @@ -165,9 +165,9 @@ export class SM2 { /** * Generates a large random number - * - * @param {*} limit - * @returns + * + * @param {*} limit + * @returns */ getBigRandom(limit) { return new r.BigInteger(limit.bitLength(), this.rng) @@ -177,51 +177,51 @@ export class SM2 { /** * Helper function for generating a large random K number; utilized for generating our initial C1 point - * TODO: Do we need to do any sort of validation on the resulting k values? - * + * TODO: Do we need to do any sort of validation on the resulting k values? + * * @returns {BigInteger} */ generatePublicKey() { const n = this.ecParams.n; - var k = this.getBigRandom(n); + const k = this.getBigRandom(n); return k; } /** * SM2 Key Derivation Function (KDF); Takes P2 point, and generates a key material stream large enough to encrypt all of the input data - * - * @param {*} p2 - * @param {*} len + * + * @param {*} p2 + * @param {*} len * @returns {string} */ kdf(p2, len) { const [hX, hY] = this.getPointAsHex(p2); - var total = Math.ceil(len / 32) + 1; - var cnt = 1; + const total = Math.ceil(len / 32) + 1; + let cnt = 1; - var keyMaterial = "" + let keyMaterial = ""; while (cnt < total) { - var num = Utils.intToByteArray(cnt, 4, "big"); - var overall = fromHex(hX).concat(fromHex(hY)).concat(num) + const num = Utils.intToByteArray(cnt, 4, "big"); + const overall = fromHex(hX).concat(fromHex(hY)).concat(num); keyMaterial += this.sm3(overall); cnt++; } - return keyMaterial + return keyMaterial; } /** * Calculates the C3 component of our final encrypted payload; which is the SM3 hash of the P2 point and the original, unencrypted input data - * - * @param {*} p2 - * @param {*} input - * @returns {string} + * + * @param {*} p2 + * @param {*} input + * @returns {string} */ c3(p2, input) { const [hX, hY] = this.getPointAsHex(p2); - var overall = fromHex(hX).concat(Array.from(input)).concat(fromHex(hY)); + const overall = fromHex(hX).concat(Array.from(input)).concat(fromHex(hY)); return toHex(this.sm3(overall)); @@ -229,12 +229,12 @@ export class SM2 { /** * SM3 setup helper function; takes input data as an array, processes the hash and returns the result - * - * @param {*} data + * + * @param {*} data * @returns {string} */ sm3(data) { - var hashData = Utils.arrayBufferToStr(Uint8Array.from(data).buffer, false); + const hashData = Utils.arrayBufferToStr(Uint8Array.from(data).buffer, false); const hasher = new Sm3(); hasher.update(hashData); return hasher.finalize(); @@ -242,17 +242,17 @@ export class SM2 { /** * Utility function, returns an elliptic curve points X and Y values as hex; - * + * * @param {EcPointFp} point * @returns {[]} */ getPointAsHex(point) { - var biX = point.getX().toBigInteger(); - var biY = point.getY().toBigInteger(); + const biX = point.getX().toBigInteger(); + const biY = point.getY().toBigInteger(); - var charlen = this.ecParams.keycharlen; - var hX = ("0000000000" + biX.toString(16)).slice(- charlen); - var hY = ("0000000000" + biY.toString(16)).slice(- charlen); - return [hX, hY] + const charlen = this.ecParams.keycharlen; + const hX = ("0000000000" + biX.toString(16)).slice(- charlen); + const hY = ("0000000000" + biY.toString(16)).slice(- charlen); + return [hX, hY]; } -} \ No newline at end of file +} diff --git a/src/core/operations/SM2Decrypt.mjs b/src/core/operations/SM2Decrypt.mjs index dcacdc3f..916056c3 100644 --- a/src/core/operations/SM2Decrypt.mjs +++ b/src/core/operations/SM2Decrypt.mjs @@ -5,7 +5,6 @@ */ import Operation from "../Operation.mjs"; -import OperationError from "../errors/OperationError.mjs"; import { SM2 } from "../lib/SM2.mjs"; @@ -55,12 +54,11 @@ class SM2Decrypt extends Operation { run(input, args) { const [privateKey, inputFormat, curveName] = args; - var sm2 = new SM2(curveName, inputFormat); + const sm2 = new SM2(curveName, inputFormat); sm2.setPrivateKey(privateKey); - - var result = sm2.decrypt(input); - return result + const result = sm2.decrypt(input); + return result; } } diff --git a/src/core/operations/SM2Encrypt.mjs b/src/core/operations/SM2Encrypt.mjs index fe20e957..a3ba08d9 100644 --- a/src/core/operations/SM2Encrypt.mjs +++ b/src/core/operations/SM2Encrypt.mjs @@ -5,16 +5,9 @@ */ import Operation from "../Operation.mjs"; -import OperationError from "../errors/OperationError.mjs"; import { SM2 } from "../lib/SM2.mjs"; -import { fromHex } from "../lib/Hex.mjs"; -import Utils from "../Utils.mjs"; -import Sm3 from "crypto-api/src/hasher/sm3.mjs"; -import {toHex} from "crypto-api/src/encoder/hex.mjs"; -import r from "jsrsasign"; - /** * SM2 Encrypt operation */ @@ -68,11 +61,11 @@ class SM2Encrypt extends Operation { const [publicKeyX, publicKeyY, outputFormat, curveName] = args; this.outputFormat = outputFormat; - var sm2 = new SM2(curveName, outputFormat); + const sm2 = new SM2(curveName, outputFormat); sm2.setPublicKey(publicKeyX, publicKeyY); - var result = sm2.encrypt(new Uint8Array(input)) - return result + const result = sm2.encrypt(new Uint8Array(input)); + return result; } /** @@ -85,11 +78,11 @@ class SM2Encrypt extends Operation { * @returns {Object[]} pos */ highlight(pos, args) { - const [privateKeyX, privateKeyY, outputFormat, curveName] = args; - var num = pos[0].end - pos[0].start - var adjust = 128 - if (outputFormat == "C1C3C2") { - adjust = 192 + const outputFormat = args[2]; + const num = pos[0].end - pos[0].start; + let adjust = 128; + if (outputFormat === "C1C3C2") { + adjust = 192; } pos[0].start = Math.ceil(pos[0].start + adjust); pos[0].end = Math.floor(pos[0].end + adjust + num); diff --git a/tests/operations/tests/SM2.mjs b/tests/operations/tests/SM2.mjs index 278d46a7..a3d6fd2c 100644 --- a/tests/operations/tests/SM2.mjs +++ b/tests/operations/tests/SM2.mjs @@ -1,6 +1,6 @@ /** * SM2 Tests - * + * * @author flakjacket95 [dflack95@gmail.com] * @copyright Crown Copyright 2024 * @license Apache-2.0 @@ -9,22 +9,22 @@ import TestRegister from "../../lib/TestRegister.mjs"; /* Plaintexts */ -const SMALL_PLAIN = "I am a small plaintext" -const LARGE_PLAIN = "I am a larger plaintext, that will require the encryption KDF to generate a much larger key to properly encrypt me" +const SMALL_PLAIN = "I am a small plaintext"; +const LARGE_PLAIN = "I am a larger plaintext, that will require the encryption KDF to generate a much larger key to properly encrypt me"; /* Test Key Parameters */ -const PUBLIC_X = "f7d903cab7925066c31150a92b31e548e63f954f92d01eaa0271fb2a336baef8" -const PUBLIC_Y = "fb0c45e410ef7a6cdae724e6a78dbff52562e97ede009e762b667d9b14adea6c" -const PRIVATE_K = "e74a72505084c3269aa9b696d603e3e08c74c6740212c11a31e26cdfe08bdf6a" +const PUBLIC_X = "f7d903cab7925066c31150a92b31e548e63f954f92d01eaa0271fb2a336baef8"; +const PUBLIC_Y = "fb0c45e410ef7a6cdae724e6a78dbff52562e97ede009e762b667d9b14adea6c"; +const PRIVATE_K = "e74a72505084c3269aa9b696d603e3e08c74c6740212c11a31e26cdfe08bdf6a"; -const CURVE = "sm2p256v1" +const CURVE = "sm2p256v1"; /* Decryption Test Ciphertext*/ -const CIPHERTEXT_1 = "9a31bc0adb4677cdc4141479e3949572a55c3e6fb52094721f741c2bd2e179aaa87be6263bc1be602e473be3d5de5dce97f8248948b3a7e15f9f67f64aef21575e0c05e6171870a10ff9ab778dbef24267ad90e1a9d47d68f757d57c4816612e9829f804025dea05a511cda39371c22a2828f976f72e" -const CIPHERTEXT_2 = "d3647d68568a2e7a4f8e843286be7bf2b4d80256697d19a73df306ae1a7e6d0364d942e23d2340606e7a2502a838b132f9242587b2ea7e4c207e87242eea8cae68f5ff4da2a95a7f6d350608ae5b6777e1d925bf9c560087af84aba7befba713130106ddb4082d803811bca3864594722f3198d58257fe4ba37f4aa540adf4cb0568bddd2d8140ad3030deea0a87e3198655cc4d22bfc3d73b1c4afec2ff15d68c8d1298d97132cace922ee8a4e41ca288a7e748b77ca94aa81dc283439923ae7939e00898e16fe5111fbe1d928d152b216a" -const CIPHERTEXT_3 = "5f340eeb4398fa8950ee3408d0e3fe34bf7728c9fdb060c94b916891b5c693610274160b52a7132a2bf16ad5cdb57d1e00da2f3ddbd55350729aa9c268b53e40c05ccce9912daa14406e8c132e389484e69757350be25351755dcc6c25c94b3c1a448b2cf8c2017582125eb6cf782055b199a875e966" -const CIPHERTEXT_4 = "0649bac46c3f9fd7fb3b2be4bff27414d634651efd02ca67d8c802bbc5468e77d035c39b581d6b56227f5d87c0b4efbea5032c0761139295ae194b9f1fce698f2f4b51d89fa5554171a1aad2e61fe9de89831aec472ecc5ab178ebf4d2230c1fb94fca03e536b87b9eba6db71ba9939260a08ffd230ca86cb45cf754854222364231bdb8b873791d63ad57a4b3fa5b6375388dc879373f5f1be9051bc5072a8afbec5b7b034e4907aa5bb4b6b1f50e725d09cb6a02e07ce20263005f6c9157ce05d3ea739d231d4f09396fb72aa680884d78" +const CIPHERTEXT_1 = "9a31bc0adb4677cdc4141479e3949572a55c3e6fb52094721f741c2bd2e179aaa87be6263bc1be602e473be3d5de5dce97f8248948b3a7e15f9f67f64aef21575e0c05e6171870a10ff9ab778dbef24267ad90e1a9d47d68f757d57c4816612e9829f804025dea05a511cda39371c22a2828f976f72e"; +const CIPHERTEXT_2 = "d3647d68568a2e7a4f8e843286be7bf2b4d80256697d19a73df306ae1a7e6d0364d942e23d2340606e7a2502a838b132f9242587b2ea7e4c207e87242eea8cae68f5ff4da2a95a7f6d350608ae5b6777e1d925bf9c560087af84aba7befba713130106ddb4082d803811bca3864594722f3198d58257fe4ba37f4aa540adf4cb0568bddd2d8140ad3030deea0a87e3198655cc4d22bfc3d73b1c4afec2ff15d68c8d1298d97132cace922ee8a4e41ca288a7e748b77ca94aa81dc283439923ae7939e00898e16fe5111fbe1d928d152b216a"; +const CIPHERTEXT_3 = "5f340eeb4398fa8950ee3408d0e3fe34bf7728c9fdb060c94b916891b5c693610274160b52a7132a2bf16ad5cdb57d1e00da2f3ddbd55350729aa9c268b53e40c05ccce9912daa14406e8c132e389484e69757350be25351755dcc6c25c94b3c1a448b2cf8c2017582125eb6cf782055b199a875e966"; +const CIPHERTEXT_4 = "0649bac46c3f9fd7fb3b2be4bff27414d634651efd02ca67d8c802bbc5468e77d035c39b581d6b56227f5d87c0b4efbea5032c0761139295ae194b9f1fce698f2f4b51d89fa5554171a1aad2e61fe9de89831aec472ecc5ab178ebf4d2230c1fb94fca03e536b87b9eba6db71ba9939260a08ffd230ca86cb45cf754854222364231bdb8b873791d63ad57a4b3fa5b6375388dc879373f5f1be9051bc5072a8afbec5b7b034e4907aa5bb4b6b1f50e725d09cb6a02e07ce20263005f6c9157ce05d3ea739d231d4f09396fb72aa680884d78"; TestRegister.addTests([ From ae9054dc37d842f0131a500c3b63f8ced957b587 Mon Sep 17 00:00:00 2001 From: Dan Flack Date: Sun, 22 Sep 2024 18:58:36 +0200 Subject: [PATCH 16/34] Remove highlighting and correct one module mismatch --- src/core/operations/SM2Decrypt.mjs | 5 +++++ src/core/operations/SM2Encrypt.mjs | 28 ++++++---------------------- 2 files changed, 11 insertions(+), 22 deletions(-) diff --git a/src/core/operations/SM2Decrypt.mjs b/src/core/operations/SM2Decrypt.mjs index 916056c3..39657110 100644 --- a/src/core/operations/SM2Decrypt.mjs +++ b/src/core/operations/SM2Decrypt.mjs @@ -4,6 +4,7 @@ * @license Apache-2.0 */ +import OperationError from "../errors/OperationError.mjs"; import Operation from "../Operation.mjs"; import { SM2 } from "../lib/SM2.mjs"; @@ -54,6 +55,10 @@ class SM2Decrypt extends Operation { run(input, args) { const [privateKey, inputFormat, curveName] = args; + if (privateKey.length !== 64) { + throw new OperationError("Input private key must be in hex; and should be 32 bytes"); + } + const sm2 = new SM2(curveName, inputFormat); sm2.setPrivateKey(privateKey); diff --git a/src/core/operations/SM2Encrypt.mjs b/src/core/operations/SM2Encrypt.mjs index a3ba08d9..b1e5f901 100644 --- a/src/core/operations/SM2Encrypt.mjs +++ b/src/core/operations/SM2Encrypt.mjs @@ -4,6 +4,7 @@ * @license Apache-2.0 */ +import OperationError from "../errors/OperationError.mjs"; import Operation from "../Operation.mjs"; import { SM2 } from "../lib/SM2.mjs"; @@ -20,7 +21,7 @@ class SM2Encrypt extends Operation { super(); this.name = "SM2 Encrypt"; - this.module = "Ciphers"; + this.module = "Crypto"; this.description = "Encrypts a message utilizing the SM2 standard"; this.infoURL = ""; // Usually a Wikipedia link. Remember to remove localisation (i.e. https://wikipedia.org/etc rather than https://en.wikipedia.org/etc) this.inputType = "ArrayBuffer"; @@ -61,33 +62,16 @@ class SM2Encrypt extends Operation { const [publicKeyX, publicKeyY, outputFormat, curveName] = args; this.outputFormat = outputFormat; + if (publicKeyX.length !== 64 || publicKeyY.length !== 64) { + throw new OperationError("Invalid Public Key - Ensure each component is 32 bytes in size and in hex"); + } + const sm2 = new SM2(curveName, outputFormat); sm2.setPublicKey(publicKeyX, publicKeyY); const result = sm2.encrypt(new Uint8Array(input)); return result; } - - /** - * Highlight SM2 Encrypt - * - * @param {Object[]} pos - * @param {number} pos[].start - * @param {number} pos[].end - * @param {Object[]} args - * @returns {Object[]} pos - */ - highlight(pos, args) { - const outputFormat = args[2]; - const num = pos[0].end - pos[0].start; - let adjust = 128; - if (outputFormat === "C1C3C2") { - adjust = 192; - } - pos[0].start = Math.ceil(pos[0].start + adjust); - pos[0].end = Math.floor(pos[0].end + adjust + num); - return pos; - } } export default SM2Encrypt; From a74e2e585eba835439105d0e7918de530d895342 Mon Sep 17 00:00:00 2001 From: Zhiyuan Zheng Date: Mon, 17 Feb 2025 13:49:17 +0800 Subject: [PATCH 17/34] add lock. --- package-lock.json | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/package-lock.json b/package-lock.json index 50639ea8..e4fb240d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -48,6 +48,7 @@ "highlight.js": "^11.9.0", "ieee754": "^1.2.1", "jimp": "^0.22.12", + "jq-web": "^0.6.1", "jquery": "3.7.1", "js-crc": "^0.2.0", "js-sha3": "^0.9.3", @@ -12290,6 +12291,12 @@ "integrity": "sha512-WZzeDOEtTOBK4Mdsar0IqEU5sMr3vSV2RqkAIzUEV2BHnUfKGyswWFPFwK5EeDo93K3FohSHbLAjj0s1Wzd+dg==", "license": "BSD-3-Clause" }, + "node_modules/jq-web": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/jq-web/-/jq-web-0.6.1.tgz", + "integrity": "sha512-7qZb0KP0Xd3OSRcEtdR8nI0h1pN7RQQRhL8UXM/Hq0zh/ZFAIncFkRcctNjKHlvHLZ29fMNxR9j+pRVJ1SKAcA==", + "license": "ISC" + }, "node_modules/jquery": { "version": "3.7.1", "resolved": "https://registry.npmjs.org/jquery/-/jquery-3.7.1.tgz", From 06b7f0129ff684786f39fbca6e298a7e2271ec53 Mon Sep 17 00:00:00 2001 From: CCarpo Date: Mon, 17 Feb 2025 08:42:14 +0100 Subject: [PATCH 18/34] fixed linter issues. --- tests/operations/tests/BeautifyYAML.mjs | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/tests/operations/tests/BeautifyYAML.mjs b/tests/operations/tests/BeautifyYAML.mjs index f2cc58fb..348991d8 100644 --- a/tests/operations/tests/BeautifyYAML.mjs +++ b/tests/operations/tests/BeautifyYAML.mjs @@ -1,4 +1,3 @@ - /** * YAML tests. * @@ -17,10 +16,10 @@ TestRegister.addTests([ name: "YAML to JSON", input: EXAMPLE_YAML, expectedOutput: JSON.stringify({ - "number": 3, - "plain": "string", - "block": "two\nlines\n" - }, null, 4), + "number": 3, + "plain": "string", + "block": "two\nlines\n" + }, null, 4), recipeConfig: [ { op: "YAML to JSON", From c2936a6f2c5eeece72b62271ccef976fddbce42b Mon Sep 17 00:00:00 2001 From: CCarpo Date: Mon, 17 Feb 2025 08:44:42 +0100 Subject: [PATCH 19/34] removed old data format --- src/core/config/Categories.json | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/core/config/Categories.json b/src/core/config/Categories.json index 234ae6cc..4b713f40 100644 --- a/src/core/config/Categories.json +++ b/src/core/config/Categories.json @@ -73,8 +73,7 @@ "CBOR Encode", "CBOR Decode", "YAML to JSON", - "Beautify YAML" - "Caret/M-decode", + "Beautify YAML", "Rison Encode", "Rison Decode", "To Modhex", From 5cef2b13a3446d4e22a896a9ab491797d384e024 Mon Sep 17 00:00:00 2001 From: CCarpo Date: Mon, 17 Feb 2025 08:46:28 +0100 Subject: [PATCH 20/34] fixed typo in categories. --- src/core/config/Categories.json | 1 + 1 file changed, 1 insertion(+) diff --git a/src/core/config/Categories.json b/src/core/config/Categories.json index 4b713f40..1ca519a0 100644 --- a/src/core/config/Categories.json +++ b/src/core/config/Categories.json @@ -74,6 +74,7 @@ "CBOR Decode", "YAML to JSON", "Beautify YAML", + "Caret/M-decode", "Rison Encode", "Rison Decode", "To Modhex", From fcecd029c71c58323939fb85495cca51a62164e9 Mon Sep 17 00:00:00 2001 From: r4mos Date: Sun, 2 Mar 2025 01:41:12 +0100 Subject: [PATCH 21/34] The CRC Operation is implemented natively with all currently known CRC's. Old Operations (CRC8, CRC16 and CRC32) and their dependencies are removed --- src/core/operations/CRC16Checksum.mjs | 41 -- src/core/operations/CRC32Checksum.mjs | 41 -- src/core/operations/CRC8Checksum.mjs | 157 -------- src/core/operations/CRCChecksum.mjs | 531 +++++++++++++++++++++++++ tests/operations/tests/CRCChecksum.mjs | 20 + tests/operations/tests/Checksum.mjs | 241 ----------- 6 files changed, 551 insertions(+), 480 deletions(-) delete mode 100644 src/core/operations/CRC16Checksum.mjs delete mode 100644 src/core/operations/CRC32Checksum.mjs delete mode 100644 src/core/operations/CRC8Checksum.mjs create mode 100644 src/core/operations/CRCChecksum.mjs create mode 100644 tests/operations/tests/CRCChecksum.mjs delete mode 100644 tests/operations/tests/Checksum.mjs diff --git a/src/core/operations/CRC16Checksum.mjs b/src/core/operations/CRC16Checksum.mjs deleted file mode 100644 index 035ee04b..00000000 --- a/src/core/operations/CRC16Checksum.mjs +++ /dev/null @@ -1,41 +0,0 @@ -/** - * @author n1474335 [n1474335@gmail.com] - * @copyright Crown Copyright 2016 - * @license Apache-2.0 - */ - -import Operation from "../Operation.mjs"; -import JSCRC from "js-crc"; - -/** - * CRC-16 Checksum operation - */ -class CRC16Checksum extends Operation { - - /** - * CRC16Checksum constructor - */ - constructor() { - super(); - - this.name = "CRC-16 Checksum"; - this.module = "Crypto"; - this.description = "A cyclic redundancy check (CRC) is an error-detecting code commonly used in digital networks and storage devices to detect accidental changes to raw data.

The CRC was invented by W. Wesley Peterson in 1961."; - this.infoURL = "https://wikipedia.org/wiki/Cyclic_redundancy_check"; - this.inputType = "ArrayBuffer"; - this.outputType = "string"; - this.args = []; - } - - /** - * @param {ArrayBuffer} input - * @param {Object[]} args - * @returns {string} - */ - run(input, args) { - return JSCRC.crc16(input); - } - -} - -export default CRC16Checksum; diff --git a/src/core/operations/CRC32Checksum.mjs b/src/core/operations/CRC32Checksum.mjs deleted file mode 100644 index cfe84643..00000000 --- a/src/core/operations/CRC32Checksum.mjs +++ /dev/null @@ -1,41 +0,0 @@ -/** - * @author n1474335 [n1474335@gmail.com] - * @copyright Crown Copyright 2016 - * @license Apache-2.0 - */ - -import Operation from "../Operation.mjs"; -import JSCRC from "js-crc"; - -/** - * CRC-32 Checksum operation - */ -class CRC32Checksum extends Operation { - - /** - * CRC32Checksum constructor - */ - constructor() { - super(); - - this.name = "CRC-32 Checksum"; - this.module = "Crypto"; - this.description = "A cyclic redundancy check (CRC) is an error-detecting code commonly used in digital networks and storage devices to detect accidental changes to raw data.

The CRC was invented by W. Wesley Peterson in 1961; the 32-bit CRC function of Ethernet and many other standards is the work of several researchers and was published in 1975."; - this.infoURL = "https://wikipedia.org/wiki/Cyclic_redundancy_check"; - this.inputType = "ArrayBuffer"; - this.outputType = "string"; - this.args = []; - } - - /** - * @param {ArrayBuffer} input - * @param {Object[]} args - * @returns {string} - */ - run(input, args) { - return JSCRC.crc32(input); - } - -} - -export default CRC32Checksum; diff --git a/src/core/operations/CRC8Checksum.mjs b/src/core/operations/CRC8Checksum.mjs deleted file mode 100644 index 193cadf9..00000000 --- a/src/core/operations/CRC8Checksum.mjs +++ /dev/null @@ -1,157 +0,0 @@ -/** - * @author mshwed [m@ttshwed.com] - * @copyright Crown Copyright 2019 - * @license Apache-2.0 - */ - -import Operation from "../Operation.mjs"; -import OperationError from "../errors/OperationError.mjs"; - -import { toHexFast } from "../lib/Hex.mjs"; - -/** - * CRC-8 Checksum operation - */ -class CRC8Checksum extends Operation { - - /** - * CRC8Checksum constructor - */ - constructor() { - super(); - - this.name = "CRC-8 Checksum"; - this.module = "Crypto"; - this.description = "A cyclic redundancy check (CRC) is an error-detecting code commonly used in digital networks and storage devices to detect accidental changes to raw data.

The CRC was invented by W. Wesley Peterson in 1961."; - this.infoURL = "https://wikipedia.org/wiki/Cyclic_redundancy_check"; - this.inputType = "ArrayBuffer"; - this.outputType = "string"; - this.args = [ - { - "name": "Algorithm", - "type": "option", - "value": [ - "CRC-8", - "CRC-8/CDMA2000", - "CRC-8/DARC", - "CRC-8/DVB-S2", - "CRC-8/EBU", - "CRC-8/I-CODE", - "CRC-8/ITU", - "CRC-8/MAXIM", - "CRC-8/ROHC", - "CRC-8/WCDMA" - ] - } - ]; - } - - /** - * Generates the pre-computed lookup table for byte division - * - * @param polynomial - */ - calculateCRC8LookupTable(polynomial) { - const crc8Table = new Uint8Array(256); - - let currentByte; - for (let i = 0; i < 256; i++) { - currentByte = i; - for (let bit = 0; bit < 8; bit++) { - if ((currentByte & 0x80) !== 0) { - currentByte <<= 1; - currentByte ^= polynomial; - } else { - currentByte <<= 1; - } - } - - crc8Table[i] = currentByte; - } - - return crc8Table; - } - - /** - * Calculates the CRC-8 Checksum from an input - * - * @param {ArrayBuffer} input - * @param {number} polynomial - * @param {number} initializationValue - * @param {boolean} inputReflection - * @param {boolean} outputReflection - * @param {number} xorOut - */ - calculateCRC8(input, polynomial, initializationValue, inputReflection, outputReflection, xorOut) { - const crcSize = 8; - const crcTable = this.calculateCRC8LookupTable(polynomial); - - let crc = initializationValue !== 0 ? initializationValue : 0; - let currentByte, position; - - input = new Uint8Array(input); - for (const inputByte of input) { - currentByte = inputReflection ? this.reverseBits(inputByte, crcSize) : inputByte; - - position = (currentByte ^ crc) & 255; - crc = crcTable[position]; - } - - crc = outputReflection ? this.reverseBits(crc, crcSize) : crc; - - if (xorOut !== 0) crc = crc ^ xorOut; - - return toHexFast(new Uint8Array([crc])); - } - - /** - * Reverse the bits for a given input byte. - * - * @param {number} input - */ - reverseBits(input, hashSize) { - let reversedByte = 0; - for (let i = hashSize - 1; i >= 0; i--) { - reversedByte |= ((input & 1) << i); - input >>= 1; - } - - return reversedByte; - } - - /** - * @param {ArrayBuffer} input - * @param {Object[]} args - * @returns {string} - */ - run(input, args) { - const algorithm = args[0]; - - switch (algorithm) { - case "CRC-8": - return this.calculateCRC8(input, 0x7, 0x0, false, false, 0x0); - case "CRC-8/CDMA2000": - return this.calculateCRC8(input, 0x9B, 0xFF, false, false, 0x0); - case "CRC-8/DARC": - return this.calculateCRC8(input, 0x39, 0x0, true, true, 0x0); - case "CRC-8/DVB-S2": - return this.calculateCRC8(input, 0xD5, 0x0, false, false, 0x0); - case "CRC-8/EBU": - return this.calculateCRC8(input, 0x1D, 0xFF, true, true, 0x0); - case "CRC-8/I-CODE": - return this.calculateCRC8(input, 0x1D, 0xFD, false, false, 0x0); - case "CRC-8/ITU": - return this.calculateCRC8(input, 0x7, 0x0, false, false, 0x55); - case "CRC-8/MAXIM": - return this.calculateCRC8(input, 0x31, 0x0, true, true, 0x0); - case "CRC-8/ROHC": - return this.calculateCRC8(input, 0x7, 0xFF, true, true, 0x0); - case "CRC-8/WCDMA": - return this.calculateCRC8(input, 0x9B, 0x0, true, true, 0x0); - default: - throw new OperationError("Unknown checksum algorithm"); - } - } -} - -export default CRC8Checksum; diff --git a/src/core/operations/CRCChecksum.mjs b/src/core/operations/CRCChecksum.mjs new file mode 100644 index 00000000..b264d010 --- /dev/null +++ b/src/core/operations/CRCChecksum.mjs @@ -0,0 +1,531 @@ +/** + * @author r4mos [2k95ljkhg@mozmail.com] + * @copyright Crown Copyright 2025 + * @license Apache-2.0 + */ + +import Operation from "../Operation.mjs"; +import OperationError from "../errors/OperationError.mjs"; + +/** + * CRC Checksum operation + */ +class CRCChecksum extends Operation { + + /** + * CRCChecksum constructor + */ + constructor() { + super(); + + this.name = "CRC Checksum"; + this.module = "Default"; + this.description = "A Cyclic Redundancy Check (CRC) is an error-detecting code commonly used in digital networks and storage devices to detect accidental changes to raw data."; + this.infoURL = "https://wikipedia.org/wiki/Cyclic_redundancy_check"; + this.inputType = "ArrayBuffer"; + this.outputType = "string"; + this.args = [ + { + name: "Algorithm", + type: "option", + value: [ + "CRC-3/GSM", + "CRC-3/ROHC", + "CRC-4/G-704", + "CRC-4/INTERLAKEN", + "CRC-4/ITU", + "CRC-5/EPC", + "CRC-5/EPC-C1G2", + "CRC-5/G-704", + "CRC-5/ITU", + "CRC-5/USB", + "CRC-6/CDMA2000-A", + "CRC-6/CDMA2000-B", + "CRC-6/DARC", + "CRC-6/G-704", + "CRC-6/GSM", + "CRC-6/ITU", + "CRC-7/MMC", + "CRC-7/ROHC", + "CRC-7/UMTS", + "CRC-8", + "CRC-8/8H2F", + "CRC-8/AES", + "CRC-8/AUTOSAR", + "CRC-8/BLUETOOTH", + "CRC-8/CDMA2000", + "CRC-8/DARC", + "CRC-8/DVB-S2", + "CRC-8/EBU", + "CRC-8/GSM-A", + "CRC-8/GSM-B", + "CRC-8/HITAG", + "CRC-8/I-432-1", + "CRC-8/I-CODE", + "CRC-8/ITU", + "CRC-8/LTE", + "CRC-8/MAXIM", + "CRC-8/MAXIM-DOW", + "CRC-8/MIFARE-MAD", + "CRC-8/NRSC-5", + "CRC-8/OPENSAFETY", + "CRC-8/ROHC", + "CRC-8/SAE-J1850", + "CRC-8/SAE-J1850-ZERO", + "CRC-8/SMBUS", + "CRC-8/TECH-3250", + "CRC-8/WCDMA", + "CRC-10/ATM", + "CRC-10/CDMA2000", + "CRC-10/GSM", + "CRC-10/I-610", + "CRC-11/FLEXRAY", + "CRC-11/UMTS", + "CRC-12/3GPP", + "CRC-12/CDMA2000", + "CRC-12/DECT", + "CRC-12/GSM", + "CRC-12/UMTS", + "CRC-13/BBC", + "CRC-14/DARC", + "CRC-14/GSM", + "CRC-15/CAN", + "CRC-15/MPT1327", + "CRC-16", + "CRC-16/A", + "CRC-16/ACORN", + "CRC-16/ARC", + "CRC-16/AUG-CCITT", + "CRC-16/AUTOSAR", + "CRC-16/B", + "CRC-16/BLUETOOTH", + "CRC-16/BUYPASS", + "CRC-16/CCITT", + "CRC-16/CCITT-FALSE", + "CRC-16/CCITT-TRUE", + "CRC-16/CCITT-ZERO", + "CRC-16/CDMA2000", + "CRC-16/CMS", + "CRC-16/DARC", + "CRC-16/DDS-110", + "CRC-16/DECT-R", + "CRC-16/DECT-X", + "CRC-16/DNP", + "CRC-16/EN-13757", + "CRC-16/EPC", + "CRC-16/EPC-C1G2", + "CRC-16/GENIBUS", + "CRC-16/GSM", + "CRC-16/I-CODE", + "CRC-16/IBM", + "CRC-16/IBM-3740", + "CRC-16/IBM-SDLC", + "CRC-16/IEC-61158-2", + "CRC-16/ISO-HDLC", + "CRC-16/ISO-IEC-14443-3-A", + "CRC-16/ISO-IEC-14443-3-B", + "CRC-16/KERMIT", + "CRC-16/LHA", + "CRC-16/LJ1200", + "CRC-16/LTE", + "CRC-16/M17", + "CRC-16/MAXIM", + "CRC-16/MAXIM-DOW", + "CRC-16/MCRF4XX", + "CRC-16/MODBUS", + "CRC-16/NRSC-5", + "CRC-16/OPENSAFETY-A", + "CRC-16/OPENSAFETY-B", + "CRC-16/PROFIBUS", + "CRC-16/RIELLO", + "CRC-16/SPI-FUJITSU", + "CRC-16/T10-DIF", + "CRC-16/TELEDISK", + "CRC-16/TMS37157", + "CRC-16/UMTS", + "CRC-16/USB", + "CRC-16/V-41-LSB", + "CRC-16/V-41-MSB", + "CRC-16/VERIFONE", + "CRC-16/X-25", + "CRC-16/XMODEM", + "CRC-16/ZMODEM", + "CRC-17/CAN-FD", + "CRC-21/CAN-FD", + "CRC-24/BLE", + "CRC-24/FLEXRAY-A", + "CRC-24/FLEXRAY-B", + "CRC-24/INTERLAKEN", + "CRC-24/LTE-A", + "CRC-24/LTE-B", + "CRC-24/OPENPGP", + "CRC-24/OS-9", + "CRC-30/CDMA", + "CRC-31/PHILIPS", + "CRC-32", + "CRC-32/AAL5", + "CRC-32/ADCCP", + "CRC-32/AIXM", + "CRC-32/AUTOSAR", + "CRC-32/BASE91-C", + "CRC-32/BASE91-D", + "CRC-32/BZIP2", + "CRC-32/C", + "CRC-32/CASTAGNOLI", + "CRC-32/CD-ROM-EDC", + "CRC-32/CKSUM", + "CRC-32/D", + "CRC-32/DECT-B", + "CRC-32/INTERLAKEN", + "CRC-32/ISCSI", + "CRC-32/ISO-HDLC", + "CRC-32/JAMCRC", + "CRC-32/MEF", + "CRC-32/MPEG-2", + "CRC-32/NVME", + "CRC-32/PKZIP", + "CRC-32/POSIX", + "CRC-32/Q", + "CRC-32/SATA", + "CRC-32/V-42", + "CRC-32/XFER", + "CRC-32/XZ", + "CRC-40/GSM", + "CRC-64/ECMA-182", + "CRC-64/GO-ECMA", + "CRC-64/GO-ISO", + "CRC-64/MS", + "CRC-64/NVME", + "CRC-64/REDIS", + "CRC-64/WE", + "CRC-64/XZ", + "CRC-82/DARC" + ] + } + ]; + } + + /** + * Reverse the order of bits in a number + * + * @param {BigInt} data + * @param {BigInt} reflect + */ + reflectData(data, reflect) { + let value = 0n; + for (let bit = 0n; bit < reflect; bit++) { + if ((data & 1n) === 1n) { + value |= (1n << ((reflect - 1n) - bit)); + } + data >>= 1n; + } + return value; + } + + /** + * Performs the CRC Checksum calculation bit per bit without acceleration + * + * @param {BigInt} width + * @param {ArrayBuffer} input + * @param {BigInt} poly + * @param {BigInt} remainder + * @param {boolean} reflectIn + * @param {boolean} reflectOut + * @param {BigInt} xorOut + */ + calculateCrcBitPerBit(width, input, poly, remainder, reflectIn, reflectOut, xorOut) { + const TOP_BIT = 1n << (width - 1n); + const MASK = (1n << width) - 1n; + + for (let byte of input) { + byte = BigInt(byte); + if (reflectIn) { + byte = this.reflectData(byte, 8n); + } + + for (let i = 0x80n; i !== 0n; i >>= 1n) { + let bit = remainder & TOP_BIT; + + remainder = (remainder << 1n) & MASK; + + if ((byte & i) !== 0n) { + bit ^= TOP_BIT; + } + + if (bit !== 0n) { + remainder ^= poly; + } + } + } + + if (reflectOut) { + remainder = this.reflectData(remainder, width); + } + + return remainder ^ xorOut; + } + + /** + * Generates the necessary table to speed up the calculation + * + * @param {BigInt} width + * @param {BigInt} poly + * @param {BigInt} MASK + * @param {BigInt} TOP_BIT + */ + generateTable(width, poly, MASK, TOP_BIT) { + const table = new Array(256n); + for (let byte = 0n; byte < 256n; byte++) { + let value = ((byte << width - 8n) & MASK); + for (let bit = 0n; bit < 8n; bit++) { + value = (value & TOP_BIT) === 0n ? + ((value << 1n) & MASK) : + ((value << 1n) & MASK) ^ poly; + } + table[byte] = value; + } + return table; + } + + /** + * Performs the CRC Checksum calculation byte per byte using a computed table to accelerate it + * + * @param {BigInt} width + * @param {ArrayBuffer} input + * @param {BigInt} poly + * @param {BigInt} remainder + * @param {boolean} reflectIn + * @param {boolean} reflectOut + * @param {BigInt} xorOut + */ + calculateCrcBytePerByte(width, input, poly, remainder, reflectIn, reflectOut, xorOut) { + const TOP_BIT = 1n << (width - 1n); + const MASK = (1n << width) - 1n; + const TABLE = this.generateTable(width, poly, MASK, TOP_BIT); + + for (let byte of input) { + byte = BigInt(byte); + if (reflectIn) { + byte = this.reflectData(byte, 8n); + } + remainder ^= (byte << width - 8n) & MASK; + + const INDEX = remainder >> width - 8n; + remainder = (remainder << 8n) & MASK; + remainder ^= TABLE[INDEX]; + } + + if (reflectOut) { + remainder = this.reflectData(remainder, width); + } + return remainder ^ xorOut; + } + + /** + * Calculates the CRC Checksum using Bigint (https://developer.mozilla.org/en-US/docs/Glossary/BigInt) + * + * @param {BigInt} width + * @param {ArrayBuffer} input + * @param {BigInt} poly + * @param {BigInt} init + * @param {boolean} reflectIn + * @param {boolean} reflectOut + * @param {BigInt} xorOut + */ + crc(width, input, poly, init, reflectIn, reflectOut, xorOut) { + const VALUE = width < 8n ? + this.calculateCrcBitPerBit(width, input, poly, init, reflectIn, reflectOut, xorOut) : + this.calculateCrcBytePerByte(width, input, poly, init, reflectIn, reflectOut, xorOut); + + return VALUE.toString(16).padStart(Math.ceil(Number(width) / 4), "0"); + } + + /** + * Calculation of all known CRCs. Names and constants extracted from https://reveng.sourceforge.io/crc-catalogue/all.htm + * + * @param {ArrayBuffer} input + * @param {Object[]} args + * @returns {string} + */ + run(input, args) { + const algorithm = args[0]; + + switch (algorithm) { + case "CRC-3/GSM": return this.crc(3n, input, 0x3n, 0x0n, false, false, 0x7n); + case "CRC-3/ROHC": return this.crc(3n, input, 0x3n, 0x7n, true, true, 0x0n); + case "CRC-4/G-704": return this.crc(4n, input, 0x3n, 0x0n, true, true, 0x0n); + case "CRC-4/INTERLAKEN": return this.crc(4n, input, 0x3n, 0xFn, false, false, 0xFn); + case "CRC-4/ITU": return this.crc(4n, input, 0x3n, 0x0n, true, true, 0x0n); + case "CRC-5/EPC": return this.crc(5n, input, 0x09n, 0x09n, false, false, 0x00n); + case "CRC-5/EPC-C1G2": return this.crc(5n, input, 0x09n, 0x09n, false, false, 0x00n); + case "CRC-5/G-704": return this.crc(5n, input, 0x15n, 0x00n, true, true, 0x00n); + case "CRC-5/ITU": return this.crc(5n, input, 0x15n, 0x00n, true, true, 0x00n); + case "CRC-5/USB": return this.crc(5n, input, 0x05n, 0x1Fn, true, true, 0x1Fn); + case "CRC-6/CDMA2000-A": return this.crc(6n, input, 0x27n, 0x3Fn, false, false, 0x00n); + case "CRC-6/CDMA2000-B": return this.crc(6n, input, 0x07n, 0x3Fn, false, false, 0x00n); + case "CRC-6/DARC": return this.crc(6n, input, 0x19n, 0x00n, true, true, 0x00n); + case "CRC-6/G-704": return this.crc(6n, input, 0x03n, 0x00n, true, true, 0x00n); + case "CRC-6/GSM": return this.crc(6n, input, 0x2Fn, 0x00n, false, false, 0x3Fn); + case "CRC-6/ITU": return this.crc(6n, input, 0x03n, 0x00n, true, true, 0x00n); + case "CRC-7/MMC": return this.crc(7n, input, 0x09n, 0x00n, false, false, 0x00n); + case "CRC-7/ROHC": return this.crc(7n, input, 0x4Fn, 0x7Fn, true, true, 0x00n); + case "CRC-7/UMTS": return this.crc(7n, input, 0x45n, 0x00n, false, false, 0x00n); + case "CRC-8": return this.crc(8n, input, 0x07n, 0x00n, false, false, 0x00n); + case "CRC-8/8H2F": return this.crc(8n, input, 0x2Fn, 0xFFn, false, false, 0xFFn); + case "CRC-8/AES": return this.crc(8n, input, 0x1Dn, 0xFFn, true, true, 0x00n); + case "CRC-8/AUTOSAR": return this.crc(8n, input, 0x2Fn, 0xFFn, false, false, 0xFFn); + case "CRC-8/BLUETOOTH": return this.crc(8n, input, 0xA7n, 0x00n, true, true, 0x00n); + case "CRC-8/CDMA2000": return this.crc(8n, input, 0x9Bn, 0xFFn, false, false, 0x00n); + case "CRC-8/DARC": return this.crc(8n, input, 0x39n, 0x00n, true, true, 0x00n); + case "CRC-8/DVB-S2": return this.crc(8n, input, 0xD5n, 0x00n, false, false, 0x00n); + case "CRC-8/EBU": return this.crc(8n, input, 0x1Dn, 0xFFn, true, true, 0x00n); + case "CRC-8/GSM-A": return this.crc(8n, input, 0x1Dn, 0x00n, false, false, 0x00n); + case "CRC-8/GSM-B": return this.crc(8n, input, 0x49n, 0x00n, false, false, 0xFFn); + case "CRC-8/HITAG": return this.crc(8n, input, 0x1Dn, 0xFFn, false, false, 0x00n); + case "CRC-8/I-432-1": return this.crc(8n, input, 0x07n, 0x00n, false, false, 0x55n); + case "CRC-8/I-CODE": return this.crc(8n, input, 0x1Dn, 0xFDn, false, false, 0x00n); + case "CRC-8/ITU": return this.crc(8n, input, 0x07n, 0x00n, false, false, 0x55n); + case "CRC-8/LTE": return this.crc(8n, input, 0x9Bn, 0x00n, false, false, 0x00n); + case "CRC-8/MAXIM": return this.crc(8n, input, 0x31n, 0x00n, true, true, 0x00n); + case "CRC-8/MAXIM-DOW": return this.crc(8n, input, 0x31n, 0x00n, true, true, 0x00n); + case "CRC-8/MIFARE-MAD": return this.crc(8n, input, 0x1Dn, 0xC7n, false, false, 0x00n); + case "CRC-8/NRSC-5": return this.crc(8n, input, 0x31n, 0xFFn, false, false, 0x00n); + case "CRC-8/OPENSAFETY": return this.crc(8n, input, 0x2Fn, 0x00n, false, false, 0x00n); + case "CRC-8/ROHC": return this.crc(8n, input, 0x07n, 0xFFn, true, true, 0x00n); + case "CRC-8/SAE-J1850": return this.crc(8n, input, 0x1Dn, 0xFFn, false, false, 0xFFn); + case "CRC-8/SAE-J1850-ZERO": return this.crc(8n, input, 0x1Dn, 0x00n, false, false, 0x00n); + case "CRC-8/SMBUS": return this.crc(8n, input, 0x07n, 0x00n, false, false, 0x00n); + case "CRC-8/TECH-3250": return this.crc(8n, input, 0x1Dn, 0xFFn, true, true, 0x00n); + case "CRC-8/WCDMA": return this.crc(8n, input, 0x9Bn, 0x00n, true, true, 0x00n); + case "CRC-10/ATM": return this.crc(10n, input, 0x233n, 0x000n, false, false, 0x000n); + case "CRC-10/CDMA2000": return this.crc(10n, input, 0x3D9n, 0x3FFn, false, false, 0x000n); + case "CRC-10/GSM": return this.crc(10n, input, 0x175n, 0x000n, false, false, 0x3FFn); + case "CRC-10/I-610": return this.crc(10n, input, 0x233n, 0x000n, false, false, 0x000n); + case "CRC-11/FLEXRAY": return this.crc(11n, input, 0x385n, 0x01An, false, false, 0x000n); + case "CRC-11/UMTS": return this.crc(11n, input, 0x307n, 0x000n, false, false, 0x000n); + case "CRC-12/3GPP": return this.crc(12n, input, 0x80Fn, 0x000n, false, true, 0x000n); + case "CRC-12/CDMA2000": return this.crc(12n, input, 0xF13n, 0xFFFn, false, false, 0x000n); + case "CRC-12/DECT": return this.crc(12n, input, 0x80Fn, 0x000n, false, false, 0x000n); + case "CRC-12/GSM": return this.crc(12n, input, 0xD31n, 0x000n, false, false, 0xFFFn); + case "CRC-12/UMTS": return this.crc(12n, input, 0x80Fn, 0x000n, false, true, 0x000n); + case "CRC-13/BBC": return this.crc(13n, input, 0x1CF5n, 0x0000n, false, false, 0x0000n); + case "CRC-14/DARC": return this.crc(14n, input, 0x0805n, 0x0000n, true, true, 0x0000n); + case "CRC-14/GSM": return this.crc(14n, input, 0x202Dn, 0x0000n, false, false, 0x3FFFn); + case "CRC-15/CAN": return this.crc(15n, input, 0x4599n, 0x0000n, false, false, 0x0000n); + case "CRC-15/MPT1327": return this.crc(15n, input, 0x6815n, 0x0000n, false, false, 0x0001n); + case "CRC-16": return this.crc(16n, input, 0x8005n, 0x0000n, true, true, 0x0000n); + case "CRC-16/A": return this.crc(16n, input, 0x1021n, 0xC6C6n, true, true, 0x0000n); + case "CRC-16/ACORN": return this.crc(16n, input, 0x1021n, 0x0000n, false, false, 0x0000n); + case "CRC-16/ARC": return this.crc(16n, input, 0x8005n, 0x0000n, true, true, 0x0000n); + case "CRC-16/AUG-CCITT": return this.crc(16n, input, 0x1021n, 0x1D0Fn, false, false, 0x0000n); + case "CRC-16/AUTOSAR": return this.crc(16n, input, 0x1021n, 0xFFFFn, false, false, 0x0000n); + case "CRC-16/B": return this.crc(16n, input, 0x1021n, 0xFFFFn, true, true, 0xFFFFn); + case "CRC-16/BLUETOOTH": return this.crc(16n, input, 0x1021n, 0x0000n, true, true, 0x0000n); + case "CRC-16/BUYPASS": return this.crc(16n, input, 0x8005n, 0x0000n, false, false, 0x0000n); + case "CRC-16/CCITT": return this.crc(16n, input, 0x1021n, 0x0000n, true, true, 0x0000n); + case "CRC-16/CCITT-FALSE": return this.crc(16n, input, 0x1021n, 0xFFFFn, false, false, 0x0000n); + case "CRC-16/CCITT-TRUE": return this.crc(16n, input, 0x1021n, 0x0000n, true, true, 0x0000n); + case "CRC-16/CCITT-ZERO": return this.crc(16n, input, 0x1021n, 0x0000n, false, false, 0x0000n); + case "CRC-16/CDMA2000": return this.crc(16n, input, 0xC867n, 0xFFFFn, false, false, 0x0000n); + case "CRC-16/CMS": return this.crc(16n, input, 0x8005n, 0xFFFFn, false, false, 0x0000n); + case "CRC-16/DARC": return this.crc(16n, input, 0x1021n, 0xFFFFn, false, false, 0xFFFFn); + case "CRC-16/DDS-110": return this.crc(16n, input, 0x8005n, 0x800Dn, false, false, 0x0000n); + case "CRC-16/DECT-R": return this.crc(16n, input, 0x0589n, 0x0000n, false, false, 0x0001n); + case "CRC-16/DECT-X": return this.crc(16n, input, 0x0589n, 0x0000n, false, false, 0x0000n); + case "CRC-16/DNP": return this.crc(16n, input, 0x3D65n, 0x0000n, true, true, 0xFFFFn); + case "CRC-16/EN-13757": return this.crc(16n, input, 0x3D65n, 0x0000n, false, false, 0xFFFFn); + case "CRC-16/EPC": return this.crc(16n, input, 0x1021n, 0xFFFFn, false, false, 0xFFFFn); + case "CRC-16/EPC-C1G2": return this.crc(16n, input, 0x1021n, 0xFFFFn, false, false, 0xFFFFn); + case "CRC-16/GENIBUS": return this.crc(16n, input, 0x1021n, 0xFFFFn, false, false, 0xFFFFn); + case "CRC-16/GSM": return this.crc(16n, input, 0x1021n, 0x0000n, false, false, 0xFFFFn); + case "CRC-16/I-CODE": return this.crc(16n, input, 0x1021n, 0xFFFFn, false, false, 0xFFFFn); + case "CRC-16/IBM": return this.crc(16n, input, 0x8005n, 0x0000n, true, true, 0x0000n); + case "CRC-16/IBM-3740": return this.crc(16n, input, 0x1021n, 0xFFFFn, false, false, 0x0000n); + case "CRC-16/IBM-SDLC": return this.crc(16n, input, 0x1021n, 0xFFFFn, true, true, 0xFFFFn); + case "CRC-16/IEC-61158-2": return this.crc(16n, input, 0x1DCFn, 0xFFFFn, false, false, 0xFFFFn); + case "CRC-16/ISO-HDLC": return this.crc(16n, input, 0x1021n, 0xFFFFn, true, true, 0xFFFFn); + case "CRC-16/ISO-IEC-14443-3-A": return this.crc(16n, input, 0x1021n, 0xC6C6n, true, true, 0x0000n); + case "CRC-16/ISO-IEC-14443-3-B": return this.crc(16n, input, 0x1021n, 0xFFFFn, true, true, 0xFFFFn); + case "CRC-16/KERMIT": return this.crc(16n, input, 0x1021n, 0x0000n, true, true, 0x0000n); + case "CRC-16/LHA": return this.crc(16n, input, 0x8005n, 0x0000n, true, true, 0x0000n); + case "CRC-16/LJ1200": return this.crc(16n, input, 0x6F63n, 0x0000n, false, false, 0x0000n); + case "CRC-16/LTE": return this.crc(16n, input, 0x1021n, 0x0000n, false, false, 0x0000n); + case "CRC-16/M17": return this.crc(16n, input, 0x5935n, 0xFFFFn, false, false, 0x0000n); + case "CRC-16/MAXIM": return this.crc(16n, input, 0x8005n, 0x0000n, true, true, 0xFFFFn); + case "CRC-16/MAXIM-DOW": return this.crc(16n, input, 0x8005n, 0x0000n, true, true, 0xFFFFn); + case "CRC-16/MCRF4XX": return this.crc(16n, input, 0x1021n, 0xFFFFn, true, true, 0x0000n); + case "CRC-16/MODBUS": return this.crc(16n, input, 0x8005n, 0xFFFFn, true, true, 0x0000n); + case "CRC-16/NRSC-5": return this.crc(16n, input, 0x080Bn, 0xFFFFn, true, true, 0x0000n); + case "CRC-16/OPENSAFETY-A": return this.crc(16n, input, 0x5935n, 0x0000n, false, false, 0x0000n); + case "CRC-16/OPENSAFETY-B": return this.crc(16n, input, 0x755Bn, 0x0000n, false, false, 0x0000n); + case "CRC-16/PROFIBUS": return this.crc(16n, input, 0x1DCFn, 0xFFFFn, false, false, 0xFFFFn); + case "CRC-16/RIELLO": return this.crc(16n, input, 0x1021n, 0xB2AAn, true, true, 0x0000n); + case "CRC-16/SPI-FUJITSU": return this.crc(16n, input, 0x1021n, 0x1D0Fn, false, false, 0x0000n); + case "CRC-16/T10-DIF": return this.crc(16n, input, 0x8BB7n, 0x0000n, false, false, 0x0000n); + case "CRC-16/TELEDISK": return this.crc(16n, input, 0xA097n, 0x0000n, false, false, 0x0000n); + case "CRC-16/TMS37157": return this.crc(16n, input, 0x1021n, 0x89ECn, true, true, 0x0000n); + case "CRC-16/UMTS": return this.crc(16n, input, 0x8005n, 0x0000n, false, false, 0x0000n); + case "CRC-16/USB": return this.crc(16n, input, 0x8005n, 0xFFFFn, true, true, 0xFFFFn); + case "CRC-16/V-41-LSB": return this.crc(16n, input, 0x1021n, 0x0000n, true, true, 0x0000n); + case "CRC-16/V-41-MSB": return this.crc(16n, input, 0x1021n, 0x0000n, false, false, 0x0000n); + case "CRC-16/VERIFONE": return this.crc(16n, input, 0x8005n, 0x0000n, false, false, 0x0000n); + case "CRC-16/X-25": return this.crc(16n, input, 0x1021n, 0xFFFFn, true, true, 0xFFFFn); + case "CRC-16/XMODEM": return this.crc(16n, input, 0x1021n, 0x0000n, false, false, 0x0000n); + case "CRC-16/ZMODEM": return this.crc(16n, input, 0x1021n, 0x0000n, false, false, 0x0000n); + case "CRC-17/CAN-FD": return this.crc(17n, input, 0x1685Bn, 0x00000n, false, false, 0x00000n); + case "CRC-21/CAN-FD": return this.crc(21n, input, 0x102899n, 0x000000n, false, false, 0x000000n); + case "CRC-24/BLE": return this.crc(24n, input, 0x00065Bn, 0x555555n, true, true, 0x000000n); + case "CRC-24/FLEXRAY-A": return this.crc(24n, input, 0x5D6DCBn, 0xFEDCBAn, false, false, 0x000000n); + case "CRC-24/FLEXRAY-B": return this.crc(24n, input, 0x5D6DCBn, 0xABCDEFn, false, false, 0x000000n); + case "CRC-24/INTERLAKEN": return this.crc(24n, input, 0x328B63n, 0xFFFFFFn, false, false, 0xFFFFFFn); + case "CRC-24/LTE-A": return this.crc(24n, input, 0x864CFBn, 0x000000n, false, false, 0x000000n); + case "CRC-24/LTE-B": return this.crc(24n, input, 0x800063n, 0x000000n, false, false, 0x000000n); + case "CRC-24/OPENPGP": return this.crc(24n, input, 0x864CFBn, 0xB704CEn, false, false, 0x000000n); + case "CRC-24/OS-9": return this.crc(24n, input, 0x800063n, 0xFFFFFFn, false, false, 0xFFFFFFn); + case "CRC-30/CDMA": return this.crc(30n, input, 0x2030B9C7n, 0x3FFFFFFFn, false, false, 0x3FFFFFFFn); + case "CRC-31/PHILIPS": return this.crc(31n, input, 0x04C11DB7n, 0x7FFFFFFFn, false, false, 0x7FFFFFFFn); + case "CRC-32": return this.crc(32n, input, 0x04C11DB7n, 0xFFFFFFFFn, true, true, 0xFFFFFFFFn); + case "CRC-32/AAL5": return this.crc(32n, input, 0x04C11DB7n, 0xFFFFFFFFn, false, false, 0xFFFFFFFFn); + case "CRC-32/ADCCP": return this.crc(32n, input, 0x04C11DB7n, 0xFFFFFFFFn, true, true, 0xFFFFFFFFn); + case "CRC-32/AIXM": return this.crc(32n, input, 0x814141ABn, 0x00000000n, false, false, 0x00000000n); + case "CRC-32/AUTOSAR": return this.crc(32n, input, 0xF4ACFB13n, 0xFFFFFFFFn, true, true, 0xFFFFFFFFn); + case "CRC-32/BASE91-C": return this.crc(32n, input, 0x1EDC6F41n, 0xFFFFFFFFn, true, true, 0xFFFFFFFFn); + case "CRC-32/BASE91-D": return this.crc(32n, input, 0xA833982Bn, 0xFFFFFFFFn, true, true, 0xFFFFFFFFn); + case "CRC-32/BZIP2": return this.crc(32n, input, 0x04C11DB7n, 0xFFFFFFFFn, false, false, 0xFFFFFFFFn); + case "CRC-32/C": return this.crc(32n, input, 0x1EDC6F41n, 0xFFFFFFFFn, true, true, 0xFFFFFFFFn); + case "CRC-32/CASTAGNOLI": return this.crc(32n, input, 0x1EDC6F41n, 0xFFFFFFFFn, true, true, 0xFFFFFFFFn); + case "CRC-32/CD-ROM-EDC": return this.crc(32n, input, 0x8001801Bn, 0x00000000n, true, true, 0x00000000n); + case "CRC-32/CKSUM": return this.crc(32n, input, 0x04C11DB7n, 0x00000000n, false, false, 0xFFFFFFFFn); + case "CRC-32/D": return this.crc(32n, input, 0xA833982Bn, 0xFFFFFFFFn, true, true, 0xFFFFFFFFn); + case "CRC-32/DECT-B": return this.crc(32n, input, 0x04C11DB7n, 0xFFFFFFFFn, false, false, 0xFFFFFFFFn); + case "CRC-32/INTERLAKEN": return this.crc(32n, input, 0x1EDC6F41n, 0xFFFFFFFFn, true, true, 0xFFFFFFFFn); + case "CRC-32/ISCSI": return this.crc(32n, input, 0x1EDC6F41n, 0xFFFFFFFFn, true, true, 0xFFFFFFFFn); + case "CRC-32/ISO-HDLC": return this.crc(32n, input, 0x04C11DB7n, 0xFFFFFFFFn, true, true, 0xFFFFFFFFn); + case "CRC-32/JAMCRC": return this.crc(32n, input, 0x04C11DB7n, 0xFFFFFFFFn, true, true, 0x00000000n); + case "CRC-32/MEF": return this.crc(32n, input, 0x741B8CD7n, 0xFFFFFFFFn, true, true, 0x00000000n); + case "CRC-32/MPEG-2": return this.crc(32n, input, 0x04C11DB7n, 0xFFFFFFFFn, false, false, 0x00000000n); + case "CRC-32/NVME": return this.crc(32n, input, 0x1EDC6F41n, 0xFFFFFFFFn, true, true, 0xFFFFFFFFn); + case "CRC-32/PKZIP": return this.crc(32n, input, 0x04C11DB7n, 0xFFFFFFFFn, true, true, 0xFFFFFFFFn); + case "CRC-32/POSIX": return this.crc(32n, input, 0x04C11DB7n, 0x00000000n, false, false, 0xFFFFFFFFn); + case "CRC-32/Q": return this.crc(32n, input, 0x814141ABn, 0x00000000n, false, false, 0x00000000n); + case "CRC-32/SATA": return this.crc(32n, input, 0x04C11DB7n, 0x52325032n, false, false, 0x00000000n); + case "CRC-32/V-42": return this.crc(32n, input, 0x04C11DB7n, 0xFFFFFFFFn, true, true, 0xFFFFFFFFn); + case "CRC-32/XFER": return this.crc(32n, input, 0x000000AFn, 0x00000000n, false, false, 0x00000000n); + case "CRC-32/XZ": return this.crc(32n, input, 0x04C11DB7n, 0xFFFFFFFFn, true, true, 0xFFFFFFFFn); + case "CRC-40/GSM": return this.crc(40n, input, 0x0004820009n, 0x0000000000n, false, false, 0xFFFFFFFFFFn); + case "CRC-64/ECMA-182": return this.crc(64n, input, 0x42F0E1EBA9EA3693n, 0x0000000000000000n, false, false, 0x0000000000000000n); + case "CRC-64/GO-ECMA": return this.crc(64n, input, 0x42F0E1EBA9EA3693n, 0xFFFFFFFFFFFFFFFFn, true, true, 0xFFFFFFFFFFFFFFFFn); + case "CRC-64/GO-ISO": return this.crc(64n, input, 0x000000000000001Bn, 0xFFFFFFFFFFFFFFFFn, true, true, 0xFFFFFFFFFFFFFFFFn); + case "CRC-64/MS": return this.crc(64n, input, 0x259C84CBA6426349n, 0xFFFFFFFFFFFFFFFFn, true, true, 0x0000000000000000n); + case "CRC-64/NVME": return this.crc(64n, input, 0xAD93D23594C93659n, 0xFFFFFFFFFFFFFFFFn, true, true, 0xFFFFFFFFFFFFFFFFn); + case "CRC-64/REDIS": return this.crc(64n, input, 0xAD93D23594C935A9n, 0x0000000000000000n, true, true, 0x0000000000000000n); + case "CRC-64/WE": return this.crc(64n, input, 0x42F0E1EBA9EA3693n, 0xFFFFFFFFFFFFFFFFn, false, false, 0xFFFFFFFFFFFFFFFFn); + case "CRC-64/XZ": return this.crc(64n, input, 0x42F0E1EBA9EA3693n, 0xFFFFFFFFFFFFFFFFn, true, true, 0xFFFFFFFFFFFFFFFFn); + case "CRC-82/DARC": return this.crc(82n, input, 0x0308C0111011401440411n, 0x000000000000000000000n, true, true, 0x000000000000000000000n); + default: throw new OperationError("Unknown checksum algorithm"); + } + } + +} + +export default CRCChecksum; diff --git a/tests/operations/tests/CRCChecksum.mjs b/tests/operations/tests/CRCChecksum.mjs new file mode 100644 index 00000000..0c771fbd --- /dev/null +++ b/tests/operations/tests/CRCChecksum.mjs @@ -0,0 +1,20 @@ +/** + * @author r4mos [2k95ljkhg@mozmail.com] + * @copyright Crown Copyright 2025 + * @license Apache-2.0 + */ +import TestRegister from "../../lib//TestRegister.mjs"; + +TestRegister.addApiTests([ + { + name: "CRC-3/GSM", + input: "123456789", + expectedOutput: "4", + recipeConfig: [ + { + "op": "CRC Checksum", + "args": ["CRC-3/GSM"] + } + ] + } +]); diff --git a/tests/operations/tests/Checksum.mjs b/tests/operations/tests/Checksum.mjs deleted file mode 100644 index 142ee267..00000000 --- a/tests/operations/tests/Checksum.mjs +++ /dev/null @@ -1,241 +0,0 @@ -/** - * Checksum tests. - * - * @author n1474335 [n1474335@gmail.com] - * @copyright Crown Copyright 2018 - * @license Apache-2.0 - */ -import TestRegister from "../../lib/TestRegister.mjs"; - -const BASIC_STRING = "The ships hung in the sky in much the same way that bricks don't."; -const UTF8_STR = "ნუ პანიკას"; -const ALL_BYTES = [ - "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f", - "\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f", - "\x20\x21\x22\x23\x24\x25\x26\x27\x28\x29\x2a\x2b\x2c\x2d\x2e\x2f", - "\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x3a\x3b\x3c\x3d\x3e\x3f", - "\x40\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4a\x4b\x4c\x4d\x4e\x4f", - "\x50\x51\x52\x53\x54\x55\x56\x57\x58\x59\x5a\x5b\x5c\x5d\x5e\x5f", - "\x60\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f", - "\x70\x71\x72\x73\x74\x75\x76\x77\x78\x79\x7a\x7b\x7c\x7d\x7e\x7f", - "\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f", - "\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f", - "\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xaa\xab\xac\xad\xae\xaf", - "\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf", - "\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf", - "\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf", - "\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef", - "\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff", -].join(""); - -TestRegister.addTests([ - { - name: "CRC-8: nothing", - input: "", - expectedOutput: "00", - recipeConfig: [ - { - "op": "CRC-8 Checksum", - "args": ["CRC-8"] - } - ] - }, - { - name: "CRC-8: default check", - input: "123456789", - expectedOutput: "f4", - recipeConfig: [ - { - "op": "CRC-8 Checksum", - "args": ["CRC-8"] - } - ] - }, - { - name: "CRC-8: CDMA2000", - input: "123456789", - expectedOutput: "da", - recipeConfig: [ - { - "op": "CRC-8 Checksum", - "args": ["CRC-8/CDMA2000"] - } - ] - }, - { - name: "CRC-8: DARC", - input: "123456789", - expectedOutput: "15", - recipeConfig: [ - { - "op": "CRC-8 Checksum", - "args": ["CRC-8/DARC"] - } - ] - }, - { - name: "CRC-8: DVB-S2", - input: "123456789", - expectedOutput: "bc", - recipeConfig: [ - { - "op": "CRC-8 Checksum", - "args": ["CRC-8/DVB-S2"] - } - ] - }, - { - name: "CRC-8: EBU", - input: "123456789", - expectedOutput: "97", - recipeConfig: [ - { - "op": "CRC-8 Checksum", - "args": ["CRC-8/EBU"] - } - ] - }, - { - name: "CRC-8: I-CODE", - input: "123456789", - expectedOutput: "7e", - recipeConfig: [ - { - "op": "CRC-8 Checksum", - "args": ["CRC-8/I-CODE"] - } - ] - }, - { - name: "CRC-8: ITU", - input: "123456789", - expectedOutput: "a1", - recipeConfig: [ - { - "op": "CRC-8 Checksum", - "args": ["CRC-8/ITU"] - } - ] - }, - { - name: "CRC-8: MAXIM", - input: "123456789", - expectedOutput: "a1", - recipeConfig: [ - { - "op": "CRC-8 Checksum", - "args": ["CRC-8/MAXIM"] - } - ] - }, - { - name: "CRC-8: ROHC", - input: "123456789", - expectedOutput: "d0", - recipeConfig: [ - { - "op": "CRC-8 Checksum", - "args": ["CRC-8/ROHC"] - } - ] - }, - { - name: "CRC-8: WCDMA", - input: "123456789", - expectedOutput: "25", - recipeConfig: [ - { - "op": "CRC-8 Checksum", - "args": ["CRC-8/WCDMA"] - } - ] - }, - { - name: "CRC-16: nothing", - input: "", - expectedOutput: "0000", - recipeConfig: [ - { - "op": "CRC-16 Checksum", - "args": [] - } - ] - }, - { - name: "CRC-16: basic string", - input: BASIC_STRING, - expectedOutput: "0c70", - recipeConfig: [ - { - "op": "CRC-16 Checksum", - "args": [] - } - ] - }, - { - name: "CRC-16: UTF-8", - input: UTF8_STR, - expectedOutput: "dcf6", - recipeConfig: [ - { - "op": "CRC-16 Checksum", - "args": [] - } - ] - }, - { - name: "CRC-16: all bytes", - input: ALL_BYTES, - expectedOutput: "bad3", - recipeConfig: [ - { - "op": "CRC-16 Checksum", - "args": [] - } - ] - }, - { - name: "CRC-32: nothing", - input: "", - expectedOutput: "00000000", - recipeConfig: [ - { - "op": "CRC-32 Checksum", - "args": [] - } - ] - }, - { - name: "CRC-32: basic string", - input: BASIC_STRING, - expectedOutput: "bf4b739c", - recipeConfig: [ - { - "op": "CRC-32 Checksum", - "args": [] - } - ] - }, - { - name: "CRC-32: UTF-8", - input: UTF8_STR, - expectedOutput: "87553290", - recipeConfig: [ - { - "op": "CRC-32 Checksum", - "args": [] - } - ] - }, - { - name: "CRC-32: all bytes", - input: ALL_BYTES, - expectedOutput: "29058c73", - recipeConfig: [ - { - "op": "CRC-32 Checksum", - "args": [] - } - ] - } -]); From 4e62aa6e1dff58edec3373d46662754f389e11be Mon Sep 17 00:00:00 2001 From: r4mos Date: Sun, 2 Mar 2025 01:51:09 +0100 Subject: [PATCH 22/34] The CRC Operation is implemented natively with all currently known CRC's. Old Operations (CRC8, CRC16 and CRC32) and their dependencies are removed --- package.json | 1 - src/core/config/Categories.json | 4 +- src/core/operations/CRCChecksum.mjs | 1 + src/core/operations/GenerateAllHashes.mjs | 10 +- tests/node/tests/operations.mjs | 10 - tests/operations/index.mjs | 2 +- tests/operations/tests/CRCChecksum.mjs | 1983 ++++++++++++++++++++- 7 files changed, 1988 insertions(+), 23 deletions(-) diff --git a/package.json b/package.json index 20180e05..82a675e2 100644 --- a/package.json +++ b/package.json @@ -135,7 +135,6 @@ "ieee754": "^1.2.1", "jimp": "^0.22.12", "jquery": "3.7.1", - "js-crc": "^0.2.0", "js-sha3": "^0.9.3", "jsesc": "^3.0.2", "json5": "^2.2.3", diff --git a/src/core/config/Categories.json b/src/core/config/Categories.json index de3ea882..239efbbc 100644 --- a/src/core/config/Categories.json +++ b/src/core/config/Categories.json @@ -441,9 +441,7 @@ "Fletcher-64 Checksum", "Adler-32 Checksum", "Luhn Checksum", - "CRC-8 Checksum", - "CRC-16 Checksum", - "CRC-32 Checksum", + "CRC Checksum", "TCP/IP Checksum" ] }, diff --git a/src/core/operations/CRCChecksum.mjs b/src/core/operations/CRCChecksum.mjs index b264d010..8a24d303 100644 --- a/src/core/operations/CRCChecksum.mjs +++ b/src/core/operations/CRCChecksum.mjs @@ -349,6 +349,7 @@ class CRCChecksum extends Operation { */ run(input, args) { const algorithm = args[0]; + input = new Uint8Array(input); switch (algorithm) { case "CRC-3/GSM": return this.crc(3n, input, 0x3n, 0x0n, false, false, 0x7n); diff --git a/src/core/operations/GenerateAllHashes.mjs b/src/core/operations/GenerateAllHashes.mjs index d9af8065..06b5f7d9 100644 --- a/src/core/operations/GenerateAllHashes.mjs +++ b/src/core/operations/GenerateAllHashes.mjs @@ -27,9 +27,7 @@ import Fletcher16Checksum from "./Fletcher16Checksum.mjs"; import Fletcher32Checksum from "./Fletcher32Checksum.mjs"; import Fletcher64Checksum from "./Fletcher64Checksum.mjs"; import Adler32Checksum from "./Adler32Checksum.mjs"; -import CRC8Checksum from "./CRC8Checksum.mjs"; -import CRC16Checksum from "./CRC16Checksum.mjs"; -import CRC32Checksum from "./CRC32Checksum.mjs"; +import CRCChecksum from "./CRCChecksum.mjs"; import BLAKE2b from "./BLAKE2b.mjs"; import BLAKE2s from "./BLAKE2s.mjs"; import Streebog from "./Streebog.mjs"; @@ -120,9 +118,9 @@ class GenerateAllHashes extends Operation { {name: "Fletcher-32", algo: (new Fletcher32Checksum), inputType: "byteArray", params: []}, {name: "Fletcher-64", algo: (new Fletcher64Checksum), inputType: "byteArray", params: []}, {name: "Adler-32", algo: (new Adler32Checksum), inputType: "byteArray", params: []}, - {name: "CRC-8", algo: (new CRC8Checksum), inputType: "arrayBuffer", params: ["CRC-8"]}, - {name: "CRC-16", algo: (new CRC16Checksum), inputType: "arrayBuffer", params: []}, - {name: "CRC-32", algo: (new CRC32Checksum), inputType: "arrayBuffer", params: []} + {name: "CRC-8", algo: (new CRCChecksum), inputType: "arrayBuffer", params: ["CRC-8"]}, + {name: "CRC-16", algo: (new CRCChecksum), inputType: "arrayBuffer", params: ["CRC-16"]}, + {name: "CRC-32", algo: (new CRCChecksum), inputType: "arrayBuffer", params: ["CRC-32"]} ]; } diff --git a/tests/node/tests/operations.mjs b/tests/node/tests/operations.mjs index 076fef6c..4c5d4ada 100644 --- a/tests/node/tests/operations.mjs +++ b/tests/node/tests/operations.mjs @@ -305,16 +305,6 @@ Full hash: $2a$10$ODeP1.6fMsb.ENk2ngPUCO7qTGVPyHA9TqDVcyupyed8FjsiF65L6`; assert.strictEqual(result.toString(), "2"); }), - it("CRC16 Checksum", () => { - const result = chef.CRC16Checksum("Rain on Your Parade"); - assert.strictEqual(result.toString(), "db1c"); - }), - - it("CRC32 Checksum", () => { - const result = chef.CRC32Checksum("Rain on Your Parade"); - assert.strictEqual(result.toString(), "e902f76c"); - }), - it("CSS Beautify", () => { const result = chef.CSSBeautify("header {color:black;padding:3rem;}"); const expected = `header { diff --git a/tests/operations/index.mjs b/tests/operations/index.mjs index a82bc874..153338cc 100644 --- a/tests/operations/index.mjs +++ b/tests/operations/index.mjs @@ -44,7 +44,6 @@ import "./tests/ChaCha.mjs"; import "./tests/ChangeIPFormat.mjs"; import "./tests/CharEnc.mjs"; import "./tests/Charts.mjs"; -import "./tests/Checksum.mjs"; import "./tests/Ciphers.mjs"; import "./tests/CipherSaber2.mjs"; import "./tests/CMAC.mjs"; @@ -56,6 +55,7 @@ import "./tests/ConditionalJump.mjs"; import "./tests/ConvertCoordinateFormat.mjs"; import "./tests/ConvertLeetSpeak.mjs"; import "./tests/ConvertToNATOAlphabet.mjs"; +import "./tests/CRCChecksum.mjs"; import "./tests/Crypt.mjs"; import "./tests/CSV.mjs"; import "./tests/DateTime.mjs"; diff --git a/tests/operations/tests/CRCChecksum.mjs b/tests/operations/tests/CRCChecksum.mjs index 0c771fbd..403340dc 100644 --- a/tests/operations/tests/CRCChecksum.mjs +++ b/tests/operations/tests/CRCChecksum.mjs @@ -5,9 +5,118 @@ */ import TestRegister from "../../lib//TestRegister.mjs"; -TestRegister.addApiTests([ +const BASIC_STRING = "The ships hung in the sky in much the same way that bricks don't."; +const UTF8_STR = "ნუ პანიკას"; +const ALL_BYTES = [ + "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f", + "\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f", + "\x20\x21\x22\x23\x24\x25\x26\x27\x28\x29\x2a\x2b\x2c\x2d\x2e\x2f", + "\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x3a\x3b\x3c\x3d\x3e\x3f", + "\x40\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4a\x4b\x4c\x4d\x4e\x4f", + "\x50\x51\x52\x53\x54\x55\x56\x57\x58\x59\x5a\x5b\x5c\x5d\x5e\x5f", + "\x60\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f", + "\x70\x71\x72\x73\x74\x75\x76\x77\x78\x79\x7a\x7b\x7c\x7d\x7e\x7f", + "\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f", + "\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f", + "\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xaa\xab\xac\xad\xae\xaf", + "\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf", + "\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf", + "\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf", + "\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef", + "\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff", +].join(""); + +TestRegister.addTests([ { - name: "CRC-3/GSM", + name: "CRC-16: nothing", + input: "", + expectedOutput: "0000", + recipeConfig: [ + { + "op": "CRC Checksum", + "args": ["CRC-16"] + } + ] + }, + { + name: "CRC-16: basic string", + input: BASIC_STRING, + expectedOutput: "0c70", + recipeConfig: [ + { + "op": "CRC Checksum", + "args": ["CRC-16"] + } + ] + }, + { + name: "CRC-16: UTF-8", + input: UTF8_STR, + expectedOutput: "dcf6", + recipeConfig: [ + { + "op": "CRC Checksum", + "args": ["CRC-16"] + } + ] + }, + { + name: "CRC-16: all bytes", + input: ALL_BYTES, + expectedOutput: "bad3", + recipeConfig: [ + { + "op": "CRC Checksum", + "args": ["CRC-16"] + } + ] + }, + { + name: "CRC-32: nothing", + input: "", + expectedOutput: "00000000", + recipeConfig: [ + { + "op": "CRC Checksum", + "args": ["CRC-32"] + } + ] + }, + { + name: "CRC-32: basic string", + input: BASIC_STRING, + expectedOutput: "bf4b739c", + recipeConfig: [ + { + "op": "CRC Checksum", + "args": ["CRC-32"] + } + ] + }, + { + name: "CRC-32: UTF-8", + input: UTF8_STR, + expectedOutput: "87553290", + recipeConfig: [ + { + "op": "CRC Checksum", + "args": ["CRC-32"] + } + ] + }, + { + name: "CRC-32: all bytes", + input: ALL_BYTES, + expectedOutput: "29058c73", + recipeConfig: [ + { + "op": "CRC Checksum", + "args": ["CRC-32"] + } + ] + }, + { + name: "CRC-3/GSM check", input: "123456789", expectedOutput: "4", recipeConfig: [ @@ -16,5 +125,1875 @@ TestRegister.addApiTests([ "args": ["CRC-3/GSM"] } ] + }, + { + name: "CRC-3/ROHC check", + input: "123456789", + expectedOutput: "6", + recipeConfig: [ + { + "op": "CRC Checksum", + "args": ["CRC-3/ROHC"] + } + ] + }, + { + name: "CRC-4/G-704 check", + input: "123456789", + expectedOutput: "7", + recipeConfig: [ + { + "op": "CRC Checksum", + "args": ["CRC-4/G-704"] + } + ] + }, + { + name: "CRC-4/INTERLAKEN check", + input: "123456789", + expectedOutput: "b", + recipeConfig: [ + { + "op": "CRC Checksum", + "args": ["CRC-4/INTERLAKEN"] + } + ] + }, + { + name: "CRC-4/ITU check", + input: "123456789", + expectedOutput: "7", + recipeConfig: [ + { + "op": "CRC Checksum", + "args": ["CRC-4/ITU"] + } + ] + }, + { + name: "CRC-5/EPC check", + input: "123456789", + expectedOutput: "00", + recipeConfig: [ + { + "op": "CRC Checksum", + "args": ["CRC-5/EPC"] + } + ] + }, + { + name: "CRC-5/EPC-C1G2 check", + input: "123456789", + expectedOutput: "00", + recipeConfig: [ + { + "op": "CRC Checksum", + "args": ["CRC-5/EPC-C1G2"] + } + ] + }, + { + name: "CRC-5/G-704 check", + input: "123456789", + expectedOutput: "07", + recipeConfig: [ + { + "op": "CRC Checksum", + "args": ["CRC-5/G-704"] + } + ] + }, + { + name: "CRC-5/ITU check", + input: "123456789", + expectedOutput: "07", + recipeConfig: [ + { + "op": "CRC Checksum", + "args": ["CRC-5/ITU"] + } + ] + }, + { + name: "CRC-5/USB check", + input: "123456789", + expectedOutput: "19", + recipeConfig: [ + { + "op": "CRC Checksum", + "args": ["CRC-5/USB"] + } + ] + }, + { + name: "CRC-6/CDMA2000-A check", + input: "123456789", + expectedOutput: "0d", + recipeConfig: [ + { + "op": "CRC Checksum", + "args": ["CRC-6/CDMA2000-A"] + } + ] + }, + { + name: "CRC-6/CDMA2000-B check", + input: "123456789", + expectedOutput: "3b", + recipeConfig: [ + { + "op": "CRC Checksum", + "args": ["CRC-6/CDMA2000-B"] + } + ] + }, + { + name: "CRC-6/DARC check", + input: "123456789", + expectedOutput: "26", + recipeConfig: [ + { + "op": "CRC Checksum", + "args": ["CRC-6/DARC"] + } + ] + }, + { + name: "CRC-6/G-704 check", + input: "123456789", + expectedOutput: "06", + recipeConfig: [ + { + "op": "CRC Checksum", + "args": ["CRC-6/G-704"] + } + ] + }, + { + name: "CRC-6/GSM check", + input: "123456789", + expectedOutput: "13", + recipeConfig: [ + { + "op": "CRC Checksum", + "args": ["CRC-6/GSM"] + } + ] + }, + { + name: "CRC-6/ITU check", + input: "123456789", + expectedOutput: "06", + recipeConfig: [ + { + "op": "CRC Checksum", + "args": ["CRC-6/ITU"] + } + ] + }, + { + name: "CRC-7/MMC check", + input: "123456789", + expectedOutput: "75", + recipeConfig: [ + { + "op": "CRC Checksum", + "args": ["CRC-7/MMC"] + } + ] + }, + { + name: "CRC-7/ROHC check", + input: "123456789", + expectedOutput: "53", + recipeConfig: [ + { + "op": "CRC Checksum", + "args": ["CRC-7/ROHC"] + } + ] + }, + { + name: "CRC-7/UMTS check", + input: "123456789", + expectedOutput: "61", + recipeConfig: [ + { + "op": "CRC Checksum", + "args": ["CRC-7/UMTS"] + } + ] + }, + { + name: "CRC-8 check", + input: "123456789", + expectedOutput: "f4", + recipeConfig: [ + { + "op": "CRC Checksum", + "args": ["CRC-8"] + } + ] + }, + { + name: "CRC-8/8H2F check", + input: "123456789", + expectedOutput: "df", + recipeConfig: [ + { + "op": "CRC Checksum", + "args": ["CRC-8/8H2F"] + } + ] + }, + { + name: "CRC-8/AES check", + input: "123456789", + expectedOutput: "97", + recipeConfig: [ + { + "op": "CRC Checksum", + "args": ["CRC-8/AES"] + } + ] + }, + { + name: "CRC-8/AUTOSAR check", + input: "123456789", + expectedOutput: "df", + recipeConfig: [ + { + "op": "CRC Checksum", + "args": ["CRC-8/AUTOSAR"] + } + ] + }, + { + name: "CRC-8/BLUETOOTH check", + input: "123456789", + expectedOutput: "26", + recipeConfig: [ + { + "op": "CRC Checksum", + "args": ["CRC-8/BLUETOOTH"] + } + ] + }, + { + name: "CRC-8/CDMA2000 check", + input: "123456789", + expectedOutput: "da", + recipeConfig: [ + { + "op": "CRC Checksum", + "args": ["CRC-8/CDMA2000"] + } + ] + }, + { + name: "CRC-8/DARC check", + input: "123456789", + expectedOutput: "15", + recipeConfig: [ + { + "op": "CRC Checksum", + "args": ["CRC-8/DARC"] + } + ] + }, + { + name: "CRC-8/DVB-S2 check", + input: "123456789", + expectedOutput: "bc", + recipeConfig: [ + { + "op": "CRC Checksum", + "args": ["CRC-8/DVB-S2"] + } + ] + }, + { + name: "CRC-8/EBU check", + input: "123456789", + expectedOutput: "97", + recipeConfig: [ + { + "op": "CRC Checksum", + "args": ["CRC-8/EBU"] + } + ] + }, + { + name: "CRC-8/GSM-A check", + input: "123456789", + expectedOutput: "37", + recipeConfig: [ + { + "op": "CRC Checksum", + "args": ["CRC-8/GSM-A"] + } + ] + }, + { + name: "CRC-8/GSM-B check", + input: "123456789", + expectedOutput: "94", + recipeConfig: [ + { + "op": "CRC Checksum", + "args": ["CRC-8/GSM-B"] + } + ] + }, + { + name: "CRC-8/HITAG check", + input: "123456789", + expectedOutput: "b4", + recipeConfig: [ + { + "op": "CRC Checksum", + "args": ["CRC-8/HITAG"] + } + ] + }, + { + name: "CRC-8/I-432-1 check", + input: "123456789", + expectedOutput: "a1", + recipeConfig: [ + { + "op": "CRC Checksum", + "args": ["CRC-8/I-432-1"] + } + ] + }, + { + name: "CRC-8/I-CODE check", + input: "123456789", + expectedOutput: "7e", + recipeConfig: [ + { + "op": "CRC Checksum", + "args": ["CRC-8/I-CODE"] + } + ] + }, + { + name: "CRC-8/ITU check", + input: "123456789", + expectedOutput: "a1", + recipeConfig: [ + { + "op": "CRC Checksum", + "args": ["CRC-8/ITU"] + } + ] + }, + { + name: "CRC-8/LTE check", + input: "123456789", + expectedOutput: "ea", + recipeConfig: [ + { + "op": "CRC Checksum", + "args": ["CRC-8/LTE"] + } + ] + }, + { + name: "CRC-8/MAXIM check", + input: "123456789", + expectedOutput: "a1", + recipeConfig: [ + { + "op": "CRC Checksum", + "args": ["CRC-8/MAXIM"] + } + ] + }, + { + name: "CRC-8/MAXIM-DOW check", + input: "123456789", + expectedOutput: "a1", + recipeConfig: [ + { + "op": "CRC Checksum", + "args": ["CRC-8/MAXIM-DOW"] + } + ] + }, + { + name: "CRC-8/MIFARE-MAD check", + input: "123456789", + expectedOutput: "99", + recipeConfig: [ + { + "op": "CRC Checksum", + "args": ["CRC-8/MIFARE-MAD"] + } + ] + }, + { + name: "CRC-8/NRSC-5 check", + input: "123456789", + expectedOutput: "f7", + recipeConfig: [ + { + "op": "CRC Checksum", + "args": ["CRC-8/NRSC-5"] + } + ] + }, + { + name: "CRC-8/OPENSAFETY check", + input: "123456789", + expectedOutput: "3e", + recipeConfig: [ + { + "op": "CRC Checksum", + "args": ["CRC-8/OPENSAFETY"] + } + ] + }, + { + name: "CRC-8/ROHC check", + input: "123456789", + expectedOutput: "d0", + recipeConfig: [ + { + "op": "CRC Checksum", + "args": ["CRC-8/ROHC"] + } + ] + }, + { + name: "CRC-8/SAE-J1850 check", + input: "123456789", + expectedOutput: "4b", + recipeConfig: [ + { + "op": "CRC Checksum", + "args": ["CRC-8/SAE-J1850"] + } + ] + }, + { + name: "CRC-8/SAE-J1850-ZERO check", + input: "123456789", + expectedOutput: "37", + recipeConfig: [ + { + "op": "CRC Checksum", + "args": ["CRC-8/SAE-J1850-ZERO"] + } + ] + }, + { + name: "CRC-8/SMBUS check", + input: "123456789", + expectedOutput: "f4", + recipeConfig: [ + { + "op": "CRC Checksum", + "args": ["CRC-8/SMBUS"] + } + ] + }, + { + name: "CRC-8/TECH-3250 check", + input: "123456789", + expectedOutput: "97", + recipeConfig: [ + { + "op": "CRC Checksum", + "args": ["CRC-8/TECH-3250"] + } + ] + }, + { + name: "CRC-8/WCDMA check", + input: "123456789", + expectedOutput: "25", + recipeConfig: [ + { + "op": "CRC Checksum", + "args": ["CRC-8/WCDMA"] + } + ] + }, + { + name: "CRC-10/ATM check", + input: "123456789", + expectedOutput: "199", + recipeConfig: [ + { + "op": "CRC Checksum", + "args": ["CRC-10/ATM"] + } + ] + }, + { + name: "CRC-10/CDMA2000 check", + input: "123456789", + expectedOutput: "233", + recipeConfig: [ + { + "op": "CRC Checksum", + "args": ["CRC-10/CDMA2000"] + } + ] + }, + { + name: "CRC-10/GSM check", + input: "123456789", + expectedOutput: "12a", + recipeConfig: [ + { + "op": "CRC Checksum", + "args": ["CRC-10/GSM"] + } + ] + }, + { + name: "CRC-10/I-610 check", + input: "123456789", + expectedOutput: "199", + recipeConfig: [ + { + "op": "CRC Checksum", + "args": ["CRC-10/I-610"] + } + ] + }, + { + name: "CRC-11/FLEXRAY check", + input: "123456789", + expectedOutput: "5a3", + recipeConfig: [ + { + "op": "CRC Checksum", + "args": ["CRC-11/FLEXRAY"] + } + ] + }, + { + name: "CRC-11/UMTS check", + input: "123456789", + expectedOutput: "061", + recipeConfig: [ + { + "op": "CRC Checksum", + "args": ["CRC-11/UMTS"] + } + ] + }, + { + name: "CRC-12/3GPP check", + input: "123456789", + expectedOutput: "daf", + recipeConfig: [ + { + "op": "CRC Checksum", + "args": ["CRC-12/3GPP"] + } + ] + }, + { + name: "CRC-12/CDMA2000 check", + input: "123456789", + expectedOutput: "d4d", + recipeConfig: [ + { + "op": "CRC Checksum", + "args": ["CRC-12/CDMA2000"] + } + ] + }, + { + name: "CRC-12/DECT check", + input: "123456789", + expectedOutput: "f5b", + recipeConfig: [ + { + "op": "CRC Checksum", + "args": ["CRC-12/DECT"] + } + ] + }, + { + name: "CRC-12/GSM check", + input: "123456789", + expectedOutput: "b34", + recipeConfig: [ + { + "op": "CRC Checksum", + "args": ["CRC-12/GSM"] + } + ] + }, + { + name: "CRC-12/UMTS check", + input: "123456789", + expectedOutput: "daf", + recipeConfig: [ + { + "op": "CRC Checksum", + "args": ["CRC-12/UMTS"] + } + ] + }, + { + name: "CRC-13/BBC check", + input: "123456789", + expectedOutput: "04fa", + recipeConfig: [ + { + "op": "CRC Checksum", + "args": ["CRC-13/BBC"] + } + ] + }, + { + name: "CRC-14/DARC check", + input: "123456789", + expectedOutput: "082d", + recipeConfig: [ + { + "op": "CRC Checksum", + "args": ["CRC-14/DARC"] + } + ] + }, + { + name: "CRC-14/GSM check", + input: "123456789", + expectedOutput: "30ae", + recipeConfig: [ + { + "op": "CRC Checksum", + "args": ["CRC-14/GSM"] + } + ] + }, + { + name: "CRC-15/CAN check", + input: "123456789", + expectedOutput: "059e", + recipeConfig: [ + { + "op": "CRC Checksum", + "args": ["CRC-15/CAN"] + } + ] + }, + { + name: "CRC-15/MPT1327 check", + input: "123456789", + expectedOutput: "2566", + recipeConfig: [ + { + "op": "CRC Checksum", + "args": ["CRC-15/MPT1327"] + } + ] + }, + { + name: "CRC-16 check", + input: "123456789", + expectedOutput: "bb3d", + recipeConfig: [ + { + "op": "CRC Checksum", + "args": ["CRC-16"] + } + ] + }, + { + name: "CRC-16/A check", + input: "123456789", + expectedOutput: "bf05", + recipeConfig: [ + { + "op": "CRC Checksum", + "args": ["CRC-16/A"] + } + ] + }, + { + name: "CRC-16/ACORN check", + input: "123456789", + expectedOutput: "31c3", + recipeConfig: [ + { + "op": "CRC Checksum", + "args": ["CRC-16/ACORN"] + } + ] + }, + { + name: "CRC-16/ARC check", + input: "123456789", + expectedOutput: "bb3d", + recipeConfig: [ + { + "op": "CRC Checksum", + "args": ["CRC-16/ARC"] + } + ] + }, + { + name: "CRC-16/AUG-CCITT check", + input: "123456789", + expectedOutput: "e5cc", + recipeConfig: [ + { + "op": "CRC Checksum", + "args": ["CRC-16/AUG-CCITT"] + } + ] + }, + { + name: "CRC-16/AUTOSAR check", + input: "123456789", + expectedOutput: "29b1", + recipeConfig: [ + { + "op": "CRC Checksum", + "args": ["CRC-16/AUTOSAR"] + } + ] + }, + { + name: "CRC-16/B check", + input: "123456789", + expectedOutput: "906e", + recipeConfig: [ + { + "op": "CRC Checksum", + "args": ["CRC-16/B"] + } + ] + }, + { + name: "CRC-16/BLUETOOTH check", + input: "123456789", + expectedOutput: "2189", + recipeConfig: [ + { + "op": "CRC Checksum", + "args": ["CRC-16/BLUETOOTH"] + } + ] + }, + { + name: "CRC-16/BUYPASS check", + input: "123456789", + expectedOutput: "fee8", + recipeConfig: [ + { + "op": "CRC Checksum", + "args": ["CRC-16/BUYPASS"] + } + ] + }, + { + name: "CRC-16/CCITT check", + input: "123456789", + expectedOutput: "2189", + recipeConfig: [ + { + "op": "CRC Checksum", + "args": ["CRC-16/CCITT"] + } + ] + }, + { + name: "CRC-16/CCITT-FALSE check", + input: "123456789", + expectedOutput: "29b1", + recipeConfig: [ + { + "op": "CRC Checksum", + "args": ["CRC-16/CCITT-FALSE"] + } + ] + }, + { + name: "CRC-16/CCITT-TRUE check", + input: "123456789", + expectedOutput: "2189", + recipeConfig: [ + { + "op": "CRC Checksum", + "args": ["CRC-16/CCITT-TRUE"] + } + ] + }, + { + name: "CRC-16/CCITT-ZERO check", + input: "123456789", + expectedOutput: "31c3", + recipeConfig: [ + { + "op": "CRC Checksum", + "args": ["CRC-16/CCITT-ZERO"] + } + ] + }, + { + name: "CRC-16/CDMA2000 check", + input: "123456789", + expectedOutput: "4c06", + recipeConfig: [ + { + "op": "CRC Checksum", + "args": ["CRC-16/CDMA2000"] + } + ] + }, + { + name: "CRC-16/CMS check", + input: "123456789", + expectedOutput: "aee7", + recipeConfig: [ + { + "op": "CRC Checksum", + "args": ["CRC-16/CMS"] + } + ] + }, + { + name: "CRC-16/DARC check", + input: "123456789", + expectedOutput: "d64e", + recipeConfig: [ + { + "op": "CRC Checksum", + "args": ["CRC-16/DARC"] + } + ] + }, + { + name: "CRC-16/DDS-110 check", + input: "123456789", + expectedOutput: "9ecf", + recipeConfig: [ + { + "op": "CRC Checksum", + "args": ["CRC-16/DDS-110"] + } + ] + }, + { + name: "CRC-16/DECT-R check", + input: "123456789", + expectedOutput: "007e", + recipeConfig: [ + { + "op": "CRC Checksum", + "args": ["CRC-16/DECT-R"] + } + ] + }, + { + name: "CRC-16/DECT-X check", + input: "123456789", + expectedOutput: "007f", + recipeConfig: [ + { + "op": "CRC Checksum", + "args": ["CRC-16/DECT-X"] + } + ] + }, + { + name: "CRC-16/DNP check", + input: "123456789", + expectedOutput: "ea82", + recipeConfig: [ + { + "op": "CRC Checksum", + "args": ["CRC-16/DNP"] + } + ] + }, + { + name: "CRC-16/EN-13757 check", + input: "123456789", + expectedOutput: "c2b7", + recipeConfig: [ + { + "op": "CRC Checksum", + "args": ["CRC-16/EN-13757"] + } + ] + }, + { + name: "CRC-16/EPC check", + input: "123456789", + expectedOutput: "d64e", + recipeConfig: [ + { + "op": "CRC Checksum", + "args": ["CRC-16/EPC"] + } + ] + }, + { + name: "CRC-16/EPC-C1G2 check", + input: "123456789", + expectedOutput: "d64e", + recipeConfig: [ + { + "op": "CRC Checksum", + "args": ["CRC-16/EPC-C1G2"] + } + ] + }, + { + name: "CRC-16/GENIBUS check", + input: "123456789", + expectedOutput: "d64e", + recipeConfig: [ + { + "op": "CRC Checksum", + "args": ["CRC-16/GENIBUS"] + } + ] + }, + { + name: "CRC-16/GSM check", + input: "123456789", + expectedOutput: "ce3c", + recipeConfig: [ + { + "op": "CRC Checksum", + "args": ["CRC-16/GSM"] + } + ] + }, + { + name: "CRC-16/I-CODE check", + input: "123456789", + expectedOutput: "d64e", + recipeConfig: [ + { + "op": "CRC Checksum", + "args": ["CRC-16/I-CODE"] + } + ] + }, + { + name: "CRC-16/IBM check", + input: "123456789", + expectedOutput: "bb3d", + recipeConfig: [ + { + "op": "CRC Checksum", + "args": ["CRC-16/IBM"] + } + ] + }, + { + name: "CRC-16/IBM-3740 check", + input: "123456789", + expectedOutput: "29b1", + recipeConfig: [ + { + "op": "CRC Checksum", + "args": ["CRC-16/IBM-3740"] + } + ] + }, + { + name: "CRC-16/IBM-SDLC check", + input: "123456789", + expectedOutput: "906e", + recipeConfig: [ + { + "op": "CRC Checksum", + "args": ["CRC-16/IBM-SDLC"] + } + ] + }, + { + name: "CRC-16/IEC-61158-2 check", + input: "123456789", + expectedOutput: "a819", + recipeConfig: [ + { + "op": "CRC Checksum", + "args": ["CRC-16/IEC-61158-2"] + } + ] + }, + { + name: "CRC-16/ISO-HDLC check", + input: "123456789", + expectedOutput: "906e", + recipeConfig: [ + { + "op": "CRC Checksum", + "args": ["CRC-16/ISO-HDLC"] + } + ] + }, + { + name: "CRC-16/ISO-IEC-14443-3-A check", + input: "123456789", + expectedOutput: "bf05", + recipeConfig: [ + { + "op": "CRC Checksum", + "args": ["CRC-16/ISO-IEC-14443-3-A"] + } + ] + }, + { + name: "CRC-16/ISO-IEC-14443-3-B check", + input: "123456789", + expectedOutput: "906e", + recipeConfig: [ + { + "op": "CRC Checksum", + "args": ["CRC-16/ISO-IEC-14443-3-B"] + } + ] + }, + { + name: "CRC-16/KERMIT check", + input: "123456789", + expectedOutput: "2189", + recipeConfig: [ + { + "op": "CRC Checksum", + "args": ["CRC-16/KERMIT"] + } + ] + }, + { + name: "CRC-16/LHA check", + input: "123456789", + expectedOutput: "bb3d", + recipeConfig: [ + { + "op": "CRC Checksum", + "args": ["CRC-16/LHA"] + } + ] + }, + { + name: "CRC-16/LJ1200 check", + input: "123456789", + expectedOutput: "bdf4", + recipeConfig: [ + { + "op": "CRC Checksum", + "args": ["CRC-16/LJ1200"] + } + ] + }, + { + name: "CRC-16/LTE check", + input: "123456789", + expectedOutput: "31c3", + recipeConfig: [ + { + "op": "CRC Checksum", + "args": ["CRC-16/LTE"] + } + ] + }, + { + name: "CRC-16/M17 check", + input: "123456789", + expectedOutput: "772b", + recipeConfig: [ + { + "op": "CRC Checksum", + "args": ["CRC-16/M17"] + } + ] + }, + { + name: "CRC-16/MAXIM check", + input: "123456789", + expectedOutput: "44c2", + recipeConfig: [ + { + "op": "CRC Checksum", + "args": ["CRC-16/MAXIM"] + } + ] + }, + { + name: "CRC-16/MAXIM-DOW check", + input: "123456789", + expectedOutput: "44c2", + recipeConfig: [ + { + "op": "CRC Checksum", + "args": ["CRC-16/MAXIM-DOW"] + } + ] + }, + { + name: "CRC-16/MCRF4XX check", + input: "123456789", + expectedOutput: "6f91", + recipeConfig: [ + { + "op": "CRC Checksum", + "args": ["CRC-16/MCRF4XX"] + } + ] + }, + { + name: "CRC-16/MODBUS check", + input: "123456789", + expectedOutput: "4b37", + recipeConfig: [ + { + "op": "CRC Checksum", + "args": ["CRC-16/MODBUS"] + } + ] + }, + { + name: "CRC-16/NRSC-5 check", + input: "123456789", + expectedOutput: "a066", + recipeConfig: [ + { + "op": "CRC Checksum", + "args": ["CRC-16/NRSC-5"] + } + ] + }, + { + name: "CRC-16/OPENSAFETY-A check", + input: "123456789", + expectedOutput: "5d38", + recipeConfig: [ + { + "op": "CRC Checksum", + "args": ["CRC-16/OPENSAFETY-A"] + } + ] + }, + { + name: "CRC-16/OPENSAFETY-B check", + input: "123456789", + expectedOutput: "20fe", + recipeConfig: [ + { + "op": "CRC Checksum", + "args": ["CRC-16/OPENSAFETY-B"] + } + ] + }, + { + name: "CRC-16/PROFIBUS check", + input: "123456789", + expectedOutput: "a819", + recipeConfig: [ + { + "op": "CRC Checksum", + "args": ["CRC-16/PROFIBUS"] + } + ] + }, + { + name: "CRC-16/RIELLO check", + input: "123456789", + expectedOutput: "63d0", + recipeConfig: [ + { + "op": "CRC Checksum", + "args": ["CRC-16/RIELLO"] + } + ] + }, + { + name: "CRC-16/SPI-FUJITSU check", + input: "123456789", + expectedOutput: "e5cc", + recipeConfig: [ + { + "op": "CRC Checksum", + "args": ["CRC-16/SPI-FUJITSU"] + } + ] + }, + { + name: "CRC-16/T10-DIF check", + input: "123456789", + expectedOutput: "d0db", + recipeConfig: [ + { + "op": "CRC Checksum", + "args": ["CRC-16/T10-DIF"] + } + ] + }, + { + name: "CRC-16/TELEDISK check", + input: "123456789", + expectedOutput: "0fb3", + recipeConfig: [ + { + "op": "CRC Checksum", + "args": ["CRC-16/TELEDISK"] + } + ] + }, + { + name: "CRC-16/TMS37157 check", + input: "123456789", + expectedOutput: "26b1", + recipeConfig: [ + { + "op": "CRC Checksum", + "args": ["CRC-16/TMS37157"] + } + ] + }, + { + name: "CRC-16/UMTS check", + input: "123456789", + expectedOutput: "fee8", + recipeConfig: [ + { + "op": "CRC Checksum", + "args": ["CRC-16/UMTS"] + } + ] + }, + { + name: "CRC-16/USB check", + input: "123456789", + expectedOutput: "b4c8", + recipeConfig: [ + { + "op": "CRC Checksum", + "args": ["CRC-16/USB"] + } + ] + }, + { + name: "CRC-16/V-41-LSB check", + input: "123456789", + expectedOutput: "2189", + recipeConfig: [ + { + "op": "CRC Checksum", + "args": ["CRC-16/V-41-LSB"] + } + ] + }, + { + name: "CRC-16/V-41-MSB check", + input: "123456789", + expectedOutput: "31c3", + recipeConfig: [ + { + "op": "CRC Checksum", + "args": ["CRC-16/V-41-MSB"] + } + ] + }, + { + name: "CRC-16/VERIFONE check", + input: "123456789", + expectedOutput: "fee8", + recipeConfig: [ + { + "op": "CRC Checksum", + "args": ["CRC-16/VERIFONE"] + } + ] + }, + { + name: "CRC-16/X-25 check", + input: "123456789", + expectedOutput: "906e", + recipeConfig: [ + { + "op": "CRC Checksum", + "args": ["CRC-16/X-25"] + } + ] + }, + { + name: "CRC-16/XMODEM check", + input: "123456789", + expectedOutput: "31c3", + recipeConfig: [ + { + "op": "CRC Checksum", + "args": ["CRC-16/XMODEM"] + } + ] + }, + { + name: "CRC-16/ZMODEM check", + input: "123456789", + expectedOutput: "31c3", + recipeConfig: [ + { + "op": "CRC Checksum", + "args": ["CRC-16/ZMODEM"] + } + ] + }, + { + name: "CRC-17/CAN-FD check", + input: "123456789", + expectedOutput: "04f03", + recipeConfig: [ + { + "op": "CRC Checksum", + "args": ["CRC-17/CAN-FD"] + } + ] + }, + { + name: "CRC-21/CAN-FD check", + input: "123456789", + expectedOutput: "0ed841", + recipeConfig: [ + { + "op": "CRC Checksum", + "args": ["CRC-21/CAN-FD"] + } + ] + }, + { + name: "CRC-24/BLE check", + input: "123456789", + expectedOutput: "c25a56", + recipeConfig: [ + { + "op": "CRC Checksum", + "args": ["CRC-24/BLE"] + } + ] + }, + { + name: "CRC-24/FLEXRAY-A check", + input: "123456789", + expectedOutput: "7979bd", + recipeConfig: [ + { + "op": "CRC Checksum", + "args": ["CRC-24/FLEXRAY-A"] + } + ] + }, + { + name: "CRC-24/FLEXRAY-B check", + input: "123456789", + expectedOutput: "1f23b8", + recipeConfig: [ + { + "op": "CRC Checksum", + "args": ["CRC-24/FLEXRAY-B"] + } + ] + }, + { + name: "CRC-24/INTERLAKEN check", + input: "123456789", + expectedOutput: "b4f3e6", + recipeConfig: [ + { + "op": "CRC Checksum", + "args": ["CRC-24/INTERLAKEN"] + } + ] + }, + { + name: "CRC-24/LTE-A check", + input: "123456789", + expectedOutput: "cde703", + recipeConfig: [ + { + "op": "CRC Checksum", + "args": ["CRC-24/LTE-A"] + } + ] + }, + { + name: "CRC-24/LTE-B check", + input: "123456789", + expectedOutput: "23ef52", + recipeConfig: [ + { + "op": "CRC Checksum", + "args": ["CRC-24/LTE-B"] + } + ] + }, + { + name: "CRC-24/OPENPGP check", + input: "123456789", + expectedOutput: "21cf02", + recipeConfig: [ + { + "op": "CRC Checksum", + "args": ["CRC-24/OPENPGP"] + } + ] + }, + { + name: "CRC-24/OS-9 check", + input: "123456789", + expectedOutput: "200fa5", + recipeConfig: [ + { + "op": "CRC Checksum", + "args": ["CRC-24/OS-9"] + } + ] + }, + { + name: "CRC-30/CDMA check", + input: "123456789", + expectedOutput: "04c34abf", + recipeConfig: [ + { + "op": "CRC Checksum", + "args": ["CRC-30/CDMA"] + } + ] + }, + { + name: "CRC-31/PHILIPS check", + input: "123456789", + expectedOutput: "0ce9e46c", + recipeConfig: [ + { + "op": "CRC Checksum", + "args": ["CRC-31/PHILIPS"] + } + ] + }, + { + name: "CRC-32 check", + input: "123456789", + expectedOutput: "cbf43926", + recipeConfig: [ + { + "op": "CRC Checksum", + "args": ["CRC-32"] + } + ] + }, + { + name: "CRC-32/AAL5 check", + input: "123456789", + expectedOutput: "fc891918", + recipeConfig: [ + { + "op": "CRC Checksum", + "args": ["CRC-32/AAL5"] + } + ] + }, + { + name: "CRC-32/ADCCP check", + input: "123456789", + expectedOutput: "cbf43926", + recipeConfig: [ + { + "op": "CRC Checksum", + "args": ["CRC-32/ADCCP"] + } + ] + }, + { + name: "CRC-32/AIXM check", + input: "123456789", + expectedOutput: "3010bf7f", + recipeConfig: [ + { + "op": "CRC Checksum", + "args": ["CRC-32/AIXM"] + } + ] + }, + { + name: "CRC-32/AUTOSAR check", + input: "123456789", + expectedOutput: "1697d06a", + recipeConfig: [ + { + "op": "CRC Checksum", + "args": ["CRC-32/AUTOSAR"] + } + ] + }, + { + name: "CRC-32/BASE91-C check", + input: "123456789", + expectedOutput: "e3069283", + recipeConfig: [ + { + "op": "CRC Checksum", + "args": ["CRC-32/BASE91-C"] + } + ] + }, + { + name: "CRC-32/BASE91-D check", + input: "123456789", + expectedOutput: "87315576", + recipeConfig: [ + { + "op": "CRC Checksum", + "args": ["CRC-32/BASE91-D"] + } + ] + }, + { + name: "CRC-32/BZIP2 check", + input: "123456789", + expectedOutput: "fc891918", + recipeConfig: [ + { + "op": "CRC Checksum", + "args": ["CRC-32/BZIP2"] + } + ] + }, + { + name: "CRC-32/C check", + input: "123456789", + expectedOutput: "e3069283", + recipeConfig: [ + { + "op": "CRC Checksum", + "args": ["CRC-32/C"] + } + ] + }, + { + name: "CRC-32/CASTAGNOLI check", + input: "123456789", + expectedOutput: "e3069283", + recipeConfig: [ + { + "op": "CRC Checksum", + "args": ["CRC-32/CASTAGNOLI"] + } + ] + }, + { + name: "CRC-32/CD-ROM-EDC check", + input: "123456789", + expectedOutput: "6ec2edc4", + recipeConfig: [ + { + "op": "CRC Checksum", + "args": ["CRC-32/CD-ROM-EDC"] + } + ] + }, + { + name: "CRC-32/CKSUM check", + input: "123456789", + expectedOutput: "765e7680", + recipeConfig: [ + { + "op": "CRC Checksum", + "args": ["CRC-32/CKSUM"] + } + ] + }, + { + name: "CRC-32/D check", + input: "123456789", + expectedOutput: "87315576", + recipeConfig: [ + { + "op": "CRC Checksum", + "args": ["CRC-32/D"] + } + ] + }, + { + name: "CRC-32/DECT-B check", + input: "123456789", + expectedOutput: "fc891918", + recipeConfig: [ + { + "op": "CRC Checksum", + "args": ["CRC-32/DECT-B"] + } + ] + }, + { + name: "CRC-32/INTERLAKEN check", + input: "123456789", + expectedOutput: "e3069283", + recipeConfig: [ + { + "op": "CRC Checksum", + "args": ["CRC-32/INTERLAKEN"] + } + ] + }, + { + name: "CRC-32/ISCSI check", + input: "123456789", + expectedOutput: "e3069283", + recipeConfig: [ + { + "op": "CRC Checksum", + "args": ["CRC-32/ISCSI"] + } + ] + }, + { + name: "CRC-32/ISO-HDLC check", + input: "123456789", + expectedOutput: "cbf43926", + recipeConfig: [ + { + "op": "CRC Checksum", + "args": ["CRC-32/ISO-HDLC"] + } + ] + }, + { + name: "CRC-32/JAMCRC check", + input: "123456789", + expectedOutput: "340bc6d9", + recipeConfig: [ + { + "op": "CRC Checksum", + "args": ["CRC-32/JAMCRC"] + } + ] + }, + { + name: "CRC-32/MEF check", + input: "123456789", + expectedOutput: "d2c22f51", + recipeConfig: [ + { + "op": "CRC Checksum", + "args": ["CRC-32/MEF"] + } + ] + }, + { + name: "CRC-32/MPEG-2 check", + input: "123456789", + expectedOutput: "0376e6e7", + recipeConfig: [ + { + "op": "CRC Checksum", + "args": ["CRC-32/MPEG-2"] + } + ] + }, + { + name: "CRC-32/NVME check", + input: "123456789", + expectedOutput: "e3069283", + recipeConfig: [ + { + "op": "CRC Checksum", + "args": ["CRC-32/NVME"] + } + ] + }, + { + name: "CRC-32/PKZIP check", + input: "123456789", + expectedOutput: "cbf43926", + recipeConfig: [ + { + "op": "CRC Checksum", + "args": ["CRC-32/PKZIP"] + } + ] + }, + { + name: "CRC-32/POSIX check", + input: "123456789", + expectedOutput: "765e7680", + recipeConfig: [ + { + "op": "CRC Checksum", + "args": ["CRC-32/POSIX"] + } + ] + }, + { + name: "CRC-32/Q check", + input: "123456789", + expectedOutput: "3010bf7f", + recipeConfig: [ + { + "op": "CRC Checksum", + "args": ["CRC-32/Q"] + } + ] + }, + { + name: "CRC-32/SATA check", + input: "123456789", + expectedOutput: "cf72afe8", + recipeConfig: [ + { + "op": "CRC Checksum", + "args": ["CRC-32/SATA"] + } + ] + }, + { + name: "CRC-32/V-42 check", + input: "123456789", + expectedOutput: "cbf43926", + recipeConfig: [ + { + "op": "CRC Checksum", + "args": ["CRC-32/V-42"] + } + ] + }, + { + name: "CRC-32/XFER check", + input: "123456789", + expectedOutput: "bd0be338", + recipeConfig: [ + { + "op": "CRC Checksum", + "args": ["CRC-32/XFER"] + } + ] + }, + { + name: "CRC-32/XZ check", + input: "123456789", + expectedOutput: "cbf43926", + recipeConfig: [ + { + "op": "CRC Checksum", + "args": ["CRC-32/XZ"] + } + ] + }, + { + name: "CRC-40/GSM check", + input: "123456789", + expectedOutput: "d4164fc646", + recipeConfig: [ + { + "op": "CRC Checksum", + "args": ["CRC-40/GSM"] + } + ] + }, + { + name: "CRC-64/ECMA-182 check", + input: "123456789", + expectedOutput: "6c40df5f0b497347", + recipeConfig: [ + { + "op": "CRC Checksum", + "args": ["CRC-64/ECMA-182"] + } + ] + }, + { + name: "CRC-64/GO-ECMA check", + input: "123456789", + expectedOutput: "995dc9bbdf1939fa", + recipeConfig: [ + { + "op": "CRC Checksum", + "args": ["CRC-64/GO-ECMA"] + } + ] + }, + { + name: "CRC-64/GO-ISO check", + input: "123456789", + expectedOutput: "b90956c775a41001", + recipeConfig: [ + { + "op": "CRC Checksum", + "args": ["CRC-64/GO-ISO"] + } + ] + }, + { + name: "CRC-64/MS check", + input: "123456789", + expectedOutput: "75d4b74f024eceea", + recipeConfig: [ + { + "op": "CRC Checksum", + "args": ["CRC-64/MS"] + } + ] + }, + { + name: "CRC-64/NVME check", + input: "123456789", + expectedOutput: "ae8b14860a799888", + recipeConfig: [ + { + "op": "CRC Checksum", + "args": ["CRC-64/NVME"] + } + ] + }, + { + name: "CRC-64/REDIS check", + input: "123456789", + expectedOutput: "e9c6d914c4b8d9ca", + recipeConfig: [ + { + "op": "CRC Checksum", + "args": ["CRC-64/REDIS"] + } + ] + }, + { + name: "CRC-64/WE check", + input: "123456789", + expectedOutput: "62ec59e3f1a4f00a", + recipeConfig: [ + { + "op": "CRC Checksum", + "args": ["CRC-64/WE"] + } + ] + }, + { + name: "CRC-64/XZ check", + input: "123456789", + expectedOutput: "995dc9bbdf1939fa", + recipeConfig: [ + { + "op": "CRC Checksum", + "args": ["CRC-64/XZ"] + } + ] + }, + { + name: "CRC-82/DARC check", + input: "123456789", + expectedOutput: "09ea83f625023801fd612", + recipeConfig: [ + { + "op": "CRC Checksum", + "args": ["CRC-82/DARC"] + } + ] } ]); From 3025391821686a346da6480a970cf8cb0a3e9a85 Mon Sep 17 00:00:00 2001 From: r4mos Date: Mon, 3 Mar 2025 09:19:01 +0100 Subject: [PATCH 23/34] Browser test changed to adapt to new CRC operation --- tests/browser/02_ops.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/browser/02_ops.js b/tests/browser/02_ops.js index 70cfd3ba..7fe7f538 100644 --- a/tests/browser/02_ops.js +++ b/tests/browser/02_ops.js @@ -64,9 +64,9 @@ module.exports = { testOp(browser, ["From Hex", "Bzip2 Decompress"], "425a68393141592653597b0884b7000003038000008200ce00200021a647a4218013709517c5dc914e14241ec2212dc0", "test_output", [[], [true]]); // testOp(browser, "CBOR Decode", "test input", "test output"); // testOp(browser, "CBOR Encode", "test input", "test output"); - testOp(browser, "CRC-16 Checksum", "test input", "77c7"); - testOp(browser, "CRC-32 Checksum", "test input", "29822bc8"); - testOp(browser, "CRC-8 Checksum", "test input", "9d"); + testOp(browser, "CRC Checksum", "test input", "77c7", ["CRC-16"]); + testOp(browser, "CRC Checksum", "test input", "29822bc8", ["CRC-32"]); + testOp(browser, "CRC Checksum", "test input", "9d", ["CRC-8"]); // testOp(browser, "CSS Beautify", "test input", "test_output"); // testOp(browser, "CSS Minify", "test input", "test_output"); // testOp(browser, "CSS selector", "test input", "test_output"); From 1b4760c4476fe9ad380cb485bee972d83efc756e Mon Sep 17 00:00:00 2001 From: r4mos Date: Mon, 3 Mar 2025 17:15:26 +0100 Subject: [PATCH 24/34] Add Custom CRC --- src/core/operations/CRCChecksum.mjs | 922 ++++++++++++++++++++----- tests/operations/tests/CRCChecksum.mjs | 55 ++ 2 files changed, 805 insertions(+), 172 deletions(-) diff --git a/src/core/operations/CRCChecksum.mjs b/src/core/operations/CRCChecksum.mjs index 8a24d303..09ccadbe 100644 --- a/src/core/operations/CRCChecksum.mjs +++ b/src/core/operations/CRCChecksum.mjs @@ -27,180 +27,731 @@ class CRCChecksum extends Operation { this.args = [ { name: "Algorithm", - type: "option", + type: "argSelector", value: [ - "CRC-3/GSM", - "CRC-3/ROHC", - "CRC-4/G-704", - "CRC-4/INTERLAKEN", - "CRC-4/ITU", - "CRC-5/EPC", - "CRC-5/EPC-C1G2", - "CRC-5/G-704", - "CRC-5/ITU", - "CRC-5/USB", - "CRC-6/CDMA2000-A", - "CRC-6/CDMA2000-B", - "CRC-6/DARC", - "CRC-6/G-704", - "CRC-6/GSM", - "CRC-6/ITU", - "CRC-7/MMC", - "CRC-7/ROHC", - "CRC-7/UMTS", - "CRC-8", - "CRC-8/8H2F", - "CRC-8/AES", - "CRC-8/AUTOSAR", - "CRC-8/BLUETOOTH", - "CRC-8/CDMA2000", - "CRC-8/DARC", - "CRC-8/DVB-S2", - "CRC-8/EBU", - "CRC-8/GSM-A", - "CRC-8/GSM-B", - "CRC-8/HITAG", - "CRC-8/I-432-1", - "CRC-8/I-CODE", - "CRC-8/ITU", - "CRC-8/LTE", - "CRC-8/MAXIM", - "CRC-8/MAXIM-DOW", - "CRC-8/MIFARE-MAD", - "CRC-8/NRSC-5", - "CRC-8/OPENSAFETY", - "CRC-8/ROHC", - "CRC-8/SAE-J1850", - "CRC-8/SAE-J1850-ZERO", - "CRC-8/SMBUS", - "CRC-8/TECH-3250", - "CRC-8/WCDMA", - "CRC-10/ATM", - "CRC-10/CDMA2000", - "CRC-10/GSM", - "CRC-10/I-610", - "CRC-11/FLEXRAY", - "CRC-11/UMTS", - "CRC-12/3GPP", - "CRC-12/CDMA2000", - "CRC-12/DECT", - "CRC-12/GSM", - "CRC-12/UMTS", - "CRC-13/BBC", - "CRC-14/DARC", - "CRC-14/GSM", - "CRC-15/CAN", - "CRC-15/MPT1327", - "CRC-16", - "CRC-16/A", - "CRC-16/ACORN", - "CRC-16/ARC", - "CRC-16/AUG-CCITT", - "CRC-16/AUTOSAR", - "CRC-16/B", - "CRC-16/BLUETOOTH", - "CRC-16/BUYPASS", - "CRC-16/CCITT", - "CRC-16/CCITT-FALSE", - "CRC-16/CCITT-TRUE", - "CRC-16/CCITT-ZERO", - "CRC-16/CDMA2000", - "CRC-16/CMS", - "CRC-16/DARC", - "CRC-16/DDS-110", - "CRC-16/DECT-R", - "CRC-16/DECT-X", - "CRC-16/DNP", - "CRC-16/EN-13757", - "CRC-16/EPC", - "CRC-16/EPC-C1G2", - "CRC-16/GENIBUS", - "CRC-16/GSM", - "CRC-16/I-CODE", - "CRC-16/IBM", - "CRC-16/IBM-3740", - "CRC-16/IBM-SDLC", - "CRC-16/IEC-61158-2", - "CRC-16/ISO-HDLC", - "CRC-16/ISO-IEC-14443-3-A", - "CRC-16/ISO-IEC-14443-3-B", - "CRC-16/KERMIT", - "CRC-16/LHA", - "CRC-16/LJ1200", - "CRC-16/LTE", - "CRC-16/M17", - "CRC-16/MAXIM", - "CRC-16/MAXIM-DOW", - "CRC-16/MCRF4XX", - "CRC-16/MODBUS", - "CRC-16/NRSC-5", - "CRC-16/OPENSAFETY-A", - "CRC-16/OPENSAFETY-B", - "CRC-16/PROFIBUS", - "CRC-16/RIELLO", - "CRC-16/SPI-FUJITSU", - "CRC-16/T10-DIF", - "CRC-16/TELEDISK", - "CRC-16/TMS37157", - "CRC-16/UMTS", - "CRC-16/USB", - "CRC-16/V-41-LSB", - "CRC-16/V-41-MSB", - "CRC-16/VERIFONE", - "CRC-16/X-25", - "CRC-16/XMODEM", - "CRC-16/ZMODEM", - "CRC-17/CAN-FD", - "CRC-21/CAN-FD", - "CRC-24/BLE", - "CRC-24/FLEXRAY-A", - "CRC-24/FLEXRAY-B", - "CRC-24/INTERLAKEN", - "CRC-24/LTE-A", - "CRC-24/LTE-B", - "CRC-24/OPENPGP", - "CRC-24/OS-9", - "CRC-30/CDMA", - "CRC-31/PHILIPS", - "CRC-32", - "CRC-32/AAL5", - "CRC-32/ADCCP", - "CRC-32/AIXM", - "CRC-32/AUTOSAR", - "CRC-32/BASE91-C", - "CRC-32/BASE91-D", - "CRC-32/BZIP2", - "CRC-32/C", - "CRC-32/CASTAGNOLI", - "CRC-32/CD-ROM-EDC", - "CRC-32/CKSUM", - "CRC-32/D", - "CRC-32/DECT-B", - "CRC-32/INTERLAKEN", - "CRC-32/ISCSI", - "CRC-32/ISO-HDLC", - "CRC-32/JAMCRC", - "CRC-32/MEF", - "CRC-32/MPEG-2", - "CRC-32/NVME", - "CRC-32/PKZIP", - "CRC-32/POSIX", - "CRC-32/Q", - "CRC-32/SATA", - "CRC-32/V-42", - "CRC-32/XFER", - "CRC-32/XZ", - "CRC-40/GSM", - "CRC-64/ECMA-182", - "CRC-64/GO-ECMA", - "CRC-64/GO-ISO", - "CRC-64/MS", - "CRC-64/NVME", - "CRC-64/REDIS", - "CRC-64/WE", - "CRC-64/XZ", - "CRC-82/DARC" + { + name: "Custom", + on: [1, 2, 3, 4, 5, 6] + }, + { + name: "CRC-3/GSM", + off: [1, 2, 3, 4, 5, 6] + }, + { + name: "CRC-3/ROHC", + off: [1, 2, 3, 4, 5, 6] + }, + { + name: "CRC-4/G-704", + off: [1, 2, 3, 4, 5, 6] + }, + { + name: "CRC-4/INTERLAKEN", + off: [1, 2, 3, 4, 5, 6] + }, + { + name: "CRC-4/ITU", + off: [1, 2, 3, 4, 5, 6] + }, + { + name: "CRC-5/EPC", + off: [1, 2, 3, 4, 5, 6] + }, + { + name: "CRC-5/EPC-C1G2", + off: [1, 2, 3, 4, 5, 6] + }, + { + name: "CRC-5/G-704", + off: [1, 2, 3, 4, 5, 6] + }, + { + name: "CRC-5/ITU", + off: [1, 2, 3, 4, 5, 6] + }, + { + name: "CRC-5/USB", + off: [1, 2, 3, 4, 5, 6] + }, + { + name: "CRC-6/CDMA2000-A", + off: [1, 2, 3, 4, 5, 6] + }, + { + name: "CRC-6/CDMA2000-B", + off: [1, 2, 3, 4, 5, 6] + }, + { + name: "CRC-6/DARC", + off: [1, 2, 3, 4, 5, 6] + }, + { + name: "CRC-6/G-704", + off: [1, 2, 3, 4, 5, 6] + }, + { + name: "CRC-6/GSM", + off: [1, 2, 3, 4, 5, 6] + }, + { + name: "CRC-6/ITU", + off: [1, 2, 3, 4, 5, 6] + }, + { + name: "CRC-7/MMC", + off: [1, 2, 3, 4, 5, 6] + }, + { + name: "CRC-7/ROHC", + off: [1, 2, 3, 4, 5, 6] + }, + { + name: "CRC-7/UMTS", + off: [1, 2, 3, 4, 5, 6] + }, + { + name: "CRC-8", + off: [1, 2, 3, 4, 5, 6] + }, + { + name: "CRC-8/8H2F", + off: [1, 2, 3, 4, 5, 6] + }, + { + name: "CRC-8/AES", + off: [1, 2, 3, 4, 5, 6] + }, + { + name: "CRC-8/AUTOSAR", + off: [1, 2, 3, 4, 5, 6] + }, + { + name: "CRC-8/BLUETOOTH", + off: [1, 2, 3, 4, 5, 6] + }, + { + name: "CRC-8/CDMA2000", + off: [1, 2, 3, 4, 5, 6] + }, + { + name: "CRC-8/DARC", + off: [1, 2, 3, 4, 5, 6] + }, + { + name: "CRC-8/DVB-S2", + off: [1, 2, 3, 4, 5, 6] + }, + { + name: "CRC-8/EBU", + off: [1, 2, 3, 4, 5, 6] + }, + { + name: "CRC-8/GSM-A", + off: [1, 2, 3, 4, 5, 6] + }, + { + name: "CRC-8/GSM-B", + off: [1, 2, 3, 4, 5, 6] + }, + { + name: "CRC-8/HITAG", + off: [1, 2, 3, 4, 5, 6] + }, + { + name: "CRC-8/I-432-1", + off: [1, 2, 3, 4, 5, 6] + }, + { + name: "CRC-8/I-CODE", + off: [1, 2, 3, 4, 5, 6] + }, + { + name: "CRC-8/ITU", + off: [1, 2, 3, 4, 5, 6] + }, + { + name: "CRC-8/LTE", + off: [1, 2, 3, 4, 5, 6] + }, + { + name: "CRC-8/MAXIM", + off: [1, 2, 3, 4, 5, 6] + }, + { + name: "CRC-8/MAXIM-DOW", + off: [1, 2, 3, 4, 5, 6] + }, + { + name: "CRC-8/MIFARE-MAD", + off: [1, 2, 3, 4, 5, 6] + }, + { + name: "CRC-8/NRSC-5", + off: [1, 2, 3, 4, 5, 6] + }, + { + name: "CRC-8/OPENSAFETY", + off: [1, 2, 3, 4, 5, 6] + }, + { + name: "CRC-8/ROHC", + off: [1, 2, 3, 4, 5, 6] + }, + { + name: "CRC-8/SAE-J1850", + off: [1, 2, 3, 4, 5, 6] + }, + { + name: "CRC-8/SAE-J1850-ZERO", + off: [1, 2, 3, 4, 5, 6] + }, + { + name: "CRC-8/SMBUS", + off: [1, 2, 3, 4, 5, 6] + }, + { + name: "CRC-8/TECH-3250", + off: [1, 2, 3, 4, 5, 6] + }, + { + name: "CRC-8/WCDMA", + off: [1, 2, 3, 4, 5, 6] + }, + { + name: "CRC-10/ATM", + off: [1, 2, 3, 4, 5, 6] + }, + { + name: "CRC-10/CDMA2000", + off: [1, 2, 3, 4, 5, 6] + }, + { + name: "CRC-10/GSM", + off: [1, 2, 3, 4, 5, 6] + }, + { + name: "CRC-10/I-610", + off: [1, 2, 3, 4, 5, 6] + }, + { + name: "CRC-11/FLEXRAY", + off: [1, 2, 3, 4, 5, 6] + }, + { + name: "CRC-11/UMTS", + off: [1, 2, 3, 4, 5, 6] + }, + { + name: "CRC-12/3GPP", + off: [1, 2, 3, 4, 5, 6] + }, + { + name: "CRC-12/CDMA2000", + off: [1, 2, 3, 4, 5, 6] + }, + { + name: "CRC-12/DECT", + off: [1, 2, 3, 4, 5, 6] + }, + { + name: "CRC-12/GSM", + off: [1, 2, 3, 4, 5, 6] + }, + { + name: "CRC-12/UMTS", + off: [1, 2, 3, 4, 5, 6] + }, + { + name: "CRC-13/BBC", + off: [1, 2, 3, 4, 5, 6] + }, + { + name: "CRC-14/DARC", + off: [1, 2, 3, 4, 5, 6] + }, + { + name: "CRC-14/GSM", + off: [1, 2, 3, 4, 5, 6] + }, + { + name: "CRC-15/CAN", + off: [1, 2, 3, 4, 5, 6] + }, + { + name: "CRC-15/MPT1327", + off: [1, 2, 3, 4, 5, 6] + }, + { + name: "CRC-16", + off: [1, 2, 3, 4, 5, 6] + }, + { + name: "CRC-16/A", + off: [1, 2, 3, 4, 5, 6] + }, + { + name: "CRC-16/ACORN", + off: [1, 2, 3, 4, 5, 6] + }, + { + name: "CRC-16/ARC", + off: [1, 2, 3, 4, 5, 6] + }, + { + name: "CRC-16/AUG-CCITT", + off: [1, 2, 3, 4, 5, 6] + }, + { + name: "CRC-16/AUTOSAR", + off: [1, 2, 3, 4, 5, 6] + }, + { + name: "CRC-16/B", + off: [1, 2, 3, 4, 5, 6] + }, + { + name: "CRC-16/BLUETOOTH", + off: [1, 2, 3, 4, 5, 6] + }, + { + name: "CRC-16/BUYPASS", + off: [1, 2, 3, 4, 5, 6] + }, + { + name: "CRC-16/CCITT", + off: [1, 2, 3, 4, 5, 6] + }, + { + name: "CRC-16/CCITT-FALSE", + off: [1, 2, 3, 4, 5, 6] + }, + { + name: "CRC-16/CCITT-TRUE", + off: [1, 2, 3, 4, 5, 6] + }, + { + name: "CRC-16/CCITT-ZERO", + off: [1, 2, 3, 4, 5, 6] + }, + { + name: "CRC-16/CDMA2000", + off: [1, 2, 3, 4, 5, 6] + }, + { + name: "CRC-16/CMS", + off: [1, 2, 3, 4, 5, 6] + }, + { + name: "CRC-16/DARC", + off: [1, 2, 3, 4, 5, 6] + }, + { + name: "CRC-16/DDS-110", + off: [1, 2, 3, 4, 5, 6] + }, + { + name: "CRC-16/DECT-R", + off: [1, 2, 3, 4, 5, 6] + }, + { + name: "CRC-16/DECT-X", + off: [1, 2, 3, 4, 5, 6] + }, + { + name: "CRC-16/DNP", + off: [1, 2, 3, 4, 5, 6] + }, + { + name: "CRC-16/EN-13757", + off: [1, 2, 3, 4, 5, 6] + }, + { + name: "CRC-16/EPC", + off: [1, 2, 3, 4, 5, 6] + }, + { + name: "CRC-16/EPC-C1G2", + off: [1, 2, 3, 4, 5, 6] + }, + { + name: "CRC-16/GENIBUS", + off: [1, 2, 3, 4, 5, 6] + }, + { + name: "CRC-16/GSM", + off: [1, 2, 3, 4, 5, 6] + }, + { + name: "CRC-16/I-CODE", + off: [1, 2, 3, 4, 5, 6] + }, + { + name: "CRC-16/IBM", + off: [1, 2, 3, 4, 5, 6] + }, + { + name: "CRC-16/IBM-3740", + off: [1, 2, 3, 4, 5, 6] + }, + { + name: "CRC-16/IBM-SDLC", + off: [1, 2, 3, 4, 5, 6] + }, + { + name: "CRC-16/IEC-61158-2", + off: [1, 2, 3, 4, 5, 6] + }, + { + name: "CRC-16/ISO-HDLC", + off: [1, 2, 3, 4, 5, 6] + }, + { + name: "CRC-16/ISO-IEC-14443-3-A", + off: [1, 2, 3, 4, 5, 6] + }, + { + name: "CRC-16/ISO-IEC-14443-3-B", + off: [1, 2, 3, 4, 5, 6] + }, + { + name: "CRC-16/KERMIT", + off: [1, 2, 3, 4, 5, 6] + }, + { + name: "CRC-16/LHA", + off: [1, 2, 3, 4, 5, 6] + }, + { + name: "CRC-16/LJ1200", + off: [1, 2, 3, 4, 5, 6] + }, + { + name: "CRC-16/LTE", + off: [1, 2, 3, 4, 5, 6] + }, + { + name: "CRC-16/M17", + off: [1, 2, 3, 4, 5, 6] + }, + { + name: "CRC-16/MAXIM", + off: [1, 2, 3, 4, 5, 6] + }, + { + name: "CRC-16/MAXIM-DOW", + off: [1, 2, 3, 4, 5, 6] + }, + { + name: "CRC-16/MCRF4XX", + off: [1, 2, 3, 4, 5, 6] + }, + { + name: "CRC-16/MODBUS", + off: [1, 2, 3, 4, 5, 6] + }, + { + name: "CRC-16/NRSC-5", + off: [1, 2, 3, 4, 5, 6] + }, + { + name: "CRC-16/OPENSAFETY-A", + off: [1, 2, 3, 4, 5, 6] + }, + { + name: "CRC-16/OPENSAFETY-B", + off: [1, 2, 3, 4, 5, 6] + }, + { + name: "CRC-16/PROFIBUS", + off: [1, 2, 3, 4, 5, 6] + }, + { + name: "CRC-16/RIELLO", + off: [1, 2, 3, 4, 5, 6] + }, + { + name: "CRC-16/SPI-FUJITSU", + off: [1, 2, 3, 4, 5, 6] + }, + { + name: "CRC-16/T10-DIF", + off: [1, 2, 3, 4, 5, 6] + }, + { + name: "CRC-16/TELEDISK", + off: [1, 2, 3, 4, 5, 6] + }, + { + name: "CRC-16/TMS37157", + off: [1, 2, 3, 4, 5, 6] + }, + { + name: "CRC-16/UMTS", + off: [1, 2, 3, 4, 5, 6] + }, + { + name: "CRC-16/USB", + off: [1, 2, 3, 4, 5, 6] + }, + { + name: "CRC-16/V-41-LSB", + off: [1, 2, 3, 4, 5, 6] + }, + { + name: "CRC-16/V-41-MSB", + off: [1, 2, 3, 4, 5, 6] + }, + { + name: "CRC-16/VERIFONE", + off: [1, 2, 3, 4, 5, 6] + }, + { + name: "CRC-16/X-25", + off: [1, 2, 3, 4, 5, 6] + }, + { + name: "CRC-16/XMODEM", + off: [1, 2, 3, 4, 5, 6] + }, + { + name: "CRC-16/ZMODEM", + off: [1, 2, 3, 4, 5, 6] + }, + { + name: "CRC-17/CAN-FD", + off: [1, 2, 3, 4, 5, 6] + }, + { + name: "CRC-21/CAN-FD", + off: [1, 2, 3, 4, 5, 6] + }, + { + name: "CRC-24/BLE", + off: [1, 2, 3, 4, 5, 6] + }, + { + name: "CRC-24/FLEXRAY-A", + off: [1, 2, 3, 4, 5, 6] + }, + { + name: "CRC-24/FLEXRAY-B", + off: [1, 2, 3, 4, 5, 6] + }, + { + name: "CRC-24/INTERLAKEN", + off: [1, 2, 3, 4, 5, 6] + }, + { + name: "CRC-24/LTE-A", + off: [1, 2, 3, 4, 5, 6] + }, + { + name: "CRC-24/LTE-B", + off: [1, 2, 3, 4, 5, 6] + }, + { + name: "CRC-24/OPENPGP", + off: [1, 2, 3, 4, 5, 6] + }, + { + name: "CRC-24/OS-9", + off: [1, 2, 3, 4, 5, 6] + }, + { + name: "CRC-30/CDMA", + off: [1, 2, 3, 4, 5, 6] + }, + { + name: "CRC-31/PHILIPS", + off: [1, 2, 3, 4, 5, 6] + }, + { + name: "CRC-32", + off: [1, 2, 3, 4, 5, 6] + }, + { + name: "CRC-32/AAL5", + off: [1, 2, 3, 4, 5, 6] + }, + { + name: "CRC-32/ADCCP", + off: [1, 2, 3, 4, 5, 6] + }, + { + name: "CRC-32/AIXM", + off: [1, 2, 3, 4, 5, 6] + }, + { + name: "CRC-32/AUTOSAR", + off: [1, 2, 3, 4, 5, 6] + }, + { + name: "CRC-32/BASE91-C", + off: [1, 2, 3, 4, 5, 6] + }, + { + name: "CRC-32/BASE91-D", + off: [1, 2, 3, 4, 5, 6] + }, + { + name: "CRC-32/BZIP2", + off: [1, 2, 3, 4, 5, 6] + }, + { + name: "CRC-32/C", + off: [1, 2, 3, 4, 5, 6] + }, + { + name: "CRC-32/CASTAGNOLI", + off: [1, 2, 3, 4, 5, 6] + }, + { + name: "CRC-32/CD-ROM-EDC", + off: [1, 2, 3, 4, 5, 6] + }, + { + name: "CRC-32/CKSUM", + off: [1, 2, 3, 4, 5, 6] + }, + { + name: "CRC-32/D", + off: [1, 2, 3, 4, 5, 6] + }, + { + name: "CRC-32/DECT-B", + off: [1, 2, 3, 4, 5, 6] + }, + { + name: "CRC-32/INTERLAKEN", + off: [1, 2, 3, 4, 5, 6] + }, + { + name: "CRC-32/ISCSI", + off: [1, 2, 3, 4, 5, 6] + }, + { + name: "CRC-32/ISO-HDLC", + off: [1, 2, 3, 4, 5, 6] + }, + { + name: "CRC-32/JAMCRC", + off: [1, 2, 3, 4, 5, 6] + }, + { + name: "CRC-32/MEF", + off: [1, 2, 3, 4, 5, 6] + }, + { + name: "CRC-32/MPEG-2", + off: [1, 2, 3, 4, 5, 6] + }, + { + name: "CRC-32/NVME", + off: [1, 2, 3, 4, 5, 6] + }, + { + name: "CRC-32/PKZIP", + off: [1, 2, 3, 4, 5, 6] + }, + { + name: "CRC-32/POSIX", + off: [1, 2, 3, 4, 5, 6] + }, + { + name: "CRC-32/Q", + off: [1, 2, 3, 4, 5, 6] + }, + { + name: "CRC-32/SATA", + off: [1, 2, 3, 4, 5, 6] + }, + { + name: "CRC-32/V-42", + off: [1, 2, 3, 4, 5, 6] + }, + { + name: "CRC-32/XFER", + off: [1, 2, 3, 4, 5, 6] + }, + { + name: "CRC-32/XZ", + off: [1, 2, 3, 4, 5, 6] + }, + { + name: "CRC-40/GSM", + off: [1, 2, 3, 4, 5, 6] + }, + { + name: "CRC-64/ECMA-182", + off: [1, 2, 3, 4, 5, 6] + }, + { + name: "CRC-64/GO-ECMA", + off: [1, 2, 3, 4, 5, 6] + }, + { + name: "CRC-64/GO-ISO", + off: [1, 2, 3, 4, 5, 6] + }, + { + name: "CRC-64/MS", + off: [1, 2, 3, 4, 5, 6] + }, + { + name: "CRC-64/NVME", + off: [1, 2, 3, 4, 5, 6] + }, + { + name: "CRC-64/REDIS", + off: [1, 2, 3, 4, 5, 6] + }, + { + name: "CRC-64/WE", + off: [1, 2, 3, 4, 5, 6] + }, + { + name: "CRC-64/XZ", + off: [1, 2, 3, 4, 5, 6] + }, + { + name: "CRC-82/DARC", + off: [1, 2, 3, 4, 5, 6] + } ] + }, + { + name: "Width (bits)", + type: "toggleString", + value: "0", + toggleValues: ["Decimal"] + }, + { + name: "Polynomial", + type: "toggleString", + value: "0", + toggleValues: ["Hex"] + }, + { + name: "Initialization", + type: "toggleString", + value: "0", + toggleValues: ["Hex"] + }, + { + name: "Reflect input", + type: "option", + value: ["True", "False"] + }, + { + name: "Reflect output", + type: "option", + value: ["True", "False"] + }, + { + name: "Xor Output", + type: "toggleString", + value: "0", + toggleValues: ["Hex"] } ]; } @@ -340,6 +891,32 @@ class CRCChecksum extends Operation { return VALUE.toString(16).padStart(Math.ceil(Number(width) / 4), "0"); } + /** + * Validates user input to perform a custom CRC + * + * @param {Object} widthObject + * @param {ArrayBuffer} input + * @param {Object} polyObject + * @param {Object} initObject + * @param {Object} reflectInObject + * @param {Object} reflectOutObject + * @param {Object} xorOutObject + */ + custom(widthObject, input, polyObject, initObject, reflectInObject, reflectOutObject, xorOutObject) { + try { + const width = BigInt(widthObject.string); + const poly = BigInt("0x" + polyObject.string); + const init = BigInt("0x" + initObject.string); + const reflectIn = reflectInObject.string === "True"; + const reflectOut = reflectOutObject.string === "True"; + const xorOut = BigInt("0x" + xorOutObject.string); + + return this.crc(width, input, poly, init, reflectIn, reflectOut, xorOut); + } catch (error) { + throw new OperationError("Invalid custom CRC arguments"); + } + } + /** * Calculation of all known CRCs. Names and constants extracted from https://reveng.sourceforge.io/crc-catalogue/all.htm * @@ -352,6 +929,7 @@ class CRCChecksum extends Operation { input = new Uint8Array(input); switch (algorithm) { + case "Custom": return this.custom(args[1], input, args[2], args[3], args[4], args[5], args[6]); case "CRC-3/GSM": return this.crc(3n, input, 0x3n, 0x0n, false, false, 0x7n); case "CRC-3/ROHC": return this.crc(3n, input, 0x3n, 0x7n, true, true, 0x0n); case "CRC-4/G-704": return this.crc(4n, input, 0x3n, 0x0n, true, true, 0x0n); diff --git a/tests/operations/tests/CRCChecksum.mjs b/tests/operations/tests/CRCChecksum.mjs index 403340dc..af21ba7f 100644 --- a/tests/operations/tests/CRCChecksum.mjs +++ b/tests/operations/tests/CRCChecksum.mjs @@ -1995,5 +1995,60 @@ TestRegister.addTests([ "args": ["CRC-82/DARC"] } ] + }, + { + name: "Custom. CRC-32", + input: "123456789", + expectedOutput: "cbf43926", + recipeConfig: [ + { + "op": "CRC Checksum", + "args": ["Custom", "32", "04C11DB7", "FFFFFFFF", "True", "True", "FFFFFFFF"] + } + ] + }, + { + name: "Custom. Invalid Width", + input: "123456789", + expectedOutput: "Invalid custom CRC arguments", + recipeConfig: [ + { + "op": "CRC Checksum", + "args": ["Custom", "ABC", "04C11DB7", "FFFFFFFF", "True", "True", "FFFFFFFF"] + } + ] + }, + { + name: "Custom. Invalid Poly", + input: "123456789", + expectedOutput: "Invalid custom CRC arguments", + recipeConfig: [ + { + "op": "CRC Checksum", + "args": ["Custom", "32", "", "FFFFFFFF", "True", "True", "FFFFFFFF"] + } + ] + }, + { + name: "Custom. Invalid Init", + input: "123456789", + expectedOutput: "Invalid custom CRC arguments", + recipeConfig: [ + { + "op": "CRC Checksum", + "args": ["Custom", "32", "04C11DB7", "", "True", "True", "FFFFFFFF"] + } + ] + }, + { + name: "Custom. Invalid Xor Out", + input: "123456789", + expectedOutput: "Invalid custom CRC arguments", + recipeConfig: [ + { + "op": "CRC Checksum", + "args": ["Custom", "32", "04C11DB7", "FFFFFFFF", "True", "True", ""] + } + ] } ]); From 566b42306561976d90ad2f69d488709784c84c96 Mon Sep 17 00:00:00 2001 From: r4mos Date: Mon, 3 Mar 2025 17:33:54 +0100 Subject: [PATCH 25/34] Correct forgotten test --- tests/operations/tests/CRCChecksum.mjs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/tests/operations/tests/CRCChecksum.mjs b/tests/operations/tests/CRCChecksum.mjs index af21ba7f..5a16e89c 100644 --- a/tests/operations/tests/CRCChecksum.mjs +++ b/tests/operations/tests/CRCChecksum.mjs @@ -2003,7 +2003,7 @@ TestRegister.addTests([ recipeConfig: [ { "op": "CRC Checksum", - "args": ["Custom", "32", "04C11DB7", "FFFFFFFF", "True", "True", "FFFFFFFF"] + "args": ["Custom", {"option": "Decimal", string: "32"}, {"option": "Hex", string: "04C11DB7"}, {"option": "Hex", string: "FFFFFFFF"}, {string: "True"}, {string: "True"}, {"option": "Hex", string: "FFFFFFFF"}] } ] }, @@ -2014,7 +2014,7 @@ TestRegister.addTests([ recipeConfig: [ { "op": "CRC Checksum", - "args": ["Custom", "ABC", "04C11DB7", "FFFFFFFF", "True", "True", "FFFFFFFF"] + "args": ["Custom", {"option": "Decimal", string: "ABC"}, {"option": "Hex", string: "04C11DB7"}, {"option": "Hex", string: "FFFFFFFF"}, {string: "True"}, {string: "True"}, {"option": "Hex", string: "FFFFFFFF"}] } ] }, @@ -2025,7 +2025,7 @@ TestRegister.addTests([ recipeConfig: [ { "op": "CRC Checksum", - "args": ["Custom", "32", "", "FFFFFFFF", "True", "True", "FFFFFFFF"] + "args": ["Custom", {"option": "Decimal", string: "32"}, {"option": "Hex", string: ""}, {"option": "Hex", string: "FFFFFFFF"}, {string: "True"}, {string: "True"}, {"option": "Hex", string: "FFFFFFFF"}] } ] }, @@ -2036,7 +2036,7 @@ TestRegister.addTests([ recipeConfig: [ { "op": "CRC Checksum", - "args": ["Custom", "32", "04C11DB7", "", "True", "True", "FFFFFFFF"] + "args": ["Custom", {"option": "Decimal", string: "32"}, {"option": "Hex", string: "04C11DB7"}, {"option": "Hex", string: ""}, {string: "True"}, {string: "True"}, {"option": "Hex", string: "FFFFFFFF"}] } ] }, @@ -2047,7 +2047,7 @@ TestRegister.addTests([ recipeConfig: [ { "op": "CRC Checksum", - "args": ["Custom", "32", "04C11DB7", "FFFFFFFF", "True", "True", ""] + "args": ["Custom", {"option": "Decimal", string: "32"}, {"option": "Hex", string: "04C11DB7"}, {"option": "Hex", string: "FFFFFFFF"}, {string: "True"}, {string: "True"}, {"option": "Hex", string: ""}] } ] } From d5f007deeabe16ac6f7d86d1e72bc5bc3acff2a1 Mon Sep 17 00:00:00 2001 From: r4mos Date: Tue, 4 Mar 2025 08:43:16 +0100 Subject: [PATCH 26/34] Fixed non-working buttons --- src/core/operations/CRCChecksum.mjs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/core/operations/CRCChecksum.mjs b/src/core/operations/CRCChecksum.mjs index 09ccadbe..88da2fa5 100644 --- a/src/core/operations/CRCChecksum.mjs +++ b/src/core/operations/CRCChecksum.mjs @@ -907,8 +907,8 @@ class CRCChecksum extends Operation { const width = BigInt(widthObject.string); const poly = BigInt("0x" + polyObject.string); const init = BigInt("0x" + initObject.string); - const reflectIn = reflectInObject.string === "True"; - const reflectOut = reflectOutObject.string === "True"; + const reflectIn = reflectInObject === "True"; + const reflectOut = reflectOutObject === "True"; const xorOut = BigInt("0x" + xorOutObject.string); return this.crc(width, input, poly, init, reflectIn, reflectOut, xorOut); From 42efc0187c343abf99d05c02c378402d8362cef2 Mon Sep 17 00:00:00 2001 From: r4mos Date: Tue, 4 Mar 2025 08:46:41 +0100 Subject: [PATCH 27/34] Fixed Test for non-working buttons --- tests/operations/tests/CRCChecksum.mjs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/tests/operations/tests/CRCChecksum.mjs b/tests/operations/tests/CRCChecksum.mjs index 5a16e89c..aa504393 100644 --- a/tests/operations/tests/CRCChecksum.mjs +++ b/tests/operations/tests/CRCChecksum.mjs @@ -2003,7 +2003,7 @@ TestRegister.addTests([ recipeConfig: [ { "op": "CRC Checksum", - "args": ["Custom", {"option": "Decimal", string: "32"}, {"option": "Hex", string: "04C11DB7"}, {"option": "Hex", string: "FFFFFFFF"}, {string: "True"}, {string: "True"}, {"option": "Hex", string: "FFFFFFFF"}] + "args": ["Custom", {"option": "Decimal", string: "32"}, {"option": "Hex", string: "04C11DB7"}, {"option": "Hex", string: "FFFFFFFF"}, "True", "True", {"option": "Hex", string: "FFFFFFFF"}] } ] }, @@ -2014,7 +2014,7 @@ TestRegister.addTests([ recipeConfig: [ { "op": "CRC Checksum", - "args": ["Custom", {"option": "Decimal", string: "ABC"}, {"option": "Hex", string: "04C11DB7"}, {"option": "Hex", string: "FFFFFFFF"}, {string: "True"}, {string: "True"}, {"option": "Hex", string: "FFFFFFFF"}] + "args": ["Custom", {"option": "Decimal", string: "ABC"}, {"option": "Hex", string: "04C11DB7"}, {"option": "Hex", string: "FFFFFFFF"}, "True", "True", {"option": "Hex", string: "FFFFFFFF"}] } ] }, @@ -2025,7 +2025,7 @@ TestRegister.addTests([ recipeConfig: [ { "op": "CRC Checksum", - "args": ["Custom", {"option": "Decimal", string: "32"}, {"option": "Hex", string: ""}, {"option": "Hex", string: "FFFFFFFF"}, {string: "True"}, {string: "True"}, {"option": "Hex", string: "FFFFFFFF"}] + "args": ["Custom", {"option": "Decimal", string: "32"}, {"option": "Hex", string: ""}, {"option": "Hex", string: "FFFFFFFF"}, "True", "True", {"option": "Hex", string: "FFFFFFFF"}] } ] }, @@ -2036,7 +2036,7 @@ TestRegister.addTests([ recipeConfig: [ { "op": "CRC Checksum", - "args": ["Custom", {"option": "Decimal", string: "32"}, {"option": "Hex", string: "04C11DB7"}, {"option": "Hex", string: ""}, {string: "True"}, {string: "True"}, {"option": "Hex", string: "FFFFFFFF"}] + "args": ["Custom", {"option": "Decimal", string: "32"}, {"option": "Hex", string: "04C11DB7"}, {"option": "Hex", string: ""}, "True", "True", {"option": "Hex", string: "FFFFFFFF"}] } ] }, @@ -2047,7 +2047,7 @@ TestRegister.addTests([ recipeConfig: [ { "op": "CRC Checksum", - "args": ["Custom", {"option": "Decimal", string: "32"}, {"option": "Hex", string: "04C11DB7"}, {"option": "Hex", string: "FFFFFFFF"}, {string: "True"}, {string: "True"}, {"option": "Hex", string: ""}] + "args": ["Custom", {"option": "Decimal", string: "32"}, {"option": "Hex", string: "04C11DB7"}, {"option": "Hex", string: "FFFFFFFF"}, "True", "True", {"option": "Hex", string: ""}] } ] } From a809321b639d2e16c7cbfbbf2b683e0c2d04d8d4 Mon Sep 17 00:00:00 2001 From: CCarpo Date: Mon, 10 Mar 2025 20:55:35 +0100 Subject: [PATCH 28/34] renamed function for clarity --- src/core/config/Categories.json | 2 +- .../operations/{BeautifyYAML.mjs => JSONtoYAML.mjs} | 10 +++++----- tests/operations/index.mjs | 4 +--- .../tests/{BeautifyYAML.mjs => JSONtoYAML.mjs} | 4 ++-- 4 files changed, 9 insertions(+), 11 deletions(-) rename src/core/operations/{BeautifyYAML.mjs => JSONtoYAML.mjs} (83%) rename tests/operations/tests/{BeautifyYAML.mjs => JSONtoYAML.mjs} (92%) diff --git a/src/core/config/Categories.json b/src/core/config/Categories.json index 1ca519a0..2833cb0a 100644 --- a/src/core/config/Categories.json +++ b/src/core/config/Categories.json @@ -73,7 +73,7 @@ "CBOR Encode", "CBOR Decode", "YAML to JSON", - "Beautify YAML", + "JSON to YAML", "Caret/M-decode", "Rison Encode", "Rison Decode", diff --git a/src/core/operations/BeautifyYAML.mjs b/src/core/operations/JSONtoYAML.mjs similarity index 83% rename from src/core/operations/BeautifyYAML.mjs rename to src/core/operations/JSONtoYAML.mjs index b87573d8..0d4cc626 100644 --- a/src/core/operations/BeautifyYAML.mjs +++ b/src/core/operations/JSONtoYAML.mjs @@ -9,17 +9,17 @@ import OperationError from "../errors/OperationError.mjs"; import YAML from "yaml"; /** - * Beautify YAML operation + * JSON to YAML operation */ -class BeautifyYAML extends Operation { +class JSONtoYAML extends Operation { /** - * BeautifyYAML constructor + * JSONtoYAML constructor */ constructor() { super(); - this.name = "Beautify YAML"; + this.name = "JSON to YAML"; this.module = "Default"; this.description = "Format a JSON object into YAML"; this.infoURL = "https://en.wikipedia.org/wiki/YAML"; @@ -43,4 +43,4 @@ class BeautifyYAML extends Operation { } -export default BeautifyYAML; +export default JSONtoYAML; diff --git a/tests/operations/index.mjs b/tests/operations/index.mjs index 713496c7..1c25a2ab 100644 --- a/tests/operations/index.mjs +++ b/tests/operations/index.mjs @@ -166,12 +166,10 @@ import "./tests/CBORDecode.mjs"; import "./tests/JA3Fingerprint.mjs"; import "./tests/JA3SFingerprint.mjs"; import "./tests/HASSH.mjs"; -import "./tests/BeautifyYAML.mjs"; - +import "./tests/JSONtoYAML.mjs"; // Cannot test operations that use the File type yet // import "./tests/SplitColourChannels.mjs"; -import "./tests/BeautifyYAML.mjs"; import "./tests/YARA.mjs"; import "./tests/ParseCSR.mjs"; import "./tests/XXTEA.mjs"; diff --git a/tests/operations/tests/BeautifyYAML.mjs b/tests/operations/tests/JSONtoYAML.mjs similarity index 92% rename from tests/operations/tests/BeautifyYAML.mjs rename to tests/operations/tests/JSONtoYAML.mjs index 348991d8..b18998e9 100644 --- a/tests/operations/tests/BeautifyYAML.mjs +++ b/tests/operations/tests/JSONtoYAML.mjs @@ -28,12 +28,12 @@ TestRegister.addTests([ ], }, { - name: "Beautify YAML", + name: "JSON to YAML", input: EXAMPLE_JSON, expectedOutput: `number: 3\nplain: string\n`, recipeConfig: [ { - op: "Beautify YAML", + op: "JSON to YAML", args: [], } ], From 95044ab767ce35d75152dc231ce3a8765016087b Mon Sep 17 00:00:00 2001 From: zhzy0077 Date: Wed, 12 Mar 2025 20:15:00 +0800 Subject: [PATCH 29/34] Making it depending on 0.5.1 version. --- package-lock.json | 8 ++++---- package.json | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package-lock.json b/package-lock.json index e4fb240d..e731efff 100644 --- a/package-lock.json +++ b/package-lock.json @@ -48,7 +48,7 @@ "highlight.js": "^11.9.0", "ieee754": "^1.2.1", "jimp": "^0.22.12", - "jq-web": "^0.6.1", + "jq-web": "^0.5.1", "jquery": "3.7.1", "js-crc": "^0.2.0", "js-sha3": "^0.9.3", @@ -12292,9 +12292,9 @@ "license": "BSD-3-Clause" }, "node_modules/jq-web": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/jq-web/-/jq-web-0.6.1.tgz", - "integrity": "sha512-7qZb0KP0Xd3OSRcEtdR8nI0h1pN7RQQRhL8UXM/Hq0zh/ZFAIncFkRcctNjKHlvHLZ29fMNxR9j+pRVJ1SKAcA==", + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/jq-web/-/jq-web-0.5.1.tgz", + "integrity": "sha512-3Fa3E6g3U1O1j46ljy0EM10yRr4txzILga8J7bqOG8F89gZ6Lilz82WG9z6TItWpYEO0YGa4W8yFGj+NMM1xqQ==", "license": "ISC" }, "node_modules/jquery": { diff --git a/package.json b/package.json index 24b3a653..3785508e 100644 --- a/package.json +++ b/package.json @@ -134,7 +134,7 @@ "highlight.js": "^11.9.0", "ieee754": "^1.2.1", "jimp": "^0.22.12", - "jq-web": "^0.6.1", + "jq-web": "^0.5.1", "jquery": "3.7.1", "js-crc": "^0.2.0", "js-sha3": "^0.9.3", From 464c92e7bfc6259dc9653f5afdc66255f09f276f Mon Sep 17 00:00:00 2001 From: zhzy0077 Date: Wed, 12 Mar 2025 20:15:09 +0800 Subject: [PATCH 30/34] Rename to "Jq" --- src/core/config/Categories.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/config/Categories.json b/src/core/config/Categories.json index b31083c5..2ea73f3b 100644 --- a/src/core/config/Categories.json +++ b/src/core/config/Categories.json @@ -465,7 +465,7 @@ "CSS Minify", "XPath expression", "JPath expression", - "jq", + "Jq", "CSS selector", "PHP Deserialize", "Microsoft Script Decoder", From b62def3d3e1bcae03729245813e9929d4243345c Mon Sep 17 00:00:00 2001 From: zhzy0077 Date: Wed, 12 Mar 2025 20:15:23 +0800 Subject: [PATCH 31/34] making it a seperate module. --- src/core/operations/Jq.mjs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/core/operations/Jq.mjs b/src/core/operations/Jq.mjs index 38aa5abb..c1e02b34 100644 --- a/src/core/operations/Jq.mjs +++ b/src/core/operations/Jq.mjs @@ -19,8 +19,8 @@ class Jq extends Operation { constructor() { super(); - this.name = "jq"; - this.module = "Code"; + this.name = "Jq"; + this.module = "Jq"; this.description = "jq is a lightweight and flexible command-line JSON processor."; this.infoURL = "https://github.com/jqlang/jq"; this.inputType = "JSON"; From 49d69a293bf431a850b86dd13f7a271e548132e4 Mon Sep 17 00:00:00 2001 From: 0xh3xa <9023404+0xh3xa@users.noreply.github.com> Date: Sat, 29 Mar 2025 01:27:38 +0100 Subject: [PATCH 32/34] Fix selected theme not loading when refreshing --- src/web/waiters/OptionsWaiter.mjs | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/web/waiters/OptionsWaiter.mjs b/src/web/waiters/OptionsWaiter.mjs index 4f4eda89..ea4a9c4e 100644 --- a/src/web/waiters/OptionsWaiter.mjs +++ b/src/web/waiters/OptionsWaiter.mjs @@ -167,8 +167,12 @@ class OptionsWaiter { * Applies the user's preferred color scheme using the `prefers-color-scheme` media query. */ applyPreferredColorScheme() { - const prefersDarkScheme = window.matchMedia("(prefers-color-scheme: dark)").matches; - const theme = prefersDarkScheme ? "dark" : "classic"; + const themeFromStorage = this.app?.options?.theme; + let theme = themeFromStorage; + if (!theme) { + const preferredTheme = (window.matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "classic"); + theme = preferredTheme; + } this.changeTheme(theme); } From 9f30dd0e7a57489aaaf9a77f3d571802a83758d4 Mon Sep 17 00:00:00 2001 From: heaprc <9023404+0xh3xa@users.noreply.github.com> Date: Sat, 29 Mar 2025 04:40:29 +0100 Subject: [PATCH 33/34] fix invalid theme error --- src/web/waiters/OptionsWaiter.mjs | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/src/web/waiters/OptionsWaiter.mjs b/src/web/waiters/OptionsWaiter.mjs index 4f4eda89..a5d04572 100644 --- a/src/web/waiters/OptionsWaiter.mjs +++ b/src/web/waiters/OptionsWaiter.mjs @@ -160,18 +160,33 @@ class OptionsWaiter { // Update theme selection const themeSelect = document.getElementById("theme"); - themeSelect.selectedIndex = themeSelect.querySelector(`option[value="${theme}"`).index; + let themeOption = themeSelect.querySelector(`option[value="${theme}"]`); + + if (!themeOption) { + const preferredColorScheme = this.getPreferredColorScheme(); + document.querySelector(":root").className = preferredColorScheme; + themeOption = themeSelect.querySelector(`option[value="${preferredColorScheme}"]`); + } + + themeSelect.selectedIndex = themeOption.index; } /** * Applies the user's preferred color scheme using the `prefers-color-scheme` media query. */ applyPreferredColorScheme() { - const prefersDarkScheme = window.matchMedia("(prefers-color-scheme: dark)").matches; - const theme = prefersDarkScheme ? "dark" : "classic"; + const theme = this.getPreferredColorScheme(); this.changeTheme(theme); } + /** + * Get the user's preferred color scheme using the `prefers-color-scheme` media query. + */ + getPreferredColorScheme() { + const prefersDarkScheme = window.matchMedia("(prefers-color-scheme: dark)").matches; + return prefersDarkScheme ? "dark" : "classic"; + } + /** * Changes the console logging level. * From 0e7b1f7c7810539006f3709ce869d23f29d1dc26 Mon Sep 17 00:00:00 2001 From: heaprc <9023404+0xh3xa@users.noreply.github.com> Date: Thu, 3 Apr 2025 09:31:53 +0200 Subject: [PATCH 34/34] resolve conflict in applyPreferredColorScheme method --- src/web/waiters/OptionsWaiter.mjs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/web/waiters/OptionsWaiter.mjs b/src/web/waiters/OptionsWaiter.mjs index 365bd695..dcb0a5f4 100644 --- a/src/web/waiters/OptionsWaiter.mjs +++ b/src/web/waiters/OptionsWaiter.mjs @@ -178,8 +178,7 @@ class OptionsWaiter { const themeFromStorage = this.app?.options?.theme; let theme = themeFromStorage; if (!theme) { - const preferredTheme = (window.matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "classic"); - theme = preferredTheme; + theme = this.getPreferredColorScheme(); } this.changeTheme(theme); }