cyberchef 9.53.0 → 9.55.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,12 @@ All major and minor version changes will be documented in this file. Details of
13
13
 
14
14
  ## Details
15
15
 
16
+ ### [9.55.0] - 2022-12-09
17
+ - Added 'AMF Encode' and 'AMF Decode' operations [@n1474335] | [760eff4]
18
+
19
+ ### [9.54.0] - 2022-11-25
20
+ - Added 'Rabbit' operation [@mikecat] | [#1450]
21
+
16
22
  ### [9.53.0] - 2022-11-25
17
23
  - Added 'AES Key Wrap' and 'AES Key Unwrap' operations [@mikecat] | [#1456]
18
24
 
@@ -336,6 +342,8 @@ All major and minor version changes will be documented in this file. Details of
336
342
 
337
343
 
338
344
 
345
+ [9.55.0]: https://github.com/gchq/CyberChef/releases/tag/v9.55.0
346
+ [9.54.0]: https://github.com/gchq/CyberChef/releases/tag/v9.54.0
339
347
  [9.53.0]: https://github.com/gchq/CyberChef/releases/tag/v9.53.0
340
348
  [9.52.0]: https://github.com/gchq/CyberChef/releases/tag/v9.52.0
341
349
  [9.51.0]: https://github.com/gchq/CyberChef/releases/tag/v9.51.0
@@ -488,6 +496,7 @@ All major and minor version changes will be documented in this file. Details of
488
496
  [dd18e52]: https://github.com/gchq/CyberChef/commit/dd18e529939078b89867297b181a584e8b2cc7da
489
497
  [a895d1d]: https://github.com/gchq/CyberChef/commit/a895d1d82a2f92d440a0c5eca2bc7c898107b737
490
498
  [31a7f83]: https://github.com/gchq/CyberChef/commit/31a7f83b82e78927f89689f323fcb9185144d6ff
499
+ [760eff4]: https://github.com/gchq/CyberChef/commit/760eff49b5307aaa3104c5e5b437ffe62299acd1
491
500
 
492
501
  [#95]: https://github.com/gchq/CyberChef/pull/299
493
502
  [#173]: https://github.com/gchq/CyberChef/pull/173
@@ -589,4 +598,5 @@ All major and minor version changes will be documented in this file. Details of
589
598
  [#1457]: https://github.com/gchq/CyberChef/pull/1457
590
599
  [#1466]: https://github.com/gchq/CyberChef/pull/1466
591
600
  [#1456]: https://github.com/gchq/CyberChef/pull/1456
601
+ [#1450]: https://github.com/gchq/CyberChef/pull/1450
592
602
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cyberchef",
3
- "version": "9.53.0",
3
+ "version": "9.55.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",
@@ -86,6 +86,7 @@
86
86
  "worker-loader": "^3.0.8"
87
87
  },
88
88
  "dependencies": {
89
+ "@astronautlabs/amf": "^0.0.6",
89
90
  "@babel/polyfill": "^7.12.1",
90
91
  "@blu3r4y/lzma": "^2.3.3",
91
92
  "arrive": "^2.4.1",
@@ -151,6 +152,7 @@
151
152
  "process": "^0.11.10",
152
153
  "protobufjs": "^6.11.3",
153
154
  "qr-image": "^3.2.0",
155
+ "reflect-metadata": "^0.1.13",
154
156
  "scryptsy": "^2.1.0",
155
157
  "snackbarjs": "^1.1.0",
156
158
  "sortablejs": "^1.15.0",
@@ -46,6 +46,8 @@
46
46
  "From Quoted Printable",
47
47
  "To Punycode",
48
48
  "From Punycode",
49
+ "AMF Encode",
50
+ "AMF Decode",
49
51
  "To Hex Content",
50
52
  "From Hex Content",
51
53
  "PEM to Hex",
@@ -75,7 +77,6 @@
75
77
  "AES Decrypt",
76
78
  "Blowfish Encrypt",
77
79
  "Blowfish Decrypt",
78
- "ChaCha",
79
80
  "DES Encrypt",
80
81
  "DES Decrypt",
81
82
  "Triple DES Encrypt",
@@ -86,6 +87,8 @@
86
87
  "RC2 Decrypt",
87
88
  "RC4",
88
89
  "RC4 Drop",
90
+ "ChaCha",
91
+ "Rabbit",
89
92
  "SM4 Encrypt",
90
93
  "SM4 Decrypt",
91
94
  "ROT13",
@@ -446,6 +446,46 @@
446
446
  }
447
447
  ]
448
448
  },
449
+ "AMF Decode": {
450
+ "module": "Encodings",
451
+ "description": "Action Message Format (AMF) is a binary format used to serialize object graphs such as ActionScript objects and XML, or send messages between an Adobe Flash client and a remote service, usually a Flash Media Server or third party alternatives.",
452
+ "infoURL": "https://wikipedia.org/wiki/Action_Message_Format",
453
+ "inputType": "ArrayBuffer",
454
+ "outputType": "JSON",
455
+ "flowControl": false,
456
+ "manualBake": false,
457
+ "args": [
458
+ {
459
+ "name": "Format",
460
+ "type": "option",
461
+ "value": [
462
+ "AMF0",
463
+ "AMF3"
464
+ ],
465
+ "defaultIndex": 1
466
+ }
467
+ ]
468
+ },
469
+ "AMF Encode": {
470
+ "module": "Encodings",
471
+ "description": "Action Message Format (AMF) is a binary format used to serialize object graphs such as ActionScript objects and XML, or send messages between an Adobe Flash client and a remote service, usually a Flash Media Server or third party alternatives.",
472
+ "infoURL": "https://wikipedia.org/wiki/Action_Message_Format",
473
+ "inputType": "JSON",
474
+ "outputType": "ArrayBuffer",
475
+ "flowControl": false,
476
+ "manualBake": false,
477
+ "args": [
478
+ {
479
+ "name": "Format",
480
+ "type": "option",
481
+ "value": [
482
+ "AMF0",
483
+ "AMF3"
484
+ ],
485
+ "defaultIndex": 1
486
+ }
487
+ ]
488
+ },
449
489
  "AND": {
450
490
  "module": "Default",
451
491
  "description": "AND the input with the given key.<br>e.g. <code>fe023da5</code>",
@@ -10845,6 +10885,63 @@
10845
10885
  }
10846
10886
  ]
10847
10887
  },
10888
+ "Rabbit": {
10889
+ "module": "Ciphers",
10890
+ "description": "Rabbit is a high-speed stream cipher introduced in 2003 and defined in RFC 4503.<br><br>The cipher uses a 128-bit key and an optional 64-bit initialization vector (IV).<br><br>big-endian: based on RFC4503 and RFC3447<br>little-endian: compatible with Crypto++",
10891
+ "infoURL": "https://wikipedia.org/wiki/Rabbit_(cipher)",
10892
+ "inputType": "string",
10893
+ "outputType": "string",
10894
+ "flowControl": false,
10895
+ "manualBake": false,
10896
+ "args": [
10897
+ {
10898
+ "name": "Key",
10899
+ "type": "toggleString",
10900
+ "value": "",
10901
+ "toggleValues": [
10902
+ "Hex",
10903
+ "UTF8",
10904
+ "Latin1",
10905
+ "Base64"
10906
+ ]
10907
+ },
10908
+ {
10909
+ "name": "IV",
10910
+ "type": "toggleString",
10911
+ "value": "",
10912
+ "toggleValues": [
10913
+ "Hex",
10914
+ "UTF8",
10915
+ "Latin1",
10916
+ "Base64"
10917
+ ]
10918
+ },
10919
+ {
10920
+ "name": "Endianness",
10921
+ "type": "option",
10922
+ "value": [
10923
+ "Big",
10924
+ "Little"
10925
+ ]
10926
+ },
10927
+ {
10928
+ "name": "Input",
10929
+ "type": "option",
10930
+ "value": [
10931
+ "Raw",
10932
+ "Hex"
10933
+ ]
10934
+ },
10935
+ {
10936
+ "name": "Output",
10937
+ "type": "option",
10938
+ "value": [
10939
+ "Raw",
10940
+ "Hex"
10941
+ ]
10942
+ }
10943
+ ]
10944
+ },
10848
10945
  "Rail Fence Cipher Decode": {
10849
10946
  "module": "Ciphers",
10850
10947
  "description": "Decodes Strings that were created using the Rail fence Cipher provided a key and an offset",
@@ -35,6 +35,7 @@ import RSADecrypt from "../../operations/RSADecrypt.mjs";
35
35
  import RSAEncrypt from "../../operations/RSAEncrypt.mjs";
36
36
  import RSASign from "../../operations/RSASign.mjs";
37
37
  import RSAVerify from "../../operations/RSAVerify.mjs";
38
+ import Rabbit from "../../operations/Rabbit.mjs";
38
39
  import RailFenceCipherDecode from "../../operations/RailFenceCipherDecode.mjs";
39
40
  import RailFenceCipherEncode from "../../operations/RailFenceCipherEncode.mjs";
40
41
  import SM4Decrypt from "../../operations/SM4Decrypt.mjs";
@@ -77,6 +78,7 @@ OpModules.Ciphers = {
77
78
  "RSA Encrypt": RSAEncrypt,
78
79
  "RSA Sign": RSASign,
79
80
  "RSA Verify": RSAVerify,
81
+ "Rabbit": Rabbit,
80
82
  "Rail Fence Cipher Decode": RailFenceCipherDecode,
81
83
  "Rail Fence Cipher Encode": RailFenceCipherEncode,
82
84
  "SM4 Decrypt": SM4Decrypt,
@@ -5,6 +5,8 @@
5
5
  * @copyright Crown Copyright 2022
6
6
  * @license Apache-2.0
7
7
  */
8
+ import AMFDecode from "../../operations/AMFDecode.mjs";
9
+ import AMFEncode from "../../operations/AMFEncode.mjs";
8
10
  import CitrixCTX1Decode from "../../operations/CitrixCTX1Decode.mjs";
9
11
  import CitrixCTX1Encode from "../../operations/CitrixCTX1Encode.mjs";
10
12
  import DecodeText from "../../operations/DecodeText.mjs";
@@ -19,6 +21,8 @@ import ToPunycode from "../../operations/ToPunycode.mjs";
19
21
  const OpModules = typeof self === "undefined" ? {} : self.OpModules || {};
20
22
 
21
23
  OpModules.Encodings = {
24
+ "AMF Decode": AMFDecode,
25
+ "AMF Encode": AMFEncode,
22
26
  "Citrix CTX1 Decode": CitrixCTX1Decode,
23
27
  "Citrix CTX1 Encode": CitrixCTX1Encode,
24
28
  "Decode text": DecodeText,
@@ -9,6 +9,7 @@
9
9
  */
10
10
  import CiphersModule from "./Ciphers.mjs";
11
11
  import DefaultModule from "./Default.mjs";
12
+ import EncodingsModule from "./Encodings.mjs";
12
13
  import ImageModule from "./Image.mjs";
13
14
  import CryptoModule from "./Crypto.mjs";
14
15
  import SerialiseModule from "./Serialise.mjs";
@@ -16,7 +17,6 @@ import HashingModule from "./Hashing.mjs";
16
17
  import BletchleyModule from "./Bletchley.mjs";
17
18
  import CompressionModule from "./Compression.mjs";
18
19
  import CodeModule from "./Code.mjs";
19
- import EncodingsModule from "./Encodings.mjs";
20
20
  import DiffModule from "./Diff.mjs";
21
21
  import ShellcodeModule from "./Shellcode.mjs";
22
22
  import ChartsModule from "./Charts.mjs";
@@ -35,6 +35,7 @@ Object.assign(
35
35
  OpModules,
36
36
  CiphersModule,
37
37
  DefaultModule,
38
+ EncodingsModule,
38
39
  ImageModule,
39
40
  CryptoModule,
40
41
  SerialiseModule,
@@ -42,7 +43,6 @@ Object.assign(
42
43
  BletchleyModule,
43
44
  CompressionModule,
44
45
  CodeModule,
45
- EncodingsModule,
46
46
  DiffModule,
47
47
  ShellcodeModule,
48
48
  ChartsModule,
@@ -0,0 +1,52 @@
1
+ /**
2
+ * @author n1474335 [n1474335@gmail.com]
3
+ * @copyright Crown Copyright 2022
4
+ * @license Apache-2.0
5
+ */
6
+
7
+ import Operation from "../Operation.mjs";
8
+ import "reflect-metadata"; // Required as a shim for the amf library
9
+ import { AMF0, AMF3 } from "@astronautlabs/amf";
10
+
11
+ /**
12
+ * AMF Decode operation
13
+ */
14
+ class AMFDecode extends Operation {
15
+
16
+ /**
17
+ * AMFDecode constructor
18
+ */
19
+ constructor() {
20
+ super();
21
+
22
+ this.name = "AMF Decode";
23
+ this.module = "Encodings";
24
+ this.description = "Action Message Format (AMF) is a binary format used to serialize object graphs such as ActionScript objects and XML, or send messages between an Adobe Flash client and a remote service, usually a Flash Media Server or third party alternatives.";
25
+ this.infoURL = "https://wikipedia.org/wiki/Action_Message_Format";
26
+ this.inputType = "ArrayBuffer";
27
+ this.outputType = "JSON";
28
+ this.args = [
29
+ {
30
+ name: "Format",
31
+ type: "option",
32
+ value: ["AMF0", "AMF3"],
33
+ defaultIndex: 1
34
+ }
35
+ ];
36
+ }
37
+
38
+ /**
39
+ * @param {ArrayBuffer} input
40
+ * @param {Object[]} args
41
+ * @returns {JSON}
42
+ */
43
+ run(input, args) {
44
+ const [format] = args;
45
+ const handler = format === "AMF0" ? AMF0 : AMF3;
46
+ const encoded = new Uint8Array(input);
47
+ return handler.Value.deserialize(encoded);
48
+ }
49
+
50
+ }
51
+
52
+ export default AMFDecode;
@@ -0,0 +1,52 @@
1
+ /**
2
+ * @author n1474335 [n1474335@gmail.com]
3
+ * @copyright Crown Copyright 2022
4
+ * @license Apache-2.0
5
+ */
6
+
7
+ import Operation from "../Operation.mjs";
8
+ import "reflect-metadata"; // Required as a shim for the amf library
9
+ import { AMF0, AMF3 } from "@astronautlabs/amf";
10
+
11
+ /**
12
+ * AMF Encode operation
13
+ */
14
+ class AMFEncode extends Operation {
15
+
16
+ /**
17
+ * AMFEncode constructor
18
+ */
19
+ constructor() {
20
+ super();
21
+
22
+ this.name = "AMF Encode";
23
+ this.module = "Encodings";
24
+ this.description = "Action Message Format (AMF) is a binary format used to serialize object graphs such as ActionScript objects and XML, or send messages between an Adobe Flash client and a remote service, usually a Flash Media Server or third party alternatives.";
25
+ this.infoURL = "https://wikipedia.org/wiki/Action_Message_Format";
26
+ this.inputType = "JSON";
27
+ this.outputType = "ArrayBuffer";
28
+ this.args = [
29
+ {
30
+ name: "Format",
31
+ type: "option",
32
+ value: ["AMF0", "AMF3"],
33
+ defaultIndex: 1
34
+ }
35
+ ];
36
+ }
37
+
38
+ /**
39
+ * @param {JSON} input
40
+ * @param {Object[]} args
41
+ * @returns {ArrayBuffer}
42
+ */
43
+ run(input, args) {
44
+ const [format] = args;
45
+ const handler = format === "AMF0" ? AMF0 : AMF3;
46
+ const output = handler.Value.any(input).serialize();
47
+ return output.buffer;
48
+ }
49
+
50
+ }
51
+
52
+ export default AMFEncode;
@@ -0,0 +1,247 @@
1
+ /**
2
+ * @author mikecat
3
+ * @copyright Crown Copyright 2022
4
+ * @license Apache-2.0
5
+ */
6
+
7
+ import Operation from "../Operation.mjs";
8
+ import Utils from "../Utils.mjs";
9
+ import { toHexFast } from "../lib/Hex.mjs";
10
+ import OperationError from "../errors/OperationError.mjs";
11
+
12
+ /**
13
+ * Rabbit operation
14
+ */
15
+ class Rabbit extends Operation {
16
+
17
+ /**
18
+ * Rabbit constructor
19
+ */
20
+ constructor() {
21
+ super();
22
+
23
+ this.name = "Rabbit";
24
+ this.module = "Ciphers";
25
+ this.description = "Rabbit is a high-speed stream cipher introduced in 2003 and defined in RFC 4503.<br><br>The cipher uses a 128-bit key and an optional 64-bit initialization vector (IV).<br><br>big-endian: based on RFC4503 and RFC3447<br>little-endian: compatible with Crypto++";
26
+ this.infoURL = "https://wikipedia.org/wiki/Rabbit_(cipher)";
27
+ this.inputType = "string";
28
+ this.outputType = "string";
29
+ this.args = [
30
+ {
31
+ "name": "Key",
32
+ "type": "toggleString",
33
+ "value": "",
34
+ "toggleValues": ["Hex", "UTF8", "Latin1", "Base64"]
35
+ },
36
+ {
37
+ "name": "IV",
38
+ "type": "toggleString",
39
+ "value": "",
40
+ "toggleValues": ["Hex", "UTF8", "Latin1", "Base64"]
41
+ },
42
+ {
43
+ "name": "Endianness",
44
+ "type": "option",
45
+ "value": ["Big", "Little"]
46
+ },
47
+ {
48
+ "name": "Input",
49
+ "type": "option",
50
+ "value": ["Raw", "Hex"]
51
+ },
52
+ {
53
+ "name": "Output",
54
+ "type": "option",
55
+ "value": ["Raw", "Hex"]
56
+ }
57
+ ];
58
+ }
59
+
60
+ /**
61
+ * @param {string} input
62
+ * @param {Object[]} args
63
+ * @returns {string}
64
+ */
65
+ run(input, args) {
66
+ const key = Utils.convertToByteArray(args[0].string, args[0].option),
67
+ iv = Utils.convertToByteArray(args[1].string, args[1].option),
68
+ endianness = args[2],
69
+ inputType = args[3],
70
+ outputType = args[4];
71
+
72
+ const littleEndian = endianness === "Little";
73
+
74
+ if (key.length !== 16) {
75
+ throw new OperationError(`Invalid key length: ${key.length} bytes (expected: 16)`);
76
+ }
77
+ if (iv.length !== 0 && iv.length !== 8) {
78
+ throw new OperationError(`Invalid IV length: ${iv.length} bytes (expected: 0 or 8)`);
79
+ }
80
+
81
+ // Inner State
82
+ const X = new Uint32Array(8), C = new Uint32Array(8);
83
+ let b = 0;
84
+
85
+ // Counter System
86
+ const A = [
87
+ 0x4d34d34d, 0xd34d34d3, 0x34d34d34, 0x4d34d34d,
88
+ 0xd34d34d3, 0x34d34d34, 0x4d34d34d, 0xd34d34d3
89
+ ];
90
+ const counterUpdate = function() {
91
+ for (let j = 0; j < 8; j++) {
92
+ const temp = C[j] + A[j] + b;
93
+ b = (temp / ((1 << 30) * 4)) >>> 0;
94
+ C[j] = temp;
95
+ }
96
+ };
97
+
98
+ // Next-State Function
99
+ const g = function(u, v) {
100
+ const uv = (u + v) >>> 0;
101
+ const upper = uv >>> 16, lower = uv & 0xffff;
102
+ const upperUpper = upper * upper;
103
+ const upperLower2 = 2 * upper * lower;
104
+ const lowerLower = lower * lower;
105
+ const mswTemp = upperUpper + ((upperLower2 / (1 << 16)) >>> 0);
106
+ const lswTemp = lowerLower + (upperLower2 & 0xffff) * (1 << 16);
107
+ const msw = mswTemp + ((lswTemp / ((1 << 30) * 4)) >>> 0);
108
+ const lsw = lswTemp >>> 0;
109
+ return lsw ^ msw;
110
+ };
111
+ const leftRotate = function(value, width) {
112
+ return (value << width) | (value >>> (32 - width));
113
+ };
114
+ const nextStateHelper1 = function(v0, v1, v2) {
115
+ return v0 + leftRotate(v1, 16) + leftRotate(v2, 16);
116
+ };
117
+ const nextStateHelper2 = function(v0, v1, v2) {
118
+ return v0 + leftRotate(v1, 8) + v2;
119
+ };
120
+ const G = new Uint32Array(8);
121
+ const nextState = function() {
122
+ for (let j = 0; j < 8; j++) {
123
+ G[j] = g(X[j], C[j]);
124
+ }
125
+ X[0] = nextStateHelper1(G[0], G[7], G[6]);
126
+ X[1] = nextStateHelper2(G[1], G[0], G[7]);
127
+ X[2] = nextStateHelper1(G[2], G[1], G[0]);
128
+ X[3] = nextStateHelper2(G[3], G[2], G[1]);
129
+ X[4] = nextStateHelper1(G[4], G[3], G[2]);
130
+ X[5] = nextStateHelper2(G[5], G[4], G[3]);
131
+ X[6] = nextStateHelper1(G[6], G[5], G[4]);
132
+ X[7] = nextStateHelper2(G[7], G[6], G[5]);
133
+ };
134
+
135
+ // Key Setup Scheme
136
+ const K = new Uint16Array(8);
137
+ if (littleEndian) {
138
+ for (let i = 0; i < 8; i++) {
139
+ K[i] = (key[1 + 2 * i] << 8) | key[2 * i];
140
+ }
141
+ } else {
142
+ for (let i = 0; i < 8; i++) {
143
+ K[i] = (key[14 - 2 * i] << 8) | key[15 - 2 * i];
144
+ }
145
+ }
146
+ for (let j = 0; j < 8; j++) {
147
+ if (j % 2 === 0) {
148
+ X[j] = (K[(j + 1) % 8] << 16) | K[j];
149
+ C[j] = (K[(j + 4) % 8] << 16) | K[(j + 5) % 8];
150
+ } else {
151
+ X[j] = (K[(j + 5) % 8] << 16) | K[(j + 4) % 8];
152
+ C[j] = (K[j] << 16) | K[(j + 1) % 8];
153
+ }
154
+ }
155
+ for (let i = 0; i < 4; i++) {
156
+ counterUpdate();
157
+ nextState();
158
+ }
159
+ for (let j = 0; j < 8; j++) {
160
+ C[j] = C[j] ^ X[(j + 4) % 8];
161
+ }
162
+
163
+ // IV Setup Scheme
164
+ if (iv.length === 8) {
165
+ const getIVValue = function(a, b, c, d) {
166
+ if (littleEndian) {
167
+ return (iv[a] << 24) | (iv[b] << 16) |
168
+ (iv[c] << 8) | iv[d];
169
+ } else {
170
+ return (iv[7 - a] << 24) | (iv[7 - b] << 16) |
171
+ (iv[7 - c] << 8) | iv[7 - d];
172
+ }
173
+ };
174
+ C[0] = C[0] ^ getIVValue(3, 2, 1, 0);
175
+ C[1] = C[1] ^ getIVValue(7, 6, 3, 2);
176
+ C[2] = C[2] ^ getIVValue(7, 6, 5, 4);
177
+ C[3] = C[3] ^ getIVValue(5, 4, 1, 0);
178
+ C[4] = C[4] ^ getIVValue(3, 2, 1, 0);
179
+ C[5] = C[5] ^ getIVValue(7, 6, 3, 2);
180
+ C[6] = C[6] ^ getIVValue(7, 6, 5, 4);
181
+ C[7] = C[7] ^ getIVValue(5, 4, 1, 0);
182
+ for (let i = 0; i < 4; i++) {
183
+ counterUpdate();
184
+ nextState();
185
+ }
186
+ }
187
+
188
+ // Extraction Scheme
189
+ const S = new Uint8Array(16);
190
+ const extract = function() {
191
+ let pos = 0;
192
+ const addPart = function(value) {
193
+ S[pos++] = value >>> 8;
194
+ S[pos++] = value & 0xff;
195
+ };
196
+ counterUpdate();
197
+ nextState();
198
+ addPart((X[6] >>> 16) ^ (X[1] & 0xffff));
199
+ addPart((X[6] & 0xffff) ^ (X[3] >>> 16));
200
+ addPart((X[4] >>> 16) ^ (X[7] & 0xffff));
201
+ addPart((X[4] & 0xffff) ^ (X[1] >>> 16));
202
+ addPart((X[2] >>> 16) ^ (X[5] & 0xffff));
203
+ addPart((X[2] & 0xffff) ^ (X[7] >>> 16));
204
+ addPart((X[0] >>> 16) ^ (X[3] & 0xffff));
205
+ addPart((X[0] & 0xffff) ^ (X[5] >>> 16));
206
+ if (littleEndian) {
207
+ for (let i = 0, j = S.length - 1; i < j;) {
208
+ const temp = S[i];
209
+ S[i] = S[j];
210
+ S[j] = temp;
211
+ i++;
212
+ j--;
213
+ }
214
+ }
215
+ };
216
+
217
+ const data = Utils.convertToByteString(input, inputType);
218
+ const result = new Uint8Array(data.length);
219
+ for (let i = 0; i <= data.length - 16; i += 16) {
220
+ extract();
221
+ for (let j = 0; j < 16; j++) {
222
+ result[i + j] = data.charCodeAt(i + j) ^ S[j];
223
+ }
224
+ }
225
+ if (data.length % 16 !== 0) {
226
+ const offset = data.length - data.length % 16;
227
+ const length = data.length - offset;
228
+ extract();
229
+ if (littleEndian) {
230
+ for (let j = 0; j < length; j++) {
231
+ result[offset + j] = data.charCodeAt(offset + j) ^ S[j];
232
+ }
233
+ } else {
234
+ for (let j = 0; j < length; j++) {
235
+ result[offset + j] = data.charCodeAt(offset + j) ^ S[16 - length + j];
236
+ }
237
+ }
238
+ }
239
+ if (outputType === "Hex") {
240
+ return toHexFast(result);
241
+ }
242
+ return Utils.byteArrayToChars(result);
243
+ }
244
+
245
+ }
246
+
247
+ export default Rabbit;
@@ -12,6 +12,8 @@ import AESDecrypt from "./AESDecrypt.mjs";
12
12
  import AESEncrypt from "./AESEncrypt.mjs";
13
13
  import AESKeyUnwrap from "./AESKeyUnwrap.mjs";
14
14
  import AESKeyWrap from "./AESKeyWrap.mjs";
15
+ import AMFDecode from "./AMFDecode.mjs";
16
+ import AMFEncode from "./AMFEncode.mjs";
15
17
  import AND from "./AND.mjs";
16
18
  import AddLineNumbers from "./AddLineNumbers.mjs";
17
19
  import AddTextToImage from "./AddTextToImage.mjs";
@@ -274,6 +276,7 @@ import RSADecrypt from "./RSADecrypt.mjs";
274
276
  import RSAEncrypt from "./RSAEncrypt.mjs";
275
277
  import RSASign from "./RSASign.mjs";
276
278
  import RSAVerify from "./RSAVerify.mjs";
279
+ import Rabbit from "./Rabbit.mjs";
277
280
  import RailFenceCipherDecode from "./RailFenceCipherDecode.mjs";
278
281
  import RailFenceCipherEncode from "./RailFenceCipherEncode.mjs";
279
282
  import RandomizeColourPalette from "./RandomizeColourPalette.mjs";
@@ -408,6 +411,8 @@ export {
408
411
  AESEncrypt,
409
412
  AESKeyUnwrap,
410
413
  AESKeyWrap,
414
+ AMFDecode,
415
+ AMFEncode,
411
416
  AND,
412
417
  AddLineNumbers,
413
418
  AddTextToImage,
@@ -670,6 +675,7 @@ export {
670
675
  RSAEncrypt,
671
676
  RSASign,
672
677
  RSAVerify,
678
+ Rabbit,
673
679
  RailFenceCipherDecode,
674
680
  RailFenceCipherEncode,
675
681
  RandomizeColourPalette,
@@ -22,6 +22,8 @@ import {
22
22
  AESEncrypt as core_AESEncrypt,
23
23
  AESKeyUnwrap as core_AESKeyUnwrap,
24
24
  AESKeyWrap as core_AESKeyWrap,
25
+ AMFDecode as core_AMFDecode,
26
+ AMFEncode as core_AMFEncode,
25
27
  AND as core_AND,
26
28
  AddLineNumbers as core_AddLineNumbers,
27
29
  AddTextToImage as core_AddTextToImage,
@@ -275,6 +277,7 @@ import {
275
277
  RSAEncrypt as core_RSAEncrypt,
276
278
  RSASign as core_RSASign,
277
279
  RSAVerify as core_RSAVerify,
280
+ Rabbit as core_Rabbit,
278
281
  RailFenceCipherDecode as core_RailFenceCipherDecode,
279
282
  RailFenceCipherEncode as core_RailFenceCipherEncode,
280
283
  RandomizeColourPalette as core_RandomizeColourPalette,
@@ -418,6 +421,8 @@ function generateChef() {
418
421
  "AESEncrypt": _wrap(core_AESEncrypt),
419
422
  "AESKeyUnwrap": _wrap(core_AESKeyUnwrap),
420
423
  "AESKeyWrap": _wrap(core_AESKeyWrap),
424
+ "AMFDecode": _wrap(core_AMFDecode),
425
+ "AMFEncode": _wrap(core_AMFEncode),
421
426
  "AND": _wrap(core_AND),
422
427
  "addLineNumbers": _wrap(core_AddLineNumbers),
423
428
  "addTextToImage": _wrap(core_AddTextToImage),
@@ -671,6 +676,7 @@ function generateChef() {
671
676
  "RSAEncrypt": _wrap(core_RSAEncrypt),
672
677
  "RSASign": _wrap(core_RSASign),
673
678
  "RSAVerify": _wrap(core_RSAVerify),
679
+ "rabbit": _wrap(core_Rabbit),
674
680
  "railFenceCipherDecode": _wrap(core_RailFenceCipherDecode),
675
681
  "railFenceCipherEncode": _wrap(core_RailFenceCipherEncode),
676
682
  "randomizeColourPalette": _wrap(core_RandomizeColourPalette),
@@ -822,6 +828,8 @@ const AESDecrypt = chef.AESDecrypt;
822
828
  const AESEncrypt = chef.AESEncrypt;
823
829
  const AESKeyUnwrap = chef.AESKeyUnwrap;
824
830
  const AESKeyWrap = chef.AESKeyWrap;
831
+ const AMFDecode = chef.AMFDecode;
832
+ const AMFEncode = chef.AMFEncode;
825
833
  const AND = chef.AND;
826
834
  const addLineNumbers = chef.addLineNumbers;
827
835
  const addTextToImage = chef.addTextToImage;
@@ -1084,6 +1092,7 @@ const RSADecrypt = chef.RSADecrypt;
1084
1092
  const RSAEncrypt = chef.RSAEncrypt;
1085
1093
  const RSASign = chef.RSASign;
1086
1094
  const RSAVerify = chef.RSAVerify;
1095
+ const rabbit = chef.rabbit;
1087
1096
  const railFenceCipherDecode = chef.railFenceCipherDecode;
1088
1097
  const railFenceCipherEncode = chef.railFenceCipherEncode;
1089
1098
  const randomizeColourPalette = chef.randomizeColourPalette;
@@ -1220,6 +1229,8 @@ const operations = [
1220
1229
  AESEncrypt,
1221
1230
  AESKeyUnwrap,
1222
1231
  AESKeyWrap,
1232
+ AMFDecode,
1233
+ AMFEncode,
1223
1234
  AND,
1224
1235
  addLineNumbers,
1225
1236
  addTextToImage,
@@ -1482,6 +1493,7 @@ const operations = [
1482
1493
  RSAEncrypt,
1483
1494
  RSASign,
1484
1495
  RSAVerify,
1496
+ rabbit,
1485
1497
  railFenceCipherDecode,
1486
1498
  railFenceCipherEncode,
1487
1499
  randomizeColourPalette,
@@ -1622,6 +1634,8 @@ export {
1622
1634
  AESEncrypt,
1623
1635
  AESKeyUnwrap,
1624
1636
  AESKeyWrap,
1637
+ AMFDecode,
1638
+ AMFEncode,
1625
1639
  AND,
1626
1640
  addLineNumbers,
1627
1641
  addTextToImage,
@@ -1884,6 +1898,7 @@ export {
1884
1898
  RSAEncrypt,
1885
1899
  RSASign,
1886
1900
  RSAVerify,
1901
+ rabbit,
1887
1902
  railFenceCipherDecode,
1888
1903
  railFenceCipherEncode,
1889
1904
  randomizeColourPalette,
@@ -129,6 +129,7 @@ import "./tests/Shuffle.mjs";
129
129
  import "./tests/FletcherChecksum.mjs";
130
130
  import "./tests/CMAC.mjs";
131
131
  import "./tests/AESKeyWrap.mjs";
132
+ import "./tests/Rabbit.mjs";
132
133
 
133
134
  // Cannot test operations that use the File type yet
134
135
  // import "./tests/SplitColourChannels.mjs";
@@ -0,0 +1,177 @@
1
+ /**
2
+ * @author mikecat
3
+ * @copyright Crown Copyright 2022
4
+ * @license Apache-2.0
5
+ */
6
+
7
+ import TestRegister from "../../lib/TestRegister.mjs";
8
+
9
+ TestRegister.addTests([
10
+ {
11
+ name: "Rabbit: RFC Test vector, without IV 1",
12
+ input: "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
13
+ expectedOutput: "b15754f036a5d6ecf56b45261c4af70288e8d815c59c0c397b696c4789c68aa7f416a1c3700cd451da68d1881673d696",
14
+ recipeConfig: [
15
+ {
16
+ "op": "Rabbit",
17
+ "args": [
18
+ {"option": "Hex", "string": "00000000000000000000000000000000"},
19
+ {"option": "Hex", "string": ""},
20
+ "Big", "Hex", "Hex"
21
+ ]
22
+ }
23
+ ]
24
+ },
25
+ {
26
+ name: "Rabbit: RFC Test vector, without IV 2",
27
+ input: "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
28
+ expectedOutput: "3d2df3c83ef627a1e97fc38487e2519cf576cd61f4405b8896bf53aa8554fc19e5547473fbdb43508ae53b20204d4c5e",
29
+ recipeConfig: [
30
+ {
31
+ "op": "Rabbit",
32
+ "args": [
33
+ {"option": "Hex", "string": "912813292e3d36fe3bfc62f1dc51c3ac"},
34
+ {"option": "Hex", "string": ""},
35
+ "Big", "Hex", "Hex"
36
+ ]
37
+ }
38
+ ]
39
+ },
40
+ {
41
+ name: "Rabbit: RFC Test vector, without IV 3",
42
+ input: "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
43
+ expectedOutput: "0cb10dcda041cdac32eb5cfd02d0609b95fc9fca0f17015a7b7092114cff3ead9649e5de8bfc7f3f924147ad3a947428",
44
+ recipeConfig: [
45
+ {
46
+ "op": "Rabbit",
47
+ "args": [
48
+ {"option": "Hex", "string": "8395741587e0c733e9e9ab01c09b0043"},
49
+ {"option": "Hex", "string": ""},
50
+ "Big", "Hex", "Hex"
51
+ ]
52
+ }
53
+ ]
54
+ },
55
+ {
56
+ name: "Rabbit: RFC Test vector, with IV 1",
57
+ input: "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
58
+ expectedOutput: "c6a7275ef85495d87ccd5d376705b7ed5f29a6ac04f5efd47b8f293270dc4a8d2ade822b29de6c1ee52bdb8a47bf8f66",
59
+ recipeConfig: [
60
+ {
61
+ "op": "Rabbit",
62
+ "args": [
63
+ {"option": "Hex", "string": "00000000000000000000000000000000"},
64
+ {"option": "Hex", "string": "0000000000000000"},
65
+ "Big", "Hex", "Hex"
66
+ ]
67
+ }
68
+ ]
69
+ },
70
+ {
71
+ name: "Rabbit: RFC Test vector, with IV 2",
72
+ input: "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
73
+ expectedOutput: "1fcd4eb9580012e2e0dccc9222017d6da75f4e10d12125017b2499ffed936f2eebc112c393e738392356bdd012029ba7",
74
+ recipeConfig: [
75
+ {
76
+ "op": "Rabbit",
77
+ "args": [
78
+ {"option": "Hex", "string": "00000000000000000000000000000000"},
79
+ {"option": "Hex", "string": "c373f575c1267e59"},
80
+ "Big", "Hex", "Hex"
81
+ ]
82
+ }
83
+ ]
84
+ },
85
+ {
86
+ name: "Rabbit: RFC Test vector, with IV 3",
87
+ input: "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
88
+ expectedOutput: "445ad8c805858dbf70b6af23a151104d96c8f27947f42c5baeae67c6acc35b039fcbfc895fa71c17313df034f01551cb",
89
+ recipeConfig: [
90
+ {
91
+ "op": "Rabbit",
92
+ "args": [
93
+ {"option": "Hex", "string": "00000000000000000000000000000000"},
94
+ {"option": "Hex", "string": "a6eb561ad2f41727"},
95
+ "Big", "Hex", "Hex"
96
+ ]
97
+ }
98
+ ]
99
+ },
100
+ {
101
+ name: "Rabbit: generated stream should be XORed with the input",
102
+ input: "cedda96c054e3ddd93da7ed05e2a4b7bdb0c00fe214f03502e2708b2c2bfc77aa2311b0b9af8aa78d119f92b26db0a6b",
103
+ expectedOutput: "7f8afd9c33ebeb3166b13bf64260bc7953e4d8ebe4d30f69554e64f54b794ddd5627bac8eaf47e290b7128a330a8dcfd",
104
+ recipeConfig: [
105
+ {
106
+ "op": "Rabbit",
107
+ "args": [
108
+ {"option": "Hex", "string": "00000000000000000000000000000000"},
109
+ {"option": "Hex", "string": ""},
110
+ "Big", "Hex", "Hex"
111
+ ]
112
+ }
113
+ ]
114
+ },
115
+ {
116
+ name: "Rabbit: least significant bits should be used for the last block",
117
+ input: "0000000000000000",
118
+ expectedOutput: "f56b45261c4af702",
119
+ recipeConfig: [
120
+ {
121
+ "op": "Rabbit",
122
+ "args": [
123
+ {"option": "Hex", "string": "00000000000000000000000000000000"},
124
+ {"option": "Hex", "string": ""},
125
+ "Big", "Hex", "Hex"
126
+ ]
127
+ }
128
+ ]
129
+ },
130
+ {
131
+ name: "Rabbit: invalid key length",
132
+ input: "",
133
+ expectedOutput: "Invalid key length: 8 bytes (expected: 16)",
134
+ recipeConfig: [
135
+ {
136
+ "op": "Rabbit",
137
+ "args": [
138
+ {"option": "Hex", "string": "0000000000000000"},
139
+ {"option": "Hex", "string": ""},
140
+ "Big", "Hex", "Hex"
141
+ ]
142
+ }
143
+ ]
144
+ },
145
+ {
146
+ name: "Rabbit: invalid IV length",
147
+ input: "",
148
+ expectedOutput: "Invalid IV length: 4 bytes (expected: 0 or 8)",
149
+ recipeConfig: [
150
+ {
151
+ "op": "Rabbit",
152
+ "args": [
153
+ {"option": "Hex", "string": "00000000000000000000000000000000"},
154
+ {"option": "Hex", "string": "00000000"},
155
+ "Big", "Hex", "Hex"
156
+ ]
157
+ }
158
+ ]
159
+ },
160
+ {
161
+ // this testcase is taken from the first example on Crypto++ Wiki
162
+ // https://www.cryptopp.com/wiki/Rabbit
163
+ name: "Rabbit: little-endian mode (Crypto++ compatible)",
164
+ input: "Rabbit stream cipher test",
165
+ expectedOutput: "1ae2d4edcf9b6063b00fd6fda0b223aded157e77031cf0440b",
166
+ recipeConfig: [
167
+ {
168
+ "op": "Rabbit",
169
+ "args": [
170
+ {"option": "Hex", "string": "23c2731e8b5469fd8dabb5bc592a0f3a"},
171
+ {"option": "Hex", "string": "712906405ef03201"},
172
+ "Little", "Raw", "Hex"
173
+ ]
174
+ }
175
+ ]
176
+ },
177
+ ]);