source: trunk/SSCext/TwofishEncryption.cs @ 157

Last change on this file since 157 was 157, checked in by Gerhard Junker, 13 years ago

SSC-Twofish tests OK

  • Property svn:keywords set to URL Author Date Rev Id
File size: 6.3 KB
Line 
1//////////////////////////////////////////////////////////////////////////////////////////////////
2// CrypTool V2
3// © 2008 - Gerhard Junker
4// Apache License see http://www.apache.org/licenses/
5//
6// $HeadURL: trunk/SSCext/TwofishEncryption.cs $
7//////////////////////////////////////////////////////////////////////////////////////////////////
8// $Revision:: 157                                                                            $://
9// $Author:: junker                                                                           $://
10// $Date:: 2008-12-17 07:07:48 +0000 (Wed, 17 Dec 2008)                                       $://
11//////////////////////////////////////////////////////////////////////////////////////////////////
12
13// more about at http://www.schneier.com/twofish.html
14// used sources from http://www.codeproject.com/KB/recipes/twofish_csharp.aspx
15
16using System;
17using System.Diagnostics;
18using System.Security.Cryptography;
19
20namespace System.Security.Cryptography
21{
22
23  partial class TwofishManaged
24  {
25    /// <summary>
26    /// Summary description for TwofishEncryption.
27    /// </summary>
28    internal class TwofishEncryption : TwofishBase, ICryptoTransform
29    {
30      public TwofishEncryption(int keyLen, ref byte[] key, ref byte[] iv, CipherMode cMode, 
31        EncryptionDirection direction)
32      {
33        // convert our key into an array of ints
34        for (int i=0; i < key.Length / 4; i++)
35        {
36          Key[i] = 
37            (uint)(key[i * 4 + 3] << 24) | 
38            (uint)(key[i * 4 + 2] << 16) | 
39            (uint)(key[i * 4 + 1] <<  8) | 
40            (uint)(key[i * 4 + 0]      );
41        }
42
43        cipherMode = cMode;
44
45        // we only need to convert our IV if we are using CBC
46        if (cipherMode == CipherMode.CBC)
47        {
48          for (int i=0; i < 4; i++)
49          {
50            IV[i] = 
51              (uint)(iv[i * 4 + 3] << 24) | 
52              (uint)(iv[i * 4 + 2] << 16) | 
53              (uint)(iv[i * 4 + 1] <<  8) | 
54              (uint)(iv[i * 4 + 0]      );
55          }
56        }
57
58        encryptionDirection = direction;
59        reKey(keyLen, ref Key);
60
61#if DEBUG2
62        for (int i =  0; i < Key.Length; i++)
63          Debug.WriteLine(i.ToString("00") + " " + Key[i].ToString("x"));
64#endif
65      }
66
67      // need to have this method due to IDisposable - just can't think of a reason to use it for in this class
68      public void Dispose()
69      {
70      }
71
72
73      /// <summary>
74      /// Transform a block depending on whether we are encrypting or decrypting
75      /// </summary>
76      /// <param name="inputBuffer"></param>
77      /// <param name="inputOffset"></param>
78      /// <param name="inputCount"></param>
79      /// <param name="outputBuffer"></param>
80      /// <param name="outputOffset"></param>
81      /// <returns></returns>
82      public int TransformBlock(
83        byte[] inputBuffer,
84        int inputOffset,
85        int inputCount,
86        byte[] outputBuffer,
87        int outputOffset
88        )
89      {
90        uint[] x=new uint[4];
91
92        // load it up
93        for (int i=0; i < 4; i++)
94        {
95          x[i] = 
96            (uint)(inputBuffer[i * 4 + 3 + inputOffset] << 24) | 
97            (uint)(inputBuffer[i * 4 + 2 + inputOffset] << 16) |
98            (uint)(inputBuffer[i * 4 + 1 + inputOffset] <<  8) | 
99            (uint)(inputBuffer[i * 4 + 0 + inputOffset]      );
100        }
101
102        if (encryptionDirection == EncryptionDirection.Encrypting)
103        {
104          blockEncrypt(ref x);
105        }
106        else
107        {
108          blockDecrypt(ref x);
109        }
110
111
112        // load it up
113        for (int i=0; i < 4; i++)
114        {
115          outputBuffer[i * 4 + 0 + outputOffset] = b0(x[i]);
116          outputBuffer[i * 4 + 1 + outputOffset] = b1(x[i]);
117          outputBuffer[i * 4 + 2 + outputOffset] = b2(x[i]);
118          outputBuffer[i * 4 + 3 + outputOffset] = b3(x[i]);
119        }
120
121
122        return inputCount;
123      }
124
125      public byte[] TransformFinalBlock(
126        byte[] inputBuffer,
127        int inputOffset,
128        int inputCount
129        )
130      {
131        byte[] outputBuffer;// = new byte[0];
132
133        if (inputCount > 0)
134        {
135          outputBuffer = new byte[16]; // blocksize
136          uint[] x=new uint[4];
137
138          // load it up
139          for (int i=0; i < 4; i++) // should be okay as we have already said to pad with zeros
140          {
141            x[i] = 
142              (uint)(inputBuffer[i * 4 + 3 + inputOffset] << 24) | 
143              (uint)(inputBuffer[i * 4 + 2 + inputOffset] << 16) |
144              (uint)(inputBuffer[i * 4 + 1 + inputOffset] <<  8) | 
145              (uint)(inputBuffer[i * 4 + 0 + inputOffset]      );
146
147          }
148
149          if (encryptionDirection == EncryptionDirection.Encrypting)
150          {
151            blockEncrypt(ref x);
152          }
153          else
154          {
155            blockDecrypt(ref x);
156          }
157
158          // load it up
159          for (int i=0; i < 4; i++)
160          {
161            outputBuffer[i * 4 + 0] = b0(x[i]);
162            outputBuffer[i * 4 + 1] = b1(x[i]);
163            outputBuffer[i * 4 + 2] = b2(x[i]);
164            outputBuffer[i * 4 + 3] = b3(x[i]);
165          }
166        }
167        else
168        {
169          outputBuffer = new byte[0]; // the .NET framework doesn't like it if you return null - this calms it down
170        }
171
172        return outputBuffer;
173      }
174
175      // not worked out this property yet - placing break points here just don't get caught.
176      private bool canReuseTransform = true;
177      public bool CanReuseTransform
178      {
179        get
180        {
181          return canReuseTransform;
182        }
183      }
184
185      // I normally set this to false when block encrypting so that I can work on one block at a time
186      // but for compression and stream type ciphers this can be set to true so that you get all the data
187      private bool canTransformMultipleBlocks = false;
188      public bool CanTransformMultipleBlocks
189      {
190        get
191        {
192          return canTransformMultipleBlocks;
193        }
194      }
195
196      public int InputBlockSize
197      {
198        get
199        {
200          return inputBlockSize;
201        }
202      }
203
204      public int OutputBlockSize
205      {
206        get
207        {
208          return outputBlockSize;
209        }
210      }
211
212      private EncryptionDirection encryptionDirection;
213    }
214  }
215}
Note: See TracBrowser for help on using the repository browser.