cyberchef 9.40.0 → 9.43.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -13,6 +13,15 @@ All major and minor version changes will be documented in this file. Details of
13
13
 
14
14
  ## Details
15
15
 
16
+ ### [9.42.0] - 2022-07-08
17
+ - Added 'LS47 Encrypt' and 'LS47 Decrypt' operations [@n1073645] | [#951]
18
+
19
+ ### [9.41.0] - 2022-07-08
20
+ - Added 'Caesar Box Cipher' operation [@n1073645] | [#1066]
21
+
22
+ ### [9.40.0] - 2022-07-08
23
+ - Added 'P-list Viewer' operation [@n1073645] | [#906]
24
+
16
25
  ### [9.39.0] - 2022-06-09
17
26
  - Added 'ELF Info' operation [@n1073645] | [#1364]
18
27
 
@@ -294,6 +303,9 @@ All major and minor version changes will be documented in this file. Details of
294
303
 
295
304
 
296
305
 
306
+ [9.42.0]: https://github.com/gchq/CyberChef/releases/tag/v9.42.0
307
+ [9.41.0]: https://github.com/gchq/CyberChef/releases/tag/v9.41.0
308
+ [9.40.0]: https://github.com/gchq/CyberChef/releases/tag/v9.40.0
297
309
  [9.39.0]: https://github.com/gchq/CyberChef/releases/tag/v9.39.0
298
310
  [9.38.0]: https://github.com/gchq/CyberChef/releases/tag/v9.38.0
299
311
  [9.37.0]: https://github.com/gchq/CyberChef/releases/tag/v9.37.0
@@ -491,10 +503,12 @@ All major and minor version changes will be documented in this file. Details of
491
503
  [#674]: https://github.com/gchq/CyberChef/pull/674
492
504
  [#683]: https://github.com/gchq/CyberChef/pull/683
493
505
  [#865]: https://github.com/gchq/CyberChef/pull/865
506
+ [#906]: https://github.com/gchq/CyberChef/pull/906
494
507
  [#912]: https://github.com/gchq/CyberChef/pull/912
495
508
  [#917]: https://github.com/gchq/CyberChef/pull/917
496
509
  [#934]: https://github.com/gchq/CyberChef/pull/934
497
510
  [#948]: https://github.com/gchq/CyberChef/pull/948
511
+ [#951]: https://github.com/gchq/CyberChef/pull/951
498
512
  [#952]: https://github.com/gchq/CyberChef/pull/952
499
513
  [#965]: https://github.com/gchq/CyberChef/pull/965
500
514
  [#966]: https://github.com/gchq/CyberChef/pull/966
@@ -506,6 +520,7 @@ All major and minor version changes will be documented in this file. Details of
506
520
  [#1045]: https://github.com/gchq/CyberChef/pull/1045
507
521
  [#1049]: https://github.com/gchq/CyberChef/pull/1049
508
522
  [#1065]: https://github.com/gchq/CyberChef/pull/1065
523
+ [#1066]: https://github.com/gchq/CyberChef/pull/1066
509
524
  [#1083]: https://github.com/gchq/CyberChef/pull/1083
510
525
  [#1189]: https://github.com/gchq/CyberChef/pull/1189
511
526
  [#1242]: https://github.com/gchq/CyberChef/pull/1242
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cyberchef",
3
- "version": "9.40.0",
3
+ "version": "9.43.0",
4
4
  "description": "The Cyber Swiss Army Knife for encryption, encoding, compression and data analysis.",
5
5
  "author": "n1474335 <n1474335@gmail.com>",
6
6
  "homepage": "https://gchq.github.io/CyberChef",
@@ -79,6 +79,8 @@
79
79
  "DES Decrypt",
80
80
  "Triple DES Encrypt",
81
81
  "Triple DES Decrypt",
82
+ "LS47 Encrypt",
83
+ "LS47 Decrypt",
82
84
  "RC2 Encrypt",
83
85
  "RC2 Decrypt",
84
86
  "RC4",
@@ -86,7 +88,9 @@
86
88
  "SM4 Encrypt",
87
89
  "SM4 Decrypt",
88
90
  "ROT13",
91
+ "ROT13 Brute Force",
89
92
  "ROT47",
93
+ "ROT47 Brute Force",
90
94
  "XOR",
91
95
  "XOR Brute Force",
92
96
  "Vigenère Encode",
@@ -97,6 +101,7 @@
97
101
  "Bacon Cipher Decode",
98
102
  "Bifid Cipher Encode",
99
103
  "Bifid Cipher Decode",
104
+ "Caesar Box Cipher",
100
105
  "Affine Cipher Encode",
101
106
  "Affine Cipher Decode",
102
107
  "A1Z26 Cipher Encode",
@@ -1469,6 +1469,22 @@
1469
1469
  "manualBake": false,
1470
1470
  "args": []
1471
1471
  },
1472
+ "Caesar Box Cipher": {
1473
+ "module": "Ciphers",
1474
+ "description": "Caesar Box is a transposition cipher used in the Roman Empire, in which letters of the message are written in rows in a square (or a rectangle) and then, read by column.",
1475
+ "infoURL": "https://www.dcode.fr/caesar-box-cipher",
1476
+ "inputType": "string",
1477
+ "outputType": "string",
1478
+ "flowControl": false,
1479
+ "manualBake": false,
1480
+ "args": [
1481
+ {
1482
+ "name": "Box Height",
1483
+ "type": "number",
1484
+ "value": 1
1485
+ }
1486
+ ]
1487
+ },
1472
1488
  "Cartesian Product": {
1473
1489
  "module": "Default",
1474
1490
  "description": "Calculates the cartesian product of multiple sets of data, returning all possible combinations.",
@@ -7918,6 +7934,53 @@
7918
7934
  }
7919
7935
  ]
7920
7936
  },
7937
+ "LS47 Decrypt": {
7938
+ "module": "Crypto",
7939
+ "description": "This is a slight improvement of the ElsieFour cipher as described by Alan Kaminsky. We use 7x7 characters instead of original (barely fitting) 6x6, to be able to encrypt some structured information. We also describe a simple key-expansion algorithm, because remembering passwords is popular. Similar security considerations as with ElsieFour hold.<br>The LS47 alphabet consists of following characters: <code>_abcdefghijklmnopqrstuvwxyz.0123456789,-+*/:?!'()</code><br>An LS47 key is a permutation of the alphabet that is then represented in a 7x7 grid used for the encryption or decryption.",
7940
+ "infoURL": "https://github.com/exaexa/ls47",
7941
+ "inputType": "string",
7942
+ "outputType": "string",
7943
+ "flowControl": false,
7944
+ "manualBake": false,
7945
+ "args": [
7946
+ {
7947
+ "name": "Password",
7948
+ "type": "string",
7949
+ "value": ""
7950
+ },
7951
+ {
7952
+ "name": "Padding",
7953
+ "type": "number",
7954
+ "value": 10
7955
+ }
7956
+ ]
7957
+ },
7958
+ "LS47 Encrypt": {
7959
+ "module": "Crypto",
7960
+ "description": "This is a slight improvement of the ElsieFour cipher as described by Alan Kaminsky. We use 7x7 characters instead of original (barely fitting) 6x6, to be able to encrypt some structured information. We also describe a simple key-expansion algorithm, because remembering passwords is popular. Similar security considerations as with ElsieFour hold.<br>The LS47 alphabet consists of following characters: <code>_abcdefghijklmnopqrstuvwxyz.0123456789,-+*/:?!'()</code><br>A LS47 key is a permutation of the alphabet that is then represented in a 7x7 grid used for the encryption or decryption.",
7961
+ "infoURL": "https://github.com/exaexa/ls47",
7962
+ "inputType": "string",
7963
+ "outputType": "string",
7964
+ "flowControl": false,
7965
+ "manualBake": false,
7966
+ "args": [
7967
+ {
7968
+ "name": "Password",
7969
+ "type": "string",
7970
+ "value": ""
7971
+ },
7972
+ {
7973
+ "name": "Padding",
7974
+ "type": "number",
7975
+ "value": 10
7976
+ },
7977
+ {
7978
+ "name": "Signature",
7979
+ "type": "string",
7980
+ "value": ""
7981
+ }
7982
+ ]
7983
+ },
7921
7984
  "Label": {
7922
7985
  "module": "Default",
7923
7986
  "description": "Provides a location for conditional and fixed jumps to redirect execution to.",
@@ -10115,6 +10178,52 @@
10115
10178
  }
10116
10179
  ]
10117
10180
  },
10181
+ "ROT13 Brute Force": {
10182
+ "module": "Default",
10183
+ "description": "Try all meaningful amounts for ROT13.<br><br>Optionally you can enter your known plaintext (crib) to filter the result.",
10184
+ "infoURL": "https://wikipedia.org/wiki/ROT13",
10185
+ "inputType": "byteArray",
10186
+ "outputType": "string",
10187
+ "flowControl": false,
10188
+ "manualBake": false,
10189
+ "args": [
10190
+ {
10191
+ "name": "Rotate lower case chars",
10192
+ "type": "boolean",
10193
+ "value": true
10194
+ },
10195
+ {
10196
+ "name": "Rotate upper case chars",
10197
+ "type": "boolean",
10198
+ "value": true
10199
+ },
10200
+ {
10201
+ "name": "Rotate numbers",
10202
+ "type": "boolean",
10203
+ "value": false
10204
+ },
10205
+ {
10206
+ "name": "Sample length",
10207
+ "type": "number",
10208
+ "value": 100
10209
+ },
10210
+ {
10211
+ "name": "Sample offset",
10212
+ "type": "number",
10213
+ "value": 0
10214
+ },
10215
+ {
10216
+ "name": "Print amount",
10217
+ "type": "boolean",
10218
+ "value": true
10219
+ },
10220
+ {
10221
+ "name": "Crib (known plaintext string)",
10222
+ "type": "string",
10223
+ "value": ""
10224
+ }
10225
+ ]
10226
+ },
10118
10227
  "ROT47": {
10119
10228
  "module": "Default",
10120
10229
  "description": "A slightly more complex variation of a caesar cipher, which includes ASCII characters from 33 '!' to 126 '~'. Default rotation: 47.",
@@ -10131,6 +10240,37 @@
10131
10240
  }
10132
10241
  ]
10133
10242
  },
10243
+ "ROT47 Brute Force": {
10244
+ "module": "Default",
10245
+ "description": "Try all meaningful amounts for ROT47.<br><br>Optionally you can enter your known plaintext (crib) to filter the result.",
10246
+ "infoURL": "https://wikipedia.org/wiki/ROT13#Variants",
10247
+ "inputType": "byteArray",
10248
+ "outputType": "string",
10249
+ "flowControl": false,
10250
+ "manualBake": false,
10251
+ "args": [
10252
+ {
10253
+ "name": "Sample length",
10254
+ "type": "number",
10255
+ "value": 100
10256
+ },
10257
+ {
10258
+ "name": "Sample offset",
10259
+ "type": "number",
10260
+ "value": 0
10261
+ },
10262
+ {
10263
+ "name": "Print amount",
10264
+ "type": "boolean",
10265
+ "value": true
10266
+ },
10267
+ {
10268
+ "name": "Crib (known plaintext string)",
10269
+ "type": "string",
10270
+ "value": ""
10271
+ }
10272
+ ]
10273
+ },
10134
10274
  "RSA Decrypt": {
10135
10275
  "module": "Ciphers",
10136
10276
  "description": "Decrypt an RSA encrypted message with a PEM encoded private key.",
@@ -16,6 +16,7 @@ import BifidCipherDecode from "../../operations/BifidCipherDecode.mjs";
16
16
  import BifidCipherEncode from "../../operations/BifidCipherEncode.mjs";
17
17
  import BlowfishDecrypt from "../../operations/BlowfishDecrypt.mjs";
18
18
  import BlowfishEncrypt from "../../operations/BlowfishEncrypt.mjs";
19
+ import CaesarBoxCipher from "../../operations/CaesarBoxCipher.mjs";
19
20
  import DESDecrypt from "../../operations/DESDecrypt.mjs";
20
21
  import DESEncrypt from "../../operations/DESEncrypt.mjs";
21
22
  import DeriveEVPKey from "../../operations/DeriveEVPKey.mjs";
@@ -53,6 +54,7 @@ OpModules.Ciphers = {
53
54
  "Bifid Cipher Encode": BifidCipherEncode,
54
55
  "Blowfish Decrypt": BlowfishDecrypt,
55
56
  "Blowfish Encrypt": BlowfishEncrypt,
57
+ "Caesar Box Cipher": CaesarBoxCipher,
56
58
  "DES Decrypt": DESDecrypt,
57
59
  "DES Encrypt": DESEncrypt,
58
60
  "Derive EVP key": DeriveEVPKey,
@@ -34,6 +34,8 @@ import JWTDecode from "../../operations/JWTDecode.mjs";
34
34
  import JWTSign from "../../operations/JWTSign.mjs";
35
35
  import JWTVerify from "../../operations/JWTVerify.mjs";
36
36
  import Keccak from "../../operations/Keccak.mjs";
37
+ import LS47Decrypt from "../../operations/LS47Decrypt.mjs";
38
+ import LS47Encrypt from "../../operations/LS47Encrypt.mjs";
37
39
  import MD2 from "../../operations/MD2.mjs";
38
40
  import MD4 from "../../operations/MD4.mjs";
39
41
  import MD5 from "../../operations/MD5.mjs";
@@ -83,6 +85,8 @@ OpModules.Crypto = {
83
85
  "JWT Sign": JWTSign,
84
86
  "JWT Verify": JWTVerify,
85
87
  "Keccak": Keccak,
88
+ "LS47 Decrypt": LS47Decrypt,
89
+ "LS47 Encrypt": LS47Encrypt,
86
90
  "MD2": MD2,
87
91
  "MD4": MD4,
88
92
  "MD5": MD5,
@@ -107,7 +107,9 @@ import ParseUNIXFilePermissions from "../../operations/ParseUNIXFilePermissions.
107
107
  import PlayMedia from "../../operations/PlayMedia.mjs";
108
108
  import PowerSet from "../../operations/PowerSet.mjs";
109
109
  import ROT13 from "../../operations/ROT13.mjs";
110
+ import ROT13BruteForce from "../../operations/ROT13BruteForce.mjs";
110
111
  import ROT47 from "../../operations/ROT47.mjs";
112
+ import ROT47BruteForce from "../../operations/ROT47BruteForce.mjs";
111
113
  import RemoveDiacritics from "../../operations/RemoveDiacritics.mjs";
112
114
  import RemoveLineNumbers from "../../operations/RemoveLineNumbers.mjs";
113
115
  import RemoveNullBytes from "../../operations/RemoveNullBytes.mjs";
@@ -277,7 +279,9 @@ OpModules.Default = {
277
279
  "Play Media": PlayMedia,
278
280
  "Power Set": PowerSet,
279
281
  "ROT13": ROT13,
282
+ "ROT13 Brute Force": ROT13BruteForce,
280
283
  "ROT47": ROT47,
284
+ "ROT47 Brute Force": ROT47BruteForce,
281
285
  "Remove Diacritics": RemoveDiacritics,
282
286
  "Remove line numbers": RemoveLineNumbers,
283
287
  "Remove null bytes": RemoveNullBytes,
@@ -0,0 +1,244 @@
1
+ /**
2
+ * @author n1073645 [n1073645@gmail.com]
3
+ * @copyright Crown Copyright 2020
4
+ * @license Apache-2.0
5
+ */
6
+
7
+ import OperationError from "../errors/OperationError.mjs";
8
+
9
+ const letters = "_abcdefghijklmnopqrstuvwxyz.0123456789,-+*/:?!'()";
10
+ const tiles = [];
11
+
12
+ /**
13
+ * Initialises the tiles with values and positions.
14
+ */
15
+ export function initTiles() {
16
+ for (let i = 0; i < 49; i++)
17
+ tiles.push([letters.charAt(i), [Math.floor(i/7), i % 7]]);
18
+ }
19
+
20
+ /**
21
+ * Rotates the key "down".
22
+ *
23
+ * @param {string} key
24
+ * @param {number} col
25
+ * @param {number} n
26
+ * @returns {string}
27
+ */
28
+ function rotateDown(key, col, n) {
29
+ const lines = [];
30
+ for (let i = 0; i < 7; i++)
31
+ lines.push(key.slice(i*7, (i + 1) * 7));
32
+ const lefts = [];
33
+ let mids = [];
34
+ const rights = [];
35
+ lines.forEach((element) => {
36
+ lefts.push(element.slice(0, col));
37
+ mids.push(element.charAt(col));
38
+ rights.push(element.slice(col+1));
39
+ });
40
+ n = (7 - n % 7) % 7;
41
+ mids = mids.slice(n).concat(mids.slice(0, n));
42
+ let result = "";
43
+ for (let i = 0; i < 7; i++)
44
+ result += lefts[i] + mids[i] + rights[i];
45
+ return result;
46
+ }
47
+
48
+ /**
49
+ * Rotates the key "right".
50
+ *
51
+ * @param {string} key
52
+ * @param {number} row
53
+ * @param {number} n
54
+ * @returns {string}
55
+ */
56
+ function rotateRight(key, row, n) {
57
+ const mid = key.slice(row * 7, (row + 1) * 7);
58
+ n = (7 - n % 7) % 7;
59
+ return key.slice(0, 7 * row) + mid.slice(n) + mid.slice(0, n) + key.slice(7 * (row + 1));
60
+ }
61
+
62
+ /**
63
+ * Finds the position of a letter in the tiles.
64
+ *
65
+ * @param {string} letter
66
+ * @returns {string}
67
+ */
68
+ function findIx(letter) {
69
+ for (let i = 0; i < tiles.length; i++)
70
+ if (tiles[i][0] === letter)
71
+ return tiles[i][1];
72
+ throw new OperationError("Letter " + letter + " is not included in LS47");
73
+ }
74
+
75
+ /**
76
+ * Derives key from the input password.
77
+ *
78
+ * @param {string} password
79
+ * @returns {string}
80
+ */
81
+ export function deriveKey(password) {
82
+ let i = 0;
83
+ let k = letters;
84
+ for (const c of password) {
85
+ const [row, col] = findIx(c);
86
+ k = rotateDown(rotateRight(k, i, col), i, row);
87
+ i = (i + 1) % 7;
88
+ }
89
+ return k;
90
+ }
91
+
92
+ /**
93
+ * Checks the key is a valid key.
94
+ *
95
+ * @param {string} key
96
+ */
97
+ function checkKey(key) {
98
+ if (key.length !== letters.length)
99
+ throw new OperationError("Wrong key size");
100
+ const counts = new Array();
101
+ for (let i = 0; i < letters.length; i++)
102
+ counts[letters.charAt(i)] = 0;
103
+ for (const elem of letters) {
104
+ if (letters.indexOf(elem) === -1)
105
+ throw new OperationError("Letter " + elem + " not in LS47");
106
+ counts[elem]++;
107
+ if (counts[elem] > 1)
108
+ throw new OperationError("Letter duplicated in the key");
109
+ }
110
+ }
111
+
112
+ /**
113
+ * Finds the position of a letter in they key.
114
+ *
115
+ * @param {letter} key
116
+ * @param {string} letter
117
+ * @returns {object}
118
+ */
119
+ function findPos (key, letter) {
120
+ const index = key.indexOf(letter);
121
+ if (index >= 0 && index < 49)
122
+ return [Math.floor(index/7), index%7];
123
+ throw new OperationError("Letter " + letter + " is not in the key");
124
+ }
125
+
126
+ /**
127
+ * Returns the character at the position on the tiles.
128
+ *
129
+ * @param {string} key
130
+ * @param {object} coord
131
+ * @returns {string}
132
+ */
133
+ function findAtPos(key, coord) {
134
+ return key.charAt(coord[1] + (coord[0] * 7));
135
+ }
136
+
137
+ /**
138
+ * Returns new position by adding two positions.
139
+ *
140
+ * @param {object} a
141
+ * @param {object} b
142
+ * @returns {object}
143
+ */
144
+ function addPos(a, b) {
145
+ return [(a[0] + b[0]) % 7, (a[1] + b[1]) % 7];
146
+ }
147
+
148
+ /**
149
+ * Returns new position by subtracting two positions.
150
+ * Note: We have to manually do the remainder division, since JS does not
151
+ * operate correctly on negative numbers (e.g. -3 % 4 = -3 when it should be 1).
152
+ *
153
+ * @param {object} a
154
+ * @param {object} b
155
+ * @returns {object}
156
+ */
157
+ function subPos(a, b) {
158
+ const asub = a[0] - b[0];
159
+ const bsub = a[1] - b[1];
160
+ return [asub - (Math.floor(asub/7) * 7), bsub - (Math.floor(bsub/7) * 7)];
161
+ }
162
+
163
+ /**
164
+ * Encrypts the plaintext string.
165
+ *
166
+ * @param {string} key
167
+ * @param {string} plaintext
168
+ * @returns {string}
169
+ */
170
+ function encrypt(key, plaintext) {
171
+ checkKey(key);
172
+ let mp = [0, 0];
173
+ let ciphertext = "";
174
+ for (const p of plaintext) {
175
+ const pp = findPos(key, p);
176
+ const mix = findIx(findAtPos(key, mp));
177
+ let cp = addPos(pp, mix);
178
+ const c = findAtPos(key, cp);
179
+ ciphertext += c;
180
+ key = rotateRight(key, pp[0], 1);
181
+ cp = findPos(key, c);
182
+ key = rotateDown(key, cp[1], 1);
183
+ mp = addPos(mp, findIx(c));
184
+ }
185
+ return ciphertext;
186
+ }
187
+
188
+ /**
189
+ * Decrypts the ciphertext string.
190
+ *
191
+ * @param {string} key
192
+ * @param {string} ciphertext
193
+ * @returns {string}
194
+ */
195
+ function decrypt(key, ciphertext) {
196
+ checkKey(key);
197
+ let mp = [0, 0];
198
+ let plaintext = "";
199
+ for (const c of ciphertext) {
200
+ let cp = findPos(key, c);
201
+ const mix = findIx(findAtPos(key, mp));
202
+ const pp = subPos(cp, mix);
203
+ const p = findAtPos(key, pp);
204
+ plaintext += p;
205
+ key = rotateRight(key, pp[0], 1);
206
+ cp = findPos(key, c);
207
+ key = rotateDown(key, cp[1], 1);
208
+ mp = addPos(mp, findIx(c));
209
+ }
210
+ return plaintext;
211
+ }
212
+
213
+ /**
214
+ * Adds padding to the input.
215
+ *
216
+ * @param {string} key
217
+ * @param {string} plaintext
218
+ * @param {string} signature
219
+ * @param {number} paddingSize
220
+ * @returns {string}
221
+ */
222
+ export function encryptPad(key, plaintext, signature, paddingSize) {
223
+ initTiles();
224
+ checkKey(key);
225
+ let padding = "";
226
+ for (let i = 0; i < paddingSize; i++) {
227
+ padding += letters.charAt(Math.floor(Math.random() * letters.length));
228
+ }
229
+ return encrypt(key, padding+plaintext+"---"+signature);
230
+ }
231
+
232
+ /**
233
+ * Removes padding from the ouput.
234
+ *
235
+ * @param {string} key
236
+ * @param {string} ciphertext
237
+ * @param {number} paddingSize
238
+ * @returns {string}
239
+ */
240
+ export function decryptPad(key, ciphertext, paddingSize) {
241
+ initTiles();
242
+ checkKey(key);
243
+ return decrypt(key, ciphertext).slice(paddingSize);
244
+ }
@@ -0,0 +1,61 @@
1
+ /**
2
+ * @author n1073645 [n1073645@gmail.com]
3
+ * @copyright Crown Copyright 2020
4
+ * @license Apache-2.0
5
+ */
6
+
7
+ import Operation from "../Operation.mjs";
8
+
9
+ /**
10
+ * Caesar Box Cipher operation
11
+ */
12
+ class CaesarBoxCipher extends Operation {
13
+
14
+ /**
15
+ * CaesarBoxCipher constructor
16
+ */
17
+ constructor() {
18
+ super();
19
+
20
+ this.name = "Caesar Box Cipher";
21
+ this.module = "Ciphers";
22
+ this.description = "Caesar Box is a transposition cipher used in the Roman Empire, in which letters of the message are written in rows in a square (or a rectangle) and then, read by column.";
23
+ this.infoURL = "https://www.dcode.fr/caesar-box-cipher";
24
+ this.inputType = "string";
25
+ this.outputType = "string";
26
+ this.args = [
27
+ {
28
+ name: "Box Height",
29
+ type: "number",
30
+ value: 1
31
+ }
32
+ ];
33
+ }
34
+
35
+ /**
36
+ * @param {string} input
37
+ * @param {Object[]} args
38
+ * @returns {string}
39
+ */
40
+ run(input, args) {
41
+ const tableHeight = args[0];
42
+ const tableWidth = Math.ceil(input.length / tableHeight);
43
+ while (input.indexOf(" ") !== -1)
44
+ input = input.replace(" ", "");
45
+ for (let i = 0; i < (tableHeight * tableWidth) - input.length; i++) {
46
+ input += "\x00";
47
+ }
48
+ let result = "";
49
+ for (let i = 0; i < tableHeight; i++) {
50
+ for (let j = i; j < input.length; j += tableHeight) {
51
+ if (input.charAt(j) !== "\x00") {
52
+ result += input.charAt(j);
53
+ }
54
+ }
55
+ }
56
+ return result;
57
+ }
58
+
59
+ }
60
+
61
+ export default CaesarBoxCipher;
@@ -0,0 +1,57 @@
1
+ /**
2
+ * @author n1073645 [n1073645@gmail.com]
3
+ * @copyright Crown Copyright 2020
4
+ * @license Apache-2.0
5
+ */
6
+
7
+ import Operation from "../Operation.mjs";
8
+ import * as LS47 from "../lib/LS47.mjs";
9
+
10
+ /**
11
+ * LS47 Decrypt operation
12
+ */
13
+ class LS47Decrypt extends Operation {
14
+
15
+ /**
16
+ * LS47Decrypt constructor
17
+ */
18
+ constructor() {
19
+ super();
20
+
21
+ this.name = "LS47 Decrypt";
22
+ this.module = "Crypto";
23
+ this.description = "This is a slight improvement of the ElsieFour cipher as described by Alan Kaminsky. We use 7x7 characters instead of original (barely fitting) 6x6, to be able to encrypt some structured information. We also describe a simple key-expansion algorithm, because remembering passwords is popular. Similar security considerations as with ElsieFour hold.<br>The LS47 alphabet consists of following characters: <code>_abcdefghijklmnopqrstuvwxyz.0123456789,-+*/:?!'()</code><br>An LS47 key is a permutation of the alphabet that is then represented in a 7x7 grid used for the encryption or decryption.";
24
+ this.infoURL = "https://github.com/exaexa/ls47";
25
+ this.inputType = "string";
26
+ this.outputType = "string";
27
+ this.args = [
28
+ {
29
+ name: "Password",
30
+ type: "string",
31
+ value: ""
32
+ },
33
+ {
34
+ name: "Padding",
35
+ type: "number",
36
+ value: 10
37
+ }
38
+ ];
39
+ }
40
+
41
+ /**
42
+ * @param {string} input
43
+ * @param {Object[]} args
44
+ * @returns {string}
45
+ */
46
+ run(input, args) {
47
+ this.paddingSize = parseInt(args[1], 10);
48
+
49
+ LS47.initTiles();
50
+
51
+ const key = LS47.deriveKey(args[0]);
52
+ return LS47.decryptPad(key, input, this.paddingSize);
53
+ }
54
+
55
+ }
56
+
57
+ export default LS47Decrypt;
@@ -0,0 +1,62 @@
1
+ /**
2
+ * @author n1073645 [n1073645@gmail.com]
3
+ * @copyright Crown Copyright 2020
4
+ * @license Apache-2.0
5
+ */
6
+
7
+ import Operation from "../Operation.mjs";
8
+ import * as LS47 from "../lib/LS47.mjs";
9
+
10
+ /**
11
+ * LS47 Encrypt operation
12
+ */
13
+ class LS47Encrypt extends Operation {
14
+
15
+ /**
16
+ * LS47Encrypt constructor
17
+ */
18
+ constructor() {
19
+ super();
20
+
21
+ this.name = "LS47 Encrypt";
22
+ this.module = "Crypto";
23
+ this.description = "This is a slight improvement of the ElsieFour cipher as described by Alan Kaminsky. We use 7x7 characters instead of original (barely fitting) 6x6, to be able to encrypt some structured information. We also describe a simple key-expansion algorithm, because remembering passwords is popular. Similar security considerations as with ElsieFour hold.<br>The LS47 alphabet consists of following characters: <code>_abcdefghijklmnopqrstuvwxyz.0123456789,-+*/:?!'()</code><br>A LS47 key is a permutation of the alphabet that is then represented in a 7x7 grid used for the encryption or decryption.";
24
+ this.infoURL = "https://github.com/exaexa/ls47";
25
+ this.inputType = "string";
26
+ this.outputType = "string";
27
+ this.args = [
28
+ {
29
+ name: "Password",
30
+ type: "string",
31
+ value: ""
32
+ },
33
+ {
34
+ name: "Padding",
35
+ type: "number",
36
+ value: 10
37
+ },
38
+ {
39
+ name: "Signature",
40
+ type: "string",
41
+ value: ""
42
+ }
43
+ ];
44
+ }
45
+
46
+ /**
47
+ * @param {string} input
48
+ * @param {Object[]} args
49
+ * @returns {string}
50
+ */
51
+ run(input, args) {
52
+ this.paddingSize = parseInt(args[1], 10);
53
+
54
+ LS47.initTiles();
55
+
56
+ const key = LS47.deriveKey(args[0]);
57
+ return LS47.encryptPad(key, input, args[2], this.paddingSize);
58
+ }
59
+
60
+ }
61
+
62
+ export default LS47Encrypt;
@@ -0,0 +1,102 @@
1
+ /**
2
+ * @author MikeCAT
3
+ * @license Apache-2.0
4
+ */
5
+
6
+ import Operation from "../Operation.mjs";
7
+ import Utils from "../Utils.mjs";
8
+
9
+ /**
10
+ * ROT13 Brute Force operation.
11
+ */
12
+ class ROT13BruteForce extends Operation {
13
+
14
+ /**
15
+ * ROT13BruteForce constructor
16
+ */
17
+ constructor() {
18
+ super();
19
+
20
+ this.name = "ROT13 Brute Force";
21
+ this.module = "Default";
22
+ this.description = "Try all meaningful amounts for ROT13.<br><br>Optionally you can enter your known plaintext (crib) to filter the result.";
23
+ this.infoURL = "https://wikipedia.org/wiki/ROT13";
24
+ this.inputType = "byteArray";
25
+ this.outputType = "string";
26
+ this.args = [
27
+ {
28
+ name: "Rotate lower case chars",
29
+ type: "boolean",
30
+ value: true
31
+ },
32
+ {
33
+ name: "Rotate upper case chars",
34
+ type: "boolean",
35
+ value: true
36
+ },
37
+ {
38
+ name: "Rotate numbers",
39
+ type: "boolean",
40
+ value: false
41
+ },
42
+ {
43
+ name: "Sample length",
44
+ type: "number",
45
+ value: 100
46
+ },
47
+ {
48
+ name: "Sample offset",
49
+ type: "number",
50
+ value: 0
51
+ },
52
+ {
53
+ name: "Print amount",
54
+ type: "boolean",
55
+ value: true
56
+ },
57
+ {
58
+ name: "Crib (known plaintext string)",
59
+ type: "string",
60
+ value: ""
61
+ }
62
+ ];
63
+ }
64
+
65
+ /**
66
+ * @param {byteArray} input
67
+ * @param {Object[]} args
68
+ * @returns {string}
69
+ */
70
+ run(input, args) {
71
+ const [rotateLower, rotateUpper, rotateNum, sampleLength, sampleOffset, printAmount, crib] = args;
72
+ const sample = input.slice(sampleOffset, sampleOffset + sampleLength);
73
+ const cribLower = crib.toLowerCase();
74
+ const lowerStart = "a".charCodeAt(0), upperStart = "A".charCodeAt(0), numStart = "0".charCodeAt(0);
75
+ const result = [];
76
+ for (let amount = 1; amount < 26; amount++) {
77
+ const rotated = sample.slice();
78
+ for (let i = 0; i < rotated.length; i++) {
79
+ if (rotateLower && lowerStart <= rotated[i] && rotated[i] < lowerStart + 26) {
80
+ rotated[i] = (rotated[i] - lowerStart + amount) % 26 + lowerStart;
81
+ } else if (rotateUpper && upperStart <= rotated[i] && rotated[i] < upperStart + 26) {
82
+ rotated[i] = (rotated[i] - upperStart + amount) % 26 + upperStart;
83
+ } else if (rotateNum && numStart <= rotated[i] && rotated[i] < numStart + 10) {
84
+ rotated[i] = (rotated[i] - numStart + amount) % 10 + numStart;
85
+ }
86
+ }
87
+ const rotatedString = Utils.byteArrayToUtf8(rotated);
88
+ if (rotatedString.toLowerCase().indexOf(cribLower) >= 0) {
89
+ const rotatedStringPrintable = Utils.printable(rotatedString, false);
90
+ if (printAmount) {
91
+ const amountStr = "Amount = " + (" " + amount).slice(-2) + ": ";
92
+ result.push(amountStr + rotatedStringPrintable);
93
+ } else {
94
+ result.push(rotatedStringPrintable);
95
+ }
96
+ }
97
+ }
98
+ return result.join("\n");
99
+ }
100
+ }
101
+
102
+ export default ROT13BruteForce;
@@ -0,0 +1,82 @@
1
+ /**
2
+ * @author MikeCAT
3
+ * @license Apache-2.0
4
+ */
5
+
6
+ import Operation from "../Operation.mjs";
7
+ import Utils from "../Utils.mjs";
8
+
9
+ /**
10
+ * ROT47 Brute Force operation.
11
+ */
12
+ class ROT47BruteForce extends Operation {
13
+
14
+ /**
15
+ * ROT47BruteForce constructor
16
+ */
17
+ constructor() {
18
+ super();
19
+
20
+ this.name = "ROT47 Brute Force";
21
+ this.module = "Default";
22
+ this.description = "Try all meaningful amounts for ROT47.<br><br>Optionally you can enter your known plaintext (crib) to filter the result.";
23
+ this.infoURL = "https://wikipedia.org/wiki/ROT13#Variants";
24
+ this.inputType = "byteArray";
25
+ this.outputType = "string";
26
+ this.args = [
27
+ {
28
+ name: "Sample length",
29
+ type: "number",
30
+ value: 100
31
+ },
32
+ {
33
+ name: "Sample offset",
34
+ type: "number",
35
+ value: 0
36
+ },
37
+ {
38
+ name: "Print amount",
39
+ type: "boolean",
40
+ value: true
41
+ },
42
+ {
43
+ name: "Crib (known plaintext string)",
44
+ type: "string",
45
+ value: ""
46
+ }
47
+ ];
48
+ }
49
+
50
+ /**
51
+ * @param {byteArray} input
52
+ * @param {Object[]} args
53
+ * @returns {string}
54
+ */
55
+ run(input, args) {
56
+ const [sampleLength, sampleOffset, printAmount, crib] = args;
57
+ const sample = input.slice(sampleOffset, sampleOffset + sampleLength);
58
+ const cribLower = crib.toLowerCase();
59
+ const result = [];
60
+ for (let amount = 1; amount < 94; amount++) {
61
+ const rotated = sample.slice();
62
+ for (let i = 0; i < rotated.length; i++) {
63
+ if (33 <= rotated[i] && rotated[i] <= 126) {
64
+ rotated[i] = (rotated[i] - 33 + amount) % 94 + 33;
65
+ }
66
+ }
67
+ const rotatedString = Utils.byteArrayToUtf8(rotated);
68
+ if (rotatedString.toLowerCase().indexOf(cribLower) >= 0) {
69
+ const rotatedStringPrintable = Utils.printable(rotatedString, false);
70
+ if (printAmount) {
71
+ const amountStr = "Amount = " + (" " + amount).slice(-2) + ": ";
72
+ result.push(amountStr + rotatedStringPrintable);
73
+ } else {
74
+ result.push(rotatedStringPrintable);
75
+ }
76
+ }
77
+ }
78
+ return result.join("\n");
79
+ }
80
+ }
81
+
82
+ export default ROT47BruteForce;
@@ -48,6 +48,7 @@ import CSSMinify from "./CSSMinify.mjs";
48
48
  import CSSSelector from "./CSSSelector.mjs";
49
49
  import CSVToJSON from "./CSVToJSON.mjs";
50
50
  import CTPH from "./CTPH.mjs";
51
+ import CaesarBoxCipher from "./CaesarBoxCipher.mjs";
51
52
  import CartesianProduct from "./CartesianProduct.mjs";
52
53
  import ChangeIPFormat from "./ChangeIPFormat.mjs";
53
54
  import ChiSquare from "./ChiSquare.mjs";
@@ -191,6 +192,8 @@ import JavaScriptMinify from "./JavaScriptMinify.mjs";
191
192
  import JavaScriptParser from "./JavaScriptParser.mjs";
192
193
  import Jump from "./Jump.mjs";
193
194
  import Keccak from "./Keccak.mjs";
195
+ import LS47Decrypt from "./LS47Decrypt.mjs";
196
+ import LS47Encrypt from "./LS47Encrypt.mjs";
194
197
  import Label from "./Label.mjs";
195
198
  import Lorenz from "./Lorenz.mjs";
196
199
  import LuhnChecksum from "./LuhnChecksum.mjs";
@@ -249,7 +252,9 @@ import RC4 from "./RC4.mjs";
249
252
  import RC4Drop from "./RC4Drop.mjs";
250
253
  import RIPEMD from "./RIPEMD.mjs";
251
254
  import ROT13 from "./ROT13.mjs";
255
+ import ROT13BruteForce from "./ROT13BruteForce.mjs";
252
256
  import ROT47 from "./ROT47.mjs";
257
+ import ROT47BruteForce from "./ROT47BruteForce.mjs";
253
258
  import RSADecrypt from "./RSADecrypt.mjs";
254
259
  import RSAEncrypt from "./RSAEncrypt.mjs";
255
260
  import RSASign from "./RSASign.mjs";
@@ -423,6 +428,7 @@ export {
423
428
  CSSSelector,
424
429
  CSVToJSON,
425
430
  CTPH,
431
+ CaesarBoxCipher,
426
432
  CartesianProduct,
427
433
  ChangeIPFormat,
428
434
  ChiSquare,
@@ -566,6 +572,8 @@ export {
566
572
  JavaScriptParser,
567
573
  Jump,
568
574
  Keccak,
575
+ LS47Decrypt,
576
+ LS47Encrypt,
569
577
  Label,
570
578
  Lorenz,
571
579
  LuhnChecksum,
@@ -624,7 +632,9 @@ export {
624
632
  RC4Drop,
625
633
  RIPEMD,
626
634
  ROT13,
635
+ ROT13BruteForce,
627
636
  ROT47,
637
+ ROT47BruteForce,
628
638
  RSADecrypt,
629
639
  RSAEncrypt,
630
640
  RSASign,
@@ -58,6 +58,7 @@ import {
58
58
  CSSSelector as core_CSSSelector,
59
59
  CSVToJSON as core_CSVToJSON,
60
60
  CTPH as core_CTPH,
61
+ CaesarBoxCipher as core_CaesarBoxCipher,
61
62
  CartesianProduct as core_CartesianProduct,
62
63
  ChangeIPFormat as core_ChangeIPFormat,
63
64
  ChiSquare as core_ChiSquare,
@@ -194,6 +195,8 @@ import {
194
195
  JWTSign as core_JWTSign,
195
196
  JWTVerify as core_JWTVerify,
196
197
  Keccak as core_Keccak,
198
+ LS47Decrypt as core_LS47Decrypt,
199
+ LS47Encrypt as core_LS47Encrypt,
197
200
  Lorenz as core_Lorenz,
198
201
  LuhnChecksum as core_LuhnChecksum,
199
202
  MD2 as core_MD2,
@@ -250,7 +253,9 @@ import {
250
253
  RC4Drop as core_RC4Drop,
251
254
  RIPEMD as core_RIPEMD,
252
255
  ROT13 as core_ROT13,
256
+ ROT13BruteForce as core_ROT13BruteForce,
253
257
  ROT47 as core_ROT47,
258
+ ROT47BruteForce as core_ROT47BruteForce,
254
259
  RSADecrypt as core_RSADecrypt,
255
260
  RSAEncrypt as core_RSAEncrypt,
256
261
  RSASign as core_RSASign,
@@ -433,6 +438,7 @@ function generateChef() {
433
438
  "CSSSelector": _wrap(core_CSSSelector),
434
439
  "CSVToJSON": _wrap(core_CSVToJSON),
435
440
  "CTPH": _wrap(core_CTPH),
441
+ "caesarBoxCipher": _wrap(core_CaesarBoxCipher),
436
442
  "cartesianProduct": _wrap(core_CartesianProduct),
437
443
  "changeIPFormat": _wrap(core_ChangeIPFormat),
438
444
  "chiSquare": _wrap(core_ChiSquare),
@@ -569,6 +575,8 @@ function generateChef() {
569
575
  "JWTSign": _wrap(core_JWTSign),
570
576
  "JWTVerify": _wrap(core_JWTVerify),
571
577
  "keccak": _wrap(core_Keccak),
578
+ "LS47Decrypt": _wrap(core_LS47Decrypt),
579
+ "LS47Encrypt": _wrap(core_LS47Encrypt),
572
580
  "lorenz": _wrap(core_Lorenz),
573
581
  "luhnChecksum": _wrap(core_LuhnChecksum),
574
582
  "MD2": _wrap(core_MD2),
@@ -625,7 +633,9 @@ function generateChef() {
625
633
  "RC4Drop": _wrap(core_RC4Drop),
626
634
  "RIPEMD": _wrap(core_RIPEMD),
627
635
  "ROT13": _wrap(core_ROT13),
636
+ "ROT13BruteForce": _wrap(core_ROT13BruteForce),
628
637
  "ROT47": _wrap(core_ROT47),
638
+ "ROT47BruteForce": _wrap(core_ROT47BruteForce),
629
639
  "RSADecrypt": _wrap(core_RSADecrypt),
630
640
  "RSAEncrypt": _wrap(core_RSAEncrypt),
631
641
  "RSASign": _wrap(core_RSASign),
@@ -816,6 +826,7 @@ const CSSMinify = chef.CSSMinify;
816
826
  const CSSSelector = chef.CSSSelector;
817
827
  const CSVToJSON = chef.CSVToJSON;
818
828
  const CTPH = chef.CTPH;
829
+ const caesarBoxCipher = chef.caesarBoxCipher;
819
830
  const cartesianProduct = chef.cartesianProduct;
820
831
  const changeIPFormat = chef.changeIPFormat;
821
832
  const chiSquare = chef.chiSquare;
@@ -959,6 +970,8 @@ const javaScriptMinify = chef.javaScriptMinify;
959
970
  const javaScriptParser = chef.javaScriptParser;
960
971
  const jump = chef.jump;
961
972
  const keccak = chef.keccak;
973
+ const LS47Decrypt = chef.LS47Decrypt;
974
+ const LS47Encrypt = chef.LS47Encrypt;
962
975
  const label = chef.label;
963
976
  const lorenz = chef.lorenz;
964
977
  const luhnChecksum = chef.luhnChecksum;
@@ -1017,7 +1030,9 @@ const RC4 = chef.RC4;
1017
1030
  const RC4Drop = chef.RC4Drop;
1018
1031
  const RIPEMD = chef.RIPEMD;
1019
1032
  const ROT13 = chef.ROT13;
1033
+ const ROT13BruteForce = chef.ROT13BruteForce;
1020
1034
  const ROT47 = chef.ROT47;
1035
+ const ROT47BruteForce = chef.ROT47BruteForce;
1021
1036
  const RSADecrypt = chef.RSADecrypt;
1022
1037
  const RSAEncrypt = chef.RSAEncrypt;
1023
1038
  const RSASign = chef.RSASign;
@@ -1193,6 +1208,7 @@ const operations = [
1193
1208
  CSSSelector,
1194
1209
  CSVToJSON,
1195
1210
  CTPH,
1211
+ caesarBoxCipher,
1196
1212
  cartesianProduct,
1197
1213
  changeIPFormat,
1198
1214
  chiSquare,
@@ -1336,6 +1352,8 @@ const operations = [
1336
1352
  javaScriptParser,
1337
1353
  jump,
1338
1354
  keccak,
1355
+ LS47Decrypt,
1356
+ LS47Encrypt,
1339
1357
  label,
1340
1358
  lorenz,
1341
1359
  luhnChecksum,
@@ -1394,7 +1412,9 @@ const operations = [
1394
1412
  RC4Drop,
1395
1413
  RIPEMD,
1396
1414
  ROT13,
1415
+ ROT13BruteForce,
1397
1416
  ROT47,
1417
+ ROT47BruteForce,
1398
1418
  RSADecrypt,
1399
1419
  RSAEncrypt,
1400
1420
  RSASign,
@@ -1574,6 +1594,7 @@ export {
1574
1594
  CSSSelector,
1575
1595
  CSVToJSON,
1576
1596
  CTPH,
1597
+ caesarBoxCipher,
1577
1598
  cartesianProduct,
1578
1599
  changeIPFormat,
1579
1600
  chiSquare,
@@ -1717,6 +1738,8 @@ export {
1717
1738
  javaScriptParser,
1718
1739
  jump,
1719
1740
  keccak,
1741
+ LS47Decrypt,
1742
+ LS47Encrypt,
1720
1743
  label,
1721
1744
  lorenz,
1722
1745
  luhnChecksum,
@@ -1775,7 +1798,9 @@ export {
1775
1798
  RC4Drop,
1776
1799
  RIPEMD,
1777
1800
  ROT13,
1801
+ ROT13BruteForce,
1778
1802
  ROT47,
1803
+ ROT47BruteForce,
1779
1804
  RSADecrypt,
1780
1805
  RSAEncrypt,
1781
1806
  RSASign,
@@ -116,6 +116,8 @@ import "./tests/GetAllCasings.mjs";
116
116
  import "./tests/SIGABA.mjs";
117
117
  import "./tests/ELFInfo.mjs";
118
118
  import "./tests/Subsection.mjs";
119
+ import "./tests/CaesarBoxCipher.mjs";
120
+ import "./tests/LS47.mjs";
119
121
 
120
122
 
121
123
  // Cannot test operations that use the File type yet
@@ -0,0 +1,45 @@
1
+ /**
2
+ * Caesar Box Cipher tests.
3
+ *
4
+ * @author n1073645 [n1073645@gmail.com]
5
+ *
6
+ * @copyright Crown Copyright 2020
7
+ * @license Apache-2.0
8
+ */
9
+ import TestRegister from "../../lib/TestRegister.mjs";
10
+
11
+ TestRegister.addTests([
12
+ {
13
+ name: "Caesar Box Cipher: nothing",
14
+ input: "",
15
+ expectedOutput: "",
16
+ recipeConfig: [
17
+ {
18
+ op: "Caesar Box Cipher",
19
+ args: ["1"],
20
+ },
21
+ ],
22
+ },
23
+ {
24
+ name: "Caesar Box Cipher: Hello World!",
25
+ input: "Hello World!",
26
+ expectedOutput: "Hlodeor!lWl",
27
+ recipeConfig: [
28
+ {
29
+ op: "Caesar Box Cipher",
30
+ args: ["3"],
31
+ },
32
+ ],
33
+ },
34
+ {
35
+ name: "Caesar Box Cipher: Hello World!",
36
+ input: "Hlodeor!lWl",
37
+ expectedOutput: "HelloWorld!",
38
+ recipeConfig: [
39
+ {
40
+ op: "Caesar Box Cipher",
41
+ args: ["4"],
42
+ },
43
+ ],
44
+ }
45
+ ]);
@@ -0,0 +1,45 @@
1
+ /**
2
+ * LS47 tests.
3
+ *
4
+ * @author n1073645 [n1073645@gmail.com]
5
+ *
6
+ * @copyright Crown Copyright 2020
7
+ * @license Apache-2.0
8
+ */
9
+ import TestRegister from "../../lib/TestRegister.mjs";
10
+
11
+ TestRegister.addTests([
12
+ {
13
+ name: "LS47 Encrypt",
14
+ input: "thequickbrownfoxjumped",
15
+ expectedOutput: "(,t74ci78cp/8trx*yesu:alp1wqy",
16
+ recipeConfig: [
17
+ {
18
+ op: "LS47 Encrypt",
19
+ args: ["helloworld", 0, "test"],
20
+ },
21
+ ],
22
+ },
23
+ {
24
+ name: "LS47 Decrypt",
25
+ input: "(,t74ci78cp/8trx*yesu:alp1wqy",
26
+ expectedOutput: "thequickbrownfoxjumped---test",
27
+ recipeConfig: [
28
+ {
29
+ op: "LS47 Decrypt",
30
+ args: ["helloworld", 0],
31
+ },
32
+ ],
33
+ },
34
+ {
35
+ name: "LS47 Encrypt",
36
+ input: "thequickbrownfoxjumped",
37
+ expectedOutput: "Letter H is not included in LS47",
38
+ recipeConfig: [
39
+ {
40
+ op: "LS47 Encrypt",
41
+ args: ["Helloworld", 0, "test"],
42
+ },
43
+ ],
44
+ }
45
+ ]);