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 +5 -0
- package/package.json +1 -1
- package/src/core/config/Categories.json +2 -1
- package/src/core/config/OperationConfig.json +57 -0
- package/src/core/config/modules/Ciphers.mjs +2 -0
- package/src/core/operations/Rabbit.mjs +247 -0
- package/src/core/operations/index.mjs +2 -0
- package/src/node/index.mjs +5 -0
- package/tests/operations/index.mjs +1 -0
- package/tests/operations/tests/Rabbit.mjs +177 -0
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.
|
|
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,
|
package/src/node/index.mjs
CHANGED
|
@@ -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
|
+
]);
|