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 +10 -0
- package/package.json +3 -1
- package/src/core/config/Categories.json +4 -1
- package/src/core/config/OperationConfig.json +97 -0
- package/src/core/config/modules/Ciphers.mjs +2 -0
- package/src/core/config/modules/Encodings.mjs +4 -0
- package/src/core/config/modules/OpModules.mjs +2 -2
- package/src/core/operations/AMFDecode.mjs +52 -0
- package/src/core/operations/AMFEncode.mjs +52 -0
- package/src/core/operations/Rabbit.mjs +247 -0
- package/src/core/operations/index.mjs +6 -0
- package/src/node/index.mjs +15 -0
- package/tests/operations/index.mjs +1 -0
- package/tests/operations/tests/Rabbit.mjs +177 -0
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.
|
|
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,
|
package/src/node/index.mjs
CHANGED
|
@@ -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
|
+
]);
|