source: trunk/SSCext/TwofishBase.cs @ 155

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

Plugin URLs filled
Source comments - references added
twofish partial added

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