Modifications made to CipherSaber2

This commit is contained in:
n1073645 2020-02-14 14:21:32 +00:00
parent 6090842372
commit 355a6d6b76
7 changed files with 202 additions and 99 deletions

View File

@ -96,7 +96,8 @@
"A1Z26 Cipher Encode",
"A1Z26 Cipher Decode",
"Atbash Cipher",
"CipherSaber2",
"CipherSaber2 Encrypt",
"CipherSaber2 Decrypt",
"Substitute",
"Derive PBKDF2 key",
"Derive EVP key",

View File

@ -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;
}

View File

@ -1,98 +0,0 @@
/**
* @author n1073645 [n1073645@gmail.com]
* @copyright Crown Copyright 2020
* @license Apache-2.0
*/
import Operation from "../Operation.mjs";
import crypto from "crypto";
import Utils from "../Utils.mjs";
/**
* CipherSaber2 operation
*/
class CipherSaber2 extends Operation {
/**
* CipherSaber2 constructor
*/
constructor() {
super();
this.name = "CipherSaber2";
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
},
{
name: "Mode",
type: "option",
value: ["Encrypt", "Decrypt"]
}
];
}
/**
* @param {ArrayBuffer} input
* @param {Object[]} args
* @returns {ArrayBuffer}
*/
run(input, args) {
input = new Uint8Array(input);
const ivp = new Uint8Array(args[0].length + 10);
ivp.set(new Uint8Array(Utils.strToByteArray(args[0])), 0);
const result = [];
let tempIVP;
// Assign into initialisation vector based on cipher mode.
if (args[2] === "Encrypt") {
tempIVP = crypto.randomBytes(10);
for (let m = 0; m < 10; m++)
result.push(tempIVP[m]);
} else {
tempIVP = input.slice(0, 10);
input = input.slice(10);
}
ivp.set(tempIVP, args[0].length);
const state = new Array(256).fill(0);
let j = 0, i = 0;
// 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 new Uint8Array(result).buffer;
}
}
export default CipherSaber2;

View File

@ -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;

View File

@ -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;

View File

@ -96,6 +96,7 @@ import "./tests/DefangIP.mjs";
import "./tests/ParseUDP.mjs";
import "./tests/AvroToJSON.mjs";
import "./tests/Lorenz.mjs";
import "./tests/CipherSaber2";
// Cannot test operations that use the File type yet

View File

@ -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],
},
],
},
]);