source: trunk/SSCext/TwofishBase.cs @ 156

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

Twofish working state

  • Property svn:keywords set to URL Author Date Rev Id
File size: 21.1 KB
Line 
1//////////////////////////////////////////////////////////////////////////////////////////////////
2// CrypTool V2
3// © 2008 - Gerhard Junker
4// Apache License see http://www.apache.org/licenses/
5//
6// $HeadURL: trunk/SSCext/TwofishBase.cs $
7//////////////////////////////////////////////////////////////////////////////////////////////////
8// $Revision:: 156                                                                            $://
9// $Author:: junker                                                                           $://
10// $Date:: 2008-12-16 14:33:31 +0000 (Tue, 16 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  partial class TwofishManaged
23  {
24
25    public enum EncryptionDirection
26    {
27      Encrypting,
28      Decrypting
29    }
30
31    /// <summary>
32    /// Summary description for TwofishManaged.
33    /// </summary>
34    internal class TwofishBase
35    {
36
37      public TwofishBase()
38      {
39      }
40
41      protected int inputBlockSize = BLOCK_SIZE / 8;
42      protected int outputBlockSize = BLOCK_SIZE / 8;
43
44      /*
45      +*****************************************************************************
46      *
47      * Function Name:  f32
48      *
49      * Function:                       Run four bytes through keyed S-boxes and apply MDS matrix
50      *
51      * Arguments:              x                       =       input to f function
52      *                                 k32                     =       pointer to key dwords
53      *                                 keyLen          =       total key length (k32 --> keyLey/2 bits)
54      *
55      * Return:                 The output of the keyed permutation applied to x.
56      *
57      * Notes:
58      * This function is a keyed 32-bit permutation.  It is the major building
59      * block for the Twofish round function, including the four keyed 8x8
60      * permutations and the 4x4 MDS matrix multiply.  This function is used
61      * both for generating round subkeys and within the round function on the
62      * block being encrypted. 
63      *
64      * This version is fairly slow and pedagogical, although a smartcard would
65      * probably perform the operation exactly this way in firmware.   For
66      * ultimate performance, the entire operation can be completed with four
67      * lookups into four 256x32-bit tables, with three dword xors.
68      *
69      * The MDS matrix is defined in TABLE.H.  To multiply by Mij, just use the
70      * macro Mij(x).
71      *
72      -****************************************************************************/
73      private static uint f32(uint x, ref uint[] k32, int keyLen)
74      {
75        byte[]  b = { b0(x), b1(x), b2(x), b3(x) };
76
77        /* Run each byte thru 8x8 S-boxes, xoring with key byte at each stage. */
78        /* Note that each byte goes through a different combination of S-boxes.*/
79
80        //*((DWORD *)b) = Bswap(x);     /* make b[0] = LSB, b[3] = MSB */
81        switch (((keyLen + 63) / 64) & 3)
82        {
83          case 0:               /* 256 bits of key */
84            b[0] = (byte)(p8[P_04, b[0]] ^ b0(k32[3]));
85            b[1] = (byte)(p8[P_14, b[1]] ^ b1(k32[3]));
86            b[2] = (byte)(p8[P_24, b[2]] ^ b2(k32[3]));
87            b[3] = (byte)(p8[P_34, b[3]] ^ b3(k32[3]));
88            /* fall thru, having pre-processed b[0]..b[3] with k32[3] */
89            goto case 3;
90          case 3:               /* 192 bits of key */
91            b[0] = (byte)(p8[P_03, b[0]] ^ b0(k32[2]));
92            b[1] = (byte)(p8[P_13, b[1]] ^ b1(k32[2]));
93            b[2] = (byte)(p8[P_23, b[2]] ^ b2(k32[2]));
94            b[3] = (byte)(p8[P_33, b[3]] ^ b3(k32[2]));
95            /* fall thru, having pre-processed b[0]..b[3] with k32[2] */
96            goto case 2;
97          case 2:               /* 128 bits of key */
98            b[0] = p8[P_00, p8[P_01, p8[P_02, b[0]] ^ b0(k32[1])] ^ b0(k32[0])];
99            b[1] = p8[P_10, p8[P_11, p8[P_12, b[1]] ^ b1(k32[1])] ^ b1(k32[0])];
100            b[2] = p8[P_20, p8[P_21, p8[P_22, b[2]] ^ b2(k32[1])] ^ b2(k32[0])];
101            b[3] = p8[P_30, p8[P_31, p8[P_32, b[3]] ^ b3(k32[1])] ^ b3(k32[0])];
102            break;
103        }
104
105
106        /* Now perform the MDS matrix multiply inline. */
107        return (uint)((M00(b[0]) ^ M01(b[1]) ^ M02(b[2]) ^ M03(b[3]))) ^
108        (uint)((M10(b[0]) ^ M11(b[1]) ^ M12(b[2]) ^ M13(b[3])) << 8) ^
109        (uint)((M20(b[0]) ^ M21(b[1]) ^ M22(b[2]) ^ M23(b[3])) << 16) ^
110        (uint)((M30(b[0]) ^ M31(b[1]) ^ M32(b[2]) ^ M33(b[3])) << 24);
111      }
112
113      /*
114      +*****************************************************************************
115      *
116      * Function Name:  reKey
117      *
118      * Function:                       Initialize the Twofish key schedule from key32
119      *
120      * Arguments:              key                     =       ptr to keyInstance to be initialized
121      *
122      * Return:                 TRUE on success
123      *
124      * Notes:
125      * Here we precompute all the round subkeys, although that is not actually
126      * required.  For example, on a smartcard, the round subkeys can
127      * be generated on-the-fly using f32()
128      *
129      -****************************************************************************/
130      protected bool reKey(int keyLen, ref uint[] key32)
131      {
132        int             i,k64Cnt;
133        keyLength = keyLen;
134        rounds = numRounds[(keyLen - 1) / 64];
135        int             subkeyCnt = ROUND_SUBKEYS + 2 * rounds;
136        uint    A,B;
137        uint[] k32e = new uint[MAX_KEY_BITS / 64];
138        uint[] k32o = new uint[MAX_KEY_BITS / 64]; /* even/odd key dwords */
139
140        k64Cnt = (keyLen + 63) / 64;            /* round up to next multiple of 64 bits */
141        for (i = 0; i < k64Cnt; i++)
142        {                                               /* split into even/odd key dwords */
143          k32e[i] = key32[2 * i];
144          k32o[i] = key32[2 * i + 1];
145          /* compute S-box keys using (12,8) Reed-Solomon code over GF(256) */
146          sboxKeys[k64Cnt - 1 - i] = RS_MDS_Encode(k32e[i], k32o[i]); /* reverse order */
147        }
148
149        for (i = 0; i < subkeyCnt / 2; i++)                                     /* compute round subkeys for PHT */
150        {
151          A = f32((uint)(i * SK_STEP), ref k32e, keyLen);       /* A uses even key dwords */
152          B = f32((uint)(i * SK_STEP + SK_BUMP), ref k32o, keyLen);     /* B uses odd  key dwords */
153          B = ROL(B, 8);
154          subKeys[2 * i] = A + B;                       /* combine with a PHT */
155          subKeys[2 * i + 1] = ROL(A + 2 * B, SK_ROTL);
156        }
157
158        return true;
159      }
160
161      protected void blockDecrypt(ref uint[] x)
162      {
163        uint t0,t1;
164        uint[] xtemp = new uint[4];
165
166        if (cipherMode == CipherMode.CBC)
167        {
168          x.CopyTo(xtemp, 0);
169        }
170
171        for (int i=0; i < BLOCK_SIZE / 32; i++) /* copy in the block, add whitening */
172          x[i] ^= subKeys[OUTPUT_WHITEN + i];
173
174        for (int r=rounds - 1; r >= 0; r--)                     /* main Twofish decryption loop */
175        {
176          t0 = f32(x[0], ref sboxKeys, keyLength);
177          t1 = f32(ROL(x[1], 8), ref sboxKeys, keyLength);
178
179          x[2] = ROL(x[2], 1);
180          x[2] ^= t0 + t1 + subKeys[ROUND_SUBKEYS + 2 * r]; /* PHT, round keys */
181          x[3] ^= t0 + 2 * t1 + subKeys[ROUND_SUBKEYS + 2 * r + 1];
182          x[3] = ROR(x[3], 1);
183
184          if (r > 0)                                                                    /* unswap, except for last round */
185          {
186            t0 = x[0];
187            x[0] = x[2];
188            x[2] = t0;
189            t1 = x[1];
190            x[1] = x[3];
191            x[3] = t1;
192          }
193        }
194
195        for (int i=0; i < BLOCK_SIZE / 32; i++) /* copy out, with whitening */
196        {
197          x[i] ^= subKeys[INPUT_WHITEN + i];
198          if (cipherMode == CipherMode.CBC)
199          {
200            x[i] ^= IV[i];
201            IV[i] = xtemp[i];
202          }
203        }
204      }
205
206      protected void blockEncrypt(ref uint[] x)
207      {
208        uint t0,t1,tmp;
209
210        for (int i=0; i < BLOCK_SIZE / 32; i++) /* copy in the block, add whitening */
211        {
212          x[i] ^= subKeys[INPUT_WHITEN + i];
213          if (cipherMode == CipherMode.CBC)
214            x[i] ^= IV[i];
215        }
216
217        for (int r=0; r < rounds; r++)                  /* main Twofish encryption loop */ // 16==rounds
218        {
219          t0 = f32(x[0], ref sboxKeys, keyLength);
220          t1 = f32(ROL(x[1], 8), ref sboxKeys, keyLength);
221
222          x[3] = ROL(x[3], 1);
223          x[2] ^= t0 + t1 + subKeys[ROUND_SUBKEYS + 2 * r]; /* PHT, round keys */
224          x[3] ^= t0 + 2 * t1 + subKeys[ROUND_SUBKEYS + 2 * r + 1];
225          x[2] = ROR(x[2], 1);
226
227          if (r < rounds - 1)                                           /* swap for next round */
228          {
229            tmp = x[0];
230            x[0] = x[2];
231            x[2] = tmp;
232            tmp = x[1];
233            x[1] = x[3];
234            x[3] = tmp;
235          }
236        }
237
238        for (int i=0; i < BLOCK_SIZE / 32; i++) /* copy out, with whitening */
239        {
240          x[i] ^= subKeys[OUTPUT_WHITEN + i];
241          if (cipherMode == CipherMode.CBC)
242          {
243            IV[i] = x[i];
244          }
245        }
246
247      }
248
249      private int[] numRounds = { 0, ROUNDS_128, ROUNDS_192, ROUNDS_256 };
250
251      /*
252      +*****************************************************************************
253      *
254      * Function Name:  RS_MDS_Encode
255      *
256      * Function:                       Use (12,8) Reed-Solomon code over GF(256) to produce
257      *                                 a key S-box dword from two key material dwords.
258      *
259      * Arguments:              k0      =       1st dword
260      *                                 k1      =       2nd dword
261      *
262      * Return:                 Remainder polynomial generated using RS code
263      *
264      * Notes:
265      * Since this computation is done only once per reKey per 64 bits of key,
266      * the performance impact of this routine is imperceptible. The RS code
267      * chosen has "simple" coefficients to allow smartcard/hardware implementation
268      * without lookup tables.
269      *
270      -****************************************************************************/
271      static private uint RS_MDS_Encode(uint k0, uint k1)
272      {
273        uint i,j;
274        uint r;
275
276        for (i = r = 0; i < 2; i++)
277        {
278          r ^= (i > 0) ? k0 : k1;                       /* merge in 32 more key bits */
279          for (j = 0; j < 4; j++)                       /* shift one byte at a time */
280            RS_rem(ref r);
281        }
282        return r;
283      }
284
285      protected uint[] sboxKeys = new uint[MAX_KEY_BITS / 64];  /* key bits used for S-boxes */
286      protected uint[] subKeys = new uint[TOTAL_SUBKEYS];               /* round subkeys, input/output whitening bits */
287      protected uint[] Key = { 0, 0, 0, 0, 0, 0, 0, 0 };                                //new int[MAX_KEY_BITS/32];
288      protected uint[] IV = { 0, 0, 0, 0 };                                             // this should be one block size
289      private int keyLength;
290      private int rounds;
291      protected CipherMode cipherMode = CipherMode.ECB;
292
293
294      #region These are all the definitions that were found in AES.H
295      static private readonly int       BLOCK_SIZE   = 128;     /* number of bits per block */
296      static private readonly int       MAX_ROUNDS   = 16;      /* max # rounds (for allocating subkey array) */
297      static private readonly int       ROUNDS_128   = 16;      /* default number of rounds for 128-bit keys*/
298      static private readonly int       ROUNDS_192   = 16;      /* default number of rounds for 192-bit keys*/
299      static private readonly int       ROUNDS_256   = 16;      /* default number of rounds for 256-bit keys*/
300      static private readonly int       MAX_KEY_BITS = 256;     /* max number of bits of key */
301      static private readonly int       MIN_KEY_BITS = 128;     /* min number of bits of key (zero pad) */
302
303      static private readonly int       INPUT_WHITEN = 0;       /* subkey array indices */
304      static private readonly int       OUTPUT_WHITEN = (INPUT_WHITEN + BLOCK_SIZE / 32);
305      static private readonly int       ROUND_SUBKEYS = (OUTPUT_WHITEN + BLOCK_SIZE / 32);      /* use 2 * (# rounds) */
306      static private readonly int       TOTAL_SUBKEYS = (ROUND_SUBKEYS + 2 * MAX_ROUNDS);
307
308
309      #endregion
310
311      #region These are all the definitions that were found in TABLE.H that we need
312      /* for computing subkeys */
313      static private readonly uint SK_STEP = 0x02020202u;
314      static private readonly uint SK_BUMP = 0x01010101u;
315      static private readonly int SK_ROTL = 9;
316
317      /* Reed-Solomon code parameters: (12,8) reversible code
318      g(x) = x**4 + (a + 1/a) x**3 + a x**2 + (a + 1/a) x + 1
319      where a = primitive root of field generator 0x14D */
320      static private readonly uint      RS_GF_FDBK = 0x14D;             /* field generator */
321      static private void RS_rem(ref uint x)
322      {
323        byte  b  = (byte)(x >> 24);
324        // TODO: maybe change g2 and g3 to bytes                         
325        uint g2 = (uint)(((b << 1) ^ (((b & 0x80) == 0x80) ? RS_GF_FDBK : 0)) & 0xFF);
326        uint g3 = (uint)(((b >> 1) & 0x7F) ^ (((b & 1) == 1) ? RS_GF_FDBK >> 1 : 0) ^ g2);
327        x = (x << 8) ^ (g3 << 24) ^ (g2 << 16) ^ (g3 << 8) ^ b;
328      }
329
330      static private readonly int       MDS_GF_FDBK     = 0x169;        /* primitive polynomial for GF(256)*/
331      static private int LFSR1(int x)
332      {
333        return (((x) >> 1) ^ ((((x) & 0x01) == 0x01) ? MDS_GF_FDBK / 2 : 0));
334      }
335
336      static private int LFSR2(int x)
337      {
338        return (((x) >> 2) ^ ((((x) & 0x02) == 0x02) ? MDS_GF_FDBK / 2 : 0) ^
339          ((((x) & 0x01) == 0x01) ? MDS_GF_FDBK / 4 : 0));
340      }
341
342      // TODO: not the most efficient use of code but it allows us to update
343      // the code a lot quicker we can possibly optimize this code once we have got it all working
344      static private int Mx_1(int x)
345      {
346        return x; /* force result to int so << will work */
347      }
348
349      static private int Mx_X(int x)
350      {
351        return x ^ LFSR2(x);    /* 5B */
352      }
353
354      static private int Mx_Y(int x)
355      {
356        return x ^ LFSR1(x) ^ LFSR2(x); /* EF */
357      }
358
359      static private int M00(int x)
360      {
361        return Mul_1(x);
362      }
363      static private int M01(int x)
364      {
365        return Mul_Y(x);
366      }
367      static private int M02(int x)
368      {
369        return Mul_X(x);
370      }
371      static private int M03(int x)
372      {
373        return Mul_X(x);
374      }
375
376      static private int M10(int x)
377      {
378        return Mul_X(x);
379      }
380      static private int M11(int x)
381      {
382        return Mul_Y(x);
383      }
384      static private int M12(int x)
385      {
386        return Mul_Y(x);
387      }
388      static private int M13(int x)
389      {
390        return Mul_1(x);
391      }
392
393      static private int M20(int x)
394      {
395        return Mul_Y(x);
396      }
397      static private int M21(int x)
398      {
399        return Mul_X(x);
400      }
401      static private int M22(int x)
402      {
403        return Mul_1(x);
404      }
405      static private int M23(int x)
406      {
407        return Mul_Y(x);
408      }
409
410      static private int M30(int x)
411      {
412        return Mul_Y(x);
413      }
414      static private int M31(int x)
415      {
416        return Mul_1(x);
417      }
418      static private int M32(int x)
419      {
420        return Mul_Y(x);
421      }
422      static private int M33(int x)
423      {
424        return Mul_X(x);
425      }
426
427      static private int Mul_1(int x)
428      {
429        return Mx_1(x);
430      }
431      static private int Mul_X(int x)
432      {
433        return Mx_X(x);
434      }
435      static private int Mul_Y(int x)
436      {
437        return Mx_Y(x);
438      }
439      /*        Define the fixed p0/p1 permutations used in keyed S-box lookup. 
440        By changing the following constant definitions for P_ij, the S-boxes will
441        automatically get changed in all the Twofish source code. Note that P_i0 is
442        the "outermost" 8x8 permutation applied.  See the f32() function to see
443        how these constants are to be  used.
444      */
445      static private readonly int       P_00 = 1;                                       /* "outermost" permutation */
446      static private readonly int       P_01 = 0;
447      static private readonly int       P_02 = 0;
448      static private readonly int       P_03 = (P_01 ^ 1);                      /* "extend" to larger key sizes */
449      static private readonly int       P_04 = 1;
450
451      static private readonly int       P_10 = 0;
452      static private readonly int       P_11 = 0;
453      static private readonly int       P_12 = 1;
454      static private readonly int       P_13 = (P_11 ^ 1);
455      static private readonly int       P_14 = 0;
456
457      static private readonly int       P_20 = 1;
458      static private readonly int       P_21 = 1;
459      static private readonly int       P_22 = 0;
460      static private readonly int       P_23 = (P_21 ^ 1);
461      static private readonly int       P_24 = 0;
462
463      static private readonly int       P_30 = 0;
464      static private readonly int       P_31 = 1;
465      static private readonly int       P_32 = 1;
466      static private readonly int       P_33 = (P_31 ^ 1);
467      static private readonly int       P_34 = 1;
468
469
470      static private byte[,] p8 = 
471                  {
472                            /*  p0:   */
473                                  {
474                                  0xA9, 0x67, 0xB3, 0xE8, 0x04, 0xFD, 0xA3, 0x76, 
475                                  0x9A, 0x92, 0x80, 0x78, 0xE4, 0xDD, 0xD1, 0x38, 
476                                  0x0D, 0xC6, 0x35, 0x98, 0x18, 0xF7, 0xEC, 0x6C, 
477                                  0x43, 0x75, 0x37, 0x26, 0xFA, 0x13, 0x94, 0x48, 
478                                  0xF2, 0xD0, 0x8B, 0x30, 0x84, 0x54, 0xDF, 0x23, 
479                                  0x19, 0x5B, 0x3D, 0x59, 0xF3, 0xAE, 0xA2, 0x82, 
480                                  0x63, 0x01, 0x83, 0x2E, 0xD9, 0x51, 0x9B, 0x7C, 
481                                  0xA6, 0xEB, 0xA5, 0xBE, 0x16, 0x0C, 0xE3, 0x61, 
482                                  0xC0, 0x8C, 0x3A, 0xF5, 0x73, 0x2C, 0x25, 0x0B, 
483                                  0xBB, 0x4E, 0x89, 0x6B, 0x53, 0x6A, 0xB4, 0xF1, 
484                                  0xE1, 0xE6, 0xBD, 0x45, 0xE2, 0xF4, 0xB6, 0x66, 
485                                  0xCC, 0x95, 0x03, 0x56, 0xD4, 0x1C, 0x1E, 0xD7, 
486                                  0xFB, 0xC3, 0x8E, 0xB5, 0xE9, 0xCF, 0xBF, 0xBA, 
487                                  0xEA, 0x77, 0x39, 0xAF, 0x33, 0xC9, 0x62, 0x71, 
488                                  0x81, 0x79, 0x09, 0xAD, 0x24, 0xCD, 0xF9, 0xD8, 
489                                  0xE5, 0xC5, 0xB9, 0x4D, 0x44, 0x08, 0x86, 0xE7, 
490                                  0xA1, 0x1D, 0xAA, 0xED, 0x06, 0x70, 0xB2, 0xD2, 
491                                  0x41, 0x7B, 0xA0, 0x11, 0x31, 0xC2, 0x27, 0x90, 
492                                  0x20, 0xF6, 0x60, 0xFF, 0x96, 0x5C, 0xB1, 0xAB, 
493                                  0x9E, 0x9C, 0x52, 0x1B, 0x5F, 0x93, 0x0A, 0xEF, 
494                                  0x91, 0x85, 0x49, 0xEE, 0x2D, 0x4F, 0x8F, 0x3B, 
495                                  0x47, 0x87, 0x6D, 0x46, 0xD6, 0x3E, 0x69, 0x64, 
496                                  0x2A, 0xCE, 0xCB, 0x2F, 0xFC, 0x97, 0x05, 0x7A, 
497                                  0xAC, 0x7F, 0xD5, 0x1A, 0x4B, 0x0E, 0xA7, 0x5A, 
498                                  0x28, 0x14, 0x3F, 0x29, 0x88, 0x3C, 0x4C, 0x02, 
499                                  0xB8, 0xDA, 0xB0, 0x17, 0x55, 0x1F, 0x8A, 0x7D, 
500                                  0x57, 0xC7, 0x8D, 0x74, 0xB7, 0xC4, 0x9F, 0x72, 
501                                  0x7E, 0x15, 0x22, 0x12, 0x58, 0x07, 0x99, 0x34, 
502                                  0x6E, 0x50, 0xDE, 0x68, 0x65, 0xBC, 0xDB, 0xF8, 
503                                  0xC8, 0xA8, 0x2B, 0x40, 0xDC, 0xFE, 0x32, 0xA4, 
504                                  0xCA, 0x10, 0x21, 0xF0, 0xD3, 0x5D, 0x0F, 0x00, 
505                                  0x6F, 0x9D, 0x36, 0x42, 0x4A, 0x5E, 0xC1, 0xE0
506                          },
507                          /*  p1:   */
508                          {
509                                  0x75, 0xF3, 0xC6, 0xF4, 0xDB, 0x7B, 0xFB, 0xC8, 
510                                  0x4A, 0xD3, 0xE6, 0x6B, 0x45, 0x7D, 0xE8, 0x4B, 
511                                  0xD6, 0x32, 0xD8, 0xFD, 0x37, 0x71, 0xF1, 0xE1, 
512                                  0x30, 0x0F, 0xF8, 0x1B, 0x87, 0xFA, 0x06, 0x3F, 
513                                  0x5E, 0xBA, 0xAE, 0x5B, 0x8A, 0x00, 0xBC, 0x9D, 
514                                  0x6D, 0xC1, 0xB1, 0x0E, 0x80, 0x5D, 0xD2, 0xD5, 
515                                  0xA0, 0x84, 0x07, 0x14, 0xB5, 0x90, 0x2C, 0xA3, 
516                                  0xB2, 0x73, 0x4C, 0x54, 0x92, 0x74, 0x36, 0x51, 
517                                  0x38, 0xB0, 0xBD, 0x5A, 0xFC, 0x60, 0x62, 0x96, 
518                                  0x6C, 0x42, 0xF7, 0x10, 0x7C, 0x28, 0x27, 0x8C, 
519                                  0x13, 0x95, 0x9C, 0xC7, 0x24, 0x46, 0x3B, 0x70, 
520                                  0xCA, 0xE3, 0x85, 0xCB, 0x11, 0xD0, 0x93, 0xB8, 
521                                  0xA6, 0x83, 0x20, 0xFF, 0x9F, 0x77, 0xC3, 0xCC, 
522                                  0x03, 0x6F, 0x08, 0xBF, 0x40, 0xE7, 0x2B, 0xE2, 
523                                  0x79, 0x0C, 0xAA, 0x82, 0x41, 0x3A, 0xEA, 0xB9, 
524                                  0xE4, 0x9A, 0xA4, 0x97, 0x7E, 0xDA, 0x7A, 0x17, 
525                                  0x66, 0x94, 0xA1, 0x1D, 0x3D, 0xF0, 0xDE, 0xB3, 
526                                  0x0B, 0x72, 0xA7, 0x1C, 0xEF, 0xD1, 0x53, 0x3E, 
527                                  0x8F, 0x33, 0x26, 0x5F, 0xEC, 0x76, 0x2A, 0x49, 
528                                  0x81, 0x88, 0xEE, 0x21, 0xC4, 0x1A, 0xEB, 0xD9, 
529                                  0xC5, 0x39, 0x99, 0xCD, 0xAD, 0x31, 0x8B, 0x01, 
530                                  0x18, 0x23, 0xDD, 0x1F, 0x4E, 0x2D, 0xF9, 0x48, 
531                                  0x4F, 0xF2, 0x65, 0x8E, 0x78, 0x5C, 0x58, 0x19, 
532                                  0x8D, 0xE5, 0x98, 0x57, 0x67, 0x7F, 0x05, 0x64, 
533                                  0xAF, 0x63, 0xB6, 0xFE, 0xF5, 0xB7, 0x3C, 0xA5, 
534                                  0xCE, 0xE9, 0x68, 0x44, 0xE0, 0x4D, 0x43, 0x69, 
535                                  0x29, 0x2E, 0xAC, 0x15, 0x59, 0xA8, 0x0A, 0x9E, 
536                                  0x6E, 0x47, 0xDF, 0x34, 0x35, 0x6A, 0xCF, 0xDC, 
537                                  0x22, 0xC9, 0xC0, 0x9B, 0x89, 0xD4, 0xED, 0xAB, 
538                                  0x12, 0xA2, 0x0D, 0x52, 0xBB, 0x02, 0x2F, 0xA9, 
539                                  0xD7, 0x61, 0x1E, 0xB4, 0x50, 0x04, 0xF6, 0xC2, 
540                                  0x16, 0x25, 0x86, 0x56, 0x55, 0x09, 0xBE, 0x91
541                          }
542                  };
543      #endregion
544
545      #region These are all the definitions that were found in PLATFORM.H that we need
546      // left rotation
547      private static uint ROL(uint x, int n)
548      {
549        return (((x) << ((n) & 0x1F)) | (x) >> (32 - ((n) & 0x1F)));
550      }
551
552      // right rotation
553      private static uint ROR(uint x, int n)
554      {
555        return (((x) >> ((n) & 0x1F)) | ((x) << (32 - ((n) & 0x1F))));
556      }
557
558      // first byte
559      protected static byte b0(uint x)
560      {
561        return (byte)(x);//& 0xFF);
562      }
563      // second byte
564      protected static byte b1(uint x)
565      {
566        return (byte)((x >> 8));// & (0xFF));
567      }
568      // third byte
569      protected static byte b2(uint x)
570      {
571        return (byte)((x >> 16));// & (0xFF));
572      }
573      // fourth byte
574      protected static byte b3(uint x)
575      {
576        return (byte)((x >> 24));// & (0xFF));
577      }
578
579      #endregion
580    }
581  }
582}
Note: See TracBrowser for help on using the repository browser.