Skip to content

Commit 5e7b004

Browse files
committed
Merge branch 'NewCiphers' of https://github.com/n1073645/CyberChef into n1073645-NewCiphers
2 parents 1e791d7 + 355a6d6 commit 5e7b004

File tree

6 files changed

+202
-0
lines changed

6 files changed

+202
-0
lines changed

src/core/config/Categories.json

+2
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,8 @@
9898
"Rail Fence Cipher Encode",
9999
"Rail Fence Cipher Decode",
100100
"Atbash Cipher",
101+
"CipherSaber2 Encrypt",
102+
"CipherSaber2 Decrypt",
101103
"Substitute",
102104
"Derive PBKDF2 key",
103105
"Derive EVP key",

src/core/lib/CipherSaber2.mjs

+36
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
import Utils from "../Utils.mjs";
2+
3+
/**
4+
* @author n1073645 [[email protected]]
5+
* @copyright Crown Copyright 2020
6+
* @license Apache-2.0
7+
*/
8+
export function encode(tempIVP, args, input) {
9+
const ivp = new Uint8Array(Utils.strToByteArray(args[0]).concat(tempIVP));
10+
const state = new Array(256).fill(0);
11+
let j = 0, i = 0;
12+
const result = [];
13+
14+
// Mixing states based off of IV.
15+
for (let i = 0; i < 256; i++)
16+
state[i] = i;
17+
const ivpLength = ivp.length;
18+
for (let r = 0; r < args[1]; r ++) {
19+
for (let k = 0; k < 256; k++) {
20+
j = (j + state[k] + ivp[k % ivpLength]) % 256;
21+
[state[k], state[j]] = [state[j], state[k]];
22+
}
23+
}
24+
j = 0;
25+
i = 0;
26+
27+
// XOR cipher with key.
28+
for (let x = 0; x < input.length; x++) {
29+
i = (++i) % 256;
30+
j = (j + state[i]) % 256;
31+
[state[i], state[j]] = [state[j], state[i]];
32+
const n = (state[i] + state[j]) % 256;
33+
result.push(state[n] ^ input[x]);
34+
}
35+
return result;
36+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
/**
2+
* @author n1073645 [[email protected]]
3+
* @copyright Crown Copyright 2020
4+
* @license Apache-2.0
5+
*/
6+
7+
import Operation from "../Operation.mjs";
8+
import { encode } from "../lib/CipherSaber2.mjs";
9+
10+
/**
11+
* CipherSaber2 Decrypt operation
12+
*/
13+
class CipherSaber2Decrypt extends Operation {
14+
15+
/**
16+
* CipherSaber2Decrypt constructor
17+
*/
18+
constructor() {
19+
super();
20+
21+
this.name = "CipherSaber2 Decrypt";
22+
this.module = "Crypto";
23+
this.description = "CipherSaber is a simple symmetric encryption protocol based on the RC4 stream cipher. It gives reasonably strong protection of message confidentiality, yet it's designed to be simple enough that even novice programmers can memorize the algorithm and implement it from scratch.";
24+
this.infoURL = "https://wikipedia.org/wiki/CipherSaber";
25+
this.inputType = "ArrayBuffer";
26+
this.outputType = "ArrayBuffer";
27+
this.args = [
28+
{
29+
name: "Key",
30+
type: "string",
31+
value: ""
32+
},
33+
{
34+
name: "Rounds",
35+
type: "number",
36+
value: 20
37+
}
38+
];
39+
}
40+
41+
/**
42+
* @param {ArrayBuffer} input
43+
* @param {Object[]} args
44+
* @returns {ArrayBuffer}
45+
*/
46+
run(input, args) {
47+
input = new Uint8Array(input);
48+
const result = [];
49+
50+
const tempIVP = input.slice(0, 10);
51+
input = input.slice(10);
52+
return new Uint8Array(result.concat(encode(tempIVP, args, input))).buffer;
53+
}
54+
55+
}
56+
57+
export default CipherSaber2Decrypt;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
/**
2+
* @author n1073645 [[email protected]]
3+
* @copyright Crown Copyright 2020
4+
* @license Apache-2.0
5+
*/
6+
7+
import Operation from "../Operation.mjs";
8+
import crypto from "crypto";
9+
import { encode } from "../lib/CipherSaber2.mjs";
10+
11+
/**
12+
* CipherSaber2 operation
13+
*/
14+
class CipherSaber2 extends Operation {
15+
16+
/**
17+
* CipherSaber2 constructor
18+
*/
19+
constructor() {
20+
super();
21+
22+
this.name = "CipherSaber2 Encrypt";
23+
this.module = "Crypto";
24+
this.description = "CipherSaber is a simple symmetric encryption protocol based on the RC4 stream cipher. It gives reasonably strong protection of message confidentiality, yet it's designed to be simple enough that even novice programmers can memorize the algorithm and implement it from scratch.";
25+
this.infoURL = "https://wikipedia.org/wiki/CipherSaber";
26+
this.inputType = "ArrayBuffer";
27+
this.outputType = "ArrayBuffer";
28+
this.args = [
29+
{
30+
name: "Key",
31+
type: "string",
32+
value: ""
33+
},
34+
{
35+
name: "Rounds",
36+
type: "number",
37+
value: 20
38+
}
39+
];
40+
}
41+
42+
/**
43+
* @param {ArrayBuffer} input
44+
* @param {Object[]} args
45+
* @returns {ArrayBuffer}
46+
*/
47+
run(input, args) {
48+
input = new Uint8Array(input);
49+
const result = [];
50+
51+
// Assign into initialisation vector based on cipher mode.
52+
const tempIVP = crypto.randomBytes(10);
53+
for (let m = 0; m < 10; m++)
54+
result.push(tempIVP[m]);
55+
56+
return new Uint8Array(result.concat(encode(tempIVP, args, input))).buffer;
57+
}
58+
59+
}
60+
61+
export default CipherSaber2;

tests/operations/index.mjs

+1
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,7 @@ import "./tests/ParseUDP.mjs";
9898
import "./tests/AvroToJSON.mjs";
9999
import "./tests/Lorenz.mjs";
100100
import "./tests/LuhnChecksum.mjs";
101+
import "./tests/CipherSaber2.mjs";
101102

102103

103104
// Cannot test operations that use the File type yet
+45
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
/**
2+
* Ciphersaber2 tests.
3+
*
4+
* @author n1073645 [[email protected]]
5+
*
6+
* @copyright Crown Copyright 2020
7+
* @license Apache-2.0
8+
*/
9+
import TestRegister from "../../lib/TestRegister.mjs";
10+
11+
TestRegister.addTests([
12+
{
13+
name: "CipherSaber2 Encrypt",
14+
input: "Hello World",
15+
expectedMatch: /.{21}/s,
16+
recipeConfig: [
17+
{
18+
op: "CipherSaber2 Encrypt",
19+
args: ["test", 20],
20+
},
21+
],
22+
},
23+
{
24+
name: "CipherSaber2 Decrypt",
25+
input: "\x5d\xd9\x7f\xeb\x77\x3c\x42\x9d\xfe\x9c\x3b\x21\x63\xbd\x53\x38\x18\x7c\x36\x37",
26+
expectedOutput: "helloworld",
27+
recipeConfig: [
28+
{
29+
op: "CipherSaber2 Decrypt",
30+
args: ["test", 20],
31+
},
32+
],
33+
},
34+
{
35+
name: "CipherSaber2 Encrypt",
36+
input: "",
37+
expectedMatch: /.{10}/s,
38+
recipeConfig: [
39+
{
40+
op: "CipherSaber2 Encrypt",
41+
args: ["", 20],
42+
},
43+
],
44+
},
45+
]);

0 commit comments

Comments
 (0)