/*
A C# implementation of the Twofish cipher
By Shaun Wilde
An article on integrating a C# implementation of the Twofish cipher into the
.NET framework.
http://www.codeproject.com/KB/recipes/twofish_csharp.aspx
The Code Project Open License (CPOL) 1.02
http://www.codeproject.com/info/cpol10.aspx
Download a copy of the CPOL.
http://www.codeproject.com/info/CPOL.zip
*/
using System;
using System.Diagnostics;
using System.Security.Cryptography;
namespace TwofishCipher.Crypto
{
///
/// Summary description for TwofishEncryption.
///
internal class TwofishEncryption : TwofishBase, ICryptoTransform
{
public TwofishEncryption(int keyLen, ref byte[] key, ref byte[] iv, CipherMode cMode, EncryptionDirection direction)
{
// convert our key into an array of ints
for (int i=0;i
/// Transform a block depending on whether we are encrypting or decrypting
///
///
///
///
///
///
///
public int TransformBlock(
byte[] inputBuffer,
int inputOffset,
int inputCount,
byte[] outputBuffer,
int outputOffset
)
{
uint[] x=new uint[4];
// load it up
for (int i=0;i<4;i++)
{
x[i]= (uint)(inputBuffer[i*4+3+inputOffset]<<24) | (uint)(inputBuffer[i*4+2+inputOffset] << 16) |
(uint)(inputBuffer[i*4+1+inputOffset] << 8) | (uint)(inputBuffer[i*4+0+inputOffset]);
}
if (encryptionDirection == EncryptionDirection.Encrypting)
{
blockEncrypt(ref x);
}
else
{
blockDecrypt(ref x);
}
// load it up
for (int i=0;i<4;i++)
{
outputBuffer[i*4+0+outputOffset] = b0(x[i]);
outputBuffer[i*4+1+outputOffset] = b1(x[i]);
outputBuffer[i*4+2+outputOffset] = b2(x[i]);
outputBuffer[i*4+3+outputOffset] = b3(x[i]);
}
return inputCount;
}
public byte[] TransformFinalBlock(
byte[] inputBuffer,
int inputOffset,
int inputCount
)
{
byte[] outputBuffer;// = new byte[0];
if (inputCount>0)
{
outputBuffer = new byte[16]; // blocksize
uint[] x=new uint[4];
// load it up
for (int i=0;i<4;i++) // should be okay as we have already said to pad with zeros
{
x[i]= (uint)(inputBuffer[i*4+3+inputOffset]<<24) | (uint)(inputBuffer[i*4+2+inputOffset] << 16) |
(uint)(inputBuffer[i*4+1+inputOffset] << 8) | (uint)(inputBuffer[i*4+0+inputOffset]);
}
if (encryptionDirection == EncryptionDirection.Encrypting)
{
blockEncrypt(ref x);
}
else
{
blockDecrypt(ref x);
}
// load it up
for (int i=0;i<4;i++)
{
outputBuffer[i*4+0] = b0(x[i]);
outputBuffer[i*4+1] = b1(x[i]);
outputBuffer[i*4+2] = b2(x[i]);
outputBuffer[i*4+3] = b3(x[i]);
}
}
else
{
outputBuffer = new byte[0]; // the .NET framework doesn't like it if you return null - this calms it down
}
return outputBuffer;
}
// not worked out this property yet - placing break points here just don't get caught.
private bool canReuseTransform = true;
public bool CanReuseTransform
{
get
{
return canReuseTransform;
}
}
// I normally set this to false when block encrypting so that I can work on one block at a time
// but for compression and stream type ciphers this can be set to true so that you get all the data
private bool canTransformMultipleBlocks = false;
public bool CanTransformMultipleBlocks
{
get
{
return canTransformMultipleBlocks;
}
}
public int InputBlockSize
{
get
{
return inputBlockSize;
}
}
public int OutputBlockSize
{
get
{
return outputBlockSize;
}
}
private EncryptionDirection encryptionDirection;
}
}