Skip to content

Commit

Permalink
Merge branch 'NewCiphers' of https://github.com/n1073645/CyberChef in…
Browse files Browse the repository at this point in the history
…to n1073645-NewCiphers
  • Loading branch information
n1474335 committed Mar 5, 2020
2 parents 1e791d7 + 355a6d6 commit 5e7b004
Show file tree
Hide file tree
Showing 6 changed files with 202 additions and 0 deletions.
2 changes: 2 additions & 0 deletions src/core/config/Categories.json
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,8 @@
"Rail Fence Cipher Encode",
"Rail Fence Cipher Decode",
"Atbash Cipher",
"CipherSaber2 Encrypt",
"CipherSaber2 Decrypt",
"Substitute",
"Derive PBKDF2 key",
"Derive EVP key",
Expand Down
36 changes: 36 additions & 0 deletions src/core/lib/CipherSaber2.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import Utils from "../Utils.mjs";

/**
* @author n1073645 [n1073645@gmail.com]
* @copyright Crown Copyright 2020
* @license Apache-2.0
*/
export function encode(tempIVP, args, input) {
const ivp = new Uint8Array(Utils.strToByteArray(args[0]).concat(tempIVP));
const state = new Array(256).fill(0);
let j = 0, i = 0;
const result = [];

// Mixing states based off of IV.
for (let i = 0; i < 256; i++)
state[i] = i;
const ivpLength = ivp.length;
for (let r = 0; r < args[1]; r ++) {
for (let k = 0; k < 256; k++) {
j = (j + state[k] + ivp[k % ivpLength]) % 256;
[state[k], state[j]] = [state[j], state[k]];
}
}
j = 0;
i = 0;

// XOR cipher with key.
for (let x = 0; x < input.length; x++) {
i = (++i) % 256;
j = (j + state[i]) % 256;
[state[i], state[j]] = [state[j], state[i]];
const n = (state[i] + state[j]) % 256;
result.push(state[n] ^ input[x]);
}
return result;
}
57 changes: 57 additions & 0 deletions src/core/operations/CipherSaber2Decrypt.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
/**
* @author n1073645 [n1073645@gmail.com]
* @copyright Crown Copyright 2020
* @license Apache-2.0
*/

import Operation from "../Operation.mjs";
import { encode } from "../lib/CipherSaber2.mjs";

/**
* CipherSaber2 Decrypt operation
*/
class CipherSaber2Decrypt extends Operation {

/**
* CipherSaber2Decrypt constructor
*/
constructor() {
super();

this.name = "CipherSaber2 Decrypt";
this.module = "Crypto";
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.";
this.infoURL = "https://wikipedia.org/wiki/CipherSaber";
this.inputType = "ArrayBuffer";
this.outputType = "ArrayBuffer";
this.args = [
{
name: "Key",
type: "string",
value: ""
},
{
name: "Rounds",
type: "number",
value: 20
}
];
}

/**
* @param {ArrayBuffer} input
* @param {Object[]} args
* @returns {ArrayBuffer}
*/
run(input, args) {
input = new Uint8Array(input);
const result = [];

const tempIVP = input.slice(0, 10);
input = input.slice(10);
return new Uint8Array(result.concat(encode(tempIVP, args, input))).buffer;
}

}

export default CipherSaber2Decrypt;
61 changes: 61 additions & 0 deletions src/core/operations/CipherSaber2Encrypt.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
/**
* @author n1073645 [n1073645@gmail.com]
* @copyright Crown Copyright 2020
* @license Apache-2.0
*/

import Operation from "../Operation.mjs";
import crypto from "crypto";
import { encode } from "../lib/CipherSaber2.mjs";

/**
* CipherSaber2 operation
*/
class CipherSaber2 extends Operation {

/**
* CipherSaber2 constructor
*/
constructor() {
super();

this.name = "CipherSaber2 Encrypt";
this.module = "Crypto";
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.";
this.infoURL = "https://wikipedia.org/wiki/CipherSaber";
this.inputType = "ArrayBuffer";
this.outputType = "ArrayBuffer";
this.args = [
{
name: "Key",
type: "string",
value: ""
},
{
name: "Rounds",
type: "number",
value: 20
}
];
}

/**
* @param {ArrayBuffer} input
* @param {Object[]} args
* @returns {ArrayBuffer}
*/
run(input, args) {
input = new Uint8Array(input);
const result = [];

// Assign into initialisation vector based on cipher mode.
const tempIVP = crypto.randomBytes(10);
for (let m = 0; m < 10; m++)
result.push(tempIVP[m]);

return new Uint8Array(result.concat(encode(tempIVP, args, input))).buffer;
}

}

export default CipherSaber2;
1 change: 1 addition & 0 deletions tests/operations/index.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@ import "./tests/ParseUDP.mjs";
import "./tests/AvroToJSON.mjs";
import "./tests/Lorenz.mjs";
import "./tests/LuhnChecksum.mjs";
import "./tests/CipherSaber2.mjs";


// Cannot test operations that use the File type yet
Expand Down
45 changes: 45 additions & 0 deletions tests/operations/tests/CipherSaber2.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
/**
* Ciphersaber2 tests.
*
* @author n1073645 [n1073645@gmail.com]
*
* @copyright Crown Copyright 2020
* @license Apache-2.0
*/
import TestRegister from "../../lib/TestRegister.mjs";

TestRegister.addTests([
{
name: "CipherSaber2 Encrypt",
input: "Hello World",
expectedMatch: /.{21}/s,
recipeConfig: [
{
op: "CipherSaber2 Encrypt",
args: ["test", 20],
},
],
},
{
name: "CipherSaber2 Decrypt",
input: "\x5d\xd9\x7f\xeb\x77\x3c\x42\x9d\xfe\x9c\x3b\x21\x63\xbd\x53\x38\x18\x7c\x36\x37",
expectedOutput: "helloworld",
recipeConfig: [
{
op: "CipherSaber2 Decrypt",
args: ["test", 20],
},
],
},
{
name: "CipherSaber2 Encrypt",
input: "",
expectedMatch: /.{10}/s,
recipeConfig: [
{
op: "CipherSaber2 Encrypt",
args: ["", 20],
},
],
},
]);

0 comments on commit 5e7b004

Please sign in to comment.