diff --git a/src/core/operations/RC6Decrypt.mjs b/src/core/operations/RC6Decrypt.mjs
index ee095cb6..5c088d0e 100644
--- a/src/core/operations/RC6Decrypt.mjs
+++ b/src/core/operations/RC6Decrypt.mjs
@@ -8,7 +8,7 @@ import Operation from "../Operation.mjs";
import Utils from "../Utils.mjs";
import OperationError from "../errors/OperationError.mjs";
import { toHex } from "../lib/Hex.mjs";
-import { decryptRC6 } from "../lib/RC6.mjs";
+import { decryptRC6, getBlockSize, getDefaultRounds } from "../lib/RC6.mjs";
/**
* RC6 Decrypt operation
@@ -23,7 +23,7 @@ class RC6Decrypt extends Operation {
this.name = "RC6 Decrypt";
this.module = "Ciphers";
- this.description = "RC6 is a symmetric key block cipher derived from RC5. It was designed by Ron Rivest, Matt Robshaw, Ray Sidney, and Yiqun Lisa Yin to meet the requirements of the AES competition, and was one of the five finalists. RC6 operates on 128-bit blocks and supports key sizes of 128, 192, or 256 bits with 20 rounds.
When using CBC or ECB mode, the PKCS#7 padding scheme is used.";
+ this.description = "RC6 is a symmetric key block cipher derived from RC5. It was designed by Ron Rivest, Matt Robshaw, Ray Sidney, and Yiqun Lisa Yin to meet the requirements of the AES competition, and was one of the five finalists.
RC6 is parameterised as RC6-w/r/b where w is word size in bits (any multiple of 8 from 8-256), r is the number of rounds (1-255), and b is the key length in bytes. The standard AES submission uses w=32, r=20. Common word sizes: 8, 16, 32 (standard), 64, 128.
IV: The Initialisation Vector should be 4*w/8 bytes (e.g. 16 bytes for w=32). If not entered, it will default to null bytes.
Padding: In CBC and ECB mode, the PKCS#7 padding scheme is used.";
this.infoURL = "https://wikipedia.org/wiki/RC6";
this.inputType = "string";
this.outputType = "string";
@@ -59,6 +59,21 @@ class RC6Decrypt extends Operation {
"name": "Padding",
"type": "option",
"value": ["PKCS5", "NO", "ZERO", "RANDOM", "BIT"]
+ },
+ {
+ "name": "Word Size",
+ "type": "number",
+ "value": 32,
+ "min": 8,
+ "max": 256,
+ "step": 8
+ },
+ {
+ "name": "Rounds",
+ "type": "number",
+ "value": 20,
+ "min": 1,
+ "max": 255
}
];
}
@@ -71,21 +86,36 @@ class RC6Decrypt extends Operation {
run(input, args) {
const key = Utils.convertToByteArray(args[0].string, args[0].option),
iv = Utils.convertToByteArray(args[1].string, args[1].option),
- [,, mode, inputType, outputType, padding] = args;
+ [,, mode, inputType, outputType, padding, wordSize, rounds] = args;
- if (key.length !== 16 && key.length !== 24 && key.length !== 32)
+ // Validate word size
+ if (!Number.isInteger(wordSize) || wordSize < 8 || wordSize > 256 || wordSize % 8 !== 0)
+ throw new OperationError(`Invalid word size: ${wordSize}. Must be a multiple of 8 between 8 and 256.`);
+
+ const blockSize = getBlockSize(wordSize);
+ const defaultRounds = getDefaultRounds(wordSize);
+
+ if (key.length === 0)
throw new OperationError(`Invalid key length: ${key.length} bytes
-RC6 uses a key length of 16 bytes (128 bits), 24 bytes (192 bits), or 32 bytes (256 bits).`);
+RC6 requires a key of at least 1 byte.`);
- if (iv.length !== 16 && mode !== "ECB")
+ if (iv.length !== blockSize && iv.length !== 0 && mode !== "ECB")
throw new OperationError(`Invalid IV length: ${iv.length} bytes
-RC6 uses an IV length of 16 bytes (128 bits).
+RC6-${wordSize} uses an IV length of ${blockSize} bytes (${blockSize * 8} bits).
Make sure you have specified the type correctly (e.g. Hex vs UTF8).`);
+ if (!Number.isInteger(rounds) || rounds < 1 || rounds > 255)
+ throw new OperationError(`Invalid number of rounds: ${rounds}
+
+Rounds must be an integer between 1 and 255. Standard for w=${wordSize} is ${defaultRounds}.`);
+
+ // Default IV to null bytes if empty (like AES)
+ const actualIv = iv.length === 0 ? new Array(blockSize).fill(0) : iv;
+
input = Utils.convertToByteArray(input, inputType);
- const output = decryptRC6(input, key, iv, mode, padding);
+ const output = decryptRC6(input, key, actualIv, mode, padding, rounds, wordSize);
return outputType === "Hex" ? toHex(output, "") : Utils.byteArrayToUtf8(output);
}
diff --git a/src/core/operations/RC6Encrypt.mjs b/src/core/operations/RC6Encrypt.mjs
index 4d0b0c11..990c33e8 100644
--- a/src/core/operations/RC6Encrypt.mjs
+++ b/src/core/operations/RC6Encrypt.mjs
@@ -8,7 +8,7 @@ import Operation from "../Operation.mjs";
import Utils from "../Utils.mjs";
import OperationError from "../errors/OperationError.mjs";
import { toHex } from "../lib/Hex.mjs";
-import { encryptRC6 } from "../lib/RC6.mjs";
+import { encryptRC6, getBlockSize, getDefaultRounds } from "../lib/RC6.mjs";
/**
* RC6 Encrypt operation
@@ -23,7 +23,7 @@ class RC6Encrypt extends Operation {
this.name = "RC6 Encrypt";
this.module = "Ciphers";
- this.description = "RC6 is a symmetric key block cipher derived from RC5. It was designed by Ron Rivest, Matt Robshaw, Ray Sidney, and Yiqun Lisa Yin to meet the requirements of the AES competition, and was one of the five finalists. RC6 operates on 128-bit blocks and supports key sizes of 128, 192, or 256 bits with 20 rounds.
When using CBC or ECB mode, the PKCS#7 padding scheme is used.";
+ this.description = "RC6 is a symmetric key block cipher derived from RC5. It was designed by Ron Rivest, Matt Robshaw, Ray Sidney, and Yiqun Lisa Yin to meet the requirements of the AES competition, and was one of the five finalists.
RC6 is parameterised as RC6-w/r/b where w is word size in bits (any multiple of 8 from 8-256), r is the number of rounds (1-255), and b is the key length in bytes. The standard AES submission uses w=32, r=20. Common word sizes: 8, 16, 32 (standard), 64, 128.
IV: The Initialisation Vector should be 4*w/8 bytes (e.g. 16 bytes for w=32). If not entered, it will default to null bytes.
Padding: In CBC and ECB mode, the PKCS#7 padding scheme is used.";
this.infoURL = "https://wikipedia.org/wiki/RC6";
this.inputType = "string";
this.outputType = "string";
@@ -59,6 +59,21 @@ class RC6Encrypt extends Operation {
"name": "Padding",
"type": "option",
"value": ["PKCS5", "NO", "ZERO", "RANDOM", "BIT"]
+ },
+ {
+ "name": "Word Size",
+ "type": "number",
+ "value": 32,
+ "min": 8,
+ "max": 256,
+ "step": 8
+ },
+ {
+ "name": "Rounds",
+ "type": "number",
+ "value": 20,
+ "min": 1,
+ "max": 255
}
];
}
@@ -71,21 +86,36 @@ class RC6Encrypt extends Operation {
run(input, args) {
const key = Utils.convertToByteArray(args[0].string, args[0].option),
iv = Utils.convertToByteArray(args[1].string, args[1].option),
- [,, mode, inputType, outputType, padding] = args;
+ [,, mode, inputType, outputType, padding, wordSize, rounds] = args;
- if (key.length !== 16 && key.length !== 24 && key.length !== 32)
+ // Validate word size
+ if (!Number.isInteger(wordSize) || wordSize < 8 || wordSize > 256 || wordSize % 8 !== 0)
+ throw new OperationError(`Invalid word size: ${wordSize}. Must be a multiple of 8 between 8 and 256.`);
+
+ const blockSize = getBlockSize(wordSize);
+ const defaultRounds = getDefaultRounds(wordSize);
+
+ if (key.length === 0)
throw new OperationError(`Invalid key length: ${key.length} bytes
-RC6 uses a key length of 16 bytes (128 bits), 24 bytes (192 bits), or 32 bytes (256 bits).`);
+RC6 requires a key of at least 1 byte.`);
- if (iv.length !== 16 && mode !== "ECB")
+ if (iv.length !== blockSize && iv.length !== 0 && mode !== "ECB")
throw new OperationError(`Invalid IV length: ${iv.length} bytes
-RC6 uses an IV length of 16 bytes (128 bits).
+RC6-${wordSize} uses an IV length of ${blockSize} bytes (${blockSize * 8} bits).
Make sure you have specified the type correctly (e.g. Hex vs UTF8).`);
+ if (!Number.isInteger(rounds) || rounds < 1 || rounds > 255)
+ throw new OperationError(`Invalid number of rounds: ${rounds}
+
+Rounds must be an integer between 1 and 255. Standard for w=${wordSize} is ${defaultRounds}.`);
+
+ // Default IV to null bytes if empty (like AES)
+ const actualIv = iv.length === 0 ? new Array(blockSize).fill(0) : iv;
+
input = Utils.convertToByteArray(input, inputType);
- const output = encryptRC6(input, key, iv, mode, padding);
+ const output = encryptRC6(input, key, actualIv, mode, padding, rounds, wordSize);
return outputType === "Hex" ? toHex(output, "") : Utils.byteArrayToUtf8(output);
}
diff --git a/tests/operations/tests/RC6.mjs b/tests/operations/tests/RC6.mjs
index efb30836..bc0220af 100644
--- a/tests/operations/tests/RC6.mjs
+++ b/tests/operations/tests/RC6.mjs
@@ -5,7 +5,7 @@
* "Test Vectors for RC6 and RC5"
* https://datatracker.ietf.org/doc/html/draft-krovetz-rc6-rc5-vectors-00
*
- * Note: PKCS5 padding adds an extra block when input is exactly block-aligned.
+ * Supports all word sizes: 8, 16, 32, 64, 128 bits.
* Round-trip tests verify correct encryption/decryption behaviour.
*
* @author Medjedtxm
@@ -17,11 +17,81 @@ import TestRegister from "../../lib/TestRegister.mjs";
TestRegister.addTests([
// ============================================================
- // OFFICIAL TEST VECTORS from IETF draft-krovetz-rc6-rc5-vectors-00
- // RC6-32/20/16 (128-bit key)
+ // IETF TEST VECTORS - RC6-8/12/4 (8-bit words, 12 rounds, 4-byte key)
+ // Block size: 4 bytes (32 bits)
// ============================================================
{
- name: "RC6 Official Vector 1: 128-bit key (IETF draft)",
+ name: "RC6-8/12/4: IETF vector encrypt",
+ input: "00010203",
+ expectedOutput: "aefc4612",
+ recipeConfig: [
+ {
+ op: "RC6 Encrypt",
+ args: [
+ { string: "00010203", option: "Hex" },
+ { string: "", option: "Hex" },
+ "ECB", "Hex", "Hex", "NO", 8, 12
+ ]
+ }
+ ]
+ },
+ {
+ name: "RC6-8/12/4: IETF vector decrypt",
+ input: "aefc4612",
+ expectedOutput: "00010203",
+ recipeConfig: [
+ {
+ op: "RC6 Decrypt",
+ args: [
+ { string: "00010203", option: "Hex" },
+ { string: "", option: "Hex" },
+ "ECB", "Hex", "Hex", "NO", 8, 12
+ ]
+ }
+ ]
+ },
+
+ // ============================================================
+ // IETF TEST VECTORS - RC6-16/16/8 (16-bit words, 16 rounds, 8-byte key)
+ // Block size: 8 bytes (64 bits)
+ // ============================================================
+ {
+ name: "RC6-16/16/8: IETF vector encrypt",
+ input: "0001020304050607",
+ expectedOutput: "2ff0b68eaeffad5b",
+ recipeConfig: [
+ {
+ op: "RC6 Encrypt",
+ args: [
+ { string: "0001020304050607", option: "Hex" },
+ { string: "", option: "Hex" },
+ "ECB", "Hex", "Hex", "NO", 16, 16
+ ]
+ }
+ ]
+ },
+ {
+ name: "RC6-16/16/8: IETF vector decrypt",
+ input: "2ff0b68eaeffad5b",
+ expectedOutput: "0001020304050607",
+ recipeConfig: [
+ {
+ op: "RC6 Decrypt",
+ args: [
+ { string: "0001020304050607", option: "Hex" },
+ { string: "", option: "Hex" },
+ "ECB", "Hex", "Hex", "NO", 16, 16
+ ]
+ }
+ ]
+ },
+
+ // ============================================================
+ // IETF TEST VECTORS - RC6-32/20/16 (32-bit words, 20 rounds, 16-byte key)
+ // Block size: 16 bytes (128 bits) - Standard AES submission
+ // ============================================================
+ {
+ name: "RC6-32/20/16: IETF vector encrypt (AES standard)",
input: "000102030405060708090a0b0c0d0e0f",
expectedOutput: "3a96f9c7f6755cfe46f00e3dcd5d2a3c",
recipeConfig: [
@@ -30,13 +100,13 @@ TestRegister.addTests([
args: [
{ string: "000102030405060708090a0b0c0d0e0f", option: "Hex" },
{ string: "", option: "Hex" },
- "ECB", "Hex", "Hex", "NO"
+ "ECB", "Hex", "Hex", "NO", 32, 20
]
}
]
},
{
- name: "RC6 Official Vector 1 Decrypt: 128-bit key",
+ name: "RC6-32/20/16: IETF vector decrypt (AES standard)",
input: "3a96f9c7f6755cfe46f00e3dcd5d2a3c",
expectedOutput: "000102030405060708090a0b0c0d0e0f",
recipeConfig: [
@@ -45,14 +115,87 @@ TestRegister.addTests([
args: [
{ string: "000102030405060708090a0b0c0d0e0f", option: "Hex" },
{ string: "", option: "Hex" },
- "ECB", "Hex", "Hex", "NO"
+ "ECB", "Hex", "Hex", "NO", 32, 20
]
}
]
},
- // RC6-32/20/24 (192-bit key) - Self-generated, verified by independent implementations
+
+ // ============================================================
+ // IETF TEST VECTORS - RC6-64/24/24 (64-bit words, 24 rounds, 24-byte key)
+ // Block size: 32 bytes (256 bits)
+ // ============================================================
{
- name: "RC6 192-bit key encrypt",
+ name: "RC6-64/24/24: IETF vector encrypt",
+ input: "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f",
+ expectedOutput: "c002de050bd55e5d36864ab9853338e6dc4a1326c6bdaaeb1bc9e4fd67886617",
+ recipeConfig: [
+ {
+ op: "RC6 Encrypt",
+ args: [
+ { string: "000102030405060708090a0b0c0d0e0f1011121314151617", option: "Hex" },
+ { string: "", option: "Hex" },
+ "ECB", "Hex", "Hex", "NO", 64, 24
+ ]
+ }
+ ]
+ },
+ {
+ name: "RC6-64/24/24: IETF vector decrypt",
+ input: "c002de050bd55e5d36864ab9853338e6dc4a1326c6bdaaeb1bc9e4fd67886617",
+ expectedOutput: "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f",
+ recipeConfig: [
+ {
+ op: "RC6 Decrypt",
+ args: [
+ { string: "000102030405060708090a0b0c0d0e0f1011121314151617", option: "Hex" },
+ { string: "", option: "Hex" },
+ "ECB", "Hex", "Hex", "NO", 64, 24
+ ]
+ }
+ ]
+ },
+
+ // ============================================================
+ // IETF TEST VECTORS - RC6-128/28/32 (128-bit words, 28 rounds, 32-byte key)
+ // Block size: 64 bytes (512 bits)
+ // ============================================================
+ {
+ name: "RC6-128/28/32: IETF vector encrypt",
+ input: "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ expectedOutput: "4ed87c64baffecd4303ee6a79aafaef575b351c024272be70a70b4a392cfc157dba52d529a79e83845bf43d67545383aed3dbf4f0d23640e44cbf6cdaa034dcb",
+ recipeConfig: [
+ {
+ op: "RC6 Encrypt",
+ args: [
+ { string: "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f", option: "Hex" },
+ { string: "", option: "Hex" },
+ "ECB", "Hex", "Hex", "NO", 128, 28
+ ]
+ }
+ ]
+ },
+ {
+ name: "RC6-128/28/32: IETF vector decrypt",
+ input: "4ed87c64baffecd4303ee6a79aafaef575b351c024272be70a70b4a392cfc157dba52d529a79e83845bf43d67545383aed3dbf4f0d23640e44cbf6cdaa034dcb",
+ expectedOutput: "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ recipeConfig: [
+ {
+ op: "RC6 Decrypt",
+ args: [
+ { string: "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f", option: "Hex" },
+ { string: "", option: "Hex" },
+ "ECB", "Hex", "Hex", "NO", 128, 28
+ ]
+ }
+ ]
+ },
+
+ // ============================================================
+ // ADDITIONAL RC6-32 TEST VECTORS (192-bit and 256-bit keys)
+ // ============================================================
+ {
+ name: "RC6-32/20/24: 192-bit key encrypt",
input: "000102030405060708090a0b0c0d0e0f",
expectedOutput: "a68a14ff1342262a2bbd21f7966615eb",
recipeConfig: [
@@ -61,13 +204,13 @@ TestRegister.addTests([
args: [
{ string: "000102030405060708090a0b0c0d0e0f1011121314151617", option: "Hex" },
{ string: "", option: "Hex" },
- "ECB", "Hex", "Hex", "NO"
+ "ECB", "Hex", "Hex", "NO", 32, 20
]
}
]
},
{
- name: "RC6 192-bit key decrypt",
+ name: "RC6-32/20/24: 192-bit key decrypt",
input: "a68a14ff1342262a2bbd21f7966615eb",
expectedOutput: "000102030405060708090a0b0c0d0e0f",
recipeConfig: [
@@ -76,14 +219,13 @@ TestRegister.addTests([
args: [
{ string: "000102030405060708090a0b0c0d0e0f1011121314151617", option: "Hex" },
{ string: "", option: "Hex" },
- "ECB", "Hex", "Hex", "NO"
+ "ECB", "Hex", "Hex", "NO", 32, 20
]
}
]
},
- // RC6-32/20/32 (256-bit key) - Self-generated, verified by independent implementations
{
- name: "RC6 256-bit key encrypt",
+ name: "RC6-32/20/32: 256-bit key encrypt",
input: "000102030405060708090a0b0c0d0e0f",
expectedOutput: "921c3ecd43d9426a90089334d67aea2e",
recipeConfig: [
@@ -92,13 +234,13 @@ TestRegister.addTests([
args: [
{ string: "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f", option: "Hex" },
{ string: "", option: "Hex" },
- "ECB", "Hex", "Hex", "NO"
+ "ECB", "Hex", "Hex", "NO", 32, 20
]
}
]
},
{
- name: "RC6 256-bit key decrypt",
+ name: "RC6-32/20/32: 256-bit key decrypt",
input: "921c3ecd43d9426a90089334d67aea2e",
expectedOutput: "000102030405060708090a0b0c0d0e0f",
recipeConfig: [
@@ -107,14 +249,17 @@ TestRegister.addTests([
args: [
{ string: "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f", option: "Hex" },
{ string: "", option: "Hex" },
- "ECB", "Hex", "Hex", "NO"
+ "ECB", "Hex", "Hex", "NO", 32, 20
]
}
]
},
- // Zero key, zero plaintext test
+
+ // ============================================================
+ // ZERO KEY/PLAINTEXT TEST (RC6-32/20/16)
+ // ============================================================
{
- name: "RC6 Zero Key/Plaintext: 128-bit key",
+ name: "RC6-32/20: Zero Key/Plaintext encrypt",
input: "00000000000000000000000000000000",
expectedOutput: "8fc3a53656b1f778c129df4e9848a41e",
recipeConfig: [
@@ -123,13 +268,13 @@ TestRegister.addTests([
args: [
{ string: "00000000000000000000000000000000", option: "Hex" },
{ string: "", option: "Hex" },
- "ECB", "Hex", "Hex", "NO"
+ "ECB", "Hex", "Hex", "NO", 32, 20
]
}
]
},
{
- name: "RC6 Zero Key/Plaintext Decrypt: 128-bit key",
+ name: "RC6-32/20: Zero Key/Plaintext decrypt",
input: "8fc3a53656b1f778c129df4e9848a41e",
expectedOutput: "00000000000000000000000000000000",
recipeConfig: [
@@ -138,16 +283,117 @@ TestRegister.addTests([
args: [
{ string: "00000000000000000000000000000000", option: "Hex" },
{ string: "", option: "Hex" },
- "ECB", "Hex", "Hex", "NO"
+ "ECB", "Hex", "Hex", "NO", 32, 20
]
}
]
},
+
// ============================================================
- // Round-trip tests - These verify encryption and decryption work correctly
+ // ROUND-TRIP TESTS - RC6-8 (8-bit words)
// ============================================================
{
- name: "RC6 Round-trip: ECB 128-bit key, short message",
+ name: "RC6-8 Round-trip: ECB mode",
+ input: "Test",
+ expectedOutput: "Test",
+ recipeConfig: [
+ {
+ op: "RC6 Encrypt",
+ args: [
+ { string: "00112233", option: "Hex" },
+ { string: "", option: "Hex" },
+ "ECB", "Raw", "Hex", "PKCS5", 8, 12
+ ]
+ },
+ {
+ op: "RC6 Decrypt",
+ args: [
+ { string: "00112233", option: "Hex" },
+ { string: "", option: "Hex" },
+ "ECB", "Hex", "Raw", "PKCS5", 8, 12
+ ]
+ }
+ ]
+ },
+ {
+ name: "RC6-8 Round-trip: CBC mode",
+ input: "Hello World!",
+ expectedOutput: "Hello World!",
+ recipeConfig: [
+ {
+ op: "RC6 Encrypt",
+ args: [
+ { string: "mysecret", option: "UTF8" },
+ { string: "abcd", option: "UTF8" },
+ "CBC", "Raw", "Hex", "PKCS5", 8, 12
+ ]
+ },
+ {
+ op: "RC6 Decrypt",
+ args: [
+ { string: "mysecret", option: "UTF8" },
+ { string: "abcd", option: "UTF8" },
+ "CBC", "Hex", "Raw", "PKCS5", 8, 12
+ ]
+ }
+ ]
+ },
+
+ // ============================================================
+ // ROUND-TRIP TESTS - RC6-16 (16-bit words)
+ // ============================================================
+ {
+ name: "RC6-16 Round-trip: ECB mode",
+ input: "Testing!",
+ expectedOutput: "Testing!",
+ recipeConfig: [
+ {
+ op: "RC6 Encrypt",
+ args: [
+ { string: "0011223344556677", option: "Hex" },
+ { string: "", option: "Hex" },
+ "ECB", "Raw", "Hex", "PKCS5", 16, 16
+ ]
+ },
+ {
+ op: "RC6 Decrypt",
+ args: [
+ { string: "0011223344556677", option: "Hex" },
+ { string: "", option: "Hex" },
+ "ECB", "Hex", "Raw", "PKCS5", 16, 16
+ ]
+ }
+ ]
+ },
+ {
+ name: "RC6-16 Round-trip: CBC mode",
+ input: "The quick brown fox",
+ expectedOutput: "The quick brown fox",
+ recipeConfig: [
+ {
+ op: "RC6 Encrypt",
+ args: [
+ { string: "secretkey1234567", option: "UTF8" },
+ { string: "initvec!", option: "UTF8" },
+ "CBC", "Raw", "Hex", "PKCS5", 16, 16
+ ]
+ },
+ {
+ op: "RC6 Decrypt",
+ args: [
+ { string: "secretkey1234567", option: "UTF8" },
+ { string: "initvec!", option: "UTF8" },
+ "CBC", "Hex", "Raw", "PKCS5", 16, 16
+ ]
+ }
+ ]
+ },
+
+ // ============================================================
+ // ROUND-TRIP TESTS - RC6-32 (32-bit words, Standard)
+ // ============================================================
+ {
+ name: "RC6-32 Round-trip: ECB 128-bit key",
input: "Hello World!!!!",
expectedOutput: "Hello World!!!!",
recipeConfig: [
@@ -156,7 +402,7 @@ TestRegister.addTests([
args: [
{ string: "00112233445566778899aabbccddeeff", option: "Hex" },
{ string: "", option: "Hex" },
- "ECB", "Raw", "Hex", "PKCS5"
+ "ECB", "Raw", "Hex", "PKCS5", 32, 20
]
},
{
@@ -164,13 +410,13 @@ TestRegister.addTests([
args: [
{ string: "00112233445566778899aabbccddeeff", option: "Hex" },
{ string: "", option: "Hex" },
- "ECB", "Hex", "Raw", "PKCS5"
+ "ECB", "Hex", "Raw", "PKCS5", 32, 20
]
}
]
},
{
- name: "RC6 Round-trip: CBC 128-bit key, long message",
+ name: "RC6-32 Round-trip: CBC 128-bit key",
input: "The quick brown fox jumps over the lazy dog",
expectedOutput: "The quick brown fox jumps over the lazy dog",
recipeConfig: [
@@ -179,7 +425,7 @@ TestRegister.addTests([
args: [
{ string: "aabbccddeeff00112233445566778899", option: "Hex" },
{ string: "00112233445566778899aabbccddeeff", option: "Hex" },
- "CBC", "Raw", "Hex", "PKCS5"
+ "CBC", "Raw", "Hex", "PKCS5", 32, 20
]
},
{
@@ -187,83 +433,13 @@ TestRegister.addTests([
args: [
{ string: "aabbccddeeff00112233445566778899", option: "Hex" },
{ string: "00112233445566778899aabbccddeeff", option: "Hex" },
- "CBC", "Hex", "Raw", "PKCS5"
+ "CBC", "Hex", "Raw", "PKCS5", 32, 20
]
}
]
},
{
- name: "RC6 Round-trip: ECB 192-bit key",
- input: "Testing RC6 cipher with 192-bit key",
- expectedOutput: "Testing RC6 cipher with 192-bit key",
- recipeConfig: [
- {
- op: "RC6 Encrypt",
- args: [
- { string: "00112233445566778899aabbccddeeff0011223344556677", option: "Hex" },
- { string: "", option: "Hex" },
- "ECB", "Raw", "Hex", "PKCS5"
- ]
- },
- {
- op: "RC6 Decrypt",
- args: [
- { string: "00112233445566778899aabbccddeeff0011223344556677", option: "Hex" },
- { string: "", option: "Hex" },
- "ECB", "Hex", "Raw", "PKCS5"
- ]
- }
- ]
- },
- {
- name: "RC6 Round-trip: CBC 256-bit key",
- input: "RC6 is a symmetric block cipher designed by Ron Rivest!",
- expectedOutput: "RC6 is a symmetric block cipher designed by Ron Rivest!",
- recipeConfig: [
- {
- op: "RC6 Encrypt",
- args: [
- { string: "ffeeddccbbaa99887766554433221100ffeeddccbbaa99887766554433221100", option: "Hex" },
- { string: "8877665544332211ffeeddccbbaa9988", option: "Hex" },
- "CBC", "Raw", "Hex", "PKCS5"
- ]
- },
- {
- op: "RC6 Decrypt",
- args: [
- { string: "ffeeddccbbaa99887766554433221100ffeeddccbbaa99887766554433221100", option: "Hex" },
- { string: "8877665544332211ffeeddccbbaa9988", option: "Hex" },
- "CBC", "Hex", "Raw", "PKCS5"
- ]
- }
- ]
- },
- {
- name: "RC6 Round-trip: UTF8 key (16 bytes)",
- input: "Secret message",
- expectedOutput: "Secret message",
- recipeConfig: [
- {
- op: "RC6 Encrypt",
- args: [
- { string: "mypassword123456", option: "UTF8" },
- { string: "initialisevec123", option: "UTF8" },
- "CBC", "Raw", "Hex", "PKCS5"
- ]
- },
- {
- op: "RC6 Decrypt",
- args: [
- { string: "mypassword123456", option: "UTF8" },
- { string: "initialisevec123", option: "UTF8" },
- "CBC", "Hex", "Raw", "PKCS5"
- ]
- }
- ]
- },
- // CFB mode tests
- {
- name: "RC6 Round-trip: CFB mode",
+ name: "RC6-32 Round-trip: CFB mode",
input: "CFB mode test message",
expectedOutput: "CFB mode test message",
recipeConfig: [
@@ -272,7 +448,7 @@ TestRegister.addTests([
args: [
{ string: "00112233445566778899aabbccddeeff", option: "Hex" },
{ string: "ffeeddccbbaa99887766554433221100", option: "Hex" },
- "CFB", "Raw", "Hex", "PKCS5"
+ "CFB", "Raw", "Hex", "PKCS5", 32, 20
]
},
{
@@ -280,14 +456,13 @@ TestRegister.addTests([
args: [
{ string: "00112233445566778899aabbccddeeff", option: "Hex" },
{ string: "ffeeddccbbaa99887766554433221100", option: "Hex" },
- "CFB", "Hex", "Raw", "PKCS5"
+ "CFB", "Hex", "Raw", "PKCS5", 32, 20
]
}
]
},
- // OFB mode tests
{
- name: "RC6 Round-trip: OFB mode",
+ name: "RC6-32 Round-trip: OFB mode",
input: "OFB mode test message",
expectedOutput: "OFB mode test message",
recipeConfig: [
@@ -296,7 +471,7 @@ TestRegister.addTests([
args: [
{ string: "00112233445566778899aabbccddeeff", option: "Hex" },
{ string: "aabbccddeeff00112233445566778899", option: "Hex" },
- "OFB", "Raw", "Hex", "PKCS5"
+ "OFB", "Raw", "Hex", "PKCS5", 32, 20
]
},
{
@@ -304,14 +479,13 @@ TestRegister.addTests([
args: [
{ string: "00112233445566778899aabbccddeeff", option: "Hex" },
{ string: "aabbccddeeff00112233445566778899", option: "Hex" },
- "OFB", "Hex", "Raw", "PKCS5"
+ "OFB", "Hex", "Raw", "PKCS5", 32, 20
]
}
]
},
- // CTR mode tests
{
- name: "RC6 Round-trip: CTR mode",
+ name: "RC6-32 Round-trip: CTR mode",
input: "CTR mode test message",
expectedOutput: "CTR mode test message",
recipeConfig: [
@@ -320,7 +494,7 @@ TestRegister.addTests([
args: [
{ string: "00112233445566778899aabbccddeeff", option: "Hex" },
{ string: "00000000000000000000000000000001", option: "Hex" },
- "CTR", "Raw", "Hex", "PKCS5"
+ "CTR", "Raw", "Hex", "PKCS5", 32, 20
]
},
{
@@ -328,14 +502,259 @@ TestRegister.addTests([
args: [
{ string: "00112233445566778899aabbccddeeff", option: "Hex" },
{ string: "00000000000000000000000000000001", option: "Hex" },
- "CTR", "Hex", "Raw", "PKCS5"
+ "CTR", "Hex", "Raw", "PKCS5", 32, 20
]
}
]
},
- // Edge case tests - various input lengths
{
- name: "RC6 Round-trip: Various lengths 1 byte",
+ name: "RC6-32 Round-trip: UTF8 key",
+ input: "Secret message",
+ expectedOutput: "Secret message",
+ recipeConfig: [
+ {
+ op: "RC6 Encrypt",
+ args: [
+ { string: "mypassword123456", option: "UTF8" },
+ { string: "initialisevec123", option: "UTF8" },
+ "CBC", "Raw", "Hex", "PKCS5", 32, 20
+ ]
+ },
+ {
+ op: "RC6 Decrypt",
+ args: [
+ { string: "mypassword123456", option: "UTF8" },
+ { string: "initialisevec123", option: "UTF8" },
+ "CBC", "Hex", "Raw", "PKCS5", 32, 20
+ ]
+ }
+ ]
+ },
+
+ // ============================================================
+ // ROUND-TRIP TESTS - RC6-64 (64-bit words)
+ // ============================================================
+ {
+ name: "RC6-64 Round-trip: ECB mode",
+ input: "Testing 64-bit word size!!!!!!!",
+ expectedOutput: "Testing 64-bit word size!!!!!!!",
+ recipeConfig: [
+ {
+ op: "RC6 Encrypt",
+ args: [
+ { string: "000102030405060708090a0b0c0d0e0f1011121314151617", option: "Hex" },
+ { string: "", option: "Hex" },
+ "ECB", "Raw", "Hex", "PKCS5", 64, 24
+ ]
+ },
+ {
+ op: "RC6 Decrypt",
+ args: [
+ { string: "000102030405060708090a0b0c0d0e0f1011121314151617", option: "Hex" },
+ { string: "", option: "Hex" },
+ "ECB", "Hex", "Raw", "PKCS5", 64, 24
+ ]
+ }
+ ]
+ },
+ {
+ name: "RC6-64 Round-trip: CBC mode",
+ input: "RC6 with 64-bit words is powerful!",
+ expectedOutput: "RC6 with 64-bit words is powerful!",
+ recipeConfig: [
+ {
+ op: "RC6 Encrypt",
+ args: [
+ { string: "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f", option: "Hex" },
+ { string: "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f", option: "Hex" },
+ "CBC", "Raw", "Hex", "PKCS5", 64, 24
+ ]
+ },
+ {
+ op: "RC6 Decrypt",
+ args: [
+ { string: "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f", option: "Hex" },
+ { string: "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f", option: "Hex" },
+ "CBC", "Hex", "Raw", "PKCS5", 64, 24
+ ]
+ }
+ ]
+ },
+
+ // ============================================================
+ // RC6-128 ROUND-TRIP TESTS (128-bit words, 64-byte block size)
+ // ============================================================
+ {
+ name: "RC6-128 Round-trip: ECB mode",
+ input: "RC6 with 128-bit words provides massive block size for testing purposes!",
+ expectedOutput: "RC6 with 128-bit words provides massive block size for testing purposes!",
+ recipeConfig: [
+ {
+ op: "RC6 Encrypt",
+ args: [
+ { string: "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f", option: "Hex" },
+ { string: "", option: "Hex" },
+ "ECB", "Raw", "Hex", "PKCS5", 128, 28
+ ]
+ },
+ {
+ op: "RC6 Decrypt",
+ args: [
+ { string: "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f", option: "Hex" },
+ { string: "", option: "Hex" },
+ "ECB", "Hex", "Raw", "PKCS5", 128, 28
+ ]
+ }
+ ]
+ },
+ {
+ name: "RC6-128 Round-trip: CBC mode",
+ input: "RC6-128 with CBC mode needs a 64-byte IV for proper operation with large blocks!",
+ expectedOutput: "RC6-128 with CBC mode needs a 64-byte IV for proper operation with large blocks!",
+ recipeConfig: [
+ {
+ op: "RC6 Encrypt",
+ args: [
+ { string: "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f", option: "Hex" },
+ { string: "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f", option: "Hex" },
+ "CBC", "Raw", "Hex", "PKCS5", 128, 28
+ ]
+ },
+ {
+ op: "RC6 Decrypt",
+ args: [
+ { string: "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f", option: "Hex" },
+ { string: "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f", option: "Hex" },
+ "CBC", "Hex", "Raw", "PKCS5", 128, 28
+ ]
+ }
+ ]
+ },
+
+ // ============================================================
+ // CUSTOM ROUND TESTS - Verify non-standard rounds work
+ // ============================================================
+ {
+ name: "RC6-32 Round-trip: Custom 8 rounds",
+ input: "Testing 8 rounds",
+ expectedOutput: "Testing 8 rounds",
+ recipeConfig: [
+ {
+ op: "RC6 Encrypt",
+ args: [
+ { string: "00112233445566778899aabbccddeeff", option: "Hex" },
+ { string: "", option: "Hex" },
+ "ECB", "Raw", "Hex", "PKCS5", 32, 8
+ ]
+ },
+ {
+ op: "RC6 Decrypt",
+ args: [
+ { string: "00112233445566778899aabbccddeeff", option: "Hex" },
+ { string: "", option: "Hex" },
+ "ECB", "Hex", "Raw", "PKCS5", 32, 8
+ ]
+ }
+ ]
+ },
+ {
+ name: "RC6-32 Round-trip: Custom 12 rounds",
+ input: "Testing 12 rounds",
+ expectedOutput: "Testing 12 rounds",
+ recipeConfig: [
+ {
+ op: "RC6 Encrypt",
+ args: [
+ { string: "00112233445566778899aabbccddeeff", option: "Hex" },
+ { string: "", option: "Hex" },
+ "ECB", "Raw", "Hex", "PKCS5", 32, 12
+ ]
+ },
+ {
+ op: "RC6 Decrypt",
+ args: [
+ { string: "00112233445566778899aabbccddeeff", option: "Hex" },
+ { string: "", option: "Hex" },
+ "ECB", "Hex", "Raw", "PKCS5", 32, 12
+ ]
+ }
+ ]
+ },
+ {
+ name: "RC6-32 Round-trip: Custom 32 rounds",
+ input: "Testing 32 rounds",
+ expectedOutput: "Testing 32 rounds",
+ recipeConfig: [
+ {
+ op: "RC6 Encrypt",
+ args: [
+ { string: "00112233445566778899aabbccddeeff", option: "Hex" },
+ { string: "", option: "Hex" },
+ "ECB", "Raw", "Hex", "PKCS5", 32, 32
+ ]
+ },
+ {
+ op: "RC6 Decrypt",
+ args: [
+ { string: "00112233445566778899aabbccddeeff", option: "Hex" },
+ { string: "", option: "Hex" },
+ "ECB", "Hex", "Raw", "PKCS5", 32, 32
+ ]
+ }
+ ]
+ },
+ {
+ name: "RC6-8 Round-trip: Custom 20 rounds",
+ input: "8-bit with 20 rounds",
+ expectedOutput: "8-bit with 20 rounds",
+ recipeConfig: [
+ {
+ op: "RC6 Encrypt",
+ args: [
+ { string: "00112233", option: "Hex" },
+ { string: "", option: "Hex" },
+ "ECB", "Raw", "Hex", "PKCS5", 8, 20
+ ]
+ },
+ {
+ op: "RC6 Decrypt",
+ args: [
+ { string: "00112233", option: "Hex" },
+ { string: "", option: "Hex" },
+ "ECB", "Hex", "Raw", "PKCS5", 8, 20
+ ]
+ }
+ ]
+ },
+ {
+ name: "RC6-16 Round-trip: Custom 24 rounds",
+ input: "16-bit with 24 rounds",
+ expectedOutput: "16-bit with 24 rounds",
+ recipeConfig: [
+ {
+ op: "RC6 Encrypt",
+ args: [
+ { string: "0011223344556677", option: "Hex" },
+ { string: "", option: "Hex" },
+ "ECB", "Raw", "Hex", "PKCS5", "16", 24
+ ]
+ },
+ {
+ op: "RC6 Decrypt",
+ args: [
+ { string: "0011223344556677", option: "Hex" },
+ { string: "", option: "Hex" },
+ "ECB", "Hex", "Raw", "PKCS5", "16", 24
+ ]
+ }
+ ]
+ },
+
+ // ============================================================
+ // EDGE CASE TESTS - Various input lengths
+ // ============================================================
+ {
+ name: "RC6-32 Round-trip: 1 byte input",
input: "A",
expectedOutput: "A",
recipeConfig: [
@@ -344,7 +763,7 @@ TestRegister.addTests([
args: [
{ string: "00112233445566778899aabbccddeeff", option: "Hex" },
{ string: "", option: "Hex" },
- "ECB", "Raw", "Hex", "PKCS5"
+ "ECB", "Raw", "Hex", "PKCS5", 32, 20
]
},
{
@@ -352,13 +771,13 @@ TestRegister.addTests([
args: [
{ string: "00112233445566778899aabbccddeeff", option: "Hex" },
{ string: "", option: "Hex" },
- "ECB", "Hex", "Raw", "PKCS5"
+ "ECB", "Hex", "Raw", "PKCS5", 32, 20
]
}
]
},
{
- name: "RC6 Round-trip: Various lengths 15 bytes",
+ name: "RC6-32 Round-trip: 15 byte input",
input: "123456789012345",
expectedOutput: "123456789012345",
recipeConfig: [
@@ -367,7 +786,7 @@ TestRegister.addTests([
args: [
{ string: "00112233445566778899aabbccddeeff", option: "Hex" },
{ string: "", option: "Hex" },
- "ECB", "Raw", "Hex", "PKCS5"
+ "ECB", "Raw", "Hex", "PKCS5", 32, 20
]
},
{
@@ -375,13 +794,13 @@ TestRegister.addTests([
args: [
{ string: "00112233445566778899aabbccddeeff", option: "Hex" },
{ string: "", option: "Hex" },
- "ECB", "Hex", "Raw", "PKCS5"
+ "ECB", "Hex", "Raw", "PKCS5", 32, 20
]
}
]
},
{
- name: "RC6 Round-trip: Various lengths 16 bytes (exact block)",
+ name: "RC6-32 Round-trip: 16 byte input (exact block)",
input: "1234567890123456",
expectedOutput: "1234567890123456",
recipeConfig: [
@@ -390,7 +809,7 @@ TestRegister.addTests([
args: [
{ string: "00112233445566778899aabbccddeeff", option: "Hex" },
{ string: "", option: "Hex" },
- "ECB", "Raw", "Hex", "PKCS5"
+ "ECB", "Raw", "Hex", "PKCS5", 32, 20
]
},
{
@@ -398,13 +817,13 @@ TestRegister.addTests([
args: [
{ string: "00112233445566778899aabbccddeeff", option: "Hex" },
{ string: "", option: "Hex" },
- "ECB", "Hex", "Raw", "PKCS5"
+ "ECB", "Hex", "Raw", "PKCS5", 32, 20
]
}
]
},
{
- name: "RC6 Round-trip: Various lengths 17 bytes",
+ name: "RC6-32 Round-trip: 17 byte input",
input: "12345678901234567",
expectedOutput: "12345678901234567",
recipeConfig: [
@@ -413,7 +832,7 @@ TestRegister.addTests([
args: [
{ string: "00112233445566778899aabbccddeeff", option: "Hex" },
{ string: "", option: "Hex" },
- "ECB", "Raw", "Hex", "PKCS5"
+ "ECB", "Raw", "Hex", "PKCS5", 32, 20
]
},
{
@@ -421,36 +840,13 @@ TestRegister.addTests([
args: [
{ string: "00112233445566778899aabbccddeeff", option: "Hex" },
{ string: "", option: "Hex" },
- "ECB", "Hex", "Raw", "PKCS5"
+ "ECB", "Hex", "Raw", "PKCS5", 32, 20
]
}
]
},
{
- name: "RC6 Round-trip: Various lengths 32 bytes (two blocks)",
- input: "12345678901234567890123456789012",
- expectedOutput: "12345678901234567890123456789012",
- recipeConfig: [
- {
- op: "RC6 Encrypt",
- args: [
- { string: "00112233445566778899aabbccddeeff", option: "Hex" },
- { string: "", option: "Hex" },
- "ECB", "Raw", "Hex", "PKCS5"
- ]
- },
- {
- op: "RC6 Decrypt",
- args: [
- { string: "00112233445566778899aabbccddeeff", option: "Hex" },
- { string: "", option: "Hex" },
- "ECB", "Hex", "Raw", "PKCS5"
- ]
- }
- ]
- },
- {
- name: "RC6 Round-trip: Binary data",
+ name: "RC6-32 Round-trip: Binary data",
input: "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f",
expectedOutput: "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f",
recipeConfig: [
@@ -459,7 +855,7 @@ TestRegister.addTests([
args: [
{ string: "ffeeddccbbaa99887766554433221100", option: "Hex" },
{ string: "00112233445566778899aabbccddeeff", option: "Hex" },
- "CBC", "Raw", "Hex", "PKCS5"
+ "CBC", "Raw", "Hex", "PKCS5", 32, 20
]
},
{
@@ -467,7 +863,7 @@ TestRegister.addTests([
args: [
{ string: "ffeeddccbbaa99887766554433221100", option: "Hex" },
{ string: "00112233445566778899aabbccddeeff", option: "Hex" },
- "CBC", "Hex", "Raw", "PKCS5"
+ "CBC", "Hex", "Raw", "PKCS5", 32, 20
]
}
]