source: trunk/SSCext/TwofishBase.cs @ 159

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

Twofish plugin continued

  • Property svn:keywords set to URL Author Date Rev Id
File size: 21.2 KB
RevLine 
[155]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:: 159                                                                            $://
9// $Author:: junker                                                                           $://
10// $Date:: 2008-12-17 13:50:51 +0000 (Wed, 17 Dec 2008)                                       $://
11//////////////////////////////////////////////////////////////////////////////////////////////////
12
[156]13// more about at http://www.schneier.com/twofish.html
14// used sources from http://www.codeproject.com/KB/recipes/twofish_csharp.aspx
[155]15
16using System;
17using System.Diagnostics;
18using System.Security.Cryptography;
19
20namespace System.Security.Cryptography
21{
[156]22  partial class TwofishManaged
[155]23  {
24
25    public enum EncryptionDirection
26    {
27      Encrypting,
28      Decrypting
29    }
30
31    /// <summary>
[156]32    /// Summary description for TwofishManaged.
[155]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 */
[156]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]));
[155]88            /* fall thru, having pre-processed b[0]..b[3] with k32[3] */
89            goto case 3;
90          case 3:               /* 192 bits of key */
[156]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]));
[155]95            /* fall thru, having pre-processed b[0]..b[3] with k32[2] */
96            goto case 2;
97          case 2:               /* 128 bits of key */
[156]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])];
[155]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;
[157]209#if DEBUG2
[155]210
[157]211        for (int i = 0; i < subKeys.Length; i++)
212          Debug.WriteLine("SubKey " + subKeys[i].ToString("x"));
213#endif
[155]214        for (int i=0; i < BLOCK_SIZE / 32; i++) /* copy in the block, add whitening */
215        {
216          x[i] ^= subKeys[INPUT_WHITEN + i];
217          if (cipherMode == CipherMode.CBC)
218            x[i] ^= IV[i];
219        }
220
221        for (int r=0; r < rounds; r++)                  /* main Twofish encryption loop */ // 16==rounds
222        {
223          t0 = f32(x[0], ref sboxKeys, keyLength);
224          t1 = f32(ROL(x[1], 8), ref sboxKeys, keyLength);
225
226          x[3] = ROL(x[3], 1);
227          x[2] ^= t0 + t1 + subKeys[ROUND_SUBKEYS + 2 * r]; /* PHT, round keys */
228          x[3] ^= t0 + 2 * t1 + subKeys[ROUND_SUBKEYS + 2 * r + 1];
229          x[2] = ROR(x[2], 1);
230
231          if (r < rounds - 1)                                           /* swap for next round */
232          {
233            tmp = x[0];
234            x[0] = x[2];
235            x[2] = tmp;
236            tmp = x[1];
237            x[1] = x[3];
238            x[3] = tmp;
239          }
240        }
241
242        for (int i=0; i < BLOCK_SIZE / 32; i++) /* copy out, with whitening */
243        {
244          x[i] ^= subKeys[OUTPUT_WHITEN + i];
245          if (cipherMode == CipherMode.CBC)
246          {
247            IV[i] = x[i];
248          }
249        }
250
251      }
252
253      private int[] numRounds = { 0, ROUNDS_128, ROUNDS_192, ROUNDS_256 };
254
255      /*
256      +*****************************************************************************
257      *
258      * Function Name:  RS_MDS_Encode
259      *
260      * Function:                       Use (12,8) Reed-Solomon code over GF(256) to produce
261      *                                 a key S-box dword from two key material dwords.
262      *
263      * Arguments:              k0      =       1st dword
264      *                                 k1      =       2nd dword
265      *
266      * Return:                 Remainder polynomial generated using RS code
267      *
268      * Notes:
269      * Since this computation is done only once per reKey per 64 bits of key,
270      * the performance impact of this routine is imperceptible. The RS code
271      * chosen has "simple" coefficients to allow smartcard/hardware implementation
272      * without lookup tables.
273      *
274      -****************************************************************************/
275      static private uint RS_MDS_Encode(uint k0, uint k1)
276      {
277        uint i,j;
278        uint r;
279
280        for (i = r = 0; i < 2; i++)
281        {
282          r ^= (i > 0) ? k0 : k1;                       /* merge in 32 more key bits */
283          for (j = 0; j < 4; j++)                       /* shift one byte at a time */
284            RS_rem(ref r);
285        }
286        return r;
287      }
288
289      protected uint[] sboxKeys = new uint[MAX_KEY_BITS / 64];  /* key bits used for S-boxes */
290      protected uint[] subKeys = new uint[TOTAL_SUBKEYS];               /* round subkeys, input/output whitening bits */
291      protected uint[] Key = { 0, 0, 0, 0, 0, 0, 0, 0 };                                //new int[MAX_KEY_BITS/32];
292      protected uint[] IV = { 0, 0, 0, 0 };                                             // this should be one block size
293      private int keyLength;
294      private int rounds;
295      protected CipherMode cipherMode = CipherMode.ECB;
296
297
298      #region These are all the definitions that were found in AES.H
299      static private readonly int       BLOCK_SIZE   = 128;     /* number of bits per block */
300      static private readonly int       MAX_ROUNDS   = 16;      /* max # rounds (for allocating subkey array) */
301      static private readonly int       ROUNDS_128   = 16;      /* default number of rounds for 128-bit keys*/
302      static private readonly int       ROUNDS_192   = 16;      /* default number of rounds for 192-bit keys*/
303      static private readonly int       ROUNDS_256   = 16;      /* default number of rounds for 256-bit keys*/
304      static private readonly int       MAX_KEY_BITS = 256;     /* max number of bits of key */
[159]305     // static private readonly int     MIN_KEY_BITS = 128;     /* min number of bits of key (zero pad) */
[155]306
307      static private readonly int       INPUT_WHITEN = 0;       /* subkey array indices */
308      static private readonly int       OUTPUT_WHITEN = (INPUT_WHITEN + BLOCK_SIZE / 32);
309      static private readonly int       ROUND_SUBKEYS = (OUTPUT_WHITEN + BLOCK_SIZE / 32);      /* use 2 * (# rounds) */
310      static private readonly int       TOTAL_SUBKEYS = (ROUND_SUBKEYS + 2 * MAX_ROUNDS);
311
312
313      #endregion
314
315      #region These are all the definitions that were found in TABLE.H that we need
316      /* for computing subkeys */
317      static private readonly uint SK_STEP = 0x02020202u;
318      static private readonly uint SK_BUMP = 0x01010101u;
319      static private readonly int SK_ROTL = 9;
320
321      /* Reed-Solomon code parameters: (12,8) reversible code
322      g(x) = x**4 + (a + 1/a) x**3 + a x**2 + (a + 1/a) x + 1
323      where a = primitive root of field generator 0x14D */
324      static private readonly uint      RS_GF_FDBK = 0x14D;             /* field generator */
325      static private void RS_rem(ref uint x)
326      {
327        byte  b  = (byte)(x >> 24);
328        // TODO: maybe change g2 and g3 to bytes                         
329        uint g2 = (uint)(((b << 1) ^ (((b & 0x80) == 0x80) ? RS_GF_FDBK : 0)) & 0xFF);
330        uint g3 = (uint)(((b >> 1) & 0x7F) ^ (((b & 1) == 1) ? RS_GF_FDBK >> 1 : 0) ^ g2);
331        x = (x << 8) ^ (g3 << 24) ^ (g2 << 16) ^ (g3 << 8) ^ b;
332      }
333
334      static private readonly int       MDS_GF_FDBK     = 0x169;        /* primitive polynomial for GF(256)*/
335      static private int LFSR1(int x)
336      {
337        return (((x) >> 1) ^ ((((x) & 0x01) == 0x01) ? MDS_GF_FDBK / 2 : 0));
338      }
339
340      static private int LFSR2(int x)
341      {
342        return (((x) >> 2) ^ ((((x) & 0x02) == 0x02) ? MDS_GF_FDBK / 2 : 0) ^
343          ((((x) & 0x01) == 0x01) ? MDS_GF_FDBK / 4 : 0));
344      }
345
346      // TODO: not the most efficient use of code but it allows us to update
347      // the code a lot quicker we can possibly optimize this code once we have got it all working
348      static private int Mx_1(int x)
349      {
350        return x; /* force result to int so << will work */
351      }
352
353      static private int Mx_X(int x)
354      {
355        return x ^ LFSR2(x);    /* 5B */
356      }
357
358      static private int Mx_Y(int x)
359      {
360        return x ^ LFSR1(x) ^ LFSR2(x); /* EF */
361      }
362
363      static private int M00(int x)
364      {
365        return Mul_1(x);
366      }
367      static private int M01(int x)
368      {
369        return Mul_Y(x);
370      }
371      static private int M02(int x)
372      {
373        return Mul_X(x);
374      }
375      static private int M03(int x)
376      {
377        return Mul_X(x);
378      }
379
380      static private int M10(int x)
381      {
382        return Mul_X(x);
383      }
384      static private int M11(int x)
385      {
386        return Mul_Y(x);
387      }
388      static private int M12(int x)
389      {
390        return Mul_Y(x);
391      }
392      static private int M13(int x)
393      {
394        return Mul_1(x);
395      }
396
397      static private int M20(int x)
398      {
399        return Mul_Y(x);
400      }
401      static private int M21(int x)
402      {
403        return Mul_X(x);
404      }
405      static private int M22(int x)
406      {
407        return Mul_1(x);
408      }
409      static private int M23(int x)
410      {
411        return Mul_Y(x);
412      }
413
414      static private int M30(int x)
415      {
416        return Mul_Y(x);
417      }
418      static private int M31(int x)
419      {
420        return Mul_1(x);
421      }
422      static private int M32(int x)
423      {
424        return Mul_Y(x);
425      }
426      static private int M33(int x)
427      {
428        return Mul_X(x);
429      }
430
431      static private int Mul_1(int x)
432      {
433        return Mx_1(x);
434      }
435      static private int Mul_X(int x)
436      {
437        return Mx_X(x);
438      }
439      static private int Mul_Y(int x)
440      {
441        return Mx_Y(x);
442      }
443      /*        Define the fixed p0/p1 permutations used in keyed S-box lookup. 
444        By changing the following constant definitions for P_ij, the S-boxes will
445        automatically get changed in all the Twofish source code. Note that P_i0 is
446        the "outermost" 8x8 permutation applied.  See the f32() function to see
447        how these constants are to be  used.
448      */
449      static private readonly int       P_00 = 1;                                       /* "outermost" permutation */
450      static private readonly int       P_01 = 0;
451      static private readonly int       P_02 = 0;
452      static private readonly int       P_03 = (P_01 ^ 1);                      /* "extend" to larger key sizes */
453      static private readonly int       P_04 = 1;
454
455      static private readonly int       P_10 = 0;
456      static private readonly int       P_11 = 0;
457      static private readonly int       P_12 = 1;
458      static private readonly int       P_13 = (P_11 ^ 1);
459      static private readonly int       P_14 = 0;
460
461      static private readonly int       P_20 = 1;
462      static private readonly int       P_21 = 1;
463      static private readonly int       P_22 = 0;
464      static private readonly int       P_23 = (P_21 ^ 1);
465      static private readonly int       P_24 = 0;
466
467      static private readonly int       P_30 = 0;
468      static private readonly int       P_31 = 1;
469      static private readonly int       P_32 = 1;
470      static private readonly int       P_33 = (P_31 ^ 1);
471      static private readonly int       P_34 = 1;
472
473
[156]474      static private byte[,] p8 = 
[155]475                  {
[156]476                            /*  p0:   */
[155]477                                  {
478                                  0xA9, 0x67, 0xB3, 0xE8, 0x04, 0xFD, 0xA3, 0x76, 
479                                  0x9A, 0x92, 0x80, 0x78, 0xE4, 0xDD, 0xD1, 0x38, 
480                                  0x0D, 0xC6, 0x35, 0x98, 0x18, 0xF7, 0xEC, 0x6C, 
481                                  0x43, 0x75, 0x37, 0x26, 0xFA, 0x13, 0x94, 0x48, 
482                                  0xF2, 0xD0, 0x8B, 0x30, 0x84, 0x54, 0xDF, 0x23, 
483                                  0x19, 0x5B, 0x3D, 0x59, 0xF3, 0xAE, 0xA2, 0x82, 
484                                  0x63, 0x01, 0x83, 0x2E, 0xD9, 0x51, 0x9B, 0x7C, 
485                                  0xA6, 0xEB, 0xA5, 0xBE, 0x16, 0x0C, 0xE3, 0x61, 
486                                  0xC0, 0x8C, 0x3A, 0xF5, 0x73, 0x2C, 0x25, 0x0B, 
487                                  0xBB, 0x4E, 0x89, 0x6B, 0x53, 0x6A, 0xB4, 0xF1, 
488                                  0xE1, 0xE6, 0xBD, 0x45, 0xE2, 0xF4, 0xB6, 0x66, 
489                                  0xCC, 0x95, 0x03, 0x56, 0xD4, 0x1C, 0x1E, 0xD7, 
490                                  0xFB, 0xC3, 0x8E, 0xB5, 0xE9, 0xCF, 0xBF, 0xBA, 
491                                  0xEA, 0x77, 0x39, 0xAF, 0x33, 0xC9, 0x62, 0x71, 
492                                  0x81, 0x79, 0x09, 0xAD, 0x24, 0xCD, 0xF9, 0xD8, 
493                                  0xE5, 0xC5, 0xB9, 0x4D, 0x44, 0x08, 0x86, 0xE7, 
494                                  0xA1, 0x1D, 0xAA, 0xED, 0x06, 0x70, 0xB2, 0xD2, 
495                                  0x41, 0x7B, 0xA0, 0x11, 0x31, 0xC2, 0x27, 0x90, 
496                                  0x20, 0xF6, 0x60, 0xFF, 0x96, 0x5C, 0xB1, 0xAB, 
497                                  0x9E, 0x9C, 0x52, 0x1B, 0x5F, 0x93, 0x0A, 0xEF, 
498                                  0x91, 0x85, 0x49, 0xEE, 0x2D, 0x4F, 0x8F, 0x3B, 
499                                  0x47, 0x87, 0x6D, 0x46, 0xD6, 0x3E, 0x69, 0x64, 
500                                  0x2A, 0xCE, 0xCB, 0x2F, 0xFC, 0x97, 0x05, 0x7A, 
501                                  0xAC, 0x7F, 0xD5, 0x1A, 0x4B, 0x0E, 0xA7, 0x5A, 
502                                  0x28, 0x14, 0x3F, 0x29, 0x88, 0x3C, 0x4C, 0x02, 
503                                  0xB8, 0xDA, 0xB0, 0x17, 0x55, 0x1F, 0x8A, 0x7D, 
504                                  0x57, 0xC7, 0x8D, 0x74, 0xB7, 0xC4, 0x9F, 0x72, 
505                                  0x7E, 0x15, 0x22, 0x12, 0x58, 0x07, 0x99, 0x34, 
506                                  0x6E, 0x50, 0xDE, 0x68, 0x65, 0xBC, 0xDB, 0xF8, 
507                                  0xC8, 0xA8, 0x2B, 0x40, 0xDC, 0xFE, 0x32, 0xA4, 
508                                  0xCA, 0x10, 0x21, 0xF0, 0xD3, 0x5D, 0x0F, 0x00, 
509                                  0x6F, 0x9D, 0x36, 0x42, 0x4A, 0x5E, 0xC1, 0xE0
510                          },
511                          /*  p1:   */
512                          {
513                                  0x75, 0xF3, 0xC6, 0xF4, 0xDB, 0x7B, 0xFB, 0xC8, 
514                                  0x4A, 0xD3, 0xE6, 0x6B, 0x45, 0x7D, 0xE8, 0x4B, 
515                                  0xD6, 0x32, 0xD8, 0xFD, 0x37, 0x71, 0xF1, 0xE1, 
516                                  0x30, 0x0F, 0xF8, 0x1B, 0x87, 0xFA, 0x06, 0x3F, 
517                                  0x5E, 0xBA, 0xAE, 0x5B, 0x8A, 0x00, 0xBC, 0x9D, 
518                                  0x6D, 0xC1, 0xB1, 0x0E, 0x80, 0x5D, 0xD2, 0xD5, 
519                                  0xA0, 0x84, 0x07, 0x14, 0xB5, 0x90, 0x2C, 0xA3, 
520                                  0xB2, 0x73, 0x4C, 0x54, 0x92, 0x74, 0x36, 0x51, 
521                                  0x38, 0xB0, 0xBD, 0x5A, 0xFC, 0x60, 0x62, 0x96, 
522                                  0x6C, 0x42, 0xF7, 0x10, 0x7C, 0x28, 0x27, 0x8C, 
523                                  0x13, 0x95, 0x9C, 0xC7, 0x24, 0x46, 0x3B, 0x70, 
524                                  0xCA, 0xE3, 0x85, 0xCB, 0x11, 0xD0, 0x93, 0xB8, 
525                                  0xA6, 0x83, 0x20, 0xFF, 0x9F, 0x77, 0xC3, 0xCC, 
526                                  0x03, 0x6F, 0x08, 0xBF, 0x40, 0xE7, 0x2B, 0xE2, 
527                                  0x79, 0x0C, 0xAA, 0x82, 0x41, 0x3A, 0xEA, 0xB9, 
528                                  0xE4, 0x9A, 0xA4, 0x97, 0x7E, 0xDA, 0x7A, 0x17, 
529                                  0x66, 0x94, 0xA1, 0x1D, 0x3D, 0xF0, 0xDE, 0xB3, 
530                                  0x0B, 0x72, 0xA7, 0x1C, 0xEF, 0xD1, 0x53, 0x3E, 
531                                  0x8F, 0x33, 0x26, 0x5F, 0xEC, 0x76, 0x2A, 0x49, 
532                                  0x81, 0x88, 0xEE, 0x21, 0xC4, 0x1A, 0xEB, 0xD9, 
533                                  0xC5, 0x39, 0x99, 0xCD, 0xAD, 0x31, 0x8B, 0x01, 
534                                  0x18, 0x23, 0xDD, 0x1F, 0x4E, 0x2D, 0xF9, 0x48, 
535                                  0x4F, 0xF2, 0x65, 0x8E, 0x78, 0x5C, 0x58, 0x19, 
536                                  0x8D, 0xE5, 0x98, 0x57, 0x67, 0x7F, 0x05, 0x64, 
537                                  0xAF, 0x63, 0xB6, 0xFE, 0xF5, 0xB7, 0x3C, 0xA5, 
538                                  0xCE, 0xE9, 0x68, 0x44, 0xE0, 0x4D, 0x43, 0x69, 
539                                  0x29, 0x2E, 0xAC, 0x15, 0x59, 0xA8, 0x0A, 0x9E, 
540                                  0x6E, 0x47, 0xDF, 0x34, 0x35, 0x6A, 0xCF, 0xDC, 
541                                  0x22, 0xC9, 0xC0, 0x9B, 0x89, 0xD4, 0xED, 0xAB, 
542                                  0x12, 0xA2, 0x0D, 0x52, 0xBB, 0x02, 0x2F, 0xA9, 
543                                  0xD7, 0x61, 0x1E, 0xB4, 0x50, 0x04, 0xF6, 0xC2, 
544                                  0x16, 0x25, 0x86, 0x56, 0x55, 0x09, 0xBE, 0x91
545                          }
546                  };
547      #endregion
548
549      #region These are all the definitions that were found in PLATFORM.H that we need
550      // left rotation
551      private static uint ROL(uint x, int n)
552      {
553        return (((x) << ((n) & 0x1F)) | (x) >> (32 - ((n) & 0x1F)));
554      }
555
556      // right rotation
557      private static uint ROR(uint x, int n)
558      {
559        return (((x) >> ((n) & 0x1F)) | ((x) << (32 - ((n) & 0x1F))));
560      }
561
562      // first byte
563      protected static byte b0(uint x)
564      {
565        return (byte)(x);//& 0xFF);
566      }
567      // second byte
568      protected static byte b1(uint x)
569      {
570        return (byte)((x >> 8));// & (0xFF));
571      }
572      // third byte
573      protected static byte b2(uint x)
574      {
575        return (byte)((x >> 16));// & (0xFF));
576      }
577      // fourth byte
578      protected static byte b3(uint x)
579      {
580        return (byte)((x >> 24));// & (0xFF));
581      }
582
583      #endregion
584    }
585  }
586}
Note: See TracBrowser for help on using the repository browser.