cyberchef 9.52.1 → 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.
@@ -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;
@@ -10,6 +10,8 @@ import A1Z26CipherEncode from "./A1Z26CipherEncode.mjs";
10
10
  import ADD from "./ADD.mjs";
11
11
  import AESDecrypt from "./AESDecrypt.mjs";
12
12
  import AESEncrypt from "./AESEncrypt.mjs";
13
+ import AESKeyUnwrap from "./AESKeyUnwrap.mjs";
14
+ import AESKeyWrap from "./AESKeyWrap.mjs";
13
15
  import AND from "./AND.mjs";
14
16
  import AddLineNumbers from "./AddLineNumbers.mjs";
15
17
  import AddTextToImage from "./AddTextToImage.mjs";
@@ -272,6 +274,7 @@ import RSADecrypt from "./RSADecrypt.mjs";
272
274
  import RSAEncrypt from "./RSAEncrypt.mjs";
273
275
  import RSASign from "./RSASign.mjs";
274
276
  import RSAVerify from "./RSAVerify.mjs";
277
+ import Rabbit from "./Rabbit.mjs";
275
278
  import RailFenceCipherDecode from "./RailFenceCipherDecode.mjs";
276
279
  import RailFenceCipherEncode from "./RailFenceCipherEncode.mjs";
277
280
  import RandomizeColourPalette from "./RandomizeColourPalette.mjs";
@@ -404,6 +407,8 @@ export {
404
407
  ADD,
405
408
  AESDecrypt,
406
409
  AESEncrypt,
410
+ AESKeyUnwrap,
411
+ AESKeyWrap,
407
412
  AND,
408
413
  AddLineNumbers,
409
414
  AddTextToImage,
@@ -666,6 +671,7 @@ export {
666
671
  RSAEncrypt,
667
672
  RSASign,
668
673
  RSAVerify,
674
+ Rabbit,
669
675
  RailFenceCipherDecode,
670
676
  RailFenceCipherEncode,
671
677
  RandomizeColourPalette,
@@ -20,6 +20,8 @@ import {
20
20
  ADD as core_ADD,
21
21
  AESDecrypt as core_AESDecrypt,
22
22
  AESEncrypt as core_AESEncrypt,
23
+ AESKeyUnwrap as core_AESKeyUnwrap,
24
+ AESKeyWrap as core_AESKeyWrap,
23
25
  AND as core_AND,
24
26
  AddLineNumbers as core_AddLineNumbers,
25
27
  AddTextToImage as core_AddTextToImage,
@@ -273,6 +275,7 @@ import {
273
275
  RSAEncrypt as core_RSAEncrypt,
274
276
  RSASign as core_RSASign,
275
277
  RSAVerify as core_RSAVerify,
278
+ Rabbit as core_Rabbit,
276
279
  RailFenceCipherDecode as core_RailFenceCipherDecode,
277
280
  RailFenceCipherEncode as core_RailFenceCipherEncode,
278
281
  RandomizeColourPalette as core_RandomizeColourPalette,
@@ -414,6 +417,8 @@ function generateChef() {
414
417
  "ADD": _wrap(core_ADD),
415
418
  "AESDecrypt": _wrap(core_AESDecrypt),
416
419
  "AESEncrypt": _wrap(core_AESEncrypt),
420
+ "AESKeyUnwrap": _wrap(core_AESKeyUnwrap),
421
+ "AESKeyWrap": _wrap(core_AESKeyWrap),
417
422
  "AND": _wrap(core_AND),
418
423
  "addLineNumbers": _wrap(core_AddLineNumbers),
419
424
  "addTextToImage": _wrap(core_AddTextToImage),
@@ -667,6 +672,7 @@ function generateChef() {
667
672
  "RSAEncrypt": _wrap(core_RSAEncrypt),
668
673
  "RSASign": _wrap(core_RSASign),
669
674
  "RSAVerify": _wrap(core_RSAVerify),
675
+ "rabbit": _wrap(core_Rabbit),
670
676
  "railFenceCipherDecode": _wrap(core_RailFenceCipherDecode),
671
677
  "railFenceCipherEncode": _wrap(core_RailFenceCipherEncode),
672
678
  "randomizeColourPalette": _wrap(core_RandomizeColourPalette),
@@ -816,6 +822,8 @@ const A1Z26CipherEncode = chef.A1Z26CipherEncode;
816
822
  const ADD = chef.ADD;
817
823
  const AESDecrypt = chef.AESDecrypt;
818
824
  const AESEncrypt = chef.AESEncrypt;
825
+ const AESKeyUnwrap = chef.AESKeyUnwrap;
826
+ const AESKeyWrap = chef.AESKeyWrap;
819
827
  const AND = chef.AND;
820
828
  const addLineNumbers = chef.addLineNumbers;
821
829
  const addTextToImage = chef.addTextToImage;
@@ -1078,6 +1086,7 @@ const RSADecrypt = chef.RSADecrypt;
1078
1086
  const RSAEncrypt = chef.RSAEncrypt;
1079
1087
  const RSASign = chef.RSASign;
1080
1088
  const RSAVerify = chef.RSAVerify;
1089
+ const rabbit = chef.rabbit;
1081
1090
  const railFenceCipherDecode = chef.railFenceCipherDecode;
1082
1091
  const railFenceCipherEncode = chef.railFenceCipherEncode;
1083
1092
  const randomizeColourPalette = chef.randomizeColourPalette;
@@ -1212,6 +1221,8 @@ const operations = [
1212
1221
  ADD,
1213
1222
  AESDecrypt,
1214
1223
  AESEncrypt,
1224
+ AESKeyUnwrap,
1225
+ AESKeyWrap,
1215
1226
  AND,
1216
1227
  addLineNumbers,
1217
1228
  addTextToImage,
@@ -1474,6 +1485,7 @@ const operations = [
1474
1485
  RSAEncrypt,
1475
1486
  RSASign,
1476
1487
  RSAVerify,
1488
+ rabbit,
1477
1489
  railFenceCipherDecode,
1478
1490
  railFenceCipherEncode,
1479
1491
  randomizeColourPalette,
@@ -1612,6 +1624,8 @@ export {
1612
1624
  ADD,
1613
1625
  AESDecrypt,
1614
1626
  AESEncrypt,
1627
+ AESKeyUnwrap,
1628
+ AESKeyWrap,
1615
1629
  AND,
1616
1630
  addLineNumbers,
1617
1631
  addTextToImage,
@@ -1874,6 +1888,7 @@ export {
1874
1888
  RSAEncrypt,
1875
1889
  RSASign,
1876
1890
  RSAVerify,
1891
+ rabbit,
1877
1892
  railFenceCipherDecode,
1878
1893
  railFenceCipherEncode,
1879
1894
  randomizeColourPalette,
@@ -128,6 +128,8 @@ import "./tests/NTLM.mjs";
128
128
  import "./tests/Shuffle.mjs";
129
129
  import "./tests/FletcherChecksum.mjs";
130
130
  import "./tests/CMAC.mjs";
131
+ import "./tests/AESKeyWrap.mjs";
132
+ import "./tests/Rabbit.mjs";
131
133
 
132
134
  // Cannot test operations that use the File type yet
133
135
  // import "./tests/SplitColourChannels.mjs";