Click here to Skip to main content
Click here to Skip to main content

A C# implementation of the Twofish cipher

By , 17 Jul 2002
 

Preface

This article is about using the .NET framework to create an encryption provider and integrate it using the same mechanism provided by the .NET platform. This article is not about the Twofish cipher itself but is used as an example cipher that can can be integrated in such a manner.

Introduction

The .NET framework supports various encryption providers such as the AES winner Rijndael. But it is possible to use the same framework to add custom encryption providers and use them in the same manner as the .NET provided ones. It is not necessary to just use it for encryption as the same framework can also be used for any form of encoding mechanism such as compression or MIME encoding. Also these transformations can be connected together via the streams so that it is possible to cascade these transformations i.e. memory -> compress -> encrypt -> encode, in a very simple manner. This technique will be familiar to people who have used Crypto++. For this purpose the .NET framework provides a base class SymmetricAlgorithm and an interface ICryptoTransform.

Investigation

To investigate how the .NET framework used the SymmetricAlgorithm class and ICryptoTransform interface I created a simple class XOR which does a byte by byte eXclusiveOR on a block of data. A very basic and very poor encryption system but it at least lets one work out if we are using the supplied classes and interfaces correctly. I have also included this in the install but it is just a bunch of methods/properties and lots of trace statements.

Discovery

byte[] ICryptoTransform.TransformFinalBlock(byte[] inputBuffer, int inputOffset, int inputCount); - This method does not like when you return null, throws an exception, when there is no data to return. You will usually have this case when this method is called but inputCount is 0, instead you have to return new byte[0]. This is not documented in the help files (yet).

public virtual SymmetricAlgorithm.CipherMode Mode {get; set;} - The framework does not use this property itself to implement the various cipher modes - you must read this property when you are transforming data and act accordingly.

Twofish

Now armed with the new found knowledge I proceeded to implement the Twofish cipher in C#. I based my implementation on the reference C implementation of the Twofish cipher which can be found at Counterpane Internet Security as I do not think the optimised C implementation would port as well. I have tested the code so that it works in EBC mode and I have also implemented CBC mode as well.

Cascade

As I mentioned before it is possible to cascade these transforms such that with one call you can compress -> encrypt -> encode. In the install I have shown how one may cascade the Twofish cipher and the .NET provided Base64 transforms FromBase64Transform and ToBase64Transform. I haven't shown the compression step as I have yet to implement that transform.

Twofish fish = new Twofish();
System.IO.MemoryStream ms = new System.IO.MemoryStream();

// create an encoder
ICryptoTransform encode = new ToBase64Transform();

//create Twofish Encryptor from this instance
ICryptoTransform encrypt = fish.CreateEncryptor( Key, IV);
// both Key and IV are byte[] types 

// we have to work backwards defining the last link in the chain first
CryptoStream cryptostreamEncode = new CryptoStream( ms, encode, 
                                                    CryptoStreamMode.Write);
CryptoStream cryptostream = new CryptoStream( cryptostreamEncode, encrypt, 
                                              CryptoStreamMode.Write);
// or we could do this as we don't need to use cryptostreamEncode
CryptoStream cryptostream = new 
  CryptoStream(new CryptoStream( ms,encode, CryptoStreamMode.Write), 
  encrypt, CryptoStreamMode.Write);

Outstanding Issues

  • I have not created any random key or IV mechanism that would normally be implemented in the GenerateIV() and GenerateKey() overrides.
  • Need further testing to test the CBC mode and to add other cipher modes.
  • Integrate a compression algorithm into a class that supports ICryptoTransform interface
  • Optimise the code. As I mentioned before I am not too sure how to go about optimising C# code so any tips appreciated.
  • The uninstall does not remove any produced files due to compilation.

History

First revision - 17 July 2002

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

About the Author

Shaun Wilde
Software Developer (Senior) MYOB
Australia Australia
Member
All articles are supplied as-is, as a howto on a particular task that worked for me in the past. None of the articles are supposed to be out-of-the-box freeware controls and nor should they be treated as such. Caveat emptor.
 
Now living and working in Australia, trying to be involved in the local .NET and Agile communities when I can.
 
I spend a good chunk of my spare time building OpenCover and maintaining PartCover both of which are Code Coverage utilities for .NET.

Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
You must Sign In to use this message board.
Search this forum  
    Spacing  Noise  Layout  Per page   
GeneralRe: Nice topicmemberShaun Wilde17 Feb '07 - 21:46 
Only what is there - the article is quite old (~4 years)
 
