The Camellia Cipher

In research, you should never dismiss something just because it isn’t currently being used. A good researcher will always look to the other…

The Camellia Cipher

In research, you should never dismiss something just because it isn’t currently being used. A good researcher will always look to the other competing methods to current practice and note their strengths and weaknesses. Something might just come along that could fit a particular problem. And, so, with the advent of AES (aka Rijndael) and ChaCha20, other block ciphers hardly get a look-in. The Camellia cipher is one of these. Overall, it is named after Camellia japonica — which is a Japanese flower that has undulating petals.

Like AES, Camellia has a block size of 128 bits (16 bytes), and can use 128-, 192-, and 256-bit encryption keys. It was created by Mitsubishi and NTT and has been approved by the ISO/IEC. Camellia is also efficient for both hardware and software implementations, and is part of the TLS stack [here]:

Camellia is a Feisitel cipher and uses 18 rounds for 128-bit keys or 24 rounds for 192/256-bit keys. It also uses four 8x8 S-boxes. These s-boxes have a similar structure to the ones used by AES. This means that its performance can be enhanced by using the x86 AES-NI instruction set.

The basic structure of a Feisitel cipher is to split the data into two (left bits and right bits) and put it through a number of rounds:

As with many other Feistel ciphers, it is seen to be secure and is almost impossible at the current time to brute force it. One of its strengths is that it can be formally defined as a number of multivariate polynomials. It is now patent-free and included in OpenSSL. Firefox used Camelia for a while but has since dropped it, but Veracrypt supports it for symmetric key encryption.

Coding

Overall, the usage of Camellia is similar to AES, and uses the same key sizes and modes [here]. First we create a folder named “bc_camellia”, and then go into that folder.We can create a Dotnet console project for .NET 8.0 with:

dotnet new console --framework net8.0

This produces a Csproject file of [here]:

<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
</Project>

We then add the latest Bouncy Castle library:

dotnet add package BouncyCastle.Cryptography --version 2.2.1

The following is the coding. Overall, the usage of Camellia is similar to AES, and uses the same key sizes and modes [here]:

namespace Camillia
{
using Org.BouncyCastle.Crypto;
using Org.BouncyCastle.Crypto.Engines;
using Org.BouncyCastle.Crypto.Modes;
using Org.BouncyCastle.Crypto.Paddings;
using Org.BouncyCastle.Crypto.Parameters;
using Org.BouncyCastle.Security;
class Program
{

static void Main(string[] args)
{



var msg="Hello";

var iv="00112233445566778899AABBCCDDEEFF00";
var size=128;
var mode="CBC";
if (args.Length >0) msg=args[0];
if (args.Length >1) iv=args[1];
if (args.Length >2) size=Convert.ToInt32(args[2]);
if (args.Length >3) mode=args[3];



try {
var plainTextData=System.Text.Encoding.UTF8.GetBytes(msg);
var cipher = new CamelliaEngine();

byte[] nonce = new byte[8];
Array.Copy(Convert.FromHexString(iv), nonce, 8);

PaddedBufferedBlockCipher cipherMode = new PaddedBufferedBlockCipher(new CbcBlockCipher(cipher), new Pkcs7Padding());

if (mode=="ECB") cipherMode = new PaddedBufferedBlockCipher(new EcbBlockCipher (cipher), new Pkcs7Padding());
else if (mode=="CFB") cipherMode = new PaddedBufferedBlockCipher(new CfbBlockCipher (cipher,128 ), new Pkcs7Padding());

CipherKeyGenerator keyGen = new CipherKeyGenerator();
keyGen.Init(new KeyGenerationParameters(new SecureRandom(), size));
KeyParameter keyParam = keyGen.GenerateKeyParameter();

cipherMode.Init(true,keyParam);
int outputSize = cipherMode.GetOutputSize(plainTextData.Length);
byte[] cipherTextData = new byte[outputSize];
int result = cipherMode.ProcessBytes(plainTextData, 0, plainTextData.Length, cipherTextData, 0);
cipherMode.DoFinal(cipherTextData, result);
var rtn = cipherTextData;

// Decrypt
cipherMode.Init(false,keyParam);
outputSize = cipherMode.GetOutputSize(cipherTextData.Length);
plainTextData = new byte[outputSize];
result = cipherMode.ProcessBytes(cipherTextData, 0, cipherTextData.Length,plainTextData, 0);

cipherMode.DoFinal(plainTextData, result);
var pln=plainTextData;

Console.WriteLine("=== {0} ==",cipher.AlgorithmName);
Console.WriteLine("Message:\t\t{0}",msg);
Console.WriteLine("Block size:\t\t{0} bits",cipher.GetBlockSize()*8);
Console.WriteLine("Mode:\t\t\t{0}",mode);
Console.WriteLine("IV:\t\t\t{0}",iv);
Console.WriteLine("Key size:\t\t{0} bits",size);
Console.WriteLine("Key:\t\t\t{0} [{1}]",Convert.ToHexString(keyParam.GetKey()),Convert.ToBase64String(keyParam.GetKey()));

Console.WriteLine("\nCipher (hex):\t\t{0}",Convert.ToHexString(rtn));
Console.WriteLine("Cipher (Base64):\t{0}",Convert.ToBase64String(rtn));
Console.WriteLine("\nPlain:\t\t\t{0}",System.Text.Encoding.ASCII.GetString(pln).TrimEnd('\0'));

} catch (Exception e) {
Console.WriteLine("Error: {0}",e.Message);
}
}
}

}

A sample run is [here]:

=== Camellia ==
Message: Hello 123
Block size: 128 bits
IV: 00112233445566778899AABBCCDDEEFF00
Key size: 256 bits
Key: 05EEC2144CEE4F9204F247F9CDB444B1CED5776DB003D8EAD0E3A4D42F177B9B [Be7CFEzuT5IE8kf5zbREsc7Vd22wA9jq0OOk1C8Xe5s=]
Cipher (hex): 1DD8EACE8127E2F2DF69F70AB31DB402
Cipher (Base64): HdjqzoEn4vLfafcKsx20Ag==
Plain: Hello 123

Conclusions

What’s interesting about Camellia is that it has a similar s-box structure to AES, but is implemented in a Feistel structure, which has applications to Format Preserving Encryption (FPE), and which can be used to encrypt data into a form that looks like valid content.