cyberchef 9.53.0 → 9.54.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,9 @@ All major and minor version changes will be documented in this file. Details of
13
13
 
14
14
  ## Details
15
15
 
16
+ ### [9.54.0] - 2022-11-25
17
+ - Added 'Rabbit' operation [@mikecat] | [#1450]
18
+
16
19
  ### [9.53.0] - 2022-11-25
17
20
  - Added 'AES Key Wrap' and 'AES Key Unwrap' operations [@mikecat] | [#1456]
18
21
 
@@ -336,6 +339,7 @@ All major and minor version changes will be documented in this file. Details of
336
339
 
337
340
 
338
341
 
342
+ [9.54.0]: https://github.com/gchq/CyberChef/releases/tag/v9.54.0
339
343
  [9.53.0]: https://github.com/gchq/CyberChef/releases/tag/v9.53.0
340
344
  [9.52.0]: https://github.com/gchq/CyberChef/releases/tag/v9.52.0
341
345
  [9.51.0]: https://github.com/gchq/CyberChef/releases/tag/v9.51.0
@@ -589,4 +593,5 @@ All major and minor version changes will be documented in this file. Details of
589
593
  [#1457]: https://github.com/gchq/CyberChef/pull/1457
590
594
  [#1466]: https://github.com/gchq/CyberChef/pull/1466
591
595
  [#1456]: https://github.com/gchq/CyberChef/pull/1456
596
+ [#1450]: https://github.com/gchq/CyberChef/pull/1450
592
597
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cyberchef",
3
- "version": "9.53.0",
3
+ "version": "9.54.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",
@@ -75,7 +75,6 @@
75
75
  "AES Decrypt",
76
76
  "Blowfish Encrypt",
77
77
  "Blowfish Decrypt",
78
- "ChaCha",
79
78
  "DES Encrypt",
80
79
  "DES Decrypt",
81
80
  "Triple DES Encrypt",
@@ -86,6 +85,8 @@
86
85
  "RC2 Decrypt",
87
86
  "RC4",
88
87
  "RC4 Drop",
88
+ "ChaCha",
89
+ "Rabbit",
89
90
  "SM4 Encrypt",
90
91
  "SM4 Decrypt",
91
92
  "ROT13",
@@ -10845,6 +10845,63 @@
10845
10845
  }
10846
10846
  ]
10847
10847
  },
10848
+ "Rabbit": {
10849
+ "module": "Ciphers",
10850
+ "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++",
10851
+ "infoURL": "https://wikipedia.org/wiki/Rabbit_(cipher)",
10852
+ "inputType": "string",
10853
+ "outputType": "string",
10854
+ "flowControl": false,
10855
+ "manualBake": false,
10856
+ "args": [
10857
+ {
10858
+ "name": "Key",
10859
+ "type": "toggleString",
10860
+ "value": "",
10861
+ "toggleValues": [
10862
+ "Hex",
10863
+ "UTF8",
10864
+ "Latin1",
10865
+ "Base64"
10866
+ ]
10867
+ },
10868
+ {
10869
+ "name": "IV",
10870
+ "type": "toggleString",
10871
+ "value": "",
10872
+ "toggleValues": [
10873
+ "Hex",
10874
+ "UTF8",
10875
+ "Latin1",
10876
+ "Base64"
10877
+ ]
10878
+ },
10879
+ {
10880
+ "name": "Endianness",
10881
+ "type": "option",
10882
+ "value": [
10883
+ "Big",
10884
+ "Little"
10885
+ ]
10886
+ },
10887
+ {
10888
+ "name": "Input",
10889
+ "type": "option",
10890
+ "value": [
10891
+ "Raw",
10892
+ "Hex"
10893
+ ]
10894
+ },
10895
+ {
10896
+ "name": "Output",
10897
+ "type": "option",
10898
+ "value": [
10899
+ "Raw",
10900
+ "Hex"
10901
+ ]
10902
+ }
10903
+ ]
10904
+ },
10848
10905
  "Rail Fence Cipher Decode": {
10849
10906
  "module": "Ciphers",
10850
10907
  "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,
@@ -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;
@@ -274,6 +274,7 @@ import RSADecrypt from "./RSADecrypt.mjs";
274
274
  import RSAEncrypt from "./RSAEncrypt.mjs";
275
275
  import RSASign from "./RSASign.mjs";
276
276
  import RSAVerify from "./RSAVerify.mjs";
277
+ import Rabbit from "./Rabbit.mjs";
277
278
  import RailFenceCipherDecode from "./RailFenceCipherDecode.mjs";
278
279
  import RailFenceCipherEncode from "./RailFenceCipherEncode.mjs";
279
280
  import RandomizeColourPalette from "./RandomizeColourPalette.mjs";
@@ -670,6 +671,7 @@ export {
670
671
  RSAEncrypt,
671
672
  RSASign,
672
673
  RSAVerify,
674
+ Rabbit,
673
675
  RailFenceCipherDecode,
674
676
  RailFenceCipherEncode,
675
677
  RandomizeColourPalette,
@@ -275,6 +275,7 @@ import {
275
275
  RSAEncrypt as core_RSAEncrypt,
276
276
  RSASign as core_RSASign,
277
277
  RSAVerify as core_RSAVerify,
278
+ Rabbit as core_Rabbit,
278
279
  RailFenceCipherDecode as core_RailFenceCipherDecode,
279
280
  RailFenceCipherEncode as core_RailFenceCipherEncode,
280
281
  RandomizeColourPalette as core_RandomizeColourPalette,
@@ -671,6 +672,7 @@ function generateChef() {
671
672
  "RSAEncrypt": _wrap(core_RSAEncrypt),
672
673
  "RSASign": _wrap(core_RSASign),
673
674
  "RSAVerify": _wrap(core_RSAVerify),
675
+ "rabbit": _wrap(core_Rabbit),
674
676
  "railFenceCipherDecode": _wrap(core_RailFenceCipherDecode),
675
677
  "railFenceCipherEncode": _wrap(core_RailFenceCipherEncode),
676
678
  "randomizeColourPalette": _wrap(core_RandomizeColourPalette),
@@ -1084,6 +1086,7 @@ const RSADecrypt = chef.RSADecrypt;
1084
1086
  const RSAEncrypt = chef.RSAEncrypt;
1085
1087
  const RSASign = chef.RSASign;
1086
1088
  const RSAVerify = chef.RSAVerify;
1089
+ const rabbit = chef.rabbit;
1087
1090
  const railFenceCipherDecode = chef.railFenceCipherDecode;
1088
1091
  const railFenceCipherEncode = chef.railFenceCipherEncode;
1089
1092
  const randomizeColourPalette = chef.randomizeColourPalette;
@@ -1482,6 +1485,7 @@ const operations = [
1482
1485
  RSAEncrypt,
1483
1486
  RSASign,
1484
1487
  RSAVerify,
1488
+ rabbit,
1485
1489
  railFenceCipherDecode,
1486
1490
  railFenceCipherEncode,
1487
1491
  randomizeColourPalette,
@@ -1884,6 +1888,7 @@ export {
1884
1888
  RSAEncrypt,
1885
1889
  RSASign,
1886
1890
  RSAVerify,
1891
+ rabbit,
1887
1892
  railFenceCipherDecode,
1888
1893
  railFenceCipherEncode,
1889
1894
  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
+ ]);