Do you have any particular questions?
 
I'll be more enthusiastic about encouraging thinking outside the box when there's evidence of any thinking going on inside it. - pTerry
www.many-monkeys.com

GeneralI met some problemmemberpdwolf18 May '03 - 20:14 
when I make the source string size less than 16 bytes,
encryption&decryption works fine, but if its size >16 bytes, encrypt it and descryption return the correct string and repeating character.
GeneralRe: I met some problemmemberShaun Wilde19 May '03 - 9:09 
Hi
 
The algorithm is a block cypher (I didn't implement the stream cipher mode) as such it expects data to be a multiple of the block size - if the data is less than that then it pads zeros on the end to make the data up to a full block in size - this is quite normal for a block cipher algorithm.
 
If the repeating character is a zero then this is normal otherwise please let me know what data you are using so I can repeat the problem and investigate more. It is not uncommon for people to but a leading int in the data to specify how many bytes is in the plaintext if you are using full block sizes.
 

Technically speaking the dictionary would define Visual Basic users as programmers.
But here again, a very generalized, liberal definition is being employed and it's wrong
- just plain wrong - Tom Archer 5/12/02


GeneralRe: I met some problemmemberfind_ananth26 Oct '10 - 6:48 
Hi Shaun,
Since you are padding with zeroes at the end, I would believe this does not conform to PKCS7 padding mode. Can you let me know what change I would need to change it to PKCS7 mode?
Thanks,
Andy
GeneralRe: I met some problemmemberShaun Wilde26 Oct '10 - 10:49 
Sorry I don't know, nor do I have the time to find out at this moment; I'll have to leave that as an exercise for the reader.
I'll be more enthusiastic about encouraging thinking outside the box when there's evidence of any thinking going on inside it. - pTerry
BizSquawk

GeneralQuestionmemberbfadi26 Mar '03 - 20:32 
Hi,
Is Towfish better than rijendal ?
Is it better to do the 2 encryption algo to secure a data ?
Thanks
Rose | [Rose]
GeneralRe: QuestionmemberShaun Wilde26 Mar '03 - 21:37 
They seem to be about even (in fact all the final AES candidates appear to be evenly matched).
 
I just used Twofish in a legacy home project (since I had previous experience with the blowfish algorithm). MS only included Rijndael into the .NET framework as it was the eventual winner. I wanted to use Twofish again but in the .NET framework (which is similar to the crypto++ architecture), however I could find no documentation so I investigated further and thus this article was born.
 
> Is it better to do the 2 encryption algo to secure a data ?
 
If you mean should you encrypt first with one algorithm and then again with another - many experts consider that it is pointless and only wastes CPU cycles.
 

Technically speaking the dictionary would define Visual Basic users as programmers.
But here again, a very generalized, liberal definition is being employed and it's wrong
- just plain wrong - Tom Archer 5/12/02


GeneralRe: Questionmemberbfadi27 Mar '03 - 0:19 
Thanks for the answer,
 
I have one more question:
1- If I have an important data and I need it to be secure for 5 years, is AES good choice ?
2- I will encrypt blocks, is it good to encrypt all the block with the same key ?
 
Bye
 

GeneralRe: QuestionmemberShaun Wilde27 Mar '03 - 1:38 
I am not an expert however it should be a good choice - it is supposed to have a high shelf life so it can be used as the US government standard.
 
learn to understand the various modes such as CBC and EBC - normally you would use CBC as this provides the best security for encrypting repeating data as EBC is good for short data but subjecvt to replay attack.
 
see www.cryptopp.com[^] for a good encryption reference start
 

Technically speaking the dictionary would define Visual Basic users as programmers.
But here again, a very generalized, liberal definition is being employed and it's wrong
- just plain wrong - Tom Archer 5/12/02


QuestionRjindael broken?memberShaun Wilde17 Sep '02 - 4:47 
Okay no cause to panic yet but this analysis shows that the world of cryptography is constantly moving the goalposts.
 
Counterpane: Crypto-Gram: September 15, 2002[^]
 

Stupidity dies.
The end of future offspring.
Evolution wins.
- A Darwin Awards Haiku


General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Permalink | Advertise | Privacy | Mobile
Web04 | 2.6.130523.1 | Last Updated 18 Jul 2002
Article Copyright 2002 by Shaun Wilde
Everything else Copyright © CodeProject, 1999-2013
Terms of Use
Layout: fixed | fluid